@bytezhang/ledger-adapter 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +16 -4
- package/dist/index.d.ts +16 -4
- package/dist/index.js +126 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IHardwareWallet, IConnector, TransportType, IUiHandler, DeviceInfo, Response, ChainCapability, HardwareEventMap, DeviceEventListener, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmGetPublicKeyParams, EvmPublicKey, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolGetPublicKeyParams, SolPublicKey, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, DeviceDescriptor, DeviceChangeEvent, HardwareErrorCode } from '@bytezhang/hardware-wallet-core';
|
|
1
|
+
import { IHardwareWallet, IConnector, TransportType, IUiHandler, DeviceInfo, Response, ChainCapability, HardwareEventMap, DeviceEventListener, ChainForFingerprint, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmGetPublicKeyParams, EvmPublicKey, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolGetPublicKeyParams, SolPublicKey, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, DeviceDescriptor, DeviceChangeEvent, HardwareErrorCode } from '@bytezhang/hardware-wallet-core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Ledger hardware wallet adapter that delegates to an IConnector.
|
|
@@ -34,6 +34,18 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
34
34
|
off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
35
35
|
off(event: string, listener: DeviceEventListener): void;
|
|
36
36
|
cancel(connectId: string): void;
|
|
37
|
+
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
38
|
+
/**
|
|
39
|
+
* Verify that the connected device matches the expected fingerprint.
|
|
40
|
+
*
|
|
41
|
+
* - If deviceId is empty, verification is skipped (returns true).
|
|
42
|
+
* - deviceId is used here as the stored fingerprint to compare against.
|
|
43
|
+
*/
|
|
44
|
+
private _verifyDeviceFingerprint;
|
|
45
|
+
/**
|
|
46
|
+
* Derive an address at the fixed testnet path for fingerprint generation.
|
|
47
|
+
*/
|
|
48
|
+
private _deriveAddressForFingerprint;
|
|
37
49
|
evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
|
|
38
50
|
evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
|
|
39
51
|
evmGetPublicKey(connectId: string, _deviceId: string, params: EvmGetPublicKeyParams): Promise<Response<EvmPublicKey>>;
|
|
@@ -45,9 +57,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
45
57
|
btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
|
|
46
58
|
btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
|
|
47
59
|
btcSignMessage(_connectId: string, _deviceId: string, _params: BtcSignMsgParams): Promise<Response<BtcSignature>>;
|
|
48
|
-
btcGetMasterFingerprint(connectId: string, _deviceId: string
|
|
49
|
-
skipOpenApp?: boolean;
|
|
50
|
-
}): Promise<Response<{
|
|
60
|
+
btcGetMasterFingerprint(connectId: string, _deviceId: string): Promise<Response<{
|
|
51
61
|
masterFingerprint: string;
|
|
52
62
|
}>>;
|
|
53
63
|
solGetAddress(_connectId: string, _deviceId: string, _params: SolGetAddressParams): Promise<Response<SolAddress>>;
|
|
@@ -64,6 +74,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
64
74
|
*/
|
|
65
75
|
private static readonly MAX_DEVICE_RETRY;
|
|
66
76
|
private _deviceConnectResolve;
|
|
77
|
+
private _connectingPromise;
|
|
67
78
|
private static readonly DEVICE_CONNECT_TIMEOUT_MS;
|
|
68
79
|
/**
|
|
69
80
|
* Wait for user to connect and unlock device.
|
|
@@ -79,6 +90,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
79
90
|
*/
|
|
80
91
|
deviceConnectResponse(type: 'confirm' | 'cancel'): void;
|
|
81
92
|
private ensureConnected;
|
|
93
|
+
private _doConnect;
|
|
82
94
|
private _connectFirstOrSelect;
|
|
83
95
|
/**
|
|
84
96
|
* Call the connector with automatic session resolution and disconnect retry.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IHardwareWallet, IConnector, TransportType, IUiHandler, DeviceInfo, Response, ChainCapability, HardwareEventMap, DeviceEventListener, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmGetPublicKeyParams, EvmPublicKey, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolGetPublicKeyParams, SolPublicKey, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, DeviceDescriptor, DeviceChangeEvent, HardwareErrorCode } from '@bytezhang/hardware-wallet-core';
|
|
1
|
+
import { IHardwareWallet, IConnector, TransportType, IUiHandler, DeviceInfo, Response, ChainCapability, HardwareEventMap, DeviceEventListener, ChainForFingerprint, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmGetPublicKeyParams, EvmPublicKey, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolGetPublicKeyParams, SolPublicKey, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, DeviceDescriptor, DeviceChangeEvent, HardwareErrorCode } from '@bytezhang/hardware-wallet-core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Ledger hardware wallet adapter that delegates to an IConnector.
|
|
@@ -34,6 +34,18 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
34
34
|
off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
35
35
|
off(event: string, listener: DeviceEventListener): void;
|
|
36
36
|
cancel(connectId: string): void;
|
|
37
|
+
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
38
|
+
/**
|
|
39
|
+
* Verify that the connected device matches the expected fingerprint.
|
|
40
|
+
*
|
|
41
|
+
* - If deviceId is empty, verification is skipped (returns true).
|
|
42
|
+
* - deviceId is used here as the stored fingerprint to compare against.
|
|
43
|
+
*/
|
|
44
|
+
private _verifyDeviceFingerprint;
|
|
45
|
+
/**
|
|
46
|
+
* Derive an address at the fixed testnet path for fingerprint generation.
|
|
47
|
+
*/
|
|
48
|
+
private _deriveAddressForFingerprint;
|
|
37
49
|
evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
|
|
38
50
|
evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
|
|
39
51
|
evmGetPublicKey(connectId: string, _deviceId: string, params: EvmGetPublicKeyParams): Promise<Response<EvmPublicKey>>;
|
|
@@ -45,9 +57,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
45
57
|
btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
|
|
46
58
|
btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
|
|
47
59
|
btcSignMessage(_connectId: string, _deviceId: string, _params: BtcSignMsgParams): Promise<Response<BtcSignature>>;
|
|
48
|
-
btcGetMasterFingerprint(connectId: string, _deviceId: string
|
|
49
|
-
skipOpenApp?: boolean;
|
|
50
|
-
}): Promise<Response<{
|
|
60
|
+
btcGetMasterFingerprint(connectId: string, _deviceId: string): Promise<Response<{
|
|
51
61
|
masterFingerprint: string;
|
|
52
62
|
}>>;
|
|
53
63
|
solGetAddress(_connectId: string, _deviceId: string, _params: SolGetAddressParams): Promise<Response<SolAddress>>;
|
|
@@ -64,6 +74,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
64
74
|
*/
|
|
65
75
|
private static readonly MAX_DEVICE_RETRY;
|
|
66
76
|
private _deviceConnectResolve;
|
|
77
|
+
private _connectingPromise;
|
|
67
78
|
private static readonly DEVICE_CONNECT_TIMEOUT_MS;
|
|
68
79
|
/**
|
|
69
80
|
* Wait for user to connect and unlock device.
|
|
@@ -79,6 +90,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
79
90
|
*/
|
|
80
91
|
deviceConnectResponse(type: 'confirm' | 'cancel'): void;
|
|
81
92
|
private ensureConnected;
|
|
93
|
+
private _doConnect;
|
|
82
94
|
private _connectFirstOrSelect;
|
|
83
95
|
/**
|
|
84
96
|
* Call the connector with automatic session resolution and disconnect retry.
|
package/dist/index.js
CHANGED
|
@@ -169,6 +169,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
169
169
|
this._sessions = /* @__PURE__ */ new Map();
|
|
170
170
|
// Pending device-connect resolve — set by _waitForDeviceConnect, resolved by uiResponse
|
|
171
171
|
this._deviceConnectResolve = null;
|
|
172
|
+
// Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections
|
|
173
|
+
this._connectingPromise = null;
|
|
172
174
|
// ---------------------------------------------------------------------------
|
|
173
175
|
// Event translation
|
|
174
176
|
// ---------------------------------------------------------------------------
|
|
@@ -222,6 +224,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
222
224
|
async init(_config) {
|
|
223
225
|
}
|
|
224
226
|
async dispose() {
|
|
227
|
+
this._deviceConnectResolve?.(true);
|
|
228
|
+
this._deviceConnectResolve = null;
|
|
225
229
|
this.unregisterEventListeners();
|
|
226
230
|
this.connector.reset();
|
|
227
231
|
this._uiHandler = null;
|
|
@@ -293,10 +297,74 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
293
297
|
void this.connector.cancel(sessionId);
|
|
294
298
|
}
|
|
295
299
|
// ---------------------------------------------------------------------------
|
|
300
|
+
// Chain fingerprint
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
async getChainFingerprint(connectId, deviceId, chain) {
|
|
303
|
+
await this._ensureDevicePermission(connectId, deviceId);
|
|
304
|
+
try {
|
|
305
|
+
const address = await this._deriveAddressForFingerprint(connectId, chain);
|
|
306
|
+
return (0, import_hardware_wallet_core2.success)((0, import_hardware_wallet_core2.deriveDeviceFingerprint)(address));
|
|
307
|
+
} catch (err) {
|
|
308
|
+
return this.errorToFailure(err);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Verify that the connected device matches the expected fingerprint.
|
|
313
|
+
*
|
|
314
|
+
* - If deviceId is empty, verification is skipped (returns true).
|
|
315
|
+
* - deviceId is used here as the stored fingerprint to compare against.
|
|
316
|
+
*/
|
|
317
|
+
async _verifyDeviceFingerprint(connectId, deviceId, chain) {
|
|
318
|
+
if (!deviceId) return true;
|
|
319
|
+
try {
|
|
320
|
+
const address = await this._deriveAddressForFingerprint(connectId, chain);
|
|
321
|
+
const fingerprint = (0, import_hardware_wallet_core2.deriveDeviceFingerprint)(address);
|
|
322
|
+
return fingerprint === deviceId;
|
|
323
|
+
} catch (err) {
|
|
324
|
+
const mapped = mapLedgerError(err);
|
|
325
|
+
if (mapped.code === import_hardware_wallet_core2.HardwareErrorCode.WrongApp || mapped.code === import_hardware_wallet_core2.HardwareErrorCode.DeviceLocked) {
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
throw err;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Derive an address at the fixed testnet path for fingerprint generation.
|
|
333
|
+
*/
|
|
334
|
+
async _deriveAddressForFingerprint(connectId, chain) {
|
|
335
|
+
const path = import_hardware_wallet_core2.CHAIN_FINGERPRINT_PATHS[chain];
|
|
336
|
+
if (chain === "evm") {
|
|
337
|
+
const result = await this.connectorCall(connectId, "evmGetAddress", {
|
|
338
|
+
path,
|
|
339
|
+
showOnDevice: false
|
|
340
|
+
});
|
|
341
|
+
return result.address;
|
|
342
|
+
}
|
|
343
|
+
if (chain === "btc") {
|
|
344
|
+
const result = await this.connectorCall(connectId, "btcGetAddress", {
|
|
345
|
+
path,
|
|
346
|
+
showOnDevice: false,
|
|
347
|
+
coin: "Testnet"
|
|
348
|
+
});
|
|
349
|
+
return result.address;
|
|
350
|
+
}
|
|
351
|
+
if (chain === "sol") {
|
|
352
|
+
const result = await this.connectorCall(connectId, "solGetAddress", {
|
|
353
|
+
path,
|
|
354
|
+
showOnDevice: false
|
|
355
|
+
});
|
|
356
|
+
return result.address;
|
|
357
|
+
}
|
|
358
|
+
throw new Error(`Unsupported chain for fingerprint: ${chain}`);
|
|
359
|
+
}
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
296
361
|
// EVM methods
|
|
297
362
|
// ---------------------------------------------------------------------------
|
|
298
363
|
async evmGetAddress(connectId, _deviceId, params) {
|
|
299
364
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
365
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "evm")) {
|
|
366
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
367
|
+
}
|
|
300
368
|
try {
|
|
301
369
|
const result = await this.connectorCall(connectId, "evmGetAddress", {
|
|
302
370
|
path: params.path,
|
|
@@ -320,6 +388,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
320
388
|
}
|
|
321
389
|
async evmGetPublicKey(connectId, _deviceId, params) {
|
|
322
390
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
391
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "evm")) {
|
|
392
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
393
|
+
}
|
|
323
394
|
try {
|
|
324
395
|
const result = await this.connectorCall(connectId, "evmGetAddress", {
|
|
325
396
|
path: params.path,
|
|
@@ -335,21 +406,19 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
335
406
|
}
|
|
336
407
|
async evmSignTransaction(connectId, _deviceId, params) {
|
|
337
408
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
409
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "evm")) {
|
|
410
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
411
|
+
}
|
|
338
412
|
try {
|
|
413
|
+
if (!params.serializedTx) {
|
|
414
|
+
return (0, import_hardware_wallet_core2.failure)(
|
|
415
|
+
import_hardware_wallet_core2.HardwareErrorCode.InvalidParams,
|
|
416
|
+
"Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string."
|
|
417
|
+
);
|
|
418
|
+
}
|
|
339
419
|
const result = await this.connectorCall(connectId, "evmSignTransaction", {
|
|
340
420
|
path: params.path,
|
|
341
|
-
|
|
342
|
-
to: params.to,
|
|
343
|
-
value: params.value,
|
|
344
|
-
chainId: params.chainId,
|
|
345
|
-
nonce: params.nonce,
|
|
346
|
-
gasLimit: params.gasLimit,
|
|
347
|
-
gasPrice: params.gasPrice,
|
|
348
|
-
maxFeePerGas: params.maxFeePerGas,
|
|
349
|
-
maxPriorityFeePerGas: params.maxPriorityFeePerGas,
|
|
350
|
-
accessList: params.accessList,
|
|
351
|
-
data: params.data
|
|
352
|
-
}
|
|
421
|
+
serializedTx: params.serializedTx
|
|
353
422
|
});
|
|
354
423
|
return (0, import_hardware_wallet_core2.success)({
|
|
355
424
|
v: ensure0x(result.v),
|
|
@@ -362,6 +431,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
362
431
|
}
|
|
363
432
|
async evmSignMessage(connectId, _deviceId, params) {
|
|
364
433
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
434
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "evm")) {
|
|
435
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
436
|
+
}
|
|
365
437
|
try {
|
|
366
438
|
const result = await this.connectorCall(connectId, "evmSignMessage", {
|
|
367
439
|
path: params.path,
|
|
@@ -376,6 +448,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
376
448
|
}
|
|
377
449
|
async evmSignTypedData(connectId, _deviceId, params) {
|
|
378
450
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
451
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "evm")) {
|
|
452
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
453
|
+
}
|
|
379
454
|
if (params.mode === "hash") {
|
|
380
455
|
return (0, import_hardware_wallet_core2.failure)(
|
|
381
456
|
import_hardware_wallet_core2.HardwareErrorCode.MethodNotSupported,
|
|
@@ -399,6 +474,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
399
474
|
// ---------------------------------------------------------------------------
|
|
400
475
|
async btcGetAddress(connectId, _deviceId, params) {
|
|
401
476
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
477
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "btc")) {
|
|
478
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
479
|
+
}
|
|
402
480
|
try {
|
|
403
481
|
const result = await this.connectorCall(connectId, "btcGetAddress", {
|
|
404
482
|
path: params.path,
|
|
@@ -423,6 +501,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
423
501
|
}
|
|
424
502
|
async btcGetPublicKey(connectId, _deviceId, params) {
|
|
425
503
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
504
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "btc")) {
|
|
505
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
506
|
+
}
|
|
426
507
|
try {
|
|
427
508
|
const result = await this.connectorCall(connectId, "btcGetPublicKey", {
|
|
428
509
|
path: params.path,
|
|
@@ -443,6 +524,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
443
524
|
}
|
|
444
525
|
async btcSignTransaction(connectId, _deviceId, params) {
|
|
445
526
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
527
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "btc")) {
|
|
528
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
529
|
+
}
|
|
446
530
|
if (!params.psbt) {
|
|
447
531
|
return (0, import_hardware_wallet_core2.failure)(
|
|
448
532
|
import_hardware_wallet_core2.HardwareErrorCode.InvalidParams,
|
|
@@ -463,12 +547,13 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
463
547
|
// ---------------------------------------------------------------------------
|
|
464
548
|
// Device fingerprint
|
|
465
549
|
// ---------------------------------------------------------------------------
|
|
466
|
-
async btcGetMasterFingerprint(connectId, _deviceId
|
|
550
|
+
async btcGetMasterFingerprint(connectId, _deviceId) {
|
|
467
551
|
await this._ensureDevicePermission(connectId, _deviceId);
|
|
552
|
+
if (!await this._verifyDeviceFingerprint(connectId, _deviceId, "btc")) {
|
|
553
|
+
return (0, import_hardware_wallet_core2.failure)(import_hardware_wallet_core2.HardwareErrorCode.DeviceMismatch, "Wrong device connected");
|
|
554
|
+
}
|
|
468
555
|
try {
|
|
469
|
-
const result = await this.connectorCall(connectId, "btcGetMasterFingerprint", {
|
|
470
|
-
skipOpenApp: params?.skipOpenApp
|
|
471
|
-
});
|
|
556
|
+
const result = await this.connectorCall(connectId, "btcGetMasterFingerprint", {});
|
|
472
557
|
return (0, import_hardware_wallet_core2.success)({ masterFingerprint: result.masterFingerprint });
|
|
473
558
|
} catch (err) {
|
|
474
559
|
return this.errorToFailure(err);
|
|
@@ -515,7 +600,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
515
600
|
clearTimeout(timer);
|
|
516
601
|
this._deviceConnectResolve = null;
|
|
517
602
|
if (cancelled) {
|
|
518
|
-
reject(
|
|
603
|
+
reject(Object.assign(
|
|
604
|
+
new Error("User cancelled Ledger connection"),
|
|
605
|
+
{ _tag: "DeviceNotRecognizedError" }
|
|
606
|
+
));
|
|
519
607
|
} else {
|
|
520
608
|
resolve();
|
|
521
609
|
}
|
|
@@ -546,6 +634,17 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
546
634
|
if (this._sessions.size > 0) {
|
|
547
635
|
return this._sessions.keys().next().value;
|
|
548
636
|
}
|
|
637
|
+
if (this._connectingPromise) {
|
|
638
|
+
return this._connectingPromise;
|
|
639
|
+
}
|
|
640
|
+
this._connectingPromise = this._doConnect();
|
|
641
|
+
try {
|
|
642
|
+
return await this._connectingPromise;
|
|
643
|
+
} finally {
|
|
644
|
+
this._connectingPromise = null;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
async _doConnect() {
|
|
549
648
|
for (let attempt = 0; attempt < _LedgerAdapter.MAX_DEVICE_RETRY; attempt++) {
|
|
550
649
|
const devices = await this.searchDevices();
|
|
551
650
|
if (devices.length > 0) {
|
|
@@ -779,7 +878,8 @@ var LedgerDeviceManager = class {
|
|
|
779
878
|
return new Promise((resolve) => {
|
|
780
879
|
let resolved = false;
|
|
781
880
|
let syncResult = null;
|
|
782
|
-
|
|
881
|
+
let sub = null;
|
|
882
|
+
sub = this._dmk.listenToAvailableDevices().subscribe({
|
|
783
883
|
next: (devices) => {
|
|
784
884
|
if (resolved) return;
|
|
785
885
|
resolved = true;
|
|
@@ -787,7 +887,12 @@ var LedgerDeviceManager = class {
|
|
|
787
887
|
for (const d of devices) {
|
|
788
888
|
this._discovered.set(d.id, d);
|
|
789
889
|
}
|
|
790
|
-
|
|
890
|
+
if (sub) {
|
|
891
|
+
sub.unsubscribe();
|
|
892
|
+
resolve(devices.map((d) => ({ path: d.id, type: d.deviceModel.id })));
|
|
893
|
+
} else {
|
|
894
|
+
syncResult = devices;
|
|
895
|
+
}
|
|
791
896
|
},
|
|
792
897
|
error: () => {
|
|
793
898
|
if (!resolved) {
|
|
@@ -799,7 +904,7 @@ var LedgerDeviceManager = class {
|
|
|
799
904
|
if (syncResult !== null) {
|
|
800
905
|
sub.unsubscribe();
|
|
801
906
|
const devices = syncResult;
|
|
802
|
-
resolve(devices.map((d) => ({ path: d.id, type: d.deviceModel.
|
|
907
|
+
resolve(devices.map((d) => ({ path: d.id, type: d.deviceModel.id })));
|
|
803
908
|
}
|
|
804
909
|
});
|
|
805
910
|
}
|
|
@@ -820,7 +925,7 @@ var LedgerDeviceManager = class {
|
|
|
820
925
|
name: d.name
|
|
821
926
|
}));
|
|
822
927
|
if (!previousIds.has(d.id)) {
|
|
823
|
-
onChange({ type: "device-connected", descriptor: { path: d.id, type: d.deviceModel.
|
|
928
|
+
onChange({ type: "device-connected", descriptor: { path: d.id, type: d.deviceModel.id } });
|
|
824
929
|
}
|
|
825
930
|
}
|
|
826
931
|
for (const id of previousIds) {
|