@onekeyfe/hd-core 1.2.0-alpha.69 → 1.2.0-alpha.70

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.
Files changed (121) hide show
  1. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +0 -28
  2. package/__tests__/connectSettings.test.ts +45 -5
  3. package/__tests__/device-initialize-timeout.test.ts +56 -0
  4. package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
  5. package/__tests__/firmware-update/device-update-bootloader.test.ts +87 -0
  6. package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
  7. package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
  8. package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
  9. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
  10. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
  11. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +394 -0
  12. package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
  13. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +231 -0
  14. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
  15. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +63 -0
  16. package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
  17. package/__tests__/protocol-v2-firmware-targets.test.ts +1 -33
  18. package/__tests__/protocol-v2-resources.test.ts +6 -9
  19. package/__tests__/protocol-v2.test.ts +383 -174
  20. package/__tests__/protocolV2FileWrite.test.ts +7 -48
  21. package/dist/api/CheckAllFirmwareRelease.d.ts +1 -2
  22. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  23. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  24. package/dist/api/FirmwareUpdateV2.d.ts +10 -0
  25. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  26. package/dist/api/FirmwareUpdateV3.d.ts +7 -3
  27. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  28. package/dist/api/FirmwareUpdateV4.d.ts +25 -6
  29. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  30. package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
  31. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  32. package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
  33. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
  34. package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
  35. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
  36. package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
  37. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
  38. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +8 -0
  39. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  40. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
  41. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
  42. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
  43. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
  44. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
  45. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
  46. package/dist/api/firmware/getBinary.d.ts +7 -0
  47. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  48. package/dist/api/firmware/updateBootloader.d.ts +2 -0
  49. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  50. package/dist/api/firmware/uploadFirmware.d.ts +9 -1
  51. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  52. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  53. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  54. package/dist/data-manager/DataManager.d.ts +1 -0
  55. package/dist/data-manager/DataManager.d.ts.map +1 -1
  56. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  57. package/dist/device/Device.d.ts +1 -0
  58. package/dist/device/Device.d.ts.map +1 -1
  59. package/dist/index.d.ts +180 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +3038 -1041
  62. package/dist/inject.d.ts.map +1 -1
  63. package/dist/lowLevelInject.d.ts.map +1 -1
  64. package/dist/protocols/protocol-v2/resources.d.ts +1 -1
  65. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  66. package/dist/topLevelInject.d.ts.map +1 -1
  67. package/dist/types/api/checkAllFirmwareRelease.d.ts +4 -0
  68. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  69. package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
  70. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  71. package/dist/types/api/export.d.ts +4 -1
  72. package/dist/types/api/export.d.ts.map +1 -1
  73. package/dist/types/api/firmwareUpdate.d.ts +68 -0
  74. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  75. package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
  76. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
  77. package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
  78. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
  79. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
  80. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
  81. package/dist/types/api/index.d.ts +9 -1
  82. package/dist/types/api/index.d.ts.map +1 -1
  83. package/dist/types/settings.d.ts +14 -1
  84. package/dist/types/settings.d.ts.map +1 -1
  85. package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
  86. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  87. package/package.json +4 -4
  88. package/src/api/CheckAllFirmwareRelease.ts +61 -25
  89. package/src/api/FirmwareUpdate.ts +13 -1
  90. package/src/api/FirmwareUpdateV2.ts +296 -121
  91. package/src/api/FirmwareUpdateV3.ts +263 -57
  92. package/src/api/FirmwareUpdateV4.ts +865 -287
  93. package/src/api/device/DeviceUpdateBootloader.ts +125 -6
  94. package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
  95. package/src/api/firmware/FirmwareHostBinding.ts +100 -0
  96. package/src/api/firmware/FirmwarePreparationError.ts +12 -0
  97. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +72 -1
  98. package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
  99. package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
  100. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +449 -0
  101. package/src/api/firmware/updateBootloader.ts +19 -4
  102. package/src/api/firmware/uploadFirmware.ts +140 -22
  103. package/src/api/helpers/protocolV2FileWrite.ts +4 -54
  104. package/src/data-manager/DataManager.ts +62 -54
  105. package/src/data-manager/connectSettings.ts +11 -0
  106. package/src/device/Device.ts +6 -1
  107. package/src/index.ts +5 -0
  108. package/src/inject.ts +22 -2
  109. package/src/lowLevelInject.ts +5 -1
  110. package/src/protocols/protocol-v2/resources.ts +1 -5
  111. package/src/topLevelInject.ts +5 -1
  112. package/src/types/api/checkAllFirmwareRelease.ts +4 -0
  113. package/src/types/api/deviceUpdateBootloader.ts +6 -0
  114. package/src/types/api/export.ts +18 -0
  115. package/src/types/api/firmwareUpdate.ts +75 -0
  116. package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
  117. package/src/types/api/firmwareUpdatePlan.ts +38 -0
  118. package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
  119. package/src/types/api/index.ts +14 -0
  120. package/src/types/settings.ts +14 -2
  121. package/src/utils/deviceFeaturesCompat.ts +6 -0
@@ -1,6 +1,13 @@
1
- import { EDeviceType, EFirmwareType, ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
1
+ import {
2
+ EDeviceType,
3
+ EFirmwareType,
4
+ ERRORS,
5
+ HardwareError,
6
+ HardwareErrorCode,
7
+ } from '@onekeyfe/hd-shared';
2
8
  import semver from 'semver';
3
9
 
10
+ import { BaseMethod } from './BaseMethod';
4
11
  import { UI_REQUEST } from '../constants/ui-request';
5
12
  import { DataManager } from '../data-manager';
6
13
  import {
@@ -8,13 +15,22 @@ import {
8
15
  getBootloaderReleaseInfo,
9
16
  getFirmwareReleaseInfo,
10
17
  } from './firmware/releaseHelper';
18
+ import {
19
+ buildFirmwareUpdatePlan,
20
+ validateFirmwareUpdatePlanForceTargets,
21
+ } from './firmware/FirmwareUpdatePlan';
11
22
  import { getBridgeReleaseInfo } from '../utils/bridgeUpdate';
12
- import { getDeviceFirmwareVersion, getDeviceType, getFirmwareType } from '../utils';
13
- import { BaseMethod } from './BaseMethod';
14
23
  import {
15
24
  buildProtocolV2ResourceUpdatePlan,
16
25
  readProtocolV2ResourceInventory,
17
26
  } from '../protocols/protocol-v2/resources';
27
+ import {
28
+ LoggerNames,
29
+ getDeviceFirmwareVersion,
30
+ getDeviceType,
31
+ getFirmwareType,
32
+ getLogger,
33
+ } from '../utils';
18
34
 
19
35
  import type {
20
36
  AllFirmwareRelease,
@@ -30,6 +46,7 @@ import type {
30
46
  IProtocolV2FirmwareComponent,
31
47
  IProtocolV2FirmwareComponentTarget,
32
48
  } from '../types';
49
+ import type { FirmwareUpdatePlan } from '../types/api/firmwareUpdatePlan';
33
50
 
34
51
  const UPDATE_TARGET_BY_COMPONENT_TARGET: Readonly<
35
52
  Partial<Record<IProtocolV2FirmwareComponentTarget, FirmwareUpdateV4Target>>
@@ -174,7 +191,6 @@ export function buildProtocolV2FirmwareRelease({
174
191
  remotePayloadHashes = {},
175
192
  firmwareType,
176
193
  release,
177
- deviceType,
178
194
  }: {
179
195
  currentVersions: DeviceStateVersions;
180
196
  currentVerification?: Partial<DeviceFeaturesVerify>;
@@ -182,7 +198,6 @@ export function buildProtocolV2FirmwareRelease({
182
198
  remotePayloadHashes?: Readonly<Record<string, string | null>>;
183
199
  firmwareType: EFirmwareType;
184
200
  release: IFirmwareReleaseInfo | undefined;
185
- deviceType?: 'pro2' | 'neo';
186
201
  }): ProtocolV2FirmwareReleasePlan {
187
202
  if (!release) {
188
203
  return {
@@ -197,8 +212,8 @@ export function buildProtocolV2FirmwareRelease({
197
212
  };
198
213
  }
199
214
 
200
- let components = getOrderedComponentEntries(release).map(([configKey, component]) => {
201
- const result = buildComponentRelease({
215
+ let components = getOrderedComponentEntries(release).map(([configKey, component]) =>
216
+ buildComponentRelease({
202
217
  configKey,
203
218
  component,
204
219
  currentVersions,
@@ -208,20 +223,8 @@ export function buildProtocolV2FirmwareRelease({
208
223
  ? remotePayloadHashes[configKey]
209
224
  : normalizeHex(component.payloadHash),
210
225
  releaseRequired: release.required,
211
- });
212
- if (
213
- deviceType === 'neo' &&
214
- (result.componentTarget === 'SE03' || result.componentTarget === 'SE04')
215
- ) {
216
- return {
217
- ...result,
218
- updateTarget: null,
219
- status: 'unsupported' as const,
220
- required: false,
221
- };
222
- }
223
- return result;
224
- });
226
+ })
227
+ );
225
228
  if (!currentVersions.applicationP2) {
226
229
  const applicationP1 = components.find(
227
230
  component => component.componentTarget === 'APPLICATION_P1'
@@ -266,6 +269,8 @@ export function buildProtocolV2FirmwareRelease({
266
269
  };
267
270
  }
268
271
 
272
+ const Log = getLogger(LoggerNames.Method);
273
+
269
274
  export default class CheckAllFirmwareRelease extends BaseMethod {
270
275
  getSupportedProtocols() {
271
276
  return ['V1', 'V2'] as const;
@@ -283,8 +288,13 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
283
288
  }
284
289
 
285
290
  const { features } = this.device;
286
- const { checkBridgeRelease, firmwareType: firmwareTypeParams } = this
287
- .payload as CheckAllFirmwareReleaseParams;
291
+ const {
292
+ checkBridgeRelease,
293
+ firmwareType: firmwareTypeParams,
294
+ platform,
295
+ forceUpdateTargets,
296
+ } = this.payload as CheckAllFirmwareReleaseParams;
297
+ const validatedForceUpdateTargets = validateFirmwareUpdatePlanForceTargets(forceUpdateTargets);
288
298
 
289
299
  if (!features) {
290
300
  return Promise.resolve(null);
@@ -315,6 +325,32 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
315
325
  firmwareType,
316
326
  });
317
327
  const bleFirmwareReleaseInfo = getBleFirmwareReleaseInfo(features);
328
+ let firmwareUpdatePlan: FirmwareUpdatePlan | undefined;
329
+ try {
330
+ firmwareUpdatePlan = buildFirmwareUpdatePlan({
331
+ features,
332
+ firmwareType,
333
+ platform: platform ?? 'web',
334
+ firmware: firmwareRelease,
335
+ ble: bleFirmwareReleaseInfo,
336
+ bootloader: bootloaderRelease,
337
+ forceUpdateTargets: validatedForceUpdateTargets,
338
+ });
339
+ } catch (error) {
340
+ if (
341
+ validatedForceUpdateTargets.length > 0 ||
342
+ !(error instanceof HardwareError) ||
343
+ error.params?.firmwareUpdateCode !== 'FirmwarePlanInvalid'
344
+ ) {
345
+ throw error;
346
+ }
347
+ // A Plan is an optional external-host capability. Release checks remain
348
+ // available for legacy and recovery flows when a Plan cannot be built.
349
+ Log.warn(
350
+ '[CheckAllFirmwareRelease] Optional firmware Plan is unavailable; using the legacy release result'
351
+ );
352
+ firmwareUpdatePlan = undefined;
353
+ }
318
354
 
319
355
  return {
320
356
  firmware: firmwareRelease,
@@ -329,7 +365,8 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
329
365
  }
330
366
  : undefined,
331
367
  features,
332
- } as AllFirmwareRelease;
368
+ firmwareUpdatePlan,
369
+ } as unknown as AllFirmwareRelease;
333
370
  }
334
371
 
335
372
  private async runProtocolV2(): Promise<AllFirmwareRelease> {
@@ -364,7 +401,6 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
364
401
  checkFirmwareHash,
365
402
  firmwareType,
366
403
  release,
367
- deviceType: state.identity.deviceType,
368
404
  });
369
405
  const resourceDeviceType =
370
406
  state.identity.deviceType === 'neo' ? EDeviceType.Neo : EDeviceType.Pro2;
@@ -10,6 +10,7 @@ import { UI_REQUEST } from '../constants/ui-request';
10
10
  import { BaseMethod } from './BaseMethod';
11
11
  import { validateParams } from './helpers/paramsValidator';
12
12
  import { getBinary } from './firmware/getBinary';
13
+ import { BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS } from './firmware/FirmwareUpdateBaseMethod';
13
14
  import { uploadFirmware } from './firmware/uploadFirmware';
14
15
  import { createUiMessage } from '../events';
15
16
  import { DeviceModelToTypes, type KnownDevice } from '../types';
@@ -78,6 +79,10 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
78
79
  this.checkPromise = createDeferred();
79
80
  const env = DataManager.getSettings('env');
80
81
  const isBleReconnect = connectId && DataManager.isBleConnect(env);
82
+ // Tracks the in-flight BLE probe so interval ticks never overlap: a superseded
83
+ // Initialize left pending on the V1 transport is exactly what later times out
84
+ // and used to tear down the connection mid-firmware-upload.
85
+ let bleProbeInFlight = false;
81
86
 
82
87
  Log.log('FirmwareUpdate [checkDeviceToBootloader] isBleReconnect: ', isBleReconnect);
83
88
 
@@ -85,6 +90,8 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
85
90
  const intervalTimer: ReturnType<typeof setInterval> | undefined = setInterval(
86
91
  async () => {
87
92
  if (isBleReconnect) {
93
+ if (bleProbeInFlight) return;
94
+ bleProbeInFlight = true;
88
95
  try {
89
96
  await this.device.deviceConnector?.acquire(
90
97
  this.device.originalDescriptor.id,
@@ -92,7 +99,10 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
92
99
  true,
93
100
  this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType
94
101
  );
95
- await this.device.initialize();
102
+ // Bound each probe so a request the rebooting device never received
103
+ // frees the slot for the next tick instead of hanging into the
104
+ // 30s reboot budget.
105
+ await this.device.initialize({ timeoutMs: BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS });
96
106
  if (this.device.isBootloader()) {
97
107
  clearInterval(intervalTimer);
98
108
  this.checkPromise?.resolve(true);
@@ -100,6 +110,8 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
100
110
  } catch (e) {
101
111
  // ignore error because of device is not connected
102
112
  Log.log('catch Bluetooth error when device is restarting: ', e);
113
+ } finally {
114
+ bleProbeInFlight = false;
103
115
  }
104
116
  } else {
105
117
  const deviceDiff = await this.device.deviceConnector?.enumerate();