]> git.codecow.com Git - libnemo.git/commitdiff
Fix account derivation. Start extracting types to bespoke type definition file.
authorChris Duncan <chris@zoso.dev>
Tue, 15 Jul 2025 19:36:05 +0000 (12:36 -0700)
committerChris Duncan <chris@zoso.dev>
Tue, 15 Jul 2025 19:36:05 +0000 (12:36 -0700)
16 files changed:
package.json
src/lib/account.ts
src/lib/blake2b.ts
src/lib/rolodex.ts
src/lib/wallets/bip44-wallet.ts
src/lib/wallets/blake2b-wallet.ts
src/lib/wallets/index.ts
src/lib/wallets/ledger-wallet.ts
src/lib/wallets/wallet.ts
src/lib/workers/bip44-ckd.ts
src/lib/workers/index.ts
src/lib/workers/nano-nacl.ts
src/lib/workers/queue.ts
src/lib/workers/safe.ts
src/lib/workers/worker-interface.ts
src/types.d.ts [new file with mode: 0644]

index e166e5070161cf61c48abc6133b8c9195ae72e51..186d89de9f80cc3c4d9caaf2de734ee2f39207ab 100644 (file)
@@ -54,6 +54,7 @@
        "imports": {
                "#dist/*": "./dist/*",
                "#src/*": "./src/*",
+               "#types": "./src/types.d.ts",
                "#workers": "./src/lib/workers/index.js"
        },
        "dependencies": {
index afeb38bb380e7e97d91f1edd1147db499dc8a5fa..e9706f74850fbf4794b6dccf5e9a4c20f5f2f405 100644 (file)
@@ -137,10 +137,10 @@ export class Account {
                                method: 'convert'\r
                        }\r
                        const data = {\r
-                               privateKey: privateKey.buffer\r
+                               privateKey: new Uint8Array(privateKey).buffer\r
                        }\r
                        const result = await NanoNaClWorker.add(headers, data)\r
-                       publicKey = bytes.toHex(new Uint8Array(result.publicKey))\r
+                       publicKey = result[0]\r
                } catch (err) {\r
                        throw new Error(`Failed to derive public key from private key`, { cause: err })\r
                }\r
@@ -242,6 +242,7 @@ export class Account {
                        if (id == null || id !== this.#pub) {\r
                                throw null\r
                        }\r
+                       debugger\r
                        this.#prv.set(obj.toBytes(privateKey))\r
                } catch (err) {\r
                        console.error(`Failed to unlock account ${this.address}`, err)\r
index 46228135a2c54410e4db47385eb0d55a83705800..b9e25dfcfbec1cfb3244186b880b566a61127a1f 100644 (file)
@@ -1,6 +1,8 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later AND ISC
 
+import { UnknownNumber, UnknownUint8Array } from "#types"
+
 /**
 * Implementation derived from blake2b@2.1.4. Copyright 2017 Emil Bay
 * <github@tixz.dk> (https://github.com/emilbayes/blake2b). See LICENSES/ISC.txt
@@ -11,9 +13,6 @@
 * Original source commit: https://github.com/emilbayes/blake2b/blob/1f63e02e3f226642959506cdaa67c8819ff145cd/index.js
 */
 
-type UnknownNumber = number | unknown
-type UnknownUint8Array = Uint8Array | unknown
-
 export class Blake2b {
        static get OUTBYTES_MIN (): 1 { return 1 }
        static get OUTBYTES_MAX (): 64 { return 64 }
index 203f4a27bbbc68b0c545d90a9b94ff7156f7f59c..aa72f70072951909e9701cc77413bae2e3d950e6 100644 (file)
@@ -3,7 +3,8 @@
 
 import { Account } from './account'
 
-type RolodexEntry = {
+
+export type RolodexEntry = {
        name: string
        account: Account
 }
index 3a49d34d03afd59530287913c8c88160a9b6fbc1..69a231623987f8c876370018a3e573425c63d623 100644 (file)
@@ -1,11 +1,12 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>\r
 // SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
-import { KeyPair, Wallet } from '.'\r
+import { Wallet } from '.'\r
 import { Bip39Mnemonic } from '#src/lib/bip39-mnemonic.js'\r
 import { SEED_LENGTH_BIP44 } from '#src/lib/constants.js'\r
-import { hex, utf8 } from '#src/lib/convert.js'\r
+import { bytes, hex, utf8 } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
+import { KeyPair } from '#types'\r
 import { Bip44CkdWorker } from '#workers'\r
 \r
 /**\r
@@ -216,11 +217,14 @@ export class Bip44Wallet extends Wallet {
                const data = {\r
                        seed: hex.toBytes(this.seed).buffer\r
                }\r
-               const privateKeys: KeyPair[] = await Bip44CkdWorker.add(headers, data)\r
-               for (let i = 0; i < privateKeys.length; i++) {\r
-                       if (privateKeys[i].privateKey == null) {\r
+               const results = (await Bip44CkdWorker.add(headers, data))[0]\r
+               const privateKeys: KeyPair[] = []\r
+               for (const i of Object.keys(results)) {\r
+                       if (results[i] == null || !(results[i] instanceof ArrayBuffer)) {\r
                                throw new Error('Failed to derive private keys')\r
                        }\r
+                       const keyBytes = new Uint8Array(results[i])\r
+                       privateKeys.push({ index: +i, privateKey: bytes.toHex(keyBytes) })\r
                }\r
                return privateKeys\r
        }\r
index 462750dfc45026ee9d6aa9491f983012d3d42b29..178d47435162b083eef7815987ec85812b1911d2 100644 (file)
@@ -1,12 +1,13 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>\r
 // SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
-import { KeyPair, Wallet } from '.'\r
+import { Wallet } from '.'\r
 import { Bip39Mnemonic } from '#src/lib/bip39-mnemonic.js'\r
 import { Blake2b } from '#src/lib/blake2b.js'\r
 import { SEED_LENGTH_BLAKE2B } from '#src/lib/constants.js'\r
-import { bytes, hex, utf8 } from '#src/lib/convert.js'\r
+import { hex, utf8 } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
+import { KeyPair } from '#types'\r
 \r
 /**\r
 * BLAKE2b wallet created by deriving a mnemonic phrase from a seed or vice\r
index 24452fb206a5ed842410cd3922ea77262bccf44e..d1bc77c6099bc7ee24044eb4aba9a98145d728f7 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>\r
 // SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
-export type { KeyPair } from './wallet'\r
 export { Wallet } from './wallet'\r
 export { Bip44Wallet } from './bip44-wallet'\r
 export { Blake2bWallet } from './blake2b-wallet'\r
index 24016595e048fa512324fe1267c710e93f5dd24f..feb05459c6ec400d0bc09615a05f9b7c71fe4277 100644 (file)
@@ -5,12 +5,13 @@ import { ledgerUSBVendorId } from '@ledgerhq/devices'
 import { default as TransportBLE } from '@ledgerhq/hw-transport-web-ble'\r
 import { default as TransportUSB } from '@ledgerhq/hw-transport-webusb'\r
 import { default as TransportHID } from '@ledgerhq/hw-transport-webhid'\r
-import { KeyPair, Wallet } from '.'\r
+import { Wallet } from '.'\r
 import { ChangeBlock, ReceiveBlock, SendBlock } from '#src/lib/block.js'\r
 import { BIP44_COIN_NANO, BIP44_PURPOSE, HARDENED_OFFSET, LEDGER_ADPU_CODES, LEDGER_STATUS_CODES } from '#src/lib/constants.js'\r
 import { bytes, dec, hex } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
 import { Rpc } from '#src/lib/rpc.js'\r
+import { KeyPair } from '#types'\r
 \r
 type DeviceStatus = 'DISCONNECTED' | 'BUSY' | 'LOCKED' | 'CONNECTED'\r
 \r
index 4834b5a56c15d643b5a4755cb071482f72f81730..fec4e39a37a3ebbca3ab10437f54da3375e921c3 100644 (file)
@@ -7,13 +7,8 @@ import { ADDRESS_GAP } from '#src/lib/constants.js'
 import { bytes, utf8 } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
 import { Rpc } from '#src/lib/rpc.js'\r
-import { Data, SafeWorker } from '#workers'\r
-\r
-export type KeyPair = {\r
-       publicKey?: string,\r
-       privateKey?: string,\r
-       index?: number\r
-}\r
+import { Data, KeyPair } from '#types'\r
+import { SafeWorker } from '#workers'\r
 \r
 /**\r
 * Represents a wallet containing numerous Nano accounts derived from a single\r
index 9b212c0f04d359181750c1456cdbd4d50911aeff..d5dd65c10edeba0f66c1d194c7c4084c24bab38e 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-import { Data, Headers } from '.'
 import { WorkerInterface } from './worker-interface'
+import { Data, Headers } from '#types'
 
 type ExtendedKey = {
        privateKey: DataView<ArrayBuffer>
@@ -19,21 +19,21 @@ export class Bip44Ckd extends WorkerInterface {
                Bip44Ckd.listen()
        }
 
-       static async work (headers: Headers, data: Data): Promise<any[]> {
+       static async work (headers: Headers, data: Data): Promise<Data> {
                let { coin, indexes } = headers
                let { seed } = data
                if (coin != null && (typeof coin !== 'number' || !Number.isInteger(coin))) {
                        throw new TypeError('BIP-44 coin derivation level must be an integer')
                }
                if (!Array.isArray(indexes)) indexes = [indexes]
-               const privateKeys: ArrayBuffer[] = []
+               const privateKeys: Data = {}
                for (const i of indexes) {
                        if (typeof i !== 'number' || !Number.isInteger(i)) {
                                throw new TypeError('BIP-44 account derivation level must be an integer')
                        }
                        try {
                                const pk = await this.ckd(seed, coin, i)
-                               privateKeys.push(pk)
+                               privateKeys[i] = pk
                        } catch (err) {
                                console.log(err)
                        }
index e4143f0185ece6d7bf292a894c7559aa100da204..e3631710dcfabd23dc97030a136ca1af0a19348c 100644 (file)
@@ -1,12 +1,4 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-export type Data = {
-       [key: string]: ArrayBuffer
-}
-
-export type Headers = {
-       [key: string]: any
-}
-
 export { Bip44CkdWorker, NanoNaClWorker, SafeWorker } from './queue'
index b90a64423d3116dde70cb6712116f1f4c3ce3f12..8edf1f933cd5a71af907d0c29393a82dbafb6d72 100644 (file)
@@ -3,10 +3,10 @@
 \r
 'use strict'\r
 \r
-import { Data, Headers } from '.'\r
 import { WorkerInterface } from './worker-interface'\r
 import { Blake2b } from '#src/lib/blake2b.js'\r
 import { default as Convert, bytes, hex } from '#src/lib/convert.js'\r
+import { Data, Headers } from '#types'\r
 \r
 /**\r
 * Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\r
index 09b3f2aaa67060e8abe0c7dbb228dccbccf754bd..d8a6d262d2fcf30d2a2566b5df0e0474dd410d8f 100644 (file)
@@ -1,10 +1,10 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-import { Data, Headers } from '.'
 import { default as bip44 } from './bip44-ckd'
 import { default as nacl } from './nano-nacl'
 import { default as safe } from './safe'
+import { Data, Headers } from '#types'
 
 type Task = {
        id: number
index ece1735b749ea42aba8f2c05869fe28bda14bd49..2bb00c56b4c399d06fa77898069071c0cc2a5237 100644 (file)
@@ -3,15 +3,10 @@
 
 'use strict'
 
-import { Data, Headers } from '.'
 import { WorkerInterface } from './worker-interface'
 import { default as Convert, bytes } from '#src/lib/convert.js'
 import { Entropy } from '#src/lib/entropy.js'
-
-type SafeRecord = {
-       iv: string
-       data: Data
-}
+import { Data, Headers, SafeRecord } from '#types'
 
 /**
 * Encrypts and stores data in the browser using IndexedDB.
index 5fa056064cddd000805f19d5d20c65eccc3b62ae..c9157608c62f04b8dec240c68a7cd55e9a19adc5 100644 (file)
@@ -1,7 +1,8 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-import { Data, Headers } from '.'
+import { Data, Headers } from '#types'
+
 /**
 * Provides basic worker event messaging to extending classes.
 *
diff --git a/src/types.d.ts b/src/types.d.ts
new file mode 100644 (file)
index 0000000..7a360ae
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+export type Data = {
+       [key: string]: ArrayBuffer
+}
+
+export type Headers = {
+       [key: string]: any
+}
+
+export type KeyPair = {
+       publicKey?: string,
+       privateKey?: string,
+       index?: number
+}
+
+export type SafeRecord = {
+       iv: string
+       data: Data
+}
+
+export type UnknownNumber = number | unknown
+
+export type UnknownUint8Array = Uint8Array | unknown