From 73ad8deb45e97c9a18d303ef6197d14d83137688 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Sat, 30 Aug 2025 00:32:14 -0700 Subject: [PATCH] Simplify promise chain. --- src/lib/crypto/bip44.ts | 54 +++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/lib/crypto/bip44.ts b/src/lib/crypto/bip44.ts index 8042068..deb200c 100644 --- a/src/lib/crypto/bip44.ts +++ b/src/lib/crypto/bip44.ts @@ -29,39 +29,25 @@ export class Bip44 { if (!Number.isSafeInteger(account) || account < 0 || account > 0x7fffffff) { throw new RangeError(`Invalid account index 0x${account.toString(16)}`) } - if (change != null && (!Number.isSafeInteger(change) || change < 0 || change > 1)) { + if (change !== undefined && (!Number.isSafeInteger(change) || change < 0 || change > 1)) { throw new RangeError(`Invalid change index 0x${account.toString(16)}`) } - if (address != null && (!Number.isSafeInteger(address) || address < 0 || address > 0x7fffffff)) { + if (address !== undefined && (!Number.isSafeInteger(address) || address < 0 || address > 0x7fffffff)) { throw new RangeError(`Invalid address index 0x${account.toString(16)}`) } - return this.#slip10(SLIP10_ED25519, seed) - .then(masterKey => { - return this.#CKDpriv(masterKey, BIP44_PURPOSE + HARDENED_OFFSET) - .then(purposeKey => { - return this.#CKDpriv(purposeKey, coin + HARDENED_OFFSET) - .then(coinKey => { - return this.#CKDpriv(coinKey, account + HARDENED_OFFSET) - .then(accountKey => { - if (change == null) return accountKey.privateKey - return this.#CKDpriv(accountKey, change + HARDENED_OFFSET) - .then(chainKey => { - if (address == null) return chainKey.privateKey - return this.#CKDpriv(chainKey, address + HARDENED_OFFSET) - .then(addressKey => { - return addressKey.privateKey - }) - }) - }) - }) - }) - }) + return this.slip10(SLIP10_ED25519, seed) + .then(masterKey => this.CKDpriv(masterKey, BIP44_PURPOSE)) + .then(purposeKey => this.CKDpriv(purposeKey, coin)) + .then(coinKey => this.CKDpriv(coinKey, account)) + .then(accountKey => this.CKDpriv(accountKey, change)) + .then(chainKey => this.CKDpriv(chainKey, address)) + .then(addressKey => addressKey.privateKey) } - static #slip10 (curve: string, S: ArrayBuffer): Promise { + static slip10 (curve: string, S: ArrayBuffer): Promise { const key = new Uint8Array(new TextEncoder().encode(curve)) const data = new Uint8Array(S) - return this.#hmac(key, data) + return this.hmac(key, data) .then(I => { const IL = I.slice(0, I.byteLength / 2) const IR = I.slice(I.byteLength / 2) @@ -69,13 +55,17 @@ export class Bip44 { }) } - static #CKDpriv ({ privateKey, chainCode }: ExtendedKey, index: number): Promise { + static CKDpriv ({ privateKey, chainCode }: ExtendedKey, index?: number): Promise { + if (index === undefined) { + return Promise.resolve({ privateKey, chainCode }) + } + index += HARDENED_OFFSET const key = new Uint8Array(chainCode) const data = new Uint8Array(37) data.set([0]) - data.set(this.#ser256(privateKey), 1) - data.set(this.#ser32(index), 33) - return this.#hmac(key, data) + data.set(this.ser256(privateKey), 1) + data.set(this.ser32(index), 33) + return this.hmac(key, data) .then(I => { const IL = I.slice(0, I.byteLength / 2) const IR = I.slice(I.byteLength / 2) @@ -83,17 +73,17 @@ export class Bip44 { }) } - static #ser32 (integer: number): Uint8Array { + static ser32 (integer: number): Uint8Array { const view = new DataView(new ArrayBuffer(4)) view.setUint32(0, integer, false) return new Uint8Array(view.buffer) } - static #ser256 (integer: ArrayBuffer): Uint8Array { + static ser256 (integer: ArrayBuffer): Uint8Array { return new Uint8Array(integer) } - static #hmac (key: Uint8Array, data: Uint8Array): Promise { + static hmac (key: Uint8Array, data: Uint8Array): Promise { return crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign']) .then(pk => { return crypto.subtle.sign('HMAC', pk, data) -- 2.47.3