]> git.codecow.com Git - libnemo.git/commitdiff
Update Ledger dependencies and install standard Ledger error codes. Fix lock status...
authorChris Duncan <chris@codecow.com>
Tue, 12 May 2026 18:36:30 +0000 (11:36 -0700)
committerChris Duncan <chris@codecow.com>
Tue, 12 May 2026 18:36:30 +0000 (11:36 -0700)
package-lock.json
package.json
src/lib/ledger.ts

index 6762c94885d628a45c7ad88bfa1bcec0c5ad4ddf..2a96404ed5e65d2c9c0bba67aa63073636e1f705 100644 (file)
@@ -9,9 +9,10 @@
                        "version": "0.12.1",
                        "license": "(GPL-3.0-or-later AND MIT AND ISC)",
                        "dependencies": {
-                               "@ledgerhq/hw-transport-web-ble": "^6.33.1",
-                               "@ledgerhq/hw-transport-webhid": "^6.34.0",
-                               "@ledgerhq/hw-transport-webusb": "^6.33.0",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/hw-transport-web-ble": "^6.34.2",
+                               "@ledgerhq/hw-transport-webhid": "^6.35.2",
+                               "@ledgerhq/hw-transport-webusb": "^6.34.2",
                                "@noble/secp256k1": "^3.0.0",
                                "nano-pow": "^5.1.14",
                                "nano25519": "^1.0.2"
                        }
                },
                "node_modules/@ledgerhq/devices": {
-                       "version": "8.13.0",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.13.0.tgz",
-                       "integrity": "sha512-hgGn1kpe/rT0EJ0Qs7rG+1TXA4g6HN2t3dB4DndRTqVqC9aSSbME+ajA0QWLZisxOD3zkwvO4Q0mJ2zARAKyag==",
+                       "version": "8.14.2",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.14.2.tgz",
+                       "integrity": "sha512-T3pnfrsQEC/eJU0XHIqWI6qww+CL1k3NumR2XGWlMz8lVpoZ9HhcuGoCkMevp+8SWmymgyNIIFue3jlNA5KiMw==",
                        "license": "Apache-2.0",
                        "dependencies": {
-                               "@ledgerhq/errors": "^6.32.0",
-                               "@ledgerhq/logs": "^6.16.0",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/logs": "^6.17.0",
                                "rxjs": "7.8.2",
                                "semver": "7.7.3"
                        }
                },
                "node_modules/@ledgerhq/errors": {
-                       "version": "6.32.0",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.32.0.tgz",
-                       "integrity": "sha512-BjjvhLM6UXYUbhllqAduo9PSneLt9FXZ3TBEUFQ3MMSZOCHt0gAgDySLwul99R8fdYWkXBza4DYQjUNckpN2lg==",
+                       "version": "6.34.1",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.34.1.tgz",
+                       "integrity": "sha512-Atkim7yM9bbfWN7OikiE1vbtRLABRz6rDayTHkX0rkPTs6EkMVZSgoNNDGhcYQRlUXrTz9Eko+5ixCLpJQpEWg==",
                        "license": "Apache-2.0"
                },
                "node_modules/@ledgerhq/hw-transport": {
-                       "version": "6.34.1",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.34.1.tgz",
-                       "integrity": "sha512-Bg9Qk2vtm0m0cZn9prZV2Hbvh3b42KBh4uomO00derh+eiwsdg5AXBBptAJiREkew1RVtETRdWxrKchUJfeWvA==",
+                       "version": "6.35.2",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.35.2.tgz",
+                       "integrity": "sha512-eSXFFqMDAB2Ra/5uqmlru0cUyc2XDQPEKf4ITWHeMms2fHhETw9lcgAEl61vszkiz0RLUVB4VQsLJjj7O8kCvg==",
                        "license": "Apache-2.0",
                        "dependencies": {
-                               "@ledgerhq/devices": "8.13.0",
-                               "@ledgerhq/errors": "^6.32.0",
-                               "@ledgerhq/logs": "^6.16.0",
+                               "@ledgerhq/devices": "8.14.2",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/logs": "^6.17.0",
                                "events": "^3.3.0"
                        }
                },
                "node_modules/@ledgerhq/hw-transport-web-ble": {
-                       "version": "6.33.1",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.33.1.tgz",
-                       "integrity": "sha512-ao/brcjeUUYyUXulT+uRtlyWxBrxGn6YGqwNi4l2qAs0A3zuE6QSnQMiRhhSrZ22SKT3caUarqK5s4GTml65wg==",
+                       "version": "6.34.2",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.34.2.tgz",
+                       "integrity": "sha512-u45djrQFh4WC0uCZj8i0Z5OK11m1+t8oYlkQkhDazrQ4bEzZmJqAtQR3jDmxQs3u2gqEMmE8tSuRfYoSCvLsKA==",
                        "license": "Apache-2.0",
                        "dependencies": {
-                               "@ledgerhq/devices": "8.13.0",
-                               "@ledgerhq/errors": "^6.32.0",
-                               "@ledgerhq/hw-transport": "6.34.1",
-                               "@ledgerhq/logs": "^6.16.0",
+                               "@ledgerhq/devices": "8.14.2",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/hw-transport": "6.35.2",
+                               "@ledgerhq/logs": "^6.17.0",
                                "rxjs": "7.8.2"
                        }
                },
                "node_modules/@ledgerhq/hw-transport-webhid": {
-                       "version": "6.34.0",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.34.0.tgz",
-                       "integrity": "sha512-SG+UnZXyUzrJBSkZnRYGaaZV+C8yiu+pF69Mzw4AKOX6TG8RZ1tOvly8hhnRQ2/gXSiTgbc07N4T8ne2eFei3A==",
+                       "version": "6.35.2",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.35.2.tgz",
+                       "integrity": "sha512-gPqOIVW0cn5WjL23EtO+h9hD12mDIKS/buha3YJkzdxVBJufobc1N8a8CdtOcFoe53o0i1mTdHqo8MJzzueQCw==",
                        "license": "Apache-2.0",
                        "dependencies": {
-                               "@ledgerhq/devices": "8.13.0",
-                               "@ledgerhq/errors": "^6.32.0",
-                               "@ledgerhq/hw-transport": "6.34.1",
-                               "@ledgerhq/logs": "^6.16.0"
+                               "@ledgerhq/devices": "8.14.2",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/hw-transport": "6.35.2",
+                               "@ledgerhq/logs": "^6.17.0"
                        }
                },
                "node_modules/@ledgerhq/hw-transport-webusb": {
-                       "version": "6.33.0",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.33.0.tgz",
-                       "integrity": "sha512-/CSDMzBykihqumItyRxmrmqvBHIBRO9eQlHk2Xvrok6X09EF8ENglcITmEiyqvtDQEofD9A0+tdUhWgV9z82fg==",
+                       "version": "6.34.2",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.34.2.tgz",
+                       "integrity": "sha512-2nRe72vfUsxWkIFSgV8b/RR8BXA27284Uy5Yx+JJnxs1D5bCdvO4WDYg1kXsDd2E3Q1eCZBvV5gSHQbi+uKsvA==",
                        "license": "Apache-2.0",
                        "dependencies": {
-                               "@ledgerhq/devices": "8.13.0",
-                               "@ledgerhq/errors": "^6.32.0",
-                               "@ledgerhq/hw-transport": "6.34.1",
-                               "@ledgerhq/logs": "^6.16.0"
+                               "@ledgerhq/devices": "8.14.2",
+                               "@ledgerhq/errors": "^6.34.1",
+                               "@ledgerhq/hw-transport": "6.35.2",
+                               "@ledgerhq/logs": "^6.17.0"
                        }
                },
                "node_modules/@ledgerhq/logs": {
-                       "version": "6.16.0",
-                       "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.16.0.tgz",
-                       "integrity": "sha512-v/PLfb1dq1En35kkpbfRWp8jLYgbPUXxGhmd4pmvPSIe0nRGkNTomsZASmWQAv6pRonVGqHIBVlte7j1MBbOww==",
+                       "version": "6.17.0",
+                       "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.17.0.tgz",
+                       "integrity": "sha512-yra33g5q/AU7+PwAws+GaVpQGUuxnDREjVBnviJjcaJLVKuLzI4pnj8Bd3nY3fypM5k1yZEYKEXfUuGFUjP2+w==",
                        "license": "Apache-2.0"
                },
                "node_modules/@noble/secp256k1": {
                        "license": "MIT"
                },
                "node_modules/basic-ftp": {
-                       "version": "5.3.0",
-                       "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz",
-                       "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==",
+                       "version": "5.3.1",
+                       "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz",
+                       "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==",
                        "license": "MIT",
                        "optional": true,
                        "engines": {
                        }
                },
                "node_modules/ip-address": {
-                       "version": "10.1.0",
-                       "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
-                       "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
+                       "version": "10.2.0",
+                       "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
+                       "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
                        "license": "MIT",
                        "optional": true,
                        "engines": {
index 6999fb0785d6c63f34e92c366aad130c09ef97d3..2dfe69b5579ade3be27e4cf97b1bf3e69a6bd68c 100644 (file)
                "test:prod": "npm run build:prod && npm run test:node"
        },
        "dependencies": {
-               "@ledgerhq/hw-transport-web-ble": "^6.33.1",
-               "@ledgerhq/hw-transport-webhid": "^6.34.0",
-               "@ledgerhq/hw-transport-webusb": "^6.33.0",
+               "@ledgerhq/errors": "^6.34.1",
+               "@ledgerhq/hw-transport-web-ble": "^6.34.2",
+               "@ledgerhq/hw-transport-webhid": "^6.35.2",
+               "@ledgerhq/hw-transport-webusb": "^6.34.2",
                "@noble/secp256k1": "^3.0.0",
                "nano-pow": "^5.1.14",
                "nano25519": "^1.0.2"
index 72fd3b672d27bd9c9873da17ef1b205f14689103..d3487af01207642e0d249d31fa33e760fed8fb46 100644 (file)
@@ -1,6 +1,7 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
+import { StatusCodes } from '@ledgerhq/errors'
 import { default as TransportBLE } from '@ledgerhq/hw-transport-web-ble'
 import { default as TransportHID } from '@ledgerhq/hw-transport-webhid'
 import { default as TransportUSB } from '@ledgerhq/hw-transport-webusb'
@@ -63,18 +64,12 @@ export class Ledger {
                ...dec.toBytes(BIP44_PURPOSE + HARDENED_OFFSET, 4),
                ...dec.toBytes(BIP44_COIN_NANO + HARDENED_OFFSET, 4)
        ])
-       static #STATUS_CODES: { [key: number]: string } = Object.freeze({
-               0x6700: 'INCORRECT_LENGTH',
-               0x670a: 'NO_APPLICATION_SPECIFIED',
+       static #STATUS_CODES: Readonly<Record<number, string>> = Object.freeze({
+               ...Object.fromEntries(Object.entries(StatusCodes).map(([k, v]) => [+v, k])),
                0x6807: 'APPLICATION_NOT_INSTALLED',
                0x6d00: 'APPLICATION_ALREADY_LAUNCHED',
-               0x6982: 'SECURITY_STATUS_NOT_SATISFIED',
-               0x6985: 'CONDITIONS_OF_USE_NOT_SATISFIED',
                0x6a81: 'INVALID_SIGNATURE',
-               0x6a82: 'CACHE_MISS',
-               0x6b00: 'INCORRECT_PARAMETER',
-               0x6e01: 'TRANSPORT_STATUS_ERROR',
-               0x9000: 'OK'
+               0x6a82: 'CACHE_MISS'
        })
 
        // Compose event emission for status changes
@@ -196,7 +191,7 @@ export class Ledger {
                        }
                }
                try {
-                       return await this.#connect()
+                       return this.#connect()
                } catch (err) {
                        throw new Error('Ledger.connect()', { cause: err })
                } finally {
@@ -461,21 +456,21 @@ export class Ledger {
        static async #connect (): Promise<LedgerStatus> {
                try {
                        const version = await this.#version()
-                       if (version.status !== 'OK') {
+                       if (version.status === 'LOCKED_DEVICE') {
+                               this.#setStatus('LOCKED')
+                       } else if (version.status !== 'OK') {
                                this.#setStatus('DISCONNECTED')
-                       } else {
-                               if (version.name === 'Nano') {
-                                       const { status } = await this.account()
-                                       if (status === 'OK') {
-                                               this.#setStatus('CONNECTED')
-                                       } else if (status === 'SECURITY_STATUS_NOT_SATISFIED') {
-                                               this.#setStatus('LOCKED')
-                                       } else {
-                                               this.#setStatus('DISCONNECTED')
-                                       }
+                       } else if (version.name === 'Nano') {
+                               const { status } = await this.account()
+                               if (status === 'OK') {
+                                       this.#setStatus('CONNECTED')
+                               } else if (status === 'SECURITY_STATUS_NOT_SATISFIED') {
+                                       this.#setStatus('LOCKED')
                                } else {
-                                       this.#setStatus('BUSY')
+                                       this.#setStatus('DISCONNECTED')
                                }
+                       } else {
+                               this.#setStatus('BUSY')
                        }
                } catch (err) {
                        console.error('Ledger.#connect()', err)