]> git.codecow.com Git - libnemo.git/commitdiff
Quit app ADPU is not working, so sever the connection by losing browser privileges...
authorChris Duncan <chris@zoso.dev>
Thu, 10 Jul 2025 20:39:25 +0000 (13:39 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 10 Jul 2025 20:39:25 +0000 (13:39 -0700)
src/lib/wallets/ledger-wallet.ts
test/test.ledger.mjs

index bc192c0bf645abf1f1d38a1c85159928baa2b8ee..492a4ad8e7ee02b5b3f049b81b730bd9c06b7c4b 100644 (file)
@@ -136,9 +136,8 @@ export class LedgerWallet extends Wallet {
        */\r
        async destroy (): Promise<void> {\r
                await super.destroy()\r
-               const { status } = await this.#close()\r
-               if (status !== 'OK') {\r
-                       throw new Error('Failed to lock Ledger wallet', { cause: status })\r
+               if (!(await this.lock())) {\r
+                       throw new Error('Failed to lock Ledger wallet')\r
                }\r
        }\r
 \r
@@ -152,7 +151,11 @@ export class LedgerWallet extends Wallet {
        }\r
 \r
        /**\r
-       * Attempts to close the current process on the Ledger device.\r
+       * Revokes permission granted by the user to access the Ledger device.\r
+       *\r
+       * The 'quit app' ADPU command has not passed testing, so this is the only way\r
+       * to ensure the connection is severed at this time. `setTimeout` is used to\r
+       * expire any lingering transient user activation.\r
        *\r
        * Overrides the default wallet `lock()` method since as a hardware wallet it\r
        * does not need to be encrypted by software.\r
@@ -160,8 +163,18 @@ export class LedgerWallet extends Wallet {
        * @returns True if successfully locked\r
        */\r
        async lock (): Promise<boolean> {\r
-               const { status } = await this.#close()\r
-               return status === 'OK'\r
+               try {\r
+                       const devices = await globalThis.navigator.usb.getDevices()\r
+                       for (const device of devices) {\r
+                               if (device.vendorId === ledgerUSBVendorId) {\r
+                                       await device.forget()\r
+                               }\r
+                       }\r
+                       return new Promise(r => setTimeout(r, 0, true))\r
+               } catch (err) {\r
+                       console.log(err)\r
+                       return new Promise(r => setTimeout(r, 0, false))\r
+               }\r
        }\r
 \r
        onConnectUsb = async (e: USBConnectionEvent): Promise<void> => {\r
index 09022b96171a25cc9ba1becf740431fd04a2fc0d..134fe7caf78cb6c85d10f94918acf81f1dc4babc 100644 (file)
@@ -176,7 +176,8 @@ await suite('Ledger hardware wallet', { skip: false || isNode }, async () => {
        })
 
        await test('destroy wallet', async () => {
-               await assert.resolves(wallet.destroy())
+               await wallet.destroy()
+               await assert.rejects(wallet.version())
        })
 
        await test('fail when using new', async () => {