@onekeyfe/hd-core 1.2.5 → 1.2.6-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -44209,6 +44209,12 @@ class DeviceCommands {
44209
44209
  const isProtocolV2DeviceBusyFailure = this.device.isProtocolV2() &&
44210
44210
  DEVICE_CONTROL_CALLS.has(callType) &&
44211
44211
  subcode === hdTransport.DeviceErrorCode.DeviceError_Busy;
44212
+ const isProtocolV2PinCancelledBusyFailure = this.device.isProtocolV2() &&
44213
+ !DEVICE_SESSION_CALLS.has(callType) &&
44214
+ subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_UserCancelled &&
44215
+ /^pin cancelled$/i.test(normalizedMessage);
44216
+ const isProtocolV2FirmwareUpdateBusyFailure = this.device.isProtocolV2() &&
44217
+ /^requested command not allowed while a firmware update is in progress$/i.test(normalizedMessage);
44212
44218
  const isLegacyProtocolV2LockedFailure = this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(normalizedMessage);
44213
44219
  if (DEVICE_SESSION_CALLS.has(callType) &&
44214
44220
  subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_InvalidSession) {
@@ -44259,7 +44265,9 @@ class DeviceCommands {
44259
44265
  firmwareMessage: message,
44260
44266
  });
44261
44267
  }
44262
- else if (isProtocolV2DeviceBusyFailure) {
44268
+ else if (isProtocolV2DeviceBusyFailure ||
44269
+ isProtocolV2PinCancelledBusyFailure ||
44270
+ isProtocolV2FirmwareUpdateBusyFailure) {
44263
44271
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceBusy, message, {
44264
44272
  failureCode: code,
44265
44273
  subcode,
@@ -44899,7 +44907,7 @@ const mapProtocolV2DeviceInfoToState = (info, mode = 'unknown') => {
44899
44907
  versions: definedEntries({
44900
44908
  firmware: imageVersion((_d = info.main_mcu) === null || _d === void 0 ? void 0 : _d.application),
44901
44909
  applicationP1: imageVersion((_e = info.main_mcu) === null || _e === void 0 ? void 0 : _e.application),
44902
- applicationP2: imageVersion((_f = info.main_mcu) === null || _f === void 0 ? void 0 : _f.application_data),
44910
+ applicationP2: mode === 'normal' ? null : imageVersion((_f = info.main_mcu) === null || _f === void 0 ? void 0 : _f.application_data),
44903
44911
  bootloader: imageVersion((_g = info.main_mcu) === null || _g === void 0 ? void 0 : _g.bootloader),
44904
44912
  board: imageVersion((_h = info.main_mcu) === null || _h === void 0 ? void 0 : _h.romloader),
44905
44913
  ble: imageVersion((_j = info.coprocessor) === null || _j === void 0 ? void 0 : _j.application),
@@ -44917,8 +44925,8 @@ const mapProtocolV2DeviceInfoToState = (info, mode = 'unknown') => {
44917
44925
  firmwareHash: imageHash((_u = info.main_mcu) === null || _u === void 0 ? void 0 : _u.application),
44918
44926
  applicationP1BuildId: imageBuildId((_v = info.main_mcu) === null || _v === void 0 ? void 0 : _v.application),
44919
44927
  applicationP1Hash: imageHash((_w = info.main_mcu) === null || _w === void 0 ? void 0 : _w.application),
44920
- applicationP2BuildId: imageBuildId((_x = info.main_mcu) === null || _x === void 0 ? void 0 : _x.application_data),
44921
- applicationP2Hash: imageHash((_y = info.main_mcu) === null || _y === void 0 ? void 0 : _y.application_data),
44928
+ applicationP2BuildId: mode === 'normal' ? null : imageBuildId((_x = info.main_mcu) === null || _x === void 0 ? void 0 : _x.application_data),
44929
+ applicationP2Hash: mode === 'normal' ? null : imageHash((_y = info.main_mcu) === null || _y === void 0 ? void 0 : _y.application_data),
44922
44930
  bootloaderBuildId: imageBuildId((_z = info.main_mcu) === null || _z === void 0 ? void 0 : _z.bootloader),
44923
44931
  bootloaderHash: imageHash((_0 = info.main_mcu) === null || _0 === void 0 ? void 0 : _0.bootloader),
44924
44932
  boardBuildId: imageBuildId((_1 = info.main_mcu) === null || _1 === void 0 ? void 0 : _1.romloader),
@@ -46655,7 +46663,7 @@ class Device extends events.exports {
46655
46663
  }
46656
46664
  hasUnexpectedMode(allow, require) {
46657
46665
  if (!this.isUnacquired()) {
46658
- if (this.isBootloader() && !this.isProtocolV2() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
46666
+ if ((this.isBootloader() || this.isRomloader()) && !allow.includes(UI_REQUEST.BOOTLOADER)) {
46659
46667
  return UI_REQUEST.BOOTLOADER;
46660
46668
  }
46661
46669
  if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {
@@ -47466,7 +47474,7 @@ class GetDeviceState extends BaseMethod {
47466
47474
  if (this.params.scope === 'settings' &&
47467
47475
  this.device.isProtocolV2() &&
47468
47476
  isLoaderMode(state.status.mode)) {
47469
- throw hdShared.createDeviceNotSupportMethodError(`${this.name}:${this.params.scope}`, this.device.getCurrentFirmwareType());
47477
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.NotAllowInBootloaderMode);
47470
47478
  }
47471
47479
  return state;
47472
47480
  });
@@ -52412,7 +52420,8 @@ const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
52412
52420
  const PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT = 3 * 60 * 1000;
52413
52421
  const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
52414
52422
  const PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT = 15 * 1000;
52415
- const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
52423
+ const PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT = 10 * 1000;
52424
+ const PROTOCOL_V2_INSTALL_TIMEOUT = 10 * 60 * 1000;
52416
52425
  const PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY = 1000;
52417
52426
  const PROTOCOL_V2_INSTALL_FINISHED_AFTER_DISCONNECT_POLLS = 4;
52418
52427
  const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
@@ -52891,8 +52900,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52891
52900
  return __awaiter(this, void 0, void 0, function* () {
52892
52901
  yield this.captureProtocolV2PhysicalIdentity();
52893
52902
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
52894
- this.protocolV2InstallBaselineVersions =
52895
- this.getProtocolV2ObservableTargetVersions(deviceFeatures);
52903
+ this.protocolV2InstallBaselineVersions = this.getProtocolV2ObservableTargetVersions(deviceFeatures, this.protocolV2InitialDeviceInfo);
52896
52904
  this.protocolV2LastRuntimeProbeFeatures = undefined;
52897
52905
  const currentDeviceType = this.device.getCurrentDeviceType();
52898
52906
  const capabilityDeviceType = currentDeviceType === hdShared.EDeviceType.Pro2 || currentDeviceType === hdShared.EDeviceType.Neo
@@ -53297,7 +53305,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53297
53305
  app_v1: features
53298
53306
  ? getDeviceFirmwareVersion(features).join('.')
53299
53307
  : (_c = (_b = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _b === void 0 ? void 0 : _b.application) === null || _c === void 0 ? void 0 : _c.version,
53300
- app_v2: (_e = (_d = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _d === void 0 ? void 0 : _d.application_data) === null || _e === void 0 ? void 0 : _e.version,
53308
+ app_v2: (features === null || features === void 0 ? void 0 : features.mode) === 'normal'
53309
+ ? getDeviceFirmwareVersion(features).join('.')
53310
+ : (_e = (_d = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _d === void 0 ? void 0 : _d.application_data) === null || _e === void 0 ? void 0 : _e.version,
53301
53311
  coprocessor: features ? getDeviceBLEFirmwareVersion(features).join('.') : undefined,
53302
53312
  se01: (_f = features === null || features === void 0 ? void 0 : features.se01Version) !== null && _f !== void 0 ? _f : undefined,
53303
53313
  se02: (_g = features === null || features === void 0 ? void 0 : features.se02Version) !== null && _g !== void 0 ? _g : undefined,
@@ -53308,9 +53318,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53308
53318
  for (const [target, expectedVersion] of expectedEntries) {
53309
53319
  const targetId = (_k = Array.from(PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.entries()).find(([, mappedTarget]) => mappedTarget === target)) === null || _k === void 0 ? void 0 : _k[0];
53310
53320
  const statusVersion = targetId === undefined ? undefined : this.protocolV2CompletedTargetVersions.get(targetId);
53311
- const observedVersion = statusVersion === undefined
53312
- ? visibleVersions[target]
53321
+ const statusVersionString = statusVersion === undefined
53322
+ ? undefined
53313
53323
  : `${Math.floor(statusVersion / 0x10000) % 0x100}.${Math.floor(statusVersion / 0x100) % 0x100}.${statusVersion % 0x100}`;
53324
+ const observedVersion = target === 'app_v2' && visibleVersions.app_v2
53325
+ ? visibleVersions.app_v2
53326
+ : statusVersionString !== null && statusVersionString !== void 0 ? statusVersionString : visibleVersions[target];
53314
53327
  if (!observedVersion) {
53315
53328
  const hasCompleteTargetEvidence = targetId !== undefined && this.protocolV2CompletedTargetIds.has(targetId);
53316
53329
  if (hasCompleteTargetEvidence) {
@@ -53402,11 +53415,16 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53402
53415
  }
53403
53416
  this.protocolV2ExpectedSerialNumber = serialNumber;
53404
53417
  this.protocolV2ExpectedPath = path;
53418
+ this.protocolV2InitialDeviceInfo = deviceInfo;
53405
53419
  });
53406
53420
  }
53407
- verifyProtocolV2ReconnectIdentity() {
53421
+ verifyProtocolV2ReconnectIdentity(request) {
53408
53422
  return __awaiter(this, void 0, void 0, function* () {
53409
- const deviceInfo = yield this.requestProtocolV2PhysicalIdentity();
53423
+ const deviceInfo = yield requestProtocolV2DeviceInfo({
53424
+ commands: this.device.getCommands(),
53425
+ timeoutMs: this.getProtocolV2DeviceInfoTimeout(),
53426
+ request,
53427
+ });
53410
53428
  this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
53411
53429
  return deviceInfo;
53412
53430
  });
@@ -54158,12 +54176,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54158
54176
  });
54159
54177
  return Array.from(expectedTargetIds).filter(targetId => !reportedTargetIds.has(targetId));
54160
54178
  }
54161
- getProtocolV2ObservableTargetVersions(features) {
54179
+ getProtocolV2ObservableTargetVersions(features, deviceInfo) {
54180
+ var _a, _b;
54162
54181
  const versions = new Map();
54163
54182
  versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, getDeviceBootloaderVersion(features).join('.'));
54164
54183
  const applicationVersion = getDeviceFirmwareVersion(features).join('.');
54165
54184
  versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, applicationVersion);
54166
- versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, applicationVersion);
54185
+ const applicationP2Version = features.mode === 'normal'
54186
+ ? applicationVersion
54187
+ : (_b = (_a = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _a === void 0 ? void 0 : _a.application_data) === null || _b === void 0 ? void 0 : _b.version;
54188
+ if (applicationP2Version) {
54189
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, applicationP2Version);
54190
+ }
54167
54191
  versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR, getDeviceBLEFirmwareVersion(features).join('.'));
54168
54192
  const secureElementVersions = [
54169
54193
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01, features.se01Version],
@@ -54177,17 +54201,31 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54177
54201
  });
54178
54202
  return versions;
54179
54203
  }
54180
- hasProtocolV2InstallVersionChanged(expectedTargetIds) {
54204
+ hasProtocolV2InstallVersionChanged(expectedTargetIds, deviceInfo) {
54181
54205
  if (!this.protocolV2LastRuntimeProbeFeatures)
54182
54206
  return false;
54183
- const currentVersions = this.getProtocolV2ObservableTargetVersions(this.protocolV2LastRuntimeProbeFeatures);
54184
- return Array.from(expectedTargetIds).some(targetId => {
54185
- const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
54186
- const currentVersion = currentVersions.get(targetId);
54187
- return (previousVersion !== undefined &&
54188
- currentVersion !== undefined &&
54189
- previousVersion !== currentVersion);
54190
- });
54207
+ const currentVersions = this.getProtocolV2ObservableTargetVersions(this.protocolV2LastRuntimeProbeFeatures, deviceInfo);
54208
+ const p1TargetId = ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1;
54209
+ const p2TargetId = ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2;
54210
+ return (expectedTargetIds.size > 0 &&
54211
+ Array.from(expectedTargetIds).every(targetId => {
54212
+ var _a, _b, _c;
54213
+ if (targetId === p2TargetId && ((_a = this.protocolV2LastRuntimeProbeFeatures) === null || _a === void 0 ? void 0 : _a.mode) === 'normal') {
54214
+ if (!expectedTargetIds.has(p1TargetId))
54215
+ return false;
54216
+ const previousP1Version = this.protocolV2InstallBaselineVersions.get(p1TargetId);
54217
+ const currentP1Version = currentVersions.get(p1TargetId);
54218
+ return (previousP1Version !== undefined &&
54219
+ currentP1Version !== undefined &&
54220
+ previousP1Version !== currentP1Version &&
54221
+ currentP1Version === ((_c = (_b = this.params) === null || _b === void 0 ? void 0 : _b.expectedTargetVersions) === null || _c === void 0 ? void 0 : _c.app_v2));
54222
+ }
54223
+ const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
54224
+ const currentVersion = currentVersions.get(targetId);
54225
+ return (previousVersion !== undefined &&
54226
+ currentVersion !== undefined &&
54227
+ previousVersion !== currentVersion);
54228
+ }));
54191
54229
  }
54192
54230
  recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds) {
54193
54231
  expectedTargetIds.forEach(targetId => this.protocolV2CompletedTargetIds.add(targetId));
@@ -54224,8 +54262,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54224
54262
  finishedStatusSnapshotKey = undefined;
54225
54263
  finishedStatusSnapshotPolls = 0;
54226
54264
  };
54227
- while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
54265
+ while (true) {
54228
54266
  this.throwIfAborted();
54267
+ const isFinalStatusCheck = Date.now() - startTime >= PROTOCOL_V2_INSTALL_TIMEOUT;
54229
54268
  try {
54230
54269
  if (shouldReconnect) {
54231
54270
  const isBleInstallReconnect = this.isBleReconnect();
@@ -54347,17 +54386,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54347
54386
  lastError = new Error('Protocol V2 firmware status is stale; waiting for the current install to start');
54348
54387
  }
54349
54388
  if (statusTargets.length === 0 &&
54350
- !currentDeviceInfo &&
54351
- bleInstallLinkReady &&
54352
- installEvidenceObserved) {
54353
- currentDeviceInfo = yield this.verifyProtocolV2ReconnectIdentity();
54389
+ (currentDeviceInfo || bleInstallLinkReady || isFinalStatusCheck)) {
54390
+ currentDeviceInfo = yield this.verifyProtocolV2ReconnectIdentity(PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST);
54354
54391
  deviceInfo = currentDeviceInfo;
54355
- }
54356
- if (statusTargets.length === 0 && currentDeviceInfo) {
54357
54392
  const isNormalMode = yield this.probeProtocolV2NormalMode(currentDeviceInfo);
54358
54393
  if (isNormalMode &&
54359
54394
  (installEvidenceObserved ||
54360
- this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
54395
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds, currentDeviceInfo))) {
54361
54396
  Log$6.log('[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete');
54362
54397
  this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
54363
54398
  this.postProgressMessage(100, 'installingFirmware');
@@ -54379,24 +54414,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54379
54414
  }
54380
54415
  }
54381
54416
  catch (error) {
54382
- if (isProtocolV2TerminalInstallStatusError(error)) {
54417
+ if (this.isProtocolV2ReconnectIdentityError(error) ||
54418
+ isProtocolV2TerminalInstallStatusError(error)) {
54383
54419
  throw error;
54384
54420
  }
54385
54421
  if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
54386
- if (!currentDeviceInfo) {
54387
- if (!bleInstallLinkReady) {
54388
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device identity is unavailable during install polling');
54389
- }
54390
- deviceInfo = yield this.verifyProtocolV2ReconnectIdentity();
54391
- }
54392
- const reconnectDeviceInfo = currentDeviceInfo !== null && currentDeviceInfo !== void 0 ? currentDeviceInfo : deviceInfo;
54393
- if (!reconnectDeviceInfo) {
54422
+ if (!currentDeviceInfo && !bleInstallLinkReady && !isFinalStatusCheck) {
54394
54423
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device identity is unavailable during install polling');
54395
54424
  }
54396
- const isNormalMode = yield this.probeProtocolV2NormalMode(reconnectDeviceInfo);
54425
+ deviceInfo = yield this.verifyProtocolV2ReconnectIdentity(PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST);
54426
+ const isNormalMode = yield this.probeProtocolV2NormalMode(deviceInfo);
54397
54427
  if (isNormalMode &&
54398
54428
  (installEvidenceObserved ||
54399
- this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
54429
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds, deviceInfo))) {
54400
54430
  Log$6.log('[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot');
54401
54431
  this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
54402
54432
  this.postProgressMessage(100, 'installingFirmware');
@@ -54437,6 +54467,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54437
54467
  bleInstallLinkReady = false;
54438
54468
  Log$6.log('Protocol V2 firmware install device readiness probe failed: ', error);
54439
54469
  }
54470
+ if (isFinalStatusCheck)
54471
+ break;
54440
54472
  yield hdShared.wait(1000);
54441
54473
  }
54442
54474
  Log$6.error(`[FirmwareUpdateV4] install timed out after ${PROTOCOL_V2_INSTALL_TIMEOUT / 1000}s: ${this.normalizeErrorMessage(lastError)}`);
@@ -54467,7 +54499,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54467
54499
  }
54468
54500
  probeProtocolV2NormalMode(deviceInfo) {
54469
54501
  return __awaiter(this, void 0, void 0, function* () {
54470
- const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
54502
+ const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT, { forceRuntimeContextRefresh: true });
54471
54503
  this.protocolV2LastRuntimeProbeFeatures = features;
54472
54504
  return this.isProtocolV2ApplicationMode(features);
54473
54505
  });
@@ -54627,6 +54659,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54627
54659
  var _a;
54628
54660
  return __awaiter(this, void 0, void 0, function* () {
54629
54661
  const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
54662
+ const env = DataManager.getSettings('env');
54630
54663
  const writeRes = yield typedCall('FilesystemFileWrite', 'FilesystemFile', {
54631
54664
  file: {
54632
54665
  path: filePath,
@@ -54638,6 +54671,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54638
54671
  append: false,
54639
54672
  ui_percentage: progress !== null && progress !== void 0 ? progress : undefined,
54640
54673
  }, {
54674
+ timeoutMs: env === 'react-native' ? PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT : undefined,
54641
54675
  writeWithResponse: false,
54642
54676
  onWriteCompleted: () => undefined,
54643
54677
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.5",
3
+ "version": "1.2.6-alpha.1",
4
4
  "description": "Core processes and APIs for communicating with OneKey hardware devices.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,8 +25,8 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-shared": "1.2.5",
29
- "@onekeyfe/hd-transport": "1.2.5",
28
+ "@onekeyfe/hd-shared": "1.2.6-alpha.1",
29
+ "@onekeyfe/hd-transport": "1.2.6-alpha.1",
30
30
  "axios": "1.15.2",
31
31
  "bignumber.js": "^9.0.2",
32
32
  "buffer": "^6.0.3",
@@ -46,5 +46,5 @@
46
46
  "@types/w3c-web-usb": "^1.0.10",
47
47
  "@types/web-bluetooth": "^0.0.21"
48
48
  },
49
- "gitHead": "c5df28718166f8c55ae7f3fe33b559d67a5c093e"
49
+ "gitHead": "32f41a09724c316ccefe39daae56c22f539d76bd"
50
50
  }
@@ -70,7 +70,7 @@ import type {
70
70
  FirmwareUpdateV4Target,
71
71
  } from '../types/api/firmwareUpdate';
72
72
  import type { EFirmwareType } from '@onekeyfe/hd-shared';
73
- import type { ProtocolV2DeviceInfo } from '@onekeyfe/hd-transport';
73
+ import type { DeviceInfoGet, ProtocolV2DeviceInfo } from '@onekeyfe/hd-transport';
74
74
  import type { TypedResponseMessage } from '../device/DeviceCommands';
75
75
  import type {
76
76
  Features,
@@ -91,7 +91,9 @@ const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
91
91
  const PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT = 3 * 60 * 1000;
92
92
  const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
93
93
  const PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT = 15 * 1000;
94
- const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
94
+ // React Native invalidates a timed-out BLE link, and V4 can safely replay the staging file.
95
+ const PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT = 10 * 1000;
96
+ const PROTOCOL_V2_INSTALL_TIMEOUT = 10 * 60 * 1000;
95
97
  const PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY = 1000;
96
98
  const PROTOCOL_V2_INSTALL_FINISHED_AFTER_DISCONNECT_POLLS = 4;
97
99
  const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
@@ -577,6 +579,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
577
579
 
578
580
  private protocolV2LatestFinalDeviceInfo?: ProtocolV2DeviceInfo;
579
581
 
582
+ private protocolV2InitialDeviceInfo?: ProtocolV2DeviceInfo;
583
+
580
584
  private protocolV2InstallBaselineVersions = new Map<number, string>();
581
585
 
582
586
  private protocolV2InstallNeedsReconnect = false;
@@ -814,8 +818,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
814
818
  private async runProtocolV2() {
815
819
  await this.captureProtocolV2PhysicalIdentity();
816
820
  const deviceFeatures = await this.getProtocolV2DeviceFeatures();
817
- this.protocolV2InstallBaselineVersions =
818
- this.getProtocolV2ObservableTargetVersions(deviceFeatures);
821
+ this.protocolV2InstallBaselineVersions = this.getProtocolV2ObservableTargetVersions(
822
+ deviceFeatures,
823
+ this.protocolV2InitialDeviceInfo
824
+ );
819
825
  this.protocolV2LastRuntimeProbeFeatures = undefined;
820
826
  const currentDeviceType = this.device.getCurrentDeviceType();
821
827
  const capabilityDeviceType =
@@ -1382,7 +1388,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1382
1388
  app_v1: features
1383
1389
  ? getDeviceFirmwareVersion(features).join('.')
1384
1390
  : deviceInfo?.main_mcu?.application?.version,
1385
- app_v2: deviceInfo?.main_mcu?.application_data?.version,
1391
+ // Production boot verifies P2 against P1 before normal firmware can run.
1392
+ app_v2:
1393
+ features?.mode === 'normal'
1394
+ ? getDeviceFirmwareVersion(features).join('.')
1395
+ : deviceInfo?.main_mcu?.application_data?.version,
1386
1396
  coprocessor: features ? getDeviceBLEFirmwareVersion(features).join('.') : undefined,
1387
1397
  se01: features?.se01Version ?? undefined,
1388
1398
  se02: features?.se02Version ?? undefined,
@@ -1398,12 +1408,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1398
1408
  )?.[0];
1399
1409
  const statusVersion =
1400
1410
  targetId === undefined ? undefined : this.protocolV2CompletedTargetVersions.get(targetId);
1401
- const observedVersion =
1411
+ const statusVersionString =
1402
1412
  statusVersion === undefined
1403
- ? visibleVersions[target]
1413
+ ? undefined
1404
1414
  : `${Math.floor(statusVersion / 0x10000) % 0x100}.${
1405
1415
  Math.floor(statusVersion / 0x100) % 0x100
1406
1416
  }.${statusVersion % 0x100}`;
1417
+ const observedVersion =
1418
+ target === 'app_v2' && visibleVersions.app_v2
1419
+ ? visibleVersions.app_v2
1420
+ : statusVersionString ?? visibleVersions[target];
1407
1421
  if (!observedVersion) {
1408
1422
  const hasCompleteTargetEvidence =
1409
1423
  targetId !== undefined && this.protocolV2CompletedTargetIds.has(targetId);
@@ -1511,10 +1525,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1511
1525
  }
1512
1526
  this.protocolV2ExpectedSerialNumber = serialNumber;
1513
1527
  this.protocolV2ExpectedPath = path;
1528
+ this.protocolV2InitialDeviceInfo = deviceInfo;
1514
1529
  }
1515
1530
 
1516
- private async verifyProtocolV2ReconnectIdentity() {
1517
- const deviceInfo = await this.requestProtocolV2PhysicalIdentity();
1531
+ private async verifyProtocolV2ReconnectIdentity(request?: DeviceInfoGet) {
1532
+ const deviceInfo = await requestProtocolV2DeviceInfo({
1533
+ commands: this.device.getCommands(),
1534
+ timeoutMs: this.getProtocolV2DeviceInfoTimeout(),
1535
+ request,
1536
+ });
1518
1537
  this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
1519
1538
  return deviceInfo;
1520
1539
  }
@@ -2505,7 +2524,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2505
2524
  return Array.from(expectedTargetIds).filter(targetId => !reportedTargetIds.has(targetId));
2506
2525
  }
2507
2526
 
2508
- private getProtocolV2ObservableTargetVersions(features: Features) {
2527
+ private getProtocolV2ObservableTargetVersions(
2528
+ features: Features,
2529
+ deviceInfo?: ProtocolV2DeviceInfo
2530
+ ) {
2509
2531
  const versions = new Map<number, string>();
2510
2532
  versions.set(
2511
2533
  ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
@@ -2513,7 +2535,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2513
2535
  );
2514
2536
  const applicationVersion = getDeviceFirmwareVersion(features).join('.');
2515
2537
  versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, applicationVersion);
2516
- versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, applicationVersion);
2538
+ const applicationP2Version =
2539
+ features.mode === 'normal'
2540
+ ? applicationVersion
2541
+ : deviceInfo?.main_mcu?.application_data?.version;
2542
+ if (applicationP2Version) {
2543
+ versions.set(
2544
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2,
2545
+ applicationP2Version
2546
+ );
2547
+ }
2517
2548
  versions.set(
2518
2549
  ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR,
2519
2550
  getDeviceBLEFirmwareVersion(features).join('.')
@@ -2530,20 +2561,41 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2530
2561
  return versions;
2531
2562
  }
2532
2563
 
2533
- private hasProtocolV2InstallVersionChanged(expectedTargetIds: Set<number>) {
2564
+ private hasProtocolV2InstallVersionChanged(
2565
+ expectedTargetIds: Set<number>,
2566
+ deviceInfo: ProtocolV2DeviceInfo
2567
+ ) {
2534
2568
  if (!this.protocolV2LastRuntimeProbeFeatures) return false;
2535
2569
  const currentVersions = this.getProtocolV2ObservableTargetVersions(
2536
- this.protocolV2LastRuntimeProbeFeatures
2570
+ this.protocolV2LastRuntimeProbeFeatures,
2571
+ deviceInfo
2572
+ );
2573
+ const p1TargetId = ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1;
2574
+ const p2TargetId = ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2;
2575
+ return (
2576
+ expectedTargetIds.size > 0 &&
2577
+ Array.from(expectedTargetIds).every(targetId => {
2578
+ if (targetId === p2TargetId && this.protocolV2LastRuntimeProbeFeatures?.mode === 'normal') {
2579
+ // P1 must change in this install; a pre-existing P1 version cannot prove a P2-only update.
2580
+ if (!expectedTargetIds.has(p1TargetId)) return false;
2581
+ const previousP1Version = this.protocolV2InstallBaselineVersions.get(p1TargetId);
2582
+ const currentP1Version = currentVersions.get(p1TargetId);
2583
+ return (
2584
+ previousP1Version !== undefined &&
2585
+ currentP1Version !== undefined &&
2586
+ previousP1Version !== currentP1Version &&
2587
+ currentP1Version === this.params?.expectedTargetVersions?.app_v2
2588
+ );
2589
+ }
2590
+ const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
2591
+ const currentVersion = currentVersions.get(targetId);
2592
+ return (
2593
+ previousVersion !== undefined &&
2594
+ currentVersion !== undefined &&
2595
+ previousVersion !== currentVersion
2596
+ );
2597
+ })
2537
2598
  );
2538
- return Array.from(expectedTargetIds).some(targetId => {
2539
- const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
2540
- const currentVersion = currentVersions.get(targetId);
2541
- return (
2542
- previousVersion !== undefined &&
2543
- currentVersion !== undefined &&
2544
- previousVersion !== currentVersion
2545
- );
2546
- });
2547
2599
  }
2548
2600
 
2549
2601
  private recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds: Set<number>) {
@@ -2588,10 +2640,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2588
2640
  finishedStatusSnapshotPolls = 0;
2589
2641
  };
2590
2642
 
2591
- while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
2643
+ while (true) {
2592
2644
  // A transport release caused by an explicit workflow cancellation must not
2593
2645
  // be mistaken for the expected device reboot during installation.
2594
2646
  this.throwIfAborted();
2647
+ // Read once more at the deadline so a completed reboot is not reported as a timeout.
2648
+ const isFinalStatusCheck = Date.now() - startTime >= PROTOCOL_V2_INSTALL_TIMEOUT;
2595
2649
  try {
2596
2650
  if (shouldReconnect) {
2597
2651
  const isBleInstallReconnect = this.isBleReconnect();
@@ -2750,22 +2804,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2750
2804
 
2751
2805
  if (
2752
2806
  statusTargets.length === 0 &&
2753
- !currentDeviceInfo &&
2754
- bleInstallLinkReady &&
2755
- installEvidenceObserved
2807
+ (currentDeviceInfo || bleInstallLinkReady || isFinalStatusCheck)
2756
2808
  ) {
2757
- // BLE install reconnect skips generic probes because loaders may not answer Ping.
2758
- // Restore the verified identity only after current-install evidence disappears.
2759
- currentDeviceInfo = await this.verifyProtocolV2ReconnectIdentity();
2809
+ // Installation can finish while BLE is disconnected, hiding all progress.
2810
+ // Refresh identity and target versions even without observed install status.
2811
+ currentDeviceInfo = await this.verifyProtocolV2ReconnectIdentity(
2812
+ PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST
2813
+ );
2760
2814
  deviceInfo = currentDeviceInfo;
2761
- }
2762
-
2763
- if (statusTargets.length === 0 && currentDeviceInfo) {
2764
2815
  const isNormalMode = await this.probeProtocolV2NormalMode(currentDeviceInfo);
2765
2816
  if (
2766
2817
  isNormalMode &&
2767
2818
  (installEvidenceObserved ||
2768
- this.hasProtocolV2InstallVersionChanged(expectedTargetIds))
2819
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds, currentDeviceInfo))
2769
2820
  ) {
2770
2821
  Log.log(
2771
2822
  '[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete'
@@ -2795,33 +2846,29 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2795
2846
  }
2796
2847
  }
2797
2848
  } catch (error) {
2798
- if (isProtocolV2TerminalInstallStatusError(error)) {
2849
+ if (
2850
+ this.isProtocolV2ReconnectIdentityError(error) ||
2851
+ isProtocolV2TerminalInstallStatusError(error)
2852
+ ) {
2799
2853
  throw error;
2800
2854
  }
2801
- // App firmware does not register DeviceFirmwareUpdateStatusGet. Treat the
2802
- // missing endpoint as completion only after the runtime probe confirms App mode.
2855
+ // Some firmware builds do not expose install status. Require a fresh runtime
2856
+ // probe and current-install evidence or changed versions before accepting completion.
2803
2857
  if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
2804
- if (!currentDeviceInfo) {
2805
- if (!bleInstallLinkReady) {
2806
- throw ERRORS.TypedError(
2807
- HardwareErrorCode.RuntimeError,
2808
- 'Protocol V2 device identity is unavailable during install polling'
2809
- );
2810
- }
2811
- deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
2812
- }
2813
- const reconnectDeviceInfo = currentDeviceInfo ?? deviceInfo;
2814
- if (!reconnectDeviceInfo) {
2858
+ if (!currentDeviceInfo && !bleInstallLinkReady && !isFinalStatusCheck) {
2815
2859
  throw ERRORS.TypedError(
2816
2860
  HardwareErrorCode.RuntimeError,
2817
2861
  'Protocol V2 device identity is unavailable during install polling'
2818
2862
  );
2819
2863
  }
2820
- const isNormalMode = await this.probeProtocolV2NormalMode(reconnectDeviceInfo);
2864
+ deviceInfo = await this.verifyProtocolV2ReconnectIdentity(
2865
+ PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST
2866
+ );
2867
+ const isNormalMode = await this.probeProtocolV2NormalMode(deviceInfo);
2821
2868
  if (
2822
2869
  isNormalMode &&
2823
2870
  (installEvidenceObserved ||
2824
- this.hasProtocolV2InstallVersionChanged(expectedTargetIds))
2871
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds, deviceInfo))
2825
2872
  ) {
2826
2873
  Log.log(
2827
2874
  '[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot'
@@ -2871,6 +2918,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2871
2918
  bleInstallLinkReady = false;
2872
2919
  Log.log('Protocol V2 firmware install device readiness probe failed: ', error);
2873
2920
  }
2921
+ if (isFinalStatusCheck) break;
2874
2922
  await wait(1000);
2875
2923
  }
2876
2924
 
@@ -2909,7 +2957,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2909
2957
  private async probeProtocolV2NormalMode(deviceInfo: ProtocolV2DeviceInfo) {
2910
2958
  const features = await this.device.probeProtocolV2RuntimeState(
2911
2959
  deviceInfo,
2912
- PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
2960
+ PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
2961
+ { forceRuntimeContextRefresh: true }
2913
2962
  );
2914
2963
  this.protocolV2LastRuntimeProbeFeatures = features;
2915
2964
  return this.isProtocolV2ApplicationMode(features);
@@ -3132,6 +3181,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
3132
3181
  progress: number | null
3133
3182
  ): Promise<TypedResponseMessage<'FilesystemFile'>> {
3134
3183
  const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
3184
+ const env = DataManager.getSettings('env');
3135
3185
  const writeRes = await typedCall(
3136
3186
  'FilesystemFileWrite',
3137
3187
  'FilesystemFile',
@@ -3147,6 +3197,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
3147
3197
  ui_percentage: progress ?? undefined,
3148
3198
  },
3149
3199
  {
3200
+ timeoutMs: env === 'react-native' ? PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT : undefined,
3150
3201
  writeWithResponse: false,
3151
3202
  onWriteCompleted: () => undefined,
3152
3203
  }
@@ -1,4 +1,4 @@
1
- import { ERRORS, HardwareErrorCode, createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
1
+ import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
2
 
3
3
  import { UI_REQUEST } from '../constants/ui-request';
4
4
  import { BaseMethod } from './BaseMethod';
@@ -49,10 +49,7 @@ export default class GetDeviceState extends BaseMethod<
49
49
  this.device.isProtocolV2() &&
50
50
  isLoaderMode(state.status.mode)
51
51
  ) {
52
- throw createDeviceNotSupportMethodError(
53
- `${this.name}:${this.params.scope}`,
54
- this.device.getCurrentFirmwareType()
55
- );
52
+ throw ERRORS.TypedError(HardwareErrorCode.NotAllowInBootloaderMode);
56
53
  }
57
54
  return state;
58
55
  }
@@ -1801,7 +1801,7 @@ export class Device extends EventEmitter {
1801
1801
  // both allow and require cases might generate single unexpected mode
1802
1802
  if (!this.isUnacquired()) {
1803
1803
  // allow cases
1804
- if (this.isBootloader() && !this.isProtocolV2() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
1804
+ if ((this.isBootloader() || this.isRomloader()) && !allow.includes(UI_REQUEST.BOOTLOADER)) {
1805
1805
  return UI_REQUEST.BOOTLOADER;
1806
1806
  }
1807
1807
  if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {