diff --git a/package-lock.json b/package-lock.json index 485e361..0a6f833 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1511,6 +1511,84 @@ "ws": "*" } }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", @@ -5087,6 +5165,16 @@ "node": ">=4" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detective-amd": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.0.tgz", @@ -8922,6 +9010,37 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, "node_modules/multimatch": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", @@ -9072,6 +9191,21 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/isexe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", @@ -12901,7 +13035,8 @@ "@electrum-cash/network": "^4.1.1", "@electrum-cash/protocol": "2.1.0-development.8075178089", "@xocash/primitives": "*", - "idb": "^8.0.0" + "idb": "^8.0.0", + "msgpackr": "^1.11.2" } } } diff --git a/packages/stack/package.json b/packages/stack/package.json index d6c90f0..3f34141 100644 --- a/packages/stack/package.json +++ b/packages/stack/package.json @@ -35,6 +35,7 @@ "@electrum-cash/network": "^4.1.1", "@electrum-cash/protocol": "2.1.0-development.8075178089", "@xocash/primitives": "*", - "idb": "^8.0.0" + "idb": "^8.0.0", + "msgpackr": "^1.11.2" } } diff --git a/packages/stack/src/blockchain/blockchain-electrum.ts b/packages/stack/src/blockchain/blockchain-electrum.ts index 4ccd83e..225d45c 100644 --- a/packages/stack/src/blockchain/blockchain-electrum.ts +++ b/packages/stack/src/blockchain/blockchain-electrum.ts @@ -224,23 +224,13 @@ export class BlockchainElectrum extends BaseBlockchain { const cacheKey = `transactions.${txHash}`; // Attempt to get the transaction hex from the cache or fetch it if not available. - const transactionHex = await this.store.getOrSet(cacheKey, async () => { - return await fetchTransaction(this.electrumClient, txHash); + const transactionRaw = await this.store.getOrSet(cacheKey, async () => { + const txHex = await fetchTransaction(this.electrumClient, txHash); + return Transaction.fromHex(txHex).toRaw(); }); // Decode the hex into our transaction primitive. - const transaction = Transaction.fromHex(transactionHex); - - // Attempt to get the transaction hex from the cache or fetch it if not available. - // NOTE: We store JSON as opposed to hex because it is MUCH faster to decode. - /* - const transaction = new Transaction( - await this.store.getOrSet(cacheKey, async () => { - const tx = await fetchTransaction(this.electrumClient, txHash); - return Transaction.fromHex(tx).transaction; - }), - ); - */ + const transaction = Transaction.fromRaw(transactionRaw); // Return the transaction hex. return transaction; diff --git a/packages/stack/src/storage/store-indexeddb.ts b/packages/stack/src/storage/store-indexeddb.ts index e6267bd..e21401b 100644 --- a/packages/stack/src/storage/store-indexeddb.ts +++ b/packages/stack/src/storage/store-indexeddb.ts @@ -3,10 +3,10 @@ import { StoreInMemorySynced } from './store-inmemory-synced.js'; import { Encrypter } from '../utils'; -import { - encodeExtendedJsonObject, - decodeExtendedJsonObject, -} from '@xocash/primitives'; +// TODO: Only use pack/unpack on encrypted content. +// Unsure why you were doing it on non-encrypted content (as it's not needed for IDB). +// Did you bump into an object that couldn't be structuredClone'd? +import { pack, unpack } from 'msgpackr'; import { openDB, deleteDB, IDBPDatabase } from 'idb'; @@ -156,7 +156,7 @@ export class StoreIndexedDB extends BaseStore { return keys.reduce( (acc, key, index) => { - acc[key.toString()] = decodeExtendedJsonObject(values[index]); + acc[key.toString()] = unpack(values[index]); return acc; }, {} as { [key: string]: T }, @@ -177,11 +177,11 @@ export class StoreIndexedDB extends BaseStore { ? this.encryption.decrypt(encodedValue) : encodedValue; - return decodeExtendedJsonObject(decryptedValue) as T; + return unpack(decryptedValue) as T; } async set(key: string, value: T) { - const encodedValue = encodeExtendedJsonObject(value); + const encodedValue = pack(value); const encryptedValue = this.encryption ? this.encryption.encrypt(encodedValue) @@ -203,10 +203,7 @@ export class StoreIndexedDB extends BaseStore { const results = await Promise.all( keys.map(async (key) => { const value = await store.get(key); - return [ - key, - value ? decodeExtendedJsonObject(value) : undefined, - ] as const; + return [key, value ? unpack(value) : undefined] as const; }), ); @@ -223,7 +220,7 @@ export class StoreIndexedDB extends BaseStore { await Promise.all( Array.from(items).map(([key, value]) => { - const encodedValue = encodeExtendedJsonObject(value); + const encodedValue = pack(value); return store.put(encodedValue, key); }), ); diff --git a/packages/stack/src/wallet/wallet-hd.ts b/packages/stack/src/wallet/wallet-hd.ts index 8ad4156..66db1d0 100644 --- a/packages/stack/src/wallet/wallet-hd.ts +++ b/packages/stack/src/wallet/wallet-hd.ts @@ -1,4 +1,3 @@ -// Import the Stamp class to derive the private keys import { BaseWallet } from './base-wallet.js'; import { type TransactionTemplate } from './types.js'; import { TransactionBuilder } from './transaction-builder.js'; @@ -106,7 +105,7 @@ export class WalletHD< this.wallets[CHAIN_INTERNAL] = []; // Initialize proxies to our stored data. - this.genesisData = this.store.proxy('genesisData'); + this.genesisData = this.store.proxy('genesis'); } static async from(