@onekeyfe/hd-core 1.2.0-alpha.135 → 1.2.0-alpha.136

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.
@@ -930,17 +930,6 @@ export class Device extends EventEmitter {
930
930
  };
931
931
 
932
932
  const expectedDeviceId = options?.deviceId;
933
- if (expectedDeviceId) {
934
- // 先只读校验物理设备身份;钱包上下文仍由下方携带完整参数的
935
- // Initialize 选择,避免标准钱包请求复用此前的隐藏钱包上下文。
936
- this.passphraseState = undefined;
937
- const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
938
- this._updateFeatures(message);
939
- await TransportManager.reconfigure(this.features);
940
- if (!this.checkDeviceId(expectedDeviceId)) {
941
- throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
942
- }
943
- }
944
933
 
945
934
  this.passphraseState = options?.passphraseState;
946
935
 
@@ -960,7 +949,46 @@ export class Device extends EventEmitter {
960
949
  payload.derive_cardano = true;
961
950
  }
962
951
 
963
- await callInitialize(payload, options?.initSession);
952
+ if (this.features) {
953
+ // Re-sync the V1 message schema for THIS device before encoding
954
+ // Initialize: the process-global schema may still reflect another
955
+ // device (e.g. legacy-firmware Touch/Mini) on multi-device setups, and
956
+ // a stale legacy schema would silently strip passphrase_state /
957
+ // is_contains_attach from the wire message. Local operation, no wire
958
+ // I/O; a no-op when the schema is unchanged.
959
+ await TransportManager.reconfigure(this.features);
960
+ }
961
+
962
+ // Initialize's own Features response carries device_id, so the physical
963
+ // device identity is validated on the same round trip instead of via a
964
+ // separate read-only GetFeatures preflight (which doubled the wire cost
965
+ // of every deviceId-carrying call). The method fn has not run yet, so a
966
+ // mismatch still fails before any wallet data can be derived, with the
967
+ // same DeviceCheckDeviceIdError. Wallet-context selection is unchanged:
968
+ // it is decided by the Initialize payload above either way.
969
+ const assertExpectedDeviceIdentity = () => {
970
+ if (expectedDeviceId && !this.checkDeviceId(expectedDeviceId)) {
971
+ // The mismatched Initialize may have cached a session under the wrong
972
+ // device's identity; drop it so no wallet context survives from it.
973
+ // (This also evicts any session the wrong device legitimately cached
974
+ // under the same passphraseState — a deliberate conservative purge
975
+ // after a physical-swap event, consistent with
976
+ // reconcileDeviceIdentity purging the previous device's sessions.)
977
+ this.clearInternalState();
978
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
979
+ }
980
+ };
981
+
982
+ try {
983
+ await callInitialize(payload, options?.initSession);
984
+ } catch (error) {
985
+ // callInitialize can fail AFTER the wire call cached the session (e.g.
986
+ // TransportManager.reconfigure rejecting); the identity check must
987
+ // still run so a wrong-device session never survives the error path.
988
+ assertExpectedDeviceIdentity();
989
+ throw error;
990
+ }
991
+ assertExpectedDeviceIdentity();
964
992
  } catch (error) {
965
993
  Log.error('Initialization failed:', error);
966
994
  throw error;
@@ -1530,18 +1558,15 @@ export class Device extends EventEmitter {
1530
1558
  const error = ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
1531
1559
  const cleanupPromise = this.runCleanupPromise;
1532
1560
  const { cancelableAction } = this;
1533
- const env = DataManager.getSettings('env');
1534
1561
  if (cancelableAction) {
1535
1562
  await cancelableAction(error);
1536
1563
  } else if (
1537
1564
  this.isProtocolV2() &&
1538
- (DataManager.isBleConnect(env) ||
1539
- DataManager.isBrowserWebUsb(env) ||
1540
- DataManager.isDesktopWebUsb(env)) &&
1565
+ DataManager.isBleConnect(DataManager.getSettings('env')) &&
1541
1566
  this.hasDeviceAcquire()
1542
1567
  ) {
1543
1568
  await this.commands?.cancelDevice?.().catch(cancelError => {
1544
- Log.debug('Protocol V2 fallback cancel error', cancelError);
1569
+ Log.debug('Protocol V2 BLE fallback cancel error', cancelError);
1545
1570
  });
1546
1571
  }
1547
1572
  await this.commands?.cancel();
@@ -69,7 +69,7 @@ const DEVICE_CONTROL_CALLS = new Set([
69
69
  // Older Protocol V2 firmware may omit the cancellation subcode, so retain a
70
70
  // narrow message fallback for compatibility.
71
71
  const isProtocolV2ActionCancelledMessage = (message: string) =>
72
- /^(?:cancel(?:led|ed)(?: on device)?|confirm dismissed|update cancel(?:led|ed)|user cancel(?:led|ed)(?:\s+.*)?)$/i.test(
72
+ /^(?:cancel(?:led|ed)(?: on device)?|confirm dismissed|user cancel(?:led|ed)(?:\s+.*)?)$/i.test(
73
73
  message
74
74
  );
75
75