@onekeyfe/hwk-ledger-adapter 1.2.0-alpha.12 → 1.2.0-alpha.13
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 +28 -17
- package/dist/index.d.ts +28 -17
- package/dist/index.js +773 -286
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +699 -209
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -53,7 +53,7 @@ __export(index_exports, {
|
|
|
53
53
|
module.exports = __toCommonJS(index_exports);
|
|
54
54
|
|
|
55
55
|
// src/adapter/LedgerAdapter.ts
|
|
56
|
-
var
|
|
56
|
+
var import_hwk_adapter_core3 = require("@onekeyfe/hwk-adapter-core");
|
|
57
57
|
|
|
58
58
|
// src/errors.ts
|
|
59
59
|
var import_hwk_adapter_core = require("@onekeyfe/hwk-adapter-core");
|
|
@@ -75,30 +75,37 @@ var USER_REJECTED_CODES = /* @__PURE__ */ new Set(["6985", "27013"]);
|
|
|
75
75
|
var WRONG_APP_CODES = /* @__PURE__ */ new Set(["6e00", "28160", "6d00", "27904", "6a83", "27267"]);
|
|
76
76
|
var APP_NOT_INSTALLED_CODES = /* @__PURE__ */ new Set(["6807", "26631"]);
|
|
77
77
|
var STEP_BLIND_SIGN_TRANSACTION_FALLBACK = "signer.eth.steps.blindSignTransactionFallback";
|
|
78
|
+
var STEP_DETECT_BLIND_SIGNING = "signer.eth.steps.detectBlindSigning";
|
|
79
|
+
var BLIND_SIGNING_STEPS = /* @__PURE__ */ new Set([
|
|
80
|
+
STEP_BLIND_SIGN_TRANSACTION_FALLBACK,
|
|
81
|
+
STEP_DETECT_BLIND_SIGNING
|
|
82
|
+
]);
|
|
83
|
+
function normalizeApduHex(value) {
|
|
84
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 65535) {
|
|
85
|
+
return value.toString(16).padStart(4, "0");
|
|
86
|
+
}
|
|
87
|
+
if (typeof value !== "string") return null;
|
|
88
|
+
const raw = value.toLowerCase().replace(/^0x/, "");
|
|
89
|
+
return /^[0-9a-f]{1,4}$/i.test(raw) ? raw.padStart(4, "0") : null;
|
|
90
|
+
}
|
|
78
91
|
function getEthAppErrorCode(err) {
|
|
79
92
|
if (!err || typeof err !== "object") return null;
|
|
80
93
|
const e = err;
|
|
81
|
-
if (e._tag === ERROR_TAG.EthAppCommand
|
|
82
|
-
|
|
94
|
+
if (e._tag === ERROR_TAG.EthAppCommand) {
|
|
95
|
+
const code = normalizeApduHex(e.errorCode) ?? normalizeApduHex(e.statusCode) ?? normalizeApduHex(e.code);
|
|
96
|
+
if (code) return code;
|
|
83
97
|
}
|
|
84
98
|
const orig = e.originalError;
|
|
85
|
-
if (orig?._tag === ERROR_TAG.EthAppCommand
|
|
86
|
-
return orig.errorCode.
|
|
99
|
+
if (orig?._tag === ERROR_TAG.EthAppCommand) {
|
|
100
|
+
return normalizeApduHex(orig.errorCode) ?? normalizeApduHex(orig.statusCode) ?? normalizeApduHex(orig.code);
|
|
87
101
|
}
|
|
88
102
|
return null;
|
|
89
103
|
}
|
|
90
104
|
function extractApduHex(err) {
|
|
91
105
|
if (!err || typeof err !== "object") return null;
|
|
92
106
|
const e = err;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
if (typeof e.statusCode === "number" && Number.isFinite(e.statusCode)) {
|
|
97
|
-
return e.statusCode.toString(16).padStart(4, "0");
|
|
98
|
-
}
|
|
99
|
-
if (typeof e.statusCode === "string" && /^[0-9a-f]+$/i.test(e.statusCode)) {
|
|
100
|
-
return e.statusCode.toLowerCase();
|
|
101
|
-
}
|
|
107
|
+
const direct = normalizeApduHex(e.errorCode) ?? normalizeApduHex(e.statusCode);
|
|
108
|
+
if (direct) return direct;
|
|
102
109
|
if (e.originalError != null) {
|
|
103
110
|
const nested = extractApduHex(e.originalError);
|
|
104
111
|
if (nested) return nested;
|
|
@@ -157,10 +164,15 @@ function classifyEthAppError(err) {
|
|
|
157
164
|
const ethCode = getEthAppErrorCode(err);
|
|
158
165
|
if (!ethCode) return null;
|
|
159
166
|
if (ethCode === "6a80") {
|
|
160
|
-
return
|
|
167
|
+
return hasBlindSigningStep(err) ? import_hwk_adapter_core.HardwareErrorCode.EvmBlindSigningRequired : null;
|
|
161
168
|
}
|
|
162
169
|
return mapEthAppErrorCode(ethCode);
|
|
163
170
|
}
|
|
171
|
+
function classifyBlindSigningDetectionError(err) {
|
|
172
|
+
if (!hasBlindSigningStep(err)) return null;
|
|
173
|
+
if (hasInvalidArgumentCode(err)) return import_hwk_adapter_core.HardwareErrorCode.EvmBlindSigningRequired;
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
164
176
|
var ERROR_TAG = {
|
|
165
177
|
// SDK-mint
|
|
166
178
|
DeviceNotAdvertising: "DeviceNotAdvertisingError",
|
|
@@ -176,6 +188,10 @@ var ERROR_TAG = {
|
|
|
176
188
|
// chain app wedged (APDU 0x6901)
|
|
177
189
|
DeviceTransportStuck: "DeviceTransportStuck",
|
|
178
190
|
// DMK transport queue wedged
|
|
191
|
+
// installApp resolved success but the app is still missing on device —
|
|
192
|
+
// DMK quirk. Surfaced as a distinct tag so callers can tell it apart from
|
|
193
|
+
// the original DMK-thrown AppNotInstalled.
|
|
194
|
+
AppInstallVerifyFailed: "AppInstallVerifyFailedError",
|
|
179
195
|
// DMK-reuse (DMK throws same string; we synthesize too)
|
|
180
196
|
DeviceLocked: "DeviceLockedError",
|
|
181
197
|
DeviceNotRecognized: "DeviceNotRecognizedError",
|
|
@@ -201,7 +217,11 @@ var ERROR_TAG = {
|
|
|
201
217
|
// ble-plx surfaces this when GATT notification setup fails — typical
|
|
202
218
|
// outcome when the user doesn't confirm pairing on the device, or the
|
|
203
219
|
// existing bond is invalid. Observed in production after ~30s.
|
|
204
|
-
PairingRefused: "PairingRefusedError"
|
|
220
|
+
PairingRefused: "PairingRefusedError",
|
|
221
|
+
// DMK remote-network failures (manager-api HTTP / secure-channel WS).
|
|
222
|
+
WebSocketConnection: "WebSocketConnectionError",
|
|
223
|
+
HttpFetch: "FetchError",
|
|
224
|
+
InvalidFirmwareMetadataResponse: "InvalidGetFirmwareMetadataResponseError"
|
|
205
225
|
};
|
|
206
226
|
function isDeviceLockedError(err) {
|
|
207
227
|
if (!err || typeof err !== "object") return false;
|
|
@@ -289,15 +309,30 @@ function hasStatusCode(err, codeSet) {
|
|
|
289
309
|
if (e.error != null && e._tag && hasStatusCode(e.error, codeSet)) return true;
|
|
290
310
|
return false;
|
|
291
311
|
}
|
|
292
|
-
function
|
|
312
|
+
function hasDeviceActionStep(err, step) {
|
|
293
313
|
if (!err || typeof err !== "object") return false;
|
|
294
314
|
const e = err;
|
|
295
|
-
if (e._lastStep ===
|
|
296
|
-
if (Array.isArray(e._deviceActionSteps) && e._deviceActionSteps.includes(
|
|
315
|
+
if (e._lastStep === step) return true;
|
|
316
|
+
if (Array.isArray(e._deviceActionSteps) && e._deviceActionSteps.includes(step)) {
|
|
297
317
|
return true;
|
|
298
318
|
}
|
|
299
|
-
if (e.originalError != null &&
|
|
300
|
-
if (e.error != null && e._tag &&
|
|
319
|
+
if (e.originalError != null && hasDeviceActionStep(e.originalError, step)) return true;
|
|
320
|
+
if (e.error != null && e._tag && hasDeviceActionStep(e.error, step)) return true;
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
function hasBlindSigningStep(err) {
|
|
324
|
+
for (const step of BLIND_SIGNING_STEPS) {
|
|
325
|
+
if (hasDeviceActionStep(err, step)) return true;
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
function hasInvalidArgumentCode(err) {
|
|
330
|
+
if (!err || typeof err !== "object") return false;
|
|
331
|
+
const e = err;
|
|
332
|
+
if (e.code === "INVALID_ARGUMENT") return true;
|
|
333
|
+
if (typeof e.message === "string" && e.message.includes("code=INVALID_ARGUMENT")) return true;
|
|
334
|
+
if (e.originalError != null && hasInvalidArgumentCode(e.originalError)) return true;
|
|
335
|
+
if (e.error != null && e._tag && hasInvalidArgumentCode(e.error)) return true;
|
|
301
336
|
return false;
|
|
302
337
|
}
|
|
303
338
|
function isDeviceNotFoundError(err) {
|
|
@@ -326,6 +361,11 @@ function isUserRejectedError(err) {
|
|
|
326
361
|
if (hasStatusCode(err, USER_REJECTED_CODES)) return true;
|
|
327
362
|
return false;
|
|
328
363
|
}
|
|
364
|
+
function isUserAbortedError(err) {
|
|
365
|
+
if (!err || typeof err !== "object") return false;
|
|
366
|
+
const e = err;
|
|
367
|
+
return e._tag === ERROR_TAG.UserAborted;
|
|
368
|
+
}
|
|
329
369
|
function isWrongAppError(err) {
|
|
330
370
|
if (!err || typeof err !== "object") return false;
|
|
331
371
|
const e = err;
|
|
@@ -352,6 +392,20 @@ function isOutOfMemoryError(err) {
|
|
|
352
392
|
const e = err;
|
|
353
393
|
return e._tag === "OutOfMemoryDAError";
|
|
354
394
|
}
|
|
395
|
+
var NETWORK_ERROR_TAGS = /* @__PURE__ */ new Set([
|
|
396
|
+
ERROR_TAG.WebSocketConnection,
|
|
397
|
+
ERROR_TAG.HttpFetch,
|
|
398
|
+
ERROR_TAG.InvalidFirmwareMetadataResponse
|
|
399
|
+
]);
|
|
400
|
+
function isNetworkError(err) {
|
|
401
|
+
if (!err || typeof err !== "object") return false;
|
|
402
|
+
const e = err;
|
|
403
|
+
const tag = e._tag;
|
|
404
|
+
if (typeof tag === "string" && NETWORK_ERROR_TAGS.has(tag)) return true;
|
|
405
|
+
if (e.originalError != null && isNetworkError(e.originalError)) return true;
|
|
406
|
+
if (e.error != null && isNetworkError(e.error)) return true;
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
355
409
|
function isDeviceDisconnectedError(err) {
|
|
356
410
|
if (!err || typeof err !== "object") return false;
|
|
357
411
|
const e = err;
|
|
@@ -408,6 +462,8 @@ function mapLedgerError(err, opts) {
|
|
|
408
462
|
code = import_hwk_adapter_core.HardwareErrorCode.DeviceBusy;
|
|
409
463
|
} else if (isBlePairingFailureError(err)) {
|
|
410
464
|
code = import_hwk_adapter_core.HardwareErrorCode.BlePairingTimeout;
|
|
465
|
+
} else if (isUserAbortedError(err)) {
|
|
466
|
+
code = import_hwk_adapter_core.HardwareErrorCode.UserAborted;
|
|
411
467
|
} else if (isUserRejectedError(err)) {
|
|
412
468
|
code = import_hwk_adapter_core.HardwareErrorCode.UserRejected;
|
|
413
469
|
} else if (isWrongAppError(err)) {
|
|
@@ -416,12 +472,14 @@ function mapLedgerError(err, opts) {
|
|
|
416
472
|
code = import_hwk_adapter_core.HardwareErrorCode.AppNotInstalled;
|
|
417
473
|
} else if (isOutOfMemoryError(err)) {
|
|
418
474
|
code = import_hwk_adapter_core.HardwareErrorCode.DeviceOutOfMemory;
|
|
475
|
+
} else if (isNetworkError(err)) {
|
|
476
|
+
code = import_hwk_adapter_core.HardwareErrorCode.NetworkError;
|
|
419
477
|
} else if (isDeviceDisconnectedError(err)) {
|
|
420
478
|
code = import_hwk_adapter_core.HardwareErrorCode.DeviceDisconnected;
|
|
421
479
|
} else if (isTimeoutError(err)) {
|
|
422
480
|
code = import_hwk_adapter_core.HardwareErrorCode.OperationTimeout;
|
|
423
481
|
} else {
|
|
424
|
-
const ethMapped = classifyEthAppError(err);
|
|
482
|
+
const ethMapped = classifyEthAppError(err) ?? classifyBlindSigningDetectionError(err);
|
|
425
483
|
const apduHex = ethMapped ? null : extractApduHex(err);
|
|
426
484
|
const chainMapped = apduHex ? mapSolanaAppError(apduHex) ?? mapTronAppError(apduHex) ?? mapBtcAppError(apduHex) : null;
|
|
427
485
|
code = ethMapped ?? chainMapped ?? import_hwk_adapter_core.HardwareErrorCode.UnknownError;
|
|
@@ -431,17 +489,8 @@ function mapLedgerError(err, opts) {
|
|
|
431
489
|
return { code, message: (0, import_hwk_adapter_core.enrichErrorMessage)(code, originalMessage), appName };
|
|
432
490
|
}
|
|
433
491
|
|
|
434
|
-
// src/
|
|
435
|
-
|
|
436
|
-
const normalized = transport?.toUpperCase();
|
|
437
|
-
return normalized === "BLE" || normalized?.endsWith("_BLE") === true;
|
|
438
|
-
}
|
|
439
|
-
function isLedgerBleConnectionType(connectionType) {
|
|
440
|
-
return connectionType === "ble";
|
|
441
|
-
}
|
|
442
|
-
function isLedgerBleDescriptor(connectionType, descriptor) {
|
|
443
|
-
return isLedgerBleConnectionType(connectionType) || isLedgerDmkBleTransport(descriptor.transport);
|
|
444
|
-
}
|
|
492
|
+
// src/adapter/methods/allNetworkGetAddress.ts
|
|
493
|
+
var import_hwk_adapter_core2 = require("@onekeyfe/hwk-adapter-core");
|
|
445
494
|
|
|
446
495
|
// src/utils/sdkEventBus.ts
|
|
447
496
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -488,6 +537,216 @@ function debugError(...args) {
|
|
|
488
537
|
emitLog("error", ...args);
|
|
489
538
|
}
|
|
490
539
|
|
|
540
|
+
// src/adapter/methods/allNetworkGetAddress.ts
|
|
541
|
+
var LEDGER_BTC_NETWORK_COIN_MAP = {
|
|
542
|
+
tbtc: "Testnet",
|
|
543
|
+
bch: "Bcash",
|
|
544
|
+
ltc: "Litecoin",
|
|
545
|
+
neurai: "Neurai"
|
|
546
|
+
};
|
|
547
|
+
var LEDGER_UNSUPPORTED_ALLNETWORK_NETWORKS = /* @__PURE__ */ new Set(["doge", "dogecoin"]);
|
|
548
|
+
function createAllNetworkGetAddress({
|
|
549
|
+
callChain,
|
|
550
|
+
getChainFingerprint
|
|
551
|
+
}) {
|
|
552
|
+
return async function allNetworkGetAddress(connectId, _deviceId, params) {
|
|
553
|
+
debugLog("[LedgerAdapter][REQ]", { method: "allNetworkGetAddress", connectId, params });
|
|
554
|
+
const installContext = {};
|
|
555
|
+
const commonParams = {
|
|
556
|
+
autoInstallApp: params.autoInstallApp
|
|
557
|
+
};
|
|
558
|
+
const chainFingerprints = /* @__PURE__ */ new Map();
|
|
559
|
+
const result = await (0, import_hwk_adapter_core2.runAllNetworkGetAddress)({
|
|
560
|
+
connectId,
|
|
561
|
+
deviceId: _deviceId,
|
|
562
|
+
params,
|
|
563
|
+
normalizeItem: normalizeLedgerAllNetworkItem,
|
|
564
|
+
buildUnsupportedNetworkResponse: (item) => isUnsupportedLedgerAllNetworkNetwork(item) ? buildUnsupportedNetworkResponse(item) : void 0,
|
|
565
|
+
callItem: async ({ method, chain, item }) => {
|
|
566
|
+
const itemDeviceId = getItemDeviceId(item) ?? chainFingerprints.get(chain) ?? "";
|
|
567
|
+
return callAllNetworkMethod(
|
|
568
|
+
callChain,
|
|
569
|
+
connectId,
|
|
570
|
+
itemDeviceId,
|
|
571
|
+
method,
|
|
572
|
+
item,
|
|
573
|
+
commonParams,
|
|
574
|
+
installContext
|
|
575
|
+
);
|
|
576
|
+
},
|
|
577
|
+
attachIdentity: async ({ item, chain, payload }) => attachLedgerIdentity(
|
|
578
|
+
getChainFingerprint,
|
|
579
|
+
connectId,
|
|
580
|
+
item,
|
|
581
|
+
chain,
|
|
582
|
+
payload,
|
|
583
|
+
chainFingerprints
|
|
584
|
+
),
|
|
585
|
+
shouldAbortBundle: isTopLevelAllNetworkFailure,
|
|
586
|
+
buildTopLevelFailure: (response) => {
|
|
587
|
+
const code = response.payload?.code ?? import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch;
|
|
588
|
+
return (0, import_hwk_adapter_core2.failure)(
|
|
589
|
+
code,
|
|
590
|
+
response.payload?.error ?? "All-network get-address aborted",
|
|
591
|
+
response.payload?.params
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
596
|
+
method: "allNetworkGetAddress",
|
|
597
|
+
success: result.success,
|
|
598
|
+
payload: result
|
|
599
|
+
});
|
|
600
|
+
return result;
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
function isTopLevelAllNetworkFailure(response) {
|
|
604
|
+
if (response.success) {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
const code = response.payload?.code;
|
|
608
|
+
return code === import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch || code === import_hwk_adapter_core2.HardwareErrorCode.UserAborted || code === import_hwk_adapter_core2.HardwareErrorCode.UserRejected;
|
|
609
|
+
}
|
|
610
|
+
function getItemDeviceId(item) {
|
|
611
|
+
const { deviceId } = item;
|
|
612
|
+
return typeof deviceId === "string" && deviceId.length > 0 ? deviceId : void 0;
|
|
613
|
+
}
|
|
614
|
+
function isUnsupportedLedgerAllNetworkNetwork(item) {
|
|
615
|
+
return LEDGER_UNSUPPORTED_ALLNETWORK_NETWORKS.has(item.network.toLowerCase());
|
|
616
|
+
}
|
|
617
|
+
function buildUnsupportedNetworkResponse(item) {
|
|
618
|
+
return {
|
|
619
|
+
...item,
|
|
620
|
+
success: false,
|
|
621
|
+
payload: {
|
|
622
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.ChainNotSupported,
|
|
623
|
+
error: `Ledger allNetwork does not support ${item.network.toLowerCase() === "doge" ? "Dogecoin" : item.network}`
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
function normalizeLedgerAllNetworkItem(method, item) {
|
|
628
|
+
if (method !== "btcGetAddress" && method !== "btcGetPublicKey") {
|
|
629
|
+
return item;
|
|
630
|
+
}
|
|
631
|
+
const itemWithCoin = item;
|
|
632
|
+
if (itemWithCoin.coin) {
|
|
633
|
+
return item;
|
|
634
|
+
}
|
|
635
|
+
const coin = LEDGER_BTC_NETWORK_COIN_MAP[item.network];
|
|
636
|
+
return coin ? { ...item, coin } : item;
|
|
637
|
+
}
|
|
638
|
+
async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain, payload, chainFingerprints) {
|
|
639
|
+
const fingerprint = getItemDeviceId(item) || chainFingerprints.get(chain) || await bootstrapChainFingerprint(getChainFingerprint, connectId, chain);
|
|
640
|
+
if (!fingerprint) {
|
|
641
|
+
return buildFingerprintBootstrapFailure(item, chain);
|
|
642
|
+
}
|
|
643
|
+
chainFingerprints.set(chain, fingerprint);
|
|
644
|
+
return {
|
|
645
|
+
...item,
|
|
646
|
+
success: true,
|
|
647
|
+
payload: {
|
|
648
|
+
...payload,
|
|
649
|
+
deviceIdentity: {
|
|
650
|
+
vendor: "ledger",
|
|
651
|
+
type: "chainFingerprint",
|
|
652
|
+
chain,
|
|
653
|
+
value: fingerprint
|
|
654
|
+
},
|
|
655
|
+
chainFingerprint: fingerprint,
|
|
656
|
+
chainFingerprintChain: chain
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain) {
|
|
661
|
+
const response = await getChainFingerprint(connectId, chain);
|
|
662
|
+
return response.success ? response.payload : "";
|
|
663
|
+
}
|
|
664
|
+
function buildFingerprintBootstrapFailure(item, chain) {
|
|
665
|
+
return {
|
|
666
|
+
...item,
|
|
667
|
+
success: false,
|
|
668
|
+
payload: {
|
|
669
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch,
|
|
670
|
+
error: `Could not establish chain fingerprint for ${chain} after device call; refusing to return unverifiable result. Please retry.`
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
async function callAllNetworkMethod(callChain, connectId, deviceId, method, item, commonParams, installContext) {
|
|
675
|
+
switch (method) {
|
|
676
|
+
case "evmGetAddress":
|
|
677
|
+
return callChain(
|
|
678
|
+
connectId,
|
|
679
|
+
deviceId,
|
|
680
|
+
"evm",
|
|
681
|
+
"evmGetAddress",
|
|
682
|
+
item,
|
|
683
|
+
commonParams,
|
|
684
|
+
false,
|
|
685
|
+
installContext
|
|
686
|
+
);
|
|
687
|
+
case "btcGetAddress":
|
|
688
|
+
return callChain(
|
|
689
|
+
connectId,
|
|
690
|
+
deviceId,
|
|
691
|
+
"btc",
|
|
692
|
+
"btcGetAddress",
|
|
693
|
+
item,
|
|
694
|
+
commonParams,
|
|
695
|
+
false,
|
|
696
|
+
installContext
|
|
697
|
+
);
|
|
698
|
+
case "btcGetPublicKey":
|
|
699
|
+
return callChain(
|
|
700
|
+
connectId,
|
|
701
|
+
deviceId,
|
|
702
|
+
"btc",
|
|
703
|
+
"btcGetPublicKey",
|
|
704
|
+
item,
|
|
705
|
+
commonParams,
|
|
706
|
+
false,
|
|
707
|
+
installContext
|
|
708
|
+
);
|
|
709
|
+
case "solGetAddress":
|
|
710
|
+
return callChain(
|
|
711
|
+
connectId,
|
|
712
|
+
deviceId,
|
|
713
|
+
"sol",
|
|
714
|
+
"solGetAddress",
|
|
715
|
+
item,
|
|
716
|
+
commonParams,
|
|
717
|
+
false,
|
|
718
|
+
installContext
|
|
719
|
+
);
|
|
720
|
+
case "tronGetAddress":
|
|
721
|
+
return callChain(
|
|
722
|
+
connectId,
|
|
723
|
+
deviceId,
|
|
724
|
+
"tron",
|
|
725
|
+
"tronGetAddress",
|
|
726
|
+
item,
|
|
727
|
+
commonParams,
|
|
728
|
+
false,
|
|
729
|
+
installContext
|
|
730
|
+
);
|
|
731
|
+
default:
|
|
732
|
+
throw Object.assign(new Error(`Unsupported allNetwork method: ${method}`), {
|
|
733
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.InvalidParams
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/utils/ledgerDmkTransport.ts
|
|
739
|
+
function isLedgerDmkBleTransport(transport) {
|
|
740
|
+
const normalized = transport?.toUpperCase();
|
|
741
|
+
return normalized === "BLE" || normalized?.endsWith("_BLE") === true;
|
|
742
|
+
}
|
|
743
|
+
function isLedgerBleConnectionType(connectionType) {
|
|
744
|
+
return connectionType === "ble";
|
|
745
|
+
}
|
|
746
|
+
function isLedgerBleDescriptor(connectionType, descriptor) {
|
|
747
|
+
return isLedgerBleConnectionType(connectionType) || isLedgerDmkBleTransport(descriptor.transport);
|
|
748
|
+
}
|
|
749
|
+
|
|
491
750
|
// src/adapter/LedgerAdapter.ts
|
|
492
751
|
function formatDeviceMismatchError(expected, actual) {
|
|
493
752
|
return `Wrong device: expected ${expected}, got ${actual}`;
|
|
@@ -503,10 +762,10 @@ function btcAccountIndexFromPath(path) {
|
|
|
503
762
|
var _LedgerAdapter = class _LedgerAdapter {
|
|
504
763
|
constructor(connector, options) {
|
|
505
764
|
this.vendor = "ledger";
|
|
506
|
-
this.emitter = new
|
|
765
|
+
this.emitter = new import_hwk_adapter_core3.TypedEventEmitter();
|
|
507
766
|
this._discoveredDevices = /* @__PURE__ */ new Map();
|
|
508
767
|
this._sessions = /* @__PURE__ */ new Map();
|
|
509
|
-
this._uiRegistry = new
|
|
768
|
+
this._uiRegistry = new import_hwk_adapter_core3.UiRequestRegistry();
|
|
510
769
|
// BTC App rejects account index >= 100 unless display=true. Cached per
|
|
511
770
|
// adapter instance: first 100+ path asks the user once via UI request,
|
|
512
771
|
// subsequent 100+ paths in the same session auto-promote silently.
|
|
@@ -515,6 +774,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
515
774
|
this._btcHighIndexConfirmedThisSession = false;
|
|
516
775
|
// Shared across concurrent callers — only `cancel()` aborts.
|
|
517
776
|
this._doConnectAbortController = null;
|
|
777
|
+
this._installProgressLastEmittedValue = -Infinity;
|
|
778
|
+
this.allNetworkGetAddress = createAllNetworkGetAddress({
|
|
779
|
+
callChain: this.callChain.bind(this),
|
|
780
|
+
getChainFingerprint: (connectId, chain) => this.getChainFingerprint(connectId, "", chain)
|
|
781
|
+
});
|
|
518
782
|
// ---------------------------------------------------------------------------
|
|
519
783
|
// Private helpers
|
|
520
784
|
// ---------------------------------------------------------------------------
|
|
@@ -534,16 +798,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
534
798
|
const deviceInfo = this.connectorDeviceToDeviceInfo(data.device);
|
|
535
799
|
this._discoveredDevices.set(deviceInfo.connectId, deviceInfo);
|
|
536
800
|
this._sessions.delete(deviceInfo.connectId);
|
|
537
|
-
this.emitter.emit(
|
|
538
|
-
type:
|
|
801
|
+
this.emitter.emit(import_hwk_adapter_core3.DEVICE.CONNECT, {
|
|
802
|
+
type: import_hwk_adapter_core3.DEVICE.CONNECT,
|
|
539
803
|
payload: deviceInfo
|
|
540
804
|
});
|
|
541
805
|
};
|
|
542
806
|
this.deviceDisconnectHandler = (data) => {
|
|
543
807
|
this._discoveredDevices.delete(data.connectId);
|
|
544
808
|
this._sessions.delete(data.connectId);
|
|
545
|
-
this.emitter.emit(
|
|
546
|
-
type:
|
|
809
|
+
this.emitter.emit(import_hwk_adapter_core3.DEVICE.DISCONNECT, {
|
|
810
|
+
type: import_hwk_adapter_core3.DEVICE.DISCONNECT,
|
|
547
811
|
payload: { connectId: data.connectId }
|
|
548
812
|
});
|
|
549
813
|
};
|
|
@@ -553,7 +817,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
553
817
|
// exists (race during teardown) we drop. All other variants pass through
|
|
554
818
|
// unchanged.
|
|
555
819
|
this.uiEventForwarder = (event) => {
|
|
556
|
-
if (event.type ===
|
|
820
|
+
if (event.type === import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress) {
|
|
557
821
|
let connectId;
|
|
558
822
|
for (const [cid, sid] of this._sessions) {
|
|
559
823
|
if (sid === event.payload.sessionId) {
|
|
@@ -568,12 +832,23 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
568
832
|
);
|
|
569
833
|
return;
|
|
570
834
|
}
|
|
835
|
+
const { appName, progress } = event.payload;
|
|
836
|
+
const key = `${connectId}:${appName}`;
|
|
837
|
+
if (this._installProgressLastKey !== key || this._installProgressLastEmittedValue >= 1) {
|
|
838
|
+
this._installProgressLastEmittedValue = -Infinity;
|
|
839
|
+
this._installProgressLastKey = key;
|
|
840
|
+
}
|
|
841
|
+
const delta = progress - this._installProgressLastEmittedValue;
|
|
842
|
+
if (delta < _LedgerAdapter.APP_INSTALL_PROGRESS_MIN_DELTA && progress < 1) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
this._installProgressLastEmittedValue = progress;
|
|
571
846
|
this.emitter.emit("ui-event", {
|
|
572
|
-
type:
|
|
847
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress,
|
|
573
848
|
payload: {
|
|
574
849
|
connectId,
|
|
575
|
-
appName
|
|
576
|
-
progress
|
|
850
|
+
appName,
|
|
851
|
+
progress
|
|
577
852
|
}
|
|
578
853
|
});
|
|
579
854
|
return;
|
|
@@ -582,7 +857,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
582
857
|
};
|
|
583
858
|
this.connector = connector;
|
|
584
859
|
this._defaultAutoInstallApp = options?.autoInstallApp ?? false;
|
|
585
|
-
this._jobQueue = new
|
|
860
|
+
this._jobQueue = new import_hwk_adapter_core3.DeviceJobQueue();
|
|
586
861
|
this.registerEventListeners();
|
|
587
862
|
}
|
|
588
863
|
// Transport
|
|
@@ -630,30 +905,42 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
630
905
|
// Device management
|
|
631
906
|
// ---------------------------------------------------------------------------
|
|
632
907
|
async searchDevices(options) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
const devices = await this.connector.searchDevices();
|
|
642
|
-
this._discoveredDevices.clear();
|
|
643
|
-
for (const d of devices) {
|
|
644
|
-
if (d.connectId) {
|
|
645
|
-
this._discoveredDevices.set(d.connectId, this.connectorDeviceToDeviceInfo(d));
|
|
908
|
+
debugLog("[LedgerAdapter][REQ]", { method: "searchDevices", params: options });
|
|
909
|
+
try {
|
|
910
|
+
if (options?.resetSession) {
|
|
911
|
+
this._doConnectAbortController?.abort();
|
|
912
|
+
this._sessions.clear();
|
|
913
|
+
this._connectingPromise = null;
|
|
914
|
+
this._doConnectAbortController = null;
|
|
915
|
+
this._btcHighIndexConfirmedThisSession = false;
|
|
646
916
|
}
|
|
647
|
-
}
|
|
648
|
-
if (this._discoveredDevices.size === 0) {
|
|
649
917
|
await this._ensureDevicePermission();
|
|
918
|
+
const devices = await this.connector.searchDevices();
|
|
919
|
+
this._discoveredDevices.clear();
|
|
920
|
+
for (const d of devices) {
|
|
921
|
+
if (d.connectId) {
|
|
922
|
+
this._discoveredDevices.set(d.connectId, this.connectorDeviceToDeviceInfo(d));
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
if (this._discoveredDevices.size === 0) {
|
|
926
|
+
await this._ensureDevicePermission();
|
|
927
|
+
}
|
|
928
|
+
const result = Array.from(this._discoveredDevices.values());
|
|
929
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
930
|
+
method: "searchDevices",
|
|
931
|
+
success: true,
|
|
932
|
+
payload: result
|
|
933
|
+
});
|
|
934
|
+
return result;
|
|
935
|
+
} catch (err) {
|
|
936
|
+
const e = err;
|
|
937
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
938
|
+
method: "searchDevices",
|
|
939
|
+
success: false,
|
|
940
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
941
|
+
});
|
|
942
|
+
throw err;
|
|
650
943
|
}
|
|
651
|
-
debugLog(
|
|
652
|
-
`[LedgerAdapter] searchDevices() return count=${this._discoveredDevices.size} ids=[${[
|
|
653
|
-
...this._discoveredDevices.keys()
|
|
654
|
-
].join(",")}]`
|
|
655
|
-
);
|
|
656
|
-
return Array.from(this._discoveredDevices.values());
|
|
657
944
|
}
|
|
658
945
|
// USB single-session invariant: evict all sessions, best-effort (see connectDevice).
|
|
659
946
|
async _evictAllSessions() {
|
|
@@ -669,14 +956,15 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
669
956
|
}
|
|
670
957
|
static _createDeviceBusyError(method) {
|
|
671
958
|
return Object.assign(new Error(`Ledger device is busy while calling ${method}`), {
|
|
672
|
-
code:
|
|
959
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceBusy
|
|
673
960
|
});
|
|
674
961
|
}
|
|
675
962
|
async connectDevice(connectId) {
|
|
963
|
+
debugLog("[LedgerAdapter][REQ]", { method: "connectDevice", connectId, params: { connectId } });
|
|
676
964
|
try {
|
|
677
965
|
if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
|
|
678
966
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
679
|
-
code:
|
|
967
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
680
968
|
});
|
|
681
969
|
}
|
|
682
970
|
if (!isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
@@ -688,28 +976,79 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
688
976
|
if (session.deviceInfo) {
|
|
689
977
|
this._discoveredDevices.set(connectId, session.deviceInfo);
|
|
690
978
|
}
|
|
691
|
-
|
|
979
|
+
const result = (0, import_hwk_adapter_core3.success)(connectId);
|
|
980
|
+
debugLog("[LedgerAdapter][RES]", { method: "connectDevice", success: true, payload: result });
|
|
981
|
+
return result;
|
|
692
982
|
} catch (err) {
|
|
693
|
-
|
|
983
|
+
const failureResult = this.errorToFailure(err);
|
|
984
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
985
|
+
method: "connectDevice",
|
|
986
|
+
success: false,
|
|
987
|
+
payload: failureResult
|
|
988
|
+
});
|
|
989
|
+
return failureResult;
|
|
694
990
|
}
|
|
695
991
|
}
|
|
696
992
|
async disconnectDevice(connectId) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
993
|
+
debugLog("[LedgerAdapter][REQ]", {
|
|
994
|
+
method: "disconnectDevice",
|
|
995
|
+
connectId,
|
|
996
|
+
params: { connectId }
|
|
997
|
+
});
|
|
998
|
+
try {
|
|
999
|
+
const sessionId = this._sessions.get(connectId);
|
|
1000
|
+
if (sessionId) {
|
|
1001
|
+
await this.connector.disconnect(sessionId);
|
|
1002
|
+
this._sessions.delete(connectId);
|
|
1003
|
+
}
|
|
1004
|
+
debugLog("[LedgerAdapter][RES]", { method: "disconnectDevice", success: true });
|
|
1005
|
+
} catch (err) {
|
|
1006
|
+
const e = err;
|
|
1007
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1008
|
+
method: "disconnectDevice",
|
|
1009
|
+
success: false,
|
|
1010
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
1011
|
+
});
|
|
1012
|
+
throw err;
|
|
701
1013
|
}
|
|
702
1014
|
}
|
|
703
1015
|
async getDeviceInfo(connectId, deviceId) {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1016
|
+
debugLog("[LedgerAdapter][REQ]", {
|
|
1017
|
+
method: "getDeviceInfo",
|
|
1018
|
+
connectId,
|
|
1019
|
+
params: { connectId, deviceId }
|
|
1020
|
+
});
|
|
1021
|
+
try {
|
|
1022
|
+
await this._ensureDevicePermission(connectId, deviceId);
|
|
1023
|
+
const cached = this._discoveredDevices.get(connectId) ?? Array.from(this._discoveredDevices.values()).find((d) => d.deviceId === deviceId);
|
|
1024
|
+
if (cached) {
|
|
1025
|
+
const result = (0, import_hwk_adapter_core3.success)(cached);
|
|
1026
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1027
|
+
method: "getDeviceInfo",
|
|
1028
|
+
success: true,
|
|
1029
|
+
payload: result
|
|
1030
|
+
});
|
|
1031
|
+
return result;
|
|
1032
|
+
}
|
|
1033
|
+
const notFound = (0, import_hwk_adapter_core3.failure)(
|
|
1034
|
+
import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound,
|
|
1035
|
+
"Device not found in cache. Call searchDevices() or wait for a device-connected event first."
|
|
1036
|
+
);
|
|
1037
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1038
|
+
method: "getDeviceInfo",
|
|
1039
|
+
success: false,
|
|
1040
|
+
payload: notFound
|
|
1041
|
+
});
|
|
1042
|
+
return notFound;
|
|
1043
|
+
} catch (err) {
|
|
1044
|
+
const e = err;
|
|
1045
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1046
|
+
method: "getDeviceInfo",
|
|
1047
|
+
success: false,
|
|
1048
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
1049
|
+
});
|
|
1050
|
+
throw err;
|
|
708
1051
|
}
|
|
709
|
-
return (0, import_hwk_adapter_core2.failure)(
|
|
710
|
-
import_hwk_adapter_core2.HardwareErrorCode.DeviceNotFound,
|
|
711
|
-
"Device not found in cache. Call searchDevices() or wait for a device-connected event first."
|
|
712
|
-
);
|
|
713
1052
|
}
|
|
714
1053
|
getSupportedChains() {
|
|
715
1054
|
return ["evm", "btc", "sol", "tron"];
|
|
@@ -717,7 +1056,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
717
1056
|
// ---------------------------------------------------------------------------
|
|
718
1057
|
// Chain call helper
|
|
719
1058
|
// ---------------------------------------------------------------------------
|
|
720
|
-
async callChain(connectId, deviceId, chain, method, params, commonParams, skipFingerprint = false) {
|
|
1059
|
+
async callChain(connectId, deviceId, chain, method, params, commonParams, skipFingerprint = false, installContext) {
|
|
721
1060
|
try {
|
|
722
1061
|
const result = await this.connectorCall(
|
|
723
1062
|
connectId,
|
|
@@ -729,183 +1068,204 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
729
1068
|
skipFingerprint
|
|
730
1069
|
},
|
|
731
1070
|
void 0,
|
|
732
|
-
commonParams
|
|
1071
|
+
commonParams,
|
|
1072
|
+
installContext
|
|
733
1073
|
);
|
|
734
|
-
return (0,
|
|
1074
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
735
1075
|
} catch (err) {
|
|
736
1076
|
return this.errorToFailure(err);
|
|
737
1077
|
}
|
|
738
1078
|
}
|
|
1079
|
+
static normalizeCallArgs(connectId, deviceId, params) {
|
|
1080
|
+
return {
|
|
1081
|
+
connectId: connectId ?? "",
|
|
1082
|
+
deviceId: deviceId ?? "",
|
|
1083
|
+
params: params ?? {}
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
static splitCommonParams(params) {
|
|
1087
|
+
if (params && typeof params === "object") {
|
|
1088
|
+
const {
|
|
1089
|
+
autoInstallApp,
|
|
1090
|
+
passphraseState: _passphraseState,
|
|
1091
|
+
useEmptyPassphrase: _useEmptyPassphrase,
|
|
1092
|
+
...rest
|
|
1093
|
+
} = params;
|
|
1094
|
+
return {
|
|
1095
|
+
commonParams: {
|
|
1096
|
+
autoInstallApp: typeof autoInstallApp === "boolean" ? autoInstallApp : void 0
|
|
1097
|
+
},
|
|
1098
|
+
rest
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
return { commonParams: {}, rest: params ?? {} };
|
|
1102
|
+
}
|
|
1103
|
+
callChainWithMergedParams(connectId, deviceId, chain, method, params) {
|
|
1104
|
+
const normalized = _LedgerAdapter.normalizeCallArgs(connectId, deviceId, params);
|
|
1105
|
+
const { commonParams, rest } = _LedgerAdapter.splitCommonParams(normalized.params);
|
|
1106
|
+
return this.callChain(
|
|
1107
|
+
normalized.connectId,
|
|
1108
|
+
normalized.deviceId,
|
|
1109
|
+
chain,
|
|
1110
|
+
method,
|
|
1111
|
+
rest,
|
|
1112
|
+
commonParams
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
739
1115
|
// ---------------------------------------------------------------------------
|
|
740
1116
|
// EVM chain methods
|
|
741
1117
|
// ---------------------------------------------------------------------------
|
|
742
|
-
evmGetAddress(connectId, deviceId, params
|
|
743
|
-
return this.
|
|
1118
|
+
evmGetAddress(connectId, deviceId, params) {
|
|
1119
|
+
return this.callChainWithMergedParams(
|
|
744
1120
|
connectId,
|
|
745
1121
|
deviceId,
|
|
746
1122
|
"evm",
|
|
747
1123
|
"evmGetAddress",
|
|
748
|
-
params
|
|
749
|
-
commonParams
|
|
1124
|
+
params
|
|
750
1125
|
);
|
|
751
1126
|
}
|
|
752
|
-
evmSignTransaction(connectId, deviceId, params
|
|
753
|
-
return this.
|
|
1127
|
+
evmSignTransaction(connectId, deviceId, params) {
|
|
1128
|
+
return this.callChainWithMergedParams(
|
|
754
1129
|
connectId,
|
|
755
1130
|
deviceId,
|
|
756
1131
|
"evm",
|
|
757
1132
|
"evmSignTransaction",
|
|
758
|
-
params
|
|
759
|
-
commonParams
|
|
1133
|
+
params
|
|
760
1134
|
);
|
|
761
1135
|
}
|
|
762
|
-
evmSignMessage(connectId, deviceId, params
|
|
763
|
-
return this.
|
|
1136
|
+
evmSignMessage(connectId, deviceId, params) {
|
|
1137
|
+
return this.callChainWithMergedParams(
|
|
764
1138
|
connectId,
|
|
765
1139
|
deviceId,
|
|
766
1140
|
"evm",
|
|
767
1141
|
"evmSignMessage",
|
|
768
|
-
params
|
|
769
|
-
commonParams
|
|
1142
|
+
params
|
|
770
1143
|
);
|
|
771
1144
|
}
|
|
772
|
-
evmSignTypedData(connectId, deviceId, params
|
|
773
|
-
return this.
|
|
1145
|
+
evmSignTypedData(connectId, deviceId, params) {
|
|
1146
|
+
return this.callChainWithMergedParams(
|
|
774
1147
|
connectId,
|
|
775
1148
|
deviceId,
|
|
776
1149
|
"evm",
|
|
777
1150
|
"evmSignTypedData",
|
|
778
|
-
params
|
|
779
|
-
commonParams
|
|
1151
|
+
params
|
|
780
1152
|
);
|
|
781
1153
|
}
|
|
782
1154
|
// ---------------------------------------------------------------------------
|
|
783
1155
|
// BTC chain methods
|
|
784
1156
|
// ---------------------------------------------------------------------------
|
|
785
|
-
btcGetAddress(connectId, deviceId, params
|
|
786
|
-
return this.
|
|
1157
|
+
btcGetAddress(connectId, deviceId, params) {
|
|
1158
|
+
return this.callChainWithMergedParams(
|
|
787
1159
|
connectId,
|
|
788
1160
|
deviceId,
|
|
789
1161
|
"btc",
|
|
790
1162
|
"btcGetAddress",
|
|
791
|
-
params
|
|
792
|
-
commonParams
|
|
1163
|
+
params
|
|
793
1164
|
);
|
|
794
1165
|
}
|
|
795
|
-
btcGetPublicKey(connectId, deviceId, params
|
|
796
|
-
return this.
|
|
1166
|
+
btcGetPublicKey(connectId, deviceId, params) {
|
|
1167
|
+
return this.callChainWithMergedParams(
|
|
797
1168
|
connectId,
|
|
798
1169
|
deviceId,
|
|
799
1170
|
"btc",
|
|
800
1171
|
"btcGetPublicKey",
|
|
801
|
-
params
|
|
802
|
-
commonParams
|
|
1172
|
+
params
|
|
803
1173
|
);
|
|
804
1174
|
}
|
|
805
|
-
btcSignTransaction(connectId, deviceId, params
|
|
806
|
-
return this.
|
|
1175
|
+
btcSignTransaction(connectId, deviceId, params) {
|
|
1176
|
+
return this.callChainWithMergedParams(
|
|
807
1177
|
connectId,
|
|
808
1178
|
deviceId,
|
|
809
1179
|
"btc",
|
|
810
1180
|
"btcSignTransaction",
|
|
811
|
-
params
|
|
812
|
-
commonParams
|
|
1181
|
+
params
|
|
813
1182
|
);
|
|
814
1183
|
}
|
|
815
|
-
btcSignPsbt(connectId, deviceId, params
|
|
816
|
-
return this.
|
|
1184
|
+
btcSignPsbt(connectId, deviceId, params) {
|
|
1185
|
+
return this.callChainWithMergedParams(
|
|
817
1186
|
connectId,
|
|
818
1187
|
deviceId,
|
|
819
1188
|
"btc",
|
|
820
1189
|
"btcSignPsbt",
|
|
821
|
-
params
|
|
822
|
-
commonParams
|
|
1190
|
+
params
|
|
823
1191
|
);
|
|
824
1192
|
}
|
|
825
|
-
btcSignMessage(connectId, deviceId, params
|
|
826
|
-
return this.
|
|
1193
|
+
btcSignMessage(connectId, deviceId, params) {
|
|
1194
|
+
return this.callChainWithMergedParams(
|
|
827
1195
|
connectId,
|
|
828
1196
|
deviceId,
|
|
829
1197
|
"btc",
|
|
830
1198
|
"btcSignMessage",
|
|
831
|
-
params
|
|
832
|
-
commonParams
|
|
1199
|
+
params
|
|
833
1200
|
);
|
|
834
1201
|
}
|
|
835
|
-
btcGetMasterFingerprint(connectId, deviceId,
|
|
836
|
-
return this.
|
|
1202
|
+
btcGetMasterFingerprint(connectId, deviceId, params) {
|
|
1203
|
+
return this.callChainWithMergedParams(
|
|
837
1204
|
connectId,
|
|
838
1205
|
deviceId,
|
|
839
1206
|
"btc",
|
|
840
1207
|
"btcGetMasterFingerprint",
|
|
841
|
-
|
|
842
|
-
commonParams
|
|
1208
|
+
params
|
|
843
1209
|
);
|
|
844
1210
|
}
|
|
845
1211
|
// ---------------------------------------------------------------------------
|
|
846
1212
|
// SOL chain methods
|
|
847
1213
|
// ---------------------------------------------------------------------------
|
|
848
|
-
solGetAddress(connectId, deviceId, params
|
|
849
|
-
return this.
|
|
1214
|
+
solGetAddress(connectId, deviceId, params) {
|
|
1215
|
+
return this.callChainWithMergedParams(
|
|
850
1216
|
connectId,
|
|
851
1217
|
deviceId,
|
|
852
1218
|
"sol",
|
|
853
1219
|
"solGetAddress",
|
|
854
|
-
params
|
|
855
|
-
commonParams
|
|
1220
|
+
params
|
|
856
1221
|
);
|
|
857
1222
|
}
|
|
858
|
-
solSignTransaction(connectId, deviceId, params
|
|
859
|
-
return this.
|
|
1223
|
+
solSignTransaction(connectId, deviceId, params) {
|
|
1224
|
+
return this.callChainWithMergedParams(
|
|
860
1225
|
connectId,
|
|
861
1226
|
deviceId,
|
|
862
1227
|
"sol",
|
|
863
1228
|
"solSignTransaction",
|
|
864
|
-
params
|
|
865
|
-
commonParams
|
|
1229
|
+
params
|
|
866
1230
|
);
|
|
867
1231
|
}
|
|
868
|
-
solSignMessage(connectId, deviceId, params
|
|
869
|
-
return this.
|
|
1232
|
+
solSignMessage(connectId, deviceId, params) {
|
|
1233
|
+
return this.callChainWithMergedParams(
|
|
870
1234
|
connectId,
|
|
871
1235
|
deviceId,
|
|
872
1236
|
"sol",
|
|
873
1237
|
"solSignMessage",
|
|
874
|
-
params
|
|
875
|
-
commonParams
|
|
1238
|
+
params
|
|
876
1239
|
);
|
|
877
1240
|
}
|
|
878
1241
|
// ---------------------------------------------------------------------------
|
|
879
1242
|
// TRON chain methods
|
|
880
1243
|
// ---------------------------------------------------------------------------
|
|
881
|
-
tronGetAddress(connectId, deviceId, params
|
|
882
|
-
return this.
|
|
1244
|
+
tronGetAddress(connectId, deviceId, params) {
|
|
1245
|
+
return this.callChainWithMergedParams(
|
|
883
1246
|
connectId,
|
|
884
1247
|
deviceId,
|
|
885
1248
|
"tron",
|
|
886
1249
|
"tronGetAddress",
|
|
887
|
-
params
|
|
888
|
-
commonParams
|
|
1250
|
+
params
|
|
889
1251
|
);
|
|
890
1252
|
}
|
|
891
|
-
tronSignTransaction(connectId, deviceId, params
|
|
892
|
-
return this.
|
|
1253
|
+
tronSignTransaction(connectId, deviceId, params) {
|
|
1254
|
+
return this.callChainWithMergedParams(
|
|
893
1255
|
connectId,
|
|
894
1256
|
deviceId,
|
|
895
1257
|
"tron",
|
|
896
1258
|
"tronSignTransaction",
|
|
897
|
-
params
|
|
898
|
-
commonParams
|
|
1259
|
+
params
|
|
899
1260
|
);
|
|
900
1261
|
}
|
|
901
|
-
tronSignMessage(connectId, deviceId, params
|
|
902
|
-
return this.
|
|
1262
|
+
tronSignMessage(connectId, deviceId, params) {
|
|
1263
|
+
return this.callChainWithMergedParams(
|
|
903
1264
|
connectId,
|
|
904
1265
|
deviceId,
|
|
905
1266
|
"tron",
|
|
906
1267
|
"tronSignMessage",
|
|
907
|
-
params
|
|
908
|
-
commonParams
|
|
1268
|
+
params
|
|
909
1269
|
);
|
|
910
1270
|
}
|
|
911
1271
|
// ---------------------------------------------------------------------------
|
|
@@ -916,7 +1276,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
916
1276
|
async installApp(connectId, appName) {
|
|
917
1277
|
try {
|
|
918
1278
|
await this.connectorCall(connectId, "installApp", { appName });
|
|
919
|
-
return (0,
|
|
1279
|
+
return (0, import_hwk_adapter_core3.success)(void 0);
|
|
920
1280
|
} catch (err) {
|
|
921
1281
|
return this.errorToFailure(err);
|
|
922
1282
|
}
|
|
@@ -924,7 +1284,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
924
1284
|
async listInstalledApps(connectId) {
|
|
925
1285
|
try {
|
|
926
1286
|
const result = await this.connectorCall(connectId, "listInstalledApps", {});
|
|
927
|
-
return (0,
|
|
1287
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
1288
|
+
} catch (err) {
|
|
1289
|
+
return this.errorToFailure(err);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
// Offline app-presence + unlock probe. No manager-api catalog (unlike listInstalledApps).
|
|
1293
|
+
async listInstalledNames(connectId) {
|
|
1294
|
+
try {
|
|
1295
|
+
const result = await this.connectorCall(connectId, "listInstalledNames", {});
|
|
1296
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
928
1297
|
} catch (err) {
|
|
929
1298
|
return this.errorToFailure(err);
|
|
930
1299
|
}
|
|
@@ -932,7 +1301,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
932
1301
|
async listAvailableApps(connectId) {
|
|
933
1302
|
try {
|
|
934
1303
|
const result = await this.connectorCall(connectId, "listAvailableApps", {});
|
|
935
|
-
return (0,
|
|
1304
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
936
1305
|
} catch (err) {
|
|
937
1306
|
return this.errorToFailure(err);
|
|
938
1307
|
}
|
|
@@ -940,7 +1309,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
940
1309
|
async getLedgerFirmwareVersion(connectId) {
|
|
941
1310
|
try {
|
|
942
1311
|
const result = await this.connectorCall(connectId, "getFirmwareVersion", {});
|
|
943
|
-
return (0,
|
|
1312
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
944
1313
|
} catch (err) {
|
|
945
1314
|
return this.errorToFailure(err);
|
|
946
1315
|
}
|
|
@@ -948,7 +1317,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
948
1317
|
async getLedgerDeviceInfo(connectId) {
|
|
949
1318
|
try {
|
|
950
1319
|
const result = await this.connectorCall(connectId, "getDeviceInfo", {});
|
|
951
|
-
return (0,
|
|
1320
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
952
1321
|
} catch (err) {
|
|
953
1322
|
return this.errorToFailure(err);
|
|
954
1323
|
}
|
|
@@ -961,7 +1330,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
961
1330
|
}
|
|
962
1331
|
cancel(connectId) {
|
|
963
1332
|
const userAbortReason = Object.assign(new Error("User aborted operation"), {
|
|
964
|
-
code:
|
|
1333
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
965
1334
|
_tag: ERROR_TAG.UserAborted
|
|
966
1335
|
});
|
|
967
1336
|
this._lastCancelReason = userAbortReason;
|
|
@@ -995,7 +1364,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
995
1364
|
chain,
|
|
996
1365
|
(method, params) => this.connectorCall(connectId, method, params, void 0, deviceId)
|
|
997
1366
|
);
|
|
998
|
-
return (0,
|
|
1367
|
+
return (0, import_hwk_adapter_core3.success)(fingerprint);
|
|
999
1368
|
} catch (err) {
|
|
1000
1369
|
debugError("[LedgerAdapter] getChainFingerprint error:", chain, err);
|
|
1001
1370
|
return this.errorToFailure(err);
|
|
@@ -1018,7 +1387,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1018
1387
|
return { success: false, expected: deviceId, actual: fingerprint };
|
|
1019
1388
|
} catch (err) {
|
|
1020
1389
|
const mapped = mapLedgerError(err);
|
|
1021
|
-
if (mapped.code ===
|
|
1390
|
+
if (mapped.code === import_hwk_adapter_core3.HardwareErrorCode.WrongApp || mapped.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceLocked) {
|
|
1022
1391
|
return { success: true };
|
|
1023
1392
|
}
|
|
1024
1393
|
throw err;
|
|
@@ -1043,7 +1412,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1043
1412
|
const result = await callMethod("btcGetMasterFingerprint", {});
|
|
1044
1413
|
return result.masterFingerprint;
|
|
1045
1414
|
}
|
|
1046
|
-
const path =
|
|
1415
|
+
const path = import_hwk_adapter_core3.CHAIN_FINGERPRINT_PATHS[chain];
|
|
1047
1416
|
let address;
|
|
1048
1417
|
if (chain === "evm") {
|
|
1049
1418
|
address = (await callMethod("evmGetAddress", { path, showOnDevice: false })).address.toLowerCase();
|
|
@@ -1054,7 +1423,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1054
1423
|
} else {
|
|
1055
1424
|
throw new Error(`Unsupported chain for fingerprint: ${chain}`);
|
|
1056
1425
|
}
|
|
1057
|
-
return (0,
|
|
1426
|
+
return (0, import_hwk_adapter_core3.deriveDeviceFingerprint)(address);
|
|
1058
1427
|
}
|
|
1059
1428
|
// Ledger WebUSB won't expose a locked device, so we can't auto-detect unlock.
|
|
1060
1429
|
// The user must press Confirm after unlocking, which triggers a search retry.
|
|
@@ -1066,10 +1435,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1066
1435
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1067
1436
|
}
|
|
1068
1437
|
const waitPromise = this._uiRegistry.wait(
|
|
1069
|
-
|
|
1438
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT
|
|
1070
1439
|
);
|
|
1071
|
-
this.emitter.emit(
|
|
1072
|
-
type:
|
|
1440
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT, {
|
|
1441
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT,
|
|
1073
1442
|
payload: {
|
|
1074
1443
|
vendor: "ledger",
|
|
1075
1444
|
reason: "device-not-found",
|
|
@@ -1080,7 +1449,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1080
1449
|
try {
|
|
1081
1450
|
if (signal) {
|
|
1082
1451
|
const onAbort = () => {
|
|
1083
|
-
this._uiRegistry.cancel(
|
|
1452
|
+
this._uiRegistry.cancel(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT);
|
|
1084
1453
|
};
|
|
1085
1454
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
1086
1455
|
try {
|
|
@@ -1092,20 +1461,20 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1092
1461
|
payload = await waitPromise;
|
|
1093
1462
|
}
|
|
1094
1463
|
} catch (err) {
|
|
1095
|
-
this.emitter.emit(
|
|
1096
|
-
type:
|
|
1464
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1465
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1097
1466
|
payload: {}
|
|
1098
1467
|
});
|
|
1099
1468
|
throw Object.assign(new Error("User cancelled Ledger connection"), {
|
|
1100
1469
|
_tag: ERROR_TAG.UserAborted,
|
|
1101
|
-
code:
|
|
1470
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1102
1471
|
cause: err
|
|
1103
1472
|
});
|
|
1104
1473
|
}
|
|
1105
1474
|
if (!payload?.confirmed) {
|
|
1106
1475
|
throw Object.assign(new Error("User cancelled Ledger connection"), {
|
|
1107
1476
|
_tag: ERROR_TAG.UserAborted,
|
|
1108
|
-
code:
|
|
1477
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted
|
|
1109
1478
|
});
|
|
1110
1479
|
}
|
|
1111
1480
|
await new Promise((resolve) => {
|
|
@@ -1135,10 +1504,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1135
1504
|
}
|
|
1136
1505
|
async _waitForBtcHighIndexConfirm(path, accountIndex) {
|
|
1137
1506
|
const waitPromise = this._uiRegistry.wait(
|
|
1138
|
-
|
|
1507
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM
|
|
1139
1508
|
);
|
|
1140
|
-
this.emitter.emit(
|
|
1141
|
-
type:
|
|
1509
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM, {
|
|
1510
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM,
|
|
1142
1511
|
payload: {
|
|
1143
1512
|
vendor: "ledger",
|
|
1144
1513
|
path,
|
|
@@ -1149,8 +1518,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1149
1518
|
const payload = await waitPromise;
|
|
1150
1519
|
return !!payload?.confirmed;
|
|
1151
1520
|
} catch (err) {
|
|
1152
|
-
this.emitter.emit(
|
|
1153
|
-
type:
|
|
1521
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1522
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1154
1523
|
payload: {}
|
|
1155
1524
|
});
|
|
1156
1525
|
return false;
|
|
@@ -1160,18 +1529,18 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1160
1529
|
// Same register-then-emit ordering as the BTC high-index gate.
|
|
1161
1530
|
async _waitForInstallAppConfirm(appName) {
|
|
1162
1531
|
const waitPromise = this._uiRegistry.wait(
|
|
1163
|
-
|
|
1532
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP
|
|
1164
1533
|
);
|
|
1165
|
-
this.emitter.emit(
|
|
1166
|
-
type:
|
|
1534
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP, {
|
|
1535
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP,
|
|
1167
1536
|
payload: { vendor: "ledger", appName }
|
|
1168
1537
|
});
|
|
1169
1538
|
try {
|
|
1170
1539
|
const payload = await waitPromise;
|
|
1171
1540
|
return !!payload?.confirmed;
|
|
1172
1541
|
} catch (err) {
|
|
1173
|
-
this.emitter.emit(
|
|
1174
|
-
type:
|
|
1542
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1543
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1175
1544
|
payload: {}
|
|
1176
1545
|
});
|
|
1177
1546
|
return false;
|
|
@@ -1184,7 +1553,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1184
1553
|
if (signal.aborted) _LedgerAdapter._throwIfAborted(signal);
|
|
1185
1554
|
if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
|
|
1186
1555
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
1187
|
-
code:
|
|
1556
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1188
1557
|
});
|
|
1189
1558
|
}
|
|
1190
1559
|
if (connectId && this._sessions.has(connectId)) return connectId;
|
|
@@ -1194,7 +1563,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1194
1563
|
new Error(
|
|
1195
1564
|
"Ledger USB session invariant violated: more than one session is active. Please reconnect the device."
|
|
1196
1565
|
),
|
|
1197
|
-
{ code:
|
|
1566
|
+
{ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceOneDeviceOnly }
|
|
1198
1567
|
);
|
|
1199
1568
|
}
|
|
1200
1569
|
return this._sessions.keys().next().value;
|
|
@@ -1236,14 +1605,14 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1236
1605
|
let confirms = 0;
|
|
1237
1606
|
while (!internalSignal.aborted) {
|
|
1238
1607
|
this.emitter.emit("ui-event", {
|
|
1239
|
-
type:
|
|
1608
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.Searching,
|
|
1240
1609
|
payload: { sessionId: "" }
|
|
1241
1610
|
});
|
|
1242
1611
|
let devices = await this.searchDevices();
|
|
1243
1612
|
if (devices.length === 0) {
|
|
1244
1613
|
for (let i = 0; i < 3 && !internalSignal.aborted; i += 1) {
|
|
1245
1614
|
await new Promise((resolve) => {
|
|
1246
|
-
setTimeout(resolve,
|
|
1615
|
+
setTimeout(resolve, import_hwk_adapter_core3.DEVICE_CONNECT_RETRY_DELAY_MS);
|
|
1247
1616
|
});
|
|
1248
1617
|
devices = await this.searchDevices();
|
|
1249
1618
|
if (devices.length > 0) break;
|
|
@@ -1274,7 +1643,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1274
1643
|
new Error(
|
|
1275
1644
|
"Device not connected after multiple attempts. Please ensure your Ledger is awake, unlocked, and in range, then try again."
|
|
1276
1645
|
),
|
|
1277
|
-
{ code:
|
|
1646
|
+
{ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound }
|
|
1278
1647
|
);
|
|
1279
1648
|
}
|
|
1280
1649
|
await this._waitForDeviceConnect(internalSignal);
|
|
@@ -1298,7 +1667,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1298
1667
|
return this._connectDeviceOrThrow(devices[0].connectId);
|
|
1299
1668
|
}
|
|
1300
1669
|
const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
|
|
1301
|
-
code:
|
|
1670
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1302
1671
|
});
|
|
1303
1672
|
if (isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
1304
1673
|
err._tag = ERROR_TAG.DeviceNotAdvertising;
|
|
@@ -1307,7 +1676,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1307
1676
|
}
|
|
1308
1677
|
if (isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
1309
1678
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
1310
|
-
code:
|
|
1679
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1311
1680
|
});
|
|
1312
1681
|
}
|
|
1313
1682
|
if (devices.length > 1) {
|
|
@@ -1315,7 +1684,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1315
1684
|
}
|
|
1316
1685
|
if (devices.length !== 1) {
|
|
1317
1686
|
throw Object.assign(new Error("Ledger device not found."), {
|
|
1318
|
-
code:
|
|
1687
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1319
1688
|
});
|
|
1320
1689
|
}
|
|
1321
1690
|
return this._connectDeviceOrThrow(devices[0].connectId);
|
|
@@ -1353,7 +1722,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1353
1722
|
*/
|
|
1354
1723
|
_unwrapConnectorResult(result) {
|
|
1355
1724
|
if (result.success) return result.payload;
|
|
1356
|
-
throw (0,
|
|
1725
|
+
throw (0, import_hwk_adapter_core3.rehydrateConnectorError)(result.error);
|
|
1357
1726
|
}
|
|
1358
1727
|
/**
|
|
1359
1728
|
* `connector.call` + result unwrap, optionally raced against an abort
|
|
@@ -1366,26 +1735,43 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1366
1735
|
const result = signal ? await this._abortable(signal, promise) : await promise;
|
|
1367
1736
|
return this._unwrapConnectorResult(result);
|
|
1368
1737
|
}
|
|
1369
|
-
async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams) {
|
|
1370
|
-
debugLog("[LedgerAdapter]
|
|
1738
|
+
async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams, installContext) {
|
|
1739
|
+
debugLog("[LedgerAdapter][REQ]", { method, connectId: connectId || "(empty)", params });
|
|
1371
1740
|
const queueKey = connectId || "__ledger_default__";
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1741
|
+
try {
|
|
1742
|
+
const result = await this._jobQueue.enqueue(
|
|
1743
|
+
queueKey,
|
|
1744
|
+
async (signal) => this._runConnectorCall(
|
|
1745
|
+
connectId,
|
|
1746
|
+
method,
|
|
1747
|
+
params,
|
|
1748
|
+
signal,
|
|
1749
|
+
fingerprint,
|
|
1750
|
+
permissionDeviceId,
|
|
1751
|
+
commonParams,
|
|
1752
|
+
installContext
|
|
1753
|
+
),
|
|
1754
|
+
{
|
|
1755
|
+
label: method,
|
|
1756
|
+
rejectIfBusy: true,
|
|
1757
|
+
busyError: _LedgerAdapter._createDeviceBusyError(method)
|
|
1758
|
+
}
|
|
1759
|
+
);
|
|
1760
|
+
debugLog("[LedgerAdapter][RES]", { method, success: true, payload: result });
|
|
1761
|
+
return result;
|
|
1762
|
+
} catch (err) {
|
|
1763
|
+
const e = err;
|
|
1764
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1376
1765
|
method,
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
busyError: _LedgerAdapter._createDeviceBusyError(method)
|
|
1387
|
-
}
|
|
1388
|
-
);
|
|
1766
|
+
success: false,
|
|
1767
|
+
error: {
|
|
1768
|
+
message: e?.message,
|
|
1769
|
+
_tag: e?._tag,
|
|
1770
|
+
code: e?.code ?? e?.errorCode
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
throw err;
|
|
1774
|
+
}
|
|
1389
1775
|
}
|
|
1390
1776
|
/**
|
|
1391
1777
|
* Race a promise against an abort signal. On abort, rejects with
|
|
@@ -1420,7 +1806,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1420
1806
|
}
|
|
1421
1807
|
}
|
|
1422
1808
|
/** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
|
|
1423
|
-
async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams) {
|
|
1809
|
+
async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext) {
|
|
1424
1810
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1425
1811
|
await this._ensureDevicePermission(
|
|
1426
1812
|
connectId,
|
|
@@ -1434,7 +1820,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1434
1820
|
if (gatedParams === null) {
|
|
1435
1821
|
throw Object.assign(new Error("User cancelled BTC high-index confirmation"), {
|
|
1436
1822
|
_tag: ERROR_TAG.UserAborted,
|
|
1437
|
-
code:
|
|
1823
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted
|
|
1438
1824
|
});
|
|
1439
1825
|
}
|
|
1440
1826
|
effectiveParams = gatedParams;
|
|
@@ -1463,7 +1849,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1463
1849
|
);
|
|
1464
1850
|
if (!fp.success) {
|
|
1465
1851
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1466
|
-
code:
|
|
1852
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1467
1853
|
});
|
|
1468
1854
|
}
|
|
1469
1855
|
}
|
|
@@ -1482,22 +1868,62 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1482
1868
|
isStuckApp: isStuckAppStateError(err)
|
|
1483
1869
|
});
|
|
1484
1870
|
const autoInstallApp = commonParams?.autoInstallApp ?? this._defaultAutoInstallApp;
|
|
1485
|
-
const isAppMissing = isAppNotInstalledError(err) || err?.code ===
|
|
1871
|
+
const isAppMissing = isAppNotInstalledError(err) || err?.code === import_hwk_adapter_core3.HardwareErrorCode.AppNotInstalled;
|
|
1486
1872
|
if (autoInstallApp && isAppMissing) {
|
|
1873
|
+
if (installContext?.deviceOutOfMemoryError) {
|
|
1874
|
+
throw installContext.deviceOutOfMemoryError;
|
|
1875
|
+
}
|
|
1487
1876
|
const appName = err?.appName ?? mapLedgerError(err).appName;
|
|
1488
1877
|
if (appName) {
|
|
1878
|
+
if (installContext?.installAttemptedAppNames?.has(appName)) {
|
|
1879
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1880
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.AppNotInstalled,
|
|
1881
|
+
message: `${appName} install reported success but the app is still missing on device`,
|
|
1882
|
+
_tag: ERROR_TAG.AppInstallVerifyFailed,
|
|
1883
|
+
appName
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1489
1886
|
const confirmed = await this._waitForInstallAppConfirm(appName);
|
|
1490
|
-
if (!confirmed)
|
|
1887
|
+
if (!confirmed) {
|
|
1888
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1889
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1890
|
+
message: `User declined to install ${appName}`,
|
|
1891
|
+
_tag: ERROR_TAG.UserAborted,
|
|
1892
|
+
appName
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1491
1895
|
this.emitter.emit("ui-event", {
|
|
1492
|
-
type:
|
|
1896
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress,
|
|
1493
1897
|
payload: { connectId: resolvedConnectId, appName, progress: 0 }
|
|
1494
1898
|
});
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1899
|
+
try {
|
|
1900
|
+
await this._callConnector(sessionId, "installApp", { appName }, signal);
|
|
1901
|
+
} catch (installErr) {
|
|
1902
|
+
if (mapLedgerError(installErr).code === import_hwk_adapter_core3.HardwareErrorCode.DeviceOutOfMemory) {
|
|
1903
|
+
if (installContext) {
|
|
1904
|
+
installContext.deviceOutOfMemoryError = installErr;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
throw installErr;
|
|
1908
|
+
}
|
|
1909
|
+
if (installContext) {
|
|
1910
|
+
installContext.installAttemptedAppNames = installContext.installAttemptedAppNames ?? /* @__PURE__ */ new Set();
|
|
1911
|
+
installContext.installAttemptedAppNames.add(appName);
|
|
1912
|
+
}
|
|
1913
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1914
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1498
1915
|
payload: {}
|
|
1499
1916
|
});
|
|
1500
|
-
return await this.
|
|
1917
|
+
return await this._runConnectorCall(
|
|
1918
|
+
resolvedConnectId,
|
|
1919
|
+
method,
|
|
1920
|
+
effectiveParams,
|
|
1921
|
+
signal,
|
|
1922
|
+
fingerprint,
|
|
1923
|
+
permissionDeviceId,
|
|
1924
|
+
commonParams,
|
|
1925
|
+
installContext
|
|
1926
|
+
);
|
|
1501
1927
|
}
|
|
1502
1928
|
}
|
|
1503
1929
|
if (isStuckAppStateError(err)) {
|
|
@@ -1572,7 +1998,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1572
1998
|
);
|
|
1573
1999
|
if (!fp.success) {
|
|
1574
2000
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1575
|
-
code:
|
|
2001
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1576
2002
|
});
|
|
1577
2003
|
}
|
|
1578
2004
|
}
|
|
@@ -1607,7 +2033,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1607
2033
|
this.connector.reset();
|
|
1608
2034
|
const codeNum = err?.code;
|
|
1609
2035
|
throw Object.assign(err, {
|
|
1610
|
-
code: codeNum ??
|
|
2036
|
+
code: codeNum ?? import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected
|
|
1611
2037
|
});
|
|
1612
2038
|
}
|
|
1613
2039
|
throw err;
|
|
@@ -1641,7 +2067,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1641
2067
|
);
|
|
1642
2068
|
if (!fp.success) {
|
|
1643
2069
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1644
|
-
code:
|
|
2070
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1645
2071
|
});
|
|
1646
2072
|
}
|
|
1647
2073
|
}
|
|
@@ -1698,7 +2124,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1698
2124
|
);
|
|
1699
2125
|
if (!fp.success) {
|
|
1700
2126
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1701
|
-
code:
|
|
2127
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1702
2128
|
});
|
|
1703
2129
|
}
|
|
1704
2130
|
}
|
|
@@ -1739,7 +2165,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1739
2165
|
);
|
|
1740
2166
|
if (!fp.success) {
|
|
1741
2167
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1742
|
-
code:
|
|
2168
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1743
2169
|
});
|
|
1744
2170
|
}
|
|
1745
2171
|
}
|
|
@@ -1764,16 +2190,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1764
2190
|
}
|
|
1765
2191
|
const transportType = this.activeTransport ?? "hid";
|
|
1766
2192
|
const waitPromise = this._uiRegistry.wait(
|
|
1767
|
-
|
|
2193
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1768
2194
|
{ timeoutMs: 6e4 }
|
|
1769
2195
|
);
|
|
1770
|
-
this.emitter.emit(
|
|
1771
|
-
type:
|
|
2196
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION, {
|
|
2197
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1772
2198
|
payload: { transportType, connectId, deviceId }
|
|
1773
2199
|
});
|
|
1774
2200
|
let response;
|
|
1775
2201
|
const onAbort = () => {
|
|
1776
|
-
this._uiRegistry.cancel(
|
|
2202
|
+
this._uiRegistry.cancel(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION);
|
|
1777
2203
|
};
|
|
1778
2204
|
try {
|
|
1779
2205
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -1782,14 +2208,14 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1782
2208
|
if (signal?.aborted) {
|
|
1783
2209
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1784
2210
|
}
|
|
1785
|
-
if (err?._tag ===
|
|
1786
|
-
this.emitter.emit(
|
|
1787
|
-
type:
|
|
2211
|
+
if (err?._tag === import_hwk_adapter_core3.UI_REQUEST_PREEMPTED_TAG) {
|
|
2212
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
2213
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1788
2214
|
payload: {}
|
|
1789
2215
|
});
|
|
1790
2216
|
throw Object.assign(new Error("Device permission request superseded"), {
|
|
1791
2217
|
_tag: ERROR_TAG.UserAborted,
|
|
1792
|
-
code:
|
|
2218
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1793
2219
|
cause: err
|
|
1794
2220
|
});
|
|
1795
2221
|
}
|
|
@@ -1800,7 +2226,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1800
2226
|
const { granted, reason, message } = response;
|
|
1801
2227
|
if (!granted) {
|
|
1802
2228
|
throw Object.assign(new Error(message ?? "Device permission denied"), {
|
|
1803
|
-
code:
|
|
2229
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DevicePermissionDenied,
|
|
1804
2230
|
reason
|
|
1805
2231
|
});
|
|
1806
2232
|
}
|
|
@@ -1814,7 +2240,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1814
2240
|
const tag = err && typeof err === "object" ? err._tag : void 0;
|
|
1815
2241
|
if (err && typeof err === "object" && "code" in err && typeof err.code === "number") {
|
|
1816
2242
|
const e = err;
|
|
1817
|
-
const params = e.code ===
|
|
2243
|
+
const params = e.code === import_hwk_adapter_core3.HardwareErrorCode.DevicePermissionDenied && e.reason ? { permissionDeniedReason: e.reason } : e.params;
|
|
1818
2244
|
return ledgerFailure(e.code, e.message ?? "Unknown error", e.appName, tag, params);
|
|
1819
2245
|
}
|
|
1820
2246
|
const mapped = mapLedgerError(err);
|
|
@@ -1861,10 +2287,13 @@ _LedgerAdapter.STUCK_APP_RETRY_DELAY_MS = 500;
|
|
|
1861
2287
|
// Confirm but device never shows up / never unlocks), throw DeviceNotFound
|
|
1862
2288
|
// instead of looping forever.
|
|
1863
2289
|
_LedgerAdapter.MAX_DOCONNECT_CONFIRMS = 3;
|
|
2290
|
+
// Throttle AppInstallProgress by progress delta — DMK streams much faster
|
|
2291
|
+
// than UIs need. Final frame (progress >= 1) always passes.
|
|
2292
|
+
_LedgerAdapter.APP_INSTALL_PROGRESS_MIN_DELTA = 0.05;
|
|
1864
2293
|
var LedgerAdapter = _LedgerAdapter;
|
|
1865
2294
|
|
|
1866
2295
|
// src/connector/LedgerConnectorBase.ts
|
|
1867
|
-
var
|
|
2296
|
+
var import_hwk_adapter_core13 = require("@onekeyfe/hwk-adapter-core");
|
|
1868
2297
|
|
|
1869
2298
|
// src/device/LedgerDeviceManager.ts
|
|
1870
2299
|
var LedgerDeviceManager = class {
|
|
@@ -2137,7 +2566,7 @@ var import_device_signer_kit_ethereum = require("@ledgerhq/device-signer-kit-eth
|
|
|
2137
2566
|
var import_context_module = require("@ledgerhq/context-module");
|
|
2138
2567
|
|
|
2139
2568
|
// src/signer/SignerEth.ts
|
|
2140
|
-
var
|
|
2569
|
+
var import_hwk_adapter_core4 = require("@onekeyfe/hwk-adapter-core");
|
|
2141
2570
|
|
|
2142
2571
|
// src/signer/deviceActionToPromise.ts
|
|
2143
2572
|
var import_device_management_kit = require("@ledgerhq/device-management-kit");
|
|
@@ -2350,7 +2779,7 @@ var SignerEth = class {
|
|
|
2350
2779
|
);
|
|
2351
2780
|
}
|
|
2352
2781
|
async signTransaction(derivationPath, serializedTxHex) {
|
|
2353
|
-
const action = this._sdk.signTransaction(derivationPath, (0,
|
|
2782
|
+
const action = this._sdk.signTransaction(derivationPath, (0, import_hwk_adapter_core4.hexToBytes)(serializedTxHex));
|
|
2354
2783
|
return deviceActionToPromise(
|
|
2355
2784
|
action,
|
|
2356
2785
|
this.onInteraction,
|
|
@@ -2359,7 +2788,7 @@ var SignerEth = class {
|
|
|
2359
2788
|
);
|
|
2360
2789
|
}
|
|
2361
2790
|
async signMessage(derivationPath, message) {
|
|
2362
|
-
const action = this._sdk.signMessage(derivationPath, (0,
|
|
2791
|
+
const action = this._sdk.signMessage(derivationPath, (0, import_hwk_adapter_core4.hexToBytes)(message));
|
|
2363
2792
|
return deviceActionToPromise(
|
|
2364
2793
|
action,
|
|
2365
2794
|
this.onInteraction,
|
|
@@ -2419,23 +2848,23 @@ var SignerManager = class _SignerManager {
|
|
|
2419
2848
|
};
|
|
2420
2849
|
|
|
2421
2850
|
// src/connector/chains/evm.ts
|
|
2422
|
-
var
|
|
2851
|
+
var import_hwk_adapter_core6 = require("@onekeyfe/hwk-adapter-core");
|
|
2423
2852
|
|
|
2424
2853
|
// src/connector/chains/utils.ts
|
|
2425
|
-
var
|
|
2854
|
+
var import_hwk_adapter_core5 = require("@onekeyfe/hwk-adapter-core");
|
|
2426
2855
|
function normalizePath(path) {
|
|
2427
2856
|
return path.startsWith("m/") ? path.slice(2) : path;
|
|
2428
2857
|
}
|
|
2429
2858
|
function collapseSignerInteraction(interaction) {
|
|
2430
2859
|
switch (interaction) {
|
|
2431
2860
|
case "confirm-open-app":
|
|
2432
|
-
return
|
|
2861
|
+
return import_hwk_adapter_core5.EConnectorInteraction.ConfirmOpenApp;
|
|
2433
2862
|
case "unlock-device":
|
|
2434
|
-
return
|
|
2863
|
+
return import_hwk_adapter_core5.EConnectorInteraction.UnlockDevice;
|
|
2435
2864
|
case "interaction-complete":
|
|
2436
|
-
return
|
|
2865
|
+
return import_hwk_adapter_core5.EConnectorInteraction.InteractionComplete;
|
|
2437
2866
|
default:
|
|
2438
|
-
return
|
|
2867
|
+
return import_hwk_adapter_core5.EConnectorInteraction.ConfirmOnDevice;
|
|
2439
2868
|
}
|
|
2440
2869
|
}
|
|
2441
2870
|
|
|
@@ -2461,7 +2890,7 @@ async function evmSignTransaction(ctx, sessionId, params) {
|
|
|
2461
2890
|
new Error(
|
|
2462
2891
|
"Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string."
|
|
2463
2892
|
),
|
|
2464
|
-
{ code:
|
|
2893
|
+
{ code: import_hwk_adapter_core6.HardwareErrorCode.InvalidParams }
|
|
2465
2894
|
);
|
|
2466
2895
|
}
|
|
2467
2896
|
const signer = await _getEthSigner(ctx, sessionId);
|
|
@@ -2470,8 +2899,8 @@ async function evmSignTransaction(ctx, sessionId, params) {
|
|
|
2470
2899
|
const result = await signer.signTransaction(path, params.serializedTx);
|
|
2471
2900
|
return {
|
|
2472
2901
|
v: `0x${result.v.toString(16)}`,
|
|
2473
|
-
r: (0,
|
|
2474
|
-
s: (0,
|
|
2902
|
+
r: (0, import_hwk_adapter_core6.padHex64)(result.r),
|
|
2903
|
+
s: (0, import_hwk_adapter_core6.padHex64)(result.s)
|
|
2475
2904
|
};
|
|
2476
2905
|
} catch (err) {
|
|
2477
2906
|
ctx.invalidateSession(sessionId);
|
|
@@ -2485,8 +2914,8 @@ async function evmSignMessage(ctx, sessionId, params) {
|
|
|
2485
2914
|
const path = normalizePath(params.path);
|
|
2486
2915
|
try {
|
|
2487
2916
|
const result = await signer.signMessage(path, params.message);
|
|
2488
|
-
const rHex = (0,
|
|
2489
|
-
const sHex = (0,
|
|
2917
|
+
const rHex = (0, import_hwk_adapter_core6.stripHex)(result.r).padStart(64, "0");
|
|
2918
|
+
const sHex = (0, import_hwk_adapter_core6.stripHex)(result.s).padStart(64, "0");
|
|
2490
2919
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2491
2920
|
return { signature: `0x${rHex}${sHex}${vHex}` };
|
|
2492
2921
|
} catch (err) {
|
|
@@ -2502,15 +2931,15 @@ async function evmSignTypedData(ctx, sessionId, params) {
|
|
|
2502
2931
|
new Error(
|
|
2503
2932
|
'Ledger does not support hash-only EIP-712 signing. Use mode "full" with the complete typed data structure.'
|
|
2504
2933
|
),
|
|
2505
|
-
{ code:
|
|
2934
|
+
{ code: import_hwk_adapter_core6.HardwareErrorCode.MethodNotSupported }
|
|
2506
2935
|
);
|
|
2507
2936
|
}
|
|
2508
2937
|
const signer = await _getEthSigner(ctx, sessionId);
|
|
2509
2938
|
const path = normalizePath(params.path);
|
|
2510
2939
|
try {
|
|
2511
2940
|
const result = await signer.signTypedData(path, params.data);
|
|
2512
|
-
const rHex = (0,
|
|
2513
|
-
const sHex = (0,
|
|
2941
|
+
const rHex = (0, import_hwk_adapter_core6.stripHex)(result.r).padStart(64, "0");
|
|
2942
|
+
const sHex = (0, import_hwk_adapter_core6.stripHex)(result.s).padStart(64, "0");
|
|
2514
2943
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2515
2944
|
return { signature: `0x${rHex}${sHex}${vHex}` };
|
|
2516
2945
|
} catch (err) {
|
|
@@ -2537,13 +2966,13 @@ async function _getEthSigner(ctx, sessionId) {
|
|
|
2537
2966
|
}
|
|
2538
2967
|
|
|
2539
2968
|
// src/connector/chains/btc.ts
|
|
2540
|
-
var
|
|
2969
|
+
var import_hwk_adapter_core8 = require("@onekeyfe/hwk-adapter-core");
|
|
2541
2970
|
var import_bitcoinjs_lib = require("bitcoinjs-lib");
|
|
2542
2971
|
|
|
2543
2972
|
// src/signer/SignerBtc.ts
|
|
2544
|
-
var
|
|
2973
|
+
var import_hwk_adapter_core7 = require("@onekeyfe/hwk-adapter-core");
|
|
2545
2974
|
function hexToUtf8(hex) {
|
|
2546
|
-
return new TextDecoder().decode((0,
|
|
2975
|
+
return new TextDecoder().decode((0, import_hwk_adapter_core7.hexToBytes)(hex));
|
|
2547
2976
|
}
|
|
2548
2977
|
var INTERACTIVE_TIMEOUT_MS2 = 5 * 6e4;
|
|
2549
2978
|
var SignerBtc = class {
|
|
@@ -2658,7 +3087,7 @@ function _purposeToTemplate(purpose, DDT) {
|
|
|
2658
3087
|
return DDT.TAPROOT;
|
|
2659
3088
|
default:
|
|
2660
3089
|
throw Object.assign(new Error(`Unsupported BTC purpose: m/${purpose ?? "<undefined>"}'`), {
|
|
2661
|
-
code:
|
|
3090
|
+
code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams
|
|
2662
3091
|
});
|
|
2663
3092
|
}
|
|
2664
3093
|
}
|
|
@@ -2714,7 +3143,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2714
3143
|
if (!params.psbt) {
|
|
2715
3144
|
throw Object.assign(
|
|
2716
3145
|
new Error("Ledger requires PSBT format for BTC transaction signing. Provide params.psbt."),
|
|
2717
|
-
{ code:
|
|
3146
|
+
{ code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams }
|
|
2718
3147
|
);
|
|
2719
3148
|
}
|
|
2720
3149
|
const btcSigner = await _createBtcSigner(ctx, sessionId);
|
|
@@ -2728,7 +3157,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2728
3157
|
debugLog("[LedgerConnector] btcSignTransaction wallet:", { path, purpose, template });
|
|
2729
3158
|
const wallet = new DefaultWallet(path, template);
|
|
2730
3159
|
const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt);
|
|
2731
|
-
return { serializedTx: (0,
|
|
3160
|
+
return { serializedTx: (0, import_hwk_adapter_core8.stripHex)(signedTxHex) };
|
|
2732
3161
|
} catch (err) {
|
|
2733
3162
|
ctx.invalidateSession(sessionId);
|
|
2734
3163
|
throw ctx.wrapError(err);
|
|
@@ -2739,7 +3168,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2739
3168
|
async function btcSignPsbt(ctx, sessionId, params) {
|
|
2740
3169
|
if (!params.psbt) {
|
|
2741
3170
|
throw Object.assign(new Error("btcSignPsbt requires params.psbt"), {
|
|
2742
|
-
code:
|
|
3171
|
+
code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams
|
|
2743
3172
|
});
|
|
2744
3173
|
}
|
|
2745
3174
|
const btcSigner = await _createBtcSigner(ctx, sessionId);
|
|
@@ -2769,8 +3198,8 @@ async function btcSignMessage(ctx, sessionId, params) {
|
|
|
2769
3198
|
try {
|
|
2770
3199
|
const result = await btcSigner.signMessage(path, params.message);
|
|
2771
3200
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2772
|
-
const rHex = (0,
|
|
2773
|
-
const sHex = (0,
|
|
3201
|
+
const rHex = (0, import_hwk_adapter_core8.stripHex)(result.r).padStart(64, "0");
|
|
3202
|
+
const sHex = (0, import_hwk_adapter_core8.stripHex)(result.s).padStart(64, "0");
|
|
2774
3203
|
return { signature: `${vHex}${rHex}${sHex}` };
|
|
2775
3204
|
} catch (err) {
|
|
2776
3205
|
ctx.invalidateSession(sessionId);
|
|
@@ -2870,7 +3299,7 @@ function _applySignaturesToPsbt(psbtHex, signatures) {
|
|
|
2870
3299
|
}
|
|
2871
3300
|
|
|
2872
3301
|
// src/connector/chains/sol.ts
|
|
2873
|
-
var
|
|
3302
|
+
var import_hwk_adapter_core9 = require("@onekeyfe/hwk-adapter-core");
|
|
2874
3303
|
|
|
2875
3304
|
// src/signer/SignerSol.ts
|
|
2876
3305
|
var SignerSol = class {
|
|
@@ -2938,10 +3367,10 @@ async function solGetAddress(ctx, sessionId, params) {
|
|
|
2938
3367
|
async function solSignTransaction(ctx, sessionId, params) {
|
|
2939
3368
|
const solSigner = await _createSolSigner(ctx, sessionId);
|
|
2940
3369
|
const path = normalizePath(params.path);
|
|
2941
|
-
const txBytes = (0,
|
|
3370
|
+
const txBytes = (0, import_hwk_adapter_core9.hexToBytes)(params.serializedTx);
|
|
2942
3371
|
try {
|
|
2943
3372
|
const result = await solSigner.signTransaction(path, txBytes);
|
|
2944
|
-
return { signature: (0,
|
|
3373
|
+
return { signature: (0, import_hwk_adapter_core9.bytesToHex)(result) };
|
|
2945
3374
|
} catch (err) {
|
|
2946
3375
|
ctx.invalidateSession(sessionId);
|
|
2947
3376
|
throw ctx.wrapError(err);
|
|
@@ -2952,7 +3381,7 @@ async function solSignTransaction(ctx, sessionId, params) {
|
|
|
2952
3381
|
async function solSignMessage(ctx, sessionId, params) {
|
|
2953
3382
|
const solSigner = await _createSolSigner(ctx, sessionId);
|
|
2954
3383
|
const path = normalizePath(params.path);
|
|
2955
|
-
const messageBytes = (0,
|
|
3384
|
+
const messageBytes = (0, import_hwk_adapter_core9.hexToBytes)(params.message);
|
|
2956
3385
|
try {
|
|
2957
3386
|
const result = await solSigner.signMessage(path, messageBytes);
|
|
2958
3387
|
return { signature: result.signature };
|
|
@@ -2984,15 +3413,15 @@ async function _createSolSigner(ctx, sessionId) {
|
|
|
2984
3413
|
}
|
|
2985
3414
|
|
|
2986
3415
|
// src/connector/chains/tron.ts
|
|
2987
|
-
var
|
|
3416
|
+
var import_hwk_adapter_core12 = require("@onekeyfe/hwk-adapter-core");
|
|
2988
3417
|
var import_hw_app_trx = __toESM(require("@ledgerhq/hw-app-trx"));
|
|
2989
3418
|
|
|
2990
3419
|
// src/connector/chains/legacyChainCall.ts
|
|
2991
|
-
var
|
|
3420
|
+
var import_hwk_adapter_core11 = require("@onekeyfe/hwk-adapter-core");
|
|
2992
3421
|
|
|
2993
3422
|
// src/app/AppManager.ts
|
|
2994
3423
|
var import_device_management_kit2 = require("@ledgerhq/device-management-kit");
|
|
2995
|
-
var
|
|
3424
|
+
var import_hwk_adapter_core10 = require("@onekeyfe/hwk-adapter-core");
|
|
2996
3425
|
var APP_NAME_MAP = {
|
|
2997
3426
|
ETH: "Ethereum",
|
|
2998
3427
|
BTC: "Bitcoin",
|
|
@@ -3096,15 +3525,30 @@ var AppManager = class {
|
|
|
3096
3525
|
command: new import_device_management_kit2.OpenAppCommand({ appName })
|
|
3097
3526
|
});
|
|
3098
3527
|
if (!(0, import_device_management_kit2.isSuccessCommandResult)(result)) {
|
|
3099
|
-
const
|
|
3100
|
-
const
|
|
3101
|
-
|
|
3528
|
+
const dmkErr = result.error;
|
|
3529
|
+
const errorCode = "errorCode" in dmkErr && dmkErr.errorCode != null ? String(dmkErr.errorCode) : "";
|
|
3530
|
+
const message = "message" in dmkErr && typeof dmkErr.message === "string" ? dmkErr.message : "";
|
|
3531
|
+
debugLog(
|
|
3532
|
+
"[AppManager] openApp failed:",
|
|
3533
|
+
appName,
|
|
3534
|
+
"errorCode:",
|
|
3535
|
+
errorCode,
|
|
3536
|
+
"tag:",
|
|
3537
|
+
dmkErr._tag
|
|
3538
|
+
);
|
|
3539
|
+
let code;
|
|
3540
|
+
if (errorCode === "6807" || /unknown application/i.test(message)) {
|
|
3541
|
+
code = import_hwk_adapter_core10.HardwareErrorCode.AppNotInstalled;
|
|
3542
|
+
} else if (errorCode === "5501" || dmkErr._tag === "ActionRefusedError") {
|
|
3543
|
+
code = import_hwk_adapter_core10.HardwareErrorCode.UserRejected;
|
|
3544
|
+
}
|
|
3102
3545
|
throw Object.assign(new Error(`Failed to open "${appName}"`), {
|
|
3103
3546
|
_tag: ERROR_TAG.OpenAppCommand,
|
|
3104
|
-
code
|
|
3105
|
-
errorCode
|
|
3106
|
-
statusCode,
|
|
3107
|
-
appName
|
|
3547
|
+
code,
|
|
3548
|
+
errorCode,
|
|
3549
|
+
statusCode: errorCode,
|
|
3550
|
+
appName,
|
|
3551
|
+
originalError: dmkErr
|
|
3108
3552
|
});
|
|
3109
3553
|
}
|
|
3110
3554
|
}
|
|
@@ -3157,14 +3601,14 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3157
3601
|
const onAppOpenPrompt = () => {
|
|
3158
3602
|
openAppPromptShown = true;
|
|
3159
3603
|
ctx.emit("ui-event", {
|
|
3160
|
-
type:
|
|
3604
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOpenApp,
|
|
3161
3605
|
payload: { sessionId }
|
|
3162
3606
|
});
|
|
3163
3607
|
};
|
|
3164
3608
|
const closeOpenAppUiIfShown = () => {
|
|
3165
3609
|
if (openAppPromptShown) {
|
|
3166
3610
|
ctx.emit("ui-event", {
|
|
3167
|
-
type:
|
|
3611
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
|
|
3168
3612
|
payload: { sessionId }
|
|
3169
3613
|
});
|
|
3170
3614
|
openAppPromptShown = false;
|
|
@@ -3185,7 +3629,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3185
3629
|
let confirmEmitted = false;
|
|
3186
3630
|
if (needsConfirmation) {
|
|
3187
3631
|
ctx.emit("ui-event", {
|
|
3188
|
-
type:
|
|
3632
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOnDevice,
|
|
3189
3633
|
payload: { sessionId }
|
|
3190
3634
|
});
|
|
3191
3635
|
confirmEmitted = true;
|
|
@@ -3195,7 +3639,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3195
3639
|
} finally {
|
|
3196
3640
|
if (confirmEmitted || openAppPromptShown) {
|
|
3197
3641
|
ctx.emit("ui-event", {
|
|
3198
|
-
type:
|
|
3642
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
|
|
3199
3643
|
payload: { sessionId }
|
|
3200
3644
|
});
|
|
3201
3645
|
openAppPromptShown = false;
|
|
@@ -3283,7 +3727,7 @@ async function tronSignTransaction(ctx, sessionId, params) {
|
|
|
3283
3727
|
if (!params.rawTxHex) {
|
|
3284
3728
|
throw Object.assign(
|
|
3285
3729
|
new Error("TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex)."),
|
|
3286
|
-
{ code:
|
|
3730
|
+
{ code: import_hwk_adapter_core12.HardwareErrorCode.InvalidParams }
|
|
3287
3731
|
);
|
|
3288
3732
|
}
|
|
3289
3733
|
const path = normalizePath(params.path);
|
|
@@ -3444,6 +3888,22 @@ var DeviceApps = class {
|
|
|
3444
3888
|
);
|
|
3445
3889
|
return result.filter((a) => a !== null).map(applicationToMetadata);
|
|
3446
3890
|
}
|
|
3891
|
+
/** Installed app names via ListApps APDU. Offline (no manager-api), but still requires unlock + dashboard. */
|
|
3892
|
+
async listInstalledNames(options) {
|
|
3893
|
+
const action = this._dmk.executeDeviceAction({
|
|
3894
|
+
sessionId: this._sessionId,
|
|
3895
|
+
deviceAction: new this._ledgerKit.ListAppsDeviceAction({
|
|
3896
|
+
input: { unlockTimeout: options?.unlockTimeout }
|
|
3897
|
+
})
|
|
3898
|
+
});
|
|
3899
|
+
const result = await deviceActionToPromise(
|
|
3900
|
+
action,
|
|
3901
|
+
this.onInteraction,
|
|
3902
|
+
void 0,
|
|
3903
|
+
this.onRegisterCanceller
|
|
3904
|
+
);
|
|
3905
|
+
return result.map((entry) => entry?.appName).filter((name) => typeof name === "string" && name.length > 0);
|
|
3906
|
+
}
|
|
3447
3907
|
// Catalog lookup via custom device action — DMK has no typed wrapper for this.
|
|
3448
3908
|
async listAvailable() {
|
|
3449
3909
|
const customAction = new ListAvailableAppsDeviceAction({
|
|
@@ -3507,6 +3967,22 @@ var DeviceApps = class {
|
|
|
3507
3967
|
async install(appName, onProgress, options) {
|
|
3508
3968
|
if (!appName) throw new Error("DeviceApps.install: appName is required");
|
|
3509
3969
|
debugLog("[DeviceApps] install:", appName);
|
|
3970
|
+
const refreshAction = this._dmk.executeDeviceAction({
|
|
3971
|
+
sessionId: this._sessionId,
|
|
3972
|
+
deviceAction: new this._ledgerKit.GetDeviceMetadataDeviceAction({
|
|
3973
|
+
input: {
|
|
3974
|
+
useSecureChannel: true,
|
|
3975
|
+
forceUpdate: true,
|
|
3976
|
+
unlockTimeout: options?.unlockTimeout
|
|
3977
|
+
}
|
|
3978
|
+
})
|
|
3979
|
+
});
|
|
3980
|
+
await deviceActionToPromise(
|
|
3981
|
+
refreshAction,
|
|
3982
|
+
this.onInteraction,
|
|
3983
|
+
INSTALL_TIMEOUT_MS,
|
|
3984
|
+
this.onRegisterCanceller
|
|
3985
|
+
);
|
|
3510
3986
|
const action = this._dmk.executeDeviceAction({
|
|
3511
3987
|
sessionId: this._sessionId,
|
|
3512
3988
|
deviceAction: new this._ledgerKit.InstallOrUpdateAppsDeviceAction({
|
|
@@ -3584,7 +4060,7 @@ var METHOD_PREFIX_TO_APP_NAME = {
|
|
|
3584
4060
|
tron: "Tron"
|
|
3585
4061
|
};
|
|
3586
4062
|
var HARDWARE_ERROR_CODE_VALUES = new Set(
|
|
3587
|
-
Object.values(
|
|
4063
|
+
Object.values(import_hwk_adapter_core13.HardwareErrorCode).filter((value) => typeof value === "number")
|
|
3588
4064
|
);
|
|
3589
4065
|
var BLE_CONNECT_SCAN_TIMEOUT_MS = 1500;
|
|
3590
4066
|
async function defaultLedgerKitImporter(pkg) {
|
|
@@ -3707,7 +4183,7 @@ var LedgerConnectorBase = class {
|
|
|
3707
4183
|
async searchDevices() {
|
|
3708
4184
|
const dm = await this._getDeviceManager();
|
|
3709
4185
|
const descriptors = await this._discoverDescriptors(dm);
|
|
3710
|
-
const resolvedDescriptors = descriptors.map((d) => ({
|
|
4186
|
+
const resolvedDescriptors = descriptors.filter((d) => !(0, import_hwk_adapter_core13.isKnownNonTargetHardwareVendor)(d, "ledger")).map((d) => ({
|
|
3711
4187
|
descriptor: d,
|
|
3712
4188
|
connectId: this._resolveConnectId(d)
|
|
3713
4189
|
}));
|
|
@@ -3755,7 +4231,7 @@ var LedgerConnectorBase = class {
|
|
|
3755
4231
|
`Ledger BLE connect did not return within ${HANG_CEILING_MS / 6e4}min \u2014 DMK hang fallback.`
|
|
3756
4232
|
);
|
|
3757
4233
|
err._tag = ERROR_TAG.BlePairingTimeout;
|
|
3758
|
-
err.code =
|
|
4234
|
+
err.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
|
|
3759
4235
|
reject(err);
|
|
3760
4236
|
}, HANG_CEILING_MS);
|
|
3761
4237
|
});
|
|
@@ -3788,7 +4264,7 @@ var LedgerConnectorBase = class {
|
|
|
3788
4264
|
"Ledger device is not currently advertising. Wake up and unlock the device, keep it nearby, then try again."
|
|
3789
4265
|
);
|
|
3790
4266
|
err._tag = ERROR_TAG.DeviceNotAdvertising;
|
|
3791
|
-
err.code =
|
|
4267
|
+
err.code = import_hwk_adapter_core13.HardwareErrorCode.DeviceNotFound;
|
|
3792
4268
|
throw err;
|
|
3793
4269
|
};
|
|
3794
4270
|
const doConnect = async (path) => {
|
|
@@ -3852,7 +4328,7 @@ var LedgerConnectorBase = class {
|
|
|
3852
4328
|
"Ledger Bluetooth pairing failed. Make sure the device is unlocked and nearby, then try again."
|
|
3853
4329
|
);
|
|
3854
4330
|
wrapped._tag = ERROR_TAG.BleGattBondingFailed;
|
|
3855
|
-
wrapped.code =
|
|
4331
|
+
wrapped.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
|
|
3856
4332
|
wrapped.originalError = err;
|
|
3857
4333
|
throw wrapped;
|
|
3858
4334
|
}
|
|
@@ -3930,7 +4406,7 @@ var LedgerConnectorBase = class {
|
|
|
3930
4406
|
this._unwatchSessionState(sessionId);
|
|
3931
4407
|
this._signerManager?.invalidate(sessionId);
|
|
3932
4408
|
this._cancellers.get(sessionId)?.({
|
|
3933
|
-
code:
|
|
4409
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.DeviceDisconnected,
|
|
3934
4410
|
tag: "DeviceDisconnected",
|
|
3935
4411
|
message: "Device disconnected"
|
|
3936
4412
|
});
|
|
@@ -3954,9 +4430,9 @@ var LedgerConnectorBase = class {
|
|
|
3954
4430
|
if (isAppStuckByApdu(err)) {
|
|
3955
4431
|
return {
|
|
3956
4432
|
success: false,
|
|
3957
|
-
error: (0,
|
|
4433
|
+
error: (0, import_hwk_adapter_core13.serializeConnectorError)(
|
|
3958
4434
|
Object.assign(new Error("Ledger app is unresponsive"), {
|
|
3959
|
-
code:
|
|
4435
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.DeviceAppStuck,
|
|
3960
4436
|
_tag: ERROR_TAG.DeviceAppStuck,
|
|
3961
4437
|
originalError: err
|
|
3962
4438
|
})
|
|
@@ -3966,16 +4442,16 @@ var LedgerConnectorBase = class {
|
|
|
3966
4442
|
if (isTransportStuck(err)) {
|
|
3967
4443
|
return {
|
|
3968
4444
|
success: false,
|
|
3969
|
-
error: (0,
|
|
4445
|
+
error: (0, import_hwk_adapter_core13.serializeConnectorError)(
|
|
3970
4446
|
Object.assign(new Error("Device communication interrupted, please retry"), {
|
|
3971
|
-
code:
|
|
4447
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.TransportError,
|
|
3972
4448
|
_tag: ERROR_TAG.DeviceTransportStuck,
|
|
3973
4449
|
originalError: err
|
|
3974
4450
|
})
|
|
3975
4451
|
)
|
|
3976
4452
|
};
|
|
3977
4453
|
}
|
|
3978
|
-
return { success: false, error: (0,
|
|
4454
|
+
return { success: false, error: (0, import_hwk_adapter_core13.serializeConnectorError)(err) };
|
|
3979
4455
|
}
|
|
3980
4456
|
}
|
|
3981
4457
|
async _dispatch(sessionId, method, params) {
|
|
@@ -4038,7 +4514,7 @@ var LedgerConnectorBase = class {
|
|
|
4038
4514
|
try {
|
|
4039
4515
|
return await apps.install(p.appName, ({ progress }) => {
|
|
4040
4516
|
ctx.emit("ui-event", {
|
|
4041
|
-
type:
|
|
4517
|
+
type: import_hwk_adapter_core13.EConnectorInteraction.AppInstallProgress,
|
|
4042
4518
|
payload: {
|
|
4043
4519
|
sessionId,
|
|
4044
4520
|
appName: p.appName,
|
|
@@ -4064,6 +4540,17 @@ var LedgerConnectorBase = class {
|
|
|
4064
4540
|
ctx.clearCanceller(sessionId);
|
|
4065
4541
|
}
|
|
4066
4542
|
}
|
|
4543
|
+
case "listInstalledNames": {
|
|
4544
|
+
const apps = await _getDeviceApps(ctx, sessionId);
|
|
4545
|
+
try {
|
|
4546
|
+
return await apps.listInstalledNames(params);
|
|
4547
|
+
} catch (err) {
|
|
4548
|
+
ctx.invalidateSession(sessionId);
|
|
4549
|
+
throw ctx.wrapError(err);
|
|
4550
|
+
} finally {
|
|
4551
|
+
ctx.clearCanceller(sessionId);
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4067
4554
|
case "listAvailableApps": {
|
|
4068
4555
|
const apps = await _getDeviceApps(ctx, sessionId);
|
|
4069
4556
|
try {
|