@onekeyfe/hwk-ledger-adapter 1.2.3-alpha.1 → 1.2.3-alpha.11

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.js CHANGED
@@ -39,7 +39,6 @@ __export(index_exports, {
39
39
  SignerEth: () => SignerEth,
40
40
  SignerManager: () => SignerManager,
41
41
  SignerSol: () => SignerSol,
42
- SignerZcash: () => SignerZcash,
43
42
  debugLog: () => debugLog,
44
43
  deviceActionToPromise: () => deviceActionToPromise,
45
44
  isDeviceLockedError: () => isDeviceLockedError,
@@ -58,14 +57,17 @@ var import_hwk_adapter_core3 = require("@onekeyfe/hwk-adapter-core");
58
57
 
59
58
  // src/errors.ts
60
59
  var import_hwk_adapter_core = require("@onekeyfe/hwk-adapter-core");
61
- function ledgerFailure(code, error, appName, tag, params, origin, recovery) {
60
+ var MULTIPLE_USB_LEDGER_DEVICES_ERROR_MESSAGE = "Multiple Ledger USB devices are connected. Please connect only one Ledger device and try again.";
61
+ function createMultipleUsbLedgerDevicesError() {
62
+ return Object.assign(new Error(MULTIPLE_USB_LEDGER_DEVICES_ERROR_MESSAGE), {
63
+ code: import_hwk_adapter_core.HardwareErrorCode.DeviceOneDeviceOnly
64
+ });
65
+ }
66
+ function ledgerFailure(code, error, appName, tag, params) {
62
67
  const payload = { error, code };
63
68
  if (appName !== void 0) payload.appName = appName;
64
69
  if (tag !== void 0) payload._tag = tag;
65
70
  if (params !== void 0) payload.params = params;
66
- const resolvedOrigin = origin ?? (0, import_hwk_adapter_core.defaultOriginForCode)(code);
67
- if (resolvedOrigin !== void 0) payload.origin = resolvedOrigin;
68
- payload.recovery = recovery ?? (0, import_hwk_adapter_core.defaultRecoveryForCode)(code);
69
71
  return { success: false, payload };
70
72
  }
71
73
  var LOCKED_ERROR_CODES = /* @__PURE__ */ new Set(["5515", "21781", "6982", "27010", "5303", "21251"]);
@@ -249,6 +251,7 @@ function isBlePairingFailureError(err) {
249
251
  return false;
250
252
  }
251
253
  var CONNECTION_LEVEL_TAGS = /* @__PURE__ */ new Set([
254
+ ERROR_TAG.DeviceLocked,
252
255
  ERROR_TAG.DeviceNotAdvertising,
253
256
  ERROR_TAG.BlePairingTimeout,
254
257
  ERROR_TAG.BleGattBondingFailed,
@@ -483,12 +486,7 @@ function mapLedgerError(err, opts) {
483
486
  }
484
487
  const errAppName = err && typeof err === "object" ? err.appName : void 0;
485
488
  const appName = errAppName ?? opts?.defaultAppName;
486
- return {
487
- code,
488
- message: (0, import_hwk_adapter_core.enrichErrorMessage)(code, originalMessage),
489
- origin: (0, import_hwk_adapter_core.defaultOriginForCode)(code),
490
- appName
491
- };
489
+ return { code, message: (0, import_hwk_adapter_core.enrichErrorMessage)(code, originalMessage), appName };
492
490
  }
493
491
 
494
492
  // src/adapter/methods/allNetworkGetAddress.ts
@@ -549,81 +547,57 @@ var LEDGER_BTC_NETWORK_COIN_MAP = {
549
547
  var LEDGER_UNSUPPORTED_ALLNETWORK_NETWORKS = /* @__PURE__ */ new Set(["doge", "dogecoin"]);
550
548
  function createAllNetworkGetAddress({
551
549
  callChain,
552
- getChainFingerprint,
553
- retainInteraction,
554
- errorToFailure
550
+ getChainFingerprint
555
551
  }) {
556
552
  return async function allNetworkGetAddress(connectId, _deviceId, params) {
557
- debugLog("[LedgerAdapter][REQ]", {
558
- method: "allNetworkGetAddress",
559
- connectId,
560
- itemCount: params.bundle.length
561
- });
562
- const target = (0, import_hwk_adapter_core2.resolveHardwareOperationTarget)(connectId, params.interactionId, "ledger");
563
- if (!target.success) return target;
564
- const effectiveTargetId = target.payload.targetId ?? "";
565
- let releaseInteractionRetention;
566
- try {
567
- releaseInteractionRetention = target.payload.interactionId ? retainInteraction(target.payload.interactionId) : void 0;
568
- } catch (error) {
569
- return errorToFailure(error);
570
- }
553
+ debugLog("[LedgerAdapter][REQ]", { method: "allNetworkGetAddress", connectId, params });
571
554
  const installContext = {};
572
555
  const commonParams = {
573
- autoInstallApp: params.autoInstallApp,
574
- interactionId: target.payload.interactionId,
575
- knownConnections: params.knownConnections,
576
- extra: params.extra,
577
- allowDeviceSelection: params.allowDeviceSelection
556
+ autoInstallApp: params.autoInstallApp
578
557
  };
579
558
  const chainFingerprints = /* @__PURE__ */ new Map();
580
- try {
581
- const result = await (0, import_hwk_adapter_core2.runAllNetworkGetAddress)({
582
- connectId: effectiveTargetId,
583
- deviceId: _deviceId,
584
- params,
585
- normalizeItem: normalizeLedgerAllNetworkItem,
586
- buildUnsupportedNetworkResponse: (item) => isUnsupportedLedgerAllNetworkNetwork(item) ? buildUnsupportedNetworkResponse(item) : void 0,
587
- callItem: async ({ method, chain, item }) => {
588
- const itemDeviceId = getItemDeviceId(item) ?? chainFingerprints.get(chain) ?? "";
589
- return callAllNetworkMethod(
590
- callChain,
591
- effectiveTargetId,
592
- itemDeviceId,
593
- method,
594
- item,
595
- commonParams,
596
- installContext
597
- );
598
- },
599
- attachIdentity: async ({ item, chain, payload }) => attachLedgerIdentity(
600
- getChainFingerprint,
601
- effectiveTargetId,
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,
602
572
  item,
603
- chain,
604
- payload,
605
- chainFingerprints,
573
+ commonParams,
606
574
  installContext
607
- ),
608
- shouldAbortBundle: isTopLevelAllNetworkFailure,
609
- buildTopLevelFailure: (response) => {
610
- const code = response.payload?.code ?? import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch;
611
- return (0, import_hwk_adapter_core2.failure)(
612
- code,
613
- response.payload?.error ?? "All-network get-address aborted",
614
- response.payload?.params
615
- );
616
- }
617
- });
618
- debugLog("[LedgerAdapter][RES]", {
619
- method: "allNetworkGetAddress",
620
- success: result.success,
621
- payload: result
622
- });
623
- return result;
624
- } finally {
625
- releaseInteractionRetention?.();
626
- }
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;
627
601
  };
628
602
  }
629
603
  function isTopLevelAllNetworkFailure(response) {
@@ -631,7 +605,7 @@ function isTopLevelAllNetworkFailure(response) {
631
605
  return false;
632
606
  }
633
607
  const code = response.payload?.code;
634
- return code === import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch || code === import_hwk_adapter_core2.HardwareErrorCode.DeviceDisconnected || code === import_hwk_adapter_core2.HardwareErrorCode.OperationTimeout || code === import_hwk_adapter_core2.HardwareErrorCode.TransportError || code === import_hwk_adapter_core2.HardwareErrorCode.InteractionEnded || code === import_hwk_adapter_core2.HardwareErrorCode.InteractionNotFound || code === import_hwk_adapter_core2.HardwareErrorCode.UserAborted || code === import_hwk_adapter_core2.HardwareErrorCode.UserRejected;
608
+ return code === import_hwk_adapter_core2.HardwareErrorCode.DeviceMismatch || code === import_hwk_adapter_core2.HardwareErrorCode.UserAborted || code === import_hwk_adapter_core2.HardwareErrorCode.UserRejected;
635
609
  }
636
610
  function getItemDeviceId(item) {
637
611
  const { deviceId } = item;
@@ -661,13 +635,8 @@ function normalizeLedgerAllNetworkItem(method, item) {
661
635
  const coin = LEDGER_BTC_NETWORK_COIN_MAP[item.network];
662
636
  return coin ? { ...item, coin } : item;
663
637
  }
664
- async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain, payload, chainFingerprints, context) {
665
- const fingerprint = getItemDeviceId(item) || chainFingerprints.get(chain) || await bootstrapChainFingerprint(
666
- getChainFingerprint,
667
- context.connection?.connectId ?? connectId,
668
- chain,
669
- context
670
- );
638
+ async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain, payload, chainFingerprints) {
639
+ const fingerprint = getItemDeviceId(item) || chainFingerprints.get(chain) || await bootstrapChainFingerprint(getChainFingerprint, connectId, chain);
671
640
  if (!fingerprint) {
672
641
  return buildFingerprintBootstrapFailure(item, chain);
673
642
  }
@@ -688,8 +657,8 @@ async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain,
688
657
  }
689
658
  };
690
659
  }
691
- async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain, context) {
692
- const response = await getChainFingerprint(connectId, chain, context);
660
+ async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain) {
661
+ const response = await getChainFingerprint(connectId, chain);
693
662
  return response.success ? response.payload : "";
694
663
  }
695
664
  function buildFingerprintBootstrapFailure(item, chain) {
@@ -794,27 +763,8 @@ var _LedgerAdapter = class _LedgerAdapter {
794
763
  constructor(connector, options) {
795
764
  this.vendor = "ledger";
796
765
  this.emitter = new import_hwk_adapter_core3.TypedEventEmitter();
797
- this._interactions = new import_hwk_adapter_core3.InteractionRegistry({
798
- vendor: "ledger",
799
- onEnded: (interaction, reason) => {
800
- const binding = this._pendingInteractionBindings.get(interaction.interactionId);
801
- if (binding?.selectedConnection?.requestId === this._bindingSelectionRequestId) {
802
- this._finishBleBinding("cancelled");
803
- }
804
- this._pendingInteractionBindings.delete(interaction.interactionId);
805
- this.emitter.emit(import_hwk_adapter_core3.SDK.INTERACTION_ENDED, {
806
- type: import_hwk_adapter_core3.SDK.INTERACTION_ENDED,
807
- payload: { interactionId: interaction.interactionId, reason }
808
- });
809
- if (reason === "timeout") {
810
- void this._releaseInteractionConnection(interaction);
811
- }
812
- }
813
- });
814
766
  this._discoveredDevices = /* @__PURE__ */ new Map();
815
767
  this._sessions = /* @__PURE__ */ new Map();
816
- this._pendingInteractionBindings = /* @__PURE__ */ new Map();
817
- this._verifiedBleReconnectTargets = /* @__PURE__ */ new Map();
818
768
  this._uiRegistry = new import_hwk_adapter_core3.UiRequestRegistry();
819
769
  // BTC App rejects account index >= 100 unless display=true. Cached per
820
770
  // adapter instance: first 100+ path asks the user once via UI request,
@@ -828,30 +778,10 @@ var _LedgerAdapter = class _LedgerAdapter {
828
778
  this._deviceAuthenticityQueueTail = Promise.resolve();
829
779
  // Shared across concurrent callers — only `cancel()` aborts.
830
780
  this._doConnectAbortController = null;
831
- this._unsettledConnectorOperations = /* @__PURE__ */ new Map();
832
- this._connectorIdleWaiters = /* @__PURE__ */ new Set();
833
- this._resetPromise = null;
834
- this._stateGeneration = 0;
835
- this._connectorTeardownTail = Promise.resolve();
836
- this._pendingConnectorTeardowns = 0;
837
- this._activeInteractionJobs = /* @__PURE__ */ new Set();
838
- this._pendingInteractionDisconnects = /* @__PURE__ */ new Set();
839
781
  this._installProgressLastEmittedValue = -Infinity;
840
782
  this.allNetworkGetAddress = createAllNetworkGetAddress({
841
783
  callChain: this.callChain.bind(this),
842
- getChainFingerprint: async (connectId, chain, context) => {
843
- try {
844
- const fingerprint = await this._computeChainFingerprint(
845
- chain,
846
- (method, params) => this.connectorCall(connectId, method, params, void 0, void 0, void 0, context)
847
- );
848
- return (0, import_hwk_adapter_core3.success)(fingerprint);
849
- } catch (error) {
850
- return this.errorToFailure(error);
851
- }
852
- },
853
- retainInteraction: (interactionId) => this._interactions.retain(interactionId),
854
- errorToFailure: (error) => this.errorToFailure(error)
784
+ getChainFingerprint: (connectId, chain) => this.getChainFingerprint(connectId, "", chain)
855
785
  });
856
786
  // ---------------------------------------------------------------------------
857
787
  // Private helpers
@@ -861,7 +791,7 @@ var _LedgerAdapter = class _LedgerAdapter {
861
791
  *
862
792
  * - If a session already exists for the given connectId, reuse it.
863
793
  * - If ANY session exists (Ledger IDs are ephemeral), reuse it.
864
- * - Otherwise: search → one USB device auto-connects; multiple asks the host to choose.
794
+ * - Otherwise: search → exactly 1 USB device auto-connects; multiple or none throws.
865
795
  */
866
796
  // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections
867
797
  this._connectingPromise = null;
@@ -878,12 +808,6 @@ var _LedgerAdapter = class _LedgerAdapter {
878
808
  });
879
809
  };
880
810
  this.deviceDisconnectHandler = (data) => {
881
- const activeInteraction = this._interactions.findActiveByConnectionKey(data.connectId);
882
- if (activeInteraction && this._activeInteractionJobs.has(activeInteraction.interactionId)) {
883
- this._pendingInteractionDisconnects.add(activeInteraction.interactionId);
884
- } else {
885
- this._interactions.endByConnectionKey(data.connectId, "disconnect");
886
- }
887
811
  this._discoveredDevices.delete(data.connectId);
888
812
  this._sessions.delete(data.connectId);
889
813
  this.emitter.emit(import_hwk_adapter_core3.DEVICE.DISCONNECT, {
@@ -940,28 +864,11 @@ var _LedgerAdapter = class _LedgerAdapter {
940
864
  this._jobQueue = new import_hwk_adapter_core3.DeviceJobQueue();
941
865
  this.registerEventListeners();
942
866
  }
943
- _finishBleBinding(status) {
944
- const selectionRequestId = this._bindingSelectionRequestId;
945
- this._bindingSelectionRequestId = void 0;
946
- if (selectionRequestId)
947
- this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.DEVICE_BINDING_STATUS, {
948
- type: import_hwk_adapter_core3.UI_REQUEST.DEVICE_BINDING_STATUS,
949
- payload: { selectionRequestId, status }
950
- });
951
- }
952
- _isBleConnection() {
953
- return isLedgerBleConnectionType(this._activeConnectionType ?? this.connector.connectionType);
954
- }
955
867
  // Transport
956
868
  get activeTransport() {
957
- return this._isBleConnection() ? "ble" : "hid";
869
+ return isLedgerBleConnectionType(this.connector.connectionType) ? "ble" : "hid";
958
870
  }
959
871
  getAvailableTransports() {
960
- if (this.connector.availableTransports) {
961
- return this.connector.availableTransports.map(
962
- (transport) => transport === "ble" ? "ble" : "hid"
963
- );
964
- }
965
872
  return this.activeTransport ? [this.activeTransport] : [];
966
873
  }
967
874
  // Connector is bound at construction; switching requires a new adapter.
@@ -978,39 +885,21 @@ var _LedgerAdapter = class _LedgerAdapter {
978
885
  * The next operation will re-discover and re-connect automatically.
979
886
  */
980
887
  resetState() {
981
- void this._resetStateAndDisconnectSessions();
982
- }
983
- _resetStateAndDisconnectSessions() {
984
- if (this._resetPromise) return this._resetPromise;
985
- const sessionIds = new Set(this._sessions.values());
986
- this._stateGeneration += 1;
987
- this._finishBleBinding("cancelled");
988
- this._interactions.endAll("runtime-reset");
989
- this._doConnectAbortController?.abort();
990
888
  this._discoveredDevices.clear();
991
889
  this._sessions.clear();
992
- this._verifiedBleReconnectTargets.clear();
993
890
  this._connectingPromise = null;
994
- this._doConnectAbortController = null;
995
891
  this._uiRegistry.reset();
996
892
  this._jobQueue.clear();
997
893
  this._btcHighIndexConfirmedThisSession = false;
998
- const resetPromise = this._runConnectorTeardown(async () => {
999
- for (const sessionId of sessionIds) {
1000
- await this.connector.disconnect(sessionId).catch(() => void 0);
1001
- }
1002
- });
1003
- this._resetPromise = resetPromise;
1004
- return resetPromise.finally(() => {
1005
- if (this._resetPromise === resetPromise) {
1006
- this._resetPromise = null;
1007
- }
1008
- });
1009
894
  }
1010
895
  async dispose() {
1011
- await this._resetStateAndDisconnectSessions();
896
+ this._uiRegistry.reset();
897
+ this._jobQueue.clear();
1012
898
  this.unregisterEventListeners();
1013
899
  this.connector.reset();
900
+ this._discoveredDevices.clear();
901
+ this._sessions.clear();
902
+ this._btcHighIndexConfirmedThisSession = false;
1014
903
  this.emitter.removeAllListeners();
1015
904
  }
1016
905
  uiResponse(response) {
@@ -1020,32 +909,17 @@ var _LedgerAdapter = class _LedgerAdapter {
1020
909
  // Device management
1021
910
  // ---------------------------------------------------------------------------
1022
911
  async searchDevices(options) {
1023
- return this._searchDevices(options);
1024
- }
1025
- async _searchDevices(options, signal) {
1026
912
  debugLog("[LedgerAdapter][REQ]", { method: "searchDevices", params: options });
1027
913
  try {
1028
914
  if (options?.resetSession) {
1029
- await this._resetStateAndDisconnectSessions();
1030
- } else {
1031
- await this._connectorTeardownTail;
1032
- }
1033
- await this._ensureDevicePermission(void 0, void 0, signal);
1034
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1035
- const stateGeneration = this._stateGeneration;
1036
- const devices = await this.connector.searchDevices(
1037
- options?.transportType ? {
1038
- transportType: options.transportType,
1039
- waitForAll: options.waitForAllTransports
1040
- } : void 0
1041
- );
1042
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1043
- if (stateGeneration !== this._stateGeneration) {
1044
- throw (0, import_hwk_adapter_core3.createHwkError)({
1045
- code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted,
1046
- message: "Ledger discovery was reset"
1047
- });
915
+ this._doConnectAbortController?.abort();
916
+ this._sessions.clear();
917
+ this._connectingPromise = null;
918
+ this._doConnectAbortController = null;
919
+ this._btcHighIndexConfirmedThisSession = false;
1048
920
  }
921
+ await this._ensureDevicePermission();
922
+ const devices = await this.connector.searchDevices();
1049
923
  this._discoveredDevices.clear();
1050
924
  for (const d of devices) {
1051
925
  if (d.connectId) {
@@ -1053,7 +927,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1053
927
  }
1054
928
  }
1055
929
  if (this._discoveredDevices.size === 0) {
1056
- await this._ensureDevicePermission(void 0, void 0, signal);
930
+ await this._ensureDevicePermission();
1057
931
  }
1058
932
  const result = Array.from(this._discoveredDevices.values());
1059
933
  debugLog("[LedgerAdapter][RES]", {
@@ -1072,172 +946,41 @@ var _LedgerAdapter = class _LedgerAdapter {
1072
946
  throw err;
1073
947
  }
1074
948
  }
1075
- async searchDeviceTargets(options) {
1076
- const devices = await this.searchDevices(options);
1077
- return devices.map((device) => ({
1078
- searchTargetId: device.connectId,
1079
- searchTargetReusePolicy: (0, import_hwk_adapter_core3.resolveSearchTargetReusePolicy)(device),
1080
- vendor: "ledger",
1081
- connectionType: device.connectionType,
1082
- kind: "physical",
1083
- label: device.label,
1084
- model: device.model,
1085
- modelName: device.modelName,
1086
- serialNumber: device.serialNumber
1087
- }));
1088
- }
1089
- async listConnectionTargets(options) {
1090
- const targets = await this.searchDeviceTargets(options);
1091
- return targets.map(({ searchTargetId, ...target }) => ({
1092
- ...target,
1093
- targetId: searchTargetId
1094
- }));
1095
- }
1096
949
  // USB single-session invariant: evict all sessions, best-effort (see connectDevice).
1097
- async _evictAllSessions(preserveInteractionId) {
1098
- this._interactions.endAll("explicit", preserveInteractionId);
950
+ async _evictAllSessions() {
1099
951
  if (this._sessions.size === 0) return;
1100
952
  const stale = [...this._sessions.values()];
1101
953
  this._sessions.clear();
1102
- await this._runConnectorTeardown(async () => {
1103
- for (const sid of stale) {
1104
- try {
1105
- await this.connector.disconnect(sid);
1106
- } catch {
1107
- }
954
+ for (const sid of stale) {
955
+ try {
956
+ await this.connector.disconnect(sid);
957
+ } catch {
1108
958
  }
1109
- });
959
+ }
1110
960
  }
1111
961
  static _createDeviceBusyError(method) {
1112
962
  return Object.assign(new Error(`Ledger device is busy while calling ${method}`), {
1113
963
  code: import_hwk_adapter_core3.HardwareErrorCode.DeviceBusy
1114
964
  });
1115
965
  }
1116
- async connectDevice(searchTargetId) {
1117
- const connected = await this._connectTarget(searchTargetId);
1118
- if (!connected.success) return connected;
1119
- return this._createInteraction(searchTargetId, connected.payload);
1120
- }
1121
- async acquireInteraction(connectId, context) {
1122
- try {
1123
- return await this._jobQueue.enqueue(
1124
- connectId || "__ledger_acquire__",
1125
- async (signal) => {
1126
- const transport = this._isBleConnection() ? "ble" : "usb";
1127
- const hint = context.knownConnections?.find(
1128
- (connection) => connection.transport === transport
1129
- );
1130
- const target = hint && hint.transport !== "qr" ? hint.connectId : connectId;
1131
- await this._ensureDevicePermission(target, void 0, signal);
1132
- const attempt = {
1133
- ...context,
1134
- extra: context.extra ? { ...context.extra } : void 0,
1135
- previousConnectId: target
1136
- };
1137
- try {
1138
- const resolvedConnectId = await this.ensureConnected(
1139
- target,
1140
- signal,
1141
- true,
1142
- void 0,
1143
- attempt
1144
- );
1145
- _LedgerAdapter._throwIfAborted(signal);
1146
- const result = this._createInteraction(connectId, resolvedConnectId);
1147
- if (result.success && attempt.selectedConnection) {
1148
- this._pendingInteractionBindings.set(result.payload, attempt);
1149
- }
1150
- return result;
1151
- } catch (error) {
1152
- this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
1153
- throw error;
1154
- }
1155
- },
1156
- {
1157
- label: "acquireInteraction",
1158
- rejectIfBusy: true,
1159
- busyError: _LedgerAdapter._createDeviceBusyError("acquireInteraction")
1160
- }
1161
- );
1162
- } catch (error) {
1163
- return this.errorToFailure(error);
1164
- }
1165
- }
1166
- _createInteraction(searchTargetId, resolvedConnectId) {
1167
- this._interactions.endByConnectionKey(resolvedConnectId, "explicit");
1168
- const sessionId = this._sessions.get(resolvedConnectId);
1169
- if (sessionId) this._interactions.endByConnectionKey(sessionId, "explicit");
1170
- const device = this._discoveredDevices.get(resolvedConnectId) ?? {
1171
- vendor: "ledger",
1172
- model: "unknown",
1173
- firmwareVersion: "",
1174
- deviceId: "",
1175
- connectId: resolvedConnectId,
1176
- connectionType: this.connector.connectionType
1177
- };
1178
- const interaction = this._interactions.create({
1179
- searchTargetId,
1180
- connectId: resolvedConnectId,
1181
- device,
1182
- connectionKeys: [this._sessions.get(resolvedConnectId) ?? ""]
1183
- });
1184
- return (0, import_hwk_adapter_core3.success)(interaction.interactionId);
1185
- }
1186
- async _connectTarget(connectId, preserveInteractionId, signal) {
966
+ async connectDevice(connectId) {
1187
967
  debugLog("[LedgerAdapter][REQ]", { method: "connectDevice", connectId, params: { connectId } });
1188
968
  try {
1189
- this._assertConnectorReady("connectDevice");
1190
- const discoveredType = this._discoveredDevices.get(connectId)?.connectionType;
1191
- if (discoveredType === "usb" || discoveredType === "ble") {
1192
- this._activeConnectionType = discoveredType;
1193
- }
1194
- if (this._isBleConnection() && !connectId) {
969
+ if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
1195
970
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
1196
971
  code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
1197
972
  });
1198
973
  }
1199
- await this._ensureDevicePermission(connectId, void 0, signal);
1200
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1201
- if (this.connector.availableTransports && this.connector.availableTransports.length > 1) {
1202
- await this._evictAllSessions(preserveInteractionId);
1203
- } else if (this._isBleConnection()) {
1204
- const previousSessionId = this._sessions.get(connectId);
1205
- this._interactions.endByConnectionKey(connectId, "explicit", preserveInteractionId);
1206
- if (previousSessionId) {
1207
- this._interactions.endByConnectionKey(
1208
- previousSessionId,
1209
- "explicit",
1210
- preserveInteractionId
1211
- );
1212
- this._sessions.delete(connectId);
1213
- await this.connector.disconnect(previousSessionId).catch(() => void 0);
1214
- }
1215
- } else {
1216
- await this._evictAllSessions(preserveInteractionId);
974
+ if (!isLedgerBleConnectionType(this.connector.connectionType)) {
975
+ await this._evictAllSessions();
1217
976
  }
1218
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1219
- const stateGeneration = this._stateGeneration;
1220
- const releaseOperation = this._retainConnectorOperation(`connect:${connectId}`);
1221
- let session;
1222
- try {
1223
- session = this.connector.availableTransports?.length ? await this.connector.connect(connectId, {
1224
- transportType: this._activeConnectionType ?? "usb"
1225
- }) : await this.connector.connect(connectId);
1226
- if (signal?.aborted || stateGeneration !== this._stateGeneration) {
1227
- await this.connector.disconnect(session.sessionId).catch(() => void 0);
1228
- throw Object.assign(new Error("Ledger connection aborted"), {
1229
- code: import_hwk_adapter_core3.HardwareErrorCode.UserAborted
1230
- });
1231
- }
1232
- } finally {
1233
- releaseOperation();
1234
- }
1235
- const resolvedConnectId = session.deviceInfo?.connectId || connectId;
1236
- this._sessions.set(resolvedConnectId, session.sessionId);
977
+ await this._ensureDevicePermission(connectId);
978
+ const session = await this.connector.connect(connectId);
979
+ this._sessions.set(connectId, session.sessionId);
1237
980
  if (session.deviceInfo) {
1238
- this._discoveredDevices.set(resolvedConnectId, session.deviceInfo);
981
+ this._discoveredDevices.set(connectId, session.deviceInfo);
1239
982
  }
1240
- const result = (0, import_hwk_adapter_core3.success)(resolvedConnectId);
983
+ const result = (0, import_hwk_adapter_core3.success)(connectId);
1241
984
  debugLog("[LedgerAdapter][RES]", { method: "connectDevice", success: true, payload: result });
1242
985
  return result;
1243
986
  } catch (err) {
@@ -1250,60 +993,30 @@ var _LedgerAdapter = class _LedgerAdapter {
1250
993
  return failureResult;
1251
994
  }
1252
995
  }
1253
- async releaseInteraction(interactionId) {
1254
- const interaction = this._interactions.find(interactionId);
1255
- if (!interaction) {
1256
- this._interactions.resolve(interactionId);
1257
- return;
1258
- }
1259
- const endedInteraction = this._interactions.end(interactionId, "explicit");
1260
- if (!endedInteraction) return;
1261
- const { connectId } = interaction;
996
+ async disconnectDevice(connectId) {
1262
997
  debugLog("[LedgerAdapter][REQ]", {
1263
- method: "releaseInteraction",
998
+ method: "disconnectDevice",
1264
999
  connectId,
1265
1000
  params: { connectId }
1266
1001
  });
1267
1002
  try {
1268
- await this._releaseInteractionConnection(endedInteraction);
1269
- debugLog("[LedgerAdapter][RES]", { method: "releaseInteraction", success: true });
1003
+ const sessionId = this._sessions.get(connectId);
1004
+ if (sessionId) {
1005
+ await this.connector.disconnect(sessionId);
1006
+ this._sessions.delete(connectId);
1007
+ }
1008
+ debugLog("[LedgerAdapter][RES]", { method: "disconnectDevice", success: true });
1270
1009
  } catch (err) {
1271
1010
  const e = err;
1272
1011
  debugLog("[LedgerAdapter][RES]", {
1273
- method: "releaseInteraction",
1012
+ method: "disconnectDevice",
1274
1013
  success: false,
1275
1014
  error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
1276
1015
  });
1277
1016
  throw err;
1278
1017
  }
1279
1018
  }
1280
- async _releaseInteractionConnection(interaction) {
1281
- const sessionIds = /* @__PURE__ */ new Set();
1282
- for (const [connectId, sessionId] of this._sessions) {
1283
- if (connectId === interaction.connectId || interaction.connectionKeys.includes(connectId) || interaction.connectionKeys.includes(sessionId)) {
1284
- this._sessions.delete(connectId);
1285
- sessionIds.add(sessionId);
1286
- }
1287
- }
1288
- for (const sessionId of sessionIds) {
1289
- await this._runConnectorTeardown(
1290
- () => this.connector.disconnect(sessionId).catch(() => void 0)
1291
- );
1292
- }
1293
- }
1294
- async _releaseLostInteractionConnection(interactionId) {
1295
- const endedInteraction = this._interactions.end(interactionId, "disconnect");
1296
- if (!endedInteraction) return;
1297
- this._discoveredDevices.delete(endedInteraction.connectId);
1298
- await this._releaseInteractionConnection(endedInteraction);
1299
- }
1300
- async getDeviceInfo(connectIdOrInteractionId, deviceId) {
1301
- let connectId;
1302
- try {
1303
- connectId = (0, import_hwk_adapter_core3.isHardwareInteractionId)(connectIdOrInteractionId) ? this._interactions.resolve(connectIdOrInteractionId).connectId : connectIdOrInteractionId;
1304
- } catch (error) {
1305
- return this.errorToFailure(error);
1306
- }
1019
+ async getDeviceInfo(connectId, deviceId) {
1307
1020
  debugLog("[LedgerAdapter][REQ]", {
1308
1021
  method: "getDeviceInfo",
1309
1022
  connectId,
@@ -1342,7 +1055,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1342
1055
  }
1343
1056
  }
1344
1057
  getSupportedChains() {
1345
- return ["evm", "btc", "sol", "tron", "zcash"];
1058
+ return ["evm", "btc", "sol", "tron"];
1346
1059
  }
1347
1060
  // ---------------------------------------------------------------------------
1348
1061
  // Chain call helper
@@ -1378,21 +1091,13 @@ var _LedgerAdapter = class _LedgerAdapter {
1378
1091
  if (params && typeof params === "object") {
1379
1092
  const {
1380
1093
  autoInstallApp,
1381
- interactionId,
1382
1094
  passphraseState: _passphraseState,
1383
1095
  useEmptyPassphrase: _useEmptyPassphrase,
1384
- knownConnections,
1385
- extra,
1386
- allowDeviceSelection,
1387
1096
  ...rest
1388
1097
  } = params;
1389
1098
  return {
1390
1099
  commonParams: {
1391
- autoInstallApp: typeof autoInstallApp === "boolean" ? autoInstallApp : void 0,
1392
- interactionId: typeof interactionId === "string" ? interactionId : void 0,
1393
- knownConnections,
1394
- extra,
1395
- allowDeviceSelection: typeof allowDeviceSelection === "boolean" ? allowDeviceSelection : void 0
1100
+ autoInstallApp: typeof autoInstallApp === "boolean" ? autoInstallApp : void 0
1396
1101
  },
1397
1102
  rest
1398
1103
  };
@@ -1568,27 +1273,6 @@ var _LedgerAdapter = class _LedgerAdapter {
1568
1273
  );
1569
1274
  }
1570
1275
  // ---------------------------------------------------------------------------
1571
- // Zcash chain methods (viewing key + shielded address reads; Zcash app >= 3.8.0)
1572
- // ---------------------------------------------------------------------------
1573
- zcashGetFullViewingKey(connectId, deviceId, params) {
1574
- return this.callChainWithMergedParams(
1575
- connectId,
1576
- deviceId,
1577
- "zcash",
1578
- "zcashGetFullViewingKey",
1579
- params
1580
- );
1581
- }
1582
- zcashGetShieldedAddress(connectId, deviceId, params) {
1583
- return this.callChainWithMergedParams(
1584
- connectId,
1585
- deviceId,
1586
- "zcash",
1587
- "zcashGetShieldedAddress",
1588
- params
1589
- );
1590
- }
1591
- // ---------------------------------------------------------------------------
1592
1276
  // App management — OS-level Ledger app install / list. Bypasses fingerprint
1593
1277
  // and chain-handler dispatch; installApp progress is forwarded to the adapter
1594
1278
  // emitter via 'ui-event' AppInstallProgress events.
@@ -1677,7 +1361,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1677
1361
  );
1678
1362
  }
1679
1363
  await this.connector.configure({ ledgerGenuineCheckWebSocketUrl: relayUrl });
1680
- await this._resetStateAndDisconnectSessions();
1364
+ this.resetState();
1681
1365
  }
1682
1366
  const result = await this.connectorCall(connectId, "getDeviceGenuineCheck", {});
1683
1367
  if (!result.isGenuine) {
@@ -1703,10 +1387,10 @@ var _LedgerAdapter = class _LedgerAdapter {
1703
1387
  if (relayUrl) {
1704
1388
  try {
1705
1389
  await this.connector.configure?.({ ledgerGenuineCheckWebSocketUrl: void 0 });
1706
- await this._resetStateAndDisconnectSessions();
1390
+ this.resetState();
1707
1391
  } catch {
1708
1392
  this.connector.reset();
1709
- await this._resetStateAndDisconnectSessions();
1393
+ this.resetState();
1710
1394
  }
1711
1395
  }
1712
1396
  }
@@ -1729,36 +1413,13 @@ var _LedgerAdapter = class _LedgerAdapter {
1729
1413
  }
1730
1414
  }, 2e3);
1731
1415
  this._uiRegistry.cancel();
1732
- this._finishBleBinding("cancelled");
1733
- const activeJobId = this._jobQueue.getActiveJob()?.deviceId;
1734
- let interactionId;
1735
- if ((0, import_hwk_adapter_core3.isHardwareInteractionId)(connectId)) {
1736
- interactionId = connectId;
1737
- } else if (!connectId && (0, import_hwk_adapter_core3.isHardwareInteractionId)(activeJobId)) {
1738
- interactionId = activeJobId;
1739
- }
1740
- let resolvedConnectId = connectId;
1741
- if (interactionId) {
1742
- try {
1743
- resolvedConnectId = this._interactions.resolve(interactionId).connectId;
1744
- } catch {
1745
- resolvedConnectId = void 0;
1746
- }
1747
- }
1748
- const interactionForPhysicalId = !interactionId && connectId ? this._interactions.findActiveByConnectionKey(connectId) : void 0;
1749
- const queueKey = interactionId ?? (activeJobId === connectId ? connectId : interactionForPhysicalId?.interactionId) ?? connectId;
1750
- const pendingInteractionId = interactionId ?? interactionForPhysicalId?.interactionId;
1751
- if (!connectId) this._pendingInteractionBindings.clear();
1752
- else if (pendingInteractionId) {
1753
- this._pendingInteractionBindings.delete(pendingInteractionId);
1754
- }
1755
- if (queueKey) {
1756
- this._jobQueue.cancelActiveAndPending(queueKey, userAbortReason);
1416
+ if (connectId) {
1417
+ this._jobQueue.cancelActiveAndPending(connectId, userAbortReason);
1757
1418
  } else {
1758
1419
  this._jobQueue.cancelActiveAndPending(void 0, userAbortReason);
1759
1420
  }
1760
- if (resolvedConnectId) {
1761
- const sessionId = this._sessions.get(resolvedConnectId) ?? resolvedConnectId;
1421
+ if (connectId) {
1422
+ const sessionId = this._sessions.get(connectId) ?? connectId;
1762
1423
  void this.connector.cancel(sessionId);
1763
1424
  } else {
1764
1425
  for (const sid of this._sessions.values()) void this.connector.cancel(sid);
@@ -1770,83 +1431,40 @@ var _LedgerAdapter = class _LedgerAdapter {
1770
1431
  // ---------------------------------------------------------------------------
1771
1432
  // Chain fingerprint
1772
1433
  // ---------------------------------------------------------------------------
1773
- /** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
1774
1434
  async getChainFingerprint(connectId, deviceId, chain) {
1775
1435
  try {
1776
1436
  const fingerprint = await this._computeChainFingerprint(
1777
1437
  chain,
1778
1438
  (method, params) => this.connectorCall(connectId, method, params, void 0, deviceId)
1779
1439
  );
1780
- if (deviceId) {
1781
- if (fingerprint !== deviceId) {
1782
- return (0, import_hwk_adapter_core3.failure)(
1783
- import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch,
1784
- formatDeviceMismatchError(deviceId, fingerprint)
1785
- );
1786
- }
1787
- if ((0, import_hwk_adapter_core3.isHardwareInteractionId)(connectId)) {
1788
- const interaction = this._interactions.resolve(connectId);
1789
- await this._publishVerifiedBleBinding(
1790
- interaction.connectId,
1791
- chain,
1792
- fingerprint,
1793
- void 0,
1794
- connectId
1795
- );
1796
- }
1797
- }
1798
1440
  return (0, import_hwk_adapter_core3.success)(fingerprint);
1799
1441
  } catch (err) {
1800
1442
  debugError("[LedgerAdapter] getChainFingerprint error:", chain, err);
1801
1443
  return this.errorToFailure(err);
1802
1444
  }
1803
1445
  }
1804
- /** Discovery may select a BLE target before a later call verifies its wallet. */
1805
- async _publishVerifiedBleBinding(connectId, chain, fingerprint, attempt, interactionId, previousConnectId = "", signal) {
1806
- const binding = interactionId ? this._pendingInteractionBindings.get(interactionId) : attempt;
1807
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== connectId) return;
1808
- const acknowledged = await (0, import_hwk_adapter_core3.requestSaveDeviceBinding)(
1809
- this.emitter,
1810
- this._uiRegistry,
1811
- {
1812
- selectionRequestId: binding.selectedConnection.requestId,
1813
- connection: { transport: "ble", connectId },
1814
- identity: { vendor: "ledger", type: "chainFingerprint", chain, value: fingerprint },
1815
- extra: binding.extra
1816
- },
1817
- signal
1818
- );
1819
- if (this._bindingSelectionRequestId === binding.selectedConnection.requestId) {
1820
- this._bindingSelectionRequestId = void 0;
1821
- }
1822
- if (interactionId) {
1823
- this._interactions.resolve(interactionId);
1824
- this._pendingInteractionBindings.delete(interactionId);
1825
- }
1826
- if (acknowledged) return;
1827
- this.emitter.emit(import_hwk_adapter_core3.DEVICE.LEDGER_CONNECTION_VERIFIED, {
1828
- type: import_hwk_adapter_core3.DEVICE.LEDGER_CONNECTION_VERIFIED,
1829
- payload: {
1830
- previousConnectId: binding.previousConnectId ?? previousConnectId,
1831
- connectId,
1832
- chain,
1833
- fingerprint,
1834
- extra: binding.extra,
1835
- selectionRequestId: binding.selectedConnection.requestId
1836
- }
1837
- });
1838
- }
1839
- /** Verify on the acquired session without re-entering the job queue. */
1446
+ /**
1447
+ * Verify fingerprint using an existing sessionId directly.
1448
+ * Safe to call inside connectorCall without causing queue deadlock.
1449
+ */
1840
1450
  async _verifyDeviceFingerprintWithSession(sessionId, deviceId, chain) {
1841
1451
  if (!deviceId) return { success: true };
1842
- const fingerprint = await this._computeChainFingerprint(
1843
- chain,
1844
- (method, params) => this._callConnector(sessionId, method, params)
1845
- );
1846
- if (fingerprint === deviceId) {
1847
- return { success: true };
1452
+ try {
1453
+ const fingerprint = await this._computeChainFingerprint(
1454
+ chain,
1455
+ (method, params) => this._callConnector(sessionId, method, params)
1456
+ );
1457
+ if (fingerprint === deviceId) {
1458
+ return { success: true };
1459
+ }
1460
+ return { success: false, expected: deviceId, actual: fingerprint };
1461
+ } catch (err) {
1462
+ const mapped = mapLedgerError(err);
1463
+ if (mapped.code === import_hwk_adapter_core3.HardwareErrorCode.WrongApp || mapped.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceLocked) {
1464
+ return { success: true };
1465
+ }
1466
+ throw err;
1848
1467
  }
1849
- return { success: false, expected: deviceId, actual: fingerprint };
1850
1468
  }
1851
1469
  /**
1852
1470
  * Compute the chain fingerprint via a caller-supplied call strategy.
@@ -1875,8 +1493,6 @@ var _LedgerAdapter = class _LedgerAdapter {
1875
1493
  address = (await callMethod("solGetAddress", { path, showOnDevice: false })).address;
1876
1494
  } else if (chain === "tron") {
1877
1495
  address = (await callMethod("tronGetAddress", { path, showOnDevice: false })).address;
1878
- } else if (chain === "zcash") {
1879
- address = (await callMethod("zcashGetShieldedAddress", { path, showOnDevice: false })).address;
1880
1496
  } else {
1881
1497
  throw new Error(`Unsupported chain for fingerprint: ${chain}`);
1882
1498
  }
@@ -2006,17 +1622,16 @@ var _LedgerAdapter = class _LedgerAdapter {
2006
1622
  // Layer 1 entry. Caller signal only races the outer awaiter; the shared
2007
1623
  // `_doConnect` runs under its own internal controller so caller A's cancel
2008
1624
  // doesn't kill caller B's await.
2009
- async ensureConnected(connectId, signal, allowUsbEphemeralFallback = false, preserveInteractionId, context) {
1625
+ async ensureConnected(connectId, signal, allowUsbEphemeralFallback = false) {
2010
1626
  if (signal.aborted) _LedgerAdapter._throwIfAborted(signal);
2011
- this._assertConnectorReady("connectDevice");
2012
- if (this._isBleConnection() && !connectId && !allowUsbEphemeralFallback) {
1627
+ if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
2013
1628
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
2014
1629
  code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
2015
1630
  });
2016
1631
  }
2017
1632
  if (connectId && this._sessions.has(connectId)) return connectId;
2018
1633
  if (!connectId && this._sessions.size > 0) {
2019
- if (!this._isBleConnection() && this._sessions.size > 1) {
1634
+ if (!isLedgerBleConnectionType(this.connector.connectionType) && this._sessions.size > 1) {
2020
1635
  throw Object.assign(
2021
1636
  new Error(
2022
1637
  "Ledger USB session invariant violated: more than one session is active. Please reconnect the device."
@@ -2026,24 +1641,15 @@ var _LedgerAdapter = class _LedgerAdapter {
2026
1641
  }
2027
1642
  return this._sessions.keys().next().value;
2028
1643
  }
2029
- if (!this._connectingPromise || this._doConnectAbortController?.signal.aborted) {
2030
- const controller = new AbortController();
2031
- this._doConnectAbortController = controller;
2032
- const innerSignal = controller.signal;
1644
+ if (!this._connectingPromise) {
1645
+ this._doConnectAbortController = new AbortController();
1646
+ const innerSignal = this._doConnectAbortController.signal;
2033
1647
  this._connectingPromise = (async () => {
2034
1648
  try {
2035
- return await this._doConnect(
2036
- innerSignal,
2037
- connectId,
2038
- allowUsbEphemeralFallback,
2039
- preserveInteractionId,
2040
- context
2041
- );
1649
+ return await this._doConnect(innerSignal, connectId, allowUsbEphemeralFallback);
2042
1650
  } finally {
2043
- if (this._doConnectAbortController === controller) {
2044
- this._connectingPromise = null;
2045
- this._doConnectAbortController = null;
2046
- }
1651
+ this._connectingPromise = null;
1652
+ this._doConnectAbortController = null;
2047
1653
  }
2048
1654
  })();
2049
1655
  }
@@ -2052,49 +1658,22 @@ var _LedgerAdapter = class _LedgerAdapter {
2052
1658
  // Layer 1 main loop — the ONLY place in SDK that emits unlock dialog.
2053
1659
  // Bounded by MAX_DOCONNECT_CONFIRMS — after N Confirms with no progress,
2054
1660
  // throw DeviceNotFound so the user is kicked out of the loop.
2055
- async _doConnect(internalSignal, targetConnectId, allowUsbEphemeralFallback = false, preserveInteractionId, context) {
2056
- _LedgerAdapter._throwIfAborted(internalSignal);
2057
- if (this.connector.availableTransports?.includes("usb") && this.connector.availableTransports.includes("ble")) {
2058
- this._activeConnectionType = "usb";
2059
- const usbDevices = await this._searchDevices({ transportType: "usb" }, internalSignal);
2060
- _LedgerAdapter._throwIfAborted(internalSignal);
2061
- if (usbDevices.length > 0) {
2062
- const knownUsb = context?.knownConnections?.find(
2063
- (connection) => connection.transport === "usb"
2064
- );
2065
- const usbTarget = knownUsb?.transport === "usb" ? knownUsb.connectId : usbDevices.find((device) => device.connectId === targetConnectId)?.connectId;
2066
- return this._connectFirstOrSelect(
2067
- usbDevices,
2068
- usbTarget,
2069
- allowUsbEphemeralFallback,
2070
- preserveInteractionId,
2071
- context,
2072
- internalSignal
2073
- );
2074
- }
2075
- this._activeConnectionType = "ble";
2076
- const knownBle = context?.knownConnections?.find(
2077
- (connection) => connection.transport === "ble"
2078
- );
2079
- if (knownBle?.transport === "ble") {
2080
- return this._connectDeviceOrThrow(
2081
- knownBle.connectId,
2082
- preserveInteractionId,
2083
- internalSignal
2084
- );
1661
+ async _doConnect(internalSignal, targetConnectId, allowUsbEphemeralFallback = false) {
1662
+ if (isLedgerBleConnectionType(this.connector.connectionType) && targetConnectId) {
1663
+ try {
1664
+ return await this._connectDeviceOrThrow(targetConnectId);
1665
+ } catch (err) {
1666
+ if (!isDeviceLockedError(err) && !isDeviceNotAdvertisingError(err) && !isDeviceDisconnectedError(err)) {
1667
+ throw err;
1668
+ }
1669
+ this._discoveredDevices.delete(targetConnectId);
1670
+ if (isDeviceDisconnectedError(err)) {
1671
+ try {
1672
+ this.connector.reset?.();
1673
+ } catch {
1674
+ }
1675
+ }
2085
1676
  }
2086
- const bleDevices = await this._searchDevices({ transportType: "ble" }, internalSignal);
2087
- return this._connectFirstOrSelect(
2088
- bleDevices,
2089
- void 0,
2090
- allowUsbEphemeralFallback,
2091
- preserveInteractionId,
2092
- context,
2093
- internalSignal
2094
- );
2095
- }
2096
- if (this._isBleConnection() && targetConnectId) {
2097
- return this._connectDeviceOrThrow(targetConnectId, preserveInteractionId, internalSignal);
2098
1677
  }
2099
1678
  let confirms = 0;
2100
1679
  while (!internalSignal.aborted) {
@@ -2102,28 +1681,22 @@ var _LedgerAdapter = class _LedgerAdapter {
2102
1681
  type: import_hwk_adapter_core3.EConnectorInteraction.Searching,
2103
1682
  payload: { sessionId: "" }
2104
1683
  });
2105
- let devices = await this._searchDevices(void 0, internalSignal);
2106
- _LedgerAdapter._throwIfAborted(internalSignal);
1684
+ let devices = await this.searchDevices();
2107
1685
  if (devices.length === 0) {
2108
1686
  for (let i = 0; i < 3 && !internalSignal.aborted; i += 1) {
2109
1687
  await new Promise((resolve) => {
2110
1688
  setTimeout(resolve, import_hwk_adapter_core3.DEVICE_CONNECT_RETRY_DELAY_MS);
2111
1689
  });
2112
- _LedgerAdapter._throwIfAborted(internalSignal);
2113
- devices = await this._searchDevices(void 0, internalSignal);
2114
- _LedgerAdapter._throwIfAborted(internalSignal);
1690
+ devices = await this.searchDevices();
2115
1691
  if (devices.length > 0) break;
2116
1692
  }
2117
1693
  }
2118
- if (devices.length > 0 || this._isBleConnection() && allowUsbEphemeralFallback) {
1694
+ if (devices.length > 0) {
2119
1695
  try {
2120
1696
  return await this._connectFirstOrSelect(
2121
1697
  devices,
2122
1698
  targetConnectId,
2123
- allowUsbEphemeralFallback,
2124
- preserveInteractionId,
2125
- context,
2126
- internalSignal
1699
+ allowUsbEphemeralFallback
2127
1700
  );
2128
1701
  } catch (err) {
2129
1702
  if (!isDeviceLockedError(err) && !isDeviceNotAdvertisingError(err) && !isDeviceDisconnectedError(err)) {
@@ -2152,107 +1725,45 @@ var _LedgerAdapter = class _LedgerAdapter {
2152
1725
  _LedgerAdapter._throwIfAborted(internalSignal);
2153
1726
  throw new Error("_doConnect aborted");
2154
1727
  }
2155
- async _connectFirstOrSelect(devices, targetConnectId, allowUsbEphemeralFallback = false, preserveInteractionId, context, signal) {
2156
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1728
+ async _connectFirstOrSelect(devices, targetConnectId, allowUsbEphemeralFallback = false) {
2157
1729
  if (targetConnectId) {
2158
1730
  const target = devices.find(
2159
1731
  (d) => d.connectId === targetConnectId || d.deviceId === targetConnectId
2160
1732
  );
2161
1733
  if (target) {
2162
- return this._connectDeviceOrThrow(target.connectId, preserveInteractionId, signal);
1734
+ return this._connectDeviceOrThrow(target.connectId);
2163
1735
  }
2164
- if (!this._isBleConnection() && devices.length === 1 && allowUsbEphemeralFallback) {
1736
+ if (!isLedgerBleConnectionType(this.connector.connectionType) && devices.length === 1 && allowUsbEphemeralFallback) {
2165
1737
  debugLog(
2166
1738
  `[LedgerAdapter] target ${targetConnectId} not in fresh enumeration; accepting sole USB device ${devices[0].connectId} for fingerprint-verified recovery`
2167
1739
  );
2168
- return this._connectDeviceOrThrow(devices[0].connectId, preserveInteractionId, signal);
1740
+ return this._connectDeviceOrThrow(devices[0].connectId);
2169
1741
  }
2170
- if (!this._isBleConnection() || !allowUsbEphemeralFallback) {
2171
- const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
2172
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
2173
- });
2174
- if (this._isBleConnection()) {
2175
- err._tag = ERROR_TAG.DeviceNotAdvertising;
2176
- }
2177
- throw err;
1742
+ const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
1743
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
1744
+ });
1745
+ if (isLedgerBleConnectionType(this.connector.connectionType)) {
1746
+ err._tag = ERROR_TAG.DeviceNotAdvertising;
2178
1747
  }
1748
+ throw err;
2179
1749
  }
2180
- const requiresBleSelection = this._isBleConnection();
2181
- if (requiresBleSelection && !allowUsbEphemeralFallback) {
1750
+ if (isLedgerBleConnectionType(this.connector.connectionType)) {
2182
1751
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
2183
1752
  code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
2184
1753
  });
2185
1754
  }
2186
- if (requiresBleSelection && context?.allowDeviceSelection !== false) {
2187
- const bindingSessionId = context?.bindingSessionId ?? this._uiRegistry.createRequestId();
2188
- if (context) context.bindingSessionId = bindingSessionId;
2189
- const { device, requestId } = await (0, import_hwk_adapter_core3.requestBleDeviceSelection)({
2190
- emitter: this.emitter,
2191
- registry: this._uiRegistry,
2192
- signal: signal ?? new AbortController().signal,
2193
- scan: async () => (await this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)).filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId)),
2194
- request: {
2195
- devices: devices.filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId)),
2196
- bindingSessionId,
2197
- rejectedConnectId: context?.rejectedConnectId,
2198
- context: {
2199
- kind: "bind-connection",
2200
- transport: "ble",
2201
- reason: targetConnectId ? "known-connection-unavailable" : "missing-binding"
2202
- },
2203
- extra: context?.extra
2204
- }
2205
- });
2206
- if (context) context.selectedConnection = { connectId: device.connectId, requestId };
2207
- this._bindingSelectionRequestId = requestId;
2208
- return this._connectDeviceOrThrow(device.connectId, preserveInteractionId, signal);
2209
- }
2210
- if (devices.length > 0 && (devices.length > 1 || requiresBleSelection)) {
2211
- if (context?.allowDeviceSelection === false || !this.emitter.listenerCount(import_hwk_adapter_core3.UI_REQUEST.REQUEST_SELECT_DEVICE)) {
2212
- throw (0, import_hwk_adapter_core3.createHwkError)({
2213
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound,
2214
- message: "Select a Ledger device before continuing"
2215
- });
2216
- }
2217
- const requestId = this._uiRegistry.createRequestId();
2218
- const waitPromise = this._uiRegistry.wait(
2219
- import_hwk_adapter_core3.UI_REQUEST.REQUEST_SELECT_DEVICE,
2220
- { requestId }
2221
- );
2222
- this.emitter.emit(import_hwk_adapter_core3.UI_REQUEST.REQUEST_SELECT_DEVICE, {
2223
- type: import_hwk_adapter_core3.UI_REQUEST.REQUEST_SELECT_DEVICE,
2224
- payload: {
2225
- devices,
2226
- requestId,
2227
- context: requiresBleSelection ? {
2228
- kind: "bind-connection",
2229
- transport: "ble",
2230
- reason: targetConnectId ? "known-connection-unavailable" : "missing-binding"
2231
- } : { kind: "select-device", transport: "usb", reason: "multiple-candidates" },
2232
- extra: context?.extra
2233
- }
2234
- });
2235
- const { sdkConnectId } = await (signal ? this._abortable(signal, waitPromise) : waitPromise);
2236
- if (signal) _LedgerAdapter._throwIfAborted(signal);
2237
- const selected = devices.find((device) => device.connectId === sdkConnectId);
2238
- if (!selected) {
2239
- throw Object.assign(new Error("Selected Ledger is no longer available"), {
2240
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
2241
- });
2242
- }
2243
- if (context && requiresBleSelection)
2244
- context.selectedConnection = { connectId: selected.connectId, requestId };
2245
- return this._connectDeviceOrThrow(selected.connectId, preserveInteractionId, signal);
1755
+ if (devices.length > 1) {
1756
+ throw createMultipleUsbLedgerDevicesError();
2246
1757
  }
2247
1758
  if (devices.length !== 1) {
2248
1759
  throw Object.assign(new Error("Ledger device not found."), {
2249
1760
  code: import_hwk_adapter_core3.HardwareErrorCode.DeviceNotFound
2250
1761
  });
2251
1762
  }
2252
- return this._connectDeviceOrThrow(devices[0].connectId, preserveInteractionId, signal);
1763
+ return this._connectDeviceOrThrow(devices[0].connectId);
2253
1764
  }
2254
- async _connectDeviceOrThrow(chosenConnectId, preserveInteractionId, signal) {
2255
- const result = await this._connectTarget(chosenConnectId, preserveInteractionId, signal);
1765
+ async _connectDeviceOrThrow(chosenConnectId) {
1766
+ const result = await this.connectDevice(chosenConnectId);
2256
1767
  if (!result.success) {
2257
1768
  const payload = result.payload;
2258
1769
  const rethrow = Object.assign(new Error(payload.error), {
@@ -2263,7 +1774,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2263
1774
  }
2264
1775
  throw rethrow;
2265
1776
  }
2266
- return result.payload;
1777
+ return chosenConnectId;
2267
1778
  }
2268
1779
  /**
2269
1780
  * Call the connector with automatic session resolution and disconnect retry.
@@ -2293,121 +1804,26 @@ var _LedgerAdapter = class _LedgerAdapter {
2293
1804
  * lives in one place.
2294
1805
  */
2295
1806
  async _callConnector(sessionId, method, params, signal) {
2296
- this._assertConnectorReady(method);
2297
- const releaseOperation = this._retainConnectorOperation(`call:${sessionId}`);
2298
- let promise;
2299
- try {
2300
- promise = this.connector.call(sessionId, method, params).finally(releaseOperation);
2301
- } catch (error) {
2302
- releaseOperation();
2303
- throw error;
2304
- }
1807
+ const promise = this.connector.call(sessionId, method, params);
2305
1808
  const result = signal ? await this._abortable(signal, promise) : await promise;
2306
1809
  return this._unwrapConnectorResult(result);
2307
1810
  }
2308
- _assertConnectorReady(method) {
2309
- if (this._resetPromise || this._pendingConnectorTeardowns > 0 || this._unsettledConnectorOperations.size > 0) {
2310
- throw _LedgerAdapter._createDeviceBusyError(method);
2311
- }
2312
- }
2313
- _runConnectorTeardown(task) {
2314
- const previous = this._connectorTeardownTail;
2315
- let releaseTail = () => void 0;
2316
- this._connectorTeardownTail = new Promise((resolve) => {
2317
- releaseTail = resolve;
2318
- });
2319
- this._pendingConnectorTeardowns += 1;
2320
- return (async () => {
2321
- try {
2322
- await previous;
2323
- await this._waitForConnectorOperationsToDrain();
2324
- await task();
2325
- } finally {
2326
- this._pendingConnectorTeardowns -= 1;
2327
- releaseTail();
2328
- }
2329
- })();
2330
- }
2331
- _waitForConnectorOperationsToDrain() {
2332
- if (this._unsettledConnectorOperations.size === 0) {
2333
- return Promise.resolve();
2334
- }
2335
- return new Promise((resolve) => {
2336
- this._connectorIdleWaiters.add(resolve);
2337
- });
2338
- }
2339
- _retainConnectorOperation(key) {
2340
- this._unsettledConnectorOperations.set(
2341
- key,
2342
- (this._unsettledConnectorOperations.get(key) ?? 0) + 1
2343
- );
2344
- let released = false;
2345
- return () => {
2346
- if (released) return;
2347
- released = true;
2348
- const remaining = (this._unsettledConnectorOperations.get(key) ?? 1) - 1;
2349
- if (remaining > 0) {
2350
- this._unsettledConnectorOperations.set(key, remaining);
2351
- } else {
2352
- this._unsettledConnectorOperations.delete(key);
2353
- }
2354
- if (this._unsettledConnectorOperations.size === 0) {
2355
- for (const resolve of this._connectorIdleWaiters) resolve();
2356
- this._connectorIdleWaiters.clear();
2357
- }
2358
- };
2359
- }
2360
1811
  async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams, installContext) {
2361
- const positionalInteractionId = (0, import_hwk_adapter_core3.isHardwareInteractionId)(connectId) ? connectId : void 0;
2362
- if (positionalInteractionId && commonParams?.interactionId && positionalInteractionId !== commonParams.interactionId) {
2363
- throw (0, import_hwk_adapter_core3.createHwkError)({
2364
- code: import_hwk_adapter_core3.HardwareErrorCode.InvalidParams,
2365
- message: "Conflicting Ledger interaction ids",
2366
- params: {
2367
- positionalInteractionId,
2368
- commonInteractionId: commonParams.interactionId
2369
- }
2370
- });
2371
- }
2372
- const interactionId = commonParams?.interactionId ?? positionalInteractionId;
2373
- const interaction = interactionId ? this._interactions.resolve(interactionId) : void 0;
2374
- const releaseInteractionRetention = interactionId ? this._interactions.retain(interactionId) : void 0;
2375
- const effectiveConnectId = interaction?.connectId ?? connectId;
2376
- debugLog("[LedgerAdapter][REQ]", {
2377
- method,
2378
- connectId: effectiveConnectId || "(empty)",
2379
- params
2380
- });
2381
- const queueKey = (interactionId ?? effectiveConnectId) || "__ledger_default__";
1812
+ debugLog("[LedgerAdapter][REQ]", { method, connectId: connectId || "(empty)", params });
1813
+ const queueKey = connectId || "__ledger_default__";
2382
1814
  try {
2383
1815
  const result = await this._jobQueue.enqueue(
2384
1816
  queueKey,
2385
- async (signal) => {
2386
- if (interactionId) this._activeInteractionJobs.add(interactionId);
2387
- try {
2388
- return await this._runConnectorCall(
2389
- effectiveConnectId,
2390
- method,
2391
- params,
2392
- signal,
2393
- fingerprint,
2394
- permissionDeviceId,
2395
- commonParams,
2396
- installContext ?? {},
2397
- interactionId
2398
- );
2399
- } catch (error) {
2400
- this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
2401
- throw error;
2402
- } finally {
2403
- if (interactionId) {
2404
- this._activeInteractionJobs.delete(interactionId);
2405
- if (this._pendingInteractionDisconnects.delete(interactionId)) {
2406
- await this._releaseLostInteractionConnection(interactionId);
2407
- }
2408
- }
2409
- }
2410
- },
1817
+ async (signal) => this._runConnectorCall(
1818
+ connectId,
1819
+ method,
1820
+ params,
1821
+ signal,
1822
+ fingerprint,
1823
+ permissionDeviceId,
1824
+ commonParams,
1825
+ installContext
1826
+ ),
2411
1827
  {
2412
1828
  label: method,
2413
1829
  rejectIfBusy: true,
@@ -2428,8 +1844,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2428
1844
  }
2429
1845
  });
2430
1846
  throw err;
2431
- } finally {
2432
- releaseInteractionRetention?.();
2433
1847
  }
2434
1848
  }
2435
1849
  /**
@@ -2439,7 +1853,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2439
1853
  _abortable(signal, promise) {
2440
1854
  const getAbortReason = () => signal.reason ?? this._lastCancelReason ?? new Error("Aborted");
2441
1855
  if (signal.aborted) {
2442
- void promise.catch(() => void 0);
2443
1856
  return Promise.reject(getAbortReason());
2444
1857
  }
2445
1858
  return new Promise((resolve, reject) => {
@@ -2466,15 +1879,13 @@ var _LedgerAdapter = class _LedgerAdapter {
2466
1879
  }
2467
1880
  }
2468
1881
  /** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
2469
- async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext, interactionId, lockedRetryBudget = _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET) {
1882
+ async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext) {
2470
1883
  _LedgerAdapter._throwIfAborted(signal);
2471
- if (!interactionId) {
2472
- await this._ensureDevicePermission(
2473
- connectId,
2474
- permissionDeviceId ?? fingerprint?.deviceId,
2475
- signal
2476
- );
2477
- }
1884
+ await this._ensureDevicePermission(
1885
+ connectId,
1886
+ permissionDeviceId ?? fingerprint?.deviceId,
1887
+ signal
1888
+ );
2478
1889
  _LedgerAdapter._throwIfAborted(signal);
2479
1890
  let effectiveParams = params;
2480
1891
  if (method === "btcGetPublicKey") {
@@ -2488,133 +1899,36 @@ var _LedgerAdapter = class _LedgerAdapter {
2488
1899
  effectiveParams = gatedParams;
2489
1900
  }
2490
1901
  const allowUsbEphemeralFallback = !!fingerprint?.deviceId && !fingerprint.skipFingerprint;
2491
- let businessCallStarted = false;
2492
- const verifiedBleTarget = connectId ? this._verifiedBleReconnectTargets.get(connectId) : void 0;
2493
- const knownTransport = this._isBleConnection() ? "ble" : "usb";
2494
- const hintedConnectId = commonParams?.knownConnections?.find(
2495
- (connection) => connection.transport === knownTransport
2496
- );
2497
- const inputConnectId = hintedConnectId && hintedConnectId.transport !== "qr" ? hintedConnectId.connectId : connectId;
2498
- const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && verifiedBleTarget?.chain === fingerprint.chain && verifiedBleTarget.fingerprint === fingerprint.deviceId ? verifiedBleTarget.connectId : inputConnectId;
2499
- const connectionAttempt = { ...commonParams };
2500
- const bundleConnection = installContext?.connection;
2501
- if (bundleConnection && this._sessions.get(bundleConnection.connectId) !== bundleConnection.sessionId) {
2502
- throw (0, import_hwk_adapter_core3.createHwkError)({
2503
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
2504
- message: "Ledger all-network connection ended"
2505
- });
2506
- }
2507
- let resolvedConnectId = interactionId ? this._interactions.resolve(interactionId).connectId : bundleConnection?.connectId ?? await this.ensureConnected(
2508
- preferredConnectId,
1902
+ const resolvedConnectId = await this.ensureConnected(
1903
+ connectId,
2509
1904
  signal,
2510
- allowUsbEphemeralFallback,
2511
- void 0,
2512
- connectionAttempt
1905
+ allowUsbEphemeralFallback
2513
1906
  );
2514
- let sessionId = this._sessions.get(resolvedConnectId);
2515
- if (sessionId && installContext && !installContext.connection) {
2516
- installContext.connection = { connectId: resolvedConnectId, sessionId };
2517
- }
1907
+ const sessionId = this._sessions.get(resolvedConnectId);
2518
1908
  if (!sessionId) {
2519
- if (interactionId) {
2520
- this._interactions.end(interactionId, "disconnect");
2521
- throw (0, import_hwk_adapter_core3.createHwkError)({
2522
- code: import_hwk_adapter_core3.HardwareErrorCode.InteractionEnded,
2523
- message: "Ledger interaction connection is no longer active",
2524
- params: { interactionId, reason: "disconnect" }
2525
- });
2526
- }
2527
1909
  throw Object.assign(new Error("Auto-connect succeeded but no session found"), {
2528
1910
  _tag: ERROR_TAG.DeviceSessionNotFound
2529
1911
  });
2530
1912
  }
2531
1913
  try {
2532
1914
  if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2533
- for (; ; ) {
2534
- const fp = await this._abortable(
2535
- signal,
2536
- this._verifyDeviceFingerprintWithSession(
2537
- sessionId,
2538
- fingerprint.deviceId,
2539
- fingerprint.chain
2540
- )
2541
- );
2542
- if (fp.success) break;
2543
- const binding = interactionId ? this._pendingInteractionBindings.get(interactionId) : connectionAttempt;
2544
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== resolvedConnectId) {
2545
- throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2546
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2547
- });
2548
- }
2549
- binding.rejectedConnectIds ?? (binding.rejectedConnectIds = /* @__PURE__ */ new Set());
2550
- binding.rejectedConnectIds.add(resolvedConnectId);
2551
- binding.rejectedConnectId = resolvedConnectId;
2552
- this._sessions.delete(resolvedConnectId);
2553
- await this.connector.disconnect(sessionId);
2554
- if (interactionId) this._pendingInteractionDisconnects.delete(interactionId);
2555
- _LedgerAdapter._throwIfAborted(signal);
2556
- resolvedConnectId = await this._connectFirstOrSelect(
2557
- [],
2558
- void 0,
2559
- true,
2560
- interactionId,
2561
- binding,
2562
- signal
2563
- );
2564
- const selectedSession = this._sessions.get(resolvedConnectId);
2565
- const selectedDevice = this._discoveredDevices.get(resolvedConnectId);
2566
- if (!selectedSession || !selectedDevice)
2567
- throw (0, import_hwk_adapter_core3.createHwkError)({
2568
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
2569
- message: "Selected Ledger connection ended"
2570
- });
2571
- sessionId = selectedSession;
2572
- if (interactionId)
2573
- this._interactions.rebind(interactionId, {
2574
- connectId: resolvedConnectId,
2575
- device: selectedDevice,
2576
- connectionKeys: [sessionId]
2577
- });
2578
- if (installContext)
2579
- installContext.connection = { connectId: resolvedConnectId, sessionId };
2580
- }
2581
- if (!interactionId && connectionAttempt.selectedConnection?.connectId === resolvedConnectId && this._isBleConnection()) {
2582
- this._verifiedBleReconnectTargets.set(connectId, {
2583
- connectId: resolvedConnectId,
2584
- chain: fingerprint.chain,
2585
- fingerprint: fingerprint.deviceId
1915
+ const fp = await this._abortable(
1916
+ signal,
1917
+ this._verifyDeviceFingerprintWithSession(
1918
+ sessionId,
1919
+ fingerprint.deviceId,
1920
+ fingerprint.chain
1921
+ )
1922
+ );
1923
+ if (!fp.success) {
1924
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
1925
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2586
1926
  });
2587
1927
  }
2588
- await this._publishVerifiedBleBinding(
2589
- resolvedConnectId,
2590
- fingerprint.chain,
2591
- fingerprint.deviceId,
2592
- connectionAttempt,
2593
- interactionId,
2594
- connectId,
2595
- signal
2596
- );
2597
1928
  }
2598
- businessCallStarted = true;
2599
1929
  return await this._callConnector(sessionId, method, effectiveParams, signal);
2600
1930
  } catch (err) {
2601
1931
  if (signal.aborted) throw err;
2602
- if (isDeviceDisconnectedError(err) || isDeviceNotAdvertisingError(err) || isTimeoutError(err) || isConnectionLevelError(err)) {
2603
- this._discoveredDevices.delete(resolvedConnectId);
2604
- if (interactionId) await this._releaseLostInteractionConnection(interactionId);
2605
- else {
2606
- this._sessions.delete(resolvedConnectId);
2607
- await this.connector.disconnect(sessionId).catch(() => void 0);
2608
- }
2609
- const ambiguous = businessCallStarted && !(0, import_hwk_adapter_core3.canReplayHardwareMethodAfterTransportFailure)(method);
2610
- const interactionParams = interactionId ? { interactionId, reason: "disconnect" } : void 0;
2611
- throw (0, import_hwk_adapter_core3.createHwkError)({
2612
- code: interactionId ? import_hwk_adapter_core3.HardwareErrorCode.InteractionEnded : mapLedgerError(err).code,
2613
- message: "Ledger operation connection was lost; start a new operation",
2614
- params: ambiguous ? (0, import_hwk_adapter_core3.operationMayHaveCompletedParams)(method, { interactionId }) : interactionParams,
2615
- recovery: ambiguous ? { scope: "unknown" } : void 0
2616
- });
2617
- }
2618
1932
  const errObj = err;
2619
1933
  debugLog("[LedgerAdapter] connectorCall error:", method, {
2620
1934
  message: errObj?.message,
@@ -2626,65 +1940,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2626
1940
  isNotAdvertising: isDeviceNotAdvertisingError(err),
2627
1941
  isStuckApp: isStuckAppStateError(err)
2628
1942
  });
2629
- if ((isDeviceLockedError(err) || errObj?.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceLocked) && lockedRetryBudget > 0) {
2630
- await this._waitForDeviceConnect(signal);
2631
- if (this._sessions.get(resolvedConnectId) !== sessionId) {
2632
- throw (0, import_hwk_adapter_core3.createHwkError)({
2633
- code: interactionId ? import_hwk_adapter_core3.HardwareErrorCode.InteractionEnded : import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
2634
- message: "Ledger connection ended while waiting for unlock"
2635
- });
2636
- }
2637
- return this._runConnectorCall(
2638
- resolvedConnectId,
2639
- method,
2640
- effectiveParams,
2641
- signal,
2642
- fingerprint,
2643
- permissionDeviceId,
2644
- commonParams,
2645
- installContext,
2646
- interactionId,
2647
- lockedRetryBudget - 1
2648
- );
2649
- }
2650
- if (businessCallStarted && isStuckAppStateError(err)) {
2651
- await this._sleepAbortable(_LedgerAdapter.STUCK_APP_RETRY_DELAY_MS, signal);
2652
- if (this._sessions.get(resolvedConnectId) !== sessionId) {
2653
- throw (0, import_hwk_adapter_core3.createHwkError)({
2654
- code: interactionId ? import_hwk_adapter_core3.HardwareErrorCode.InteractionEnded : import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
2655
- message: "Ledger connection ended during the app transition"
2656
- });
2657
- }
2658
- try {
2659
- return await this._callConnector(sessionId, method, effectiveParams, signal);
2660
- } catch (retryErr) {
2661
- if (isStuckAppStateError(retryErr)) throw err;
2662
- if (isDeviceDisconnectedError(retryErr) || isDeviceNotAdvertisingError(retryErr) || isTimeoutError(retryErr) || isConnectionLevelError(retryErr)) {
2663
- if (interactionId) await this._releaseLostInteractionConnection(interactionId);
2664
- else {
2665
- this._sessions.delete(resolvedConnectId);
2666
- this._discoveredDevices.delete(resolvedConnectId);
2667
- await this.connector.disconnect(sessionId).catch(() => void 0);
2668
- }
2669
- throw (0, import_hwk_adapter_core3.createHwkError)({
2670
- code: interactionId ? import_hwk_adapter_core3.HardwareErrorCode.InteractionEnded : mapLedgerError(retryErr).code,
2671
- message: `Ledger ${method} may have completed before the connection was lost`,
2672
- params: !(0, import_hwk_adapter_core3.canReplayHardwareMethodAfterTransportFailure)(method) ? (0, import_hwk_adapter_core3.operationMayHaveCompletedParams)(method, {
2673
- interactionId,
2674
- reason: "disconnect"
2675
- }) : { interactionId, reason: "disconnect" },
2676
- recovery: !(0, import_hwk_adapter_core3.canReplayHardwareMethodAfterTransportFailure)(method) ? { scope: "unknown" } : void 0
2677
- });
2678
- }
2679
- throw retryErr;
2680
- }
2681
- }
2682
- if (!interactionId && err?.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch) {
2683
- this._sessions.delete(resolvedConnectId);
2684
- this._discoveredDevices.delete(resolvedConnectId);
2685
- await this.connector.disconnect(sessionId).catch(() => void 0);
2686
- throw err;
2687
- }
2688
1943
  const autoInstallApp = commonParams?.autoInstallApp ?? this._defaultAutoInstallApp;
2689
1944
  const isAppMissing = isAppNotInstalledError(err) || err?.code === import_hwk_adapter_core3.HardwareErrorCode.AppNotInstalled;
2690
1945
  if (autoInstallApp && isAppMissing) {
@@ -2740,14 +1995,157 @@ var _LedgerAdapter = class _LedgerAdapter {
2740
1995
  fingerprint,
2741
1996
  permissionDeviceId,
2742
1997
  commonParams,
2743
- installContext,
2744
- interactionId
1998
+ installContext
1999
+ );
2000
+ }
2001
+ }
2002
+ if (isStuckAppStateError(err)) {
2003
+ try {
2004
+ this._sessions.delete(resolvedConnectId);
2005
+ this._discoveredDevices.delete(resolvedConnectId);
2006
+ this.connector.reset?.();
2007
+ } catch {
2008
+ }
2009
+ debugLog(
2010
+ "[LedgerAdapter] stuck-app retry: method=",
2011
+ method,
2012
+ "delayMs=",
2013
+ _LedgerAdapter.STUCK_APP_RETRY_DELAY_MS,
2014
+ "_tag=",
2015
+ err?._tag
2016
+ );
2017
+ try {
2018
+ const retryResult = await this._retryAfterStuckApp(
2019
+ resolvedConnectId,
2020
+ method,
2021
+ effectiveParams,
2022
+ signal,
2023
+ err,
2024
+ fingerprint
2025
+ );
2026
+ debugLog("[LedgerAdapter] stuck-app retry succeeded: method=", method);
2027
+ return retryResult;
2028
+ } catch (retryErr) {
2029
+ if (signal.aborted) throw retryErr;
2030
+ if (isStuckAppStateError(retryErr)) {
2031
+ debugLog("[LedgerAdapter] stuck-app retry exhausted (2nd 6901): method=", method);
2032
+ throw err;
2033
+ }
2034
+ debugLog(
2035
+ "[LedgerAdapter] stuck-app retry threw non-stuck error: method=",
2036
+ method,
2037
+ "retryErrTag=",
2038
+ retryErr?._tag
2745
2039
  );
2040
+ throw retryErr;
2746
2041
  }
2747
2042
  }
2043
+ if (isDeviceLockedError(err) || isDeviceNotAdvertisingError(err) || isDeviceDisconnectedError(err)) {
2044
+ let lastErr = err;
2045
+ for (let attempt = 0; attempt < _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET; attempt += 1) {
2046
+ if (signal.aborted) throw lastErr;
2047
+ try {
2048
+ this._sessions.delete(resolvedConnectId);
2049
+ this._discoveredDevices.delete(resolvedConnectId);
2050
+ if (isDeviceDisconnectedError(lastErr)) {
2051
+ try {
2052
+ this.connector.reset?.();
2053
+ } catch {
2054
+ }
2055
+ }
2056
+ const reConnectId = await this.ensureConnected(
2057
+ resolvedConnectId,
2058
+ signal,
2059
+ allowUsbEphemeralFallback
2060
+ );
2061
+ const reSessionId = this._sessions.get(reConnectId);
2062
+ if (!reSessionId) throw lastErr;
2063
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2064
+ const fp = await this._abortable(
2065
+ signal,
2066
+ this._verifyDeviceFingerprintWithSession(
2067
+ reSessionId,
2068
+ fingerprint.deviceId,
2069
+ fingerprint.chain
2070
+ )
2071
+ );
2072
+ if (!fp.success) {
2073
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2074
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2075
+ });
2076
+ }
2077
+ }
2078
+ return await this._callConnector(reSessionId, method, effectiveParams, signal);
2079
+ } catch (retryErr) {
2080
+ if (signal.aborted) throw retryErr;
2081
+ lastErr = retryErr;
2082
+ const canRetry = attempt < _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET - 1 && (isDeviceLockedError(retryErr) || isDeviceNotAdvertisingError(retryErr) || isDeviceDisconnectedError(retryErr));
2083
+ if (!canRetry) {
2084
+ throw retryErr;
2085
+ }
2086
+ }
2087
+ }
2088
+ throw lastErr;
2089
+ }
2090
+ if (isTimeoutError(err)) {
2091
+ debugLog("[LedgerAdapter] timeout, retrying with fresh connection...");
2092
+ this._discoveredDevices.delete(resolvedConnectId);
2093
+ return this._retryWithFreshConnection(
2094
+ resolvedConnectId,
2095
+ method,
2096
+ effectiveParams,
2097
+ signal,
2098
+ err,
2099
+ fingerprint
2100
+ );
2101
+ }
2102
+ if (isConnectionLevelError(err)) {
2103
+ debugLog("[LedgerAdapter] connection-level fail-closed reset");
2104
+ this._sessions.delete(resolvedConnectId);
2105
+ this._discoveredDevices.delete(resolvedConnectId);
2106
+ this.connector.reset();
2107
+ const codeNum = err?.code;
2108
+ throw Object.assign(err, {
2109
+ code: codeNum ?? import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected
2110
+ });
2111
+ }
2748
2112
  throw err;
2749
2113
  }
2750
2114
  }
2115
+ /**
2116
+ * Stuck-app recovery: pause for the device's UI transition, then retry once.
2117
+ *
2118
+ * Caller has already cleared the session + reset connector. We wait so Stax
2119
+ * finishes its post-CloseApp animation, then go through ensureConnected +
2120
+ * fingerprint check + call exactly once. Caller decides what to do on a
2121
+ * second stuck-app hit.
2122
+ */
2123
+ async _retryAfterStuckApp(resolvedConnectId, method, params, signal, originalErr, fingerprint) {
2124
+ await this._sleepAbortable(_LedgerAdapter.STUCK_APP_RETRY_DELAY_MS, signal);
2125
+ const retryConnectId = await this.ensureConnected(
2126
+ resolvedConnectId,
2127
+ signal,
2128
+ !!fingerprint?.deviceId && !fingerprint.skipFingerprint
2129
+ );
2130
+ const retrySessionId = this._sessions.get(retryConnectId);
2131
+ if (!retrySessionId) throw originalErr;
2132
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2133
+ const fp = await this._abortable(
2134
+ signal,
2135
+ this._verifyDeviceFingerprintWithSession(
2136
+ retrySessionId,
2137
+ fingerprint.deviceId,
2138
+ fingerprint.chain
2139
+ )
2140
+ );
2141
+ if (!fp.success) {
2142
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2143
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2144
+ });
2145
+ }
2146
+ }
2147
+ return this._callConnector(retrySessionId, method, params, signal);
2148
+ }
2751
2149
  _sleepAbortable(ms, signal) {
2752
2150
  return new Promise((resolve, reject) => {
2753
2151
  if (signal.aborted) {
@@ -2765,6 +2163,88 @@ var _LedgerAdapter = class _LedgerAdapter {
2765
2163
  signal.addEventListener("abort", onAbort, { once: true });
2766
2164
  });
2767
2165
  }
2166
+ /**
2167
+ * Clear stale session, reconnect, and retry the call.
2168
+ *
2169
+ * Timeout recovery starts with a full connector reset. After an APDU
2170
+ * timeout, DMK/transport state may still emit malformed responses; retrying
2171
+ * on the same DMK can poison the next chain switch.
2172
+ */
2173
+ async _retryWithFreshConnection(targetConnectId, method, params, signal, originalErr, fingerprint) {
2174
+ this.connector.reset();
2175
+ this._sessions.clear();
2176
+ this._discoveredDevices.clear();
2177
+ this._connectingPromise = null;
2178
+ const allowUsbEphemeralFallback = !!fingerprint?.deviceId && !fingerprint.skipFingerprint;
2179
+ const retryConnectId = await this.ensureConnected(
2180
+ targetConnectId,
2181
+ signal,
2182
+ allowUsbEphemeralFallback
2183
+ );
2184
+ const retrySessionId = this._sessions.get(retryConnectId);
2185
+ if (!retrySessionId) {
2186
+ throw originalErr;
2187
+ }
2188
+ try {
2189
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2190
+ const fp = await this._abortable(
2191
+ signal,
2192
+ this._verifyDeviceFingerprintWithSession(
2193
+ retrySessionId,
2194
+ fingerprint.deviceId,
2195
+ fingerprint.chain
2196
+ )
2197
+ );
2198
+ if (!fp.success) {
2199
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2200
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2201
+ });
2202
+ }
2203
+ }
2204
+ return await this._callConnector(retrySessionId, method, params, signal);
2205
+ } catch (retryErr) {
2206
+ if (signal.aborted) throw retryErr;
2207
+ this.connector.reset();
2208
+ this._sessions.clear();
2209
+ this._discoveredDevices.clear();
2210
+ this._connectingPromise = null;
2211
+ if (!isDeviceDisconnectedError(retryErr) && !isTimeoutError(retryErr)) {
2212
+ throw retryErr;
2213
+ }
2214
+ debugLog(
2215
+ "[LedgerAdapter] fresh-session retry still failed; resetting connector and rebuilding DMK"
2216
+ );
2217
+ this.connector.reset();
2218
+ this._sessions.clear();
2219
+ this._discoveredDevices.clear();
2220
+ this._connectingPromise = null;
2221
+ const finalConnectId = await this.ensureConnected(
2222
+ targetConnectId,
2223
+ signal,
2224
+ allowUsbEphemeralFallback
2225
+ );
2226
+ const finalSessionId = this._sessions.get(finalConnectId);
2227
+ if (!finalSessionId) {
2228
+ throw originalErr;
2229
+ }
2230
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2231
+ const fp = await this._abortable(
2232
+ signal,
2233
+ this._verifyDeviceFingerprintWithSession(
2234
+ finalSessionId,
2235
+ fingerprint.deviceId,
2236
+ fingerprint.chain
2237
+ )
2238
+ );
2239
+ if (!fp.success) {
2240
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2241
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2242
+ });
2243
+ }
2244
+ }
2245
+ return this._callConnector(finalSessionId, method, params, signal);
2246
+ }
2247
+ }
2768
2248
  /**
2769
2249
  * Ensure OS-level device permission (Bluetooth / USB) before proceeding.
2770
2250
  *
@@ -2834,15 +2314,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2834
2314
  if (err && typeof err === "object" && "code" in err && typeof err.code === "number") {
2835
2315
  const e = err;
2836
2316
  const params = e.code === import_hwk_adapter_core3.HardwareErrorCode.DevicePermissionDenied && e.reason ? { permissionDeniedReason: e.reason } : e.params;
2837
- return ledgerFailure(
2838
- e.code,
2839
- e.message ?? "Unknown error",
2840
- e.appName,
2841
- tag,
2842
- params,
2843
- void 0,
2844
- (0, import_hwk_adapter_core3.isHwkRecoveryHint)(e.recovery) ? e.recovery : void 0
2845
- );
2317
+ return ledgerFailure(e.code, e.message ?? "Unknown error", e.appName, tag, params);
2846
2318
  }
2847
2319
  const mapped = mapLedgerError(err);
2848
2320
  return ledgerFailure(mapped.code, mapped.message, mapped.appName, tag);
@@ -2869,7 +2341,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2869
2341
  deviceId: device.deviceId,
2870
2342
  connectId: device.connectId,
2871
2343
  label: device.name,
2872
- connectionType: device.connectionType ?? this.connector.connectionType,
2344
+ connectionType: this.connector.connectionType,
2873
2345
  rssi: device.rssi,
2874
2346
  isConnectable: device.isConnectable,
2875
2347
  serialNumber: device.serialNumber,
@@ -2894,7 +2366,7 @@ _LedgerAdapter.APP_INSTALL_PROGRESS_MIN_DELTA = 0.05;
2894
2366
  var LedgerAdapter = _LedgerAdapter;
2895
2367
 
2896
2368
  // src/connector/LedgerConnectorBase.ts
2897
- var import_hwk_adapter_core14 = require("@onekeyfe/hwk-adapter-core");
2369
+ var import_hwk_adapter_core13 = require("@onekeyfe/hwk-adapter-core");
2898
2370
 
2899
2371
  // src/device/LedgerDeviceManager.ts
2900
2372
  var LedgerDeviceManager = class {
@@ -3430,7 +2902,7 @@ var SignerManager = class _SignerManager {
3430
2902
  return (args) => new import_device_signer_kit_ethereum.SignerEthBuilder(args);
3431
2903
  }
3432
2904
  static _createContextModule() {
3433
- const contextModule = new import_context_module.ContextModuleBuilder({}).setChain(import_context_module.ContextModuleChainID.Ethereum).removeDefaultLoaders().build();
2905
+ const contextModule = new import_context_module.ContextModuleBuilder({}).removeDefaultLoaders().build();
3434
2906
  return _SignerManager.wrapBlindSigningReportNonBlocking(contextModule);
3435
2907
  }
3436
2908
  static wrapBlindSigningReportNonBlocking(contextModule) {
@@ -3901,7 +3373,6 @@ function _applySignaturesToPsbt(psbtHex, signatures) {
3901
3373
 
3902
3374
  // src/connector/chains/sol.ts
3903
3375
  var import_hwk_adapter_core9 = require("@onekeyfe/hwk-adapter-core");
3904
- var import_bs58 = __toESM(require("bs58"));
3905
3376
 
3906
3377
  // src/signer/SignerSol.ts
3907
3378
  var SignerSol = class {
@@ -3985,21 +3456,8 @@ async function solSignMessage(ctx, sessionId, params) {
3985
3456
  const path = normalizePath(params.path);
3986
3457
  const messageBytes = (0, import_hwk_adapter_core9.hexToBytes)(params.message);
3987
3458
  try {
3988
- if (params.messageVersion === 1) {
3989
- const preparedMessage = (0, import_hwk_adapter_core9.prepareSolanaOffchainMessageV1)({
3990
- message: messageBytes,
3991
- requiredSigners: params.requiredSigners
3992
- });
3993
- const { SignMessageVersion } = await ctx.importLedgerKit(
3994
- "@ledgerhq/device-signer-kit-solana"
3995
- );
3996
- const result2 = await solSigner.signMessage(path, preparedMessage.serializedMessage, {
3997
- version: SignMessageVersion.Raw
3998
- });
3999
- return { signature: decodeBase58Signature(result2.signature) };
4000
- }
4001
3459
  const result = await solSigner.signMessage(path, messageBytes);
4002
- return { signature: decodeBase58EnvelopeSignature(result.signature) };
3460
+ return { signature: result.signature };
4003
3461
  } catch (err) {
4004
3462
  ctx.invalidateSession(sessionId);
4005
3463
  throw ctx.wrapError(err);
@@ -4007,27 +3465,11 @@ async function solSignMessage(ctx, sessionId, params) {
4007
3465
  ctx.clearCanceller(sessionId);
4008
3466
  }
4009
3467
  }
4010
- function decodeBase58Signature(signature) {
4011
- const bytes = import_bs58.default.decode(signature);
4012
- if (bytes.length !== 64) {
4013
- throw new Error(`Ledger Solana signature must be 64 bytes, received ${bytes.length}`);
4014
- }
4015
- return (0, import_hwk_adapter_core9.bytesToHex)(bytes);
4016
- }
4017
- function decodeBase58EnvelopeSignature(envelope) {
4018
- const bytes = import_bs58.default.decode(envelope);
4019
- if (bytes.length < 65 || bytes[0] !== 1) {
4020
- throw new Error("Ledger Solana signature envelope is invalid");
4021
- }
4022
- return (0, import_hwk_adapter_core9.bytesToHex)(bytes.subarray(1, 65));
4023
- }
4024
3468
  async function _createSolSigner(ctx, sessionId) {
4025
3469
  const dmk = await ctx.getOrCreateDmk();
4026
- const { ContextModuleBuilder: ContextModuleBuilder2, ContextModuleChainID: ContextModuleChainID2 } = await ctx.importLedgerKit(
4027
- "@ledgerhq/context-module"
4028
- );
3470
+ const { ContextModuleBuilder: ContextModuleBuilder2 } = await ctx.importLedgerKit("@ledgerhq/context-module");
4029
3471
  const { SignerSolanaBuilder } = await ctx.importLedgerKit("@ledgerhq/device-signer-kit-solana");
4030
- const contextModule = new ContextModuleBuilder2({}).setChain(ContextModuleChainID2.Solana).removeDefaultLoaders().build();
3472
+ const contextModule = new ContextModuleBuilder2({}).removeDefaultLoaders().build();
4031
3473
  const sdkSigner = new SignerSolanaBuilder({ dmk, sessionId }).withContextModule(contextModule).build();
4032
3474
  const signer = new SignerSol(sdkSigner);
4033
3475
  signer.onInteraction = (interaction) => {
@@ -4043,102 +3485,21 @@ async function _createSolSigner(ctx, sessionId) {
4043
3485
  return signer;
4044
3486
  }
4045
3487
 
4046
- // src/connector/chains/zcash.ts
4047
- var import_hwk_adapter_core10 = require("@onekeyfe/hwk-adapter-core");
4048
-
4049
- // src/signer/SignerZcash.ts
4050
- var SignerZcash = class {
4051
- // eslint-disable-next-line no-useless-constructor, no-empty-function
4052
- constructor(_sdk) {
4053
- this._sdk = _sdk;
4054
- }
4055
- /** GET_VK: UFVK string (default) or raw 96-byte Orchard FVK. */
4056
- async getFullViewingKey(derivationPath, options) {
4057
- const action = this._sdk.getFullViewingKey(derivationPath, options);
4058
- return deviceActionToPromise(
4059
- action,
4060
- this.onInteraction,
4061
- void 0,
4062
- this.onRegisterCanceller
4063
- );
4064
- }
4065
- /** GET_SHIELDED_ADDRESS: single-Orchard-receiver UA for a 5-level transparent path. */
4066
- async getShieldedAddress(derivationPath, options) {
4067
- const action = this._sdk.getShieldedAddress(derivationPath, options);
4068
- return deviceActionToPromise(
4069
- action,
4070
- this.onInteraction,
4071
- void 0,
4072
- this.onRegisterCanceller
4073
- );
4074
- }
4075
- };
4076
-
4077
- // src/connector/chains/zcash.ts
4078
- async function zcashGetFullViewingKey(ctx, sessionId, params) {
4079
- const signer = await _createZcashSigner(ctx, sessionId);
4080
- const path = normalizePath(params.path);
4081
- const mode = params.mode ?? "ufvk";
4082
- try {
4083
- const result = await signer.getFullViewingKey(path, { mode });
4084
- if (result.mode === "ufvk") {
4085
- return { path: params.path, mode, ufvk: result.fullViewingKey };
4086
- }
4087
- return { path: params.path, mode, orchardFvk: (0, import_hwk_adapter_core10.bytesToHex)(result.fullViewingKey) };
4088
- } catch (err) {
4089
- ctx.invalidateSession(sessionId);
4090
- throw ctx.wrapError(err);
4091
- } finally {
4092
- ctx.clearCanceller(sessionId);
4093
- }
4094
- }
4095
- async function zcashGetShieldedAddress(ctx, sessionId, params) {
4096
- const signer = await _createZcashSigner(ctx, sessionId);
4097
- const path = normalizePath(params.path);
4098
- try {
4099
- const result = await signer.getShieldedAddress(path, {
4100
- checkOnDevice: params.showOnDevice ?? false
4101
- });
4102
- return { address: result.address, path: params.path };
4103
- } catch (err) {
4104
- ctx.invalidateSession(sessionId);
4105
- throw ctx.wrapError(err);
4106
- } finally {
4107
- ctx.clearCanceller(sessionId);
4108
- }
4109
- }
4110
- async function _createZcashSigner(ctx, sessionId) {
4111
- const dmk = await ctx.getOrCreateDmk();
4112
- const { SignerZcashBuilder } = await ctx.importLedgerKit("@ledgerhq/device-signer-kit-zcash");
4113
- const sdkSigner = new SignerZcashBuilder({ dmk, sessionId }).build();
4114
- const signer = new SignerZcash(sdkSigner);
4115
- signer.onInteraction = (interaction) => {
4116
- debugLog("[LedgerConnector] zcash.onInteraction:", interaction);
4117
- ctx.emit("ui-event", {
4118
- type: collapseSignerInteraction(interaction),
4119
- payload: { sessionId }
4120
- });
4121
- };
4122
- signer.onRegisterCanceller = (cancel) => ctx.registerCanceller(sessionId, cancel);
4123
- return signer;
4124
- }
4125
-
4126
3488
  // src/connector/chains/tron.ts
4127
- var import_hwk_adapter_core13 = require("@onekeyfe/hwk-adapter-core");
3489
+ var import_hwk_adapter_core12 = require("@onekeyfe/hwk-adapter-core");
4128
3490
  var import_hw_app_trx = __toESM(require("@ledgerhq/hw-app-trx"));
4129
3491
 
4130
3492
  // src/connector/chains/legacyChainCall.ts
4131
- var import_hwk_adapter_core12 = require("@onekeyfe/hwk-adapter-core");
3493
+ var import_hwk_adapter_core11 = require("@onekeyfe/hwk-adapter-core");
4132
3494
 
4133
3495
  // src/app/AppManager.ts
4134
3496
  var import_device_management_kit2 = require("@ledgerhq/device-management-kit");
4135
- var import_hwk_adapter_core11 = require("@onekeyfe/hwk-adapter-core");
3497
+ var import_hwk_adapter_core10 = require("@onekeyfe/hwk-adapter-core");
4136
3498
  var APP_NAME_MAP = {
4137
3499
  ETH: "Ethereum",
4138
3500
  BTC: "Bitcoin",
4139
3501
  SOL: "Solana",
4140
3502
  TRX: "Tron",
4141
- ZEC: "Zcash",
4142
3503
  XRP: "XRP",
4143
3504
  ADA: "Cardano",
4144
3505
  DOT: "Polkadot",
@@ -4250,9 +3611,9 @@ var AppManager = class {
4250
3611
  );
4251
3612
  let code;
4252
3613
  if (errorCode === "6807" || /unknown application/i.test(message)) {
4253
- code = import_hwk_adapter_core11.HardwareErrorCode.AppNotInstalled;
3614
+ code = import_hwk_adapter_core10.HardwareErrorCode.AppNotInstalled;
4254
3615
  } else if (errorCode === "5501" || dmkErr._tag === "ActionRefusedError") {
4255
- code = import_hwk_adapter_core11.HardwareErrorCode.UserRejected;
3616
+ code = import_hwk_adapter_core10.HardwareErrorCode.UserRejected;
4256
3617
  }
4257
3618
  throw Object.assign(new Error(`Failed to open "${appName}"`), {
4258
3619
  _tag: ERROR_TAG.OpenAppCommand,
@@ -4313,14 +3674,14 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
4313
3674
  const onAppOpenPrompt = () => {
4314
3675
  openAppPromptShown = true;
4315
3676
  ctx.emit("ui-event", {
4316
- type: import_hwk_adapter_core12.EConnectorInteraction.ConfirmOpenApp,
3677
+ type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOpenApp,
4317
3678
  payload: { sessionId }
4318
3679
  });
4319
3680
  };
4320
3681
  const closeOpenAppUiIfShown = () => {
4321
3682
  if (openAppPromptShown) {
4322
3683
  ctx.emit("ui-event", {
4323
- type: import_hwk_adapter_core12.EConnectorInteraction.InteractionComplete,
3684
+ type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
4324
3685
  payload: { sessionId }
4325
3686
  });
4326
3687
  openAppPromptShown = false;
@@ -4341,7 +3702,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
4341
3702
  let confirmEmitted = false;
4342
3703
  if (needsConfirmation) {
4343
3704
  ctx.emit("ui-event", {
4344
- type: import_hwk_adapter_core12.EConnectorInteraction.ConfirmOnDevice,
3705
+ type: import_hwk_adapter_core11.EConnectorInteraction.ConfirmOnDevice,
4345
3706
  payload: { sessionId }
4346
3707
  });
4347
3708
  confirmEmitted = true;
@@ -4351,7 +3712,7 @@ async function withLegacyChainCall(ctx, sessionId, options, action) {
4351
3712
  } finally {
4352
3713
  if (confirmEmitted || openAppPromptShown) {
4353
3714
  ctx.emit("ui-event", {
4354
- type: import_hwk_adapter_core12.EConnectorInteraction.InteractionComplete,
3715
+ type: import_hwk_adapter_core11.EConnectorInteraction.InteractionComplete,
4355
3716
  payload: { sessionId }
4356
3717
  });
4357
3718
  openAppPromptShown = false;
@@ -4439,7 +3800,7 @@ async function tronSignTransaction(ctx, sessionId, params) {
4439
3800
  if (!params.rawTxHex) {
4440
3801
  throw Object.assign(
4441
3802
  new Error("TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex)."),
4442
- { code: import_hwk_adapter_core13.HardwareErrorCode.InvalidParams }
3803
+ { code: import_hwk_adapter_core12.HardwareErrorCode.InvalidParams }
4443
3804
  );
4444
3805
  }
4445
3806
  const path = normalizePath(params.path);
@@ -4652,7 +4013,7 @@ var DeviceApps = class {
4652
4013
  seTargetId: v.seTargetId,
4653
4014
  mcuTargetId: v.mcuTargetId,
4654
4015
  seVersion: v.seVersion,
4655
- seFlagsHex: bytesToHex3(v.seFlags),
4016
+ seFlagsHex: bytesToHex2(v.seFlags),
4656
4017
  mcuSephVersion: v.mcuSephVersion,
4657
4018
  mcuBootloaderVersion: v.mcuBootloaderVersion,
4658
4019
  hwVersion: v.hwVersion
@@ -4726,7 +4087,7 @@ var DeviceApps = class {
4726
4087
  }
4727
4088
  }
4728
4089
  };
4729
- function bytesToHex3(bytes) {
4090
+ function bytesToHex2(bytes) {
4730
4091
  if (!bytes) return "";
4731
4092
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
4732
4093
  }
@@ -4769,11 +4130,10 @@ var METHOD_PREFIX_TO_APP_NAME = {
4769
4130
  evm: "Ethereum",
4770
4131
  btc: "Bitcoin",
4771
4132
  sol: "Solana",
4772
- tron: "Tron",
4773
- zcash: "Zcash"
4133
+ tron: "Tron"
4774
4134
  };
4775
4135
  var HARDWARE_ERROR_CODE_VALUES = new Set(
4776
- Object.values(import_hwk_adapter_core14.HardwareErrorCode).filter((value) => typeof value === "number")
4136
+ Object.values(import_hwk_adapter_core13.HardwareErrorCode).filter((value) => typeof value === "number")
4777
4137
  );
4778
4138
  var BLE_CONNECT_SCAN_TIMEOUT_MS = 1500;
4779
4139
  var LEDGER_RELAY_ALLOWED_ROOT_DOMAINS = ["onekeytest.com", "onekey.com"];
@@ -4810,8 +4170,6 @@ async function defaultLedgerKitImporter(pkg) {
4810
4170
  return import("@ledgerhq/device-signer-kit-bitcoin");
4811
4171
  case "@ledgerhq/device-signer-kit-solana":
4812
4172
  return import("@ledgerhq/device-signer-kit-solana");
4813
- case "@ledgerhq/device-signer-kit-zcash":
4814
- return import("@ledgerhq/device-signer-kit-zcash");
4815
4173
  case "@ledgerhq/context-module":
4816
4174
  return import("@ledgerhq/context-module");
4817
4175
  default:
@@ -4922,7 +4280,7 @@ var LedgerConnectorBase = class {
4922
4280
  async searchDevices() {
4923
4281
  const dm = await this._getDeviceManager();
4924
4282
  const descriptors = await this._discoverDescriptors(dm);
4925
- const resolvedDescriptors = descriptors.filter((d) => !(0, import_hwk_adapter_core14.isKnownNonTargetHardwareVendor)(d, "ledger")).map((d) => ({
4283
+ const resolvedDescriptors = descriptors.filter((d) => !(0, import_hwk_adapter_core13.isKnownNonTargetHardwareVendor)(d, "ledger")).map((d) => ({
4926
4284
  descriptor: d,
4927
4285
  connectId: this._resolveConnectId(d)
4928
4286
  }));
@@ -4970,7 +4328,7 @@ var LedgerConnectorBase = class {
4970
4328
  `Ledger BLE connect did not return within ${HANG_CEILING_MS / 6e4}min \u2014 DMK hang fallback.`
4971
4329
  );
4972
4330
  err._tag = ERROR_TAG.BlePairingTimeout;
4973
- err.code = import_hwk_adapter_core14.HardwareErrorCode.BlePairingTimeout;
4331
+ err.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
4974
4332
  reject(err);
4975
4333
  }, HANG_CEILING_MS);
4976
4334
  });
@@ -5003,7 +4361,7 @@ var LedgerConnectorBase = class {
5003
4361
  "Ledger device is not currently advertising. Wake up and unlock the device, keep it nearby, then try again."
5004
4362
  );
5005
4363
  err._tag = ERROR_TAG.DeviceNotAdvertising;
5006
- err.code = import_hwk_adapter_core14.HardwareErrorCode.DeviceNotFound;
4364
+ err.code = import_hwk_adapter_core13.HardwareErrorCode.DeviceNotFound;
5007
4365
  throw err;
5008
4366
  };
5009
4367
  const doConnect = async (path) => {
@@ -5067,7 +4425,7 @@ var LedgerConnectorBase = class {
5067
4425
  "Ledger Bluetooth pairing failed. Make sure the device is unlocked and nearby, then try again."
5068
4426
  );
5069
4427
  wrapped._tag = ERROR_TAG.BleGattBondingFailed;
5070
- wrapped.code = import_hwk_adapter_core14.HardwareErrorCode.BlePairingTimeout;
4428
+ wrapped.code = import_hwk_adapter_core13.HardwareErrorCode.BlePairingTimeout;
5071
4429
  wrapped.originalError = err;
5072
4430
  throw wrapped;
5073
4431
  }
@@ -5145,7 +4503,7 @@ var LedgerConnectorBase = class {
5145
4503
  this._unwatchSessionState(sessionId);
5146
4504
  this._signerManager?.invalidate(sessionId);
5147
4505
  this._cancellers.get(sessionId)?.({
5148
- code: import_hwk_adapter_core14.HardwareErrorCode.DeviceDisconnected,
4506
+ code: import_hwk_adapter_core13.HardwareErrorCode.DeviceDisconnected,
5149
4507
  tag: "DeviceDisconnected",
5150
4508
  message: "Device disconnected"
5151
4509
  });
@@ -5169,9 +4527,9 @@ var LedgerConnectorBase = class {
5169
4527
  if (isAppStuckByApdu(err)) {
5170
4528
  return {
5171
4529
  success: false,
5172
- error: (0, import_hwk_adapter_core14.serializeConnectorError)(
4530
+ error: (0, import_hwk_adapter_core13.serializeConnectorError)(
5173
4531
  Object.assign(new Error("Ledger app is unresponsive"), {
5174
- code: import_hwk_adapter_core14.HardwareErrorCode.DeviceAppStuck,
4532
+ code: import_hwk_adapter_core13.HardwareErrorCode.DeviceAppStuck,
5175
4533
  _tag: ERROR_TAG.DeviceAppStuck,
5176
4534
  originalError: err
5177
4535
  })
@@ -5181,16 +4539,16 @@ var LedgerConnectorBase = class {
5181
4539
  if (isTransportStuck(err)) {
5182
4540
  return {
5183
4541
  success: false,
5184
- error: (0, import_hwk_adapter_core14.serializeConnectorError)(
4542
+ error: (0, import_hwk_adapter_core13.serializeConnectorError)(
5185
4543
  Object.assign(new Error("Device communication interrupted, please retry"), {
5186
- code: import_hwk_adapter_core14.HardwareErrorCode.TransportError,
4544
+ code: import_hwk_adapter_core13.HardwareErrorCode.TransportError,
5187
4545
  _tag: ERROR_TAG.DeviceTransportStuck,
5188
4546
  originalError: err
5189
4547
  })
5190
4548
  )
5191
4549
  };
5192
4550
  }
5193
- return { success: false, error: (0, import_hwk_adapter_core14.serializeConnectorError)(err) };
4551
+ return { success: false, error: (0, import_hwk_adapter_core13.serializeConnectorError)(err) };
5194
4552
  }
5195
4553
  }
5196
4554
  async _dispatch(sessionId, method, params) {
@@ -5229,11 +4587,6 @@ var LedgerConnectorBase = class {
5229
4587
  return solSignTransaction(ctx, sessionId, params);
5230
4588
  case "solSignMessage":
5231
4589
  return solSignMessage(ctx, sessionId, params);
5232
- // ZCASH
5233
- case "zcashGetFullViewingKey":
5234
- return zcashGetFullViewingKey(ctx, sessionId, params);
5235
- case "zcashGetShieldedAddress":
5236
- return zcashGetShieldedAddress(ctx, sessionId, params);
5237
4590
  // TRON
5238
4591
  case "tronGetAddress":
5239
4592
  return tronGetAddress(ctx, sessionId, params);
@@ -5258,7 +4611,7 @@ var LedgerConnectorBase = class {
5258
4611
  try {
5259
4612
  return await apps.install(p.appName, ({ progress }) => {
5260
4613
  ctx.emit("ui-event", {
5261
- type: import_hwk_adapter_core14.EConnectorInteraction.AppInstallProgress,
4614
+ type: import_hwk_adapter_core13.EConnectorInteraction.AppInstallProgress,
5262
4615
  payload: {
5263
4616
  sessionId,
5264
4617
  appName: p.appName,
@@ -5563,7 +4916,7 @@ var LedgerConnectorBase = class {
5563
4916
  * at every catch site. Falls through unchanged for unknown methods.
5564
4917
  */
5565
4918
  _ctxForMethod(method) {
5566
- const prefix = /^(evm|btc|sol|tron|zcash)/.exec(method)?.[1];
4919
+ const prefix = /^(evm|btc|sol|tron)/.exec(method)?.[1];
5567
4920
  const defaultAppName = prefix ? METHOD_PREFIX_TO_APP_NAME[prefix] : void 0;
5568
4921
  if (!defaultAppName) return this._ctx;
5569
4922
  return {
@@ -5608,7 +4961,6 @@ var LedgerConnectorBase = class {
5608
4961
  SignerEth,
5609
4962
  SignerManager,
5610
4963
  SignerSol,
5611
- SignerZcash,
5612
4964
  debugLog,
5613
4965
  deviceActionToPromise,
5614
4966
  isDeviceLockedError,