@onekeyfe/hwk-ledger-adapter 1.2.0-alpha.0 → 1.2.0-alpha.2
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 +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +723 -220
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +655 -151
- 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,252 @@ 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
|
+
doge: "Dogecoin",
|
|
545
|
+
ltc: "Litecoin",
|
|
546
|
+
neurai: "Neurai"
|
|
547
|
+
};
|
|
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 responses = [];
|
|
559
|
+
const chainFingerprints = /* @__PURE__ */ new Map();
|
|
560
|
+
for (const item of params.bundle) {
|
|
561
|
+
const method = getAllNetworkMethod(item);
|
|
562
|
+
if (!method) {
|
|
563
|
+
responses.push(buildUnsupportedMethodResponse(item));
|
|
564
|
+
} else {
|
|
565
|
+
const chain = getFingerprintChain(method);
|
|
566
|
+
const itemDeviceId = getItemDeviceId(item) ?? chainFingerprints.get(chain) ?? "";
|
|
567
|
+
const normalizedItem = normalizeLedgerAllNetworkItem(method, item);
|
|
568
|
+
const response = await callAllNetworkItem(
|
|
569
|
+
callChain,
|
|
570
|
+
getChainFingerprint,
|
|
571
|
+
connectId,
|
|
572
|
+
itemDeviceId,
|
|
573
|
+
chain,
|
|
574
|
+
method,
|
|
575
|
+
normalizedItem,
|
|
576
|
+
commonParams,
|
|
577
|
+
installContext,
|
|
578
|
+
chainFingerprints
|
|
579
|
+
);
|
|
580
|
+
if (isTopLevelAllNetworkFailure(response)) {
|
|
581
|
+
const code = response.payload?.code ?? import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch;
|
|
582
|
+
const result2 = (0, import_hwk_adapter_core2.failure)(
|
|
583
|
+
code,
|
|
584
|
+
response.payload?.error ?? "All-network get-address aborted",
|
|
585
|
+
response.payload?.params
|
|
586
|
+
);
|
|
587
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
588
|
+
method: "allNetworkGetAddress",
|
|
589
|
+
success: false,
|
|
590
|
+
payload: result2
|
|
591
|
+
});
|
|
592
|
+
return result2;
|
|
593
|
+
}
|
|
594
|
+
responses.push(response);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
const result = (0, import_hwk_adapter_core2.success)(responses);
|
|
598
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
599
|
+
method: "allNetworkGetAddress",
|
|
600
|
+
success: true,
|
|
601
|
+
payload: result
|
|
602
|
+
});
|
|
603
|
+
return result;
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function isTopLevelAllNetworkFailure(response) {
|
|
607
|
+
if (response.success) {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
const code = response.payload?.code;
|
|
611
|
+
return code === import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch || code === import_hwk_adapter_core2.HardwareErrorCode.UserAborted || code === import_hwk_adapter_core2.HardwareErrorCode.UserRejected;
|
|
612
|
+
}
|
|
613
|
+
function getItemDeviceId(item) {
|
|
614
|
+
const { deviceId } = item;
|
|
615
|
+
return typeof deviceId === "string" && deviceId.length > 0 ? deviceId : void 0;
|
|
616
|
+
}
|
|
617
|
+
function getAllNetworkMethod(item) {
|
|
618
|
+
switch (item.methodName) {
|
|
619
|
+
case "evmGetAddress":
|
|
620
|
+
case "btcGetAddress":
|
|
621
|
+
case "btcGetPublicKey":
|
|
622
|
+
case "solGetAddress":
|
|
623
|
+
case "tronGetAddress":
|
|
624
|
+
return item.methodName;
|
|
625
|
+
default:
|
|
626
|
+
return void 0;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
function buildUnsupportedMethodResponse(item) {
|
|
630
|
+
return {
|
|
631
|
+
...item,
|
|
632
|
+
success: false,
|
|
633
|
+
payload: {
|
|
634
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.InvalidParams,
|
|
635
|
+
error: `Unsupported allNetwork method: ${String(item.methodName)}`
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function normalizeLedgerAllNetworkItem(method, item) {
|
|
640
|
+
if (method !== "btcGetAddress" && method !== "btcGetPublicKey") {
|
|
641
|
+
return item;
|
|
642
|
+
}
|
|
643
|
+
const itemWithCoin = item;
|
|
644
|
+
if (itemWithCoin.coin) {
|
|
645
|
+
return item;
|
|
646
|
+
}
|
|
647
|
+
const coin = LEDGER_BTC_NETWORK_COIN_MAP[item.network];
|
|
648
|
+
return coin ? { ...item, coin } : item;
|
|
649
|
+
}
|
|
650
|
+
async function callAllNetworkItem(callChain, getChainFingerprint, connectId, deviceId, chain, method, item, commonParams, installContext, chainFingerprints) {
|
|
651
|
+
const response = await callAllNetworkMethod(
|
|
652
|
+
callChain,
|
|
653
|
+
connectId,
|
|
654
|
+
deviceId,
|
|
655
|
+
method,
|
|
656
|
+
item,
|
|
657
|
+
commonParams,
|
|
658
|
+
installContext
|
|
659
|
+
);
|
|
660
|
+
if (!response.success) {
|
|
661
|
+
return { ...item, success: false, payload: response.payload };
|
|
662
|
+
}
|
|
663
|
+
const payload = response.payload;
|
|
664
|
+
const fingerprint = deviceId || chainFingerprints.get(chain) || await bootstrapChainFingerprint(getChainFingerprint, connectId, chain);
|
|
665
|
+
if (!fingerprint) {
|
|
666
|
+
return buildFingerprintBootstrapFailure(item, chain);
|
|
667
|
+
}
|
|
668
|
+
chainFingerprints.set(chain, fingerprint);
|
|
669
|
+
return {
|
|
670
|
+
...item,
|
|
671
|
+
success: true,
|
|
672
|
+
payload: {
|
|
673
|
+
...payload,
|
|
674
|
+
chainFingerprint: fingerprint,
|
|
675
|
+
chainFingerprintChain: chain
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain) {
|
|
680
|
+
const response = await getChainFingerprint(connectId, chain);
|
|
681
|
+
return response.success ? response.payload : "";
|
|
682
|
+
}
|
|
683
|
+
function buildFingerprintBootstrapFailure(item, chain) {
|
|
684
|
+
return {
|
|
685
|
+
...item,
|
|
686
|
+
success: false,
|
|
687
|
+
payload: {
|
|
688
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch,
|
|
689
|
+
error: `Could not establish chain fingerprint for ${chain} after device call; refusing to return unverifiable result. Please retry.`
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
function getFingerprintChain(method) {
|
|
694
|
+
switch (method) {
|
|
695
|
+
case "evmGetAddress":
|
|
696
|
+
return "evm";
|
|
697
|
+
case "btcGetAddress":
|
|
698
|
+
case "btcGetPublicKey":
|
|
699
|
+
return "btc";
|
|
700
|
+
case "solGetAddress":
|
|
701
|
+
return "sol";
|
|
702
|
+
case "tronGetAddress":
|
|
703
|
+
return "tron";
|
|
704
|
+
default:
|
|
705
|
+
throw Object.assign(new Error(`Unsupported allNetwork method: ${method}`), {
|
|
706
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.InvalidParams
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async function callAllNetworkMethod(callChain, connectId, deviceId, method, item, commonParams, installContext) {
|
|
711
|
+
switch (method) {
|
|
712
|
+
case "evmGetAddress":
|
|
713
|
+
return callChain(
|
|
714
|
+
connectId,
|
|
715
|
+
deviceId,
|
|
716
|
+
"evm",
|
|
717
|
+
"evmGetAddress",
|
|
718
|
+
item,
|
|
719
|
+
commonParams,
|
|
720
|
+
false,
|
|
721
|
+
installContext
|
|
722
|
+
);
|
|
723
|
+
case "btcGetAddress":
|
|
724
|
+
return callChain(
|
|
725
|
+
connectId,
|
|
726
|
+
deviceId,
|
|
727
|
+
"btc",
|
|
728
|
+
"btcGetAddress",
|
|
729
|
+
item,
|
|
730
|
+
commonParams,
|
|
731
|
+
false,
|
|
732
|
+
installContext
|
|
733
|
+
);
|
|
734
|
+
case "btcGetPublicKey":
|
|
735
|
+
return callChain(
|
|
736
|
+
connectId,
|
|
737
|
+
deviceId,
|
|
738
|
+
"btc",
|
|
739
|
+
"btcGetPublicKey",
|
|
740
|
+
item,
|
|
741
|
+
commonParams,
|
|
742
|
+
false,
|
|
743
|
+
installContext
|
|
744
|
+
);
|
|
745
|
+
case "solGetAddress":
|
|
746
|
+
return callChain(
|
|
747
|
+
connectId,
|
|
748
|
+
deviceId,
|
|
749
|
+
"sol",
|
|
750
|
+
"solGetAddress",
|
|
751
|
+
item,
|
|
752
|
+
commonParams,
|
|
753
|
+
false,
|
|
754
|
+
installContext
|
|
755
|
+
);
|
|
756
|
+
case "tronGetAddress":
|
|
757
|
+
return callChain(
|
|
758
|
+
connectId,
|
|
759
|
+
deviceId,
|
|
760
|
+
"tron",
|
|
761
|
+
"tronGetAddress",
|
|
762
|
+
item,
|
|
763
|
+
commonParams,
|
|
764
|
+
false,
|
|
765
|
+
installContext
|
|
766
|
+
);
|
|
767
|
+
default:
|
|
768
|
+
throw Object.assign(new Error(`Unsupported allNetwork method: ${method}`), {
|
|
769
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.InvalidParams
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/utils/ledgerDmkTransport.ts
|
|
775
|
+
function isLedgerDmkBleTransport(transport) {
|
|
776
|
+
const normalized = transport?.toUpperCase();
|
|
777
|
+
return normalized === "BLE" || normalized?.endsWith("_BLE") === true;
|
|
778
|
+
}
|
|
779
|
+
function isLedgerBleConnectionType(connectionType) {
|
|
780
|
+
return connectionType === "ble";
|
|
781
|
+
}
|
|
782
|
+
function isLedgerBleDescriptor(connectionType, descriptor) {
|
|
783
|
+
return isLedgerBleConnectionType(connectionType) || isLedgerDmkBleTransport(descriptor.transport);
|
|
784
|
+
}
|
|
785
|
+
|
|
491
786
|
// src/adapter/LedgerAdapter.ts
|
|
492
787
|
function formatDeviceMismatchError(expected, actual) {
|
|
493
788
|
return `Wrong device: expected ${expected}, got ${actual}`;
|
|
@@ -503,10 +798,10 @@ function btcAccountIndexFromPath(path) {
|
|
|
503
798
|
var _LedgerAdapter = class _LedgerAdapter {
|
|
504
799
|
constructor(connector, options) {
|
|
505
800
|
this.vendor = "ledger";
|
|
506
|
-
this.emitter = new
|
|
801
|
+
this.emitter = new import_hwk_adapter_core3.TypedEventEmitter();
|
|
507
802
|
this._discoveredDevices = /* @__PURE__ */ new Map();
|
|
508
803
|
this._sessions = /* @__PURE__ */ new Map();
|
|
509
|
-
this._uiRegistry = new
|
|
804
|
+
this._uiRegistry = new import_hwk_adapter_core3.UiRequestRegistry();
|
|
510
805
|
// BTC App rejects account index >= 100 unless display=true. Cached per
|
|
511
806
|
// adapter instance: first 100+ path asks the user once via UI request,
|
|
512
807
|
// subsequent 100+ paths in the same session auto-promote silently.
|
|
@@ -515,6 +810,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
515
810
|
this._btcHighIndexConfirmedThisSession = false;
|
|
516
811
|
// Shared across concurrent callers — only `cancel()` aborts.
|
|
517
812
|
this._doConnectAbortController = null;
|
|
813
|
+
this._installProgressLastEmittedValue = -Infinity;
|
|
814
|
+
this.allNetworkGetAddress = createAllNetworkGetAddress({
|
|
815
|
+
callChain: this.callChain.bind(this),
|
|
816
|
+
getChainFingerprint: (connectId, chain) => this.getChainFingerprint(connectId, "", chain)
|
|
817
|
+
});
|
|
518
818
|
// ---------------------------------------------------------------------------
|
|
519
819
|
// Private helpers
|
|
520
820
|
// ---------------------------------------------------------------------------
|
|
@@ -534,16 +834,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
534
834
|
const deviceInfo = this.connectorDeviceToDeviceInfo(data.device);
|
|
535
835
|
this._discoveredDevices.set(deviceInfo.connectId, deviceInfo);
|
|
536
836
|
this._sessions.delete(deviceInfo.connectId);
|
|
537
|
-
this.emitter.emit(
|
|
538
|
-
type:
|
|
837
|
+
this.emitter.emit(import_hwk_adapter_core3.DEVICE.CONNECT, {
|
|
838
|
+
type: import_hwk_adapter_core3.DEVICE.CONNECT,
|
|
539
839
|
payload: deviceInfo
|
|
540
840
|
});
|
|
541
841
|
};
|
|
542
842
|
this.deviceDisconnectHandler = (data) => {
|
|
543
843
|
this._discoveredDevices.delete(data.connectId);
|
|
544
844
|
this._sessions.delete(data.connectId);
|
|
545
|
-
this.emitter.emit(
|
|
546
|
-
type:
|
|
845
|
+
this.emitter.emit(import_hwk_adapter_core3.DEVICE.DISCONNECT, {
|
|
846
|
+
type: import_hwk_adapter_core3.DEVICE.DISCONNECT,
|
|
547
847
|
payload: { connectId: data.connectId }
|
|
548
848
|
});
|
|
549
849
|
};
|
|
@@ -553,7 +853,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
553
853
|
// exists (race during teardown) we drop. All other variants pass through
|
|
554
854
|
// unchanged.
|
|
555
855
|
this.uiEventForwarder = (event) => {
|
|
556
|
-
if (event.type ===
|
|
856
|
+
if (event.type === import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress) {
|
|
557
857
|
let connectId;
|
|
558
858
|
for (const [cid, sid] of this._sessions) {
|
|
559
859
|
if (sid === event.payload.sessionId) {
|
|
@@ -568,12 +868,23 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
568
868
|
);
|
|
569
869
|
return;
|
|
570
870
|
}
|
|
871
|
+
const { appName, progress } = event.payload;
|
|
872
|
+
const key = `${connectId}:${appName}`;
|
|
873
|
+
if (this._installProgressLastKey !== key || this._installProgressLastEmittedValue >= 1) {
|
|
874
|
+
this._installProgressLastEmittedValue = -Infinity;
|
|
875
|
+
this._installProgressLastKey = key;
|
|
876
|
+
}
|
|
877
|
+
const delta = progress - this._installProgressLastEmittedValue;
|
|
878
|
+
if (delta < _LedgerAdapter.APP_INSTALL_PROGRESS_MIN_DELTA && progress < 1) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
this._installProgressLastEmittedValue = progress;
|
|
571
882
|
this.emitter.emit("ui-event", {
|
|
572
|
-
type:
|
|
883
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress,
|
|
573
884
|
payload: {
|
|
574
885
|
connectId,
|
|
575
|
-
appName
|
|
576
|
-
progress
|
|
886
|
+
appName,
|
|
887
|
+
progress
|
|
577
888
|
}
|
|
578
889
|
});
|
|
579
890
|
return;
|
|
@@ -582,7 +893,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
582
893
|
};
|
|
583
894
|
this.connector = connector;
|
|
584
895
|
this._defaultAutoInstallApp = options?.autoInstallApp ?? false;
|
|
585
|
-
this._jobQueue = new
|
|
896
|
+
this._jobQueue = new import_hwk_adapter_core3.DeviceJobQueue();
|
|
586
897
|
this.registerEventListeners();
|
|
587
898
|
}
|
|
588
899
|
// Transport
|
|
@@ -630,30 +941,42 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
630
941
|
// Device management
|
|
631
942
|
// ---------------------------------------------------------------------------
|
|
632
943
|
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));
|
|
944
|
+
debugLog("[LedgerAdapter][REQ]", { method: "searchDevices", params: options });
|
|
945
|
+
try {
|
|
946
|
+
if (options?.resetSession) {
|
|
947
|
+
this._doConnectAbortController?.abort();
|
|
948
|
+
this._sessions.clear();
|
|
949
|
+
this._connectingPromise = null;
|
|
950
|
+
this._doConnectAbortController = null;
|
|
951
|
+
this._btcHighIndexConfirmedThisSession = false;
|
|
646
952
|
}
|
|
647
|
-
}
|
|
648
|
-
if (this._discoveredDevices.size === 0) {
|
|
649
953
|
await this._ensureDevicePermission();
|
|
954
|
+
const devices = await this.connector.searchDevices();
|
|
955
|
+
this._discoveredDevices.clear();
|
|
956
|
+
for (const d of devices) {
|
|
957
|
+
if (d.connectId) {
|
|
958
|
+
this._discoveredDevices.set(d.connectId, this.connectorDeviceToDeviceInfo(d));
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
if (this._discoveredDevices.size === 0) {
|
|
962
|
+
await this._ensureDevicePermission();
|
|
963
|
+
}
|
|
964
|
+
const result = Array.from(this._discoveredDevices.values());
|
|
965
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
966
|
+
method: "searchDevices",
|
|
967
|
+
success: true,
|
|
968
|
+
payload: result
|
|
969
|
+
});
|
|
970
|
+
return result;
|
|
971
|
+
} catch (err) {
|
|
972
|
+
const e = err;
|
|
973
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
974
|
+
method: "searchDevices",
|
|
975
|
+
success: false,
|
|
976
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
977
|
+
});
|
|
978
|
+
throw err;
|
|
650
979
|
}
|
|
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
980
|
}
|
|
658
981
|
// USB single-session invariant: evict all sessions, best-effort (see connectDevice).
|
|
659
982
|
async _evictAllSessions() {
|
|
@@ -669,14 +992,15 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
669
992
|
}
|
|
670
993
|
static _createDeviceBusyError(method) {
|
|
671
994
|
return Object.assign(new Error(`Ledger device is busy while calling ${method}`), {
|
|
672
|
-
code:
|
|
995
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceBusy
|
|
673
996
|
});
|
|
674
997
|
}
|
|
675
998
|
async connectDevice(connectId) {
|
|
999
|
+
debugLog("[LedgerAdapter][REQ]", { method: "connectDevice", connectId, params: { connectId } });
|
|
676
1000
|
try {
|
|
677
1001
|
if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
|
|
678
1002
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
679
|
-
code:
|
|
1003
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
680
1004
|
});
|
|
681
1005
|
}
|
|
682
1006
|
if (!isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
@@ -688,28 +1012,79 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
688
1012
|
if (session.deviceInfo) {
|
|
689
1013
|
this._discoveredDevices.set(connectId, session.deviceInfo);
|
|
690
1014
|
}
|
|
691
|
-
|
|
1015
|
+
const result = (0, import_hwk_adapter_core3.success)(connectId);
|
|
1016
|
+
debugLog("[LedgerAdapter][RES]", { method: "connectDevice", success: true, payload: result });
|
|
1017
|
+
return result;
|
|
692
1018
|
} catch (err) {
|
|
693
|
-
|
|
1019
|
+
const failureResult = this.errorToFailure(err);
|
|
1020
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1021
|
+
method: "connectDevice",
|
|
1022
|
+
success: false,
|
|
1023
|
+
payload: failureResult
|
|
1024
|
+
});
|
|
1025
|
+
return failureResult;
|
|
694
1026
|
}
|
|
695
1027
|
}
|
|
696
1028
|
async disconnectDevice(connectId) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
1029
|
+
debugLog("[LedgerAdapter][REQ]", {
|
|
1030
|
+
method: "disconnectDevice",
|
|
1031
|
+
connectId,
|
|
1032
|
+
params: { connectId }
|
|
1033
|
+
});
|
|
1034
|
+
try {
|
|
1035
|
+
const sessionId = this._sessions.get(connectId);
|
|
1036
|
+
if (sessionId) {
|
|
1037
|
+
await this.connector.disconnect(sessionId);
|
|
1038
|
+
this._sessions.delete(connectId);
|
|
1039
|
+
}
|
|
1040
|
+
debugLog("[LedgerAdapter][RES]", { method: "disconnectDevice", success: true });
|
|
1041
|
+
} catch (err) {
|
|
1042
|
+
const e = err;
|
|
1043
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1044
|
+
method: "disconnectDevice",
|
|
1045
|
+
success: false,
|
|
1046
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
1047
|
+
});
|
|
1048
|
+
throw err;
|
|
701
1049
|
}
|
|
702
1050
|
}
|
|
703
1051
|
async getDeviceInfo(connectId, deviceId) {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1052
|
+
debugLog("[LedgerAdapter][REQ]", {
|
|
1053
|
+
method: "getDeviceInfo",
|
|
1054
|
+
connectId,
|
|
1055
|
+
params: { connectId, deviceId }
|
|
1056
|
+
});
|
|
1057
|
+
try {
|
|
1058
|
+
await this._ensureDevicePermission(connectId, deviceId);
|
|
1059
|
+
const cached = this._discoveredDevices.get(connectId) ?? Array.from(this._discoveredDevices.values()).find((d) => d.deviceId === deviceId);
|
|
1060
|
+
if (cached) {
|
|
1061
|
+
const result = (0, import_hwk_adapter_core3.success)(cached);
|
|
1062
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1063
|
+
method: "getDeviceInfo",
|
|
1064
|
+
success: true,
|
|
1065
|
+
payload: result
|
|
1066
|
+
});
|
|
1067
|
+
return result;
|
|
1068
|
+
}
|
|
1069
|
+
const notFound = (0, import_hwk_adapter_core3.failure)(
|
|
1070
|
+
import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound,
|
|
1071
|
+
"Device not found in cache. Call searchDevices() or wait for a device-connected event first."
|
|
1072
|
+
);
|
|
1073
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1074
|
+
method: "getDeviceInfo",
|
|
1075
|
+
success: false,
|
|
1076
|
+
payload: notFound
|
|
1077
|
+
});
|
|
1078
|
+
return notFound;
|
|
1079
|
+
} catch (err) {
|
|
1080
|
+
const e = err;
|
|
1081
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1082
|
+
method: "getDeviceInfo",
|
|
1083
|
+
success: false,
|
|
1084
|
+
error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
|
|
1085
|
+
});
|
|
1086
|
+
throw err;
|
|
708
1087
|
}
|
|
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
1088
|
}
|
|
714
1089
|
getSupportedChains() {
|
|
715
1090
|
return ["evm", "btc", "sol", "tron"];
|
|
@@ -717,7 +1092,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
717
1092
|
// ---------------------------------------------------------------------------
|
|
718
1093
|
// Chain call helper
|
|
719
1094
|
// ---------------------------------------------------------------------------
|
|
720
|
-
async callChain(connectId, deviceId, chain, method, params, commonParams, skipFingerprint = false) {
|
|
1095
|
+
async callChain(connectId, deviceId, chain, method, params, commonParams, skipFingerprint = false, installContext) {
|
|
721
1096
|
try {
|
|
722
1097
|
const result = await this.connectorCall(
|
|
723
1098
|
connectId,
|
|
@@ -729,9 +1104,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
729
1104
|
skipFingerprint
|
|
730
1105
|
},
|
|
731
1106
|
void 0,
|
|
732
|
-
commonParams
|
|
1107
|
+
commonParams,
|
|
1108
|
+
installContext
|
|
733
1109
|
);
|
|
734
|
-
return (0,
|
|
1110
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
735
1111
|
} catch (err) {
|
|
736
1112
|
return this.errorToFailure(err);
|
|
737
1113
|
}
|
|
@@ -916,7 +1292,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
916
1292
|
async installApp(connectId, appName) {
|
|
917
1293
|
try {
|
|
918
1294
|
await this.connectorCall(connectId, "installApp", { appName });
|
|
919
|
-
return (0,
|
|
1295
|
+
return (0, import_hwk_adapter_core3.success)(void 0);
|
|
920
1296
|
} catch (err) {
|
|
921
1297
|
return this.errorToFailure(err);
|
|
922
1298
|
}
|
|
@@ -924,7 +1300,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
924
1300
|
async listInstalledApps(connectId) {
|
|
925
1301
|
try {
|
|
926
1302
|
const result = await this.connectorCall(connectId, "listInstalledApps", {});
|
|
927
|
-
return (0,
|
|
1303
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
1304
|
+
} catch (err) {
|
|
1305
|
+
return this.errorToFailure(err);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
// Offline app-presence + unlock probe. No manager-api catalog (unlike listInstalledApps).
|
|
1309
|
+
async listInstalledNames(connectId) {
|
|
1310
|
+
try {
|
|
1311
|
+
const result = await this.connectorCall(connectId, "listInstalledNames", {});
|
|
1312
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
928
1313
|
} catch (err) {
|
|
929
1314
|
return this.errorToFailure(err);
|
|
930
1315
|
}
|
|
@@ -932,7 +1317,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
932
1317
|
async listAvailableApps(connectId) {
|
|
933
1318
|
try {
|
|
934
1319
|
const result = await this.connectorCall(connectId, "listAvailableApps", {});
|
|
935
|
-
return (0,
|
|
1320
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
936
1321
|
} catch (err) {
|
|
937
1322
|
return this.errorToFailure(err);
|
|
938
1323
|
}
|
|
@@ -940,7 +1325,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
940
1325
|
async getLedgerFirmwareVersion(connectId) {
|
|
941
1326
|
try {
|
|
942
1327
|
const result = await this.connectorCall(connectId, "getFirmwareVersion", {});
|
|
943
|
-
return (0,
|
|
1328
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
944
1329
|
} catch (err) {
|
|
945
1330
|
return this.errorToFailure(err);
|
|
946
1331
|
}
|
|
@@ -948,7 +1333,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
948
1333
|
async getLedgerDeviceInfo(connectId) {
|
|
949
1334
|
try {
|
|
950
1335
|
const result = await this.connectorCall(connectId, "getDeviceInfo", {});
|
|
951
|
-
return (0,
|
|
1336
|
+
return (0, import_hwk_adapter_core3.success)(result);
|
|
952
1337
|
} catch (err) {
|
|
953
1338
|
return this.errorToFailure(err);
|
|
954
1339
|
}
|
|
@@ -961,7 +1346,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
961
1346
|
}
|
|
962
1347
|
cancel(connectId) {
|
|
963
1348
|
const userAbortReason = Object.assign(new Error("User aborted operation"), {
|
|
964
|
-
code:
|
|
1349
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
965
1350
|
_tag: ERROR_TAG.UserAborted
|
|
966
1351
|
});
|
|
967
1352
|
this._lastCancelReason = userAbortReason;
|
|
@@ -995,7 +1380,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
995
1380
|
chain,
|
|
996
1381
|
(method, params) => this.connectorCall(connectId, method, params, void 0, deviceId)
|
|
997
1382
|
);
|
|
998
|
-
return (0,
|
|
1383
|
+
return (0, import_hwk_adapter_core3.success)(fingerprint);
|
|
999
1384
|
} catch (err) {
|
|
1000
1385
|
debugError("[LedgerAdapter] getChainFingerprint error:", chain, err);
|
|
1001
1386
|
return this.errorToFailure(err);
|
|
@@ -1018,7 +1403,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1018
1403
|
return { success: false, expected: deviceId, actual: fingerprint };
|
|
1019
1404
|
} catch (err) {
|
|
1020
1405
|
const mapped = mapLedgerError(err);
|
|
1021
|
-
if (mapped.code ===
|
|
1406
|
+
if (mapped.code === import_hwk_adapter_core3.HardwareErrorCode.WrongApp || mapped.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceLocked) {
|
|
1022
1407
|
return { success: true };
|
|
1023
1408
|
}
|
|
1024
1409
|
throw err;
|
|
@@ -1043,7 +1428,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1043
1428
|
const result = await callMethod("btcGetMasterFingerprint", {});
|
|
1044
1429
|
return result.masterFingerprint;
|
|
1045
1430
|
}
|
|
1046
|
-
const path =
|
|
1431
|
+
const path = import_hwk_adapter_core3.CHAIN_FINGERPRINT_PATHS[chain];
|
|
1047
1432
|
let address;
|
|
1048
1433
|
if (chain === "evm") {
|
|
1049
1434
|
address = (await callMethod("evmGetAddress", { path, showOnDevice: false })).address.toLowerCase();
|
|
@@ -1054,7 +1439,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1054
1439
|
} else {
|
|
1055
1440
|
throw new Error(`Unsupported chain for fingerprint: ${chain}`);
|
|
1056
1441
|
}
|
|
1057
|
-
return (0,
|
|
1442
|
+
return (0, import_hwk_adapter_core3.deriveDeviceFingerprint)(address);
|
|
1058
1443
|
}
|
|
1059
1444
|
// Ledger WebUSB won't expose a locked device, so we can't auto-detect unlock.
|
|
1060
1445
|
// The user must press Confirm after unlocking, which triggers a search retry.
|
|
@@ -1066,10 +1451,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1066
1451
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1067
1452
|
}
|
|
1068
1453
|
const waitPromise = this._uiRegistry.wait(
|
|
1069
|
-
|
|
1454
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT
|
|
1070
1455
|
);
|
|
1071
|
-
this.emitter.emit(
|
|
1072
|
-
type:
|
|
1456
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT, {
|
|
1457
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT,
|
|
1073
1458
|
payload: {
|
|
1074
1459
|
vendor: "ledger",
|
|
1075
1460
|
reason: "device-not-found",
|
|
@@ -1080,7 +1465,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1080
1465
|
try {
|
|
1081
1466
|
if (signal) {
|
|
1082
1467
|
const onAbort = () => {
|
|
1083
|
-
this._uiRegistry.cancel(
|
|
1468
|
+
this._uiRegistry.cancel(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_CONNECT);
|
|
1084
1469
|
};
|
|
1085
1470
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
1086
1471
|
try {
|
|
@@ -1092,20 +1477,20 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1092
1477
|
payload = await waitPromise;
|
|
1093
1478
|
}
|
|
1094
1479
|
} catch (err) {
|
|
1095
|
-
this.emitter.emit(
|
|
1096
|
-
type:
|
|
1480
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1481
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1097
1482
|
payload: {}
|
|
1098
1483
|
});
|
|
1099
1484
|
throw Object.assign(new Error("User cancelled Ledger connection"), {
|
|
1100
1485
|
_tag: ERROR_TAG.UserAborted,
|
|
1101
|
-
code:
|
|
1486
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1102
1487
|
cause: err
|
|
1103
1488
|
});
|
|
1104
1489
|
}
|
|
1105
1490
|
if (!payload?.confirmed) {
|
|
1106
1491
|
throw Object.assign(new Error("User cancelled Ledger connection"), {
|
|
1107
1492
|
_tag: ERROR_TAG.UserAborted,
|
|
1108
|
-
code:
|
|
1493
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted
|
|
1109
1494
|
});
|
|
1110
1495
|
}
|
|
1111
1496
|
await new Promise((resolve) => {
|
|
@@ -1135,10 +1520,10 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1135
1520
|
}
|
|
1136
1521
|
async _waitForBtcHighIndexConfirm(path, accountIndex) {
|
|
1137
1522
|
const waitPromise = this._uiRegistry.wait(
|
|
1138
|
-
|
|
1523
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM
|
|
1139
1524
|
);
|
|
1140
|
-
this.emitter.emit(
|
|
1141
|
-
type:
|
|
1525
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM, {
|
|
1526
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM,
|
|
1142
1527
|
payload: {
|
|
1143
1528
|
vendor: "ledger",
|
|
1144
1529
|
path,
|
|
@@ -1149,8 +1534,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1149
1534
|
const payload = await waitPromise;
|
|
1150
1535
|
return !!payload?.confirmed;
|
|
1151
1536
|
} catch (err) {
|
|
1152
|
-
this.emitter.emit(
|
|
1153
|
-
type:
|
|
1537
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1538
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1154
1539
|
payload: {}
|
|
1155
1540
|
});
|
|
1156
1541
|
return false;
|
|
@@ -1160,18 +1545,18 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1160
1545
|
// Same register-then-emit ordering as the BTC high-index gate.
|
|
1161
1546
|
async _waitForInstallAppConfirm(appName) {
|
|
1162
1547
|
const waitPromise = this._uiRegistry.wait(
|
|
1163
|
-
|
|
1548
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP
|
|
1164
1549
|
);
|
|
1165
|
-
this.emitter.emit(
|
|
1166
|
-
type:
|
|
1550
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP, {
|
|
1551
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_INSTALL_APP,
|
|
1167
1552
|
payload: { vendor: "ledger", appName }
|
|
1168
1553
|
});
|
|
1169
1554
|
try {
|
|
1170
1555
|
const payload = await waitPromise;
|
|
1171
1556
|
return !!payload?.confirmed;
|
|
1172
1557
|
} catch (err) {
|
|
1173
|
-
this.emitter.emit(
|
|
1174
|
-
type:
|
|
1558
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1559
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1175
1560
|
payload: {}
|
|
1176
1561
|
});
|
|
1177
1562
|
return false;
|
|
@@ -1184,7 +1569,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1184
1569
|
if (signal.aborted) _LedgerAdapter._throwIfAborted(signal);
|
|
1185
1570
|
if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
|
|
1186
1571
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
1187
|
-
code:
|
|
1572
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1188
1573
|
});
|
|
1189
1574
|
}
|
|
1190
1575
|
if (connectId && this._sessions.has(connectId)) return connectId;
|
|
@@ -1194,7 +1579,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1194
1579
|
new Error(
|
|
1195
1580
|
"Ledger USB session invariant violated: more than one session is active. Please reconnect the device."
|
|
1196
1581
|
),
|
|
1197
|
-
{ code:
|
|
1582
|
+
{ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceOneDeviceOnly }
|
|
1198
1583
|
);
|
|
1199
1584
|
}
|
|
1200
1585
|
return this._sessions.keys().next().value;
|
|
@@ -1236,7 +1621,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1236
1621
|
let confirms = 0;
|
|
1237
1622
|
while (!internalSignal.aborted) {
|
|
1238
1623
|
this.emitter.emit("ui-event", {
|
|
1239
|
-
type:
|
|
1624
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.Searching,
|
|
1240
1625
|
payload: { sessionId: "" }
|
|
1241
1626
|
});
|
|
1242
1627
|
let devices = await this.searchDevices();
|
|
@@ -1274,7 +1659,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1274
1659
|
new Error(
|
|
1275
1660
|
"Device not connected after multiple attempts. Please ensure your Ledger is awake, unlocked, and in range, then try again."
|
|
1276
1661
|
),
|
|
1277
|
-
{ code:
|
|
1662
|
+
{ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound }
|
|
1278
1663
|
);
|
|
1279
1664
|
}
|
|
1280
1665
|
await this._waitForDeviceConnect(internalSignal);
|
|
@@ -1298,7 +1683,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1298
1683
|
return this._connectDeviceOrThrow(devices[0].connectId);
|
|
1299
1684
|
}
|
|
1300
1685
|
const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
|
|
1301
|
-
code:
|
|
1686
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1302
1687
|
});
|
|
1303
1688
|
if (isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
1304
1689
|
err._tag = ERROR_TAG.DeviceNotAdvertising;
|
|
@@ -1307,7 +1692,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1307
1692
|
}
|
|
1308
1693
|
if (isLedgerBleConnectionType(this.connector.connectionType)) {
|
|
1309
1694
|
throw Object.assign(new Error("Ledger BLE connectId is required."), {
|
|
1310
|
-
code:
|
|
1695
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1311
1696
|
});
|
|
1312
1697
|
}
|
|
1313
1698
|
if (devices.length > 1) {
|
|
@@ -1315,7 +1700,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1315
1700
|
}
|
|
1316
1701
|
if (devices.length !== 1) {
|
|
1317
1702
|
throw Object.assign(new Error("Ledger device not found."), {
|
|
1318
|
-
code:
|
|
1703
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
|
|
1319
1704
|
});
|
|
1320
1705
|
}
|
|
1321
1706
|
return this._connectDeviceOrThrow(devices[0].connectId);
|
|
@@ -1353,7 +1738,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1353
1738
|
*/
|
|
1354
1739
|
_unwrapConnectorResult(result) {
|
|
1355
1740
|
if (result.success) return result.payload;
|
|
1356
|
-
throw (0,
|
|
1741
|
+
throw (0, import_hwk_adapter_core3.rehydrateConnectorError)(result.error);
|
|
1357
1742
|
}
|
|
1358
1743
|
/**
|
|
1359
1744
|
* `connector.call` + result unwrap, optionally raced against an abort
|
|
@@ -1366,26 +1751,43 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1366
1751
|
const result = signal ? await this._abortable(signal, promise) : await promise;
|
|
1367
1752
|
return this._unwrapConnectorResult(result);
|
|
1368
1753
|
}
|
|
1369
|
-
async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams) {
|
|
1370
|
-
debugLog("[LedgerAdapter]
|
|
1754
|
+
async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams, installContext) {
|
|
1755
|
+
debugLog("[LedgerAdapter][REQ]", { method, connectId: connectId || "(empty)", params });
|
|
1371
1756
|
const queueKey = connectId || "__ledger_default__";
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1757
|
+
try {
|
|
1758
|
+
const result = await this._jobQueue.enqueue(
|
|
1759
|
+
queueKey,
|
|
1760
|
+
async (signal) => this._runConnectorCall(
|
|
1761
|
+
connectId,
|
|
1762
|
+
method,
|
|
1763
|
+
params,
|
|
1764
|
+
signal,
|
|
1765
|
+
fingerprint,
|
|
1766
|
+
permissionDeviceId,
|
|
1767
|
+
commonParams,
|
|
1768
|
+
installContext
|
|
1769
|
+
),
|
|
1770
|
+
{
|
|
1771
|
+
label: method,
|
|
1772
|
+
rejectIfBusy: true,
|
|
1773
|
+
busyError: _LedgerAdapter._createDeviceBusyError(method)
|
|
1774
|
+
}
|
|
1775
|
+
);
|
|
1776
|
+
debugLog("[LedgerAdapter][RES]", { method, success: true, payload: result });
|
|
1777
|
+
return result;
|
|
1778
|
+
} catch (err) {
|
|
1779
|
+
const e = err;
|
|
1780
|
+
debugLog("[LedgerAdapter][RES]", {
|
|
1376
1781
|
method,
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
busyError: _LedgerAdapter._createDeviceBusyError(method)
|
|
1387
|
-
}
|
|
1388
|
-
);
|
|
1782
|
+
success: false,
|
|
1783
|
+
error: {
|
|
1784
|
+
message: e?.message,
|
|
1785
|
+
_tag: e?._tag,
|
|
1786
|
+
code: e?.code ?? e?.errorCode
|
|
1787
|
+
}
|
|
1788
|
+
});
|
|
1789
|
+
throw err;
|
|
1790
|
+
}
|
|
1389
1791
|
}
|
|
1390
1792
|
/**
|
|
1391
1793
|
* Race a promise against an abort signal. On abort, rejects with
|
|
@@ -1420,7 +1822,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1420
1822
|
}
|
|
1421
1823
|
}
|
|
1422
1824
|
/** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
|
|
1423
|
-
async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams) {
|
|
1825
|
+
async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext) {
|
|
1424
1826
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1425
1827
|
await this._ensureDevicePermission(
|
|
1426
1828
|
connectId,
|
|
@@ -1434,7 +1836,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1434
1836
|
if (gatedParams === null) {
|
|
1435
1837
|
throw Object.assign(new Error("User cancelled BTC high-index confirmation"), {
|
|
1436
1838
|
_tag: ERROR_TAG.UserAborted,
|
|
1437
|
-
code:
|
|
1839
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted
|
|
1438
1840
|
});
|
|
1439
1841
|
}
|
|
1440
1842
|
effectiveParams = gatedParams;
|
|
@@ -1463,7 +1865,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1463
1865
|
);
|
|
1464
1866
|
if (!fp.success) {
|
|
1465
1867
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1466
|
-
code:
|
|
1868
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1467
1869
|
});
|
|
1468
1870
|
}
|
|
1469
1871
|
}
|
|
@@ -1482,22 +1884,62 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1482
1884
|
isStuckApp: isStuckAppStateError(err)
|
|
1483
1885
|
});
|
|
1484
1886
|
const autoInstallApp = commonParams?.autoInstallApp ?? this._defaultAutoInstallApp;
|
|
1485
|
-
const isAppMissing = isAppNotInstalledError(err) || err?.code ===
|
|
1887
|
+
const isAppMissing = isAppNotInstalledError(err) || err?.code === import_hwk_adapter_core3.HardwareErrorCode.AppNotInstalled;
|
|
1486
1888
|
if (autoInstallApp && isAppMissing) {
|
|
1889
|
+
if (installContext?.deviceOutOfMemoryError) {
|
|
1890
|
+
throw installContext.deviceOutOfMemoryError;
|
|
1891
|
+
}
|
|
1487
1892
|
const appName = err?.appName ?? mapLedgerError(err).appName;
|
|
1488
1893
|
if (appName) {
|
|
1894
|
+
if (installContext?.installAttemptedAppNames?.has(appName)) {
|
|
1895
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1896
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.AppNotInstalled,
|
|
1897
|
+
message: `${appName} install reported success but the app is still missing on device`,
|
|
1898
|
+
_tag: ERROR_TAG.AppInstallVerifyFailed,
|
|
1899
|
+
appName
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1489
1902
|
const confirmed = await this._waitForInstallAppConfirm(appName);
|
|
1490
|
-
if (!confirmed)
|
|
1903
|
+
if (!confirmed) {
|
|
1904
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1905
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1906
|
+
message: `User declined to install ${appName}`,
|
|
1907
|
+
_tag: ERROR_TAG.UserAborted,
|
|
1908
|
+
appName
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1491
1911
|
this.emitter.emit("ui-event", {
|
|
1492
|
-
type:
|
|
1912
|
+
type: import_hwk_adapter_core3.EConnectorInteraction.AppInstallProgress,
|
|
1493
1913
|
payload: { connectId: resolvedConnectId, appName, progress: 0 }
|
|
1494
1914
|
});
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1915
|
+
try {
|
|
1916
|
+
await this._callConnector(sessionId, "installApp", { appName }, signal);
|
|
1917
|
+
} catch (installErr) {
|
|
1918
|
+
if (mapLedgerError(installErr).code === import_hwk_adapter_core3.HardwareErrorCode.DeviceOutOfMemory) {
|
|
1919
|
+
if (installContext) {
|
|
1920
|
+
installContext.deviceOutOfMemoryError = installErr;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
throw installErr;
|
|
1924
|
+
}
|
|
1925
|
+
if (installContext) {
|
|
1926
|
+
installContext.installAttemptedAppNames = installContext.installAttemptedAppNames ?? /* @__PURE__ */ new Set();
|
|
1927
|
+
installContext.installAttemptedAppNames.add(appName);
|
|
1928
|
+
}
|
|
1929
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
1930
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1498
1931
|
payload: {}
|
|
1499
1932
|
});
|
|
1500
|
-
return await this.
|
|
1933
|
+
return await this._runConnectorCall(
|
|
1934
|
+
resolvedConnectId,
|
|
1935
|
+
method,
|
|
1936
|
+
effectiveParams,
|
|
1937
|
+
signal,
|
|
1938
|
+
fingerprint,
|
|
1939
|
+
permissionDeviceId,
|
|
1940
|
+
commonParams,
|
|
1941
|
+
installContext
|
|
1942
|
+
);
|
|
1501
1943
|
}
|
|
1502
1944
|
}
|
|
1503
1945
|
if (isStuckAppStateError(err)) {
|
|
@@ -1572,7 +2014,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1572
2014
|
);
|
|
1573
2015
|
if (!fp.success) {
|
|
1574
2016
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1575
|
-
code:
|
|
2017
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1576
2018
|
});
|
|
1577
2019
|
}
|
|
1578
2020
|
}
|
|
@@ -1607,7 +2049,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1607
2049
|
this.connector.reset();
|
|
1608
2050
|
const codeNum = err?.code;
|
|
1609
2051
|
throw Object.assign(err, {
|
|
1610
|
-
code: codeNum ??
|
|
2052
|
+
code: codeNum ?? import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected
|
|
1611
2053
|
});
|
|
1612
2054
|
}
|
|
1613
2055
|
throw err;
|
|
@@ -1641,7 +2083,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1641
2083
|
);
|
|
1642
2084
|
if (!fp.success) {
|
|
1643
2085
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1644
|
-
code:
|
|
2086
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1645
2087
|
});
|
|
1646
2088
|
}
|
|
1647
2089
|
}
|
|
@@ -1698,7 +2140,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1698
2140
|
);
|
|
1699
2141
|
if (!fp.success) {
|
|
1700
2142
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1701
|
-
code:
|
|
2143
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1702
2144
|
});
|
|
1703
2145
|
}
|
|
1704
2146
|
}
|
|
@@ -1739,7 +2181,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1739
2181
|
);
|
|
1740
2182
|
if (!fp.success) {
|
|
1741
2183
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
1742
|
-
code:
|
|
2184
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
1743
2185
|
});
|
|
1744
2186
|
}
|
|
1745
2187
|
}
|
|
@@ -1764,16 +2206,16 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1764
2206
|
}
|
|
1765
2207
|
const transportType = this.activeTransport ?? "hid";
|
|
1766
2208
|
const waitPromise = this._uiRegistry.wait(
|
|
1767
|
-
|
|
2209
|
+
import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1768
2210
|
{ timeoutMs: 6e4 }
|
|
1769
2211
|
);
|
|
1770
|
-
this.emitter.emit(
|
|
1771
|
-
type:
|
|
2212
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION, {
|
|
2213
|
+
type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1772
2214
|
payload: { transportType, connectId, deviceId }
|
|
1773
2215
|
});
|
|
1774
2216
|
let response;
|
|
1775
2217
|
const onAbort = () => {
|
|
1776
|
-
this._uiRegistry.cancel(
|
|
2218
|
+
this._uiRegistry.cancel(import_hwk_adapter_core3.UI_REQUEST.REQUEST_DEVICE_PERMISSION);
|
|
1777
2219
|
};
|
|
1778
2220
|
try {
|
|
1779
2221
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -1782,14 +2224,14 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1782
2224
|
if (signal?.aborted) {
|
|
1783
2225
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1784
2226
|
}
|
|
1785
|
-
if (err?._tag ===
|
|
1786
|
-
this.emitter.emit(
|
|
1787
|
-
type:
|
|
2227
|
+
if (err?._tag === import_hwk_adapter_core3.UI_REQUEST_PREEMPTED_TAG) {
|
|
2228
|
+
this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW, {
|
|
2229
|
+
type: import_hwk_adapter_core3.UI_REQUEST.CLOSE_UI_WINDOW,
|
|
1788
2230
|
payload: {}
|
|
1789
2231
|
});
|
|
1790
2232
|
throw Object.assign(new Error("Device permission request superseded"), {
|
|
1791
2233
|
_tag: ERROR_TAG.UserAborted,
|
|
1792
|
-
code:
|
|
2234
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
|
|
1793
2235
|
cause: err
|
|
1794
2236
|
});
|
|
1795
2237
|
}
|
|
@@ -1800,7 +2242,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1800
2242
|
const { granted, reason, message } = response;
|
|
1801
2243
|
if (!granted) {
|
|
1802
2244
|
throw Object.assign(new Error(message ?? "Device permission denied"), {
|
|
1803
|
-
code:
|
|
2245
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DevicePermissionDenied,
|
|
1804
2246
|
reason
|
|
1805
2247
|
});
|
|
1806
2248
|
}
|
|
@@ -1814,7 +2256,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1814
2256
|
const tag = err && typeof err === "object" ? err._tag : void 0;
|
|
1815
2257
|
if (err && typeof err === "object" && "code" in err && typeof err.code === "number") {
|
|
1816
2258
|
const e = err;
|
|
1817
|
-
const params = e.code ===
|
|
2259
|
+
const params = e.code === import_hwk_adapter_core3.HardwareErrorCode.DevicePermissionDenied && e.reason ? { permissionDeniedReason: e.reason } : e.params;
|
|
1818
2260
|
return ledgerFailure(e.code, e.message ?? "Unknown error", e.appName, tag, params);
|
|
1819
2261
|
}
|
|
1820
2262
|
const mapped = mapLedgerError(err);
|
|
@@ -1861,10 +2303,13 @@ _LedgerAdapter.STUCK_APP_RETRY_DELAY_MS = 500;
|
|
|
1861
2303
|
// Confirm but device never shows up / never unlocks), throw DeviceNotFound
|
|
1862
2304
|
// instead of looping forever.
|
|
1863
2305
|
_LedgerAdapter.MAX_DOCONNECT_CONFIRMS = 3;
|
|
2306
|
+
// Throttle AppInstallProgress by progress delta — DMK streams much faster
|
|
2307
|
+
// than UIs need. Final frame (progress >= 1) always passes.
|
|
2308
|
+
_LedgerAdapter.APP_INSTALL_PROGRESS_MIN_DELTA = 0.05;
|
|
1864
2309
|
var LedgerAdapter = _LedgerAdapter;
|
|
1865
2310
|
|
|
1866
2311
|
// src/connector/LedgerConnectorBase.ts
|
|
1867
|
-
var
|
|
2312
|
+
var import_hwk_adapter_core13 = require("@onekeyfe/hwk-adapter-core");
|
|
1868
2313
|
|
|
1869
2314
|
// src/device/LedgerDeviceManager.ts
|
|
1870
2315
|
var LedgerDeviceManager = class {
|
|
@@ -2137,7 +2582,7 @@ var import_device_signer_kit_ethereum = require("@ledgerhq/device-signer-kit-eth
|
|
|
2137
2582
|
var import_context_module = require("@ledgerhq/context-module");
|
|
2138
2583
|
|
|
2139
2584
|
// src/signer/SignerEth.ts
|
|
2140
|
-
var
|
|
2585
|
+
var import_hwk_adapter_core4 = require("@onekeyfe/hwk-adapter-core");
|
|
2141
2586
|
|
|
2142
2587
|
// src/signer/deviceActionToPromise.ts
|
|
2143
2588
|
var import_device_management_kit = require("@ledgerhq/device-management-kit");
|
|
@@ -2350,7 +2795,7 @@ var SignerEth = class {
|
|
|
2350
2795
|
);
|
|
2351
2796
|
}
|
|
2352
2797
|
async signTransaction(derivationPath, serializedTxHex) {
|
|
2353
|
-
const action = this._sdk.signTransaction(derivationPath, (0,
|
|
2798
|
+
const action = this._sdk.signTransaction(derivationPath, (0, import_hwk_adapter_core4.hexToBytes)(serializedTxHex));
|
|
2354
2799
|
return deviceActionToPromise(
|
|
2355
2800
|
action,
|
|
2356
2801
|
this.onInteraction,
|
|
@@ -2359,7 +2804,7 @@ var SignerEth = class {
|
|
|
2359
2804
|
);
|
|
2360
2805
|
}
|
|
2361
2806
|
async signMessage(derivationPath, message) {
|
|
2362
|
-
const action = this._sdk.signMessage(derivationPath, (0,
|
|
2807
|
+
const action = this._sdk.signMessage(derivationPath, (0, import_hwk_adapter_core4.hexToBytes)(message));
|
|
2363
2808
|
return deviceActionToPromise(
|
|
2364
2809
|
action,
|
|
2365
2810
|
this.onInteraction,
|
|
@@ -2419,23 +2864,23 @@ var SignerManager = class _SignerManager {
|
|
|
2419
2864
|
};
|
|
2420
2865
|
|
|
2421
2866
|
// src/connector/chains/evm.ts
|
|
2422
|
-
var
|
|
2867
|
+
var import_hwk_adapter_core6 = require("@onekeyfe/hwk-adapter-core");
|
|
2423
2868
|
|
|
2424
2869
|
// src/connector/chains/utils.ts
|
|
2425
|
-
var
|
|
2870
|
+
var import_hwk_adapter_core5 = require("@onekeyfe/hwk-adapter-core");
|
|
2426
2871
|
function normalizePath(path) {
|
|
2427
2872
|
return path.startsWith("m/") ? path.slice(2) : path;
|
|
2428
2873
|
}
|
|
2429
2874
|
function collapseSignerInteraction(interaction) {
|
|
2430
2875
|
switch (interaction) {
|
|
2431
2876
|
case "confirm-open-app":
|
|
2432
|
-
return
|
|
2877
|
+
return import_hwk_adapter_core5.EConnectorInteraction.ConfirmOpenApp;
|
|
2433
2878
|
case "unlock-device":
|
|
2434
|
-
return
|
|
2879
|
+
return import_hwk_adapter_core5.EConnectorInteraction.UnlockDevice;
|
|
2435
2880
|
case "interaction-complete":
|
|
2436
|
-
return
|
|
2881
|
+
return import_hwk_adapter_core5.EConnectorInteraction.InteractionComplete;
|
|
2437
2882
|
default:
|
|
2438
|
-
return
|
|
2883
|
+
return import_hwk_adapter_core5.EConnectorInteraction.ConfirmOnDevice;
|
|
2439
2884
|
}
|
|
2440
2885
|
}
|
|
2441
2886
|
|
|
@@ -2461,7 +2906,7 @@ async function evmSignTransaction(ctx, sessionId, params) {
|
|
|
2461
2906
|
new Error(
|
|
2462
2907
|
"Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string."
|
|
2463
2908
|
),
|
|
2464
|
-
{ code:
|
|
2909
|
+
{ code: import_hwk_adapter_core6.HardwareErrorCode.InvalidParams }
|
|
2465
2910
|
);
|
|
2466
2911
|
}
|
|
2467
2912
|
const signer = await _getEthSigner(ctx, sessionId);
|
|
@@ -2470,8 +2915,8 @@ async function evmSignTransaction(ctx, sessionId, params) {
|
|
|
2470
2915
|
const result = await signer.signTransaction(path, params.serializedTx);
|
|
2471
2916
|
return {
|
|
2472
2917
|
v: `0x${result.v.toString(16)}`,
|
|
2473
|
-
r: (0,
|
|
2474
|
-
s: (0,
|
|
2918
|
+
r: (0, import_hwk_adapter_core6.padHex64)(result.r),
|
|
2919
|
+
s: (0, import_hwk_adapter_core6.padHex64)(result.s)
|
|
2475
2920
|
};
|
|
2476
2921
|
} catch (err) {
|
|
2477
2922
|
ctx.invalidateSession(sessionId);
|
|
@@ -2485,8 +2930,8 @@ async function evmSignMessage(ctx, sessionId, params) {
|
|
|
2485
2930
|
const path = normalizePath(params.path);
|
|
2486
2931
|
try {
|
|
2487
2932
|
const result = await signer.signMessage(path, params.message);
|
|
2488
|
-
const rHex = (0,
|
|
2489
|
-
const sHex = (0,
|
|
2933
|
+
const rHex = (0, import_hwk_adapter_core6.stripHex)(result.r).padStart(64, "0");
|
|
2934
|
+
const sHex = (0, import_hwk_adapter_core6.stripHex)(result.s).padStart(64, "0");
|
|
2490
2935
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2491
2936
|
return { signature: `0x${rHex}${sHex}${vHex}` };
|
|
2492
2937
|
} catch (err) {
|
|
@@ -2502,15 +2947,15 @@ async function evmSignTypedData(ctx, sessionId, params) {
|
|
|
2502
2947
|
new Error(
|
|
2503
2948
|
'Ledger does not support hash-only EIP-712 signing. Use mode "full" with the complete typed data structure.'
|
|
2504
2949
|
),
|
|
2505
|
-
{ code:
|
|
2950
|
+
{ code: import_hwk_adapter_core6.HardwareErrorCode.MethodNotSupported }
|
|
2506
2951
|
);
|
|
2507
2952
|
}
|
|
2508
2953
|
const signer = await _getEthSigner(ctx, sessionId);
|
|
2509
2954
|
const path = normalizePath(params.path);
|
|
2510
2955
|
try {
|
|
2511
2956
|
const result = await signer.signTypedData(path, params.data);
|
|
2512
|
-
const rHex = (0,
|
|
2513
|
-
const sHex = (0,
|
|
2957
|
+
const rHex = (0, import_hwk_adapter_core6.stripHex)(result.r).padStart(64, "0");
|
|
2958
|
+
const sHex = (0, import_hwk_adapter_core6.stripHex)(result.s).padStart(64, "0");
|
|
2514
2959
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2515
2960
|
return { signature: `0x${rHex}${sHex}${vHex}` };
|
|
2516
2961
|
} catch (err) {
|
|
@@ -2537,13 +2982,13 @@ async function _getEthSigner(ctx, sessionId) {
|
|
|
2537
2982
|
}
|
|
2538
2983
|
|
|
2539
2984
|
// src/connector/chains/btc.ts
|
|
2540
|
-
var
|
|
2985
|
+
var import_hwk_adapter_core8 = require("@onekeyfe/hwk-adapter-core");
|
|
2541
2986
|
var import_bitcoinjs_lib = require("bitcoinjs-lib");
|
|
2542
2987
|
|
|
2543
2988
|
// src/signer/SignerBtc.ts
|
|
2544
|
-
var
|
|
2989
|
+
var import_hwk_adapter_core7 = require("@onekeyfe/hwk-adapter-core");
|
|
2545
2990
|
function hexToUtf8(hex) {
|
|
2546
|
-
return new TextDecoder().decode((0,
|
|
2991
|
+
return new TextDecoder().decode((0, import_hwk_adapter_core7.hexToBytes)(hex));
|
|
2547
2992
|
}
|
|
2548
2993
|
var INTERACTIVE_TIMEOUT_MS2 = 5 * 6e4;
|
|
2549
2994
|
var SignerBtc = class {
|
|
@@ -2658,7 +3103,7 @@ function _purposeToTemplate(purpose, DDT) {
|
|
|
2658
3103
|
return DDT.TAPROOT;
|
|
2659
3104
|
default:
|
|
2660
3105
|
throw Object.assign(new Error(`Unsupported BTC purpose: m/${purpose ?? "<undefined>"}'`), {
|
|
2661
|
-
code:
|
|
3106
|
+
code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams
|
|
2662
3107
|
});
|
|
2663
3108
|
}
|
|
2664
3109
|
}
|
|
@@ -2714,7 +3159,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2714
3159
|
if (!params.psbt) {
|
|
2715
3160
|
throw Object.assign(
|
|
2716
3161
|
new Error("Ledger requires PSBT format for BTC transaction signing. Provide params.psbt."),
|
|
2717
|
-
{ code:
|
|
3162
|
+
{ code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams }
|
|
2718
3163
|
);
|
|
2719
3164
|
}
|
|
2720
3165
|
const btcSigner = await _createBtcSigner(ctx, sessionId);
|
|
@@ -2728,7 +3173,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2728
3173
|
debugLog("[LedgerConnector] btcSignTransaction wallet:", { path, purpose, template });
|
|
2729
3174
|
const wallet = new DefaultWallet(path, template);
|
|
2730
3175
|
const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt);
|
|
2731
|
-
return { serializedTx: (0,
|
|
3176
|
+
return { serializedTx: (0, import_hwk_adapter_core8.stripHex)(signedTxHex) };
|
|
2732
3177
|
} catch (err) {
|
|
2733
3178
|
ctx.invalidateSession(sessionId);
|
|
2734
3179
|
throw ctx.wrapError(err);
|
|
@@ -2739,7 +3184,7 @@ async function btcSignTransaction(ctx, sessionId, params) {
|
|
|
2739
3184
|
async function btcSignPsbt(ctx, sessionId, params) {
|
|
2740
3185
|
if (!params.psbt) {
|
|
2741
3186
|
throw Object.assign(new Error("btcSignPsbt requires params.psbt"), {
|
|
2742
|
-
code:
|
|
3187
|
+
code: import_hwk_adapter_core8.HardwareErrorCode.InvalidParams
|
|
2743
3188
|
});
|
|
2744
3189
|
}
|
|
2745
3190
|
const btcSigner = await _createBtcSigner(ctx, sessionId);
|
|
@@ -2769,8 +3214,8 @@ async function btcSignMessage(ctx, sessionId, params) {
|
|
|
2769
3214
|
try {
|
|
2770
3215
|
const result = await btcSigner.signMessage(path, params.message);
|
|
2771
3216
|
const vHex = result.v.toString(16).padStart(2, "0");
|
|
2772
|
-
const rHex = (0,
|
|
2773
|
-
const sHex = (0,
|
|
3217
|
+
const rHex = (0, import_hwk_adapter_core8.stripHex)(result.r).padStart(64, "0");
|
|
3218
|
+
const sHex = (0, import_hwk_adapter_core8.stripHex)(result.s).padStart(64, "0");
|
|
2774
3219
|
return { signature: `${vHex}${rHex}${sHex}` };
|
|
2775
3220
|
} catch (err) {
|
|
2776
3221
|
ctx.invalidateSession(sessionId);
|
|
@@ -2870,7 +3315,7 @@ function _applySignaturesToPsbt(psbtHex, signatures) {
|
|
|
2870
3315
|
}
|
|
2871
3316
|
|
|
2872
3317
|
// src/connector/chains/sol.ts
|
|
2873
|
-
var
|
|
3318
|
+
var import_hwk_adapter_core9 = require("@onekeyfe/hwk-adapter-core");
|
|
2874
3319
|
|
|
2875
3320
|
// src/signer/SignerSol.ts
|
|
2876
3321
|
var SignerSol = class {
|
|
@@ -2938,10 +3383,10 @@ async function solGetAddress(ctx, sessionId, params) {
|
|
|
2938
3383
|
async function solSignTransaction(ctx, sessionId, params) {
|
|
2939
3384
|
const solSigner = await _createSolSigner(ctx, sessionId);
|
|
2940
3385
|
const path = normalizePath(params.path);
|
|
2941
|
-
const txBytes = (0,
|
|
3386
|
+
const txBytes = (0, import_hwk_adapter_core9.hexToBytes)(params.serializedTx);
|
|
2942
3387
|
try {
|
|
2943
3388
|
const result = await solSigner.signTransaction(path, txBytes);
|
|
2944
|
-
return { signature: (0,
|
|
3389
|
+
return { signature: (0, import_hwk_adapter_core9.bytesToHex)(result) };
|
|
2945
3390
|
} catch (err) {
|
|
2946
3391
|
ctx.invalidateSession(sessionId);
|
|
2947
3392
|
throw ctx.wrapError(err);
|
|
@@ -2952,7 +3397,7 @@ async function solSignTransaction(ctx, sessionId, params) {
|
|
|
2952
3397
|
async function solSignMessage(ctx, sessionId, params) {
|
|
2953
3398
|
const solSigner = await _createSolSigner(ctx, sessionId);
|
|
2954
3399
|
const path = normalizePath(params.path);
|
|
2955
|
-
const messageBytes = (0,
|
|
3400
|
+
const messageBytes = (0, import_hwk_adapter_core9.hexToBytes)(params.message);
|
|
2956
3401
|
try {
|
|
2957
3402
|
const result = await solSigner.signMessage(path, messageBytes);
|
|
2958
3403
|
return { signature: result.signature };
|
|
@@ -2984,15 +3429,15 @@ async function _createSolSigner(ctx, sessionId) {
|
|
|
2984
3429
|
}
|
|
2985
3430
|
|
|
2986
3431
|
// src/connector/chains/tron.ts
|
|
2987
|
-
var
|
|
3432
|
+
var import_hwk_adapter_core12 = require("@onekeyfe/hwk-adapter-core");
|
|
2988
3433
|
var import_hw_app_trx = __toESM(require("@ledgerhq/hw-app-trx"));
|
|
2989
3434
|
|
|
2990
3435
|
// src/connector/chains/legacyChainCall.ts
|
|
2991
|
-
var
|
|
3436
|
+
var import_hwk_adapter_core11 = require("@onekeyfe/hwk-adapter-core");
|
|
2992
3437
|
|
|
2993
3438
|
// src/app/AppManager.ts
|
|
2994
3439
|
var import_device_management_kit2 = require("@ledgerhq/device-management-kit");
|
|
2995
|
-
var
|
|
3440
|
+
var import_hwk_adapter_core10 = require("@onekeyfe/hwk-adapter-core");
|
|
2996
3441
|
var APP_NAME_MAP = {
|
|
2997
3442
|
ETH: "Ethereum",
|
|
2998
3443
|
BTC: "Bitcoin",
|
|
@@ -3096,15 +3541,30 @@ var AppManager = class {
|
|
|
3096
3541
|
command: new import_device_management_kit2.OpenAppCommand({ appName })
|
|
3097
3542
|
});
|
|
3098
3543
|
if (!(0, import_device_management_kit2.isSuccessCommandResult)(result)) {
|
|
3099
|
-
const
|
|
3100
|
-
const
|
|
3101
|
-
|
|
3544
|
+
const dmkErr = result.error;
|
|
3545
|
+
const errorCode = "errorCode" in dmkErr && dmkErr.errorCode != null ? String(dmkErr.errorCode) : "";
|
|
3546
|
+
const message = "message" in dmkErr && typeof dmkErr.message === "string" ? dmkErr.message : "";
|
|
3547
|
+
debugLog(
|
|
3548
|
+
"[AppManager] openApp failed:",
|
|
3549
|
+
appName,
|
|
3550
|
+
"errorCode:",
|
|
3551
|
+
errorCode,
|
|
3552
|
+
"tag:",
|
|
3553
|
+
dmkErr._tag
|
|
3554
|
+
);
|
|
3555
|
+
let code;
|
|
3556
|
+
if (errorCode === "6807" || /unknown application/i.test(message)) {
|
|
3557
|
+
code = import_hwk_adapter_core10.HardwareErrorCode.AppNotInstalled;
|
|
3558
|
+
} else if (errorCode === "5501" || dmkErr._tag === "ActionRefusedError") {
|
|
3559
|
+
code = import_hwk_adapter_core10.HardwareErrorCode.UserRejected;
|
|
3560
|
+
}
|
|
3102
3561
|
throw Object.assign(new Error(`Failed to open "${appName}"`), {
|
|
3103
3562
|
_tag: ERROR_TAG.OpenAppCommand,
|
|
3104
|
-
code
|
|
3105
|
-
errorCode
|
|
3106
|
-
statusCode,
|
|
3107
|
-
appName
|
|
3563
|
+
code,
|
|
3564
|
+
errorCode,
|
|
3565
|
+
statusCode: errorCode,
|
|
3566
|
+
appName,
|
|
3567
|
+
originalError: dmkErr
|
|
3108
3568
|
});
|
|
3109
3569
|
}
|
|
3110
3570
|
}
|
|
@@ -3157,14 +3617,14 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3157
3617
|
const onAppOpenPrompt = () => {
|
|
3158
3618
|
openAppPromptShown = true;
|
|
3159
3619
|
ctx.emit("ui-event", {
|
|
3160
|
-
type:
|
|
3620
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOpenApp,
|
|
3161
3621
|
payload: { sessionId }
|
|
3162
3622
|
});
|
|
3163
3623
|
};
|
|
3164
3624
|
const closeOpenAppUiIfShown = () => {
|
|
3165
3625
|
if (openAppPromptShown) {
|
|
3166
3626
|
ctx.emit("ui-event", {
|
|
3167
|
-
type:
|
|
3627
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
|
|
3168
3628
|
payload: { sessionId }
|
|
3169
3629
|
});
|
|
3170
3630
|
openAppPromptShown = false;
|
|
@@ -3185,7 +3645,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3185
3645
|
let confirmEmitted = false;
|
|
3186
3646
|
if (needsConfirmation) {
|
|
3187
3647
|
ctx.emit("ui-event", {
|
|
3188
|
-
type:
|
|
3648
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOnDevice,
|
|
3189
3649
|
payload: { sessionId }
|
|
3190
3650
|
});
|
|
3191
3651
|
confirmEmitted = true;
|
|
@@ -3195,7 +3655,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
|
|
|
3195
3655
|
} finally {
|
|
3196
3656
|
if (confirmEmitted || openAppPromptShown) {
|
|
3197
3657
|
ctx.emit("ui-event", {
|
|
3198
|
-
type:
|
|
3658
|
+
type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
|
|
3199
3659
|
payload: { sessionId }
|
|
3200
3660
|
});
|
|
3201
3661
|
openAppPromptShown = false;
|
|
@@ -3283,7 +3743,7 @@ async function tronSignTransaction(ctx, sessionId, params) {
|
|
|
3283
3743
|
if (!params.rawTxHex) {
|
|
3284
3744
|
throw Object.assign(
|
|
3285
3745
|
new Error("TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex)."),
|
|
3286
|
-
{ code:
|
|
3746
|
+
{ code: import_hwk_adapter_core12.HardwareErrorCode.InvalidParams }
|
|
3287
3747
|
);
|
|
3288
3748
|
}
|
|
3289
3749
|
const path = normalizePath(params.path);
|
|
@@ -3444,6 +3904,22 @@ var DeviceApps = class {
|
|
|
3444
3904
|
);
|
|
3445
3905
|
return result.filter((a) => a !== null).map(applicationToMetadata);
|
|
3446
3906
|
}
|
|
3907
|
+
/** Installed app names via ListApps APDU. Offline (no manager-api), but still requires unlock + dashboard. */
|
|
3908
|
+
async listInstalledNames(options) {
|
|
3909
|
+
const action = this._dmk.executeDeviceAction({
|
|
3910
|
+
sessionId: this._sessionId,
|
|
3911
|
+
deviceAction: new this._ledgerKit.ListAppsDeviceAction({
|
|
3912
|
+
input: { unlockTimeout: options?.unlockTimeout }
|
|
3913
|
+
})
|
|
3914
|
+
});
|
|
3915
|
+
const result = await deviceActionToPromise(
|
|
3916
|
+
action,
|
|
3917
|
+
this.onInteraction,
|
|
3918
|
+
void 0,
|
|
3919
|
+
this.onRegisterCanceller
|
|
3920
|
+
);
|
|
3921
|
+
return result.map((entry) => entry?.appName).filter((name) => typeof name === "string" && name.length > 0);
|
|
3922
|
+
}
|
|
3447
3923
|
// Catalog lookup via custom device action — DMK has no typed wrapper for this.
|
|
3448
3924
|
async listAvailable() {
|
|
3449
3925
|
const customAction = new ListAvailableAppsDeviceAction({
|
|
@@ -3507,6 +3983,22 @@ var DeviceApps = class {
|
|
|
3507
3983
|
async install(appName, onProgress, options) {
|
|
3508
3984
|
if (!appName) throw new Error("DeviceApps.install: appName is required");
|
|
3509
3985
|
debugLog("[DeviceApps] install:", appName);
|
|
3986
|
+
const refreshAction = this._dmk.executeDeviceAction({
|
|
3987
|
+
sessionId: this._sessionId,
|
|
3988
|
+
deviceAction: new this._ledgerKit.GetDeviceMetadataDeviceAction({
|
|
3989
|
+
input: {
|
|
3990
|
+
useSecureChannel: true,
|
|
3991
|
+
forceUpdate: true,
|
|
3992
|
+
unlockTimeout: options?.unlockTimeout
|
|
3993
|
+
}
|
|
3994
|
+
})
|
|
3995
|
+
});
|
|
3996
|
+
await deviceActionToPromise(
|
|
3997
|
+
refreshAction,
|
|
3998
|
+
this.onInteraction,
|
|
3999
|
+
INSTALL_TIMEOUT_MS,
|
|
4000
|
+
this.onRegisterCanceller
|
|
4001
|
+
);
|
|
3510
4002
|
const action = this._dmk.executeDeviceAction({
|
|
3511
4003
|
sessionId: this._sessionId,
|
|
3512
4004
|
deviceAction: new this._ledgerKit.InstallOrUpdateAppsDeviceAction({
|
|
@@ -3584,7 +4076,7 @@ var METHOD_PREFIX_TO_APP_NAME = {
|
|
|
3584
4076
|
tron: "Tron"
|
|
3585
4077
|
};
|
|
3586
4078
|
var HARDWARE_ERROR_CODE_VALUES = new Set(
|
|
3587
|
-
Object.values(
|
|
4079
|
+
Object.values(import_hwk_adapter_core13.HardwareErrorCode).filter((value) => typeof value === "number")
|
|
3588
4080
|
);
|
|
3589
4081
|
var BLE_CONNECT_SCAN_TIMEOUT_MS = 1500;
|
|
3590
4082
|
async function defaultLedgerKitImporter(pkg) {
|
|
@@ -3755,7 +4247,7 @@ var LedgerConnectorBase = class {
|
|
|
3755
4247
|
`Ledger BLE connect did not return within ${HANG_CEILING_MS / 6e4}min \u2014 DMK hang fallback.`
|
|
3756
4248
|
);
|
|
3757
4249
|
err._tag = ERROR_TAG.BlePairingTimeout;
|
|
3758
|
-
err.code =
|
|
4250
|
+
err.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
|
|
3759
4251
|
reject(err);
|
|
3760
4252
|
}, HANG_CEILING_MS);
|
|
3761
4253
|
});
|
|
@@ -3788,7 +4280,7 @@ var LedgerConnectorBase = class {
|
|
|
3788
4280
|
"Ledger device is not currently advertising. Wake up and unlock the device, keep it nearby, then try again."
|
|
3789
4281
|
);
|
|
3790
4282
|
err._tag = ERROR_TAG.DeviceNotAdvertising;
|
|
3791
|
-
err.code =
|
|
4283
|
+
err.code = import_hwk_adapter_core13.HardwareErrorCode.DeviceNotFound;
|
|
3792
4284
|
throw err;
|
|
3793
4285
|
};
|
|
3794
4286
|
const doConnect = async (path) => {
|
|
@@ -3852,7 +4344,7 @@ var LedgerConnectorBase = class {
|
|
|
3852
4344
|
"Ledger Bluetooth pairing failed. Make sure the device is unlocked and nearby, then try again."
|
|
3853
4345
|
);
|
|
3854
4346
|
wrapped._tag = ERROR_TAG.BleGattBondingFailed;
|
|
3855
|
-
wrapped.code =
|
|
4347
|
+
wrapped.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
|
|
3856
4348
|
wrapped.originalError = err;
|
|
3857
4349
|
throw wrapped;
|
|
3858
4350
|
}
|
|
@@ -3930,7 +4422,7 @@ var LedgerConnectorBase = class {
|
|
|
3930
4422
|
this._unwatchSessionState(sessionId);
|
|
3931
4423
|
this._signerManager?.invalidate(sessionId);
|
|
3932
4424
|
this._cancellers.get(sessionId)?.({
|
|
3933
|
-
code:
|
|
4425
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.DeviceDisconnected,
|
|
3934
4426
|
tag: "DeviceDisconnected",
|
|
3935
4427
|
message: "Device disconnected"
|
|
3936
4428
|
});
|
|
@@ -3954,9 +4446,9 @@ var LedgerConnectorBase = class {
|
|
|
3954
4446
|
if (isAppStuckByApdu(err)) {
|
|
3955
4447
|
return {
|
|
3956
4448
|
success: false,
|
|
3957
|
-
error: (0,
|
|
4449
|
+
error: (0, import_hwk_adapter_core13.serializeConnectorError)(
|
|
3958
4450
|
Object.assign(new Error("Ledger app is unresponsive"), {
|
|
3959
|
-
code:
|
|
4451
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.DeviceAppStuck,
|
|
3960
4452
|
_tag: ERROR_TAG.DeviceAppStuck,
|
|
3961
4453
|
originalError: err
|
|
3962
4454
|
})
|
|
@@ -3966,16 +4458,16 @@ var LedgerConnectorBase = class {
|
|
|
3966
4458
|
if (isTransportStuck(err)) {
|
|
3967
4459
|
return {
|
|
3968
4460
|
success: false,
|
|
3969
|
-
error: (0,
|
|
4461
|
+
error: (0, import_hwk_adapter_core13.serializeConnectorError)(
|
|
3970
4462
|
Object.assign(new Error("Device communication interrupted, please retry"), {
|
|
3971
|
-
code:
|
|
4463
|
+
code: import_hwk_adapter_core13.HardwareErrorCode.TransportError,
|
|
3972
4464
|
_tag: ERROR_TAG.DeviceTransportStuck,
|
|
3973
4465
|
originalError: err
|
|
3974
4466
|
})
|
|
3975
4467
|
)
|
|
3976
4468
|
};
|
|
3977
4469
|
}
|
|
3978
|
-
return { success: false, error: (0,
|
|
4470
|
+
return { success: false, error: (0, import_hwk_adapter_core13.serializeConnectorError)(err) };
|
|
3979
4471
|
}
|
|
3980
4472
|
}
|
|
3981
4473
|
async _dispatch(sessionId, method, params) {
|
|
@@ -4038,7 +4530,7 @@ var LedgerConnectorBase = class {
|
|
|
4038
4530
|
try {
|
|
4039
4531
|
return await apps.install(p.appName, ({ progress }) => {
|
|
4040
4532
|
ctx.emit("ui-event", {
|
|
4041
|
-
type:
|
|
4533
|
+
type: import_hwk_adapter_core13.EConnectorInteraction.AppInstallProgress,
|
|
4042
4534
|
payload: {
|
|
4043
4535
|
sessionId,
|
|
4044
4536
|
appName: p.appName,
|
|
@@ -4064,6 +4556,17 @@ var LedgerConnectorBase = class {
|
|
|
4064
4556
|
ctx.clearCanceller(sessionId);
|
|
4065
4557
|
}
|
|
4066
4558
|
}
|
|
4559
|
+
case "listInstalledNames": {
|
|
4560
|
+
const apps = await _getDeviceApps(ctx, sessionId);
|
|
4561
|
+
try {
|
|
4562
|
+
return await apps.listInstalledNames(params);
|
|
4563
|
+
} catch (err) {
|
|
4564
|
+
ctx.invalidateSession(sessionId);
|
|
4565
|
+
throw ctx.wrapError(err);
|
|
4566
|
+
} finally {
|
|
4567
|
+
ctx.clearCanceller(sessionId);
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4067
4570
|
case "listAvailableApps": {
|
|
4068
4571
|
const apps = await _getDeviceApps(ctx, sessionId);
|
|
4069
4572
|
try {
|