@onekeyfe/hd-core 1.2.0-alpha.99 → 1.2.1-alpha.0

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 (200) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +20 -4
  2. package/__tests__/DeviceCommands.test.ts +203 -27
  3. package/__tests__/base64Data.test.ts +69 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +48 -2
  5. package/__tests__/check-firmware-release-protocol-v2.test.ts +82 -13
  6. package/__tests__/device-connector-protocol.test.ts +21 -0
  7. package/__tests__/device-lifecycle-events.test.ts +427 -7
  8. package/__tests__/device-pool-state.test.ts +25 -0
  9. package/__tests__/device-settings.test.ts +237 -9
  10. package/__tests__/device-state-events.test.ts +2 -2
  11. package/__tests__/device-state-mapper.test.ts +61 -5
  12. package/__tests__/device-utils.test.ts +15 -1
  13. package/__tests__/device-wallet-session-store.test.ts +147 -21
  14. package/__tests__/deviceSettings.test.ts +7 -3
  15. package/__tests__/deviceUploadNft.test.ts +36 -4
  16. package/__tests__/firmware-update/device-update-bootloader.test.ts +13 -3
  17. package/__tests__/firmware-update/firmware-artifact-source.test.ts +61 -9
  18. package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +19 -9
  19. package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +21 -0
  20. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +63 -0
  21. package/__tests__/firmware-update/firmware-update-plan.test.ts +59 -55
  22. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +19 -5
  23. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +116 -0
  24. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +979 -0
  25. package/__tests__/firmware-update/firmware-update-v4-parameters.test.ts +85 -0
  26. package/__tests__/get-device-state.test.ts +60 -21
  27. package/__tests__/logBlockEvent.test.ts +13 -1
  28. package/__tests__/open-wallet-session.test.ts +127 -1
  29. package/__tests__/protocol-v2-firmware-targets.test.ts +23 -0
  30. package/__tests__/protocol-v2-resources.test.ts +185 -88
  31. package/__tests__/protocol-v2-unlock-policy.test.ts +235 -2
  32. package/__tests__/protocol-v2.test.ts +2199 -486
  33. package/__tests__/refresh-device-state.test.ts +3 -1
  34. package/__tests__/resourceBase64Boundary.test.ts +48 -0
  35. package/__tests__/search-devices.test.ts +79 -32
  36. package/__tests__/ton-sign-message.test.ts +84 -0
  37. package/dist/api/BaseMethod.d.ts +2 -1
  38. package/dist/api/BaseMethod.d.ts.map +1 -1
  39. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  40. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  41. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  42. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  43. package/dist/api/FirmwareUpdateV4.d.ts +20 -6
  44. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  45. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  46. package/dist/api/SearchDevices.d.ts.map +1 -1
  47. package/dist/api/UploadPortfolio.d.ts +1 -1
  48. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  49. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  50. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  51. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  52. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  53. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  54. package/dist/api/device/DeviceVerify.d.ts +1 -0
  55. package/dist/api/device/DeviceVerify.d.ts.map +1 -1
  56. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  57. package/dist/api/firmware/FirmwareArtifactSource.d.ts +5 -1
  58. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -1
  59. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -1
  60. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -2
  61. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  62. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -15
  63. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  64. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
  65. package/dist/api/firmware/getBinary.d.ts +3 -2
  66. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  67. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
  68. package/dist/api/helpers/base64Data.d.ts +16 -0
  69. package/dist/api/helpers/base64Data.d.ts.map +1 -0
  70. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +3 -1
  71. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  72. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
  73. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
  74. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  75. package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -1
  76. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  77. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
  78. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
  79. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
  80. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  81. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  82. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  83. package/dist/core/index.d.ts +6 -1
  84. package/dist/core/index.d.ts.map +1 -1
  85. package/dist/data-manager/DataManager.d.ts +4 -3
  86. package/dist/data-manager/DataManager.d.ts.map +1 -1
  87. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  88. package/dist/device/Device.d.ts +16 -3
  89. package/dist/device/Device.d.ts.map +1 -1
  90. package/dist/device/DeviceCommands.d.ts +4 -4
  91. package/dist/device/DeviceCommands.d.ts.map +1 -1
  92. package/dist/device/DeviceConnector.d.ts +1 -1
  93. package/dist/device/DeviceConnector.d.ts.map +1 -1
  94. package/dist/device/DevicePool.d.ts.map +1 -1
  95. package/dist/device/DeviceStateMapper.d.ts.map +1 -1
  96. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  97. package/dist/events/logBlockEvent.d.ts.map +1 -1
  98. package/dist/events/ui-request.d.ts +3 -0
  99. package/dist/events/ui-request.d.ts.map +1 -1
  100. package/dist/index.d.ts +54 -84
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +2150 -1469
  103. package/dist/protocols/protocol-v2/features.d.ts +13 -5
  104. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  105. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  106. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  107. package/dist/protocols/protocol-v2/resources.d.ts +12 -7
  108. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  109. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +3 -1
  110. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
  111. package/dist/protocols/protocol-v2/walletSession.d.ts +3 -0
  112. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  113. package/dist/types/api/firmwareUpdatePlan.d.ts +2 -2
  114. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -1
  115. package/dist/types/api/protocolV2.d.ts +1 -1
  116. package/dist/types/api/protocolV2.d.ts.map +1 -1
  117. package/dist/types/device.d.ts.map +1 -1
  118. package/dist/types/settings.d.ts +3 -31
  119. package/dist/types/settings.d.ts.map +1 -1
  120. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  121. package/dist/utils/deviceFeaturesUtils.d.ts +3 -0
  122. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  123. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  124. package/dist/utils/deviceSettings.d.ts +1 -0
  125. package/dist/utils/deviceSettings.d.ts.map +1 -1
  126. package/dist/utils/index.d.ts +1 -1
  127. package/dist/utils/index.d.ts.map +1 -1
  128. package/dist/utils/patch.d.ts +1 -1
  129. package/dist/utils/patch.d.ts.map +1 -1
  130. package/dist/utils/pro2Nft.d.ts +7 -0
  131. package/dist/utils/pro2Nft.d.ts.map +1 -1
  132. package/package.json +6 -4
  133. package/src/api/BaseMethod.ts +8 -1
  134. package/src/api/CheckAllFirmwareRelease.ts +2 -4
  135. package/src/api/CheckBLEFirmwareRelease.ts +2 -2
  136. package/src/api/CheckBootloaderRelease.ts +3 -2
  137. package/src/api/CheckFirmwareRelease.ts +2 -2
  138. package/src/api/FirmwareUpdateV2.ts +12 -9
  139. package/src/api/FirmwareUpdateV3.ts +29 -19
  140. package/src/api/FirmwareUpdateV4.ts +934 -739
  141. package/src/api/OpenWalletSession.ts +39 -9
  142. package/src/api/PromptWebDeviceAccess.ts +2 -2
  143. package/src/api/SearchDevices.ts +6 -3
  144. package/src/api/UploadPortfolio.ts +9 -2
  145. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +2 -1
  146. package/src/api/device/DeviceChangePin.ts +4 -1
  147. package/src/api/device/DeviceRebootToBoardloader.ts +3 -1
  148. package/src/api/device/DeviceRebootToBootloader.ts +3 -1
  149. package/src/api/device/DeviceSettings.ts +34 -20
  150. package/src/api/device/DeviceVerify.ts +25 -0
  151. package/src/api/device/DeviceWipe.ts +4 -1
  152. package/src/api/firmware/FirmwareArtifactSource.ts +41 -14
  153. package/src/api/firmware/FirmwarePreparedResourceArchive.ts +16 -27
  154. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +9 -3
  155. package/src/api/firmware/FirmwareUpdatePlan.ts +37 -77
  156. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +10 -6
  157. package/src/api/firmware/protocolV2Release.ts +7 -2
  158. package/src/api/helpers/base64Data.ts +85 -0
  159. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +1 -1
  160. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +6 -28
  161. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +7 -1
  162. package/src/api/protocol-v2/DeviceInfoGet.ts +3 -3
  163. package/src/api/protocol-v2/DeviceReboot.ts +5 -0
  164. package/src/api/protocol-v2/DeviceUploadNft.ts +61 -9
  165. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +53 -19
  166. package/src/api/protocol-v2/helpers.ts +8 -0
  167. package/src/api/ton/TonSignMessage.ts +5 -3
  168. package/src/core/index.ts +264 -55
  169. package/src/data/messages/messages-protocol-v2.json +140 -13
  170. package/src/data-manager/DataManager.ts +46 -39
  171. package/src/data-manager/TransportManager.ts +3 -1
  172. package/src/device/Device.ts +210 -44
  173. package/src/device/DeviceCommands.ts +27 -18
  174. package/src/device/DeviceConnector.ts +17 -3
  175. package/src/device/DevicePool.ts +9 -2
  176. package/src/device/DeviceStateMapper.ts +30 -24
  177. package/src/deviceProfile/buildDeviceFeatures.ts +10 -5
  178. package/src/events/logBlockEvent.ts +14 -1
  179. package/src/events/ui-request.ts +3 -0
  180. package/src/index.ts +0 -10
  181. package/src/protocols/protocol-v2/features.ts +22 -5
  182. package/src/protocols/protocol-v2/index.ts +2 -0
  183. package/src/protocols/protocol-v2/resources.ts +110 -147
  184. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +13 -1
  185. package/src/protocols/protocol-v2/walletSession.ts +65 -22
  186. package/src/types/api/firmwareUpdate.ts +1 -1
  187. package/src/types/api/firmwareUpdatePlan.ts +2 -2
  188. package/src/types/api/protocolV2.ts +1 -1
  189. package/src/types/device.ts +2 -1
  190. package/src/types/settings.ts +6 -34
  191. package/src/utils/deviceFeaturesCompat.ts +9 -4
  192. package/src/utils/deviceFeaturesUtils.ts +4 -0
  193. package/src/utils/deviceInfoUtils.ts +9 -2
  194. package/src/utils/deviceSettings.ts +11 -4
  195. package/src/utils/index.ts +1 -0
  196. package/src/utils/pro2Nft.ts +31 -8
  197. package/__tests__/firmware-memory-host.test.ts +0 -126
  198. package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -22
  199. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +0 -1
  200. package/src/api/firmware/FirmwareMemoryHost.ts +0 -143
@@ -376,62 +376,66 @@ describe('buildFirmwareUpdatePlan', () => {
376
376
  }
377
377
  );
378
378
 
379
- test('rejects a legacy resource archive without complete integrity metadata', () => {
380
- expectFirmwarePlanInvalid(
381
- () =>
382
- buildFirmwareUpdatePlan(
383
- createLegacyForceInput(['resource'], {
384
- url: 'https://firmware.onekey.so/pro/firmware.bin',
385
- resource: 'https://firmware.onekey.so/pro/resource.zip',
386
- resourceExpectedSize: 4096,
387
- })
388
- ),
389
- 'integrity metadata is invalid'
390
- );
391
- });
379
+ test.each([
380
+ {
381
+ executor: 'v2',
382
+ deviceType: EDeviceType.Classic1s,
383
+ bootloaderVersion: '2.1.2',
384
+ },
385
+ {
386
+ executor: 'v3',
387
+ deviceType: EDeviceType.Pro,
388
+ bootloaderVersion: '2.8.4',
389
+ },
390
+ ])(
391
+ 'allows $executor config releases without optional integrity metadata',
392
+ ({ executor, deviceType, bootloaderVersion }) => {
393
+ const plan = buildFirmwareUpdatePlan({
394
+ features: createFeatures({
395
+ deviceType,
396
+ firmwareVersion: '4.21.0',
397
+ bootloaderVersion,
398
+ }),
399
+ firmwareType: EFirmwareType.Universal,
400
+ platform: 'desktop',
401
+ firmware: {
402
+ status: 'valid',
403
+ release: {
404
+ url: 'https://firmware.onekey.so/legacy/firmware.bin',
405
+ version: [4, 21, 0],
406
+ fingerprint: '',
407
+ resource: 'https://firmware.onekey.so/legacy/resource.zip',
408
+ resourceFingerprint: '',
409
+ },
410
+ },
411
+ ble: {
412
+ status: 'valid',
413
+ release: {
414
+ webUpdate: 'https://firmware.onekey.so/legacy/ble.bin',
415
+ version: [2, 3, 7],
416
+ fingerprintWeb: '',
417
+ },
418
+ },
419
+ bootloader: {
420
+ status: 'valid',
421
+ release: {
422
+ bootloaderResource: 'https://firmware.onekey.so/legacy/bootloader.bin',
423
+ bootloaderVersion: [2, 8, 4],
424
+ bootloaderFingerprint: '',
425
+ },
426
+ },
427
+ forceUpdateTargets: ['firmware', 'resource', 'ble', 'bootloader'],
428
+ });
392
429
 
393
- test.each(['firmware', 'ble', 'bootloader'] as const)(
394
- 'rejects a remote legacy %s artifact without complete integrity metadata',
395
- target => {
396
- expectFirmwarePlanInvalid(
397
- () =>
398
- buildFirmwareUpdatePlan({
399
- features: createFeatures({ deviceType: EDeviceType.Classic1s }),
400
- firmwareType: EFirmwareType.Universal,
401
- platform: 'desktop',
402
- firmware:
403
- target === 'firmware'
404
- ? {
405
- status: 'outdated',
406
- release: {
407
- url: 'https://firmware.onekey.so/classic/firmware.bin',
408
- expectedSize: 1024,
409
- },
410
- }
411
- : noUpdate,
412
- ble:
413
- target === 'ble'
414
- ? {
415
- status: 'outdated',
416
- release: {
417
- webUpdate: 'https://firmware.onekey.so/classic/ble.bin',
418
- expectedSize: 512,
419
- },
420
- }
421
- : noUpdate,
422
- bootloader:
423
- target === 'bootloader'
424
- ? {
425
- status: 'outdated',
426
- release: {
427
- bootloaderResource: 'https://firmware.onekey.so/classic/bootloader.bin',
428
- bootloaderExpectedSize: 768,
429
- },
430
- }
431
- : noUpdate,
432
- }),
433
- 'integrity metadata is invalid'
434
- );
430
+ expect(plan.executor).toBe(executor);
431
+ expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual([
432
+ 'bootloader',
433
+ 'firmware',
434
+ 'resource',
435
+ 'ble',
436
+ ]);
437
+ expect(plan.artifacts.every(artifact => artifact.expectedSize === undefined)).toBe(true);
438
+ expect(plan.artifacts.every(artifact => artifact.expectedSha256 === undefined)).toBe(true);
435
439
  }
436
440
  );
437
441
 
@@ -179,7 +179,7 @@ describe('FirmwareUpdatePreparedPlan', () => {
179
179
  ).toThrow('plan digest is invalid');
180
180
  });
181
181
 
182
- test('projects portable archive paths to unique device resource names', () => {
182
+ test('keeps ZIP entries unique by archive path, not basename', () => {
183
183
  const plan = buildPlan();
184
184
  const buildArtifacts = (entryNames: string[]) => [
185
185
  {
@@ -200,7 +200,17 @@ describe('FirmwareUpdatePreparedPlan', () => {
200
200
  prepareFirmwareUpdatePlan({
201
201
  plan,
202
202
  leaseRef: 'fwlease:00000000-0000-4000-8000-000000000001',
203
- artifacts: buildArtifacts(['icons/index.bin', 'fonts/index.bin']),
203
+ artifacts: buildArtifacts([
204
+ 'loaders/bootloader/params-pro2-prod_resource-unsigned.okpkg',
205
+ 'loaders/rom/params-pro2-prod_resource-unsigned.okpkg',
206
+ ]),
207
+ })
208
+ ).not.toThrow();
209
+ expect(() =>
210
+ prepareFirmwareUpdatePlan({
211
+ plan,
212
+ leaseRef: 'fwlease:00000000-0000-4000-8000-000000000001',
213
+ artifacts: buildArtifacts(['loaders/rom/params.okpkg', 'loaders/rom/params.okpkg']),
204
214
  })
205
215
  ).toThrow('duplicate entry names');
206
216
  expect(() =>
@@ -234,7 +244,11 @@ describe('FirmwareUpdatePreparedPlan', () => {
234
244
  },
235
245
  ],
236
246
  });
237
- const resourceArtifact = prepared.artifacts.find(item => item.target === 'resource')!;
247
+ const resourceArtifact = prepared.artifacts.find(item => item.target === 'resource');
248
+ expect(resourceArtifact).toBeDefined();
249
+ if (!resourceArtifact) {
250
+ throw new Error('Expected prepared resource artifact');
251
+ }
238
252
  const tamperedWithoutDigest = {
239
253
  ...prepared,
240
254
  artifacts: prepared.artifacts.map(item =>
@@ -242,9 +256,9 @@ describe('FirmwareUpdatePreparedPlan', () => {
242
256
  ? {
243
257
  ...item,
244
258
  materializedEntries: [
245
- ...resourceArtifact.materializedEntries!,
259
+ ...(resourceArtifact.materializedEntries ?? []),
246
260
  {
247
- entryName: 'other/index.bin',
261
+ entryName: 'resource/index.bin',
248
262
  artifact: artifact('d'.repeat(64), 2),
249
263
  },
250
264
  ],
@@ -1,6 +1,7 @@
1
1
  import * as hdShared from '@onekeyfe/hd-shared';
2
2
 
3
3
  import FirmwareUpdateV3 from '../../src/api/FirmwareUpdateV3';
4
+ import { DataManager } from '../../src/data-manager';
4
5
  import { DevicePool } from '../../src/device/DevicePool';
5
6
 
6
7
  import type { Device } from '../../src/device/Device';
@@ -112,10 +113,125 @@ describe('FirmwareUpdateV3 reconnect', () => {
112
113
  })
113
114
  ).rejects.toBe(reconnectError);
114
115
 
116
+ expect(commands.typedCall).toHaveBeenCalledWith('GetFeatures', 'Features', {});
115
117
  expect(waitForDeviceReconnect).toHaveBeenCalledWith(3 * 60 * 1000);
116
118
  } finally {
117
119
  jest.clearAllTimers();
118
120
  jest.useRealTimers();
119
121
  }
120
122
  });
123
+
124
+ it('lets Browser WebUSB clean up a timed out install probe before reconnecting', async () => {
125
+ jest.spyOn(hdShared, 'wait').mockResolvedValue(undefined);
126
+ jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
127
+ jest.spyOn(DataManager, 'isBrowserWebUsb').mockReturnValue(true);
128
+ const method = new FirmwareUpdateV3({
129
+ id: 1,
130
+ payload: {
131
+ method: 'firmwareUpdateV3',
132
+ connectId: 'webusb-device',
133
+ },
134
+ });
135
+ const reconnectError = new Error('stop after WebUSB reconnect assertion');
136
+ const waitForDeviceReconnect = jest
137
+ .spyOn(method, 'waitForDeviceReconnect')
138
+ .mockRejectedValue(reconnectError);
139
+ method.isBleReconnect = jest.fn(() => false);
140
+ method.params = {
141
+ platform: 'web',
142
+ } as any;
143
+ const commands = {
144
+ typedCall: jest.fn().mockRejectedValue(new Error('Protocol V1 read timeout after 3000ms')),
145
+ };
146
+ method.device = {
147
+ features: {},
148
+ getCommands: () => commands,
149
+ } as unknown as Device;
150
+ (method as any).createUpdatesFolderIfNotExists = jest.fn().mockResolvedValue(undefined);
151
+ (method as any).startEmmcFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
152
+ method.postTipMessage = jest.fn();
153
+ method.postProcessingMessage = jest.fn();
154
+ method.postProgressMessage = jest.fn();
155
+
156
+ await expect(
157
+ (method as any).executeUpdate({
158
+ resourceBinary: null,
159
+ resourceEntries: [],
160
+ fwSources: [],
161
+ bootloaderSource: null,
162
+ })
163
+ ).rejects.toBe(reconnectError);
164
+
165
+ expect(commands.typedCall).toHaveBeenCalledWith(
166
+ 'GetFeatures',
167
+ 'Features',
168
+ {},
169
+ {
170
+ timeoutMs: 3000,
171
+ }
172
+ );
173
+ expect(waitForDeviceReconnect).toHaveBeenCalledWith(60 * 1000);
174
+ });
175
+
176
+ it('does not treat cached firmware versions as Browser WebUSB install completion', async () => {
177
+ jest.spyOn(hdShared, 'wait').mockResolvedValue(undefined);
178
+ jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
179
+ jest.spyOn(DataManager, 'isBrowserWebUsb').mockReturnValue(true);
180
+ const method = new FirmwareUpdateV3({
181
+ id: 1,
182
+ payload: {
183
+ method: 'firmwareUpdateV3',
184
+ connectId: 'webusb-device',
185
+ },
186
+ });
187
+ method.params = {
188
+ platform: 'web',
189
+ } as any;
190
+ const commands = {
191
+ typedCall: jest
192
+ .fn()
193
+ .mockResolvedValueOnce({
194
+ type: 'Features',
195
+ message: {
196
+ major_version: 0,
197
+ minor_version: 0,
198
+ patch_version: 0,
199
+ },
200
+ })
201
+ .mockResolvedValueOnce({
202
+ type: 'Features',
203
+ message: {
204
+ major_version: 4,
205
+ minor_version: 21,
206
+ patch_version: 0,
207
+ onekey_ble_version: '2.3.7',
208
+ },
209
+ }),
210
+ };
211
+ method.device = {
212
+ features: {
213
+ firmwareVersion: '4.21.0',
214
+ bleVersion: '2.3.7',
215
+ },
216
+ getCommands: () => commands,
217
+ } as unknown as Device;
218
+ (method as any).createUpdatesFolderIfNotExists = jest.fn().mockResolvedValue(undefined);
219
+ (method as any).startEmmcFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
220
+ method.postTipMessage = jest.fn();
221
+ method.postProcessingMessage = jest.fn();
222
+ method.postProgressMessage = jest.fn();
223
+
224
+ const result = await (method as any).executeUpdate({
225
+ resourceBinary: null,
226
+ resourceEntries: [],
227
+ fwSources: [],
228
+ bootloaderSource: null,
229
+ });
230
+
231
+ expect(commands.typedCall).toHaveBeenCalledTimes(2);
232
+ expect(result).toMatchObject({
233
+ firmwareVersion: '4.21.0',
234
+ bleVersion: '2.3.7',
235
+ });
236
+ });
121
237
  });