]> git.codecow.com Git - libnemo.git/commitdiff
Update wallet parent to support Ledger public-only keypairs, and deprecate Ledger...
authorChris Duncan <chris@zoso.dev>
Thu, 10 Jul 2025 16:04:09 +0000 (09:04 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 10 Jul 2025 16:04:09 +0000 (09:04 -0700)
src/lib/wallets/ledger-wallet.ts
src/lib/wallets/wallet.ts
test/test.ledger.mjs

index ec25851ef1d9bbf8025da03b38d932369eaca3d2..d3a97731c20f802b95a55ff8bfc629331b07dd36 100644 (file)
@@ -5,7 +5,7 @@ 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 { Account } from '#src/lib/account.js'\r
+import { Account, AccountList } from '#src/lib/account.js'\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
@@ -69,33 +69,6 @@ export class LedgerWallet extends Wallet {
                super(id)\r
        }\r
 \r
-       /**\r
-       * Since the Ledger device can only return one account per request, this\r
-       * overrides the default behavior of calling `accounts()` to instead\r
-       * directly derive and return a single account at the specified index.\r
-       *\r
-       * @returns Account\r
-       */\r
-       async account (index: number = 0, show: boolean = false): Promise<Account> {\r
-               const { status, publicKey } = await this.#account(index, show)\r
-               if (publicKey == null) {\r
-                       throw new Error('Failed to get account from device', { cause: status })\r
-               }\r
-               const account = await Account.fromPublicKey(publicKey)\r
-               return account\r
-       }\r
-\r
-       /**\r
-       * Since the Ledger device can only return one account per request, this\r
-       * overrides the default behavior of returning multiple accounts to instead\r
-       * return a single account at the specified index.\r
-       *\r
-       * @returns Account\r
-       */\r
-       async accounts (): Promise<never> {\r
-               throw new Error(`Ledger device only supports 'account()' calls`)\r
-       }\r
-\r
        /**\r
        * Check which transport protocols are supported by the browser and set the\r
        * transport type according to the following priorities: Bluetooth, USB, HID.\r
index d81d3a801ed27ab16dd6b02fc2cf18ae79d9569a..e35b808a21c333baab3f712e7dfb57918a906532 100644 (file)
@@ -111,10 +111,15 @@ export abstract class Wallet {
                if (indexes.length > 0) {\r
                        const keypairs = await this.ckd(indexes)\r
                        for (const keypair of keypairs) {\r
-                               const { privateKey, index } = keypair\r
-                               if (privateKey == null) throw new RangeError('Account private key missing')\r
+                               const { privateKey, publicKey, index } = keypair\r
                                if (index == null) throw new RangeError('Account keys derived but index missing')\r
-                               output[index] = await Account.fromPrivateKey(privateKey, index)\r
+                               if (privateKey != null && privateKey) {\r
+                                       output[index] = await Account.fromPrivateKey(privateKey, index)\r
+                               } else if (publicKey != null) {\r
+                                       output[index] = await Account.fromPublicKey(publicKey, index)\r
+                               } else {\r
+                                       throw new RangeError('Account keys missing')\r
+                               }\r
                                this.#accounts[index] = output[index]\r
                        }\r
                }\r
index a18d7a12850b66e7093598381f1961c1a0825c81..2ee701ed2ea23955900b38ce003e3262af984dc7 100644 (file)
@@ -62,6 +62,20 @@ await suite('Ledger hardware wallet', { skip: false || isNode }, async () => {
                assert.equals(account.privateKey, '0000000000000000000000000000000000000000000000000000000000000000')
        })
 
+       await test('get second and third accounts', async () => {
+               const accounts = await wallet.accounts(1, 2)
+
+               assert.exists(accounts)
+               assert.equals(accounts.length, 2)
+               for (const account of accounts) {
+                       assert.ok(account instanceof Account)
+                       assert.exists(account.address)
+                       assert.exists(account.publicKey)
+                       assert.exists(account.privateKey)
+                       assert.equals(account.privateKey, '0000000000000000000000000000000000000000000000000000000000000000')
+               }
+       })
+
        await test('sign open block from block', async () => {
                openBlock = new ReceiveBlock(
                        account,
@@ -136,10 +150,7 @@ await suite('Ledger hardware wallet', { skip: false || isNode }, async () => {
        })
 
        await test('destroy wallet', async () => {
-               const { status } = await wallet.close()
-
-               assert.equals(status, 'OK')
-               await wallet.destroy()
+               await assert.resolves(wallet.destroy())
        })
 
        // nonce signing is currently broken: https://github.com/LedgerHQ/app-nano/pull/14