@onekeyfe/hd-core 1.2.0-alpha.73 → 1.2.0-alpha.75

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 (120) hide show
  1. package/__tests__/connectSettings.test.ts +5 -45
  2. package/__tests__/devicePoolBootloaderPath.test.ts +64 -0
  3. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  4. package/__tests__/protocol-v2.test.ts +100 -405
  5. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  6. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  7. package/dist/api/FirmwareUpdateV2.d.ts +0 -10
  8. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  9. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  10. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  11. package/dist/api/FirmwareUpdateV4.d.ts +5 -25
  12. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  13. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  14. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  15. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -8
  16. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  17. package/dist/api/firmware/getBinary.d.ts +0 -7
  18. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  19. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  20. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  21. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  22. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  23. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  24. package/dist/core/index.d.ts.map +1 -1
  25. package/dist/data-manager/DataManager.d.ts +0 -1
  26. package/dist/data-manager/DataManager.d.ts.map +1 -1
  27. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  28. package/dist/device/Device.d.ts +0 -1
  29. package/dist/device/Device.d.ts.map +1 -1
  30. package/dist/device/DeviceConnector.d.ts +1 -1
  31. package/dist/device/DeviceConnector.d.ts.map +1 -1
  32. package/dist/device/DevicePool.d.ts +1 -0
  33. package/dist/device/DevicePool.d.ts.map +1 -1
  34. package/dist/index.d.ts +2 -180
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1076 -3080
  37. package/dist/inject.d.ts.map +1 -1
  38. package/dist/lowLevelInject.d.ts.map +1 -1
  39. package/dist/topLevelInject.d.ts.map +1 -1
  40. package/dist/types/api/checkAllFirmwareRelease.d.ts +0 -4
  41. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  42. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  43. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  44. package/dist/types/api/export.d.ts +1 -4
  45. package/dist/types/api/export.d.ts.map +1 -1
  46. package/dist/types/api/firmwareUpdate.d.ts +0 -68
  47. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  48. package/dist/types/api/index.d.ts +1 -9
  49. package/dist/types/api/index.d.ts.map +1 -1
  50. package/dist/types/settings.d.ts +0 -13
  51. package/dist/types/settings.d.ts.map +1 -1
  52. package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
  53. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  54. package/package.json +4 -4
  55. package/src/api/CheckAllFirmwareRelease.ts +6 -57
  56. package/src/api/FirmwareUpdate.ts +1 -13
  57. package/src/api/FirmwareUpdateV2.ts +121 -296
  58. package/src/api/FirmwareUpdateV3.ts +57 -263
  59. package/src/api/FirmwareUpdateV4.ts +347 -875
  60. package/src/api/device/DeviceUpdateBootloader.ts +6 -125
  61. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +1 -72
  62. package/src/api/firmware/updateBootloader.ts +4 -19
  63. package/src/api/firmware/uploadFirmware.ts +22 -140
  64. package/src/core/index.ts +16 -0
  65. package/src/data-manager/DataManager.ts +54 -62
  66. package/src/data-manager/connectSettings.ts +0 -11
  67. package/src/device/Device.ts +3 -7
  68. package/src/device/DeviceConnector.ts +2 -2
  69. package/src/device/DevicePool.ts +15 -1
  70. package/src/index.ts +0 -5
  71. package/src/inject.ts +2 -22
  72. package/src/lowLevelInject.ts +1 -5
  73. package/src/topLevelInject.ts +1 -5
  74. package/src/types/api/checkAllFirmwareRelease.ts +0 -4
  75. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  76. package/src/types/api/export.ts +0 -18
  77. package/src/types/api/firmwareUpdate.ts +0 -75
  78. package/src/types/api/index.ts +0 -14
  79. package/src/types/settings.ts +0 -13
  80. package/src/utils/deviceFeaturesCompat.ts +0 -6
  81. package/__tests__/device-initialize-timeout.test.ts +0 -56
  82. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  83. package/__tests__/firmware-update/device-update-bootloader.test.ts +0 -87
  84. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  85. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  86. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  87. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
  88. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  89. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -394
  90. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  91. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -231
  92. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -63
  93. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  94. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  95. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  96. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  97. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  98. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  99. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  100. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  101. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  102. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  103. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  104. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
  105. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  106. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  107. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  108. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  109. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  110. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  111. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  112. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  113. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  114. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  115. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  116. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
  117. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -449
  118. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  119. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  120. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
@@ -1,593 +0,0 @@
1
- import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
2
-
3
- import { buildFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePlan';
4
-
5
- import type { Features } from '../../src/types';
6
-
7
- const createFeatures = ({
8
- deviceType,
9
- firmwareVersion = '1.0.0',
10
- bootloaderVersion = '1.0.0',
11
- }: {
12
- deviceType: EDeviceType;
13
- firmwareVersion?: string;
14
- bootloaderVersion?: string;
15
- }) =>
16
- ({
17
- deviceType,
18
- serialNo: `${deviceType}-device-id`,
19
- firmwareVersion,
20
- bootloaderVersion,
21
- } as Features);
22
-
23
- const noUpdate = {
24
- status: 'valid',
25
- release: undefined,
26
- };
27
-
28
- const expectFirmwarePlanInvalid = (build: () => unknown, expectedMessage?: string) => {
29
- let thrown: unknown;
30
- try {
31
- build();
32
- } catch (error) {
33
- thrown = error;
34
- }
35
- expect(thrown).toMatchObject({
36
- params: {
37
- firmwareUpdateCode: 'FirmwarePlanInvalid',
38
- },
39
- });
40
- if (expectedMessage) {
41
- expect(thrown).toBeInstanceOf(Error);
42
- expect((thrown as Error).message).toContain(expectedMessage);
43
- }
44
- };
45
-
46
- type BuildPlanInput = Parameters<typeof buildFirmwareUpdatePlan>[0];
47
-
48
- const createLegacyForceInput = (
49
- forceUpdateTargets: unknown,
50
- release: Record<string, unknown> = {
51
- url: 'https://firmware.onekey.so/pro/firmware.bin',
52
- version: [4, 21, 0],
53
- }
54
- ): BuildPlanInput => ({
55
- features: createFeatures({
56
- deviceType: EDeviceType.Pro,
57
- firmwareVersion: '4.21.0',
58
- bootloaderVersion: '2.8.4',
59
- }),
60
- firmwareType: EFirmwareType.Universal,
61
- platform: 'desktop',
62
- firmware: { status: 'valid', release },
63
- ble: noUpdate,
64
- bootloader: noUpdate,
65
- forceUpdateTargets: forceUpdateTargets as BuildPlanInput['forceUpdateTargets'],
66
- });
67
-
68
- const createProtocolV2ForceInput = (
69
- forceUpdateTargets: unknown,
70
- release: Record<string, unknown>
71
- ): BuildPlanInput => ({
72
- features: createFeatures({
73
- deviceType: EDeviceType.Pro2,
74
- firmwareVersion: '1.0.0',
75
- bootloaderVersion: '1.0.0',
76
- }),
77
- firmwareType: EFirmwareType.Universal,
78
- platform: 'desktop',
79
- firmware: { status: 'valid', release },
80
- ble: noUpdate,
81
- bootloader: noUpdate,
82
- forceUpdateTargets: forceUpdateTargets as BuildPlanInput['forceUpdateTargets'],
83
- });
84
-
85
- describe('buildFirmwareUpdatePlan', () => {
86
- test('selects all legacy artifacts before execution and chooses the desktop full resource', () => {
87
- const plan = buildFirmwareUpdatePlan({
88
- features: createFeatures({
89
- deviceType: EDeviceType.Classic1s,
90
- firmwareVersion: '1.0.0',
91
- }),
92
- firmwareType: EFirmwareType.Universal,
93
- platform: 'desktop',
94
- firmware: {
95
- status: 'outdated',
96
- release: {
97
- url: 'https://firmware.onekey.so/classic/firmware.bin',
98
- expectedSize: 1024,
99
- fingerprint: '1111111111111111111111111111111111111111111111111111111111111111',
100
- version: [3, 0, 0],
101
- resource: 'https://firmware.onekey.so/classic/resource.zip',
102
- fullResource: 'https://firmware.onekey.so/classic/full-resource.zip',
103
- fullResourceExpectedSize: 4096,
104
- fullResourceFingerprint:
105
- '2222222222222222222222222222222222222222222222222222222222222222',
106
- fullResourceRange: ['2.0.0', '3.0.0'],
107
- },
108
- },
109
- ble: {
110
- status: 'outdated',
111
- release: {
112
- webUpdate: 'https://firmware.onekey.so/classic/ble.bin',
113
- expectedSize: 512,
114
- fingerprintWeb: '3333333333333333333333333333333333333333333333333333333333333333',
115
- },
116
- },
117
- bootloader: {
118
- status: 'outdated',
119
- shouldUpdate: true,
120
- release: {
121
- bootloaderResource: 'https://firmware.onekey.so/classic/bootloader.bin',
122
- bootloaderExpectedSize: 768,
123
- bootloaderFingerprint: '4444444444444444444444444444444444444444444444444444444444444444',
124
- bootloaderVersion: [2, 0, 0],
125
- },
126
- },
127
- });
128
-
129
- expect(plan.executor).toBe('v2');
130
- expect(plan.artifacts).toEqual([
131
- expect.objectContaining({
132
- artifactId: 'bootloader',
133
- role: 'bootloader',
134
- expectedSize: 768,
135
- targetVersion: '2.0.0',
136
- }),
137
- expect.objectContaining({
138
- artifactId: 'firmware',
139
- role: 'firmware',
140
- expectedSize: 1024,
141
- targetVersion: '3.0.0',
142
- }),
143
- expect.objectContaining({
144
- artifactId: 'resource',
145
- role: 'resource',
146
- url: 'https://firmware.onekey.so/classic/full-resource.zip',
147
- expectedSize: 4096,
148
- }),
149
- expect.objectContaining({
150
- artifactId: 'ble',
151
- role: 'ble',
152
- expectedSize: 512,
153
- }),
154
- ]);
155
- expect(plan.targetsToUpdate).toEqual(['bootloader', 'firmware', 'resource', 'ble']);
156
- });
157
-
158
- test('selects V3 for Pro with bootloader 2.8 or newer', () => {
159
- const plan = buildFirmwareUpdatePlan({
160
- features: createFeatures({
161
- deviceType: EDeviceType.Pro,
162
- bootloaderVersion: '2.8.0',
163
- }),
164
- firmwareType: EFirmwareType.BitcoinOnly,
165
- platform: 'native',
166
- firmware: {
167
- status: 'outdated',
168
- release: {
169
- url: 'https://firmware.onekey.so/pro/firmware.bin',
170
- version: [4, 0, 0],
171
- },
172
- },
173
- ble: noUpdate,
174
- bootloader: noUpdate,
175
- });
176
-
177
- expect(plan.executor).toBe('v3');
178
- expect(plan.firmwareType).toBe(EFirmwareType.BitcoinOnly);
179
- expect(plan.platform).toBe('native');
180
- });
181
-
182
- test('includes same-version legacy artifacts selected by the host', () => {
183
- const plan = buildFirmwareUpdatePlan({
184
- features: createFeatures({
185
- deviceType: EDeviceType.Pro,
186
- firmwareVersion: '4.21.0',
187
- bootloaderVersion: '2.8.4',
188
- }),
189
- firmwareType: EFirmwareType.Universal,
190
- platform: 'desktop',
191
- firmware: {
192
- status: 'valid',
193
- release: {
194
- url: 'https://firmware.onekey.so/pro/firmware.bin',
195
- version: [4, 21, 0],
196
- resource: 'https://firmware.onekey.so/pro/resource.zip',
197
- },
198
- },
199
- ble: {
200
- status: 'valid',
201
- release: {
202
- webUpdate: 'https://firmware.onekey.so/pro/ble.bin',
203
- version: [2, 3, 7],
204
- },
205
- },
206
- bootloader: {
207
- status: 'valid',
208
- release: {
209
- bootloaderResource: 'https://firmware.onekey.so/pro/bootloader.bin',
210
- bootloaderVersion: [2, 8, 4],
211
- },
212
- },
213
- forceUpdateTargets: ['firmware', 'resource', 'ble', 'bootloader'],
214
- });
215
-
216
- expect(plan.executor).toBe('v3');
217
- expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual([
218
- 'bootloader',
219
- 'firmware',
220
- 'resource',
221
- 'ble',
222
- ]);
223
- expect(plan.targetsToUpdate).toEqual(['bootloader', 'firmware', 'resource', 'ble']);
224
- });
225
-
226
- test('does not include a same-version resource unless the host selects it', () => {
227
- const plan = buildFirmwareUpdatePlan({
228
- features: createFeatures({
229
- deviceType: EDeviceType.Pro,
230
- firmwareVersion: '4.21.0',
231
- bootloaderVersion: '2.8.4',
232
- }),
233
- firmwareType: EFirmwareType.Universal,
234
- platform: 'desktop',
235
- firmware: {
236
- status: 'valid',
237
- release: {
238
- url: 'https://firmware.onekey.so/pro/firmware.bin',
239
- version: [4, 21, 0],
240
- resource: 'https://firmware.onekey.so/pro/resource.zip',
241
- },
242
- },
243
- ble: noUpdate,
244
- bootloader: noUpdate,
245
- forceUpdateTargets: ['firmware'],
246
- });
247
-
248
- expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual(['firmware']);
249
- expect(plan.targetsToUpdate).toEqual(['firmware']);
250
- });
251
-
252
- test.each([
253
- {
254
- label: 'a non-array value',
255
- forceUpdateTargets: 'firmware',
256
- },
257
- {
258
- label: 'an unknown target',
259
- forceUpdateTargets: ['firmware', 'unknown'],
260
- },
261
- {
262
- label: 'a duplicate target',
263
- forceUpdateTargets: ['firmware', 'firmware'],
264
- },
265
- ])('rejects $label in forceUpdateTargets', ({ forceUpdateTargets }) => {
266
- expectFirmwarePlanInvalid(() =>
267
- buildFirmwareUpdatePlan(createLegacyForceInput(forceUpdateTargets))
268
- );
269
- });
270
-
271
- test('rejects an explicitly forced legacy resource without a resource artifact', () => {
272
- expectFirmwarePlanInvalid(() => buildFirmwareUpdatePlan(createLegacyForceInput(['resource'])));
273
- });
274
-
275
- test.each(['ble', 'bootloader'] as const)(
276
- 'rejects the unsupported Pro2 %s force target',
277
- forceTarget => {
278
- expectFirmwarePlanInvalid(
279
- () =>
280
- buildFirmwareUpdatePlan(
281
- createProtocolV2ForceInput([forceTarget], {
282
- components: {
283
- applicationP1: {
284
- target: 'APPLICATION_P1',
285
- url: 'https://firmware.onekey.so/pro2/application-p1.bin',
286
- },
287
- },
288
- })
289
- ),
290
- 'does not support forced'
291
- );
292
- }
293
- );
294
-
295
- test.each([
296
- {
297
- forceTarget: 'firmware' as const,
298
- release: {
299
- components: {},
300
- resourceBundles: [
301
- {
302
- name: 'images',
303
- url: 'https://firmware.onekey.so/pro2/images.okpkg',
304
- },
305
- ],
306
- },
307
- },
308
- {
309
- forceTarget: 'resource' as const,
310
- release: {
311
- components: {
312
- applicationP1: {
313
- target: 'APPLICATION_P1',
314
- url: 'https://firmware.onekey.so/pro2/application-p1.bin',
315
- },
316
- },
317
- },
318
- },
319
- ])(
320
- 'rejects a Pro2 $forceTarget force target not represented by an artifact',
321
- ({ forceTarget, release }) => {
322
- expectFirmwarePlanInvalid(() =>
323
- buildFirmwareUpdatePlan(createProtocolV2ForceInput([forceTarget], release))
324
- );
325
- }
326
- );
327
-
328
- test.each([
329
- {
330
- forceTarget: 'firmware' as const,
331
- expectedArtifactIds: ['component:app_v1'],
332
- expectedTargets: ['app_v1'],
333
- },
334
- {
335
- forceTarget: 'resource' as const,
336
- expectedArtifactIds: ['resourceBundle:images'],
337
- expectedTargets: ['resource'],
338
- },
339
- ])(
340
- 'limits a Pro2 $forceTarget force to the selected artifact role',
341
- ({ forceTarget, expectedArtifactIds, expectedTargets }) => {
342
- const plan = buildFirmwareUpdatePlan(
343
- createProtocolV2ForceInput([forceTarget], {
344
- components: {
345
- applicationP1: {
346
- target: 'APPLICATION_P1',
347
- url: 'https://firmware.onekey.so/pro2/application-p1.bin',
348
- },
349
- },
350
- resourceBundles: [
351
- {
352
- name: 'images',
353
- url: 'https://firmware.onekey.so/pro2/images.okpkg',
354
- },
355
- ],
356
- })
357
- );
358
-
359
- expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual(expectedArtifactIds);
360
- expect(plan.targetsToUpdate).toEqual(expectedTargets);
361
- }
362
- );
363
-
364
- test('rejects a prepared native plan without a stable device identity', () => {
365
- const features = createFeatures({
366
- deviceType: EDeviceType.Classic1s,
367
- });
368
- delete (features as Partial<Features>).serialNo;
369
-
370
- expect(() =>
371
- buildFirmwareUpdatePlan({
372
- features,
373
- firmwareType: EFirmwareType.Universal,
374
- platform: 'native',
375
- firmware: {
376
- status: 'outdated',
377
- release: {
378
- url: 'https://firmware.onekey.so/classic/firmware.bin',
379
- },
380
- },
381
- ble: noUpdate,
382
- bootloader: noUpdate,
383
- })
384
- ).toThrow('requires a stable device identity');
385
- });
386
-
387
- test('maps the Pro2 component order and resource bundles without downloading them', () => {
388
- const plan = buildFirmwareUpdatePlan({
389
- features: createFeatures({ deviceType: EDeviceType.Pro2 }),
390
- firmwareType: EFirmwareType.Universal,
391
- platform: 'desktop',
392
- firmware: {
393
- status: 'required',
394
- release: {
395
- installOrder: ['bootloader', 'applicationP1'],
396
- components: {
397
- applicationP1: {
398
- target: 'APPLICATION_P1',
399
- url: 'https://firmware.onekey.so/pro2/application-p1.bin',
400
- expectedSize: 1024,
401
- fingerprint: '1111111111111111111111111111111111111111111111111111111111111111',
402
- },
403
- bootloader: {
404
- target: 'BOOTLOADER',
405
- url: 'https://firmware.onekey.so/pro2/bootloader.bin',
406
- },
407
- se01: {
408
- target: 'SE01',
409
- url: 'https://firmware.onekey.so/pro2/se01.bin',
410
- },
411
- },
412
- resourceBundles: [
413
- {
414
- name: 'images',
415
- url: 'https://firmware.onekey.so/pro2/images.okpkg',
416
- },
417
- ],
418
- },
419
- },
420
- ble: noUpdate,
421
- bootloader: noUpdate,
422
- });
423
-
424
- expect(plan.executor).toBe('v4');
425
- expect(plan.artifacts.map(artifact => artifact.artifactId)).toEqual([
426
- 'component:boot',
427
- 'component:app_v1',
428
- 'component:se01',
429
- 'resourceBundle:images',
430
- ]);
431
- expect(plan.targetsToUpdate).toEqual(['boot', 'app_v1', 'se01', 'resource']);
432
- expect(plan.artifacts[1]).toEqual(
433
- expect.objectContaining({
434
- expectedSize: 1024,
435
- expectedSha256: '1111111111111111111111111111111111111111111111111111111111111111',
436
- })
437
- );
438
- });
439
-
440
- test('rejects Pro2 ROMLOADER because it requires a separate loader flow', () => {
441
- expect(() =>
442
- buildFirmwareUpdatePlan({
443
- features: createFeatures({ deviceType: EDeviceType.Pro2 }),
444
- firmwareType: EFirmwareType.Universal,
445
- platform: 'desktop',
446
- firmware: {
447
- status: 'required',
448
- release: {
449
- components: {
450
- romloader: {
451
- target: 'ROMLOADER',
452
- url: 'https://firmware.onekey.so/pro2/romloader.bin',
453
- },
454
- },
455
- },
456
- },
457
- ble: noUpdate,
458
- bootloader: noUpdate,
459
- })
460
- ).toThrow('ROMLOADER requires its dedicated loader flow');
461
- });
462
-
463
- test.each([
464
- {
465
- label: 'component target',
466
- release: {
467
- components: {
468
- application: {
469
- target: 'APPLICATION_P1',
470
- url: 'https://firmware.onekey.so/pro2/application.bin',
471
- },
472
- applicationDuplicate: {
473
- target: 'APPLICATION_P1',
474
- url: 'https://firmware.onekey.so/pro2/application-duplicate.bin',
475
- },
476
- },
477
- },
478
- expectedError: 'duplicates target app_v1',
479
- },
480
- {
481
- label: 'resource bundle name',
482
- release: {
483
- components: {
484
- application: {
485
- target: 'APPLICATION_P1',
486
- url: 'https://firmware.onekey.so/pro2/application.bin',
487
- },
488
- },
489
- resourceBundles: [
490
- {
491
- name: 'images',
492
- url: 'https://firmware.onekey.so/pro2/images.okpkg',
493
- },
494
- {
495
- name: 'images',
496
- url: 'https://firmware.onekey.so/pro2/images-duplicate.okpkg',
497
- },
498
- ],
499
- },
500
- expectedError: 'duplicates name images',
501
- },
502
- ])('rejects a duplicate Pro2 $label', ({ release, expectedError }) => {
503
- expect(() =>
504
- buildFirmwareUpdatePlan({
505
- features: createFeatures({ deviceType: EDeviceType.Pro2 }),
506
- firmwareType: EFirmwareType.Universal,
507
- platform: 'desktop',
508
- firmware: {
509
- status: 'required',
510
- release,
511
- },
512
- ble: noUpdate,
513
- bootloader: noUpdate,
514
- })
515
- ).toThrow(expectedError);
516
- });
517
-
518
- test('produces a deterministic digest and binds it to the platform', () => {
519
- const input = {
520
- features: createFeatures({ deviceType: EDeviceType.Classic1s }),
521
- firmwareType: EFirmwareType.Universal,
522
- firmware: noUpdate,
523
- ble: noUpdate,
524
- bootloader: noUpdate,
525
- };
526
- const first = buildFirmwareUpdatePlan({ ...input, platform: 'native' });
527
- const second = buildFirmwareUpdatePlan({ ...input, platform: 'native' });
528
- const desktop = buildFirmwareUpdatePlan({ ...input, platform: 'desktop' });
529
-
530
- expect(first.planDigest).toMatch(/^[a-f0-9]{64}$/);
531
- expect(first.planDigest).toBe(second.planDigest);
532
- expect(first.planDigest).not.toBe(desktop.planDigest);
533
- });
534
-
535
- test('normalizes a malformed artifact URL to FirmwarePlanInvalid', () => {
536
- let thrown: unknown;
537
- try {
538
- buildFirmwareUpdatePlan({
539
- features: createFeatures({ deviceType: EDeviceType.Classic1s }),
540
- firmwareType: EFirmwareType.Universal,
541
- platform: 'native',
542
- firmware: {
543
- status: 'outdated',
544
- release: {
545
- url: 'not a url',
546
- version: [3, 0, 0],
547
- },
548
- },
549
- ble: noUpdate,
550
- bootloader: noUpdate,
551
- });
552
- } catch (error) {
553
- thrown = error;
554
- }
555
-
556
- expect(thrown).toMatchObject({
557
- params: {
558
- firmwareUpdateCode: 'FirmwarePlanInvalid',
559
- },
560
- });
561
- });
562
-
563
- test('binds trusted artifact integrity metadata into the plan digest', () => {
564
- const createPlan = (fingerprint: string) =>
565
- buildFirmwareUpdatePlan({
566
- features: createFeatures({ deviceType: EDeviceType.Classic1s }),
567
- firmwareType: EFirmwareType.Universal,
568
- platform: 'native',
569
- firmware: {
570
- status: 'outdated',
571
- release: {
572
- url: 'https://firmware.onekey.so/classic/firmware.bin',
573
- version: [3, 0, 0],
574
- expectedSize: 1024,
575
- fingerprint,
576
- },
577
- },
578
- ble: noUpdate,
579
- bootloader: noUpdate,
580
- });
581
-
582
- const first = createPlan('1111111111111111111111111111111111111111111111111111111111111111');
583
- const second = createPlan('2222222222222222222222222222222222222222222222222222222222222222');
584
-
585
- expect(first.artifacts[0]).toEqual(
586
- expect.objectContaining({
587
- expectedSize: 1024,
588
- expectedSha256: '1111111111111111111111111111111111111111111111111111111111111111',
589
- })
590
- );
591
- expect(first.planDigest).not.toBe(second.planDigest);
592
- });
593
- });