]> git.codecow.com Git - libnemo.git/commitdiff
Privatize Ledger transport.
authorChris Duncan <chris@zoso.dev>
Mon, 15 Sep 2025 14:44:08 +0000 (07:44 -0700)
committerChris Duncan <chris@zoso.dev>
Mon, 15 Sep 2025 14:44:08 +0000 (07:44 -0700)
src/lib/wallet/ledger.ts

index dbe4e3539b73e81333db10e5a2fbe1f1150b3c73..311faaa5e4112a1275d672851522dcb43e817d58 100644 (file)
@@ -25,6 +25,7 @@ export class Ledger {
        static #listenTimeout: 30000 = 30000
        static #openTimeout: 3000 = 3000
        static #status: DeviceStatus = 'DISCONNECTED'
+       static #transport: typeof TransportHID | typeof TransportBLE | typeof TransportUSB
        static #ADPU_CODES: { [key: string]: number } = Object.freeze({
                class: 0xa1,
                bip32DerivationLevel: 0x03,
@@ -54,8 +55,7 @@ export class Ledger {
                0x9000: 'OK'
        })
 
-       static DynamicTransport: typeof TransportHID | typeof TransportBLE | typeof TransportUSB
-       static UsbVendorId: typeof ledgerUSBVendorId = ledgerUSBVendorId
+       static get UsbVendorId (): typeof ledgerUSBVendorId { return ledgerUSBVendorId }
 
        /**
        * Check which transport protocols are supported by the browser and return the
@@ -64,15 +64,15 @@ export class Ledger {
        static get isUnsupported (): boolean {
                console.log('Checking browser Ledger support...')
                if (typeof globalThis.navigator?.hid?.getDevices === 'function') {
-                       this.DynamicTransport = TransportHID
+                       this.#transport ??= TransportHID
                        return false
                }
                if (typeof globalThis.navigator?.bluetooth?.getDevices === 'function') {
-                       this.DynamicTransport = TransportBLE
+                       this.#transport ??= TransportBLE
                        return false
                }
                if (typeof globalThis.navigator?.usb?.getDevices === 'function') {
-                       this.DynamicTransport = TransportUSB
+                       this.#transport ??= TransportUSB
                        return false
                }
                return true
@@ -97,7 +97,7 @@ export class Ledger {
                const account = dec.toBytes(index + HARDENED_OFFSET, 4)
                const data = new Uint8Array([...Ledger.#DERIVATION_PATH, ...account])
 
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(Ledger.#ADPU_CODES.class, Ledger.#ADPU_CODES.account, show ? 1 : 0, Ledger.#ADPU_CODES.paramUnused, data as Buffer)
                        .catch(err => dec.toBytes(err.statusCode)) as Uint8Array
@@ -316,7 +316,7 @@ export class Ledger {
                const signature = hex.toBytes(block.signature, 64)
                const data = new Uint8Array([Ledger.#ADPU_CODES.bip32DerivationLevel, ...purpose, ...coin, ...account, ...previous, ...link, ...representative, ...balance, ...signature])
 
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(Ledger.#ADPU_CODES.class, Ledger.#ADPU_CODES.cacheBlock, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused, data as Buffer)
                        .then(res => bytes.toDec(res))
@@ -340,7 +340,7 @@ export class Ledger {
        * @returns Status of command
        */
        static async #close (): Promise<LedgerResponse> {
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(0xb0, 0xa7, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused)
                        .then(res => bytes.toDec(res))
@@ -405,7 +405,7 @@ export class Ledger {
        */
        static async #open (): Promise<LedgerResponse> {
                const name = new TextEncoder().encode('Nano')
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(0xe0, 0xd8, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused, name as Buffer)
                        .then(res => bytes.toDec(res))
@@ -438,7 +438,7 @@ export class Ledger {
                const balance = hex.toBytes(BigInt(block.balance).toString(16), 16)
                const data = new Uint8Array([...Ledger.#DERIVATION_PATH, ...account, ...previous, ...link, ...representative, ...balance])
 
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(Ledger.#ADPU_CODES.class, Ledger.#ADPU_CODES.signBlock, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused, data as Buffer)
                        .catch(err => dec.toBytes(err.statusCode)) as Uint8Array
@@ -479,7 +479,7 @@ export class Ledger {
                const derivationAccount = dec.toBytes(index + HARDENED_OFFSET, 4)
                const data = new Uint8Array([...Ledger.#DERIVATION_PATH, ...derivationAccount, ...nonce])
 
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(Ledger.#ADPU_CODES.class, Ledger.#ADPU_CODES.signNonce, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused, data as Buffer)
                        .catch(err => dec.toBytes(err.statusCode)) as Uint8Array
@@ -508,7 +508,7 @@ export class Ledger {
        * @returns Status, process name, and version
        */
        static async #version (): Promise<LedgerVersionResponse> {
-               const transport = await Ledger.DynamicTransport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
+               const transport = await Ledger.#transport.create(Ledger.#openTimeout, Ledger.#listenTimeout)
                const response = await transport
                        .send(0xb0, Ledger.#ADPU_CODES.version, Ledger.#ADPU_CODES.paramUnused, Ledger.#ADPU_CODES.paramUnused)
                        .catch(err => dec.toBytes(err.statusCode)) as Uint8Array