From 110fc5c87d9b730c69d3bbc295a0dd66be0392e5 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Fri, 19 Sep 2025 14:06:51 -0700 Subject: [PATCH] Close devices instead of forgetting them. --- src/lib/ledger.ts | 24 +++++++----------------- test/test.ledger.mjs | 13 +++++++++++-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/lib/ledger.ts b/src/lib/ledger.ts index 869c452..4f7d989 100644 --- a/src/lib/ledger.ts +++ b/src/lib/ledger.ts @@ -221,26 +221,16 @@ export class Ledger { } /** - * Clears Ledger connections from all device interfaces. + * Clears Ledger connections from HID and USB interfaces. */ static disconnect (): void { setTimeout(async () => { - const hidDevices = await globalThis.navigator?.hid?.getDevices?.() ?? [] - for (const device of hidDevices) { - if (device.vendorId === this.ledgerVendorId) { - device.forget() - } - } - const bleDevices = await globalThis.navigator?.bluetooth?.getDevices?.() ?? [] - for (const device of bleDevices) { - TransportBLE.disconnect(device.id).catch(() => { }) - } - const usbDevices = await globalThis.navigator?.usb?.getDevices?.() ?? [] - for (const device of usbDevices) { - if (device.vendorId === this.ledgerVendorId) { - device.forget() - } - } + const hidDevices = (await navigator?.hid?.getDevices?.()) + .filter(device => device.vendorId === this.ledgerVendorId) + .map(device => device.close()) + const usbDevices = (await navigator?.usb?.getDevices?.()) + .filter(device => device.vendorId === this.ledgerVendorId) + .map(device => device.close()) this.#status = 'DISCONNECTED' }) } diff --git a/test/test.ledger.mjs b/test/test.ledger.mjs index e3a9188..a339912 100644 --- a/test/test.ledger.mjs +++ b/test/test.ledger.mjs @@ -53,7 +53,7 @@ await Promise.all([ }) }), - suite('Ledger hardware wallet', { skip: false || isNode || navigator?.usb == null }, async () => { + suite('Ledger hardware wallet', { skip: isNode || navigator?.usb == null }, async () => { const { LEDGER_MNEMONIC, LEDGER_SEED, LEDGER_PUBLIC_0, LEDGER_ADDRESS_0 } = CUSTOM_TEST_VECTORS const { OPEN_BLOCK, RECEIVE_BLOCK, SEND_BLOCK } = NANO_TEST_VECTORS @@ -139,9 +139,18 @@ await Promise.all([ resolve(null) }, 90000) }) + + await assert.resolves(async () => { + await click( + 'Unlock device again, then click to continue', + async () => {} + ) + }) + assert.equal(wallet.isLocked, false) + assert.equal(Ledger.status, 'CONNECTED') }) - await test('switch between interfaces', { skip: false }, async () => { + await test('switch between interfaces', { skip: false || isNode || navigator?.usb == null }, async () => { await assert.resolves(async () => { await click( 'Verify current interface is HID, switch to unlocked Bluetooth device, then click to continue', -- 2.47.3