]> git.codecow.com Git - libnemo.git/commitdiff
Fix restore of Ledger wallets.
authorChris Duncan <chris@zoso.dev>
Wed, 24 Sep 2025 15:09:01 +0000 (08:09 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 24 Sep 2025 15:09:01 +0000 (08:09 -0700)
src/lib/wallet/get.ts
src/lib/wallet/index.ts
src/lib/wallet/load.ts
src/lib/wallet/update.ts
test/test.ledger.mjs
test/test.lock-unlock.mjs

index 3e47f2484362408b31a05675cbf241f6b5e7715b..2d8d3528b9e88865702cbaa08835110d542a03f0 100644 (file)
@@ -12,17 +12,19 @@ export async function _get (recordId: string) {
                if (typeof id !== 'string') {
                        throw new TypeError('Retrieved invalid ID', { cause: id })
                }
-               if (type !== 'BIP-44' && type !== 'BLAKE2b') {
+               if (type !== 'BIP-44' && type !== 'BLAKE2b' && type !== 'Ledger') {
                        throw new TypeError('Retrieved invalid type', { cause: type })
                }
-               if (!(iv instanceof ArrayBuffer)) {
-                       throw new TypeError('Retrieved invalid iv', { cause: iv })
-               }
-               if (!(salt instanceof ArrayBuffer)) {
-                       throw new TypeError('Retrieved invalid salt', { cause: salt })
-               }
-               if (!(encrypted instanceof ArrayBuffer)) {
-                       throw new TypeError('Retrieved invalid encrypted data', { cause: encrypted })
+               if (type !== 'Ledger') {
+                       if (!(iv instanceof ArrayBuffer)) {
+                               throw new TypeError('Retrieved invalid iv', { cause: iv })
+                       }
+                       if (!(salt instanceof ArrayBuffer)) {
+                               throw new TypeError('Retrieved invalid salt', { cause: salt })
+                       }
+                       if (!(encrypted instanceof ArrayBuffer)) {
+                               throw new TypeError('Retrieved invalid encrypted data', { cause: encrypted })
+                       }
                }
                return { id, type, iv, salt, encrypted } as const
        } catch (err) {
index d116e436231c4eec55c160b2f5aa2d40dbe22aa5..574f9c511a89c3d42572f711579d9415259af9c4 100644 (file)
@@ -14,7 +14,6 @@ import { _backup } from './backup'
 import { _config } from './config'\r
 import { _create } from './create'\r
 import { _destroy } from './destroy'\r
-import { _get } from './get'\r
 import { _load } from './load'\r
 import { _lock } from './lock'\r
 import { _refresh } from './refresh'\r
index 4d6fb60798b6c74963041c72e0b4fa0cee806d87..dee3b5798353bba4a6998cec4979504b2c58896c 100644 (file)
@@ -17,7 +17,6 @@ export async function _load (wallet: Wallet, vault: Vault, password: unknown, se
                        type: wallet.type
                }
                if (wallet.type === 'Ledger') {
-
                        if (Ledger.isUnsupported) {
                                throw new Error('Failed to initialize Ledger wallet', { cause: 'Browser is unsupported' })
                        }
index 50d3f92556ff9f1b699d58d24e9794b35b4c8fa7..1199c16fab124af658b2848e7b04bf344afd9e64 100644 (file)
@@ -6,7 +6,6 @@ import { utf8 } from '../convert'
 import { Database } from '../database'
 import { Vault } from '../vault'
 import { Wallet } from '../wallet'
-import { _get } from './get'
 
 export async function _update (wallet: Wallet, vault: Vault, password?: string): Promise<void>
 export async function _update (wallet: Wallet, vault: Vault, password: unknown): Promise<void> {
index c1a2759c6c22ae7aed5a20a5b2d043495f4cd69c..0a64da4233b110a08892053de383f53fd13b18c5 100644 (file)
@@ -31,7 +31,7 @@ await Promise.all([
 
                const { LEDGER_MNEMONIC, LEDGER_SEED, LEDGER_PUBLIC_0, LEDGER_ADDRESS_0 } = CUSTOM_TEST_VECTORS
                const { OPEN_BLOCK, RECEIVE_BLOCK, SEND_BLOCK } = NANO_TEST_VECTORS
-               let wallet, account, openBlock, sendBlock, receiveBlock
+               let wallet, account, openBlock, sendBlock, receiveBlock, restored
                try {
                        wallet = await Wallet.create('Ledger')
                } catch {
@@ -170,6 +170,10 @@ await Promise.all([
                })
 
                await test('verify mnemonic', async () => {
+                       await click(
+                               'Open Nano app, then click to continue',
+                               async () => wallet.unlock()
+                       )
                        const isVerified = await wallet.verify(LEDGER_MNEMONIC)
 
                        assert.exists(isVerified)
@@ -302,7 +306,13 @@ await Promise.all([
                        await assert.rejects(sendBlock.sign(wallet, 0))
                })
 
-               await test('destroy wallet', async () => {
+               await test('restore from db then destroy', async () => {
+                       restored = await Wallet.restore(wallet.id)
+
+                       assert.exists(restored)
+                       await assert.resolves(restored.unlock())
+                       assert.equal(await restored.verify(LEDGER_MNEMONIC), true)
+
                        await click(
                                'Click to finish Ledger tests by destroying wallet',
                                async () => new Promise(r => setTimeout(r))
@@ -310,6 +320,7 @@ await Promise.all([
                        await assert.resolves(wallet.destroy())
                        await assert.rejects(wallet.unlock())
                        await wallet.destroy()
+                       await restored.destroy()
                })
        })
 ])
index e86a5d8fdb2525af0882bc4bef2b366f6e13b0e8..b42edfadbb38b99545b2fa170ba9bfded78d9acf 100644 (file)
@@ -253,6 +253,8 @@ await Promise.all([
                        await assert.rejects(wallet.config({ timeout: 0 }))\r
                        await assert.rejects(wallet.config({ timeout: 9 }))\r
                        await assert.rejects(wallet.config({ timeout: 601 }))\r
+\r
+                       await assert.resolves(wallet.destroy())\r
                })\r
        })\r
 ])\r