* https://github.com/roosmaa/ledger-app-nano/blob/master/doc/nano.md
*/
export class Ledger {
+ static #isInternal: boolean = true
static #isPolling: boolean = false
static #status: LedgerStatus = 'DISCONNECTED'
static #transport: typeof TransportHID | typeof TransportBLE | typeof TransportUSB
* transport type according to the following priorities: HID, Bluetooth, USB.
*/
static get isUnsupported (): boolean {
- if (this.#status === 'UNSUPPORTED') {
- return true
- }
- if (this.#transport !== undefined) {
- return false
- }
console.log('Checking browser Ledger support...')
if (typeof globalThis.navigator?.hid?.getDevices === 'function') {
this.#transport ??= TransportHID
this.#transport ??= TransportUSB
return false
}
- this.#setStatus('UNSUPPORTED')
+ this.status = 'UNSUPPORTED'
return true
}
* UNSUPPORTED | DISCONNECTED | BUSY | LOCKED | CONNECTED
*/
static get status (): LedgerStatus {
- return this.isUnsupported ? 'UNSUPPORTED' : this.#status
+ return this.#status
+ }
+
+ /**
+ * Sets the Ledger status and emits an event. Only callable within the class.
+ */
+ static set status (value: LedgerStatus) {
+ if (#isInternal in this && this.#status !== value) {
+ this.#status = value
+ const event = new LedgerEvent('ledgerstatuschanged', value)
+ this.dispatchEvent(event)
+ console.log(event)
+ }
}
/**
* - CONNECTED: Nano app is open and listening
*/
static async connect (api?: 'hid' | 'ble' | 'usb'): Promise<LedgerStatus> {
- if (api !== undefined || this.#status !== 'UNSUPPORTED') {
+ if (api !== undefined || !this.isUnsupported) {
if (api === 'hid' && this.#transport !== TransportHID) {
this.#transport = TransportHID
}
}
}
const status = await queue(async () => _connect(this.#transport))
- this.#setStatus(status)
+ this.status = status
if (!this.isUnsupported && !this.#isPolling) {
this.#isPolling = true
this.#poll().then(() => void 0, () => void 0)
}
- return this.#status
+ return this.status
}
/**
queue(async () => {
_disconnect()
this.#isPolling = false
- this.#setStatus('DISCONNECTED')
+ this.status = 'DISCONNECTED'
})
}
|| (this.#transport === TransportUSB && isUsbPaired)) {
await this.connect()
} else {
- this.#setStatus('DISCONNECTED')
+ this.status = 'DISCONNECTED'
}
this.#isPolling ? setTimeout(() => this.#poll(), 500) : void 0
} catch {
console.warn('Error polling Ledger device')
- this.#setStatus('DISCONNECTED')
- }
- }
-
- /**
- * Sets the Ledger status and emits an event.
- */
- static #setStatus (value: LedgerStatus) {
- if (this.#status !== value) {
- this.#status = value
- const event = new LedgerEvent('ledgerstatuschanged', value)
- this.dispatchEvent(event)
- console.log(event)
+ this.status = 'DISCONNECTED'
}
}
}