From: Chris Duncan Date: Sat, 13 Sep 2025 05:27:22 +0000 (-0700) Subject: Fix restored wallets with undefined type. X-Git-Tag: v0.10.5~20^2~1 X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=1e6c040709c004edf423179c49cdce4f6ca226f9;p=libnemo.git Fix restored wallets with undefined type. --- diff --git a/src/lib/vault/vault-worker.ts b/src/lib/vault/vault-worker.ts index 2f4efb8..c254b3b 100644 --- a/src/lib/vault/vault-worker.ts +++ b/src/lib/vault/vault-worker.ts @@ -223,7 +223,7 @@ export class VaultWorker { /** * Decrypts the input and sets the seed and, if it is included, the mnemonic. */ - static async unlock (type?: string, key?: CryptoKey, iv?: ArrayBuffer, encrypted?: ArrayBuffer): Promise> { + static async unlock (type?: 'BIP-44' | 'BLAKE2b', key?: CryptoKey, iv?: ArrayBuffer, encrypted?: ArrayBuffer): Promise> { try { if (type == null) { throw new TypeError('Wallet type is required') @@ -340,10 +340,11 @@ export class VaultWorker { return await crypto.subtle.deriveKey(derivationAlgorithm, derivationKey, derivedKeyType, false, [purpose]) } - static async #decryptWallet (type: string, key: CryptoKey, iv: ArrayBuffer, encrypted: ArrayBuffer): Promise { + static async #decryptWallet (type: 'BIP-44' | 'BLAKE2b', key: CryptoKey, iv: ArrayBuffer, encrypted: ArrayBuffer): Promise { const seedLength = type === 'BIP-44' ? 64 : 32 const additionalData = utf8.toBytes(type) const decrypted = new Uint8Array(await crypto.subtle.decrypt({ name: 'AES-GCM', iv, additionalData }, key, encrypted)) + this.#type = type this.#seed = decrypted.buffer.slice(0, seedLength) this.#mnemonic = decrypted.buffer.slice(seedLength) decrypted.fill(0) diff --git a/test/test.derive-accounts.mjs b/test/test.derive-accounts.mjs index 1fee8fd..b84e84e 100644 --- a/test/test.derive-accounts.mjs +++ b/test/test.derive-accounts.mjs @@ -67,6 +67,24 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) + + await test('derive from restored BIP-44 wallet', async () => { + const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED) + const restored = await Wallet.restore(wallet.id) + await restored.unlock(NANO_TEST_VECTORS.PASSWORD) + const account = await restored.account() + + assert.equal(account.publicKey, NANO_TEST_VECTORS.PUBLIC_0) + assert.equal(account.address, NANO_TEST_VECTORS.ADDRESS_0) + assert.equal(account.index, 0) + + const accounts = await restored.accounts() + assert.exists(accounts[0]) + assert.equal(account, accounts[0]) + + await assert.resolves(wallet.destroy()) + await assert.resolves(restored.destroy()) + }) }), suite('Derive accounts from BLAKE2b wallet', async () => { @@ -121,5 +139,23 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) + + await test('derive from restored BLAKE2b wallet', async () => { + const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BLAKE2B_SEED) + const restored = await Wallet.restore(wallet.id) + await restored.unlock(NANO_TEST_VECTORS.PASSWORD) + const account = await restored.account(1) + + assert.equal(account.publicKey, NANO_TEST_VECTORS.BLAKE2B_PUBLIC_1) + assert.equal(account.address, NANO_TEST_VECTORS.BLAKE2B_ADDRESS_1) + assert.equal(account.index, 1) + + const accounts = await restored.accounts(1) + assert.exists(accounts[1]) + assert.equal(account, accounts[1]) + + await assert.resolves(wallet.destroy()) + await assert.resolves(restored.destroy()) + }) }) ]) diff --git a/test/test.lock-unlock.mjs b/test/test.lock-unlock.mjs index bca0ae1..eabbfcb 100644 --- a/test/test.lock-unlock.mjs +++ b/test/test.lock-unlock.mjs @@ -39,7 +39,7 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) - await test('fail to unlock a Bip44Wallet with different passwords', async () => { + await test('fail to unlock a BIP-44 wallet with different passwords', async () => { const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD) await wallet.unlock(NANO_TEST_VECTORS.PASSWORD) wallet.lock() @@ -62,7 +62,7 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) - await test('fail to unlock a Bip44Wallet with invalid input', async () => { + await test('fail to unlock a BIP-44 wallet with invalid input', async () => { const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD) await wallet.unlock(NANO_TEST_VECTORS.PASSWORD) @@ -74,7 +74,7 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) - await test('locking and unlocking a Blake2bWallet with a password', async () => { + await test('locking and unlocking a BLAKE2b wallet with a password', async () => { const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_0) assert.ok('mnemonic' in wallet) @@ -90,7 +90,7 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) - await test('fail to unlock a Blake2bWallet with different passwords', async () => { + await test('fail to unlock a BLAKE2b wallet with different passwords', async () => { const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1) await assert.rejects(wallet.unlock(TREZOR_TEST_VECTORS.PASSWORD), { message: 'Failed to unlock wallet' }) @@ -104,7 +104,7 @@ await Promise.all([ await assert.resolves(wallet.destroy()) }) - await test('fail to unlock a Blake2bWallet with no input', async () => { + await test('fail to unlock a BLAKE2b wallet with no input', async () => { const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1) //@ts-expect-error