@onekeyfe/hwk-ledger-adapter 1.2.5-alpha.2 → 1.2.5-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -102,8 +102,8 @@ declare class LedgerAdapter implements IHardwareWallet {
102
102
  private readonly _operations;
103
103
  private _discoveredDevices;
104
104
  private _sessions;
105
- private readonly _pendingOperationBindings;
106
- private readonly _verifiedBleReconnectTargets;
105
+ private readonly _sessionTransports;
106
+ private readonly _selectedBleReconnectTargets;
107
107
  private readonly _uiRegistry;
108
108
  private _btcHighIndexConfirmedThisSession;
109
109
  private readonly _jobQueue;
@@ -153,6 +153,7 @@ declare class LedgerAdapter implements IHardwareWallet {
153
153
  private _installProgressLastKey;
154
154
  private static _createDeviceBusyError;
155
155
  connectDevice(searchTargetId: string): Promise<Response<string>>;
156
+ /** Ledger binds whichever BLE device the user picks; its wallet is not checked. */
156
157
  bindBleDevice(params: BindBleDeviceParams): Promise<Response<string>>;
157
158
  acquireOperation(connectId: string, context: IHardwareConnectionContext): Promise<Response<string>>;
158
159
  private _createOperation;
@@ -212,8 +213,9 @@ declare class LedgerAdapter implements IHardwareWallet {
212
213
  cancel(connectId?: string): void;
213
214
  /** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
214
215
  getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
215
- /** Discovery may select a BLE target before a later call verifies its wallet. */
216
- private _publishVerifiedBleBinding;
216
+ /** Ledger takes the selected BLE endpoint as the device and binds it right away. */
217
+ private _saveSelectedBleBinding;
218
+ private _dropSession;
217
219
  /** Verify on the acquired session without re-entering the job queue. */
218
220
  private _verifyDeviceFingerprintWithSession;
219
221
  /**
package/dist/index.d.ts CHANGED
@@ -102,8 +102,8 @@ declare class LedgerAdapter implements IHardwareWallet {
102
102
  private readonly _operations;
103
103
  private _discoveredDevices;
104
104
  private _sessions;
105
- private readonly _pendingOperationBindings;
106
- private readonly _verifiedBleReconnectTargets;
105
+ private readonly _sessionTransports;
106
+ private readonly _selectedBleReconnectTargets;
107
107
  private readonly _uiRegistry;
108
108
  private _btcHighIndexConfirmedThisSession;
109
109
  private readonly _jobQueue;
@@ -153,6 +153,7 @@ declare class LedgerAdapter implements IHardwareWallet {
153
153
  private _installProgressLastKey;
154
154
  private static _createDeviceBusyError;
155
155
  connectDevice(searchTargetId: string): Promise<Response<string>>;
156
+ /** Ledger binds whichever BLE device the user picks; its wallet is not checked. */
156
157
  bindBleDevice(params: BindBleDeviceParams): Promise<Response<string>>;
157
158
  acquireOperation(connectId: string, context: IHardwareConnectionContext): Promise<Response<string>>;
158
159
  private _createOperation;
@@ -212,8 +213,9 @@ declare class LedgerAdapter implements IHardwareWallet {
212
213
  cancel(connectId?: string): void;
213
214
  /** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
214
215
  getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
215
- /** Discovery may select a BLE target before a later call verifies its wallet. */
216
- private _publishVerifiedBleBinding;
216
+ /** Ledger takes the selected BLE endpoint as the device and binds it right away. */
217
+ private _saveSelectedBleBinding;
218
+ private _dropSession;
217
219
  /** Verify on the acquired session without re-entering the job queue. */
218
220
  private _verifyDeviceFingerprintWithSession;
219
221
  /**
package/dist/index.js CHANGED
@@ -892,11 +892,6 @@ var _LedgerAdapter = class _LedgerAdapter {
892
892
  this._operations = new import_hwk_adapter_core3.OperationRegistry({
893
893
  vendor: "ledger",
894
894
  onEnded: (operation, reason) => {
895
- const binding = this._pendingOperationBindings.get(operation.operationId);
896
- if (binding?.selectedConnection?.requestId === this._bindingSelectionRequestId) {
897
- this._finishBleBinding("cancelled");
898
- }
899
- this._pendingOperationBindings.delete(operation.operationId);
900
895
  this.emitter.emit(import_hwk_adapter_core3.SDK.OPERATION_ENDED, {
901
896
  type: import_hwk_adapter_core3.SDK.OPERATION_ENDED,
902
897
  payload: { operationId: operation.operationId, reason }
@@ -908,8 +903,10 @@ var _LedgerAdapter = class _LedgerAdapter {
908
903
  });
909
904
  this._discoveredDevices = /* @__PURE__ */ new Map();
910
905
  this._sessions = /* @__PURE__ */ new Map();
911
- this._pendingOperationBindings = /* @__PURE__ */ new Map();
912
- this._verifiedBleReconnectTargets = /* @__PURE__ */ new Map();
906
+ // Transport each session was opened on, by sessionId. The adapter-wide
907
+ // `_activeConnectionType` moves with every discovery and can go stale.
908
+ this._sessionTransports = /* @__PURE__ */ new Map();
909
+ this._selectedBleReconnectTargets = /* @__PURE__ */ new Map();
913
910
  this._uiRegistry = new import_hwk_adapter_core3.UiRequestRegistry();
914
911
  // BTC App rejects account index >= 100 unless display=true. Cached per
915
912
  // adapter instance: first 100+ path asks the user once via UI request,
@@ -1083,7 +1080,8 @@ var _LedgerAdapter = class _LedgerAdapter {
1083
1080
  this._doConnectAbortController?.abort();
1084
1081
  this._discoveredDevices.clear();
1085
1082
  this._sessions.clear();
1086
- this._verifiedBleReconnectTargets.clear();
1083
+ this._sessionTransports.clear();
1084
+ this._selectedBleReconnectTargets.clear();
1087
1085
  this._connectingPromise = null;
1088
1086
  this._doConnectAbortController = null;
1089
1087
  this._uiRegistry.reset();
@@ -1193,6 +1191,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1193
1191
  if (this._sessions.size === 0) return;
1194
1192
  const stale = [...this._sessions.values()];
1195
1193
  this._sessions.clear();
1194
+ for (const sid of stale) this._sessionTransports.delete(sid);
1196
1195
  await this._runConnectorTeardown(async () => {
1197
1196
  for (const sid of stale) {
1198
1197
  try {
@@ -1226,14 +1225,11 @@ var _LedgerAdapter = class _LedgerAdapter {
1226
1225
  return this.errorToFailure(error);
1227
1226
  }
1228
1227
  }
1228
+ /** Ledger binds whichever BLE device the user picks; its wallet is not checked. */
1229
1229
  async bindBleDevice(params) {
1230
- if (params.identity.vendor !== "ledger" || !params.identity.value) {
1231
- return (0, import_hwk_adapter_core3.failure)(import_hwk_adapter_core3.HardwareErrorCode.InvalidParams, "Ledger wallet identity is required");
1232
- }
1233
- const { chain, value: expectedFingerprint } = params.identity;
1234
1230
  try {
1235
1231
  return await this._jobQueue.enqueue(
1236
- expectedFingerprint,
1232
+ "__ledger_bind_ble__",
1237
1233
  async (signal) => {
1238
1234
  if (!this.getAvailableTransports().includes("ble")) {
1239
1235
  throw (0, import_hwk_adapter_core3.createHwkError)({
@@ -1248,73 +1244,23 @@ var _LedgerAdapter = class _LedgerAdapter {
1248
1244
  bindingReason: "manual-rebind"
1249
1245
  };
1250
1246
  try {
1251
- for (; ; ) {
1252
- const connectId = await this._connectFirstOrSelect(
1253
- [],
1254
- void 0,
1255
- true,
1256
- void 0,
1257
- attempt,
1258
- signal
1259
- );
1260
- const sessionId = this._sessions.get(connectId);
1261
- if (!sessionId) {
1262
- throw (0, import_hwk_adapter_core3.createHwkError)({
1263
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
1264
- message: "Selected Ledger connection ended"
1265
- });
1266
- }
1267
- let saved = false;
1268
- try {
1269
- const installContext = {
1270
- connection: { connectId, sessionId }
1271
- };
1272
- const fingerprint = await this._computeChainFingerprint(
1273
- chain,
1274
- (method, callParams) => this._runConnectorCall(
1275
- connectId,
1276
- method,
1277
- callParams,
1278
- signal,
1279
- void 0,
1280
- void 0,
1281
- { autoInstallApp: true },
1282
- installContext
1283
- )
1284
- );
1285
- if (fingerprint !== expectedFingerprint) {
1286
- attempt.rejectedConnectIds ?? (attempt.rejectedConnectIds = /* @__PURE__ */ new Set());
1287
- attempt.rejectedConnectIds.add(connectId);
1288
- attempt.rejectedConnectId = connectId;
1289
- } else {
1290
- const persisted = await this._publishVerifiedBleBinding(
1291
- connectId,
1292
- chain,
1293
- fingerprint,
1294
- attempt,
1295
- void 0,
1296
- signal
1297
- );
1298
- if (!persisted) {
1299
- throw (0, import_hwk_adapter_core3.createHwkError)({
1300
- code: import_hwk_adapter_core3.HardwareErrorCode.UnknownError,
1301
- message: "Bluetooth binding could not be saved",
1302
- origin: "host"
1303
- });
1304
- }
1305
- saved = true;
1306
- return (0, import_hwk_adapter_core3.success)(connectId);
1307
- }
1308
- } finally {
1309
- if (!saved && this._sessions.get(connectId) === sessionId) {
1310
- this._sessions.delete(connectId);
1311
- const teardown = this._runConnectorTeardown(
1312
- () => this.connector.disconnect(sessionId)
1313
- ).catch(() => void 0);
1314
- if (!signal.aborted) await teardown;
1315
- }
1316
- }
1247
+ const connectId = await this._connectFirstOrSelect(
1248
+ [],
1249
+ void 0,
1250
+ true,
1251
+ void 0,
1252
+ attempt,
1253
+ signal
1254
+ );
1255
+ if (!attempt.bindingSaved) {
1256
+ await this._dropSession(connectId, signal);
1257
+ throw (0, import_hwk_adapter_core3.createHwkError)({
1258
+ code: import_hwk_adapter_core3.HardwareErrorCode.UnknownError,
1259
+ message: "Bluetooth binding could not be saved",
1260
+ origin: "host"
1261
+ });
1317
1262
  }
1263
+ return (0, import_hwk_adapter_core3.success)(connectId);
1318
1264
  } catch (error) {
1319
1265
  this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
1320
1266
  throw error;
@@ -1354,11 +1300,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1354
1300
  attempt
1355
1301
  );
1356
1302
  _LedgerAdapter._throwIfAborted(signal);
1357
- const result = this._createOperation(connectId, resolvedConnectId);
1358
- if (result.success && attempt.selectedConnection) {
1359
- this._pendingOperationBindings.set(result.payload, attempt);
1360
- }
1361
- return result;
1303
+ return this._createOperation(connectId, resolvedConnectId);
1362
1304
  } catch (error) {
1363
1305
  this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
1364
1306
  throw error;
@@ -1378,7 +1320,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1378
1320
  this._operations.endByConnectionKey(resolvedConnectId, "explicit");
1379
1321
  const sessionId = this._sessions.get(resolvedConnectId);
1380
1322
  if (sessionId) this._operations.endByConnectionKey(sessionId, "explicit");
1381
- const connectionType = this._isBleConnection() ? "ble" : "usb";
1323
+ const connectionType = sessionId && this._sessionTransports.get(sessionId) || (this._isBleConnection() ? "ble" : "usb");
1382
1324
  const device = this._discoveredDevices.get(resolvedConnectId) ?? {
1383
1325
  vendor: "ledger",
1384
1326
  model: "unknown",
@@ -1444,6 +1386,7 @@ var _LedgerAdapter = class _LedgerAdapter {
1444
1386
  }
1445
1387
  const resolvedConnectId = session.deviceInfo?.connectId || connectId;
1446
1388
  this._sessions.set(resolvedConnectId, session.sessionId);
1389
+ this._sessionTransports.set(session.sessionId, this._isBleConnection() ? "ble" : "usb");
1447
1390
  if (session.deviceInfo) {
1448
1391
  this._discoveredDevices.set(resolvedConnectId, session.deviceInfo);
1449
1392
  }
@@ -1972,10 +1915,6 @@ var _LedgerAdapter = class _LedgerAdapter {
1972
1915
  this._uiRegistry.cancel(void 0, void 0, pendingOperationId);
1973
1916
  }
1974
1917
  this._finishBleBinding("cancelled");
1975
- if (!connectId) this._pendingOperationBindings.clear();
1976
- else if (pendingOperationId) {
1977
- this._pendingOperationBindings.delete(pendingOperationId);
1978
- }
1979
1918
  const queueKeys = /* @__PURE__ */ new Set();
1980
1919
  if (connectId) queueKeys.add(ledgerQueueKey({ connectId }));
1981
1920
  if (pendingOperationId) queueKeys.add(ledgerQueueKey({ operationId: pendingOperationId }));
@@ -2020,16 +1959,6 @@ var _LedgerAdapter = class _LedgerAdapter {
2020
1959
  formatDeviceMismatchError(deviceId, fingerprint)
2021
1960
  );
2022
1961
  }
2023
- if ((0, import_hwk_adapter_core3.isHardwareOperationId)(connectId)) {
2024
- const operation = this._operations.resolve(connectId);
2025
- await this._publishVerifiedBleBinding(
2026
- operation.connectId,
2027
- chain,
2028
- fingerprint,
2029
- void 0,
2030
- connectId
2031
- );
2032
- }
2033
1962
  }
2034
1963
  return (0, import_hwk_adapter_core3.success)(fingerprint);
2035
1964
  } catch (err) {
@@ -2037,56 +1966,46 @@ var _LedgerAdapter = class _LedgerAdapter {
2037
1966
  return this.errorToFailure(err);
2038
1967
  }
2039
1968
  }
2040
- /** Discovery may select a BLE target before a later call verifies its wallet. */
2041
- async _publishVerifiedBleBinding(connectId, chain, fingerprint, attempt, operationId, signal) {
2042
- const binding = operationId ? this._pendingOperationBindings.get(operationId) : attempt;
2043
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== connectId) {
2044
- return false;
2045
- }
1969
+ /** Ledger takes the selected BLE endpoint as the device and binds it right away. */
1970
+ async _saveSelectedBleBinding(connectId, selectionRequestId, context, operationId, signal) {
2046
1971
  try {
2047
1972
  const outcome = await (0, import_hwk_adapter_core3.requestSaveDeviceBinding)(
2048
1973
  this.emitter,
2049
1974
  this._uiRegistry,
2050
1975
  {
2051
- selectionRequestId: binding.selectedConnection.requestId,
1976
+ selectionRequestId,
2052
1977
  connection: { transport: "ble", connectId },
2053
- identity: { vendor: "ledger", type: "chainFingerprint", chain, value: fingerprint },
2054
- extra: binding.extra,
1978
+ extra: context?.extra,
2055
1979
  operationId
2056
1980
  },
2057
1981
  signal
2058
1982
  );
2059
- if (operationId) this._operations.resolve(operationId);
1983
+ if (context) context.bindingSaved = outcome.saved;
2060
1984
  if (!outcome.saved) {
2061
1985
  debugLog("[LedgerAdapter] BLE binding not persisted by host", {
2062
1986
  connectId,
2063
1987
  reason: outcome.reason
2064
1988
  });
2065
1989
  }
2066
- return outcome.saved;
2067
1990
  } catch (error) {
2068
- if (operationId) {
2069
- this._pendingOperationBindings.delete(operationId);
2070
- this._operations.end(operationId, "explicit");
2071
- }
2072
- const sessionId = this._sessions.get(connectId);
2073
- this._sessions.delete(connectId);
2074
- if (sessionId) {
2075
- const teardown = this._runConnectorTeardown(
2076
- () => this.connector.disconnect(sessionId)
2077
- ).catch(() => void 0);
2078
- if (!signal?.aborted) await teardown;
2079
- }
1991
+ await this._dropSession(connectId, signal);
2080
1992
  throw error;
2081
1993
  } finally {
2082
- if (this._bindingSelectionRequestId === binding.selectedConnection.requestId) {
1994
+ if (this._bindingSelectionRequestId === selectionRequestId) {
2083
1995
  this._bindingSelectionRequestId = void 0;
2084
1996
  }
2085
- if (operationId) {
2086
- this._pendingOperationBindings.delete(operationId);
2087
- }
2088
1997
  }
2089
1998
  }
1999
+ async _dropSession(connectId, signal) {
2000
+ const sessionId = this._sessions.get(connectId);
2001
+ this._sessions.delete(connectId);
2002
+ if (!sessionId) return;
2003
+ this._sessionTransports.delete(sessionId);
2004
+ const teardown = this._runConnectorTeardown(() => this.connector.disconnect(sessionId)).catch(
2005
+ () => void 0
2006
+ );
2007
+ if (!signal.aborted) await teardown;
2008
+ }
2090
2009
  /** Verify on the acquired session without re-entering the job queue. */
2091
2010
  async _verifyDeviceFingerprintWithSession(sessionId, deviceId, chain) {
2092
2011
  if (!deviceId) return { success: true };
@@ -2481,12 +2400,11 @@ var _LedgerAdapter = class _LedgerAdapter {
2481
2400
  ) ?? (usbDevices.length === 1 && usbDevices[0].connectionType === "usb" ? usbDevices[0] : void 0);
2482
2401
  if (candidate) return [candidate];
2483
2402
  }
2484
- return (await this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)).filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId));
2403
+ return this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal);
2485
2404
  },
2486
2405
  request: {
2487
- devices: devices.filter((device2) => !context?.rejectedConnectIds?.has(device2.connectId)),
2406
+ devices,
2488
2407
  bindingSessionId,
2489
- rejectedConnectId: context?.rejectedConnectId,
2490
2408
  context: {
2491
2409
  kind: "bind-connection",
2492
2410
  transport: "ble",
@@ -2499,14 +2417,25 @@ var _LedgerAdapter = class _LedgerAdapter {
2499
2417
  if (device.connectionType === "usb") {
2500
2418
  this._activeConnectionType = "usb";
2501
2419
  if (context) context.selectedConnection = void 0;
2502
- if (preserveOperationId) this._pendingOperationBindings.delete(preserveOperationId);
2503
2420
  this._bindingSelectionRequestId = requestId;
2504
2421
  this._finishBleBinding("cancelled");
2505
2422
  return this._connectDeviceOrThrow(device.connectId, preserveOperationId, signal);
2506
2423
  }
2507
- if (context) context.selectedConnection = { connectId: device.connectId, requestId };
2508
2424
  this._bindingSelectionRequestId = requestId;
2509
- return this._connectDeviceOrThrow(device.connectId, preserveOperationId, signal);
2425
+ const connected = await this._connectDeviceOrThrow(
2426
+ device.connectId,
2427
+ preserveOperationId,
2428
+ signal
2429
+ );
2430
+ if (context) context.selectedConnection = { connectId: connected, requestId };
2431
+ await this._saveSelectedBleBinding(
2432
+ connected,
2433
+ requestId,
2434
+ context,
2435
+ preserveOperationId,
2436
+ signal
2437
+ );
2438
+ return connected;
2510
2439
  }
2511
2440
  if (devices.length > 0 && (devices.length > 1 || requiresBleSelection)) {
2512
2441
  if (context?.allowDeviceSelection === false || !this.emitter.listenerCount(import_hwk_adapter_core3.UI_REQUEST.REQUEST_SELECT_DEVICE)) {
@@ -2801,13 +2730,13 @@ var _LedgerAdapter = class _LedgerAdapter {
2801
2730
  }
2802
2731
  const allowUsbEphemeralFallback = !!fingerprint?.deviceId && !fingerprint.skipFingerprint;
2803
2732
  let businessCallStarted = false;
2804
- const verifiedBleTarget = connectId ? this._verifiedBleReconnectTargets.get(connectId) : void 0;
2733
+ const selectedBleTarget = connectId ? this._selectedBleReconnectTargets.get(connectId) : void 0;
2805
2734
  const knownTransport = this._isBleConnection() ? "ble" : "usb";
2806
2735
  const hintedConnectId = commonParams?.knownConnections?.find(
2807
2736
  (connection) => connection.transport === knownTransport
2808
2737
  );
2809
2738
  const inputConnectId = hintedConnectId && hintedConnectId.transport !== "qr" ? hintedConnectId.connectId : connectId;
2810
- const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && verifiedBleTarget?.chain === fingerprint.chain && verifiedBleTarget.fingerprint === fingerprint.deviceId ? verifiedBleTarget.connectId : inputConnectId;
2739
+ const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && selectedBleTarget?.chain === fingerprint.chain && selectedBleTarget.fingerprint === fingerprint.deviceId ? selectedBleTarget.connectId : inputConnectId;
2811
2740
  const connectionAttempt = { ...commonParams };
2812
2741
  const bundleConnection = installContext?.connection;
2813
2742
  if (bundleConnection && this._sessions.get(bundleConnection.connectId) !== bundleConnection.sessionId) {
@@ -2816,14 +2745,14 @@ var _LedgerAdapter = class _LedgerAdapter {
2816
2745
  message: "Ledger all-network connection ended"
2817
2746
  });
2818
2747
  }
2819
- let resolvedConnectId = operationId ? this._operations.resolve(operationId).connectId : bundleConnection?.connectId ?? await this.ensureConnected(
2748
+ const resolvedConnectId = operationId ? this._operations.resolve(operationId).connectId : bundleConnection?.connectId ?? await this.ensureConnected(
2820
2749
  preferredConnectId,
2821
2750
  signal,
2822
2751
  allowUsbEphemeralFallback,
2823
2752
  void 0,
2824
2753
  connectionAttempt
2825
2754
  );
2826
- let sessionId = this._sessions.get(resolvedConnectId);
2755
+ const sessionId = this._sessions.get(resolvedConnectId);
2827
2756
  if (sessionId && installContext && !installContext.connection) {
2828
2757
  installContext.connection = { connectId: resolvedConnectId, sessionId };
2829
2758
  }
@@ -2841,74 +2770,29 @@ var _LedgerAdapter = class _LedgerAdapter {
2841
2770
  });
2842
2771
  }
2843
2772
  try {
2844
- if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {
2845
- for (; ; ) {
2846
- const fp = await this._abortable(
2847
- signal,
2848
- this._verifyDeviceFingerprintWithSession(
2849
- sessionId,
2850
- fingerprint.deviceId,
2851
- fingerprint.chain
2852
- )
2853
- );
2854
- if (fp.success) break;
2855
- const binding = operationId ? this._pendingOperationBindings.get(operationId) : connectionAttempt;
2856
- if (!this._isBleConnection() || binding?.selectedConnection?.connectId !== resolvedConnectId) {
2857
- throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2858
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2859
- });
2860
- }
2861
- binding.rejectedConnectIds ?? (binding.rejectedConnectIds = /* @__PURE__ */ new Set());
2862
- binding.rejectedConnectIds.add(resolvedConnectId);
2863
- binding.rejectedConnectId = resolvedConnectId;
2864
- this._sessions.delete(resolvedConnectId);
2865
- await this.connector.disconnect(sessionId);
2866
- if (operationId) this._pendingOperationDisconnects.delete(operationId);
2867
- _LedgerAdapter._throwIfAborted(signal);
2868
- resolvedConnectId = await this._connectFirstOrSelect(
2869
- [],
2870
- void 0,
2871
- true,
2872
- operationId,
2873
- binding,
2874
- signal
2875
- );
2876
- const selectedSession = this._sessions.get(resolvedConnectId);
2877
- const selectedDevice = this._discoveredDevices.get(resolvedConnectId);
2878
- if (!selectedSession || !selectedDevice)
2879
- throw (0, import_hwk_adapter_core3.createHwkError)({
2880
- code: import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
2881
- message: "Selected Ledger connection ended"
2882
- });
2883
- sessionId = selectedSession;
2884
- if (operationId)
2885
- this._operations.rebind(operationId, {
2886
- connectId: resolvedConnectId,
2887
- device: selectedDevice,
2888
- // Same source as `_createOperation`: the selected transport, not
2889
- // the device snapshot a session connect overwrote.
2890
- connectionType: this._isBleConnection() ? "ble" : "usb",
2891
- connectionKeys: [sessionId]
2892
- });
2893
- if (installContext)
2894
- installContext.connection = { connectId: resolvedConnectId, sessionId };
2895
- }
2896
- await this._publishVerifiedBleBinding(
2897
- resolvedConnectId,
2898
- fingerprint.chain,
2899
- fingerprint.deviceId,
2900
- connectionAttempt,
2901
- operationId,
2902
- signal
2773
+ const isBleSession = this._sessionTransports.get(sessionId) === "ble";
2774
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId && !isBleSession) {
2775
+ const fp = await this._abortable(
2776
+ signal,
2777
+ this._verifyDeviceFingerprintWithSession(
2778
+ sessionId,
2779
+ fingerprint.deviceId,
2780
+ fingerprint.chain
2781
+ )
2903
2782
  );
2904
- if (!operationId && connectionAttempt.selectedConnection?.connectId === resolvedConnectId && this._isBleConnection()) {
2905
- this._verifiedBleReconnectTargets.set(connectId, {
2906
- connectId: resolvedConnectId,
2907
- chain: fingerprint.chain,
2908
- fingerprint: fingerprint.deviceId
2783
+ if (!fp.success) {
2784
+ throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
2785
+ code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
2909
2786
  });
2910
2787
  }
2911
2788
  }
2789
+ if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId && !operationId && isBleSession && connectionAttempt.selectedConnection?.connectId === resolvedConnectId) {
2790
+ this._selectedBleReconnectTargets.set(connectId, {
2791
+ connectId: resolvedConnectId,
2792
+ chain: fingerprint.chain,
2793
+ fingerprint: fingerprint.deviceId
2794
+ });
2795
+ }
2912
2796
  businessCallStarted = true;
2913
2797
  return await this._callConnector(sessionId, method, effectiveParams, signal);
2914
2798
  } catch (err) {