Merge pull request #518 from aleksre/ledger-ux

Improve Ledger UX
This commit is contained in:
Joohansson (Json) 2023-08-28 18:07:57 +02:00 committed by GitHub
commit b7edd072ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 291 additions and 242 deletions

View file

@ -1,6 +1,6 @@
import TransportNodeHid from '@ledgerhq/hw-transport-node-hid';
import TransportNodeBle from '@ledgerhq/hw-transport-node-ble';
import * as LedgerLogs from '@ledgerhq/logs';
import Transport from '@ledgerhq/hw-transport';
import Nano from 'hw-app-nano';
import * as rx from 'rxjs';
@ -20,6 +20,12 @@ const LedgerStatus = {
READY: 'ready',
};
export interface LedgerData {
status: string;
nano: any|null;
transport: Transport|null;
}
/**
* This class is close to a clone of the LedgerService for web, but it
@ -27,9 +33,8 @@ const LedgerStatus = {
*/
export class LedgerService {
walletPrefix = `44'/165'/`;
waitTimeout = 300000;
normalTimeout = 5000;
pollInterval = 45000;
waitTimeout = 30000;
pollInterval = 5000;
pollingLedger = false;
queryingLedger = false;
@ -37,7 +42,7 @@ export class LedgerService {
ledgerStatus$ = new rx.Subject();
ledgerMessage$ = new rx.Subject();
ledger = {
ledger: LedgerData = {
status: LedgerStatus.NOT_CONNECTED,
nano: null,
transport: null,
@ -56,15 +61,33 @@ export class LedgerService {
// Open a connection to the usb device and initialize up the Nano Ledger library
async loadTransport(bluetooth: boolean) {
return new Promise((resolve, reject) => {
(bluetooth ? TransportNodeBle : TransportNodeHid).create().then(trans => {
// LedgerLogs.listen((log) => console.log(`Ledger: ${log.type}: ${log.message}`))
this.ledger.transport = trans;
this.ledger.transport.setExchangeTimeout(this.waitTimeout); // 5 minutes
const transport = bluetooth ? TransportNodeBle : TransportNodeHid;
let found = false;
const sub = transport.listen({
next: async(e) => {
found = true;
if (sub) sub.unsubscribe();
clearTimeout(timeoutId);
this.ledger.transport = await transport.open(e.descriptor);
this.ledger.nano = new Nano(this.ledger.transport);
resolve(this.ledger.transport);
}).catch(reject);
},
error: (e) => {
clearTimeout(timeoutId);
reject(e);
},
complete: () => {
clearTimeout(timeoutId);
if (!found) {
reject(new Error(transport.ErrorMessage_NoDeviceFound));
}
}
})
const timeoutId = setTimeout(() => {
sub.unsubscribe();
reject(new Error(transport.ErrorMessage_ListenTimeout));
}, this.waitTimeout);
});
}
@ -88,10 +111,6 @@ export class LedgerService {
}
let resolved = false;
if (this.ledger.status === LedgerStatus.READY) {
this.ledgerStatus$.next({ status: this.ledger.status, statusText: 'Ledger device already ready' });
return true; // Already ready?
}
setTimeout(() => {
if (resolved || this.ledger.status === LedgerStatus.READY) return;
@ -117,6 +136,7 @@ export class LedgerService {
} catch (err) {
console.log(err);
if (err.statusCode === STATUS_CODES.SECURITY_STATUS_NOT_SATISFIED) {
this.setLedgerStatus(LedgerStatus.LOCKED, `Ledger device locked`);
}
}
@ -125,8 +145,6 @@ export class LedgerService {
async getLedgerAccount(accountIndex, showOnScreen = false) {
try {
this.ledger.transport.setExchangeTimeout(showOnScreen ? this.waitTimeout : this.normalTimeout);
this.queryingLedger = true;
const account = await this.ledger.nano.getAddress(this.ledgerPath(accountIndex), showOnScreen);
this.queryingLedger = false;
@ -208,7 +226,11 @@ export class LedgerService {
await this.getLedgerAccount(0, false);
this.setLedgerStatus(LedgerStatus.READY);
} catch (err) {
if (err.statusCode === STATUS_CODES.SECURITY_STATUS_NOT_SATISFIED) {
this.setLedgerStatus(LedgerStatus.LOCKED, `Ledger device locked`);
} else {
this.setLedgerStatus(LedgerStatus.NOT_CONNECTED, `Ledger Disconnected: ${err.message || err }`);
}
this.pollingLedger = false;
}
}

View file

@ -5,6 +5,7 @@
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"esModuleInterop": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
@ -20,5 +21,8 @@
},
"include": [
"src/**/*"
],
"exclude": [
"**/node_modules/**"
]
}

331
package-lock.json generated
View file

@ -32,6 +32,7 @@
"@ngneat/transloco": "^3.1.1",
"@types/crypto-js": "^3.1.38",
"@types/w3c-web-hid": "^1.0.2",
"@types/w3c-web-usb": "^1.0.5",
"@zxing/browser": "^0.0.10",
"@zxing/library": "^0.18.6",
"@zxing/ngx-scanner": "^3.4.0",
@ -76,7 +77,7 @@
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.2",
"@types/ledgerhq__hw-transport": "^4.21.3",
"@types/node": "^12.11.1",
"@types/node": "^12.20.39",
"@types/qrcode": "^0.8.1",
"@typescript-eslint/eslint-plugin": "5.17.0",
"@typescript-eslint/parser": "5.17.0",
@ -3320,20 +3321,20 @@
"integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg=="
},
"node_modules/@ledgerhq/devices": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.27.1.tgz",
"integrity": "sha512-jX++oy89jtv7Dp2X6gwt3MMkoajel80JFWcdc0HCouwDsV1mVJ3SQdwl/bQU0zd8HI6KebvUP95QTwbQLLK/RQ==",
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-7.0.2.tgz",
"integrity": "sha512-JfDAt0Ige21BoA4KE/vk2trB/8RtsdJTU1qGblCS09ludxPSUcZIN1XgWMr4LiNDpCOkOqriWE7DudSRxv5nXA==",
"dependencies": {
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/logs": "^6.10.0",
"rxjs": "6",
"semver": "^7.3.5"
}
},
"node_modules/@ledgerhq/devices/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/devices/node_modules/semver": {
"version": "7.3.7",
@ -3355,43 +3356,43 @@
"integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow=="
},
"node_modules/@ledgerhq/hw-transport": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.1.tgz",
"integrity": "sha512-hnE4/Fq1YzQI4PA1W0H8tCkI99R3UWDb3pJeZd6/Xs4Qw/q1uiQO+vNLC6KIPPhK0IajUfuI/P2jk0qWcMsuAQ==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.5.tgz",
"integrity": "sha512-vHeOsWNEXGwQT7y1UQE3eULZQb2PzHdpuMjDDHpWYdNABckXOQDlyMThk9ZYzODhlIJIi3ASgpxLtbTFRhERjg==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"events": "^3.3.0"
}
},
"node_modules/@ledgerhq/hw-transport-node-ble": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-ble/-/hw-transport-node-ble-6.27.1.tgz",
"integrity": "sha512-Qy36HcZjau1GuimZrpiABS/CuXhMoD5X/8kaoMzDz1VjgrSGiIlB8IyA6r/q0lI1YlBA9gXKoZ6AO/F6D3bIKw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-ble/-/hw-transport-node-ble-6.27.5.tgz",
"integrity": "sha512-dHnlMZ3Jc7un8/0sGCAEL2J1s0R2sOHBPNkGcTaK7vvHyu8cI2BQpehOhb9a81B6mbr/Oz4TaHCwU8JuI45YVA==",
"dependencies": {
"@abandonware/noble": "1.9.2-15",
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"invariant": "^2.2.4",
"rxjs": "6"
}
},
"node_modules/@ledgerhq/hw-transport-node-ble/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport-node-hid": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.1.tgz",
"integrity": "sha512-H3kGFU6lDAZM7ef17nVGTCpgwPzDcbO8dwqvGoIDTopvlNgNqmzw95GT3aCosJMp04C9yYGyMPSF5UFjRX8ckg==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.5.tgz",
"integrity": "sha512-azE0klZLBc6VOEcUjVgWPz2XtcubEevQyGwNSCWxrUTedRjoyRbLZ8HbLYNKy/kZQOQr+YNeB9Oa8CItuA+Jzw==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/hw-transport-node-hid-noevents": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/hw-transport-node-hid-noevents": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"lodash": "^4.17.21",
"node-hid": "2.1.1",
@ -3399,21 +3400,21 @@
}
},
"node_modules/@ledgerhq/hw-transport-node-hid-noevents": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.1.tgz",
"integrity": "sha512-nsPo491bslP7QySXIB2asILxws7+t2V/0F4Hjc3IBEkHexH3iS+TmeegE5A72vDXhXKI4wskJ8Pp8Odcz9TN1A==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.5.tgz",
"integrity": "sha512-4CYA/SKOmjtGziRVoLyeEchgDr9LMa7+VOSWqEZwH1D3j8D0Vi6RYWKZsXpjyrVo3Os+cibAO5diAhJt8TsUdQ==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"node-hid": "2.1.1"
}
},
"node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-hid": {
"version": "2.1.1",
@ -3459,9 +3460,9 @@
}
},
"node_modules/@ledgerhq/hw-transport-node-hid/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport-node-hid/node_modules/node-hid": {
"version": "2.1.1",
@ -3563,9 +3564,9 @@
"integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA=="
},
"node_modules/@ledgerhq/hw-transport-u2f/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@ -3577,58 +3578,58 @@
}
},
"node_modules/@ledgerhq/hw-transport-web-ble": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.27.1.tgz",
"integrity": "sha512-odJq8Wc+lT9/yF5xbgMkaacRXdHmTl2zo9JfdK1Ch9Ek3a+aLdHaJUUItteTZSiKJyg8DvLBUvozo/KuPm3zrw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.27.5.tgz",
"integrity": "sha512-HiHWJtVCqwx7QNAx7+WNW1SX67EazB5gtXQjinen1c+u2ZQIOu8Quooakx6rRjDpl5Y9v2Vk1HlhBWK9sV/lcg==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"rxjs": "6"
}
},
"node_modules/@ledgerhq/hw-transport-web-ble/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport-webhid": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.1.tgz",
"integrity": "sha512-u74rBYlibpbyGblSn74fRs2pMM19gEAkYhfVibq0RE1GNFjxDMFC1n7Sb+93Jqmz8flyfB4UFJsxs8/l1tm2Kw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.5.tgz",
"integrity": "sha512-GV27rmkIHBHc/OMy6p90CD4piegHlD9ioAWFwWkulbM/16TGmB18WN0MQrW6Nifd7bmO3nUQ+fKP/F1263jqAA==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0"
}
},
"node_modules/@ledgerhq/hw-transport-webhid/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport-webusb": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.27.1.tgz",
"integrity": "sha512-n0ygJSeRpznrUfwtbDCLQOM5mA23YT/ngYY8HU46dzsVJHrHQ4jwBNJU48iKB+a9GhHyPAUpPNlWGTogvoVUxg==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.27.5.tgz",
"integrity": "sha512-dDnO0qNGk1nZ5vpe2oKxpuzTqt2Vohh2L1tUgfEKQLRvG2kAsw7G6mW89wX8PIxv5LXzl3IYCj7AgsB+E9w3ag==",
"dependencies": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0"
}
},
"node_modules/@ledgerhq/hw-transport-webusb/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/hw-transport/node_modules/@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node_modules/@ledgerhq/logs": {
"version": "6.10.0",
@ -3673,9 +3674,9 @@
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz",
"integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==",
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
"integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
"optional": true,
"dependencies": {
"detect-libc": "^2.0.0",
@ -5292,9 +5293,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "12.12.47",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.47.tgz",
"integrity": "sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A=="
"version": "12.20.55",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@ -19069,7 +19070,7 @@
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"optional": true
},
"node_modules/tree-kill": {
@ -19727,7 +19728,7 @@
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"optional": true
},
"node_modules/webpack": {
@ -20071,7 +20072,7 @@
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"optional": true,
"dependencies": {
"tr46": "~0.0.3",
@ -22762,20 +22763,20 @@
"integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg=="
},
"@ledgerhq/devices": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.27.1.tgz",
"integrity": "sha512-jX++oy89jtv7Dp2X6gwt3MMkoajel80JFWcdc0HCouwDsV1mVJ3SQdwl/bQU0zd8HI6KebvUP95QTwbQLLK/RQ==",
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-7.0.2.tgz",
"integrity": "sha512-JfDAt0Ige21BoA4KE/vk2trB/8RtsdJTU1qGblCS09ludxPSUcZIN1XgWMr4LiNDpCOkOqriWE7DudSRxv5nXA==",
"requires": {
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/logs": "^6.10.0",
"rxjs": "6",
"semver": "^7.3.5"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"semver": {
"version": "7.3.7",
@ -22793,52 +22794,52 @@
"integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow=="
},
"@ledgerhq/hw-transport": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.1.tgz",
"integrity": "sha512-hnE4/Fq1YzQI4PA1W0H8tCkI99R3UWDb3pJeZd6/Xs4Qw/q1uiQO+vNLC6KIPPhK0IajUfuI/P2jk0qWcMsuAQ==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.5.tgz",
"integrity": "sha512-vHeOsWNEXGwQT7y1UQE3eULZQb2PzHdpuMjDDHpWYdNABckXOQDlyMThk9ZYzODhlIJIi3ASgpxLtbTFRhERjg==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"events": "^3.3.0"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
}
}
},
"@ledgerhq/hw-transport-node-ble": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-ble/-/hw-transport-node-ble-6.27.1.tgz",
"integrity": "sha512-Qy36HcZjau1GuimZrpiABS/CuXhMoD5X/8kaoMzDz1VjgrSGiIlB8IyA6r/q0lI1YlBA9gXKoZ6AO/F6D3bIKw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-ble/-/hw-transport-node-ble-6.27.5.tgz",
"integrity": "sha512-dHnlMZ3Jc7un8/0sGCAEL2J1s0R2sOHBPNkGcTaK7vvHyu8cI2BQpehOhb9a81B6mbr/Oz4TaHCwU8JuI45YVA==",
"requires": {
"@abandonware/noble": "1.9.2-15",
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"invariant": "^2.2.4",
"rxjs": "6"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
}
}
},
"@ledgerhq/hw-transport-node-hid": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.1.tgz",
"integrity": "sha512-H3kGFU6lDAZM7ef17nVGTCpgwPzDcbO8dwqvGoIDTopvlNgNqmzw95GT3aCosJMp04C9yYGyMPSF5UFjRX8ckg==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.5.tgz",
"integrity": "sha512-azE0klZLBc6VOEcUjVgWPz2XtcubEevQyGwNSCWxrUTedRjoyRbLZ8HbLYNKy/kZQOQr+YNeB9Oa8CItuA+Jzw==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/hw-transport-node-hid-noevents": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/hw-transport-node-hid-noevents": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"lodash": "^4.17.21",
"node-hid": "2.1.1",
@ -22846,9 +22847,9 @@
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node-hid": {
"version": "2.1.1",
@ -22899,21 +22900,21 @@
}
},
"@ledgerhq/hw-transport-node-hid-noevents": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.1.tgz",
"integrity": "sha512-nsPo491bslP7QySXIB2asILxws7+t2V/0F4Hjc3IBEkHexH3iS+TmeegE5A72vDXhXKI4wskJ8Pp8Odcz9TN1A==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.5.tgz",
"integrity": "sha512-4CYA/SKOmjtGziRVoLyeEchgDr9LMa7+VOSWqEZwH1D3j8D0Vi6RYWKZsXpjyrVo3Os+cibAO5diAhJt8TsUdQ==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"node-hid": "2.1.1"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
},
"node-hid": {
"version": "2.1.1",
@ -22985,9 +22986,9 @@
"integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA=="
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"requires": {
"lru-cache": "^6.0.0"
}
@ -22995,57 +22996,57 @@
}
},
"@ledgerhq/hw-transport-web-ble": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.27.1.tgz",
"integrity": "sha512-odJq8Wc+lT9/yF5xbgMkaacRXdHmTl2zo9JfdK1Ch9Ek3a+aLdHaJUUItteTZSiKJyg8DvLBUvozo/KuPm3zrw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.27.5.tgz",
"integrity": "sha512-HiHWJtVCqwx7QNAx7+WNW1SX67EazB5gtXQjinen1c+u2ZQIOu8Quooakx6rRjDpl5Y9v2Vk1HlhBWK9sV/lcg==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0",
"rxjs": "6"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
}
}
},
"@ledgerhq/hw-transport-webhid": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.1.tgz",
"integrity": "sha512-u74rBYlibpbyGblSn74fRs2pMM19gEAkYhfVibq0RE1GNFjxDMFC1n7Sb+93Jqmz8flyfB4UFJsxs8/l1tm2Kw==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.5.tgz",
"integrity": "sha512-GV27rmkIHBHc/OMy6p90CD4piegHlD9ioAWFwWkulbM/16TGmB18WN0MQrW6Nifd7bmO3nUQ+fKP/F1263jqAA==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
}
}
},
"@ledgerhq/hw-transport-webusb": {
"version": "6.27.1",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.27.1.tgz",
"integrity": "sha512-n0ygJSeRpznrUfwtbDCLQOM5mA23YT/ngYY8HU46dzsVJHrHQ4jwBNJU48iKB+a9GhHyPAUpPNlWGTogvoVUxg==",
"version": "6.27.5",
"resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.27.5.tgz",
"integrity": "sha512-dDnO0qNGk1nZ5vpe2oKxpuzTqt2Vohh2L1tUgfEKQLRvG2kAsw7G6mW89wX8PIxv5LXzl3IYCj7AgsB+E9w3ag==",
"requires": {
"@ledgerhq/devices": "^6.27.1",
"@ledgerhq/errors": "^6.10.0",
"@ledgerhq/hw-transport": "^6.27.1",
"@ledgerhq/devices": "^7.0.2",
"@ledgerhq/errors": "^6.11.0",
"@ledgerhq/hw-transport": "^6.27.5",
"@ledgerhq/logs": "^6.10.0"
},
"dependencies": {
"@ledgerhq/errors": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz",
"integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg=="
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.11.0.tgz",
"integrity": "sha512-z4Gb39Vt2bK77enmAI2kU25zIEPFaLfgkP53UizQfkj7mj72vieuR9Q2eAHLJsoiiITp/TJJdeWkc2PZyFw9ZQ=="
}
}
},
@ -23076,9 +23077,9 @@
}
},
"@mapbox/node-pre-gyp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz",
"integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==",
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
"integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
"optional": true,
"requires": {
"detect-libc": "^2.0.0",
@ -24281,9 +24282,9 @@
"dev": true
},
"@types/node": {
"version": "12.12.47",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.47.tgz",
"integrity": "sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A=="
"version": "12.20.55",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
},
"@types/parse-json": {
"version": "4.0.0",
@ -34692,7 +34693,7 @@
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"optional": true
},
"tree-kill": {
@ -35210,7 +35211,7 @@
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"optional": true
},
"webpack": {
@ -35450,7 +35451,7 @@
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"optional": true,
"requires": {
"tr46": "~0.0.3",

View file

@ -49,6 +49,7 @@
"@ngneat/transloco": "^3.1.1",
"@types/crypto-js": "^3.1.38",
"@types/w3c-web-hid": "^1.0.2",
"@types/w3c-web-usb": "^1.0.5",
"@zxing/browser": "^0.0.10",
"@zxing/library": "^0.18.6",
"@zxing/ngx-scanner": "^3.4.0",
@ -93,7 +94,7 @@
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.2",
"@types/ledgerhq__hw-transport": "^4.21.3",
"@types/node": "^12.11.1",
"@types/node": "^12.20.39",
"@types/qrcode": "^0.8.1",
"@typescript-eslint/eslint-plugin": "5.17.0",
"@typescript-eslint/parser": "5.17.0",

View file

@ -313,11 +313,12 @@
<div uk-grid *ngIf="selectedImportOption === 'ledger'" class="uk-margin-top">
<div class="uk-width-1-1">
<h3>Use Ledger Hardware Wallet</h3>
<p>
Make sure you have the nano app installed and running on your Ledger, then click one of the buttons below to connect via either USB or Bluetooth.<br>
<a href="https://docs.nault.cc/2020/08/04/ledger-guide.html" target="_blank" rel="noopener noreferrer">Ledger/Nault User Guide and Troubleshooting</a><br>
<div *ngIf="ledger.status === ledgerStatus.NOT_CONNECTED">
<p>Make sure you have the nano app installed and running on your Ledger, then click one of the buttons below to connect via either USB or Bluetooth.</p>
<p *ngIf="!ledgerService.isDesktop && !ledgerService.supportsBluetooth">Bluetooth is currently not supported by your browser, please use Chrome, Edge, Opera or Brave</p>
<p><a href="https://docs.nault.cc/2020/08/04/ledger-guide.html" target="_blank" rel="noopener noreferrer">Ledger/Nault User Guide and Troubleshooting</a></p>
<br>
</p>
</div>
<div *ngIf="!ledgerService.supportsUSB">
<div class="uk-alert uk-alert-warning nlt-inline-alert">
<div class="icon-column">
@ -338,8 +339,7 @@
</div>
<p>
<b>Ledger Device Not Connected</b><br>
Connect your Ledger device and make sure you have the nano app installed and running, then press the button below.<br>
<span *ngIf=!ledgerService.supportsBluetooth>Bluetooth is currently not supported by your browser, please use Google Chrome or <a href="https://github.com/Nault/Nault/releases/latest" target="_blank" rel="noopener noreferrer">download the Desktop App</a></span>
Make sure you have the nano app installed and running on the device, then press connect.<br>
</p>
</div>
</div>
@ -360,12 +360,24 @@
<div uk-icon="icon: check; ratio: 2;"></div>
</div>
<p>
<b>Ledger Device Ready</b><br>
Press the import button below to use your ledger wallet
<b>Ledger Device Connected</b><br>
Ledger data was imported successfully.
</p>
</div>
</div>
</div>
<div *ngIf="ledgerService.isDesktop && !ledgerService.supportsBluetooth && ledger.status === ledgerStatus.NOT_CONNECTED">
<div class="uk-alert uk-alert-danger nlt-inline-alert">
<div class="icon-column">
<div uk-icon="icon: warning; ratio: 2;"></div>
</div>
<p>
<b>No Compatible Bluetooth Hardware</b><br>
The Bluetooth support in Nault for desktop is limited to only specific Bluetooth modules.<br>
For better compatibility, please try <a href="https://nault.cc" target="_blank" rel="noopener noreferrer">Nault.cc</a> in a browser with Bluetooth support (Chrome, Edge, Opera or Brave).
</p>
</div>
</div>
</div>
</div>
<div uk-grid *ngIf="selectedImportOption === 'privateKey'" class="uk-margin-top">

View file

@ -189,13 +189,10 @@ export class ConfigureWalletComponent implements OnInit {
if (!this.isConfigured()) return true;
const UIkit = window['UIkit'];
let msg;
try {
if (this.walletService.isLedgerWallet()) {
msg = '<p class="uk-alert uk-alert-danger"><br><span class="uk-flex"><span uk-icon="icon: warning; ratio: 3;" class="uk-align-center"></span></span><span style="font-size: 18px;">You are about to configure a new wallet, which will <b>disconnect your Ledger device from Nault</b>.</span><br><br>If you need to use the Ledger wallet, simply import your device again.<br><br><b style="font-size: 18px;">Make sure you have saved the recovery phrase you got when initially setting up your Ledger device</b>.<br><br><span style="font-size: 18px;"><b>YOU WILL NOT BE ABLE TO RECOVER THE FUNDS</b><br>if you lose both the recovery phrase and access to your Ledger device.</span></p><br>';
} else {
msg = '<p class="uk-alert uk-alert-danger"><br><span class="uk-flex"><span uk-icon="icon: warning; ratio: 3;" class="uk-align-center"></span></span><span style="font-size: 18px;">You are about to configure a new wallet, which will <b>replace your currently configured wallet</b>.</span><br><br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.before-continuing-make-sure-you-have-saved-the-nano-seed') + '</b><br><br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.you-will-not-be-able-to-recover-the-funds-without-a-backup') + '</b></p><br>';
}
const msg = this.walletService.isLedgerWallet()
? '<p class="uk-alert uk-alert-info"><br><span class="uk-flex"><span uk-icon="icon: info; ratio: 3;" class="uk-align-center"></span></span><span style="font-size: 18px;">You are about to configure a new wallet, which will <b>disconnect your Ledger device from Nault</b>.</span><br><br>If you need to use the Ledger wallet, simply import your device again.</p><br>'
: '<p class="uk-alert uk-alert-danger"><br><span class="uk-flex"><span uk-icon="icon: warning; ratio: 3;" class="uk-align-center"></span></span><span style="font-size: 18px;">You are about to configure a new wallet, which will <b>replace your currently configured wallet</b>.</span><br><br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.before-continuing-make-sure-you-have-saved-the-nano-seed') + '</b><br><br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.you-will-not-be-able-to-recover-the-funds-without-a-backup') + '</b></p><br>';
await UIkit.modal.confirm(msg);
return true;
} catch (err) {

View file

@ -12,11 +12,17 @@
</div>
<div class="uk-card uk-card-default uk-margin" *ngIf="activePanel == 'import'">
<div *ngIf="walletService.isConfigured()" class="uk-alert uk-alert-danger">
<div *ngIf="walletService.isConfigured()">
<div *ngIf="!walletService.isLedgerWallet()" class="uk-alert uk-alert-danger">
<b>You already have a local Nault wallet configured</b><br>
Before going any further, be 100% certain you have backed up the secret recovery phrase for your current wallet!<br>
Without it, <b>any funds you have will become completely unrecoverable!</b>
</div>
<div *ngIf="walletService.isLedgerWallet()" class="uk-alert uk-alert-info">
<b>You are about to import a new wallet, which will disconnect your Ledger device from Nault</b><br>
If you need to use the Ledger wallet later, simply import your device again.
</div>
</div>
<div class="uk-card-header">
<h3 class="uk-card-title">Confirm Wallet Import</h3>
</div>

View file

@ -1,5 +1,5 @@
<div *ngIf="walletService.isLedgerWallet()">
<div class="nav-status-row" *ngIf="ledgerStatus === 'not-connected' || !ledgerStatus">
<div class="nav-status-row" *ngIf="ledgerStatus.status === 'not-connected' || !ledgerStatus.status">
<div class="status-icon">
<span class="uk-text-warning" uk-icon="icon: warning; ratio: 1.2;"></span>
</div>
@ -8,7 +8,7 @@
<div class="label secondary"><a (click)="reloadLedger()">Reconnect</a> or <a href="https://docs.nault.cc/2020/08/04/ledger-guide.html#troubleshooting" target="_blank" rel="noopener noreferrer">view Troubleshooting Guide</a></div>
</div>
</div>
<div class="nav-status-row" *ngIf="( ledgerStatus === 'locked' )">
<div class="nav-status-row" *ngIf="( ledgerStatus.status === 'locked' )">
<div class="status-icon">
<span class="uk-text-warning" uk-icon="icon: warning; ratio: 1.2;"></span>
</div>
@ -17,7 +17,7 @@
<div class="label secondary">Unlock the device, then <a (click)="reloadLedger()">click here</a> to reconnect</div>
</div>
</div>
<div class="nav-status-row interactable" (click)="reloadLedger()" *ngIf="( ledgerStatus === 'ready' )">
<div class="nav-status-row interactable" (click)="reloadLedger()" *ngIf="( ledgerStatus.status === 'ready' )">
<div class="status-icon">
<span class="uk-text-success" uk-icon="icon: bolt; ratio: 1.2;"></span>
</div>

View file

@ -13,7 +13,10 @@ import {PowService} from '../../services/pow.service';
export class WalletWidgetComponent implements OnInit {
wallet = this.walletService.wallet;
ledgerStatus = 'not-connected';
ledgerStatus = {
status: 'not-connected',
statusText: '',
};
powAlert = false;
unlockPassword = '';
@ -39,8 +42,8 @@ export class WalletWidgetComponent implements OnInit {
});
this.modal = modal;
this.ledgerService.ledgerStatus$.subscribe((ledgerStatus: any) => {
this.ledgerStatus = ledgerStatus.status;
this.ledgerService.ledgerStatus$.subscribe((ledgerStatus) => {
this.ledgerStatus = ledgerStatus;
});
// Detect if a PoW is taking too long and alert
@ -89,7 +92,7 @@ export class WalletWidgetComponent implements OnInit {
try {
await this.ledgerService.loadLedger();
this.notificationService.removeNotification('ledger-status');
if (this.ledgerStatus === LedgerStatus.READY) {
if (this.ledgerStatus.status === LedgerStatus.READY) {
this.notificationService.sendSuccess(`Successfully connected to Ledger device`);
}
} catch (err) {

View file

@ -5,7 +5,6 @@ import TransportUSB from '@ledgerhq/hw-transport-webusb';
import TransportHID from '@ledgerhq/hw-transport-webhid';
import TransportBLE from '@ledgerhq/hw-transport-web-ble';
import Transport from '@ledgerhq/hw-transport';
import * as LedgerLogs from '@ledgerhq/logs';
import {Subject} from 'rxjs';
import {ApiService} from './api.service';
import {NotificationService} from './notification.service';
@ -47,9 +46,9 @@ const zeroBlock = '0000000000000000000000000000000000000000000000000000000000000
export class LedgerService {
walletPrefix = `44'/165'/`;
waitTimeout = 300000;
normalTimeout = 5000;
pollInterval = 15000;
waitTimeout = 30000;
pollInterval = 5000;
u2fPollInterval = 30000;
pollingLedger = false;
@ -70,9 +69,9 @@ export class LedgerService {
supportsUSB = false;
transportMode: 'U2F' | 'USB' | 'HID' | 'Bluetooth' = 'U2F';
DynamicTransport = TransportU2F;
DynamicTransport: typeof TransportUSB | typeof TransportHID | typeof TransportBLE = TransportU2F;
ledgerStatus$: Subject<any> = new Subject();
ledgerStatus$: Subject<{ status: string, statusText: string }> = new Subject();
desktopMessage$ = new Subject();
constructor(private api: ApiService,
@ -118,6 +117,7 @@ export class LedgerService {
}
});
this.supportsUSB = true;
this.supportsBluetooth = true;
}
/**
@ -137,14 +137,8 @@ export class LedgerService {
* Detect the optimal USB transport protocol for the current browser and OS
*/
detectUsbTransport() {
const isWindows = window.navigator.platform.includes('Win');
if (isWindows && this.supportsWebHID) {
// Prefer WebHID on Windows due to stability issues with WebUSB
this.transportMode = 'HID';
this.DynamicTransport = TransportHID;
} else if (this.supportsWebUSB) {
// Else prefer WebUSB
if (this.supportsWebUSB) {
// Prefer WebUSB
this.transportMode = 'USB';
this.DynamicTransport = TransportUSB;
} else if (this.supportsWebHID) {
@ -267,11 +261,10 @@ export class LedgerService {
async loadTransport() {
return new Promise((resolve, reject) => {
this.DynamicTransport.create().then(trans => {
this.DynamicTransport.create(3000, this.waitTimeout).then(trans => {
// LedgerLogs.listen((log: LedgerLog) => console.log(`Ledger: ${log.type}: ${log.message}`));
this.ledger.transport = trans;
this.ledger.transport.setExchangeTimeout(this.waitTimeout); // 5 minutes
this.ledger.nano = new Nano(this.ledger.transport);
resolve(this.ledger.transport);
@ -298,6 +291,9 @@ export class LedgerService {
const sub = this.ledgerStatus$.subscribe(newStatus => {
if (newStatus.status === LedgerStatus.READY) {
resolve(true);
} else if (newStatus.statusText.includes('No compatible USB Bluetooth 4.0 device found') || newStatus.statusText.includes('Could not start scanning')) {
this.supportsBluetooth = false;
reject(newStatus.statusText);
} else {
reject(new Error(newStatus.statusText || `Unable to load desktop Ledger device`));
}
@ -323,6 +319,9 @@ export class LedgerService {
console.log(`Error loading ${this.transportMode} transport `, err);
this.ledger.status = LedgerStatus.NOT_CONNECTED;
this.ledgerStatus$.next({ status: this.ledger.status, statusText: `Unable to load Ledger transport: ${err.message || err}` });
if (!hideNotifications) {
this.notifications.sendWarning(`Ledger connection failed. Make sure your Ledger is unlocked. Restart the nano app on your Ledger if the error persists`);
}
}
this.resetLedger();
resolve(false);
@ -333,9 +332,6 @@ export class LedgerService {
return resolve(false);
}
if (this.ledger.status === LedgerStatus.READY) {
return resolve(true); // Already ready?
}
let resolved = false;
// Set up a timeout when things are not ready
@ -357,12 +353,10 @@ export class LedgerService {
resolved = true;
if (!ledgerConfig) return resolve(false);
if (ledgerConfig && ledgerConfig.version) {
this.ledger.status = LedgerStatus.LOCKED;
this.ledgerStatus$.next({ status: this.ledger.status, statusText: `Nano app detected, but ledger is locked` });
}
} catch (err) {
console.log(`App config error: `, err);
this.ledger.status = LedgerStatus.NOT_CONNECTED;
this.ledgerStatus$.next({ status: this.ledger.status, statusText: `Unable to load Nano App configuration: ${err.message || err}` });
if (err.statusText === 'HALTED') {
this.resetLedger();
}
@ -452,9 +446,8 @@ export class LedgerService {
await this.loadLedger(); // Make sure ledger is ready
}
if (this.isDesktop) {
return this.signBlockDesktop(accountIndex, blockData);
return await this.signBlockDesktop(accountIndex, blockData);
} else {
this.ledger.transport.setExchangeTimeout(this.waitTimeout);
return await this.ledger.nano.signBlock(this.ledgerPath(accountIndex), blockData);
}
}
@ -464,7 +457,6 @@ export class LedgerService {
}
async getLedgerAccountWeb(accountIndex: number, showOnScreen = false) {
this.ledger.transport.setExchangeTimeout(showOnScreen ? this.waitTimeout : this.normalTimeout);
try {
return await this.ledger.nano.getAddress(this.ledgerPath(accountIndex), showOnScreen);
} catch (err) {
@ -483,9 +475,10 @@ export class LedgerService {
pollLedgerStatus() {
if (!this.pollingLedger) return;
setTimeout(async () => {
if (!this.pollingLedger) return;
await this.checkLedgerStatus();
this.pollLedgerStatus();
}, this.pollInterval);
}, this.transportMode === 'U2F' ? this.u2fPollInterval : this.pollInterval);
}
async checkLedgerStatus() {
@ -499,8 +492,12 @@ export class LedgerService {
} catch (err) {
// Ignore race condition error, which means an action is pending on the ledger (such as block confirmation)
if (err.name !== 'TransportRaceCondition') {
console.log('Check ledger status failed ', err);
console.log('Check ledger status failed ', JSON.stringify(err));
if (err.statusCode === STATUS_CODES.SECURITY_STATUS_NOT_SATISFIED) {
this.ledger.status = LedgerStatus.LOCKED;
} else {
this.ledger.status = LedgerStatus.NOT_CONNECTED;
}
this.pollingLedger = false;
this.resetLedger();
}

View file

@ -13,5 +13,8 @@
],
"include": [
"src/**/*.d.ts"
],
"exclude": [
"**/node_modules/**"
]
}

View file

@ -13,7 +13,10 @@
"polyfills.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
"src/**/*.spec.ts",
"src/**/*.d.ts"
],
"exclude": [
"node_modules"
]
}