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

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.mjs CHANGED
@@ -6,41 +6,30 @@ import {
6
6
  DeviceJobQueue,
7
7
  EConnectorInteraction,
8
8
  HardwareErrorCode as HardwareErrorCode3,
9
- InteractionRegistry,
10
- SDK,
11
9
  TypedEventEmitter,
12
10
  UI_REQUEST,
13
11
  UI_REQUEST_PREEMPTED_TAG,
14
12
  UiRequestRegistry,
15
- canReplayHardwareMethodAfterTransportFailure,
16
13
  createHwkError,
17
14
  deriveDeviceFingerprint,
18
15
  failure as failure2,
19
- isHardwareInteractionId,
20
- isHwkRecoveryHint,
21
- operationMayHaveCompletedParams,
22
16
  rehydrateConnectorError,
23
- requestBleDeviceSelection,
24
- requestSaveDeviceBinding,
25
- resolveSearchTargetReusePolicy,
26
17
  success
27
18
  } from "@onekeyfe/hwk-adapter-core";
28
19
 
29
20
  // src/errors.ts
30
- import {
31
- HardwareErrorCode,
32
- defaultOriginForCode,
33
- defaultRecoveryForCode,
34
- enrichErrorMessage
35
- } from "@onekeyfe/hwk-adapter-core";
36
- function ledgerFailure(code, error, appName, tag, params, origin, recovery) {
21
+ import { HardwareErrorCode, enrichErrorMessage } from "@onekeyfe/hwk-adapter-core";
22
+ var MULTIPLE_USB_LEDGER_DEVICES_ERROR_MESSAGE = "Multiple Ledger USB devices are connected. Please connect only one Ledger device and try again.";
23
+ function createMultipleUsbLedgerDevicesError() {
24
+ return Object.assign(new Error(MULTIPLE_USB_LEDGER_DEVICES_ERROR_MESSAGE), {
25
+ code: HardwareErrorCode.DeviceOneDeviceOnly
26
+ });
27
+ }
28
+ function ledgerFailure(code, error, appName, tag, params) {
37
29
  const payload = { error, code };
38
30
  if (appName !== void 0) payload.appName = appName;
39
31
  if (tag !== void 0) payload._tag = tag;
40
32
  if (params !== void 0) payload.params = params;
41
- const resolvedOrigin = origin ?? defaultOriginForCode(code);
42
- if (resolvedOrigin !== void 0) payload.origin = resolvedOrigin;
43
- payload.recovery = recovery ?? defaultRecoveryForCode(code);
44
33
  return { success: false, payload };
45
34
  }
46
35
  var LOCKED_ERROR_CODES = /* @__PURE__ */ new Set(["5515", "21781", "6982", "27010", "5303", "21251"]);
@@ -224,6 +213,7 @@ function isBlePairingFailureError(err) {
224
213
  return false;
225
214
  }
226
215
  var CONNECTION_LEVEL_TAGS = /* @__PURE__ */ new Set([
216
+ ERROR_TAG.DeviceLocked,
227
217
  ERROR_TAG.DeviceNotAdvertising,
228
218
  ERROR_TAG.BlePairingTimeout,
229
219
  ERROR_TAG.BleGattBondingFailed,
@@ -458,21 +448,11 @@ function mapLedgerError(err, opts) {
458
448
  }
459
449
  const errAppName = err && typeof err === "object" ? err.appName : void 0;
460
450
  const appName = errAppName ?? opts?.defaultAppName;
461
- return {
462
- code,
463
- message: enrichErrorMessage(code, originalMessage),
464
- origin: defaultOriginForCode(code),
465
- appName
466
- };
451
+ return { code, message: enrichErrorMessage(code, originalMessage), appName };
467
452
  }
468
453
 
469
454
  // src/adapter/methods/allNetworkGetAddress.ts
470
- import {
471
- HardwareErrorCode as HardwareErrorCode2,
472
- failure,
473
- resolveHardwareOperationTarget,
474
- runAllNetworkGetAddress
475
- } from "@onekeyfe/hwk-adapter-core";
455
+ import { HardwareErrorCode as HardwareErrorCode2, failure, runAllNetworkGetAddress } from "@onekeyfe/hwk-adapter-core";
476
456
 
477
457
  // src/utils/sdkEventBus.ts
478
458
  var listeners = /* @__PURE__ */ new Set();
@@ -529,81 +509,57 @@ var LEDGER_BTC_NETWORK_COIN_MAP = {
529
509
  var LEDGER_UNSUPPORTED_ALLNETWORK_NETWORKS = /* @__PURE__ */ new Set(["doge", "dogecoin"]);
530
510
  function createAllNetworkGetAddress({
531
511
  callChain,
532
- getChainFingerprint,
533
- retainInteraction,
534
- errorToFailure
512
+ getChainFingerprint
535
513
  }) {
536
514
  return async function allNetworkGetAddress(connectId, _deviceId, params) {
537
- debugLog("[LedgerAdapter][REQ]", {
538
- method: "allNetworkGetAddress",
539
- connectId,
540
- itemCount: params.bundle.length
541
- });
542
- const target = resolveHardwareOperationTarget(connectId, params.interactionId, "ledger");
543
- if (!target.success) return target;
544
- const effectiveTargetId = target.payload.targetId ?? "";
545
- let releaseInteractionRetention;
546
- try {
547
- releaseInteractionRetention = target.payload.interactionId ? retainInteraction(target.payload.interactionId) : void 0;
548
- } catch (error) {
549
- return errorToFailure(error);
550
- }
515
+ debugLog("[LedgerAdapter][REQ]", { method: "allNetworkGetAddress", connectId, params });
551
516
  const installContext = {};
552
517
  const commonParams = {
553
- autoInstallApp: params.autoInstallApp,
554
- interactionId: target.payload.interactionId,
555
- knownConnections: params.knownConnections,
556
- extra: params.extra,
557
- allowDeviceSelection: params.allowDeviceSelection
518
+ autoInstallApp: params.autoInstallApp
558
519
  };
559
520
  const chainFingerprints = /* @__PURE__ */ new Map();
560
- try {
561
- const result = await runAllNetworkGetAddress({
562
- connectId: effectiveTargetId,
563
- deviceId: _deviceId,
564
- params,
565
- normalizeItem: normalizeLedgerAllNetworkItem,
566
- buildUnsupportedNetworkResponse: (item) => isUnsupportedLedgerAllNetworkNetwork(item) ? buildUnsupportedNetworkResponse(item) : void 0,
567
- callItem: async ({ method, chain, item }) => {
568
- const itemDeviceId = getItemDeviceId(item) ?? chainFingerprints.get(chain) ?? "";
569
- return callAllNetworkMethod(
570
- callChain,
571
- effectiveTargetId,
572
- itemDeviceId,
573
- method,
574
- item,
575
- commonParams,
576
- installContext
577
- );
578
- },
579
- attachIdentity: async ({ item, chain, payload }) => attachLedgerIdentity(
580
- getChainFingerprint,
581
- effectiveTargetId,
521
+ const result = await runAllNetworkGetAddress({
522
+ connectId,
523
+ deviceId: _deviceId,
524
+ params,
525
+ normalizeItem: normalizeLedgerAllNetworkItem,
526
+ buildUnsupportedNetworkResponse: (item) => isUnsupportedLedgerAllNetworkNetwork(item) ? buildUnsupportedNetworkResponse(item) : void 0,
527
+ callItem: async ({ method, chain, item }) => {
528
+ const itemDeviceId = getItemDeviceId(item) ?? chainFingerprints.get(chain) ?? "";
529
+ return callAllNetworkMethod(
530
+ callChain,
531
+ connectId,
532
+ itemDeviceId,
533
+ method,
582
534
  item,
583
- chain,
584
- payload,
585
- chainFingerprints,
535
+ commonParams,
586
536
  installContext
587
- ),
588
- shouldAbortBundle: isTopLevelAllNetworkFailure,
589
- buildTopLevelFailure: (response) => {
590
- const code = response.payload?.code ?? HardwareErrorCode2.DeviceMismatch;
591
- return failure(
592
- code,
593
- response.payload?.error ?? "All-network get-address aborted",
594
- response.payload?.params
595
- );
596
- }
597
- });
598
- debugLog("[LedgerAdapter][RES]", {
599
- method: "allNetworkGetAddress",
600
- success: result.success,
601
- payload: result
602
- });
603
- return result;
604
- } finally {
605
- releaseInteractionRetention?.();
606
- }
537
+ );
538
+ },
539
+ attachIdentity: async ({ item, chain, payload }) => attachLedgerIdentity(
540
+ getChainFingerprint,
541
+ connectId,
542
+ item,
543
+ chain,
544
+ payload,
545
+ chainFingerprints
546
+ ),
547
+ shouldAbortBundle: isTopLevelAllNetworkFailure,
548
+ buildTopLevelFailure: (response) => {
549
+ const code = response.payload?.code ?? HardwareErrorCode2.DeviceMismatch;
550
+ return failure(
551
+ code,
552
+ response.payload?.error ?? "All-network get-address aborted",
553
+ response.payload?.params
554
+ );
555
+ }
556
+ });
557
+ debugLog("[LedgerAdapter][RES]", {
558
+ method: "allNetworkGetAddress",
559
+ success: result.success,
560
+ payload: result
561
+ });
562
+ return result;
607
563
  };
608
564
  }
609
565
  function isTopLevelAllNetworkFailure(response) {
@@ -611,7 +567,7 @@ function isTopLevelAllNetworkFailure(response) {
611
567
  return false;
612
568
  }
613
569
  const code = response.payload?.code;
614
- return code === HardwareErrorCode2.DeviceMismatch || code === HardwareErrorCode2.DeviceDisconnected || code === HardwareErrorCode2.OperationTimeout || code === HardwareErrorCode2.TransportError || code === HardwareErrorCode2.InteractionEnded || code === HardwareErrorCode2.InteractionNotFound || code === HardwareErrorCode2.UserAborted || code === HardwareErrorCode2.UserRejected;
570
+ return code === HardwareErrorCode2.DeviceMismatch || code === HardwareErrorCode2.UserAborted || code === HardwareErrorCode2.UserRejected;
615
571
  }
616
572
  function getItemDeviceId(item) {
617
573
  const { deviceId } = item;
@@ -641,13 +597,8 @@ function normalizeLedgerAllNetworkItem(method, item) {
641
597
  const coin = LEDGER_BTC_NETWORK_COIN_MAP[item.network];
642
598
  return coin ? { ...item, coin } : item;
643
599
  }
644
- async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain, payload, chainFingerprints, context) {
645
- const fingerprint = getItemDeviceId(item) || chainFingerprints.get(chain) || await bootstrapChainFingerprint(
646
- getChainFingerprint,
647
- context.connection?.connectId ?? connectId,
648
- chain,
649
- context
650
- );
600
+ async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain, payload, chainFingerprints) {
601
+ const fingerprint = getItemDeviceId(item) || chainFingerprints.get(chain) || await bootstrapChainFingerprint(getChainFingerprint, connectId, chain);
651
602
  if (!fingerprint) {
652
603
  return buildFingerprintBootstrapFailure(item, chain);
653
604
  }
@@ -668,8 +619,8 @@ async function attachLedgerIdentity(getChainFingerprint, connectId, item, chain,
668
619
  }
669
620
  };
670
621
  }
671
- async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain, context) {
672
- const response = await getChainFingerprint(connectId, chain, context);
622
+ async function bootstrapChainFingerprint(getChainFingerprint, connectId, chain) {
623
+ const response = await getChainFingerprint(connectId, chain);
673
624
  return response.success ? response.payload : "";
674
625
  }
675
626
  function buildFingerprintBootstrapFailure(item, chain) {
@@ -774,27 +725,8 @@ var _LedgerAdapter = class _LedgerAdapter {
774
725
  constructor(connector, options) {
775
726
  this.vendor = "ledger";
776
727
  this.emitter = new TypedEventEmitter();
777
- this._interactions = new InteractionRegistry({
778
- vendor: "ledger",
779
- onEnded: (interaction, reason) => {
780
- const binding = this._pendingInteractionBindings.get(interaction.interactionId);
781
- if (binding?.selectedConnection?.requestId === this._bindingSelectionRequestId) {
782
- this._finishBleBinding("cancelled");
783
- }
784
- this._pendingInteractionBindings.delete(interaction.interactionId);
785
- this.emitter.emit(SDK.INTERACTION_ENDED, {
786
- type: SDK.INTERACTION_ENDED,
787
- payload: { interactionId: interaction.interactionId, reason }
788
- });
789
- if (reason === "timeout") {
790
- void this._releaseInteractionConnection(interaction);
791
- }
792
- }
793
- });
794
728
  this._discoveredDevices = /* @__PURE__ */ new Map();
795
729
  this._sessions = /* @__PURE__ */ new Map();
796
- this._pendingInteractionBindings = /* @__PURE__ */ new Map();
797
- this._verifiedBleReconnectTargets = /* @__PURE__ */ new Map();
798
730
  this._uiRegistry = new UiRequestRegistry();
799
731
  // BTC App rejects account index >= 100 unless display=true. Cached per
800
732
  // adapter instance: first 100+ path asks the user once via UI request,
@@ -808,30 +740,10 @@ var _LedgerAdapter = class _LedgerAdapter {
808
740
  this._deviceAuthenticityQueueTail = Promise.resolve();
809
741
  // Shared across concurrent callers — only `cancel()` aborts.
810
742
  this._doConnectAbortController = null;
811
- this._unsettledConnectorOperations = /* @__PURE__ */ new Map();
812
- this._connectorIdleWaiters = /* @__PURE__ */ new Set();
813
- this._resetPromise = null;
814
- this._stateGeneration = 0;
815
- this._connectorTeardownTail = Promise.resolve();
816
- this._pendingConnectorTeardowns = 0;
817
- this._activeInteractionJobs = /* @__PURE__ */ new Set();
818
- this._pendingInteractionDisconnects = /* @__PURE__ */ new Set();
819
743
  this._installProgressLastEmittedValue = -Infinity;
820
744
  this.allNetworkGetAddress = createAllNetworkGetAddress({
821
745
  callChain: this.callChain.bind(this),
822
- getChainFingerprint: async (connectId, chain, context) => {
823
- try {
824
- const fingerprint = await this._computeChainFingerprint(
825
- chain,
826
- (method, params) => this.connectorCall(connectId, method, params, void 0, void 0, void 0, context)
827
- );
828
- return success(fingerprint);
829
- } catch (error) {
830
- return this.errorToFailure(error);
831
- }
832
- },
833
- retainInteraction: (interactionId) => this._interactions.retain(interactionId),
834
- errorToFailure: (error) => this.errorToFailure(error)
746
+ getChainFingerprint: (connectId, chain) => this.getChainFingerprint(connectId, "", chain)
835
747
  });
836
748
  // ---------------------------------------------------------------------------
837
749
  // Private helpers
@@ -841,7 +753,7 @@ var _LedgerAdapter = class _LedgerAdapter {
841
753
  *
842
754
  * - If a session already exists for the given connectId, reuse it.
843
755
  * - If ANY session exists (Ledger IDs are ephemeral), reuse it.
844
- * - Otherwise: search → one USB device auto-connects; multiple asks the host to choose.
756
+ * - Otherwise: search → exactly 1 USB device auto-connects; multiple or none throws.
845
757
  */
846
758
  // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections
847
759
  this._connectingPromise = null;
@@ -858,12 +770,6 @@ var _LedgerAdapter = class _LedgerAdapter {
858
770
  });
859
771
  };
860
772
  this.deviceDisconnectHandler = (data) => {
861
- const activeInteraction = this._interactions.findActiveByConnectionKey(data.connectId);
862
- if (activeInteraction && this._activeInteractionJobs.has(activeInteraction.interactionId)) {
863
- this._pendingInteractionDisconnects.add(activeInteraction.interactionId);
864
- } else {
865
- this._interactions.endByConnectionKey(data.connectId, "disconnect");
866
- }
867
773
  this._discoveredDevices.delete(data.connectId);
868
774
  this._sessions.delete(data.connectId);
869
775
  this.emitter.emit(DEVICE.DISCONNECT, {
@@ -920,28 +826,11 @@ var _LedgerAdapter = class _LedgerAdapter {
920
826
  this._jobQueue = new DeviceJobQueue();
921
827
  this.registerEventListeners();
922
828
  }
923
- _finishBleBinding(status) {
924
- const selectionRequestId = this._bindingSelectionRequestId;
925
- this._bindingSelectionRequestId = void 0;
926
- if (selectionRequestId)
927
- this.emitter.emit(UI_REQUEST.DEVICE_BINDING_STATUS, {
928
- type: UI_REQUEST.DEVICE_BINDING_STATUS,
929
- payload: { selectionRequestId, status }
930
- });
931
- }
932
- _isBleConnection() {
933
- return isLedgerBleConnectionType(this._activeConnectionType ?? this.connector.connectionType);
934
- }
935
829
  // Transport
936
830
  get activeTransport() {
937
- return this._isBleConnection() ? "ble" : "hid";
831
+ return isLedgerBleConnectionType(this.connector.connectionType) ? "ble" : "hid";
938
832
  }
939
833
  getAvailableTransports() {
940
- if (this.connector.availableTransports) {
941
- return this.connector.availableTransports.map(
942
- (transport) => transport === "ble" ? "ble" : "hid"
943
- );
944
- }
945
834
  return this.activeTransport ? [this.activeTransport] : [];
946
835
  }
947
836
  // Connector is bound at construction; switching requires a new adapter.
@@ -958,39 +847,21 @@ var _LedgerAdapter = class _LedgerAdapter {
958
847
  * The next operation will re-discover and re-connect automatically.
959
848
  */
960
849
  resetState() {
961
- void this._resetStateAndDisconnectSessions();
962
- }
963
- _resetStateAndDisconnectSessions() {
964
- if (this._resetPromise) return this._resetPromise;
965
- const sessionIds = new Set(this._sessions.values());
966
- this._stateGeneration += 1;
967
- this._finishBleBinding("cancelled");
968
- this._interactions.endAll("runtime-reset");
969
- this._doConnectAbortController?.abort();
970
850
  this._discoveredDevices.clear();
971
851
  this._sessions.clear();
972
- this._verifiedBleReconnectTargets.clear();
973
852
  this._connectingPromise = null;
974
- this._doConnectAbortController = null;
975
853
  this._uiRegistry.reset();
976
854
  this._jobQueue.clear();
977
855
  this._btcHighIndexConfirmedThisSession = false;
978
- const resetPromise = this._runConnectorTeardown(async () => {
979
- for (const sessionId of sessionIds) {
980
- await this.connector.disconnect(sessionId).catch(() => void 0);
981
- }
982
- });
983
- this._resetPromise = resetPromise;
984
- return resetPromise.finally(() => {
985
- if (this._resetPromise === resetPromise) {
986
- this._resetPromise = null;
987
- }
988
- });
989
856
  }
990
857
  async dispose() {
991
- await this._resetStateAndDisconnectSessions();
858
+ this._uiRegistry.reset();
859
+ this._jobQueue.clear();
992
860
  this.unregisterEventListeners();
993
861
  this.connector.reset();
862
+ this._discoveredDevices.clear();
863
+ this._sessions.clear();
864
+ this._btcHighIndexConfirmedThisSession = false;
994
865
  this.emitter.removeAllListeners();
995
866
  }
996
867
  uiResponse(response) {
@@ -1000,32 +871,17 @@ var _LedgerAdapter = class _LedgerAdapter {
1000
871
  // Device management
1001
872
  // ---------------------------------------------------------------------------
1002
873
  async searchDevices(options) {
1003
- return this._searchDevices(options);
1004
- }
1005
- async _searchDevices(options, signal) {
1006
874
  debugLog("[LedgerAdapter][REQ]", { method: "searchDevices", params: options });
1007
875
  try {
1008
876
  if (options?.resetSession) {
1009
- await this._resetStateAndDisconnectSessions();
1010
- } else {
1011
- await this._connectorTeardownTail;
1012
- }
1013
- await this._ensureDevicePermission(void 0, void 0, signal);
1014
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1015
- const stateGeneration = this._stateGeneration;
1016
- const devices = await this.connector.searchDevices(
1017
- options?.transportType ? {
1018
- transportType: options.transportType,
1019
- waitForAll: options.waitForAllTransports
1020
- } : void 0
1021
- );
1022
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1023
- if (stateGeneration !== this._stateGeneration) {
1024
- throw createHwkError({
1025
- code: HardwareErrorCode3.UserAborted,
1026
- message: "Ledger discovery was reset"
1027
- });
877
+ this._doConnectAbortController?.abort();
878
+ this._sessions.clear();
879
+ this._connectingPromise = null;
880
+ this._doConnectAbortController = null;
881
+ this._btcHighIndexConfirmedThisSession = false;
1028
882
  }
883
+ await this._ensureDevicePermission();
884
+ const devices = await this.connector.searchDevices();
1029
885
  this._discoveredDevices.clear();
1030
886
  for (const d of devices) {
1031
887
  if (d.connectId) {
@@ -1033,7 +889,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1033
889
  }
1034
890
  }
1035
891
  if (this._discoveredDevices.size === 0) {
1036
- await this._ensureDevicePermission(void 0, void 0, signal);
892
+ await this._ensureDevicePermission();
1037
893
  }
1038
894
  const result = Array.from(this._discoveredDevices.values());
1039
895
  debugLog("[LedgerAdapter][RES]", {
@@ -1052,172 +908,41 @@ var _LedgerAdapter = class _LedgerAdapter {
1052
908
  throw err;
1053
909
  }
1054
910
  }
1055
- async searchDeviceTargets(options) {
1056
- const devices = await this.searchDevices(options);
1057
- return devices.map((device) => ({
1058
- searchTargetId: device.connectId,
1059
- searchTargetReusePolicy: resolveSearchTargetReusePolicy(device),
1060
- vendor: "ledger",
1061
- connectionType: device.connectionType,
1062
- kind: "physical",
1063
- label: device.label,
1064
- model: device.model,
1065
- modelName: device.modelName,
1066
- serialNumber: device.serialNumber
1067
- }));
1068
- }
1069
- async listConnectionTargets(options) {
1070
- const targets = await this.searchDeviceTargets(options);
1071
- return targets.map(({ searchTargetId, ...target }) => ({
1072
- ...target,
1073
- targetId: searchTargetId
1074
- }));
1075
- }
1076
911
  // USB single-session invariant: evict all sessions, best-effort (see connectDevice).
1077
- async _evictAllSessions(preserveInteractionId) {
1078
- this._interactions.endAll("explicit", preserveInteractionId);
912
+ async _evictAllSessions() {
1079
913
  if (this._sessions.size === 0) return;
1080
914
  const stale = [...this._sessions.values()];
1081
915
  this._sessions.clear();
1082
- await this._runConnectorTeardown(async () => {
1083
- for (const sid of stale) {
1084
- try {
1085
- await this.connector.disconnect(sid);
1086
- } catch {
1087
- }
916
+ for (const sid of stale) {
917
+ try {
918
+ await this.connector.disconnect(sid);
919
+ } catch {
1088
920
  }
1089
- });
921
+ }
1090
922
  }
1091
923
  static _createDeviceBusyError(method) {
1092
924
  return Object.assign(new Error(`Ledger device is busy while calling ${method}`), {
1093
925
  code: HardwareErrorCode3.DeviceBusy
1094
926
  });
1095
927
  }
1096
- async connectDevice(searchTargetId) {
1097
- const connected = await this._connectTarget(searchTargetId);
1098
- if (!connected.success) return connected;
1099
- return this._createInteraction(searchTargetId, connected.payload);
1100
- }
1101
- async acquireInteraction(connectId, context) {
1102
- try {
1103
- return await this._jobQueue.enqueue(
1104
- connectId || "__ledger_acquire__",
1105
- async (signal) => {
1106
- const transport = this._isBleConnection() ? "ble" : "usb";
1107
- const hint = context.knownConnections?.find(
1108
- (connection) => connection.transport === transport
1109
- );
1110
- const target = hint && hint.transport !== "qr" ? hint.connectId : connectId;
1111
- await this._ensureDevicePermission(target, void 0, signal);
1112
- const attempt = {
1113
- ...context,
1114
- extra: context.extra ? { ...context.extra } : void 0,
1115
- previousConnectId: target
1116
- };
1117
- try {
1118
- const resolvedConnectId = await this.ensureConnected(
1119
- target,
1120
- signal,
1121
- true,
1122
- void 0,
1123
- attempt
1124
- );
1125
- _LedgerAdapter._throwIfAborted(signal);
1126
- const result = this._createInteraction(connectId, resolvedConnectId);
1127
- if (result.success && attempt.selectedConnection) {
1128
- this._pendingInteractionBindings.set(result.payload, attempt);
1129
- }
1130
- return result;
1131
- } catch (error) {
1132
- this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
1133
- throw error;
1134
- }
1135
- },
1136
- {
1137
- label: "acquireInteraction",
1138
- rejectIfBusy: true,
1139
- busyError: _LedgerAdapter._createDeviceBusyError("acquireInteraction")
1140
- }
1141
- );
1142
- } catch (error) {
1143
- return this.errorToFailure(error);
1144
- }
1145
- }
1146
- _createInteraction(searchTargetId, resolvedConnectId) {
1147
- this._interactions.endByConnectionKey(resolvedConnectId, "explicit");
1148
- const sessionId = this._sessions.get(resolvedConnectId);
1149
- if (sessionId) this._interactions.endByConnectionKey(sessionId, "explicit");
1150
- const device = this._discoveredDevices.get(resolvedConnectId) ?? {
1151
- vendor: "ledger",
1152
- model: "unknown",
1153
- firmwareVersion: "",
1154
- deviceId: "",
1155
- connectId: resolvedConnectId,
1156
- connectionType: this.connector.connectionType
1157
- };
1158
- const interaction = this._interactions.create({
1159
- searchTargetId,
1160
- connectId: resolvedConnectId,
1161
- device,
1162
- connectionKeys: [this._sessions.get(resolvedConnectId) ?? ""]
1163
- });
1164
- return success(interaction.interactionId);
1165
- }
1166
- async _connectTarget(connectId, preserveInteractionId, signal) {
928
+ async connectDevice(connectId) {
1167
929
  debugLog("[LedgerAdapter][REQ]", { method: "connectDevice", connectId, params: { connectId } });
1168
930
  try {
1169
- this._assertConnectorReady("connectDevice");
1170
- const discoveredType = this._discoveredDevices.get(connectId)?.connectionType;
1171
- if (discoveredType === "usb" || discoveredType === "ble") {
1172
- this._activeConnectionType = discoveredType;
1173
- }
1174
- if (this._isBleConnection() && !connectId) {
931
+ if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
1175
932
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
1176
933
  code: HardwareErrorCode3.DeviceNotFound
1177
934
  });
1178
935
  }
1179
- await this._ensureDevicePermission(connectId, void 0, signal);
1180
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1181
- if (this.connector.availableTransports && this.connector.availableTransports.length > 1) {
1182
- await this._evictAllSessions(preserveInteractionId);
1183
- } else if (this._isBleConnection()) {
1184
- const previousSessionId = this._sessions.get(connectId);
1185
- this._interactions.endByConnectionKey(connectId, "explicit", preserveInteractionId);
1186
- if (previousSessionId) {
1187
- this._interactions.endByConnectionKey(
1188
- previousSessionId,
1189
- "explicit",
1190
- preserveInteractionId
1191
- );
1192
- this._sessions.delete(connectId);
1193
- await this.connector.disconnect(previousSessionId).catch(() => void 0);
1194
- }
1195
- } else {
1196
- await this._evictAllSessions(preserveInteractionId);
1197
- }
1198
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1199
- const stateGeneration = this._stateGeneration;
1200
- const releaseOperation = this._retainConnectorOperation(`connect:${connectId}`);
1201
- let session;
1202
- try {
1203
- session = this.connector.availableTransports?.length ? await this.connector.connect(connectId, {
1204
- transportType: this._activeConnectionType ?? "usb"
1205
- }) : await this.connector.connect(connectId);
1206
- if (signal?.aborted || stateGeneration !== this._stateGeneration) {
1207
- await this.connector.disconnect(session.sessionId).catch(() => void 0);
1208
- throw Object.assign(new Error("Ledger connection aborted"), {
1209
- code: HardwareErrorCode3.UserAborted
1210
- });
1211
- }
1212
- } finally {
1213
- releaseOperation();
936
+ if (!isLedgerBleConnectionType(this.connector.connectionType)) {
937
+ await this._evictAllSessions();
1214
938
  }
1215
- const resolvedConnectId = session.deviceInfo?.connectId || connectId;
1216
- this._sessions.set(resolvedConnectId, session.sessionId);
939
+ await this._ensureDevicePermission(connectId);
940
+ const session = await this.connector.connect(connectId);
941
+ this._sessions.set(connectId, session.sessionId);
1217
942
  if (session.deviceInfo) {
1218
- this._discoveredDevices.set(resolvedConnectId, session.deviceInfo);
943
+ this._discoveredDevices.set(connectId, session.deviceInfo);
1219
944
  }
1220
- const result = success(resolvedConnectId);
945
+ const result = success(connectId);
1221
946
  debugLog("[LedgerAdapter][RES]", { method: "connectDevice", success: true, payload: result });
1222
947
  return result;
1223
948
  } catch (err) {
@@ -1230,60 +955,30 @@ var _LedgerAdapter = class _LedgerAdapter {
1230
955
  return failureResult;
1231
956
  }
1232
957
  }
1233
- async releaseInteraction(interactionId) {
1234
- const interaction = this._interactions.find(interactionId);
1235
- if (!interaction) {
1236
- this._interactions.resolve(interactionId);
1237
- return;
1238
- }
1239
- const endedInteraction = this._interactions.end(interactionId, "explicit");
1240
- if (!endedInteraction) return;
1241
- const { connectId } = interaction;
958
+ async disconnectDevice(connectId) {
1242
959
  debugLog("[LedgerAdapter][REQ]", {
1243
- method: "releaseInteraction",
960
+ method: "disconnectDevice",
1244
961
  connectId,
1245
962
  params: { connectId }
1246
963
  });
1247
964
  try {
1248
- await this._releaseInteractionConnection(endedInteraction);
1249
- debugLog("[LedgerAdapter][RES]", { method: "releaseInteraction", success: true });
965
+ const sessionId = this._sessions.get(connectId);
966
+ if (sessionId) {
967
+ await this.connector.disconnect(sessionId);
968
+ this._sessions.delete(connectId);
969
+ }
970
+ debugLog("[LedgerAdapter][RES]", { method: "disconnectDevice", success: true });
1250
971
  } catch (err) {
1251
972
  const e = err;
1252
973
  debugLog("[LedgerAdapter][RES]", {
1253
- method: "releaseInteraction",
974
+ method: "disconnectDevice",
1254
975
  success: false,
1255
976
  error: { message: e?.message, _tag: e?._tag, code: e?.code ?? e?.errorCode }
1256
977
  });
1257
978
  throw err;
1258
979
  }
1259
980
  }
1260
- async _releaseInteractionConnection(interaction) {
1261
- const sessionIds = /* @__PURE__ */ new Set();
1262
- for (const [connectId, sessionId] of this._sessions) {
1263
- if (connectId === interaction.connectId || interaction.connectionKeys.includes(connectId) || interaction.connectionKeys.includes(sessionId)) {
1264
- this._sessions.delete(connectId);
1265
- sessionIds.add(sessionId);
1266
- }
1267
- }
1268
- for (const sessionId of sessionIds) {
1269
- await this._runConnectorTeardown(
1270
- () => this.connector.disconnect(sessionId).catch(() => void 0)
1271
- );
1272
- }
1273
- }
1274
- async _releaseLostInteractionConnection(interactionId) {
1275
- const endedInteraction = this._interactions.end(interactionId, "disconnect");
1276
- if (!endedInteraction) return;
1277
- this._discoveredDevices.delete(endedInteraction.connectId);
1278
- await this._releaseInteractionConnection(endedInteraction);
1279
- }
1280
- async getDeviceInfo(connectIdOrInteractionId, deviceId) {
1281
- let connectId;
1282
- try {
1283
- connectId = isHardwareInteractionId(connectIdOrInteractionId) ? this._interactions.resolve(connectIdOrInteractionId).connectId : connectIdOrInteractionId;
1284
- } catch (error) {
1285
- return this.errorToFailure(error);
1286
- }
981
+ async getDeviceInfo(connectId, deviceId) {
1287
982
  debugLog("[LedgerAdapter][REQ]", {
1288
983
  method: "getDeviceInfo",
1289
984
  connectId,
@@ -1322,7 +1017,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1322
1017
  }
1323
1018
  }
1324
1019
  getSupportedChains() {
1325
- return ["evm", "btc", "sol", "tron", "zcash"];
1020
+ return ["evm", "btc", "sol", "tron"];
1326
1021
  }
1327
1022
  // ---------------------------------------------------------------------------
1328
1023
  // Chain call helper
@@ -1358,21 +1053,13 @@ var _LedgerAdapter = class _LedgerAdapter {
1358
1053
  if (params && typeof params === "object") {
1359
1054
  const {
1360
1055
  autoInstallApp,
1361
- interactionId,
1362
1056
  passphraseState: _passphraseState,
1363
1057
  useEmptyPassphrase: _useEmptyPassphrase,
1364
- knownConnections,
1365
- extra,
1366
- allowDeviceSelection,
1367
1058
  ...rest
1368
1059
  } = params;
1369
1060
  return {
1370
1061
  commonParams: {
1371
- autoInstallApp: typeof autoInstallApp === "boolean" ? autoInstallApp : void 0,
1372
- interactionId: typeof interactionId === "string" ? interactionId : void 0,
1373
- knownConnections,
1374
- extra,
1375
- allowDeviceSelection: typeof allowDeviceSelection === "boolean" ? allowDeviceSelection : void 0
1062
+ autoInstallApp: typeof autoInstallApp === "boolean" ? autoInstallApp : void 0
1376
1063
  },
1377
1064
  rest
1378
1065
  };
@@ -1548,27 +1235,6 @@ var _LedgerAdapter = class _LedgerAdapter {
1548
1235
  );
1549
1236
  }
1550
1237
  // ---------------------------------------------------------------------------
1551
- // Zcash chain methods (viewing key + shielded address reads; Zcash app >= 3.8.0)
1552
- // ---------------------------------------------------------------------------
1553
- zcashGetFullViewingKey(connectId, deviceId, params) {
1554
- return this.callChainWithMergedParams(
1555
- connectId,
1556
- deviceId,
1557
- "zcash",
1558
- "zcashGetFullViewingKey",
1559
- params
1560
- );
1561
- }
1562
- zcashGetShieldedAddress(connectId, deviceId, params) {
1563
- return this.callChainWithMergedParams(
1564
- connectId,
1565
- deviceId,
1566
- "zcash",
1567
- "zcashGetShieldedAddress",
1568
- params
1569
- );
1570
- }
1571
- // ---------------------------------------------------------------------------
1572
1238
  // App management — OS-level Ledger app install / list. Bypasses fingerprint
1573
1239
  // and chain-handler dispatch; installApp progress is forwarded to the adapter
1574
1240
  // emitter via 'ui-event' AppInstallProgress events.
@@ -1657,7 +1323,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1657
1323
  );
1658
1324
  }
1659
1325
  await this.connector.configure({ ledgerGenuineCheckWebSocketUrl: relayUrl });
1660
- await this._resetStateAndDisconnectSessions();
1326
+ this.resetState();
1661
1327
  }
1662
1328
  const result = await this.connectorCall(connectId, "getDeviceGenuineCheck", {});
1663
1329
  if (!result.isGenuine) {
@@ -1683,10 +1349,10 @@ var _LedgerAdapter = class _LedgerAdapter {
1683
1349
  if (relayUrl) {
1684
1350
  try {
1685
1351
  await this.connector.configure?.({ ledgerGenuineCheckWebSocketUrl: void 0 });
1686
- await this._resetStateAndDisconnectSessions();
1352
+ this.resetState();
1687
1353
  } catch {
1688
1354
  this.connector.reset();
1689
- await this._resetStateAndDisconnectSessions();
1355
+ this.resetState();
1690
1356
  }
1691
1357
  }
1692
1358
  }
@@ -1709,36 +1375,13 @@ var _LedgerAdapter = class _LedgerAdapter {
1709
1375
  }
1710
1376
  }, 2e3);
1711
1377
  this._uiRegistry.cancel();
1712
- this._finishBleBinding("cancelled");
1713
- const activeJobId = this._jobQueue.getActiveJob()?.deviceId;
1714
- let interactionId;
1715
- if (isHardwareInteractionId(connectId)) {
1716
- interactionId = connectId;
1717
- } else if (!connectId && isHardwareInteractionId(activeJobId)) {
1718
- interactionId = activeJobId;
1719
- }
1720
- let resolvedConnectId = connectId;
1721
- if (interactionId) {
1722
- try {
1723
- resolvedConnectId = this._interactions.resolve(interactionId).connectId;
1724
- } catch {
1725
- resolvedConnectId = void 0;
1726
- }
1727
- }
1728
- const interactionForPhysicalId = !interactionId && connectId ? this._interactions.findActiveByConnectionKey(connectId) : void 0;
1729
- const queueKey = interactionId ?? (activeJobId === connectId ? connectId : interactionForPhysicalId?.interactionId) ?? connectId;
1730
- const pendingInteractionId = interactionId ?? interactionForPhysicalId?.interactionId;
1731
- if (!connectId) this._pendingInteractionBindings.clear();
1732
- else if (pendingInteractionId) {
1733
- this._pendingInteractionBindings.delete(pendingInteractionId);
1734
- }
1735
- if (queueKey) {
1736
- this._jobQueue.cancelActiveAndPending(queueKey, userAbortReason);
1378
+ if (connectId) {
1379
+ this._jobQueue.cancelActiveAndPending(connectId, userAbortReason);
1737
1380
  } else {
1738
1381
  this._jobQueue.cancelActiveAndPending(void 0, userAbortReason);
1739
1382
  }
1740
- if (resolvedConnectId) {
1741
- const sessionId = this._sessions.get(resolvedConnectId) ?? resolvedConnectId;
1383
+ if (connectId) {
1384
+ const sessionId = this._sessions.get(connectId) ?? connectId;
1742
1385
  void this.connector.cancel(sessionId);
1743
1386
  } else {
1744
1387
  for (const sid of this._sessions.values()) void this.connector.cancel(sid);
@@ -1750,83 +1393,40 @@ var _LedgerAdapter = class _LedgerAdapter {
1750
1393
  // ---------------------------------------------------------------------------
1751
1394
  // Chain fingerprint
1752
1395
  // ---------------------------------------------------------------------------
1753
- /** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
1754
1396
  async getChainFingerprint(connectId, deviceId, chain) {
1755
1397
  try {
1756
1398
  const fingerprint = await this._computeChainFingerprint(
1757
1399
  chain,
1758
1400
  (method, params) => this.connectorCall(connectId, method, params, void 0, deviceId)
1759
1401
  );
1760
- if (deviceId) {
1761
- if (fingerprint !== deviceId) {
1762
- return failure2(
1763
- HardwareErrorCode3.DeviceMismatch,
1764
- formatDeviceMismatchError(deviceId, fingerprint)
1765
- );
1766
- }
1767
- if (isHardwareInteractionId(connectId)) {
1768
- const interaction = this._interactions.resolve(connectId);
1769
- await this._publishVerifiedBleBinding(
1770
- interaction.connectId,
1771
- chain,
1772
- fingerprint,
1773
- void 0,
1774
- connectId
1775
- );
1776
- }
1777
- }
1778
1402
  return success(fingerprint);
1779
1403
  } catch (err) {
1780
1404
  debugError("[LedgerAdapter] getChainFingerprint error:", chain, err);
1781
1405
  return this.errorToFailure(err);
1782
1406
  }
1783
1407
  }
1784
- /** Discovery may select a BLE target before a later call verifies its wallet. */
1785
- async _publishVerifiedBleBinding(connectId, chain, fingerprint, attempt, interactionId, previousConnectId = "", signal) {
1786
- const binding = interactionId ? this._pendingInteractionBindings.get(interactionId) : attempt;
1787
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== connectId) return;
1788
- const acknowledged = await requestSaveDeviceBinding(
1789
- this.emitter,
1790
- this._uiRegistry,
1791
- {
1792
- selectionRequestId: binding.selectedConnection.requestId,
1793
- connection: { transport: "ble", connectId },
1794
- identity: { vendor: "ledger", type: "chainFingerprint", chain, value: fingerprint },
1795
- extra: binding.extra
1796
- },
1797
- signal
1798
- );
1799
- if (this._bindingSelectionRequestId === binding.selectedConnection.requestId) {
1800
- this._bindingSelectionRequestId = void 0;
1801
- }
1802
- if (interactionId) {
1803
- this._interactions.resolve(interactionId);
1804
- this._pendingInteractionBindings.delete(interactionId);
1805
- }
1806
- if (acknowledged) return;
1807
- this.emitter.emit(DEVICE.LEDGER_CONNECTION_VERIFIED, {
1808
- type: DEVICE.LEDGER_CONNECTION_VERIFIED,
1809
- payload: {
1810
- previousConnectId: binding.previousConnectId ?? previousConnectId,
1811
- connectId,
1812
- chain,
1813
- fingerprint,
1814
- extra: binding.extra,
1815
- selectionRequestId: binding.selectedConnection.requestId
1816
- }
1817
- });
1818
- }
1819
- /** Verify on the acquired session without re-entering the job queue. */
1408
+ /**
1409
+ * Verify fingerprint using an existing sessionId directly.
1410
+ * Safe to call inside connectorCall without causing queue deadlock.
1411
+ */
1820
1412
  async _verifyDeviceFingerprintWithSession(sessionId, deviceId, chain) {
1821
1413
  if (!deviceId) return { success: true };
1822
- const fingerprint = await this._computeChainFingerprint(
1823
- chain,
1824
- (method, params) => this._callConnector(sessionId, method, params)
1825
- );
1826
- if (fingerprint === deviceId) {
1827
- return { success: true };
1414
+ try {
1415
+ const fingerprint = await this._computeChainFingerprint(
1416
+ chain,
1417
+ (method, params) => this._callConnector(sessionId, method, params)
1418
+ );
1419
+ if (fingerprint === deviceId) {
1420
+ return { success: true };
1421
+ }
1422
+ return { success: false, expected: deviceId, actual: fingerprint };
1423
+ } catch (err) {
1424
+ const mapped = mapLedgerError(err);
1425
+ if (mapped.code === HardwareErrorCode3.WrongApp || mapped.code === HardwareErrorCode3.DeviceLocked) {
1426
+ return { success: true };
1427
+ }
1428
+ throw err;
1828
1429
  }
1829
- return { success: false, expected: deviceId, actual: fingerprint };
1830
1430
  }
1831
1431
  /**
1832
1432
  * Compute the chain fingerprint via a caller-supplied call strategy.
@@ -1855,8 +1455,6 @@ var _LedgerAdapter = class _LedgerAdapter {
1855
1455
  address = (await callMethod("solGetAddress", { path, showOnDevice: false })).address;
1856
1456
  } else if (chain === "tron") {
1857
1457
  address = (await callMethod("tronGetAddress", { path, showOnDevice: false })).address;
1858
- } else if (chain === "zcash") {
1859
- address = (await callMethod("zcashGetShieldedAddress", { path, showOnDevice: false })).address;
1860
1458
  } else {
1861
1459
  throw new Error(`Unsupported chain for fingerprint: ${chain}`);
1862
1460
  }
@@ -1986,17 +1584,16 @@ var _LedgerAdapter = class _LedgerAdapter {
1986
1584
  // Layer 1 entry. Caller signal only races the outer awaiter; the shared
1987
1585
  // `_doConnect` runs under its own internal controller so caller A's cancel
1988
1586
  // doesn't kill caller B's await.
1989
- async ensureConnected(connectId, signal, allowUsbEphemeralFallback = false, preserveInteractionId, context) {
1587
+ async ensureConnected(connectId, signal, allowUsbEphemeralFallback = false) {
1990
1588
  if (signal.aborted) _LedgerAdapter._throwIfAborted(signal);
1991
- this._assertConnectorReady("connectDevice");
1992
- if (this._isBleConnection() && !connectId && !allowUsbEphemeralFallback) {
1589
+ if (isLedgerBleConnectionType(this.connector.connectionType) && !connectId) {
1993
1590
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
1994
1591
  code: HardwareErrorCode3.DeviceNotFound
1995
1592
  });
1996
1593
  }
1997
1594
  if (connectId && this._sessions.has(connectId)) return connectId;
1998
1595
  if (!connectId && this._sessions.size > 0) {
1999
- if (!this._isBleConnection() && this._sessions.size > 1) {
1596
+ if (!isLedgerBleConnectionType(this.connector.connectionType) && this._sessions.size > 1) {
2000
1597
  throw Object.assign(
2001
1598
  new Error(
2002
1599
  "Ledger USB session invariant violated: more than one session is active. Please reconnect the device."
@@ -2006,24 +1603,15 @@ var _LedgerAdapter = class _LedgerAdapter {
2006
1603
  }
2007
1604
  return this._sessions.keys().next().value;
2008
1605
  }
2009
- if (!this._connectingPromise || this._doConnectAbortController?.signal.aborted) {
2010
- const controller = new AbortController();
2011
- this._doConnectAbortController = controller;
2012
- const innerSignal = controller.signal;
1606
+ if (!this._connectingPromise) {
1607
+ this._doConnectAbortController = new AbortController();
1608
+ const innerSignal = this._doConnectAbortController.signal;
2013
1609
  this._connectingPromise = (async () => {
2014
1610
  try {
2015
- return await this._doConnect(
2016
- innerSignal,
2017
- connectId,
2018
- allowUsbEphemeralFallback,
2019
- preserveInteractionId,
2020
- context
2021
- );
1611
+ return await this._doConnect(innerSignal, connectId, allowUsbEphemeralFallback);
2022
1612
  } finally {
2023
- if (this._doConnectAbortController === controller) {
2024
- this._connectingPromise = null;
2025
- this._doConnectAbortController = null;
2026
- }
1613
+ this._connectingPromise = null;
1614
+ this._doConnectAbortController = null;
2027
1615
  }
2028
1616
  })();
2029
1617
  }
@@ -2032,49 +1620,22 @@ var _LedgerAdapter = class _LedgerAdapter {
2032
1620
  // Layer 1 main loop — the ONLY place in SDK that emits unlock dialog.
2033
1621
  // Bounded by MAX_DOCONNECT_CONFIRMS — after N Confirms with no progress,
2034
1622
  // throw DeviceNotFound so the user is kicked out of the loop.
2035
- async _doConnect(internalSignal, targetConnectId, allowUsbEphemeralFallback = false, preserveInteractionId, context) {
2036
- _LedgerAdapter._throwIfAborted(internalSignal);
2037
- if (this.connector.availableTransports?.includes("usb") && this.connector.availableTransports.includes("ble")) {
2038
- this._activeConnectionType = "usb";
2039
- const usbDevices = await this._searchDevices({ transportType: "usb" }, internalSignal);
2040
- _LedgerAdapter._throwIfAborted(internalSignal);
2041
- if (usbDevices.length > 0) {
2042
- const knownUsb = context?.knownConnections?.find(
2043
- (connection) => connection.transport === "usb"
2044
- );
2045
- const usbTarget = knownUsb?.transport === "usb" ? knownUsb.connectId : usbDevices.find((device) => device.connectId === targetConnectId)?.connectId;
2046
- return this._connectFirstOrSelect(
2047
- usbDevices,
2048
- usbTarget,
2049
- allowUsbEphemeralFallback,
2050
- preserveInteractionId,
2051
- context,
2052
- internalSignal
2053
- );
2054
- }
2055
- this._activeConnectionType = "ble";
2056
- const knownBle = context?.knownConnections?.find(
2057
- (connection) => connection.transport === "ble"
2058
- );
2059
- if (knownBle?.transport === "ble") {
2060
- return this._connectDeviceOrThrow(
2061
- knownBle.connectId,
2062
- preserveInteractionId,
2063
- internalSignal
2064
- );
1623
+ async _doConnect(internalSignal, targetConnectId, allowUsbEphemeralFallback = false) {
1624
+ if (isLedgerBleConnectionType(this.connector.connectionType) && targetConnectId) {
1625
+ try {
1626
+ return await this._connectDeviceOrThrow(targetConnectId);
1627
+ } catch (err) {
1628
+ if (!isDeviceLockedError(err) && !isDeviceNotAdvertisingError(err) && !isDeviceDisconnectedError(err)) {
1629
+ throw err;
1630
+ }
1631
+ this._discoveredDevices.delete(targetConnectId);
1632
+ if (isDeviceDisconnectedError(err)) {
1633
+ try {
1634
+ this.connector.reset?.();
1635
+ } catch {
1636
+ }
1637
+ }
2065
1638
  }
2066
- const bleDevices = await this._searchDevices({ transportType: "ble" }, internalSignal);
2067
- return this._connectFirstOrSelect(
2068
- bleDevices,
2069
- void 0,
2070
- allowUsbEphemeralFallback,
2071
- preserveInteractionId,
2072
- context,
2073
- internalSignal
2074
- );
2075
- }
2076
- if (this._isBleConnection() && targetConnectId) {
2077
- return this._connectDeviceOrThrow(targetConnectId, preserveInteractionId, internalSignal);
2078
1639
  }
2079
1640
  let confirms = 0;
2080
1641
  while (!internalSignal.aborted) {
@@ -2082,28 +1643,22 @@ var _LedgerAdapter = class _LedgerAdapter {
2082
1643
  type: EConnectorInteraction.Searching,
2083
1644
  payload: { sessionId: "" }
2084
1645
  });
2085
- let devices = await this._searchDevices(void 0, internalSignal);
2086
- _LedgerAdapter._throwIfAborted(internalSignal);
1646
+ let devices = await this.searchDevices();
2087
1647
  if (devices.length === 0) {
2088
1648
  for (let i = 0; i < 3 && !internalSignal.aborted; i += 1) {
2089
1649
  await new Promise((resolve) => {
2090
1650
  setTimeout(resolve, DEVICE_CONNECT_RETRY_DELAY_MS);
2091
1651
  });
2092
- _LedgerAdapter._throwIfAborted(internalSignal);
2093
- devices = await this._searchDevices(void 0, internalSignal);
2094
- _LedgerAdapter._throwIfAborted(internalSignal);
1652
+ devices = await this.searchDevices();
2095
1653
  if (devices.length > 0) break;
2096
1654
  }
2097
1655
  }
2098
- if (devices.length > 0 || this._isBleConnection() && allowUsbEphemeralFallback) {
1656
+ if (devices.length > 0) {
2099
1657
  try {
2100
1658
  return await this._connectFirstOrSelect(
2101
1659
  devices,
2102
1660
  targetConnectId,
2103
- allowUsbEphemeralFallback,
2104
- preserveInteractionId,
2105
- context,
2106
- internalSignal
1661
+ allowUsbEphemeralFallback
2107
1662
  );
2108
1663
  } catch (err) {
2109
1664
  if (!isDeviceLockedError(err) && !isDeviceNotAdvertisingError(err) && !isDeviceDisconnectedError(err)) {
@@ -2132,107 +1687,45 @@ var _LedgerAdapter = class _LedgerAdapter {
2132
1687
  _LedgerAdapter._throwIfAborted(internalSignal);
2133
1688
  throw new Error("_doConnect aborted");
2134
1689
  }
2135
- async _connectFirstOrSelect(devices, targetConnectId, allowUsbEphemeralFallback = false, preserveInteractionId, context, signal) {
2136
- if (signal) _LedgerAdapter._throwIfAborted(signal);
1690
+ async _connectFirstOrSelect(devices, targetConnectId, allowUsbEphemeralFallback = false) {
2137
1691
  if (targetConnectId) {
2138
1692
  const target = devices.find(
2139
1693
  (d) => d.connectId === targetConnectId || d.deviceId === targetConnectId
2140
1694
  );
2141
1695
  if (target) {
2142
- return this._connectDeviceOrThrow(target.connectId, preserveInteractionId, signal);
1696
+ return this._connectDeviceOrThrow(target.connectId);
2143
1697
  }
2144
- if (!this._isBleConnection() && devices.length === 1 && allowUsbEphemeralFallback) {
1698
+ if (!isLedgerBleConnectionType(this.connector.connectionType) && devices.length === 1 && allowUsbEphemeralFallback) {
2145
1699
  debugLog(
2146
1700
  `[LedgerAdapter] target ${targetConnectId} not in fresh enumeration; accepting sole USB device ${devices[0].connectId} for fingerprint-verified recovery`
2147
1701
  );
2148
- return this._connectDeviceOrThrow(devices[0].connectId, preserveInteractionId, signal);
1702
+ return this._connectDeviceOrThrow(devices[0].connectId);
2149
1703
  }
2150
- if (!this._isBleConnection() || !allowUsbEphemeralFallback) {
2151
- const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
2152
- code: HardwareErrorCode3.DeviceNotFound
2153
- });
2154
- if (this._isBleConnection()) {
2155
- err._tag = ERROR_TAG.DeviceNotAdvertising;
2156
- }
2157
- throw err;
1704
+ const err = Object.assign(new Error(`Target Ledger unavailable: ${targetConnectId}`), {
1705
+ code: HardwareErrorCode3.DeviceNotFound
1706
+ });
1707
+ if (isLedgerBleConnectionType(this.connector.connectionType)) {
1708
+ err._tag = ERROR_TAG.DeviceNotAdvertising;
2158
1709
  }
1710
+ throw err;
2159
1711
  }
2160
- const requiresBleSelection = this._isBleConnection();
2161
- if (requiresBleSelection && !allowUsbEphemeralFallback) {
1712
+ if (isLedgerBleConnectionType(this.connector.connectionType)) {
2162
1713
  throw Object.assign(new Error("Ledger BLE connectId is required."), {
2163
1714
  code: HardwareErrorCode3.DeviceNotFound
2164
1715
  });
2165
1716
  }
2166
- if (requiresBleSelection && context?.allowDeviceSelection !== false) {
2167
- const bindingSessionId = context?.bindingSessionId ?? this._uiRegistry.createRequestId();
2168
- if (context) context.bindingSessionId = bindingSessionId;
2169
- const { device, requestId } = await requestBleDeviceSelection({
2170
- emitter: this.emitter,
2171
- registry: this._uiRegistry,
2172
- signal: signal ?? new AbortController().signal,
2173
- scan: async () => (await this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)).filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId)),
2174
- request: {
2175
- devices: devices.filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId)),
2176
- bindingSessionId,
2177
- rejectedConnectId: context?.rejectedConnectId,
2178
- context: {
2179
- kind: "bind-connection",
2180
- transport: "ble",
2181
- reason: targetConnectId ? "known-connection-unavailable" : "missing-binding"
2182
- },
2183
- extra: context?.extra
2184
- }
2185
- });
2186
- if (context) context.selectedConnection = { connectId: device.connectId, requestId };
2187
- this._bindingSelectionRequestId = requestId;
2188
- return this._connectDeviceOrThrow(device.connectId, preserveInteractionId, signal);
2189
- }
2190
- if (devices.length > 0 && (devices.length > 1 || requiresBleSelection)) {
2191
- if (context?.allowDeviceSelection === false || !this.emitter.listenerCount(UI_REQUEST.REQUEST_SELECT_DEVICE)) {
2192
- throw createHwkError({
2193
- code: HardwareErrorCode3.DeviceNotFound,
2194
- message: "Select a Ledger device before continuing"
2195
- });
2196
- }
2197
- const requestId = this._uiRegistry.createRequestId();
2198
- const waitPromise = this._uiRegistry.wait(
2199
- UI_REQUEST.REQUEST_SELECT_DEVICE,
2200
- { requestId }
2201
- );
2202
- this.emitter.emit(UI_REQUEST.REQUEST_SELECT_DEVICE, {
2203
- type: UI_REQUEST.REQUEST_SELECT_DEVICE,
2204
- payload: {
2205
- devices,
2206
- requestId,
2207
- context: requiresBleSelection ? {
2208
- kind: "bind-connection",
2209
- transport: "ble",
2210
- reason: targetConnectId ? "known-connection-unavailable" : "missing-binding"
2211
- } : { kind: "select-device", transport: "usb", reason: "multiple-candidates" },
2212
- extra: context?.extra
2213
- }
2214
- });
2215
- const { sdkConnectId } = await (signal ? this._abortable(signal, waitPromise) : waitPromise);
2216
- if (signal) _LedgerAdapter._throwIfAborted(signal);
2217
- const selected = devices.find((device) => device.connectId === sdkConnectId);
2218
- if (!selected) {
2219
- throw Object.assign(new Error("Selected Ledger is no longer available"), {
2220
- code: HardwareErrorCode3.DeviceNotFound
2221
- });
2222
- }
2223
- if (context && requiresBleSelection)
2224
- context.selectedConnection = { connectId: selected.connectId, requestId };
2225
- return this._connectDeviceOrThrow(selected.connectId, preserveInteractionId, signal);
1717
+ if (devices.length > 1) {
1718
+ throw createMultipleUsbLedgerDevicesError();
2226
1719
  }
2227
1720
  if (devices.length !== 1) {
2228
1721
  throw Object.assign(new Error("Ledger device not found."), {
2229
1722
  code: HardwareErrorCode3.DeviceNotFound
2230
1723
  });
2231
1724
  }
2232
- return this._connectDeviceOrThrow(devices[0].connectId, preserveInteractionId, signal);
1725
+ return this._connectDeviceOrThrow(devices[0].connectId);
2233
1726
  }
2234
- async _connectDeviceOrThrow(chosenConnectId, preserveInteractionId, signal) {
2235
- const result = await this._connectTarget(chosenConnectId, preserveInteractionId, signal);
1727
+ async _connectDeviceOrThrow(chosenConnectId) {
1728
+ const result = await this.connectDevice(chosenConnectId);
2236
1729
  if (!result.success) {
2237
1730
  const payload = result.payload;
2238
1731
  const rethrow = Object.assign(new Error(payload.error), {
@@ -2243,7 +1736,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2243
1736
  }
2244
1737
  throw rethrow;
2245
1738
  }
2246
- return result.payload;
1739
+ return chosenConnectId;
2247
1740
  }
2248
1741
  /**
2249
1742
  * Call the connector with automatic session resolution and disconnect retry.
@@ -2273,121 +1766,26 @@ var _LedgerAdapter = class _LedgerAdapter {
2273
1766
  * lives in one place.
2274
1767
  */
2275
1768
  async _callConnector(sessionId, method, params, signal) {
2276
- this._assertConnectorReady(method);
2277
- const releaseOperation = this._retainConnectorOperation(`call:${sessionId}`);
2278
- let promise;
2279
- try {
2280
- promise = this.connector.call(sessionId, method, params).finally(releaseOperation);
2281
- } catch (error) {
2282
- releaseOperation();
2283
- throw error;
2284
- }
1769
+ const promise = this.connector.call(sessionId, method, params);
2285
1770
  const result = signal ? await this._abortable(signal, promise) : await promise;
2286
1771
  return this._unwrapConnectorResult(result);
2287
1772
  }
2288
- _assertConnectorReady(method) {
2289
- if (this._resetPromise || this._pendingConnectorTeardowns > 0 || this._unsettledConnectorOperations.size > 0) {
2290
- throw _LedgerAdapter._createDeviceBusyError(method);
2291
- }
2292
- }
2293
- _runConnectorTeardown(task) {
2294
- const previous = this._connectorTeardownTail;
2295
- let releaseTail = () => void 0;
2296
- this._connectorTeardownTail = new Promise((resolve) => {
2297
- releaseTail = resolve;
2298
- });
2299
- this._pendingConnectorTeardowns += 1;
2300
- return (async () => {
2301
- try {
2302
- await previous;
2303
- await this._waitForConnectorOperationsToDrain();
2304
- await task();
2305
- } finally {
2306
- this._pendingConnectorTeardowns -= 1;
2307
- releaseTail();
2308
- }
2309
- })();
2310
- }
2311
- _waitForConnectorOperationsToDrain() {
2312
- if (this._unsettledConnectorOperations.size === 0) {
2313
- return Promise.resolve();
2314
- }
2315
- return new Promise((resolve) => {
2316
- this._connectorIdleWaiters.add(resolve);
2317
- });
2318
- }
2319
- _retainConnectorOperation(key) {
2320
- this._unsettledConnectorOperations.set(
2321
- key,
2322
- (this._unsettledConnectorOperations.get(key) ?? 0) + 1
2323
- );
2324
- let released = false;
2325
- return () => {
2326
- if (released) return;
2327
- released = true;
2328
- const remaining = (this._unsettledConnectorOperations.get(key) ?? 1) - 1;
2329
- if (remaining > 0) {
2330
- this._unsettledConnectorOperations.set(key, remaining);
2331
- } else {
2332
- this._unsettledConnectorOperations.delete(key);
2333
- }
2334
- if (this._unsettledConnectorOperations.size === 0) {
2335
- for (const resolve of this._connectorIdleWaiters) resolve();
2336
- this._connectorIdleWaiters.clear();
2337
- }
2338
- };
2339
- }
2340
1773
  async connectorCall(connectId, method, params, fingerprint, permissionDeviceId, commonParams, installContext) {
2341
- const positionalInteractionId = isHardwareInteractionId(connectId) ? connectId : void 0;
2342
- if (positionalInteractionId && commonParams?.interactionId && positionalInteractionId !== commonParams.interactionId) {
2343
- throw createHwkError({
2344
- code: HardwareErrorCode3.InvalidParams,
2345
- message: "Conflicting Ledger interaction ids",
2346
- params: {
2347
- positionalInteractionId,
2348
- commonInteractionId: commonParams.interactionId
2349
- }
2350
- });
2351
- }
2352
- const interactionId = commonParams?.interactionId ?? positionalInteractionId;
2353
- const interaction = interactionId ? this._interactions.resolve(interactionId) : void 0;
2354
- const releaseInteractionRetention = interactionId ? this._interactions.retain(interactionId) : void 0;
2355
- const effectiveConnectId = interaction?.connectId ?? connectId;
2356
- debugLog("[LedgerAdapter][REQ]", {
2357
- method,
2358
- connectId: effectiveConnectId || "(empty)",
2359
- params
2360
- });
2361
- const queueKey = (interactionId ?? effectiveConnectId) || "__ledger_default__";
1774
+ debugLog("[LedgerAdapter][REQ]", { method, connectId: connectId || "(empty)", params });
1775
+ const queueKey = connectId || "__ledger_default__";
2362
1776
  try {
2363
1777
  const result = await this._jobQueue.enqueue(
2364
1778
  queueKey,
2365
- async (signal) => {
2366
- if (interactionId) this._activeInteractionJobs.add(interactionId);
2367
- try {
2368
- return await this._runConnectorCall(
2369
- effectiveConnectId,
2370
- method,
2371
- params,
2372
- signal,
2373
- fingerprint,
2374
- permissionDeviceId,
2375
- commonParams,
2376
- installContext ?? {},
2377
- interactionId
2378
- );
2379
- } catch (error) {
2380
- this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
2381
- throw error;
2382
- } finally {
2383
- if (interactionId) {
2384
- this._activeInteractionJobs.delete(interactionId);
2385
- if (this._pendingInteractionDisconnects.delete(interactionId)) {
2386
- await this._releaseLostInteractionConnection(interactionId);
2387
- }
2388
- }
2389
- }
2390
- },
1779
+ async (signal) => this._runConnectorCall(
1780
+ connectId,
1781
+ method,
1782
+ params,
1783
+ signal,
1784
+ fingerprint,
1785
+ permissionDeviceId,
1786
+ commonParams,
1787
+ installContext
1788
+ ),
2391
1789
  {
2392
1790
  label: method,
2393
1791
  rejectIfBusy: true,
@@ -2408,8 +1806,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2408
1806
  }
2409
1807
  });
2410
1808
  throw err;
2411
- } finally {
2412
- releaseInteractionRetention?.();
2413
1809
  }
2414
1810
  }
2415
1811
  /**
@@ -2419,7 +1815,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2419
1815
  _abortable(signal, promise) {
2420
1816
  const getAbortReason = () => signal.reason ?? this._lastCancelReason ?? new Error("Aborted");
2421
1817
  if (signal.aborted) {
2422
- void promise.catch(() => void 0);
2423
1818
  return Promise.reject(getAbortReason());
2424
1819
  }
2425
1820
  return new Promise((resolve, reject) => {
@@ -2446,15 +1841,13 @@ var _LedgerAdapter = class _LedgerAdapter {
2446
1841
  }
2447
1842
  }
2448
1843
  /** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
2449
- async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext, interactionId, lockedRetryBudget = _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET) {
1844
+ async _runConnectorCall(connectId, method, params, signal, fingerprint, permissionDeviceId, commonParams, installContext) {
2450
1845
  _LedgerAdapter._throwIfAborted(signal);
2451
- if (!interactionId) {
2452
- await this._ensureDevicePermission(
2453
- connectId,
2454
- permissionDeviceId ?? fingerprint?.deviceId,
2455
- signal
2456
- );
2457
- }
1846
+ await this._ensureDevicePermission(
1847
+ connectId,
1848
+ permissionDeviceId ?? fingerprint?.deviceId,
1849
+ signal
1850
+ );
2458
1851
  _LedgerAdapter._throwIfAborted(signal);
2459
1852
  let effectiveParams = params;
2460
1853
  if (method === "btcGetPublicKey") {
@@ -2468,133 +1861,36 @@ var _LedgerAdapter = class _LedgerAdapter {
2468
1861
  effectiveParams = gatedParams;
2469
1862
  }
2470
1863
  const allowUsbEphemeralFallback = !!fingerprint?.deviceId && !fingerprint.skipFingerprint;
2471
- let businessCallStarted = false;
2472
- const verifiedBleTarget = connectId ? this._verifiedBleReconnectTargets.get(connectId) : void 0;
2473
- const knownTransport = this._isBleConnection() ? "ble" : "usb";
2474
- const hintedConnectId = commonParams?.knownConnections?.find(
2475
- (connection) => connection.transport === knownTransport
2476
- );
2477
- const inputConnectId = hintedConnectId && hintedConnectId.transport !== "qr" ? hintedConnectId.connectId : connectId;
2478
- const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && verifiedBleTarget?.chain === fingerprint.chain && verifiedBleTarget.fingerprint === fingerprint.deviceId ? verifiedBleTarget.connectId : inputConnectId;
2479
- const connectionAttempt = { ...commonParams };
2480
- const bundleConnection = installContext?.connection;
2481
- if (bundleConnection && this._sessions.get(bundleConnection.connectId) !== bundleConnection.sessionId) {
2482
- throw createHwkError({
2483
- code: HardwareErrorCode3.DeviceDisconnected,
2484
- message: "Ledger all-network connection ended"
2485
- });
2486
- }
2487
- let resolvedConnectId = interactionId ? this._interactions.resolve(interactionId).connectId : bundleConnection?.connectId ?? await this.ensureConnected(
2488
- preferredConnectId,
1864
+ const resolvedConnectId = await this.ensureConnected(
1865
+ connectId,
2489
1866
  signal,
2490
- allowUsbEphemeralFallback,
2491
- void 0,
2492
- connectionAttempt
1867
+ allowUsbEphemeralFallback
2493
1868
  );
2494
- let sessionId = this._sessions.get(resolvedConnectId);
2495
- if (sessionId && installContext && !installContext.connection) {
2496
- installContext.connection = { connectId: resolvedConnectId, sessionId };
2497
- }
1869
+ const sessionId = this._sessions.get(resolvedConnectId);
2498
1870
  if (!sessionId) {
2499
- if (interactionId) {
2500
- this._interactions.end(interactionId, "disconnect");
2501
- throw createHwkError({
2502
- code: HardwareErrorCode3.InteractionEnded,
2503
- message: "Ledger interaction connection is no longer active",
2504
- params: { interactionId, reason: "disconnect" }
2505
- });
2506
- }
2507
1871
  throw Object.assign(new Error("Auto-connect succeeded but no session found"), {
2508
1872
  _tag: ERROR_TAG.DeviceSessionNotFound
2509
1873
  });
2510
1874
  }
2511
1875
  try {
2512
1876
  if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2513
- for (; ; ) {
2514
- const fp = await this._abortable(
2515
- signal,
2516
- this._verifyDeviceFingerprintWithSession(
2517
- sessionId,
2518
- fingerprint.deviceId,
2519
- fingerprint.chain
2520
- )
2521
- );
2522
- if (fp.success) break;
2523
- const binding = interactionId ? this._pendingInteractionBindings.get(interactionId) : connectionAttempt;
2524
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== resolvedConnectId) {
2525
- throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2526
- code: HardwareErrorCode3.DeviceMismatch
2527
- });
2528
- }
2529
- binding.rejectedConnectIds ?? (binding.rejectedConnectIds = /* @__PURE__ */ new Set());
2530
- binding.rejectedConnectIds.add(resolvedConnectId);
2531
- binding.rejectedConnectId = resolvedConnectId;
2532
- this._sessions.delete(resolvedConnectId);
2533
- await this.connector.disconnect(sessionId);
2534
- if (interactionId) this._pendingInteractionDisconnects.delete(interactionId);
2535
- _LedgerAdapter._throwIfAborted(signal);
2536
- resolvedConnectId = await this._connectFirstOrSelect(
2537
- [],
2538
- void 0,
2539
- true,
2540
- interactionId,
2541
- binding,
2542
- signal
2543
- );
2544
- const selectedSession = this._sessions.get(resolvedConnectId);
2545
- const selectedDevice = this._discoveredDevices.get(resolvedConnectId);
2546
- if (!selectedSession || !selectedDevice)
2547
- throw createHwkError({
2548
- code: HardwareErrorCode3.DeviceDisconnected,
2549
- message: "Selected Ledger connection ended"
2550
- });
2551
- sessionId = selectedSession;
2552
- if (interactionId)
2553
- this._interactions.rebind(interactionId, {
2554
- connectId: resolvedConnectId,
2555
- device: selectedDevice,
2556
- connectionKeys: [sessionId]
2557
- });
2558
- if (installContext)
2559
- installContext.connection = { connectId: resolvedConnectId, sessionId };
2560
- }
2561
- if (!interactionId && connectionAttempt.selectedConnection?.connectId === resolvedConnectId && this._isBleConnection()) {
2562
- this._verifiedBleReconnectTargets.set(connectId, {
2563
- connectId: resolvedConnectId,
2564
- chain: fingerprint.chain,
2565
- fingerprint: fingerprint.deviceId
1877
+ const fp = await this._abortable(
1878
+ signal,
1879
+ this._verifyDeviceFingerprintWithSession(
1880
+ sessionId,
1881
+ fingerprint.deviceId,
1882
+ fingerprint.chain
1883
+ )
1884
+ );
1885
+ if (!fp.success) {
1886
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
1887
+ code: HardwareErrorCode3.DeviceMismatch
2566
1888
  });
2567
1889
  }
2568
- await this._publishVerifiedBleBinding(
2569
- resolvedConnectId,
2570
- fingerprint.chain,
2571
- fingerprint.deviceId,
2572
- connectionAttempt,
2573
- interactionId,
2574
- connectId,
2575
- signal
2576
- );
2577
1890
  }
2578
- businessCallStarted = true;
2579
1891
  return await this._callConnector(sessionId, method, effectiveParams, signal);
2580
1892
  } catch (err) {
2581
1893
  if (signal.aborted) throw err;
2582
- if (isDeviceDisconnectedError(err) || isDeviceNotAdvertisingError(err) || isTimeoutError(err) || isConnectionLevelError(err)) {
2583
- this._discoveredDevices.delete(resolvedConnectId);
2584
- if (interactionId) await this._releaseLostInteractionConnection(interactionId);
2585
- else {
2586
- this._sessions.delete(resolvedConnectId);
2587
- await this.connector.disconnect(sessionId).catch(() => void 0);
2588
- }
2589
- const ambiguous = businessCallStarted && !canReplayHardwareMethodAfterTransportFailure(method);
2590
- const interactionParams = interactionId ? { interactionId, reason: "disconnect" } : void 0;
2591
- throw createHwkError({
2592
- code: interactionId ? HardwareErrorCode3.InteractionEnded : mapLedgerError(err).code,
2593
- message: "Ledger operation connection was lost; start a new operation",
2594
- params: ambiguous ? operationMayHaveCompletedParams(method, { interactionId }) : interactionParams,
2595
- recovery: ambiguous ? { scope: "unknown" } : void 0
2596
- });
2597
- }
2598
1894
  const errObj = err;
2599
1895
  debugLog("[LedgerAdapter] connectorCall error:", method, {
2600
1896
  message: errObj?.message,
@@ -2606,65 +1902,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2606
1902
  isNotAdvertising: isDeviceNotAdvertisingError(err),
2607
1903
  isStuckApp: isStuckAppStateError(err)
2608
1904
  });
2609
- if ((isDeviceLockedError(err) || errObj?.code === HardwareErrorCode3.DeviceLocked) && lockedRetryBudget > 0) {
2610
- await this._waitForDeviceConnect(signal);
2611
- if (this._sessions.get(resolvedConnectId) !== sessionId) {
2612
- throw createHwkError({
2613
- code: interactionId ? HardwareErrorCode3.InteractionEnded : HardwareErrorCode3.DeviceDisconnected,
2614
- message: "Ledger connection ended while waiting for unlock"
2615
- });
2616
- }
2617
- return this._runConnectorCall(
2618
- resolvedConnectId,
2619
- method,
2620
- effectiveParams,
2621
- signal,
2622
- fingerprint,
2623
- permissionDeviceId,
2624
- commonParams,
2625
- installContext,
2626
- interactionId,
2627
- lockedRetryBudget - 1
2628
- );
2629
- }
2630
- if (businessCallStarted && isStuckAppStateError(err)) {
2631
- await this._sleepAbortable(_LedgerAdapter.STUCK_APP_RETRY_DELAY_MS, signal);
2632
- if (this._sessions.get(resolvedConnectId) !== sessionId) {
2633
- throw createHwkError({
2634
- code: interactionId ? HardwareErrorCode3.InteractionEnded : HardwareErrorCode3.DeviceDisconnected,
2635
- message: "Ledger connection ended during the app transition"
2636
- });
2637
- }
2638
- try {
2639
- return await this._callConnector(sessionId, method, effectiveParams, signal);
2640
- } catch (retryErr) {
2641
- if (isStuckAppStateError(retryErr)) throw err;
2642
- if (isDeviceDisconnectedError(retryErr) || isDeviceNotAdvertisingError(retryErr) || isTimeoutError(retryErr) || isConnectionLevelError(retryErr)) {
2643
- if (interactionId) await this._releaseLostInteractionConnection(interactionId);
2644
- else {
2645
- this._sessions.delete(resolvedConnectId);
2646
- this._discoveredDevices.delete(resolvedConnectId);
2647
- await this.connector.disconnect(sessionId).catch(() => void 0);
2648
- }
2649
- throw createHwkError({
2650
- code: interactionId ? HardwareErrorCode3.InteractionEnded : mapLedgerError(retryErr).code,
2651
- message: `Ledger ${method} may have completed before the connection was lost`,
2652
- params: !canReplayHardwareMethodAfterTransportFailure(method) ? operationMayHaveCompletedParams(method, {
2653
- interactionId,
2654
- reason: "disconnect"
2655
- }) : { interactionId, reason: "disconnect" },
2656
- recovery: !canReplayHardwareMethodAfterTransportFailure(method) ? { scope: "unknown" } : void 0
2657
- });
2658
- }
2659
- throw retryErr;
2660
- }
2661
- }
2662
- if (!interactionId && err?.code === HardwareErrorCode3.DeviceMismatch) {
2663
- this._sessions.delete(resolvedConnectId);
2664
- this._discoveredDevices.delete(resolvedConnectId);
2665
- await this.connector.disconnect(sessionId).catch(() => void 0);
2666
- throw err;
2667
- }
2668
1905
  const autoInstallApp = commonParams?.autoInstallApp ?? this._defaultAutoInstallApp;
2669
1906
  const isAppMissing = isAppNotInstalledError(err) || err?.code === HardwareErrorCode3.AppNotInstalled;
2670
1907
  if (autoInstallApp && isAppMissing) {
@@ -2720,14 +1957,157 @@ var _LedgerAdapter = class _LedgerAdapter {
2720
1957
  fingerprint,
2721
1958
  permissionDeviceId,
2722
1959
  commonParams,
2723
- installContext,
2724
- interactionId
1960
+ installContext
2725
1961
  );
2726
1962
  }
2727
1963
  }
1964
+ if (isStuckAppStateError(err)) {
1965
+ try {
1966
+ this._sessions.delete(resolvedConnectId);
1967
+ this._discoveredDevices.delete(resolvedConnectId);
1968
+ this.connector.reset?.();
1969
+ } catch {
1970
+ }
1971
+ debugLog(
1972
+ "[LedgerAdapter] stuck-app retry: method=",
1973
+ method,
1974
+ "delayMs=",
1975
+ _LedgerAdapter.STUCK_APP_RETRY_DELAY_MS,
1976
+ "_tag=",
1977
+ err?._tag
1978
+ );
1979
+ try {
1980
+ const retryResult = await this._retryAfterStuckApp(
1981
+ resolvedConnectId,
1982
+ method,
1983
+ effectiveParams,
1984
+ signal,
1985
+ err,
1986
+ fingerprint
1987
+ );
1988
+ debugLog("[LedgerAdapter] stuck-app retry succeeded: method=", method);
1989
+ return retryResult;
1990
+ } catch (retryErr) {
1991
+ if (signal.aborted) throw retryErr;
1992
+ if (isStuckAppStateError(retryErr)) {
1993
+ debugLog("[LedgerAdapter] stuck-app retry exhausted (2nd 6901): method=", method);
1994
+ throw err;
1995
+ }
1996
+ debugLog(
1997
+ "[LedgerAdapter] stuck-app retry threw non-stuck error: method=",
1998
+ method,
1999
+ "retryErrTag=",
2000
+ retryErr?._tag
2001
+ );
2002
+ throw retryErr;
2003
+ }
2004
+ }
2005
+ if (isDeviceLockedError(err) || isDeviceNotAdvertisingError(err) || isDeviceDisconnectedError(err)) {
2006
+ let lastErr = err;
2007
+ for (let attempt = 0; attempt < _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET; attempt += 1) {
2008
+ if (signal.aborted) throw lastErr;
2009
+ try {
2010
+ this._sessions.delete(resolvedConnectId);
2011
+ this._discoveredDevices.delete(resolvedConnectId);
2012
+ if (isDeviceDisconnectedError(lastErr)) {
2013
+ try {
2014
+ this.connector.reset?.();
2015
+ } catch {
2016
+ }
2017
+ }
2018
+ const reConnectId = await this.ensureConnected(
2019
+ resolvedConnectId,
2020
+ signal,
2021
+ allowUsbEphemeralFallback
2022
+ );
2023
+ const reSessionId = this._sessions.get(reConnectId);
2024
+ if (!reSessionId) throw lastErr;
2025
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2026
+ const fp = await this._abortable(
2027
+ signal,
2028
+ this._verifyDeviceFingerprintWithSession(
2029
+ reSessionId,
2030
+ fingerprint.deviceId,
2031
+ fingerprint.chain
2032
+ )
2033
+ );
2034
+ if (!fp.success) {
2035
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2036
+ code: HardwareErrorCode3.DeviceMismatch
2037
+ });
2038
+ }
2039
+ }
2040
+ return await this._callConnector(reSessionId, method, effectiveParams, signal);
2041
+ } catch (retryErr) {
2042
+ if (signal.aborted) throw retryErr;
2043
+ lastErr = retryErr;
2044
+ const canRetry = attempt < _LedgerAdapter.MAX_BUSINESS_RETRY_BUDGET - 1 && (isDeviceLockedError(retryErr) || isDeviceNotAdvertisingError(retryErr) || isDeviceDisconnectedError(retryErr));
2045
+ if (!canRetry) {
2046
+ throw retryErr;
2047
+ }
2048
+ }
2049
+ }
2050
+ throw lastErr;
2051
+ }
2052
+ if (isTimeoutError(err)) {
2053
+ debugLog("[LedgerAdapter] timeout, retrying with fresh connection...");
2054
+ this._discoveredDevices.delete(resolvedConnectId);
2055
+ return this._retryWithFreshConnection(
2056
+ resolvedConnectId,
2057
+ method,
2058
+ effectiveParams,
2059
+ signal,
2060
+ err,
2061
+ fingerprint
2062
+ );
2063
+ }
2064
+ if (isConnectionLevelError(err)) {
2065
+ debugLog("[LedgerAdapter] connection-level fail-closed reset");
2066
+ this._sessions.delete(resolvedConnectId);
2067
+ this._discoveredDevices.delete(resolvedConnectId);
2068
+ this.connector.reset();
2069
+ const codeNum = err?.code;
2070
+ throw Object.assign(err, {
2071
+ code: codeNum ?? HardwareErrorCode3.DeviceDisconnected
2072
+ });
2073
+ }
2728
2074
  throw err;
2729
2075
  }
2730
2076
  }
2077
+ /**
2078
+ * Stuck-app recovery: pause for the device's UI transition, then retry once.
2079
+ *
2080
+ * Caller has already cleared the session + reset connector. We wait so Stax
2081
+ * finishes its post-CloseApp animation, then go through ensureConnected +
2082
+ * fingerprint check + call exactly once. Caller decides what to do on a
2083
+ * second stuck-app hit.
2084
+ */
2085
+ async _retryAfterStuckApp(resolvedConnectId, method, params, signal, originalErr, fingerprint) {
2086
+ await this._sleepAbortable(_LedgerAdapter.STUCK_APP_RETRY_DELAY_MS, signal);
2087
+ const retryConnectId = await this.ensureConnected(
2088
+ resolvedConnectId,
2089
+ signal,
2090
+ !!fingerprint?.deviceId && !fingerprint.skipFingerprint
2091
+ );
2092
+ const retrySessionId = this._sessions.get(retryConnectId);
2093
+ if (!retrySessionId) throw originalErr;
2094
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2095
+ const fp = await this._abortable(
2096
+ signal,
2097
+ this._verifyDeviceFingerprintWithSession(
2098
+ retrySessionId,
2099
+ fingerprint.deviceId,
2100
+ fingerprint.chain
2101
+ )
2102
+ );
2103
+ if (!fp.success) {
2104
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2105
+ code: HardwareErrorCode3.DeviceMismatch
2106
+ });
2107
+ }
2108
+ }
2109
+ return this._callConnector(retrySessionId, method, params, signal);
2110
+ }
2731
2111
  _sleepAbortable(ms, signal) {
2732
2112
  return new Promise((resolve, reject) => {
2733
2113
  if (signal.aborted) {
@@ -2745,6 +2125,88 @@ var _LedgerAdapter = class _LedgerAdapter {
2745
2125
  signal.addEventListener("abort", onAbort, { once: true });
2746
2126
  });
2747
2127
  }
2128
+ /**
2129
+ * Clear stale session, reconnect, and retry the call.
2130
+ *
2131
+ * Timeout recovery starts with a full connector reset. After an APDU
2132
+ * timeout, DMK/transport state may still emit malformed responses; retrying
2133
+ * on the same DMK can poison the next chain switch.
2134
+ */
2135
+ async _retryWithFreshConnection(targetConnectId, method, params, signal, originalErr, fingerprint) {
2136
+ this.connector.reset();
2137
+ this._sessions.clear();
2138
+ this._discoveredDevices.clear();
2139
+ this._connectingPromise = null;
2140
+ const allowUsbEphemeralFallback = !!fingerprint?.deviceId && !fingerprint.skipFingerprint;
2141
+ const retryConnectId = await this.ensureConnected(
2142
+ targetConnectId,
2143
+ signal,
2144
+ allowUsbEphemeralFallback
2145
+ );
2146
+ const retrySessionId = this._sessions.get(retryConnectId);
2147
+ if (!retrySessionId) {
2148
+ throw originalErr;
2149
+ }
2150
+ try {
2151
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2152
+ const fp = await this._abortable(
2153
+ signal,
2154
+ this._verifyDeviceFingerprintWithSession(
2155
+ retrySessionId,
2156
+ fingerprint.deviceId,
2157
+ fingerprint.chain
2158
+ )
2159
+ );
2160
+ if (!fp.success) {
2161
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2162
+ code: HardwareErrorCode3.DeviceMismatch
2163
+ });
2164
+ }
2165
+ }
2166
+ return await this._callConnector(retrySessionId, method, params, signal);
2167
+ } catch (retryErr) {
2168
+ if (signal.aborted) throw retryErr;
2169
+ this.connector.reset();
2170
+ this._sessions.clear();
2171
+ this._discoveredDevices.clear();
2172
+ this._connectingPromise = null;
2173
+ if (!isDeviceDisconnectedError(retryErr) && !isTimeoutError(retryErr)) {
2174
+ throw retryErr;
2175
+ }
2176
+ debugLog(
2177
+ "[LedgerAdapter] fresh-session retry still failed; resetting connector and rebuilding DMK"
2178
+ );
2179
+ this.connector.reset();
2180
+ this._sessions.clear();
2181
+ this._discoveredDevices.clear();
2182
+ this._connectingPromise = null;
2183
+ const finalConnectId = await this.ensureConnected(
2184
+ targetConnectId,
2185
+ signal,
2186
+ allowUsbEphemeralFallback
2187
+ );
2188
+ const finalSessionId = this._sessions.get(finalConnectId);
2189
+ if (!finalSessionId) {
2190
+ throw originalErr;
2191
+ }
2192
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2193
+ const fp = await this._abortable(
2194
+ signal,
2195
+ this._verifyDeviceFingerprintWithSession(
2196
+ finalSessionId,
2197
+ fingerprint.deviceId,
2198
+ fingerprint.chain
2199
+ )
2200
+ );
2201
+ if (!fp.success) {
2202
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2203
+ code: HardwareErrorCode3.DeviceMismatch
2204
+ });
2205
+ }
2206
+ }
2207
+ return this._callConnector(finalSessionId, method, params, signal);
2208
+ }
2209
+ }
2748
2210
  /**
2749
2211
  * Ensure OS-level device permission (Bluetooth / USB) before proceeding.
2750
2212
  *
@@ -2814,15 +2276,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2814
2276
  if (err && typeof err === "object" && "code" in err && typeof err.code === "number") {
2815
2277
  const e = err;
2816
2278
  const params = e.code === HardwareErrorCode3.DevicePermissionDenied && e.reason ? { permissionDeniedReason: e.reason } : e.params;
2817
- return ledgerFailure(
2818
- e.code,
2819
- e.message ?? "Unknown error",
2820
- e.appName,
2821
- tag,
2822
- params,
2823
- void 0,
2824
- isHwkRecoveryHint(e.recovery) ? e.recovery : void 0
2825
- );
2279
+ return ledgerFailure(e.code, e.message ?? "Unknown error", e.appName, tag, params);
2826
2280
  }
2827
2281
  const mapped = mapLedgerError(err);
2828
2282
  return ledgerFailure(mapped.code, mapped.message, mapped.appName, tag);
@@ -2849,7 +2303,7 @@ var _LedgerAdapter = class _LedgerAdapter {
2849
2303
  deviceId: device.deviceId,
2850
2304
  connectId: device.connectId,
2851
2305
  label: device.name,
2852
- connectionType: device.connectionType ?? this.connector.connectionType,
2306
+ connectionType: this.connector.connectionType,
2853
2307
  rssi: device.rssi,
2854
2308
  isConnectable: device.isConnectable,
2855
2309
  serialNumber: device.serialNumber,
@@ -3149,7 +2603,7 @@ var LedgerDeviceManager = class {
3149
2603
 
3150
2604
  // src/signer/SignerManager.ts
3151
2605
  import { SignerEthBuilder } from "@ledgerhq/device-signer-kit-ethereum";
3152
- import { ContextModuleBuilder, ContextModuleChainID } from "@ledgerhq/context-module";
2606
+ import { ContextModuleBuilder } from "@ledgerhq/context-module";
3153
2607
 
3154
2608
  // src/signer/SignerEth.ts
3155
2609
  import { hexToBytes } from "@onekeyfe/hwk-adapter-core";
@@ -3415,7 +2869,7 @@ var SignerManager = class _SignerManager {
3415
2869
  return (args) => new SignerEthBuilder(args);
3416
2870
  }
3417
2871
  static _createContextModule() {
3418
- const contextModule = new ContextModuleBuilder({}).setChain(ContextModuleChainID.Ethereum).removeDefaultLoaders().build();
2872
+ const contextModule = new ContextModuleBuilder({}).removeDefaultLoaders().build();
3419
2873
  return _SignerManager.wrapBlindSigningReportNonBlocking(contextModule);
3420
2874
  }
3421
2875
  static wrapBlindSigningReportNonBlocking(contextModule) {
@@ -3885,8 +3339,7 @@ function _applySignaturesToPsbt(psbtHex, signatures) {
3885
3339
  }
3886
3340
 
3887
3341
  // src/connector/chains/sol.ts
3888
- import { bytesToHex, hexToBytes as hexToBytes3, prepareSolanaOffchainMessageV1 } from "@onekeyfe/hwk-adapter-core";
3889
- import bs58 from "bs58";
3342
+ import { bytesToHex, hexToBytes as hexToBytes3 } from "@onekeyfe/hwk-adapter-core";
3890
3343
 
3891
3344
  // src/signer/SignerSol.ts
3892
3345
  var SignerSol = class {
@@ -3970,21 +3423,8 @@ async function solSignMessage(ctx, sessionId, params) {
3970
3423
  const path = normalizePath(params.path);
3971
3424
  const messageBytes = hexToBytes3(params.message);
3972
3425
  try {
3973
- if (params.messageVersion === 1) {
3974
- const preparedMessage = prepareSolanaOffchainMessageV1({
3975
- message: messageBytes,
3976
- requiredSigners: params.requiredSigners
3977
- });
3978
- const { SignMessageVersion } = await ctx.importLedgerKit(
3979
- "@ledgerhq/device-signer-kit-solana"
3980
- );
3981
- const result2 = await solSigner.signMessage(path, preparedMessage.serializedMessage, {
3982
- version: SignMessageVersion.Raw
3983
- });
3984
- return { signature: decodeBase58Signature(result2.signature) };
3985
- }
3986
3426
  const result = await solSigner.signMessage(path, messageBytes);
3987
- return { signature: decodeBase58EnvelopeSignature(result.signature) };
3427
+ return { signature: result.signature };
3988
3428
  } catch (err) {
3989
3429
  ctx.invalidateSession(sessionId);
3990
3430
  throw ctx.wrapError(err);
@@ -3992,27 +3432,11 @@ async function solSignMessage(ctx, sessionId, params) {
3992
3432
  ctx.clearCanceller(sessionId);
3993
3433
  }
3994
3434
  }
3995
- function decodeBase58Signature(signature) {
3996
- const bytes = bs58.decode(signature);
3997
- if (bytes.length !== 64) {
3998
- throw new Error(`Ledger Solana signature must be 64 bytes, received ${bytes.length}`);
3999
- }
4000
- return bytesToHex(bytes);
4001
- }
4002
- function decodeBase58EnvelopeSignature(envelope) {
4003
- const bytes = bs58.decode(envelope);
4004
- if (bytes.length < 65 || bytes[0] !== 1) {
4005
- throw new Error("Ledger Solana signature envelope is invalid");
4006
- }
4007
- return bytesToHex(bytes.subarray(1, 65));
4008
- }
4009
3435
  async function _createSolSigner(ctx, sessionId) {
4010
3436
  const dmk = await ctx.getOrCreateDmk();
4011
- const { ContextModuleBuilder: ContextModuleBuilder2, ContextModuleChainID: ContextModuleChainID2 } = await ctx.importLedgerKit(
4012
- "@ledgerhq/context-module"
4013
- );
3437
+ const { ContextModuleBuilder: ContextModuleBuilder2 } = await ctx.importLedgerKit("@ledgerhq/context-module");
4014
3438
  const { SignerSolanaBuilder } = await ctx.importLedgerKit("@ledgerhq/device-signer-kit-solana");
4015
- const contextModule = new ContextModuleBuilder2({}).setChain(ContextModuleChainID2.Solana).removeDefaultLoaders().build();
3439
+ const contextModule = new ContextModuleBuilder2({}).removeDefaultLoaders().build();
4016
3440
  const sdkSigner = new SignerSolanaBuilder({ dmk, sessionId }).withContextModule(contextModule).build();
4017
3441
  const signer = new SignerSol(sdkSigner);
4018
3442
  signer.onInteraction = (interaction) => {
@@ -4028,86 +3452,6 @@ async function _createSolSigner(ctx, sessionId) {
4028
3452
  return signer;
4029
3453
  }
4030
3454
 
4031
- // src/connector/chains/zcash.ts
4032
- import { bytesToHex as bytesToHex2 } from "@onekeyfe/hwk-adapter-core";
4033
-
4034
- // src/signer/SignerZcash.ts
4035
- var SignerZcash = class {
4036
- // eslint-disable-next-line no-useless-constructor, no-empty-function
4037
- constructor(_sdk) {
4038
- this._sdk = _sdk;
4039
- }
4040
- /** GET_VK: UFVK string (default) or raw 96-byte Orchard FVK. */
4041
- async getFullViewingKey(derivationPath, options) {
4042
- const action = this._sdk.getFullViewingKey(derivationPath, options);
4043
- return deviceActionToPromise(
4044
- action,
4045
- this.onInteraction,
4046
- void 0,
4047
- this.onRegisterCanceller
4048
- );
4049
- }
4050
- /** GET_SHIELDED_ADDRESS: single-Orchard-receiver UA for a 5-level transparent path. */
4051
- async getShieldedAddress(derivationPath, options) {
4052
- const action = this._sdk.getShieldedAddress(derivationPath, options);
4053
- return deviceActionToPromise(
4054
- action,
4055
- this.onInteraction,
4056
- void 0,
4057
- this.onRegisterCanceller
4058
- );
4059
- }
4060
- };
4061
-
4062
- // src/connector/chains/zcash.ts
4063
- async function zcashGetFullViewingKey(ctx, sessionId, params) {
4064
- const signer = await _createZcashSigner(ctx, sessionId);
4065
- const path = normalizePath(params.path);
4066
- const mode = params.mode ?? "ufvk";
4067
- try {
4068
- const result = await signer.getFullViewingKey(path, { mode });
4069
- if (result.mode === "ufvk") {
4070
- return { path: params.path, mode, ufvk: result.fullViewingKey };
4071
- }
4072
- return { path: params.path, mode, orchardFvk: bytesToHex2(result.fullViewingKey) };
4073
- } catch (err) {
4074
- ctx.invalidateSession(sessionId);
4075
- throw ctx.wrapError(err);
4076
- } finally {
4077
- ctx.clearCanceller(sessionId);
4078
- }
4079
- }
4080
- async function zcashGetShieldedAddress(ctx, sessionId, params) {
4081
- const signer = await _createZcashSigner(ctx, sessionId);
4082
- const path = normalizePath(params.path);
4083
- try {
4084
- const result = await signer.getShieldedAddress(path, {
4085
- checkOnDevice: params.showOnDevice ?? false
4086
- });
4087
- return { address: result.address, path: params.path };
4088
- } catch (err) {
4089
- ctx.invalidateSession(sessionId);
4090
- throw ctx.wrapError(err);
4091
- } finally {
4092
- ctx.clearCanceller(sessionId);
4093
- }
4094
- }
4095
- async function _createZcashSigner(ctx, sessionId) {
4096
- const dmk = await ctx.getOrCreateDmk();
4097
- const { SignerZcashBuilder } = await ctx.importLedgerKit("@ledgerhq/device-signer-kit-zcash");
4098
- const sdkSigner = new SignerZcashBuilder({ dmk, sessionId }).build();
4099
- const signer = new SignerZcash(sdkSigner);
4100
- signer.onInteraction = (interaction) => {
4101
- debugLog("[LedgerConnector] zcash.onInteraction:", interaction);
4102
- ctx.emit("ui-event", {
4103
- type: collapseSignerInteraction(interaction),
4104
- payload: { sessionId }
4105
- });
4106
- };
4107
- signer.onRegisterCanceller = (cancel) => ctx.registerCanceller(sessionId, cancel);
4108
- return signer;
4109
- }
4110
-
4111
3455
  // src/connector/chains/tron.ts
4112
3456
  import { HardwareErrorCode as HardwareErrorCode7 } from "@onekeyfe/hwk-adapter-core";
4113
3457
  import Trx from "@ledgerhq/hw-app-trx";
@@ -4128,7 +3472,6 @@ var APP_NAME_MAP = {
4128
3472
  BTC: "Bitcoin",
4129
3473
  SOL: "Solana",
4130
3474
  TRX: "Tron",
4131
- ZEC: "Zcash",
4132
3475
  XRP: "XRP",
4133
3476
  ADA: "Cardano",
4134
3477
  DOT: "Polkadot",
@@ -4642,7 +3985,7 @@ var DeviceApps = class {
4642
3985
  seTargetId: v.seTargetId,
4643
3986
  mcuTargetId: v.mcuTargetId,
4644
3987
  seVersion: v.seVersion,
4645
- seFlagsHex: bytesToHex3(v.seFlags),
3988
+ seFlagsHex: bytesToHex2(v.seFlags),
4646
3989
  mcuSephVersion: v.mcuSephVersion,
4647
3990
  mcuBootloaderVersion: v.mcuBootloaderVersion,
4648
3991
  hwVersion: v.hwVersion
@@ -4716,7 +4059,7 @@ var DeviceApps = class {
4716
4059
  }
4717
4060
  }
4718
4061
  };
4719
- function bytesToHex3(bytes) {
4062
+ function bytesToHex2(bytes) {
4720
4063
  if (!bytes) return "";
4721
4064
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
4722
4065
  }
@@ -4759,8 +4102,7 @@ var METHOD_PREFIX_TO_APP_NAME = {
4759
4102
  evm: "Ethereum",
4760
4103
  btc: "Bitcoin",
4761
4104
  sol: "Solana",
4762
- tron: "Tron",
4763
- zcash: "Zcash"
4105
+ tron: "Tron"
4764
4106
  };
4765
4107
  var HARDWARE_ERROR_CODE_VALUES = new Set(
4766
4108
  Object.values(HardwareErrorCode8).filter((value) => typeof value === "number")
@@ -4800,8 +4142,6 @@ async function defaultLedgerKitImporter(pkg) {
4800
4142
  return import("@ledgerhq/device-signer-kit-bitcoin");
4801
4143
  case "@ledgerhq/device-signer-kit-solana":
4802
4144
  return import("@ledgerhq/device-signer-kit-solana");
4803
- case "@ledgerhq/device-signer-kit-zcash":
4804
- return import("@ledgerhq/device-signer-kit-zcash");
4805
4145
  case "@ledgerhq/context-module":
4806
4146
  return import("@ledgerhq/context-module");
4807
4147
  default:
@@ -5219,11 +4559,6 @@ var LedgerConnectorBase = class {
5219
4559
  return solSignTransaction(ctx, sessionId, params);
5220
4560
  case "solSignMessage":
5221
4561
  return solSignMessage(ctx, sessionId, params);
5222
- // ZCASH
5223
- case "zcashGetFullViewingKey":
5224
- return zcashGetFullViewingKey(ctx, sessionId, params);
5225
- case "zcashGetShieldedAddress":
5226
- return zcashGetShieldedAddress(ctx, sessionId, params);
5227
4562
  // TRON
5228
4563
  case "tronGetAddress":
5229
4564
  return tronGetAddress(ctx, sessionId, params);
@@ -5553,7 +4888,7 @@ var LedgerConnectorBase = class {
5553
4888
  * at every catch site. Falls through unchanged for unknown methods.
5554
4889
  */
5555
4890
  _ctxForMethod(method) {
5556
- const prefix = /^(evm|btc|sol|tron|zcash)/.exec(method)?.[1];
4891
+ const prefix = /^(evm|btc|sol|tron)/.exec(method)?.[1];
5557
4892
  const defaultAppName = prefix ? METHOD_PREFIX_TO_APP_NAME[prefix] : void 0;
5558
4893
  if (!defaultAppName) return this._ctx;
5559
4894
  return {
@@ -5597,7 +4932,6 @@ export {
5597
4932
  SignerEth,
5598
4933
  SignerManager,
5599
4934
  SignerSol,
5600
- SignerZcash,
5601
4935
  debugLog,
5602
4936
  deviceActionToPromise,
5603
4937
  isDeviceLockedError,