* calls. This wallet does not feature any seed nor mnemonic phrase as all\r
* private keys are held in the secure chip of the device. As such, the user\r
* is responsible for using Ledger technology to back up these pieces of data.\r
-*\r
-* Usage of this wallet is generally controlled by calling functions of the\r
-* `ledger` object. For example, the wallet interface should have a button to\r
-* initiate a device connection by calling `wallet.ledger.connect()`. For more\r
-* information, refer to the ledger.js service file.\r
*/\r
export class LedgerWallet extends Wallet {\r
static #isInternal: boolean = false\r
}\r
\r
/**\r
- * Check which transport protocols are supported by the browser and set the\r
+ * Check which transport protocols are supported by the browser and return the\r
* transport type according to the following priorities: Bluetooth, USB, HID.\r
*/\r
- async checkBrowserSupport (): Promise<typeof TransportBLE | typeof TransportUSB | typeof TransportHID> {\r
+ static checkBrowserSupport (): typeof TransportBLE | typeof TransportUSB | typeof TransportHID {\r
console.log('Checking browser Ledger support...')\r
try {\r
- if (await TransportBLE.isSupported()) {\r
+ if (typeof globalThis.navigator?.bluetooth?.getDevices === 'function') {\r
return TransportBLE\r
}\r
- if (await TransportUSB.isSupported()) {\r
+ if (typeof globalThis.navigator?.usb?.getDevices === 'function') {\r
return TransportUSB\r
}\r
- if (await TransportHID.isSupported()) {\r
+ if (typeof globalThis.navigator?.hid?.getDevices === 'function') {\r
return TransportHID\r
}\r
} catch { }\r
throw new Error('Unsupported browser')\r
}\r
\r
+ /**\r
+ * Creates a new Ledger hardware wallet communication layer by dynamically\r
+ * importing the ledger.js service.\r
+ *\r
+ * @returns {LedgerWallet} A wallet containing accounts and a Ledger device communication object\r
+ */\r
+ static async create (): Promise<LedgerWallet> {\r
+ try {\r
+ const transport = LedgerWallet.checkBrowserSupport()\r
+ const id = await Entropy.create(16)\r
+ LedgerWallet.#isInternal = true\r
+ const wallet = new this(id)\r
+ wallet.DynamicTransport = transport\r
+ return wallet\r
+ } catch (err) {\r
+ throw new Error('failed to initialize Ledger wallet', { cause: err })\r
+ }\r
+ }\r
+\r
/**\r
* Check if the Nano app is currently open and set device status accordingly.\r
*\r
return this.status\r
}\r
\r
- /**\r
- * Creates a new Ledger hardware wallet communication layer by dynamically\r
- * importing the ledger.js service.\r
- *\r
- * @returns {LedgerWallet} A wallet containing accounts and a Ledger device communication object\r
- */\r
- static async create (): Promise<LedgerWallet> {\r
- const id = await Entropy.create(16)\r
- LedgerWallet.#isInternal = true\r
- const wallet = new this(id)\r
- await wallet.init()\r
- return wallet\r
- }\r
-\r
/**\r
* Removes encrypted secrets in storage and releases variable references to\r
* allow garbage collection.\r
}\r
}\r
\r
- async init (): Promise<void> {\r
- try {\r
- this.DynamicTransport = await this.checkBrowserSupport()\r
- // await this.connect()\r
- } catch (err) {\r
- throw new Error('Failed to initialize Ledger wallet', { cause: err })\r
- }\r
- }\r
-\r
/**\r
* Revokes permission granted by the user to access the Ledger device.\r
*\r
if (typeof id !== 'string' || id === '') {\r
throw new TypeError('Wallet ID is required to restore')\r
}\r
- LedgerWallet.#isInternal = true\r
- id = id.replace('libnemo_', '')\r
- const wallet = new this(await Entropy.import(id))\r
- await wallet.init()\r
- return wallet\r
+ try {\r
+ const transport = LedgerWallet.checkBrowserSupport()\r
+ LedgerWallet.#isInternal = true\r
+ const wallet = new this(await Entropy.import(id))\r
+ wallet.DynamicTransport = transport\r
+ return wallet\r
+ } catch (err) {\r
+ console.error(err)\r
+ throw new Error('failed to restore wallet', { cause: err })\r
+ }\r
}\r
\r
/**\r
* calls. This wallet does not feature any seed nor mnemonic phrase as all
* private keys are held in the secure chip of the device. As such, the user
* is responsible for using Ledger technology to back up these pieces of data.
-*
-* Usage of this wallet is generally controlled by calling functions of the
-* `ledger` object. For example, the wallet interface should have a button to
-* initiate a device connection by calling `wallet.ledger.connect()`. For more
-* information, refer to the ledger.js service file.
*/
export declare class LedgerWallet extends Wallet {
#private
DynamicTransport: typeof TransportBLE | typeof TransportUSB | typeof TransportHID
private constructor ()
/**
- * Check which transport protocols are supported by the browser and set the
+ * Check which transport protocols are supported by the browser and return the
* transport type according to the following priorities: Bluetooth, USB, HID.
*/
- checkBrowserSupport (): Promise<typeof TransportBLE | typeof TransportUSB | typeof TransportHID>
+ static checkBrowserSupport (): typeof TransportBLE | typeof TransportUSB | typeof TransportHID
+ /**
+ * Creates a new Ledger hardware wallet communication layer by dynamically
+ * importing the ledger.js service.
+ *
+ * @returns {LedgerWallet} A wallet containing accounts and a Ledger device communication object
+ */
+ static create (): Promise<LedgerWallet>
/**
* Check if the Nano app is currently open and set device status accordingly.
*
*/
connect (): Promise<DeviceStatus>
/**
- * Creates a new Ledger hardware wallet communication layer by dynamically
- * importing the ledger.js service.
- *
- * @returns {LedgerWallet} A wallet containing accounts and a Ledger device communication object
- */
- static create (): Promise<LedgerWallet>
- /**
* Removes encrypted secrets in storage and releases variable references to
* allow garbage collection.
*/
const rpc = new Rpc(env.NODE_URL ?? '', env.API_KEY_NAME)
+let isUnsupported = true
+try {
+ LedgerWallet.checkBrowserSupport()
+ isUnsupported = false
+} catch {}
+
/**
* HID interactions require user gestures, so to reduce clicks, the variables
* shared among tests like wallet and account are declared at the top-level.
*/
await Promise.all([
/* node:coverage disable */
- suite('Ledger hardware wallet', { skip: false || isNode }, async () => {
+ suite('Ledger hardware wallet', { skip: false || isNode || isUnsupported }, async () => {
let wallet, account, openBlock, sendBlock, receiveBlock