From 5df7f2a6f7ffea70da7d1e6aa262018c98096364 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Mon, 18 May 2026 14:42:28 -0700 Subject: [PATCH] Extract Ledger polling. --- src/lib/ledger/index.ts | 25 +++++-------------------- src/lib/ledger/poll.ts | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 src/lib/ledger/poll.ts diff --git a/src/lib/ledger/index.ts b/src/lib/ledger/index.ts index 23d4a4d..cda83f7 100644 --- a/src/lib/ledger/index.ts +++ b/src/lib/ledger/index.ts @@ -16,6 +16,7 @@ import { _connect } from './connect' import { _disconnect } from './disconnect' import { LedgerEvent } from './event' import { _open } from './open' +import { _poll } from './poll' import { queue } from './queue' import { _sign } from './sign' import { _verify } from './verify' @@ -153,9 +154,7 @@ export class Ledger { this.#transport = TransportBLE } if (api === 'usb' && this.#transport !== TransportUSB) { - this.#transport = typeof navigator.hid?.getDevices === 'function' - ? TransportHID - : TransportUSB + this.#transport = TransportUSB } } const status = await queue(async () => _connect(this.#transport)) @@ -172,7 +171,7 @@ export class Ledger { * connection updates. */ static async disconnect (): Promise { - queue(async () => { + return queue(async () => { _disconnect() this.#isPolling = false this.status = 'DISCONNECTED' @@ -316,21 +315,7 @@ export class Ledger { * device. */ static async #poll (): Promise { - try { - const isHidPaired = (await navigator.hid?.getDevices?.() ?? []) - .some(device => device.vendorId === LEDGER_VENDOR_ID) - const isUsbPaired = (await navigator.usb?.getDevices?.() ?? []) - .some(device => device.vendorId === LEDGER_VENDOR_ID) - if ((this.#transport === TransportHID && isHidPaired) - || (this.#transport === TransportUSB && isUsbPaired)) { - await this.connect() - } else { - this.status = 'DISCONNECTED' - } - this.#isPolling ? setTimeout(() => this.#poll(), 500) : void 0 - } catch { - console.warn('Error polling Ledger device') - this.status = 'DISCONNECTED' - } + this.status = await queue(async () => _poll(this.#transport)) + this.#isPolling ? setTimeout(() => this.#poll(), 500) : void 0 } } diff --git a/src/lib/ledger/poll.ts b/src/lib/ledger/poll.ts new file mode 100644 index 0000000..c9a61f7 --- /dev/null +++ b/src/lib/ledger/poll.ts @@ -0,0 +1,24 @@ +//! SPDX-FileCopyrightText: 2025 Chris Duncan +//! SPDX-License-Identifier: GPL-3.0-or-later + +import TransportHID from '@ledgerhq/hw-transport-webhid' +import TransportUSB from '@ledgerhq/hw-transport-webusb' +import { LEDGER_VENDOR_ID, Ledger, LedgerStatus, LedgerTransport } from '.' + +export async function _poll (transport: LedgerTransport): Promise { + let status: LedgerStatus = 'DISCONNECTED' + try { + const isHidPaired = (await navigator.hid?.getDevices?.() ?? []) + .some(device => device.vendorId === LEDGER_VENDOR_ID) + const isUsbPaired = (await navigator.usb?.getDevices?.() ?? []) + .some(device => device.vendorId === LEDGER_VENDOR_ID) + if ((transport === TransportHID && isHidPaired) + || (transport === TransportUSB && isUsbPaired)) { + status = await Ledger.connect() + } + } catch { + console.warn('Error polling Ledger device') + } finally { + return status + } +} -- 2.47.3