From 319193bf106de762d3c58315b80feb92e4507c1a Mon Sep 17 00:00:00 2001 From: Patrick Keenum <5631043+prof197@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:02:17 -0500 Subject: [PATCH 1/4] add encryption helpers --- src/index.js | 14 +++ src/lib/delivery.js | 9 +- src/utils/encryption.js | 167 ++++++++++++++++++++++++++++++++++ test/utils/encryption.spec.js | 89 ++++++++++++++++++ 4 files changed, 275 insertions(+), 4 deletions(-) create mode 100644 src/utils/encryption.js create mode 100644 test/utils/encryption.spec.js diff --git a/src/index.js b/src/index.js index c5e1e74..55fd08c 100644 --- a/src/index.js +++ b/src/index.js @@ -28,6 +28,7 @@ import System from './lib/system.js'; import AdalianOrbit from './utils/AdalianOrbit.js'; import Address from './utils/address.js'; +import Encryption from './utils/encryption.js'; import Fixed from './utils/fixed.js'; import Merkle from './utils/MerkleTree.js'; import ProductionJSON from './utils/ProductionJSON.js'; @@ -39,10 +40,23 @@ import ethereumContracts from './contracts/ethereum_abis.json' assert { type: 'j import starknetAddresses from './contracts/starknet_addresses.json' assert { type: 'json' }; import starknetContracts from './contracts/starknet_abis.json' assert { type: 'json' }; +(async function() { + const isNode = typeof process !== 'undefined' && + process.versions != null && + process.versions.node != null; + if (isNode && !globalThis.crypto) { + const { webcrypto } = await import('crypto'); + if (!globalThis.crypto) { + globalThis.crypto = webcrypto; + } + } +})(); + // Utility libs export { AdalianOrbit, Address, + Encryption, Fixed, Merkle, ProductionJSON, diff --git a/src/lib/delivery.js b/src/lib/delivery.js index ae61056..885eb9b 100644 --- a/src/lib/delivery.js +++ b/src/lib/delivery.js @@ -1,10 +1,11 @@ const INSTANT_TRANSPORT_DISTANCE = 5; // instant transport distance in km const STATUSES = { - PACKAGED: 3, // packaged, controlled by origin - ON_HOLD: 1, // controlled by a system (rather than a user) - SENT: 4, // sent, controlled by destination - COMPLETE: 2 // complete at destination + PACKAGED: 3, // packaged, controlled by origin + ON_HOLD: 1, // controlled by a system (rather than a user) + SENT: 4, // sent, controlled by destination + COMPLETE: 2, // complete at destination + REJECTED: 0 // rejected (i.e. packaged but dismissed) }; export default { diff --git a/src/utils/encryption.js b/src/utils/encryption.js new file mode 100644 index 0000000..9edc943 --- /dev/null +++ b/src/utils/encryption.js @@ -0,0 +1,167 @@ +import { ec } from 'starknet'; + +// Helper functions +function bytesToHex(bytes) { + return Array.from(bytes) + .map((byte) => ('00' + byte.toString(16)).slice(-2)) + .join(''); +} + +function hexToBytes(hexStr) { + const bytes = new Uint8Array(hexStr.length / 2); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = parseInt(hexStr.substr(i * 2, 2), 16); + } + return bytes; +} + +export function generateSeed() { + const array = crypto.getRandomValues(new Uint8Array(32)); + return Array.from(array).map(byte => byte.toString(16).padStart(2, '0')).join(''); +} + +export function publicKeyToMessageKeys(publicKey) { + if (publicKey?.length === 130) { + return { + message_key_x: BigInt(`0x${publicKey.substr(2, 64)}`), + message_key_y: BigInt(`0x${publicKey.substr(66)}`), + }; + } +} + +export function messageKeysToPublicKey({ message_key_x, message_key_y }) { + if (message_key_x && message_key_y) { + return `04${BigInt(message_key_x).toString(16).padStart(64, '0')}${BigInt(message_key_y).toString(16).padStart(64, '0')}`; + } + return null; +} + +// Function to generate private key from seed +export async function generatePrivateKeyFromSeed(seed) { + // Convert seed to bytes + const encoder = new TextEncoder(); + const seedBytes = encoder.encode(seed); + // Hash the seed using SHA-256 + const hashBuffer = await crypto.subtle.digest('SHA-256', seedBytes); + const hashArray = new Uint8Array(hashBuffer); + // Convert hash to BigInt + const hashHex = bytesToHex(hashArray); + const hashBigInt = BigInt('0x' + hashHex); + // Reduce modulo curve order n to get a valid private key + const privateKey = hashBigInt % ec.starkCurve.CURVE.n; + // Ensure privateKey != 0 + if (privateKey === 0n) { + throw new Error('Invalid seed resulting in zero private key'); + } + return `0x${privateKey.toString(16).padStart(64, '0')}`; +} + +// Function to get public key from private key +export function getPublicKeyFromPrivateKey(privateKey, returnHex = true) { + const publicKey = ec.starkCurve.getPublicKey(privateKey, false); // Uint8Array + return returnHex ? bytesToHex(publicKey) : publicKey; +} + +// Function to encrypt message +export async function encryptContent(recipientPublicKeyHex, message) { + // Convert recipientPublicKeyHex to Uint8Array + const recipientPublicKeyBytes = hexToBytes(recipientPublicKeyHex); + + // Generate ephemeral keypair + const ephemeralPrivateKey = ec.starkCurve.utils.randomPrivateKey(); + const ephemeralPublicKey = ec.starkCurve.getPublicKey(ephemeralPrivateKey, false); // Uint8Array + + // Compute shared secret + const sharedSecret = ec.starkCurve.getSharedSecret(ephemeralPrivateKey, recipientPublicKeyBytes); // Uint8Array + + // Derive symmetric key + const hashBuffer = await crypto.subtle.digest('SHA-256', sharedSecret); + + // Import symmetric key + const symmetricKey = await crypto.subtle.importKey( + 'raw', + hashBuffer, + { name: 'AES-GCM' }, + false, + ['encrypt'] + ); + + // Generate IV + const iv = crypto.getRandomValues(new Uint8Array(12)); + + // Encrypt the message using AES-256-GCM + const encoder = new TextEncoder(); + const messageBytes = encoder.encode(message); + + const encryptedBuffer = await crypto.subtle.encrypt( + { + name: 'AES-GCM', + iv: iv, + }, + symmetricKey, + messageBytes + ); + + // The encrypted data is an ArrayBuffer + const encryptedBytes = new Uint8Array(encryptedBuffer); + + // Return encrypted data: ephemeralPublicKey, iv, encryptedMessage + const payload = { + ephemeralPublicKey: bytesToHex(ephemeralPublicKey), + iv: bytesToHex(iv), + encryptedMessage: bytesToHex(encryptedBytes), + }; + + return btoa(JSON.stringify(payload)); +} + +// Function to decrypt message +export async function decryptContent(privateKey, encryptedData) { + const { ephemeralPublicKey, iv, encryptedMessage } = JSON.parse(atob(encryptedData)); + + // Convert data from hex to Uint8Array + const ephemeralPublicKeyBytes = hexToBytes(ephemeralPublicKey); + const ivBytes = hexToBytes(iv); + const encryptedBytes = hexToBytes(encryptedMessage); + + // Compute shared secret + const sharedSecret = ec.starkCurve.getSharedSecret(privateKey, ephemeralPublicKeyBytes); // Uint8Array + + // Derive symmetric key + const hashBuffer = await crypto.subtle.digest('SHA-256', sharedSecret); + + // Import symmetric key + const symmetricKey = await crypto.subtle.importKey( + 'raw', + hashBuffer, + { name: 'AES-GCM' }, + false, + ['decrypt'] + ); + + // Decrypt the message using AES-256-GCM + const decryptedBuffer = await crypto.subtle.decrypt( + { + name: 'AES-GCM', + iv: ivBytes, + }, + symmetricKey, + encryptedBytes + ); + + // Convert decryptedBuffer to string + const decoder = new TextDecoder(); + const decryptedMessage = decoder.decode(decryptedBuffer); + + return decryptedMessage; +} + +export default { + generateSeed, + generatePrivateKeyFromSeed, + getPublicKeyFromPrivateKey, + publicKeyToMessageKeys, + messageKeysToPublicKey, + encryptContent, + decryptContent, +} \ No newline at end of file diff --git a/test/utils/encryption.spec.js b/test/utils/encryption.spec.js new file mode 100644 index 0000000..d04fbb0 --- /dev/null +++ b/test/utils/encryption.spec.js @@ -0,0 +1,89 @@ +import { expect } from 'chai'; +import { Encryption } from '../../src/index.js'; + +const sampleSeed = '2a1ded6e8f66bc48e5872bf9105e80046300308962fe51f0b611f2af6bab60ea'; +const samplePrivateKey = '0x0550aeb48829403d98e3ba904acc0217e6dfbd009f0b5ad98569c4b61e373309'; +const samplePublicKey = '0404fa8d30182b0f62618a481bf4afb14b815057570a028355fae8da22969840f6042a3c380981faa3ae8e95406ab898b91f124f7f7aced5f3ec4746b99e529c95'; +const sampleMessageKeys = { + message_key_x: 2251937603385208024268746691711293108925510072271936097377258983003822506230n, + message_key_y: 1883874586592859398548265238594790780856956796067331763265145999321206004885n +}; +const sampleDecryptedMessage = 'Hello, world!'; +const sampleEncryptedMessage = 'eyJlcGhlbWVyYWxQdWJsaWNLZXkiOiIwNDA3MDU4YzFkZmM4N2NhZDIwMjkxZDQ3OWY2OWZhMDQwZWY2NjMzOGYwZjQ4OWE4OTNmNDM0NzhmZGY2YTQ2ZTIwNjkwODM4MDUzYjcxNTkxYTU0ZGM0MjU3MmExNjc1YWU5NjI3ZDE5MGQ3MjNiZGE0ZmI0MzU0MGU4ZTFhYmQzIiwiaXYiOiJhMzA4NTY1ZmM3NTFlMDRlOWE5YTU1YmYiLCJlbmNyeXB0ZWRNZXNzYWdlIjoiYTc4OTBmZjY0M2M2MjhjYTUwNmQ5NzY3MDViYjVlMDAzMzJmOTY0NzZkMzFjZmM5MTdjMDhmZjlmYSJ9'; + +describe('Encryption library', function () { + describe('generateSeed', function () { + it ('should generate a seed', function () { + const seed = Encryption.generateSeed(); + expect(seed).to.be.a('string').with.lengthOf(64); + }); + }); + + describe('publicKeyToMessageKeys', function () { + it ('should convert a public key to message keys', function () { + const messageKeys = Encryption.publicKeyToMessageKeys(samplePublicKey); + expect(messageKeys).to.be.an('object').with.keys('message_key_x', 'message_key_y'); + expect(messageKeys.message_key_x).to.be.a('bigint'); + expect(messageKeys.message_key_y).to.be.a('bigint'); + expect(messageKeys).to.deep.equal(sampleMessageKeys); + }); + }); + + describe('messageKeysToPublicKey', function () { + it ('should convert message keys to a public key', function () { + const publicKey = Encryption.messageKeysToPublicKey(sampleMessageKeys); + expect(publicKey).to.be.a('string').with.lengthOf(130); + expect(publicKey.slice(0, 2)).to.equal('04'); + expect(publicKey).to.equal(samplePublicKey); + }); + }); + + describe('getPublicKeyFromPrivateKey', function () { + it('should get a public key (buffer) from a private key', function () { + const publicKey = Encryption.getPublicKeyFromPrivateKey(samplePrivateKey, false); + expect(publicKey).to.be.a('Uint8Array').with.lengthOf(65); + expect(publicKey[0]).to.equal(4); + }); + + it('should get a public key (hex string) from a private key', function () { + const publicKey = Encryption.getPublicKeyFromPrivateKey(samplePrivateKey); + expect(publicKey).to.be.a('string').with.lengthOf(130); + expect(publicKey.slice(0, 2)).to.equal('04'); + expect(publicKey).to.equal(samplePublicKey); + }); + }); + + describe('generatePrivateKeyFromSeed', function () { + it ('should generate a private key from a seed', async function () { + const privateKey = await Encryption.generatePrivateKeyFromSeed(sampleSeed); + expect(privateKey).to.be.a('string').with.lengthOf(66); + expect(privateKey).to.equal(samplePrivateKey); + }); + }); + + describe('encrypt + decrypt', function () { + it ('should encrypt a message', async function () { + const encryptedMessage = await Encryption.encryptContent(samplePublicKey, sampleDecryptedMessage); + expect(encryptedMessage).to.be.a('string'); + }); + + it ('should decrypt a message', async function () { + const decryptedMessage = await Encryption.decryptContent(samplePrivateKey, sampleEncryptedMessage); + expect(decryptedMessage).to.equal(sampleDecryptedMessage); + }); + + it ('should encrypt and decrypt a unique message', async function () { + const message = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. + + ${Date.now()} + `; + + const encryptedMessage = await Encryption.encryptContent(samplePublicKey, message); + expect(encryptedMessage).to.not.equal(message); + const decryptedMessage = await Encryption.decryptContent(samplePrivateKey, encryptedMessage); + expect(decryptedMessage).to.equal(message); + }); + }); + +}); \ No newline at end of file From ac41a7fe844b3d60a217de41094ed2d83725b3b9 Mon Sep 17 00:00:00 2001 From: Patrick Keenum <5631043+prof197@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:22:27 -0500 Subject: [PATCH 2/4] support encryption in node and browser --- package.json | 3 +++ src/index.js | 8 +++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0969f3e..5d79756 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,9 @@ "import": "./build/index.js", "require": "./build/index.cjs" }, + "browser": { + "crypto": false + }, "files": [ "build/*" ], diff --git a/src/index.js b/src/index.js index 55fd08c..2695f4b 100644 --- a/src/index.js +++ b/src/index.js @@ -41,13 +41,11 @@ import starknetAddresses from './contracts/starknet_addresses.json' assert { typ import starknetContracts from './contracts/starknet_abis.json' assert { type: 'json' }; (async function() { - const isNode = typeof process !== 'undefined' && - process.versions != null && - process.versions.node != null; + const isNode = process?.versions?.node != null; if (isNode && !globalThis.crypto) { const { webcrypto } = await import('crypto'); - if (!globalThis.crypto) { - globalThis.crypto = webcrypto; + if (webcrypto) { + globalThis.crypto = webcrypto; } } })(); From 9ca3fc8ec5e0703e9daf15f72f2e7b620cb5979f Mon Sep 17 00:00:00 2001 From: Patrick Keenum <5631043+prof197@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:45:06 -0500 Subject: [PATCH 3/4] encryption updates --- src/index.js | 2 +- src/lib/system.js | 16 ++++++++++------ src/utils/encryption.js | 22 ++++++++++------------ test/utils/encryption.spec.js | 30 +++++++++++++++++------------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/index.js b/src/index.js index 2695f4b..0627a70 100644 --- a/src/index.js +++ b/src/index.js @@ -41,7 +41,7 @@ import starknetAddresses from './contracts/starknet_addresses.json' assert { typ import starknetContracts from './contracts/starknet_abis.json' assert { type: 'json' }; (async function() { - const isNode = process?.versions?.node != null; + const isNode = typeof process !== 'undefined' && !!process?.versions?.node; if (isNode && !globalThis.crypto) { const { webcrypto } = await import('crypto'); if (webcrypto) { diff --git a/src/lib/system.js b/src/lib/system.js index 0ae0b36..5feb85b 100644 --- a/src/lib/system.js +++ b/src/lib/system.js @@ -14,7 +14,8 @@ const parseCairoType = (cairoType) => { let type; if (['influence::common::types::entity::Entity'].includes(cairoType)) type = 'Entity'; else if (['core::starknet::contract_address::ContractAddress'].includes(cairoType)) type = 'ContractAddress'; - else if (['core::integer::u64', 'core::integer::u128', 'core::integer::u256'].includes(cairoType)) type = 'BigNumber'; + else if (['core::integer::u64', 'core::integer::u128'].includes(cairoType)) type = 'BigNumber'; + else if (['core::integer::u256'].includes(cairoType)) type = 'u256'; else if (['influence::common::types::string::String', 'core::felt252'].includes(cairoType)) type = 'String'; else if (['influence::common::types::inventory_item::InventoryItem'].includes(cairoType)) type = 'InventoryItem'; else if (['influence::interfaces::escrow::Withdrawal'].includes(cairoType)) type = 'Withdrawal'; @@ -101,9 +102,12 @@ const formatSystemCalldata = (name, vars, limitToVars = false) => { (isArray ? vars[name] : [vars[name]]).forEach((v) => { const formattedVar = formatCalldataValue(type, v); try { - (Array.isArray(formattedVar) ? formattedVar : [formattedVar]).forEach((val) => { - acc.push(val); - }); + let parts; + if (Array.isArray(formattedVar)) parts = formattedVar; + else if (typeof formattedVar === 'object') parts = Object.values(formattedVar); + else parts = [formattedVar]; + + parts.forEach((val) => acc.push(val)); } catch (e) { console.error(`${name} could not be formatted`, vars[name], e); } @@ -130,7 +134,7 @@ const getApproveErc20Call = (amount, erc20Address, dispatcherAddress) => getForm 'approve', [ { value: dispatcherAddress, type: 'ContractAddress' }, - { value: amount, type: 'Ether' } + { value: amount, type: 'u256' } ] ); @@ -139,7 +143,7 @@ const getEscrowDepositCall = (amount, depositHook, withdrawHook, escrowAddress, 'deposit', [ { value: swayAddress, type: 'ContractAddress' }, - { value: amount, type: 'Ether' }, // using Ether b/c should match u256 + { value: amount, type: 'u256' }, { value: withdrawHook, type: 'EscrowHook' }, { value: depositHook, type: 'EscrowHook' } ] diff --git a/src/utils/encryption.js b/src/utils/encryption.js index 9edc943..032af13 100644 --- a/src/utils/encryption.js +++ b/src/utils/encryption.js @@ -20,18 +20,18 @@ export function generateSeed() { return Array.from(array).map(byte => byte.toString(16).padStart(2, '0')).join(''); } -export function publicKeyToMessageKeys(publicKey) { +export function publicKeyToMessagingKeys(publicKey) { if (publicKey?.length === 130) { return { - message_key_x: BigInt(`0x${publicKey.substr(2, 64)}`), - message_key_y: BigInt(`0x${publicKey.substr(66)}`), + messaging_key_x: BigInt(`0x${publicKey.substr(2, 64)}`), + messaging_key_y: BigInt(`0x${publicKey.substr(66)}`), }; } } -export function messageKeysToPublicKey({ message_key_x, message_key_y }) { - if (message_key_x && message_key_y) { - return `04${BigInt(message_key_x).toString(16).padStart(64, '0')}${BigInt(message_key_y).toString(16).padStart(64, '0')}`; +export function messagingKeysToPublicKey({ messaging_key_x, messaging_key_y }) { + if (messaging_key_x && messaging_key_y) { + return `04${BigInt(messaging_key_x).toString(16).padStart(64, '0')}${BigInt(messaging_key_y).toString(16).padStart(64, '0')}`; } return null; } @@ -106,18 +106,16 @@ export async function encryptContent(recipientPublicKeyHex, message) { const encryptedBytes = new Uint8Array(encryptedBuffer); // Return encrypted data: ephemeralPublicKey, iv, encryptedMessage - const payload = { + return { ephemeralPublicKey: bytesToHex(ephemeralPublicKey), iv: bytesToHex(iv), encryptedMessage: bytesToHex(encryptedBytes), }; - - return btoa(JSON.stringify(payload)); } // Function to decrypt message export async function decryptContent(privateKey, encryptedData) { - const { ephemeralPublicKey, iv, encryptedMessage } = JSON.parse(atob(encryptedData)); + const { ephemeralPublicKey, iv, encryptedMessage } = encryptedData; // Convert data from hex to Uint8Array const ephemeralPublicKeyBytes = hexToBytes(ephemeralPublicKey); @@ -160,8 +158,8 @@ export default { generateSeed, generatePrivateKeyFromSeed, getPublicKeyFromPrivateKey, - publicKeyToMessageKeys, - messageKeysToPublicKey, + publicKeyToMessagingKeys, + messagingKeysToPublicKey, encryptContent, decryptContent, } \ No newline at end of file diff --git a/test/utils/encryption.spec.js b/test/utils/encryption.spec.js index d04fbb0..ef18fb8 100644 --- a/test/utils/encryption.spec.js +++ b/test/utils/encryption.spec.js @@ -4,12 +4,16 @@ import { Encryption } from '../../src/index.js'; const sampleSeed = '2a1ded6e8f66bc48e5872bf9105e80046300308962fe51f0b611f2af6bab60ea'; const samplePrivateKey = '0x0550aeb48829403d98e3ba904acc0217e6dfbd009f0b5ad98569c4b61e373309'; const samplePublicKey = '0404fa8d30182b0f62618a481bf4afb14b815057570a028355fae8da22969840f6042a3c380981faa3ae8e95406ab898b91f124f7f7aced5f3ec4746b99e529c95'; -const sampleMessageKeys = { - message_key_x: 2251937603385208024268746691711293108925510072271936097377258983003822506230n, - message_key_y: 1883874586592859398548265238594790780856956796067331763265145999321206004885n +const sampleMessagingKeys = { + messaging_key_x: 2251937603385208024268746691711293108925510072271936097377258983003822506230n, + messaging_key_y: 1883874586592859398548265238594790780856956796067331763265145999321206004885n }; const sampleDecryptedMessage = 'Hello, world!'; -const sampleEncryptedMessage = 'eyJlcGhlbWVyYWxQdWJsaWNLZXkiOiIwNDA3MDU4YzFkZmM4N2NhZDIwMjkxZDQ3OWY2OWZhMDQwZWY2NjMzOGYwZjQ4OWE4OTNmNDM0NzhmZGY2YTQ2ZTIwNjkwODM4MDUzYjcxNTkxYTU0ZGM0MjU3MmExNjc1YWU5NjI3ZDE5MGQ3MjNiZGE0ZmI0MzU0MGU4ZTFhYmQzIiwiaXYiOiJhMzA4NTY1ZmM3NTFlMDRlOWE5YTU1YmYiLCJlbmNyeXB0ZWRNZXNzYWdlIjoiYTc4OTBmZjY0M2M2MjhjYTUwNmQ5NzY3MDViYjVlMDAzMzJmOTY0NzZkMzFjZmM5MTdjMDhmZjlmYSJ9'; +const sampleEncryptedMessage = { + ephemeralPublicKey: '040314053669c042458428babf66fb999d8e489399a3db7d1df9888bd0553b6c1502243a2abf82c8445a6c3b3e8c52fa435cf30554dd10c3b0d7343ed33f792124', + iv: '3cb407c88633f38b1edbf950', + encryptedMessage: '8a7b5550e7f4291a2c762c3dbfe6191b2d61952b19038c0987cef06156' +}; describe('Encryption library', function () { describe('generateSeed', function () { @@ -19,19 +23,19 @@ describe('Encryption library', function () { }); }); - describe('publicKeyToMessageKeys', function () { + describe('publicKeyToMessagingKeys', function () { it ('should convert a public key to message keys', function () { - const messageKeys = Encryption.publicKeyToMessageKeys(samplePublicKey); - expect(messageKeys).to.be.an('object').with.keys('message_key_x', 'message_key_y'); - expect(messageKeys.message_key_x).to.be.a('bigint'); - expect(messageKeys.message_key_y).to.be.a('bigint'); - expect(messageKeys).to.deep.equal(sampleMessageKeys); + const messagingKeys = Encryption.publicKeyToMessagingKeys(samplePublicKey); + expect(messagingKeys).to.be.an('object').with.keys('messaging_key_x', 'messaging_key_y'); + expect(messagingKeys.messaging_key_x).to.be.a('bigint'); + expect(messagingKeys.messaging_key_y).to.be.a('bigint'); + expect(messagingKeys).to.deep.equal(sampleMessagingKeys); }); }); - describe('messageKeysToPublicKey', function () { + describe('messagingKeysToPublicKey', function () { it ('should convert message keys to a public key', function () { - const publicKey = Encryption.messageKeysToPublicKey(sampleMessageKeys); + const publicKey = Encryption.messagingKeysToPublicKey(sampleMessagingKeys); expect(publicKey).to.be.a('string').with.lengthOf(130); expect(publicKey.slice(0, 2)).to.equal('04'); expect(publicKey).to.equal(samplePublicKey); @@ -64,7 +68,7 @@ describe('Encryption library', function () { describe('encrypt + decrypt', function () { it ('should encrypt a message', async function () { const encryptedMessage = await Encryption.encryptContent(samplePublicKey, sampleDecryptedMessage); - expect(encryptedMessage).to.be.a('string'); + expect(encryptedMessage).to.be.a('object').with.keys('ephemeralPublicKey', 'iv', 'encryptedMessage'); }); it ('should decrypt a message', async function () { From 8c6ff3298cee1e66d11cc3a543a6cdf6b4bc595b Mon Sep 17 00:00:00 2001 From: Patrick Keenum <5631043+prof197@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:46:43 -0500 Subject: [PATCH 4/4] bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d05ba58..d28792c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@influenceth/sdk", - "version": "2.3.3", + "version": "2.3.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@influenceth/sdk", - "version": "2.3.3", + "version": "2.3.6", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@influenceth/astro": "^0.2.6", diff --git a/package.json b/package.json index 5d79756..56b869d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@influenceth/sdk", - "version": "2.3.3", + "version": "2.3.6", "description": "Influence SDK", "type": "module", "module": "./build/index.js",