]> git.codecow.com Git - libnemo.git/commitdiff
Fix restored wallets with undefined type.
authorChris Duncan <chris@zoso.dev>
Sat, 13 Sep 2025 05:27:22 +0000 (22:27 -0700)
committerChris Duncan <chris@zoso.dev>
Sat, 13 Sep 2025 05:59:41 +0000 (22:59 -0700)
src/lib/vault/vault-worker.ts
test/test.derive-accounts.mjs
test/test.lock-unlock.mjs

index 2f4efb869938f870d69bae39afc3108f470456fd..c254b3b3a8bf0ab85c07bd7fc0627db9e0273e03 100644 (file)
@@ -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<NamedData<boolean>> {
+       static async unlock (type?: 'BIP-44' | 'BLAKE2b', key?: CryptoKey, iv?: ArrayBuffer, encrypted?: ArrayBuffer): Promise<NamedData<boolean>> {
                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<void> {
+       static async #decryptWallet (type: 'BIP-44' | 'BLAKE2b', key: CryptoKey, iv: ArrayBuffer, encrypted: ArrayBuffer): Promise<void> {
                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)
index 1fee8fd04d74bad78a0d84138b9aeb2a3b2bdc8a..b84e84ecbf04438ec35364dad0c7cabf1d0a7ac4 100644 (file)
@@ -67,6 +67,24 @@ await Promise.all([
 \r
                        await assert.resolves(wallet.destroy())\r
                })\r
+\r
+               await test('derive from restored BIP-44 wallet', async () => {\r
+                       const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
+                       const restored = await Wallet.restore(wallet.id)\r
+                       await restored.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+                       const account = await restored.account()\r
+\r
+                       assert.equal(account.publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
+                       assert.equal(account.address, NANO_TEST_VECTORS.ADDRESS_0)\r
+                       assert.equal(account.index, 0)\r
+\r
+                       const accounts = await restored.accounts()\r
+                       assert.exists(accounts[0])\r
+                       assert.equal(account, accounts[0])\r
+\r
+                       await assert.resolves(wallet.destroy())\r
+                       await assert.resolves(restored.destroy())\r
+               })\r
        }),\r
 \r
        suite('Derive accounts from BLAKE2b wallet', async () => {\r
@@ -121,5 +139,23 @@ await Promise.all([
 \r
                        await assert.resolves(wallet.destroy())\r
                })\r
+\r
+               await test('derive from restored BLAKE2b wallet', async () => {\r
+                       const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BLAKE2B_SEED)\r
+                       const restored = await Wallet.restore(wallet.id)\r
+                       await restored.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+                       const account = await restored.account(1)\r
+\r
+                       assert.equal(account.publicKey, NANO_TEST_VECTORS.BLAKE2B_PUBLIC_1)\r
+                       assert.equal(account.address, NANO_TEST_VECTORS.BLAKE2B_ADDRESS_1)\r
+                       assert.equal(account.index, 1)\r
+\r
+                       const accounts = await restored.accounts(1)\r
+                       assert.exists(accounts[1])\r
+                       assert.equal(account, accounts[1])\r
+\r
+                       await assert.resolves(wallet.destroy())\r
+                       await assert.resolves(restored.destroy())\r
+               })\r
        })\r
 ])\r
index bca0ae1eefd93e2daa520ee4272211d9c8c7632f..eabbfcbd5104d87b7a71cd7a8745acb771eea3db 100644 (file)
@@ -39,7 +39,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())\r
                })\r
 \r
-               await test('fail to unlock a Bip44Wallet with different passwords', async () => {\r
+               await test('fail to unlock a BIP-44 wallet with different passwords', async () => {\r
                        const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
                        await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
                        wallet.lock()\r
@@ -62,7 +62,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())\r
                })\r
 \r
-               await test('fail to unlock a Bip44Wallet with invalid input', async () => {\r
+               await test('fail to unlock a BIP-44 wallet with invalid input', async () => {\r
                        const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
                        await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
 \r
@@ -74,7 +74,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())\r
                })\r
 \r
-               await test('locking and unlocking a Blake2bWallet with a password', async () => {\r
+               await test('locking and unlocking a BLAKE2b wallet with a password', async () => {\r
                        const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_0)\r
 \r
                        assert.ok('mnemonic' in wallet)\r
@@ -90,7 +90,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())\r
                })\r
 \r
-               await test('fail to unlock a Blake2bWallet with different passwords', async () => {\r
+               await test('fail to unlock a BLAKE2b wallet with different passwords', async () => {\r
                        const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1)\r
 \r
                        await assert.rejects(wallet.unlock(TREZOR_TEST_VECTORS.PASSWORD), { message: 'Failed to unlock wallet' })\r
@@ -104,7 +104,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())\r
                })\r
 \r
-               await test('fail to unlock a Blake2bWallet with no input', async () => {\r
+               await test('fail to unlock a BLAKE2b wallet with no input', async () => {\r
                        const wallet = await Wallet.load('BLAKE2b', NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1)\r
 \r
                        //@ts-expect-error\r