@onekeyfe/hd-core 1.2.0-alpha.51 → 1.2.0-alpha.53

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 (247) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +78 -0
  2. package/__tests__/DeviceCommands.test.ts +45 -0
  3. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +198 -3
  5. package/__tests__/connectSettings.test.ts +5 -47
  6. package/__tests__/device-lifecycle-events.test.ts +105 -3
  7. package/__tests__/deviceUploadNft.test.ts +293 -0
  8. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  9. package/__tests__/get-device-state.test.ts +132 -12
  10. package/__tests__/homescreen.test.ts +41 -1
  11. package/__tests__/logBlockEvent.test.ts +1 -1
  12. package/__tests__/method-protocol-support.test.ts +19 -0
  13. package/__tests__/open-wallet-session.test.ts +446 -33
  14. package/__tests__/pro2Nft.test.ts +108 -0
  15. package/__tests__/protocol-binding.test.ts +89 -0
  16. package/__tests__/protocol-v2-resources.test.ts +284 -0
  17. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  18. package/__tests__/protocol-v2-unlock-policy.test.ts +201 -35
  19. package/__tests__/protocol-v2.test.ts +1349 -1005
  20. package/__tests__/protocolV2UiInteraction.test.ts +63 -0
  21. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  22. package/__tests__/search-devices.test.ts +12 -3
  23. package/__tests__/uiProgressThrottle.test.ts +74 -0
  24. package/__tests__/uiPromiseRegistry.test.ts +86 -0
  25. package/dist/api/BaseMethod.d.ts +3 -1
  26. package/dist/api/BaseMethod.d.ts.map +1 -1
  27. package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
  28. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  29. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  30. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  31. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  32. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  33. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  34. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  35. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  36. package/dist/api/FirmwareUpdateV4.d.ts +11 -25
  37. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  38. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  39. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  40. package/dist/api/SearchDevices.d.ts.map +1 -1
  41. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  42. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  43. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  44. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  45. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  46. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -9
  47. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  48. package/dist/api/firmware/getBinary.d.ts +0 -7
  49. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  50. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  51. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  52. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  53. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  54. package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
  55. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  56. package/dist/api/index.d.ts +2 -0
  57. package/dist/api/index.d.ts.map +1 -1
  58. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  59. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  60. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  61. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  62. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  63. package/dist/core/deviceEventRegistration.d.ts +2 -0
  64. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  65. package/dist/core/index.d.ts.map +1 -1
  66. package/dist/core/uiPromiseRegistry.d.ts +4 -0
  67. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  68. package/dist/data-manager/DataManager.d.ts +4 -2
  69. package/dist/data-manager/DataManager.d.ts.map +1 -1
  70. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  71. package/dist/device/Device.d.ts +29 -6
  72. package/dist/device/Device.d.ts.map +1 -1
  73. package/dist/device/DeviceCommands.d.ts +4 -4
  74. package/dist/device/DeviceCommands.d.ts.map +1 -1
  75. package/dist/device/DevicePool.d.ts.map +1 -1
  76. package/dist/events/device.d.ts +4 -0
  77. package/dist/events/device.d.ts.map +1 -1
  78. package/dist/events/logBlockEvent.d.ts.map +1 -1
  79. package/dist/events/ui-promise.d.ts +4 -2
  80. package/dist/events/ui-promise.d.ts.map +1 -1
  81. package/dist/events/ui-request.d.ts +31 -2
  82. package/dist/events/ui-request.d.ts.map +1 -1
  83. package/dist/events/ui-response.d.ts +10 -2
  84. package/dist/events/ui-response.d.ts.map +1 -1
  85. package/dist/index.d.ts +214 -231
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2559 -3473
  88. package/dist/inject.d.ts +6 -1
  89. package/dist/inject.d.ts.map +1 -1
  90. package/dist/lowLevelInject.d.ts.map +1 -1
  91. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  92. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  93. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  94. package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
  95. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  96. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  97. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  98. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  99. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  100. package/dist/protocols/protocol-v2/walletSession.d.ts +5 -1
  101. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  102. package/dist/topLevelInject.d.ts.map +1 -1
  103. package/dist/types/api/checkAllFirmwareRelease.d.ts +2 -4
  104. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  105. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  106. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  107. package/dist/types/api/deviceUnlock.d.ts +5 -1
  108. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  109. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  110. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  111. package/dist/types/api/export.d.ts +2 -4
  112. package/dist/types/api/export.d.ts.map +1 -1
  113. package/dist/types/api/firmwareUpdate.d.ts +2 -70
  114. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  115. package/dist/types/api/index.d.ts +7 -10
  116. package/dist/types/api/index.d.ts.map +1 -1
  117. package/dist/types/api/protocolV2.d.ts +3 -0
  118. package/dist/types/api/protocolV2.d.ts.map +1 -1
  119. package/dist/types/device.d.ts.map +1 -1
  120. package/dist/types/params.d.ts +1 -0
  121. package/dist/types/params.d.ts.map +1 -1
  122. package/dist/types/settings.d.ts +22 -13
  123. package/dist/types/settings.d.ts.map +1 -1
  124. package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
  125. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  126. package/dist/utils/homescreen.d.ts +4 -0
  127. package/dist/utils/homescreen.d.ts.map +1 -1
  128. package/dist/utils/index.d.ts +1 -1
  129. package/dist/utils/index.d.ts.map +1 -1
  130. package/dist/utils/patch.d.ts +1 -1
  131. package/dist/utils/patch.d.ts.map +1 -1
  132. package/dist/utils/pro2Nft.d.ts +31 -0
  133. package/dist/utils/pro2Nft.d.ts.map +1 -0
  134. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  135. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  136. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  137. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  138. package/package.json +4 -4
  139. package/src/api/BaseMethod.ts +8 -10
  140. package/src/api/CheckAllFirmwareRelease.ts +54 -57
  141. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  142. package/src/api/FirmwareUpdate.ts +7 -15
  143. package/src/api/FirmwareUpdateV2.ts +126 -313
  144. package/src/api/FirmwareUpdateV3.ts +63 -265
  145. package/src/api/FirmwareUpdateV4.ts +566 -965
  146. package/src/api/GetPassphraseState.ts +7 -1
  147. package/src/api/OpenWalletSession.ts +54 -17
  148. package/src/api/SearchDevices.ts +3 -1
  149. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +32 -11
  150. package/src/api/device/DeviceUnlock.ts +8 -3
  151. package/src/api/device/DeviceUpdateBootloader.ts +6 -122
  152. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -83
  153. package/src/api/firmware/updateBootloader.ts +4 -19
  154. package/src/api/firmware/uploadFirmware.ts +39 -144
  155. package/src/api/helpers/protocolV2FileWrite.ts +11 -4
  156. package/src/api/index.ts +2 -0
  157. package/src/api/protocol-v2/DeviceUploadNft.ts +189 -0
  158. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  159. package/src/api/protocol-v2/helpers.ts +1 -0
  160. package/src/core/deviceEventRegistration.ts +4 -0
  161. package/src/core/index.ts +167 -83
  162. package/src/core/uiPromiseRegistry.ts +41 -0
  163. package/src/data/messages/messages-protocol-v2.json +25 -0
  164. package/src/data-manager/DataManager.ts +67 -38
  165. package/src/data-manager/connectSettings.ts +0 -11
  166. package/src/device/Device.ts +258 -42
  167. package/src/device/DeviceCommands.ts +7 -1
  168. package/src/device/DevicePool.ts +7 -2
  169. package/src/events/device.ts +4 -0
  170. package/src/events/logBlockEvent.ts +1 -0
  171. package/src/events/ui-promise.ts +4 -2
  172. package/src/events/ui-request.ts +36 -2
  173. package/src/events/ui-response.ts +12 -2
  174. package/src/index.ts +0 -5
  175. package/src/inject.ts +60 -24
  176. package/src/lowLevelInject.ts +7 -8
  177. package/src/protocols/protocol-v2/features.ts +10 -3
  178. package/src/protocols/protocol-v2/resources.ts +359 -0
  179. package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
  180. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  181. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +118 -0
  182. package/src/protocols/protocol-v2/walletSession.ts +180 -30
  183. package/src/topLevelInject.ts +7 -8
  184. package/src/types/api/checkAllFirmwareRelease.ts +2 -4
  185. package/src/types/api/detectDeviceConnectProtocol.ts +7 -0
  186. package/src/types/api/deviceUnlock.ts +12 -1
  187. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  188. package/src/types/api/export.ts +1 -18
  189. package/src/types/api/firmwareUpdate.ts +3 -76
  190. package/src/types/api/index.ts +13 -14
  191. package/src/types/api/protocolV2.ts +13 -0
  192. package/src/types/device.ts +3 -0
  193. package/src/types/params.ts +7 -1
  194. package/src/types/settings.ts +42 -13
  195. package/src/utils/deviceFeaturesUtils.ts +8 -0
  196. package/src/utils/homescreen.ts +32 -6
  197. package/src/utils/index.ts +6 -1
  198. package/src/utils/pro2Nft.ts +142 -0
  199. package/src/utils/pro2Wallpaper.ts +35 -8
  200. package/src/utils/uiProgressThrottle.ts +63 -0
  201. package/__tests__/device-initialize-timeout.test.ts +0 -56
  202. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  203. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  204. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  205. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  206. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
  207. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  208. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  209. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
  210. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
  211. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  212. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  213. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  214. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  215. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  216. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  217. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  218. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  219. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  220. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  221. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  222. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -30
  223. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  224. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  225. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  226. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  227. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  228. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  229. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  230. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  231. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  232. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  233. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  234. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  235. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  236. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  237. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  238. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  239. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  240. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -745
  241. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -392
  242. package/src/api/firmware/progressThrottle.ts +0 -44
  243. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  244. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
  245. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  246. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  247. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
@@ -14,45 +14,18 @@ import { BaseMethod } from './BaseMethod';
14
14
  import { validateParams } from './helpers/paramsValidator';
15
15
  import { DevicePool } from '../device/DevicePool';
16
16
  import { getBinary, getInfo, getSysResourceBinary } from './firmware/getBinary';
17
- import { normalizeFirmwarePreparationError } from './firmware/FirmwarePreparationError';
18
- import {
19
- updateResources,
20
- updateResourcesFromSources,
21
- uploadFirmwareFromSource,
22
- } from './firmware/uploadFirmware';
23
- import { BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS } from './firmware/FirmwareUpdateBaseMethod';
24
- import { LoggerNames, getDeviceUUID, getLogger, wait } from '../utils';
17
+ import { updateResources, uploadFirmware } from './firmware/uploadFirmware';
18
+ import { LoggerNames, getLogger, wait } from '../utils';
25
19
  import { FirmwareUpdateTipMessage, createUiMessage } from '../events/ui-request';
26
20
  import { DeviceModelToTypes } from '../types';
27
21
  import { DataManager } from '../data-manager';
28
22
  import { DEVICE } from '../events';
29
- import { type FirmwareByteSource, openFirmwareByteSource } from './firmware/FirmwareArtifactSource';
30
- import { resolveFirmwareUpdateHostBinding } from './firmware/FirmwareHostBinding';
31
- import {
32
- assertFirmwareUpdatePreparedPlanBinding,
33
- assertFirmwareUpdatePreparedPlanDeviceIdentity,
34
- getFirmwareUpdateResourceName,
35
- } from './firmware/FirmwareUpdatePreparedPlan';
36
23
 
37
24
  import type { Features, KnownDevice } from '../types';
38
25
  import type { FirmwareBinary } from './firmware/getBinary';
39
- import type {
40
- FirmwareArtifactReader,
41
- FirmwareArtifactReference,
42
- } from '../types/api/firmwareUpdate';
43
- import type { FirmwareUpdatePreparedPlan } from '../types/api/firmwareUpdatePreparedPlan';
44
26
 
45
27
  type Params = {
46
28
  binary?: ArrayBuffer;
47
- artifact?: FirmwareArtifactReference;
48
- resourceArtifact?: FirmwareArtifactReference;
49
- resourceEntries?: Array<{
50
- entryName: string;
51
- artifact: FirmwareArtifactReference;
52
- }>;
53
- artifactReader?: FirmwareArtifactReader;
54
- preparedPlan?: FirmwareUpdatePreparedPlan;
55
- platform?: FirmwareUpdatePreparedPlan['platform'];
56
29
  version?: number[];
57
30
  updateType: 'firmware' | 'ble';
58
31
  forcedUpdateRes?: boolean;
@@ -133,13 +106,6 @@ const normalizeFirmwareBinary = (binary: unknown): FirmwareBinary | undefined =>
133
106
  return normalized.buffer;
134
107
  };
135
108
 
136
- const toArrayBuffer = (binary: FirmwareBinary): ArrayBuffer => {
137
- if (binary instanceof ArrayBuffer) {
138
- return binary;
139
- }
140
- return new Uint8Array(binary.buffer, binary.byteOffset, binary.byteLength).slice().buffer;
141
- };
142
-
143
109
  export default class FirmwareUpdateV2 extends BaseMethod<Params> {
144
110
  checkPromise: Deferred<any> | null = null;
145
111
 
@@ -186,38 +152,6 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
186
152
  binary: payload.binary,
187
153
  };
188
154
  }
189
-
190
- if ('artifact' in payload) {
191
- const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration);
192
- const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
193
- const resourceBindings = [
194
- ...(payload.resourceArtifact
195
- ? [{ target: 'resource' as const, artifact: payload.resourceArtifact }]
196
- : []),
197
- ...(payload.resourceEntries ?? []).map(
198
- (entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
199
- target: 'resource' as const,
200
- entryName: entry.entryName,
201
- artifact: entry.artifact,
202
- })
203
- ),
204
- ];
205
- assertFirmwareUpdatePreparedPlanBinding({
206
- preparedPlan: payload.preparedPlan,
207
- executor: 'v2',
208
- platform: payload.platform,
209
- scopeTargets: [target, ...(target === 'firmware' ? (['resource'] as const) : [])],
210
- bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
211
- });
212
- this.params = {
213
- ...this.params,
214
- preparedPlan: payload.preparedPlan,
215
- artifact: payload.artifact,
216
- resourceArtifact: payload.resourceArtifact,
217
- resourceEntries: payload.resourceEntries,
218
- artifactReader: hostBinding.artifactReader,
219
- };
220
- }
221
155
  }
222
156
 
223
157
  postTipMessage = (message: string) => {
@@ -253,10 +187,6 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
253
187
  this.checkPromise = createDeferred();
254
188
  const env = DataManager.getSettings('env');
255
189
  const isBleReconnect = connectId && DataManager.isBleConnect(env);
256
- // Tracks the in-flight BLE probe so interval ticks never overlap: a superseded
257
- // Initialize left pending on the V1 transport is exactly what later times out
258
- // and used to tear down the connection mid-firmware-upload.
259
- let bleProbeInFlight = false;
260
190
 
261
191
  Log.log('FirmwareUpdateV2 [checkDeviceToBootloader] isBleReconnect: ', isBleReconnect);
262
192
 
@@ -304,18 +234,14 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
304
234
  }
305
235
 
306
236
  if (isBleReconnect) {
307
- if (bleProbeInFlight) return;
308
- bleProbeInFlight = true;
309
237
  try {
310
238
  await this.device.deviceConnector?.acquire(
311
239
  this.device.originalDescriptor.id,
312
240
  null,
313
- true
241
+ true,
242
+ this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType
314
243
  );
315
- // Bound each probe so a request the rebooting device never received
316
- // frees the slot for the next tick instead of hanging into the
317
- // 30s reboot budget.
318
- await this.device.initialize({ timeoutMs: BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS });
244
+ await this.device.initialize();
319
245
  if (this.device.isBootloader()) {
320
246
  clearInterval(intervalTimer);
321
247
  this.checkPromise?.resolve(true);
@@ -323,8 +249,6 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
323
249
  } catch (e) {
324
250
  // ignore error because of device is not connected
325
251
  Log.log('catch Bluetooth error when device is restarting: ', e);
326
- } finally {
327
- bleProbeInFlight = false;
328
252
  }
329
253
  } else {
330
254
  await this._checkDeviceInBootloaderMode(connectId, intervalTimer, timeoutTimer);
@@ -349,7 +273,9 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
349
273
  ) {
350
274
  const deviceDiff = await this.device.deviceConnector?.enumerate();
351
275
  const devicesDescriptor = deviceDiff?.descriptors ?? [];
352
- const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId);
276
+ const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId, {
277
+ connectProtocol: this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType,
278
+ });
353
279
 
354
280
  if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
355
281
  // should update current device from cache
@@ -418,264 +344,151 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
418
344
  const { features, commands } = device;
419
345
  const deviceType = device.getCurrentDeviceType();
420
346
 
421
- // Protocol V2 (Pro2) uses DeviceFirmwareUpdate and must not enter this legacy flow.
422
- if (device.isProtocolV2()) {
423
- throw ERRORS.TypedError(
424
- HardwareErrorCode.RuntimeError,
425
- 'Protocol V2 firmware update must use firmwareUpdateV4'
426
- );
427
- }
428
- if (params.preparedPlan) {
429
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
430
- preparedPlan: params.preparedPlan,
431
- deviceIdentity: getDeviceUUID(features) || undefined,
432
- });
433
- }
434
-
435
347
  const deviceFirmwareType = device.getCurrentFirmwareType();
436
348
  const firmwareType = params.firmwareType ?? deviceFirmwareType;
437
349
 
438
350
  this.checkVersionForCopyTouchResource(features, firmwareType);
439
351
 
440
- let preparedSource: FirmwareByteSource | undefined;
441
- try {
442
- const acquireFirmwareSource = async (): Promise<FirmwareByteSource> => {
443
- try {
444
- if (preparedSource) {
445
- return preparedSource;
446
- }
352
+ let preparedBinary: FirmwareBinary | undefined;
353
+ const acquireFirmwareBinary = async (): Promise<FirmwareBinary> => {
354
+ try {
355
+ if (preparedBinary) {
356
+ return preparedBinary;
357
+ }
447
358
 
448
- if (params.binary !== undefined) {
449
- const binary = normalizeFirmwareBinary(params.binary);
450
- if (!binary) {
451
- throw new Error('firmware binary is empty or invalid');
452
- }
453
- const source = await openFirmwareByteSource({
454
- binary: toArrayBuffer(binary),
455
- });
456
- if (!source) {
457
- throw new Error('firmware binary is empty or invalid');
458
- }
459
- preparedSource = source;
460
- return source;
359
+ if (params.binary !== undefined) {
360
+ preparedBinary = normalizeFirmwareBinary(params.binary);
361
+ if (!preparedBinary) {
362
+ throw new Error('firmware binary is empty or invalid');
461
363
  }
364
+ return preparedBinary;
365
+ }
462
366
 
463
- if (params.artifact) {
464
- const source = await openFirmwareByteSource({
465
- artifact: params.artifact,
466
- reader: params.artifactReader,
467
- });
468
- if (!source) {
469
- throw new Error('firmware artifact is not prepared');
470
- }
471
- preparedSource = source;
472
- return source;
473
- }
367
+ if (!device.features) {
368
+ throw ERRORS.TypedError(
369
+ HardwareErrorCode.RuntimeError,
370
+ 'no features found for this device'
371
+ );
372
+ }
474
373
 
475
- if (!device.features) {
476
- throw ERRORS.TypedError(
477
- HardwareErrorCode.RuntimeError,
478
- 'no features found for this device'
479
- );
480
- }
374
+ this.postTipMessage('DownloadFirmware');
375
+ const firmware = await getBinary({
376
+ features: device.features,
377
+ version: params.version,
378
+ updateType: params.updateType,
379
+ isUpdateBootloader: params.isUpdateBootloader,
380
+ firmwareType,
381
+ requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
382
+ });
383
+ preparedBinary = normalizeFirmwareBinary(firmware.binary);
384
+ if (!preparedBinary) {
385
+ throw new Error('downloaded firmware binary is empty or invalid');
386
+ }
387
+ this.postTipMessage('DownloadFirmwareSuccess');
388
+ return preparedBinary;
389
+ } catch (err) {
390
+ throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
391
+ }
392
+ };
481
393
 
482
- if (
483
- params.artifactReader ||
484
- DataManager.getSettings('firmwareManifestMode') === 'external-only'
485
- ) {
486
- throw ERRORS.TypedError(
487
- HardwareErrorCode.RuntimeError,
488
- 'Firmware must be prepared by the external firmware host',
489
- {
490
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
491
- artifactName: 'firmware',
492
- }
493
- );
494
- }
394
+ if (!device.isBootloader() && features) {
395
+ const serialNo = device.getCurrentSerialNo();
396
+ // should go to bootloader mode manually
397
+ if (this.isEnteredManuallyBoot()) {
398
+ return Promise.reject(ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateManuallyEnterBoot));
399
+ }
495
400
 
496
- this.postTipMessage('DownloadFirmware');
497
- const firmware = await getBinary({
498
- features: device.features,
499
- version: params.version,
500
- updateType: params.updateType,
501
- isUpdateBootloader: params.isUpdateBootloader,
502
- firmwareType,
503
- requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
504
- });
505
- const binary = normalizeFirmwareBinary(firmware.binary);
506
- if (!binary) {
507
- throw new Error('downloaded firmware binary is empty or invalid');
508
- }
509
- const source = await openFirmwareByteSource({
510
- binary: toArrayBuffer(binary),
511
- });
512
- if (!source) {
513
- throw new Error('downloaded firmware binary is empty or invalid');
401
+ // check & upgrade firmware resource
402
+ if (this.isSupportResourceUpdate(params.updateType)) {
403
+ this.postTipMessage('CheckLatestUiResource');
404
+ const resourceUrl = DataManager.getSysResourcesLatestRelease({
405
+ features,
406
+ forcedUpdateRes: params.forcedUpdateRes,
407
+ firmwareType,
408
+ });
409
+ if (resourceUrl) {
410
+ this.postTipMessage('DownloadLatestUiResource');
411
+ const resource = await getSysResourceBinary(resourceUrl);
412
+ this.postTipMessage('DownloadLatestUiResourceSuccess');
413
+ if (resource) {
414
+ await updateResources(
415
+ this.device.getCommands().typedCall.bind(this.device.getCommands()),
416
+ this.postMessage,
417
+ device,
418
+ resource.binary
419
+ );
514
420
  }
515
- preparedSource = source;
516
- this.postTipMessage('DownloadFirmwareSuccess');
517
- return source;
518
- } catch (err) {
519
- throw normalizeFirmwarePreparationError(err);
520
421
  }
521
- };
422
+ }
522
423
 
523
- if (!device.isBootloader() && features) {
524
- const serialNo = device.getCurrentSerialNo();
525
- // should go to bootloader mode manually
526
- if (this.isEnteredManuallyBoot()) {
527
- throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateManuallyEnterBoot);
424
+ // check if the device commands has been disposed
425
+ this.device?.commands?.checkDisposed();
426
+
427
+ // A failed firmware download must leave the device in normal mode.
428
+ await acquireFirmwareBinary();
429
+
430
+ // The request may outlive the current transport command instance.
431
+ this.device?.commands?.checkDisposed();
432
+
433
+ // auto go to bootloader mode
434
+ try {
435
+ this.postTipMessage('AutoRebootToBootloader');
436
+ const bootRes = await commands.typedCall('DeviceBackToBoot', 'Success');
437
+ // @ts-expect-error
438
+ if (bootRes.type === 'CallMethodError') {
439
+ throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
528
440
  }
441
+ this.postTipMessage('GoToBootloaderSuccess');
442
+ this.checkDeviceToBootloader(this.payload.connectId);
529
443
 
530
- // All network-backed input must be ready before the first device mutation.
531
- await acquireFirmwareSource();
532
-
533
- // check & upgrade firmware resource
534
- if (this.isSupportResourceUpdate(params.updateType)) {
535
- this.postTipMessage('CheckLatestUiResource');
536
- const resourceUrl = DataManager.getSysResourcesLatestRelease({
537
- features,
538
- forcedUpdateRes: params.forcedUpdateRes,
539
- firmwareType,
540
- });
541
- if (resourceUrl) {
542
- this.postTipMessage('DownloadLatestUiResource');
543
- if (params.resourceEntries?.length) {
544
- const sources: Array<{
545
- entryName: string;
546
- source: FirmwareByteSource;
547
- }> = [];
548
- try {
549
- for (const entry of params.resourceEntries) {
550
- const resourceName = getFirmwareUpdateResourceName(entry.entryName);
551
- const source = await openFirmwareByteSource({
552
- artifact: entry.artifact,
553
- reader: params.artifactReader,
554
- });
555
- if (!source) {
556
- throw new Error('Firmware resource entry is not prepared');
557
- }
558
- sources.push({ entryName: resourceName, source });
559
- }
560
- await updateResourcesFromSources(
561
- this.device.getCommands().typedCall.bind(this.device.getCommands()),
562
- this.postMessage,
563
- device,
564
- sources.map(entry => ({
565
- entryName: entry.entryName,
566
- source: entry.source,
567
- }))
568
- );
569
- } finally {
570
- await Promise.all(
571
- sources.map(entry => entry.source.close().catch(() => undefined))
572
- );
573
- }
574
- this.postTipMessage('DownloadLatestUiResourceSuccess');
575
- } else {
576
- let resourceBinary: ArrayBuffer | Buffer;
577
- if (params.resourceArtifact) {
578
- throw ERRORS.TypedError(
579
- HardwareErrorCode.RuntimeError,
580
- 'Firmware resource archive must be materialized into prepared entries',
581
- {
582
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
583
- artifactName: 'resource',
584
- }
585
- );
586
- } else {
587
- if (
588
- params.artifactReader ||
589
- DataManager.getSettings('firmwareManifestMode') === 'external-only'
590
- ) {
591
- throw ERRORS.TypedError(
592
- HardwareErrorCode.RuntimeError,
593
- 'Firmware resource must be prepared by the external firmware host',
594
- {
595
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
596
- artifactName: 'resource',
597
- }
598
- );
599
- }
600
- resourceBinary = (await getSysResourceBinary(resourceUrl)).binary;
601
- }
602
- this.postTipMessage('DownloadLatestUiResourceSuccess');
603
- await updateResources(
604
- this.device.getCommands().typedCall.bind(this.device.getCommands()),
605
- this.postMessage,
606
- device,
607
- resourceBinary
608
- );
609
- }
610
- }
444
+ // force clean classic device cache so that the device can initialize again
445
+ if (DeviceModelToTypes.model_classic.includes(deviceType)) {
446
+ DevicePool.clearDeviceCache(serialNo);
611
447
  }
448
+ delete DevicePool.devicesCache[''];
449
+ await this.checkPromise?.promise;
450
+ this.checkPromise = null;
612
451
 
613
- // The request may outlive the current transport command instance.
452
+ // check if the device commands has been disposed
614
453
  this.device?.commands?.checkDisposed();
615
454
 
616
- // auto go to bootloader mode
617
- try {
618
- this.postTipMessage('AutoRebootToBootloader');
619
- const bootRes = await commands.typedCall('DeviceBackToBoot', 'Success');
620
- // @ts-expect-error
621
- if (bootRes.type === 'CallMethodError') {
622
- throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
623
- }
624
- this.postTipMessage('GoToBootloaderSuccess');
625
- this.checkDeviceToBootloader(this.payload.connectId);
626
-
627
- // force clean classic device cache so that the device can initialize again
628
- if (DeviceModelToTypes.model_classic.includes(deviceType)) {
629
- DevicePool.clearDeviceCache(serialNo);
630
- }
631
- delete DevicePool.devicesCache[''];
632
- await this.checkPromise?.promise;
633
- this.checkPromise = null;
634
-
635
- // check if the device commands has been disposed
636
- this.device?.commands?.checkDisposed();
637
-
638
- /**
639
- * Touch 1 with bootloader v2.5.0 issue: BLE chip need more time for looking up name, here change the delay time to 3000ms after rebooting.
640
- */
641
- const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
642
- await wait(isTouch ? 3000 : 1500);
643
- } catch (e) {
644
- if (e instanceof HardwareError) {
645
- return Promise.reject(e);
646
- }
647
- console.log('auto go to bootloader mode failed: ', e);
648
- return Promise.reject(
649
- ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure)
650
- );
455
+ /**
456
+ * Touch 1 with bootloader v2.5.0 issue: BLE chip need more time for looking up name, here change the delay time to 3000ms after rebooting.
457
+ */
458
+ const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
459
+ await wait(isTouch ? 3000 : 1500);
460
+ } catch (e) {
461
+ if (e instanceof HardwareError) {
462
+ return Promise.reject(e);
651
463
  }
464
+ console.log('auto go to bootloader mode failed: ', e);
465
+ return Promise.reject(
466
+ ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure)
467
+ );
652
468
  }
469
+ }
653
470
 
654
- // Devices already in bootloader mode still acquire through the same helper.
655
- const source = await acquireFirmwareSource();
656
-
657
- // check if the device commands has been disposed
658
- this.device?.commands?.checkDisposed();
471
+ // Devices already in bootloader mode still acquire through the same helper.
472
+ const binary = await acquireFirmwareBinary();
659
473
 
660
- await this.device.acquire();
474
+ // check if the device commands has been disposed
475
+ this.device?.commands?.checkDisposed();
661
476
 
662
- const response = await uploadFirmwareFromSource(
663
- params.updateType,
664
- this.device.getCommands().typedCall.bind(this.device.getCommands()),
665
- this.postMessage,
666
- device,
667
- source,
668
- true,
669
- params.isUpdateBootloader
670
- );
477
+ await this.device.acquire();
671
478
 
672
- if (this.connectId) {
673
- DevicePool.clearDeviceCache(this.connectId);
674
- }
479
+ const response = await uploadFirmware(
480
+ params.updateType,
481
+ this.device.getCommands().typedCall.bind(this.device.getCommands()),
482
+ this.postMessage,
483
+ device,
484
+ { payload: binary, rebootOnSuccess: true },
485
+ params.isUpdateBootloader
486
+ );
675
487
 
676
- return response;
677
- } finally {
678
- await preparedSource?.close().catch(() => undefined);
488
+ if (this.connectId) {
489
+ DevicePool.clearDeviceCache(this.connectId);
679
490
  }
491
+
492
+ return response;
680
493
  }
681
494
  }