]> git.codecow.com Git - libnemo.git/commitdiff
Transfer account indexes to vault worker as typed array.
authorChris Duncan <chris@codecow.com>
Sat, 8 Aug 2026 05:10:20 +0000 (22:10 -0700)
committerChris Duncan <chris@codecow.com>
Sat, 8 Aug 2026 05:10:20 +0000 (22:10 -0700)
src/lib/vault/parsers.ts
src/lib/vault/vault-worker.ts
src/lib/wallet/accounts.ts

index f910e5bebd95ecb41601e55ba248facd793e2896..dc0705ff4c1c9e688bdd87cc874e31589e2b11e3 100644 (file)
@@ -82,19 +82,11 @@ export function parseData (action: string, data: Record<string, unknown>) {
                }
 
                // Index for child account to derive or sign
-               if ((action === 'derive' || action === 'sign') && typeof data.index !== 'number') {
+               if ((action === 'derive' || action === 'sign') && !(data.indexes instanceof ArrayBuffer)) {
                        throw new TypeError('Index is required to derive an account private key')
                }
-               const index = typeof data.index === 'number'
-                       ? data.index
-                       : undefined
-
-               // Number of public keys to derive
-               if (action === 'derive' && (typeof data.count !== 'number' || data.count < 1)) {
-                       throw new TypeError('Count is required to derive a batch of keys')
-               }
-               const count = typeof data.count === 'number'
-                       ? data.count
+               const indexes = typeof data.indexes instanceof ArrayBuffer
+                       ? new Uint32Array(data.index)
                        : undefined
 
                // Data to sign
index 6363247be4d7162aa47de983de0523f9c04e9074..028bbe2a6b9b416ffa9b7a95ff17448c59752df6 100644 (file)
@@ -40,7 +40,7 @@ const listener = (event: MessageEvent<any>): void => {
        const id = parseId(action, data)
        const iv = parseIv(action, data)
        const parsed = parseData(action, data)
-       const { seed, mnemonicPhrase, mnemonicSalt, index, count, encrypted, message, timeout } = parsed
+       const { seed, mnemonicPhrase, mnemonicSalt, indexes, encrypted, message, timeout } = parsed
        passkey(action, keySalt, data)
                .then((key: CryptoKey | undefined): Promise<Record<string, boolean | number | ArrayBuffer> | void> => {
                        switch (action) {
@@ -56,7 +56,7 @@ const listener = (event: MessageEvent<any>): void => {
                                        return create(type, id, key, keySalt, mnemonicSalt)
                                }
                                case 'derive': {
-                                       return derive(index, count)
+                                       return derive(indexes)
                                }
                                case 'load': {
                                        return load(type, id, key, keySalt, mnemonicPhrase ?? seed, mnemonicSalt)
@@ -170,7 +170,7 @@ function create (type?: WalletType, id?: UUID, key?: CryptoKey, keySalt?: ArrayB
  * wallet seed at a specified index and then returns the public key. The wallet
  * must be unlocked prior to derivation.
  */
-function derive (index?: number, count?: number): Promise<Record<string, number | ArrayBuffer>> {
+function derive (indexes?: Uint32Array): Promise<Record<string, number | ArrayBuffer>> {
        try {
                _timer.pause()
                if (_locked) {
@@ -182,18 +182,12 @@ function derive (index?: number, count?: number): Promise<Record<string, number
                if (_type !== 'BIP-44' && _type !== 'BLAKE2b' && _type !== 'Exodus') {
                        throw new Error('Invalid wallet type')
                }
-               if (typeof index !== 'number' || index < 0) {
-                       throw new Error('Invalid wallet account index')
-               }
-               if (typeof count !== 'number' || count < 1) {
-                       throw new Error('Invalid wallet account batch size')
-               }
-               const max = index + count
-               if (max > (_type === 'BLAKE2b' ? 0xffffffff : 0x7fffffff)) {
-                       throw new Error('Wallet account range exceeded ')
+               if (indexes == null) {
+                       throw new Error('Invalid wallet account index(es)')
                }
                const promises = []
-               for (let i = index; i < max; i++) {
+               const values = indexes.values()
+               for (const index of values) {
                        promises.push(_ckd(index).then(result => {
                                const prv = new Uint8Array(result)
                                const pub = nano25519_derive(prv)
index 1a74fd64640c2eab3fa60cca2f383acb929f8092..0ec8d86805c0da32742c002d3eb5a5fca75bdf41 100644 (file)
@@ -25,18 +25,18 @@ export async function _accounts (type: WalletType, accounts: Map<number, Account
                console.warn('libnemo performance may degrade when deriving many accounts at once')
        }
        const output = new Map<number, Account>()
-       const indexes: number[] = []
+       const missing: number[] = []
        for (let i = from; i <= to; i++) {
                const account = accounts.get(i)
                if (account == null) {
-                       indexes.push(i)
+                       missing.push(i)
                } else {
                        output.set(i, account)
                }
        }
-       if (indexes.length > 0) {
+       if (missing.length > 0) {
                if (type === 'Ledger') {
-                       for (const index of indexes) {
+                       for (const index of missing) {
                                const { status, publicKey } = await Ledger.account(index)
                                if (status !== 'OK' || publicKey == null) {
                                        throw new Error(`Error getting Ledger account: ${status}`)
@@ -46,20 +46,10 @@ export async function _accounts (type: WalletType, accounts: Map<number, Account
                                accounts.set(index, account)
                        }
                } else {
-                       // const promises = []
-                       // for (const index of indexes) {
-                       //      promises.push(vault.request<number | ArrayBuffer>({
-                       //              action: 'derive',
-                       //              index
-                       //      }))
-                       // }
-                       // const publicKeys = await Promise.all(promises)
-                       const min = Math.min(...indexes)
-                       const count = Math.max(...indexes) - min + 1
+                       const indexes = new Uint32Array(missing).buffer
                        const publicKeys = await vault.request<ArrayBuffer>({
                                action: 'derive',
-                               index: min,
-                               count
+                               indexes
                        })
                        console.log(publicKeys)
                        for (const [index, publicKey] of Object.entries(publicKeys)) {