@onekeyfe/hd-core 1.2.0-alpha.66 → 1.2.0-alpha.67

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 (315) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +0 -313
  2. package/__tests__/DeviceCommands.test.ts +13 -59
  3. package/__tests__/DeviceEventRegistration.test.ts +0 -6
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -198
  5. package/__tests__/connectSettings.test.ts +47 -5
  6. package/__tests__/device-initialize-timeout.test.ts +56 -0
  7. package/__tests__/device-lifecycle-events.test.ts +3 -105
  8. package/__tests__/device-pool-state.test.ts +0 -22
  9. package/__tests__/device-settings.test.ts +18 -39
  10. package/__tests__/device-state-contract.test.ts +0 -1
  11. package/__tests__/device-state-mapper.test.ts +1 -13
  12. package/__tests__/device-utils.test.ts +1 -48
  13. package/__tests__/deviceSettings.test.ts +1 -11
  14. package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
  15. package/__tests__/firmware-update/device-update-bootloader.test.ts +87 -0
  16. package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
  17. package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
  18. package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
  19. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
  20. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
  21. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +394 -0
  22. package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
  23. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +231 -0
  24. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
  25. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
  26. package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
  27. package/__tests__/get-device-state.test.ts +12 -132
  28. package/__tests__/homescreen.test.ts +1 -41
  29. package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
  30. package/__tests__/kaspaSignTransaction.test.ts +26 -3
  31. package/__tests__/logBlockEvent.test.ts +1 -1
  32. package/__tests__/method-protocol-support.test.ts +0 -19
  33. package/__tests__/open-wallet-session.test.ts +37 -568
  34. package/__tests__/protocol-v2-unlock-policy.test.ts +37 -300
  35. package/__tests__/protocol-v2.test.ts +1153 -1458
  36. package/__tests__/protocolV2FileWrite.test.ts +0 -152
  37. package/__tests__/protocolV2UiInteraction.test.ts +0 -63
  38. package/__tests__/public-pro2-api-boundary.test.ts +0 -1
  39. package/__tests__/search-devices.test.ts +3 -12
  40. package/__tests__/tron-sign-message-init.test.ts +2 -2
  41. package/dist/api/BaseMethod.d.ts +1 -3
  42. package/dist/api/BaseMethod.d.ts.map +1 -1
  43. package/dist/api/CheckAllFirmwareRelease.d.ts +1 -2
  44. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  45. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  46. package/dist/api/FirmwareUpdateV2.d.ts +10 -0
  47. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  48. package/dist/api/FirmwareUpdateV3.d.ts +7 -3
  49. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  50. package/dist/api/FirmwareUpdateV4.d.ts +27 -13
  51. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  52. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  53. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  54. package/dist/api/SearchDevices.d.ts.map +1 -1
  55. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  56. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  57. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  58. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  59. package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
  60. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  61. package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
  62. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
  63. package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
  64. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
  65. package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
  66. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
  67. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +11 -4
  68. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  69. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
  70. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
  71. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
  72. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
  73. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
  74. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
  75. package/dist/api/firmware/getBinary.d.ts +7 -0
  76. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  77. package/dist/api/firmware/progressThrottle.d.ts +3 -0
  78. package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
  79. package/dist/api/firmware/updateBootloader.d.ts +2 -0
  80. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  81. package/dist/api/firmware/uploadFirmware.d.ts +9 -1
  82. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  83. package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -9
  84. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  85. package/dist/api/index.d.ts +0 -2
  86. package/dist/api/index.d.ts.map +1 -1
  87. package/dist/api/kaspa/KaspaGetAddress.d.ts +1 -1
  88. package/dist/api/kaspa/KaspaSignTransaction.d.ts +1 -1
  89. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  90. package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -1
  91. package/dist/api/polkadot/networks.d.ts +1 -1
  92. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  93. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  94. package/dist/api/solana/SolSignMessage.d.ts +1 -1
  95. package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -1
  96. package/dist/api/solana/SolSignTransaction.d.ts +2 -2
  97. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  98. package/dist/api/sui/SuiGetAddress.d.ts +1 -1
  99. package/dist/api/sui/SuiGetPublicKey.d.ts +1 -1
  100. package/dist/api/sui/SuiSignMessage.d.ts +1 -1
  101. package/dist/api/sui/SuiSignTransaction.d.ts +1 -1
  102. package/dist/api/ton/TonGetAddress.d.ts +1 -1
  103. package/dist/api/ton/TonSignMessage.d.ts +1 -1
  104. package/dist/api/ton/TonSignProof.d.ts +1 -1
  105. package/dist/api/tron/TronSignMessage.d.ts +2 -2
  106. package/dist/api/tron/TronSignTransaction.d.ts +1 -1
  107. package/dist/core/deviceEventRegistration.d.ts +0 -2
  108. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  109. package/dist/core/index.d.ts.map +1 -1
  110. package/dist/data-manager/DataManager.d.ts +4 -9
  111. package/dist/data-manager/DataManager.d.ts.map +1 -1
  112. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  113. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  114. package/dist/device/Device.d.ts +6 -29
  115. package/dist/device/Device.d.ts.map +1 -1
  116. package/dist/device/DeviceCommands.d.ts +4 -4
  117. package/dist/device/DeviceCommands.d.ts.map +1 -1
  118. package/dist/device/DeviceConnector.d.ts +1 -2
  119. package/dist/device/DeviceConnector.d.ts.map +1 -1
  120. package/dist/device/DevicePool.d.ts.map +1 -1
  121. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -1
  122. package/dist/events/device.d.ts +0 -4
  123. package/dist/events/device.d.ts.map +1 -1
  124. package/dist/events/logBlockEvent.d.ts.map +1 -1
  125. package/dist/events/ui-promise.d.ts +2 -4
  126. package/dist/events/ui-promise.d.ts.map +1 -1
  127. package/dist/events/ui-request.d.ts +2 -31
  128. package/dist/events/ui-request.d.ts.map +1 -1
  129. package/dist/events/ui-response.d.ts +2 -10
  130. package/dist/events/ui-response.d.ts.map +1 -1
  131. package/dist/index.d.ts +247 -243
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +3773 -3054
  134. package/dist/inject.d.ts +1 -6
  135. package/dist/inject.d.ts.map +1 -1
  136. package/dist/lowLevelInject.d.ts.map +1 -1
  137. package/dist/protocols/protocol-v2/features.d.ts +4 -0
  138. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  139. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  140. package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
  141. package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
  142. package/dist/protocols/protocol-v2/uiInteraction.d.ts +4 -7
  143. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  144. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
  145. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  146. package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
  147. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
  148. package/dist/protocols/protocol-v2/walletSession.d.ts +1 -6
  149. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  150. package/dist/topLevelInject.d.ts.map +1 -1
  151. package/dist/types/api/checkAllFirmwareRelease.d.ts +5 -3
  152. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  153. package/dist/types/api/deviceUnlock.d.ts +1 -5
  154. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  155. package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
  156. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  157. package/dist/types/api/export.d.ts +4 -2
  158. package/dist/types/api/export.d.ts.map +1 -1
  159. package/dist/types/api/firmwareUpdate.d.ts +70 -4
  160. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  161. package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
  162. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
  163. package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
  164. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
  165. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
  166. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
  167. package/dist/types/api/index.d.ts +10 -7
  168. package/dist/types/api/index.d.ts.map +1 -1
  169. package/dist/types/api/protocolV2.d.ts +0 -3
  170. package/dist/types/api/protocolV2.d.ts.map +1 -1
  171. package/dist/types/device.d.ts +2 -2
  172. package/dist/types/device.d.ts.map +1 -1
  173. package/dist/types/params.d.ts +0 -1
  174. package/dist/types/params.d.ts.map +1 -1
  175. package/dist/types/settings.d.ts +21 -38
  176. package/dist/types/settings.d.ts.map +1 -1
  177. package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
  178. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  179. package/dist/utils/deviceFeaturesUtils.d.ts +0 -4
  180. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  181. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  182. package/dist/utils/deviceSettings.d.ts.map +1 -1
  183. package/dist/utils/homescreen.d.ts +0 -4
  184. package/dist/utils/homescreen.d.ts.map +1 -1
  185. package/dist/utils/index.d.ts +1 -1
  186. package/dist/utils/index.d.ts.map +1 -1
  187. package/dist/utils/patch.d.ts +1 -1
  188. package/dist/utils/patch.d.ts.map +1 -1
  189. package/dist/utils/pro2Wallpaper.d.ts +0 -10
  190. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  191. package/package.json +4 -4
  192. package/src/api/BaseMethod.ts +10 -8
  193. package/src/api/CheckAllFirmwareRelease.ts +60 -59
  194. package/src/api/FirmwareUpdate.ts +15 -7
  195. package/src/api/FirmwareUpdateV2.ts +298 -126
  196. package/src/api/FirmwareUpdateV3.ts +265 -63
  197. package/src/api/FirmwareUpdateV4.ts +1017 -602
  198. package/src/api/GetPassphraseState.ts +1 -7
  199. package/src/api/OpenWalletSession.ts +17 -71
  200. package/src/api/SearchDevices.ts +1 -3
  201. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  202. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -36
  203. package/src/api/device/DeviceSettings.ts +4 -5
  204. package/src/api/device/DeviceUnlock.ts +3 -8
  205. package/src/api/device/DeviceUpdateBootloader.ts +125 -6
  206. package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
  207. package/src/api/firmware/FirmwareHostBinding.ts +100 -0
  208. package/src/api/firmware/FirmwarePreparationError.ts +12 -0
  209. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -27
  210. package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
  211. package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
  212. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +449 -0
  213. package/src/api/firmware/progressThrottle.ts +44 -0
  214. package/src/api/firmware/updateBootloader.ts +19 -4
  215. package/src/api/firmware/uploadFirmware.ts +144 -39
  216. package/src/api/helpers/protocolV2FileWrite.ts +63 -202
  217. package/src/api/index.ts +0 -2
  218. package/src/api/kaspa/KaspaGetAddress.ts +1 -1
  219. package/src/api/kaspa/KaspaSignTransaction.ts +13 -2
  220. package/src/api/polkadot/networks.ts +3 -3
  221. package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
  222. package/src/api/protocol-v2/helpers.ts +1 -1
  223. package/src/api/solana/SolSignMessage.ts +1 -1
  224. package/src/api/solana/SolSignOffchainMessage.ts +1 -1
  225. package/src/api/solana/SolSignTransaction.ts +2 -2
  226. package/src/api/sui/SuiGetAddress.ts +1 -1
  227. package/src/api/sui/SuiGetPublicKey.ts +1 -1
  228. package/src/api/sui/SuiSignMessage.ts +1 -1
  229. package/src/api/sui/SuiSignTransaction.ts +1 -1
  230. package/src/api/ton/TonGetAddress.ts +1 -1
  231. package/src/api/ton/TonSignMessage.ts +1 -1
  232. package/src/api/ton/TonSignProof.ts +1 -1
  233. package/src/api/tron/TronSignMessage.ts +2 -2
  234. package/src/api/tron/TronSignTransaction.ts +1 -1
  235. package/src/core/deviceEventRegistration.ts +0 -4
  236. package/src/core/index.ts +111 -213
  237. package/src/data/messages/messages-protocol-v2.json +0 -25
  238. package/src/data-manager/DataManager.ts +41 -113
  239. package/src/data-manager/TransportManager.ts +0 -6
  240. package/src/data-manager/connectSettings.ts +11 -0
  241. package/src/device/Device.ts +49 -274
  242. package/src/device/DeviceCommands.ts +4 -31
  243. package/src/device/DeviceConnector.ts +13 -33
  244. package/src/device/DevicePool.ts +7 -21
  245. package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
  246. package/src/deviceProfile/protocolV2DeviceIdentity.ts +0 -3
  247. package/src/events/device.ts +0 -4
  248. package/src/events/logBlockEvent.ts +0 -1
  249. package/src/events/ui-promise.ts +2 -4
  250. package/src/events/ui-request.ts +2 -36
  251. package/src/events/ui-response.ts +2 -12
  252. package/src/index.ts +5 -0
  253. package/src/inject.ts +24 -60
  254. package/src/lowLevelInject.ts +8 -7
  255. package/src/protocols/protocol-v2/features.ts +7 -10
  256. package/src/protocols/protocol-v2/firmware.ts +0 -2
  257. package/src/protocols/protocol-v2/lockedError.ts +10 -0
  258. package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
  259. package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
  260. package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
  261. package/src/protocols/protocol-v2/walletSession.ts +36 -214
  262. package/src/topLevelInject.ts +8 -7
  263. package/src/types/api/checkAllFirmwareRelease.ts +5 -3
  264. package/src/types/api/deviceUnlock.ts +1 -12
  265. package/src/types/api/deviceUpdateBootloader.ts +6 -0
  266. package/src/types/api/export.ts +18 -1
  267. package/src/types/api/firmwareUpdate.ts +78 -6
  268. package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
  269. package/src/types/api/firmwareUpdatePlan.ts +38 -0
  270. package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
  271. package/src/types/api/index.ts +14 -13
  272. package/src/types/api/protocolV2.ts +0 -13
  273. package/src/types/device.ts +3 -15
  274. package/src/types/params.ts +1 -7
  275. package/src/types/settings.ts +22 -60
  276. package/src/utils/deviceFeaturesCompat.ts +6 -5
  277. package/src/utils/deviceFeaturesUtils.ts +3 -14
  278. package/src/utils/deviceInfoUtils.ts +0 -2
  279. package/src/utils/deviceSettings.ts +0 -3
  280. package/src/utils/homescreen.ts +6 -32
  281. package/src/utils/index.ts +1 -6
  282. package/src/utils/pro2Wallpaper.ts +8 -35
  283. package/__tests__/core-initialization.test.ts +0 -23
  284. package/__tests__/device-connector-protocol.test.ts +0 -81
  285. package/__tests__/deviceUploadNft.test.ts +0 -316
  286. package/__tests__/pro2Nft.test.ts +0 -108
  287. package/__tests__/protocol-binding.test.ts +0 -89
  288. package/__tests__/protocol-v2-resources.test.ts +0 -340
  289. package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
  290. package/__tests__/uiProgressThrottle.test.ts +0 -74
  291. package/__tests__/uiPromiseRegistry.test.ts +0 -115
  292. package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
  293. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
  294. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
  295. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
  296. package/dist/core/uiPromiseRegistry.d.ts +0 -6
  297. package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
  298. package/dist/protocols/protocol-v2/resources.d.ts +0 -30
  299. package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
  300. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
  301. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
  302. package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
  303. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
  304. package/dist/utils/pro2Nft.d.ts +0 -31
  305. package/dist/utils/pro2Nft.d.ts.map +0 -1
  306. package/dist/utils/uiProgressThrottle.d.ts +0 -3
  307. package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
  308. package/src/api/DetectDeviceConnectProtocol.ts +0 -18
  309. package/src/api/protocol-v2/DeviceUploadNft.ts +0 -197
  310. package/src/core/uiPromiseRegistry.ts +0 -63
  311. package/src/protocols/protocol-v2/resources.ts +0 -390
  312. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -131
  313. package/src/types/api/detectDeviceConnectProtocol.ts +0 -6
  314. package/src/utils/pro2Nft.ts +0 -142
  315. package/src/utils/uiProgressThrottle.ts +0 -63
@@ -0,0 +1,593 @@
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
+ });