@onekeyfe/hd-core 1.2.0-alpha.2 → 1.2.0-alpha.20

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 (434) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +75 -0
  2. package/__tests__/DeviceCommands.test.ts +285 -0
  3. package/__tests__/DeviceEventRegistration.test.ts +43 -0
  4. package/__tests__/RequestQueue.test.ts +140 -0
  5. package/__tests__/UploadPortfolio.test.ts +46 -0
  6. package/__tests__/connectSettings.test.ts +19 -0
  7. package/__tests__/core-dispose.test.ts +34 -0
  8. package/__tests__/core-error-output.test.ts +39 -0
  9. package/__tests__/device-features-state.test.ts +78 -0
  10. package/__tests__/device-identity.test.ts +30 -0
  11. package/__tests__/device-lifecycle-events.test.ts +117 -0
  12. package/__tests__/device-pool-state.test.ts +132 -0
  13. package/__tests__/device-settings.test.ts +286 -0
  14. package/__tests__/device-state-contract.test.ts +27 -0
  15. package/__tests__/device-state-events.test.ts +162 -0
  16. package/__tests__/device-state-mapper.test.ts +229 -0
  17. package/__tests__/device-state-projector.test.ts +94 -0
  18. package/__tests__/device-state-store.test.ts +82 -0
  19. package/__tests__/device-utils.test.ts +106 -0
  20. package/__tests__/device-wallet-session-store.test.ts +213 -0
  21. package/__tests__/deviceFeaturesUtils.test.ts +39 -0
  22. package/__tests__/deviceSettings.test.ts +63 -0
  23. package/__tests__/evmLedgerLegacySafety.test.ts +4 -1
  24. package/__tests__/evmSignTypedData.test.ts +80 -0
  25. package/__tests__/filesystemValidation.test.ts +53 -0
  26. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +402 -0
  27. package/__tests__/get-device-state.test.ts +403 -0
  28. package/__tests__/homescreen.test.ts +24 -0
  29. package/__tests__/kaspaSignTransaction.test.ts +591 -0
  30. package/__tests__/logBlockEvent.test.ts +26 -0
  31. package/__tests__/networkUtils.test.ts +386 -0
  32. package/__tests__/open-wallet-session-error-response.test.ts +43 -0
  33. package/__tests__/open-wallet-session.test.ts +559 -0
  34. package/__tests__/preInitialize.test.ts +33 -0
  35. package/__tests__/pro2Wallpaper.test.ts +50 -0
  36. package/__tests__/protocol-v2-bootloader-mode.test.ts +37 -0
  37. package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
  38. package/__tests__/protocol-v2.test.ts +4054 -1178
  39. package/__tests__/protocolV2FileWrite.test.ts +92 -0
  40. package/__tests__/protocolV2UiInteraction.test.ts +266 -0
  41. package/__tests__/public-device-state-api.test.ts +253 -0
  42. package/__tests__/public-pro2-api-boundary.test.ts +91 -0
  43. package/__tests__/refresh-device-state.test.ts +101 -0
  44. package/__tests__/request-context-logging.test.ts +16 -0
  45. package/__tests__/search-devices.test.ts +136 -0
  46. package/dist/api/BaseMethod.d.ts +11 -0
  47. package/dist/api/BaseMethod.d.ts.map +1 -1
  48. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  49. package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
  50. package/dist/api/ClearSessionCache.d.ts +9 -0
  51. package/dist/api/ClearSessionCache.d.ts.map +1 -0
  52. package/dist/api/DirList.d.ts.map +1 -1
  53. package/dist/api/FileRead.d.ts.map +1 -1
  54. package/dist/api/FileWrite.d.ts +1 -0
  55. package/dist/api/FileWrite.d.ts.map +1 -1
  56. package/dist/api/FirmwareUpdateV2.d.ts +2 -2
  57. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  58. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  59. package/dist/api/FirmwareUpdateV4.d.ts +25 -5
  60. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  61. package/dist/api/GetDeviceState.d.ts +7 -0
  62. package/dist/api/GetDeviceState.d.ts.map +1 -0
  63. package/dist/api/GetFeatures.d.ts +1 -1
  64. package/dist/api/GetFeatures.d.ts.map +1 -1
  65. package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
  66. package/dist/api/GetPassphraseState.d.ts +1 -6
  67. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  68. package/dist/api/OpenWalletSession.d.ts +14 -0
  69. package/dist/api/OpenWalletSession.d.ts.map +1 -0
  70. package/dist/api/PathInfo.d.ts.map +1 -1
  71. package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
  72. package/dist/api/SearchDevices.d.ts +3 -0
  73. package/dist/api/SearchDevices.d.ts.map +1 -1
  74. package/dist/api/UploadPortfolio.d.ts +18 -0
  75. package/dist/api/UploadPortfolio.d.ts.map +1 -0
  76. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  77. package/dist/api/device/DeviceCancel.d.ts.map +1 -1
  78. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  79. package/dist/api/device/DeviceFullyUploadResource.d.ts +1 -2
  80. package/dist/api/device/DeviceFullyUploadResource.d.ts.map +1 -1
  81. package/dist/api/device/DeviceLock.d.ts.map +1 -1
  82. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  83. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  84. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  85. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  86. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  87. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  88. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  89. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +1 -0
  90. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  91. package/dist/api/firmware/getBinary.d.ts +11 -3
  92. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  93. package/dist/api/firmware/progressThrottle.d.ts +3 -0
  94. package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
  95. package/dist/api/helpers/filesystemValidation.d.ts +3 -0
  96. package/dist/api/helpers/filesystemValidation.d.ts.map +1 -1
  97. package/dist/api/helpers/paramsValidator.d.ts +1 -0
  98. package/dist/api/helpers/paramsValidator.d.ts.map +1 -1
  99. package/dist/api/helpers/protocolV2FileWrite.d.ts +33 -0
  100. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
  101. package/dist/api/index.d.ts +15 -19
  102. package/dist/api/index.d.ts.map +1 -1
  103. package/dist/api/kaspa/KaspaSignTransaction.d.ts +5 -1
  104. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  105. package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
  106. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +6 -0
  107. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -0
  108. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +7 -0
  109. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -0
  110. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -1
  111. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  112. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +3 -2
  113. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
  114. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +1 -1
  115. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -1
  116. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +28 -0
  117. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -0
  118. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  119. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +6 -0
  120. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +1 -0
  121. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +16 -0
  122. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -0
  123. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +12 -0
  124. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -0
  125. package/dist/api/protocol-v2/DeviceStatusGet.d.ts +6 -0
  126. package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
  127. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
  128. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
  129. package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
  130. package/dist/api/protocol-v2/{FilesystemFixPermission.d.ts → FilesystemPermissionFix.d.ts} +2 -2
  131. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -0
  132. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +6 -0
  133. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -0
  134. package/dist/api/protocol-v2/helpers.d.ts +27 -19
  135. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  136. package/dist/api/ton/TonSignData.d.ts +1 -5
  137. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  138. package/dist/api/utils.d.ts +2 -1
  139. package/dist/api/utils.d.ts.map +1 -1
  140. package/dist/constants/index.d.ts +2 -1
  141. package/dist/constants/index.d.ts.map +1 -1
  142. package/dist/core/RequestQueue.d.ts +19 -1
  143. package/dist/core/RequestQueue.d.ts.map +1 -1
  144. package/dist/core/deviceEventRegistration.d.ts +11 -0
  145. package/dist/core/deviceEventRegistration.d.ts.map +1 -0
  146. package/dist/core/index.d.ts +4 -1
  147. package/dist/core/index.d.ts.map +1 -1
  148. package/dist/data-manager/DataManager.d.ts +1 -1
  149. package/dist/data-manager/DataManager.d.ts.map +1 -1
  150. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  151. package/dist/device/Device.d.ts +34 -10
  152. package/dist/device/Device.d.ts.map +1 -1
  153. package/dist/device/DeviceCommands.d.ts +8 -6
  154. package/dist/device/DeviceCommands.d.ts.map +1 -1
  155. package/dist/device/DeviceFeaturesState.d.ts +4 -0
  156. package/dist/device/DeviceFeaturesState.d.ts.map +1 -0
  157. package/dist/device/DevicePool.d.ts +4 -2
  158. package/dist/device/DevicePool.d.ts.map +1 -1
  159. package/dist/device/DeviceStateMapper.d.ts +13 -0
  160. package/dist/device/DeviceStateMapper.d.ts.map +1 -0
  161. package/dist/device/DeviceStateProjector.d.ts +7 -0
  162. package/dist/device/DeviceStateProjector.d.ts.map +1 -0
  163. package/dist/device/DeviceStateStore.d.ts +21 -0
  164. package/dist/device/DeviceStateStore.d.ts.map +1 -0
  165. package/dist/device/DeviceWalletSessionStore.d.ts +20 -0
  166. package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
  167. package/dist/device/cloneDeviceState.d.ts +2 -0
  168. package/dist/device/cloneDeviceState.d.ts.map +1 -0
  169. package/dist/device/deviceIdentity.d.ts +5 -0
  170. package/dist/device/deviceIdentity.d.ts.map +1 -0
  171. package/dist/deviceProfile/buildDeviceFeatures.d.ts +9 -3
  172. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  173. package/dist/deviceProfile/index.d.ts +0 -1
  174. package/dist/deviceProfile/index.d.ts.map +1 -1
  175. package/dist/events/call.d.ts +7 -0
  176. package/dist/events/call.d.ts.map +1 -1
  177. package/dist/events/core.d.ts +2 -2
  178. package/dist/events/core.d.ts.map +1 -1
  179. package/dist/events/device.d.ts +11 -2
  180. package/dist/events/device.d.ts.map +1 -1
  181. package/dist/events/iframe.d.ts +1 -0
  182. package/dist/events/iframe.d.ts.map +1 -1
  183. package/dist/events/logBlockEvent.d.ts.map +1 -1
  184. package/dist/events/ui-request.d.ts +18 -2
  185. package/dist/events/ui-request.d.ts.map +1 -1
  186. package/dist/index.d.ts +1351 -603
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js +5995 -2816
  189. package/dist/inject.d.ts +3 -2
  190. package/dist/inject.d.ts.map +1 -1
  191. package/dist/lowLevelInject.d.ts +2 -1
  192. package/dist/lowLevelInject.d.ts.map +1 -1
  193. package/dist/protocols/protocol-v2/deviceSession.d.ts +7 -0
  194. package/dist/protocols/protocol-v2/deviceSession.d.ts.map +1 -0
  195. package/dist/protocols/protocol-v2/features.d.ts +23 -28
  196. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  197. package/dist/protocols/protocol-v2/firmware.d.ts +11 -9
  198. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  199. package/dist/protocols/protocol-v2/index.d.ts +3 -2
  200. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  201. package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
  202. package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
  203. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +16 -0
  204. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
  205. package/dist/protocols/protocol-v2/uiInteraction.d.ts +39 -0
  206. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
  207. package/dist/protocols/protocol-v2/unlockRetry.d.ts +11 -0
  208. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
  209. package/dist/protocols/protocol-v2/walletSession.d.ts +19 -0
  210. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
  211. package/dist/topLevelInject.d.ts.map +1 -1
  212. package/dist/types/api/checkAllFirmwareRelease.d.ts +1 -2
  213. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  214. package/dist/types/api/deviceSettings.d.ts +9 -0
  215. package/dist/types/api/deviceSettings.d.ts.map +1 -1
  216. package/dist/types/api/deviceUnlock.d.ts +1 -1
  217. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  218. package/dist/types/api/firmwareUpdate.d.ts +6 -6
  219. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  220. package/dist/types/api/getDeviceState.d.ts +12 -0
  221. package/dist/types/api/getDeviceState.d.ts.map +1 -0
  222. package/dist/types/api/getFeatures.d.ts.map +1 -1
  223. package/dist/types/api/getOnekeyFeatures.d.ts.map +1 -1
  224. package/dist/types/api/getPassphraseState.d.ts +2 -10
  225. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  226. package/dist/types/api/index.d.ts +26 -25
  227. package/dist/types/api/index.d.ts.map +1 -1
  228. package/dist/types/api/kaspaSignTransaction.d.ts +27 -2
  229. package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
  230. package/dist/types/api/openWalletSession.d.ts +41 -0
  231. package/dist/types/api/openWalletSession.d.ts.map +1 -0
  232. package/dist/types/api/protocolV2.d.ts +31 -28
  233. package/dist/types/api/protocolV2.d.ts.map +1 -1
  234. package/dist/types/api/sessionCache.d.ts +10 -0
  235. package/dist/types/api/sessionCache.d.ts.map +1 -0
  236. package/dist/types/device.d.ts +120 -4
  237. package/dist/types/device.d.ts.map +1 -1
  238. package/dist/types/params.d.ts +1 -0
  239. package/dist/types/params.d.ts.map +1 -1
  240. package/dist/types/settings.d.ts +21 -1
  241. package/dist/types/settings.d.ts.map +1 -1
  242. package/dist/utils/assets.d.ts +2 -1
  243. package/dist/utils/assets.d.ts.map +1 -1
  244. package/dist/utils/deviceFeaturesCompat.d.ts +13 -0
  245. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -0
  246. package/dist/utils/deviceFeaturesUtils.d.ts +13 -3
  247. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  248. package/dist/utils/deviceInfoUtils.d.ts +9 -8
  249. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  250. package/dist/utils/deviceSettings.d.ts +2 -0
  251. package/dist/utils/deviceSettings.d.ts.map +1 -1
  252. package/dist/utils/deviceVersionUtils.d.ts +6 -5
  253. package/dist/utils/deviceVersionUtils.d.ts.map +1 -1
  254. package/dist/utils/homescreen.d.ts.map +1 -1
  255. package/dist/utils/index.d.ts +3 -1
  256. package/dist/utils/index.d.ts.map +1 -1
  257. package/dist/utils/networkUtils.d.ts +9 -1
  258. package/dist/utils/networkUtils.d.ts.map +1 -1
  259. package/dist/utils/patch.d.ts +1 -1
  260. package/dist/utils/patch.d.ts.map +1 -1
  261. package/dist/utils/pro2Wallpaper.d.ts +12 -0
  262. package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
  263. package/dist/utils/tracing.d.ts.map +1 -1
  264. package/package.json +4 -4
  265. package/src/api/BaseMethod.ts +40 -7
  266. package/src/api/CheckBootloaderRelease.ts +1 -2
  267. package/src/api/CheckFirmwareRelease.ts +1 -2
  268. package/src/api/ClearSessionCache.ts +28 -0
  269. package/src/api/DirList.ts +5 -3
  270. package/src/api/DirMake.ts +3 -3
  271. package/src/api/DirRemove.ts +3 -3
  272. package/src/api/FileDelete.ts +3 -3
  273. package/src/api/FileRead.ts +23 -7
  274. package/src/api/FileWrite.ts +23 -168
  275. package/src/api/FirmwareUpdate.ts +4 -4
  276. package/src/api/FirmwareUpdateV2.ts +133 -45
  277. package/src/api/FirmwareUpdateV3.ts +3 -5
  278. package/src/api/FirmwareUpdateV4.ts +1138 -357
  279. package/src/api/GetDeviceState.ts +55 -0
  280. package/src/api/GetFeatures.ts +8 -3
  281. package/src/api/GetOnekeyFeatures.ts +3 -72
  282. package/src/api/GetPassphraseState.ts +11 -18
  283. package/src/api/OpenWalletSession.ts +221 -0
  284. package/src/api/PathInfo.ts +5 -3
  285. package/src/api/PromptWebDeviceAccess.ts +2 -3
  286. package/src/api/SearchDevices.ts +29 -4
  287. package/src/api/UploadPortfolio.ts +50 -0
  288. package/src/api/alephium/AlephiumSignTransaction.ts +2 -2
  289. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +4 -8
  290. package/src/api/benfen/BenfenGetAddress.ts +1 -1
  291. package/src/api/btc/BTCGetPublicKey.ts +1 -1
  292. package/src/api/cardano/CardanoSignMessage.ts +1 -1
  293. package/src/api/cardano/CardanoSignTransaction.ts +1 -1
  294. package/src/api/device/DeviceCancel.ts +1 -0
  295. package/src/api/device/DeviceChangePin.ts +24 -0
  296. package/src/api/device/DeviceFullyUploadResource.ts +4 -5
  297. package/src/api/device/DeviceLock.ts +1 -0
  298. package/src/api/device/DeviceRebootToBoardloader.ts +5 -4
  299. package/src/api/device/DeviceRebootToBootloader.ts +5 -4
  300. package/src/api/device/DeviceSettings.ts +121 -0
  301. package/src/api/device/DeviceUnlock.ts +9 -0
  302. package/src/api/device/DeviceUpdateBootloader.ts +1 -2
  303. package/src/api/device/DeviceWipe.ts +19 -0
  304. package/src/api/evm/EVMSignTypedData.ts +3 -5
  305. package/src/api/evm/legacyV1/getAddress.ts +2 -2
  306. package/src/api/evm/legacyV1/getPublicKey.ts +2 -2
  307. package/src/api/evm/legacyV1/signMessage.ts +2 -2
  308. package/src/api/evm/legacyV1/signTypedData.ts +2 -2
  309. package/src/api/evm/legacyV1/signTypedHash.ts +2 -2
  310. package/src/api/evm/legacyV1/verifyMessage.ts +2 -2
  311. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +21 -7
  312. package/src/api/firmware/getBinary.ts +8 -3
  313. package/src/api/firmware/progressThrottle.ts +44 -0
  314. package/src/api/helpers/batchGetPublickeys.ts +2 -2
  315. package/src/api/helpers/filesystemValidation.ts +61 -0
  316. package/src/api/helpers/paramsValidator.ts +1 -1
  317. package/src/api/helpers/protocolV2FileWrite.ts +193 -0
  318. package/src/api/index.ts +17 -20
  319. package/src/api/kaspa/KaspaSignTransaction.ts +341 -22
  320. package/src/api/kaspa/helpers/TransferSerialize.ts +14 -0
  321. package/src/api/nervos/NervosSignTransaction.ts +2 -2
  322. package/src/api/nexa/NexaSignTransaction.ts +1 -1
  323. package/src/api/protocol-v2/{FactoryGetDeviceInfo.ts → DeviceFactoryInfoGet.ts} +4 -4
  324. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +32 -0
  325. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +7 -9
  326. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +41 -6
  327. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +6 -4
  328. package/src/api/protocol-v2/DeviceInfoGet.ts +145 -0
  329. package/src/api/protocol-v2/DeviceReboot.ts +5 -3
  330. package/src/api/protocol-v2/DeviceSettingsGet.ts +18 -0
  331. package/src/api/protocol-v2/DeviceSettingsPageShow.ts +70 -0
  332. package/src/api/protocol-v2/DeviceSettingsSet.ts +44 -0
  333. package/src/api/protocol-v2/DeviceStatusGet.ts +16 -0
  334. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +131 -0
  335. package/src/api/protocol-v2/FilesystemFormat.ts +5 -2
  336. package/src/api/protocol-v2/{FilesystemFixPermission.ts → FilesystemPermissionFix.ts} +3 -3
  337. package/src/api/protocol-v2/Ping.ts +1 -1
  338. package/src/api/protocol-v2/{GetProtoVersion.ts → ProtocolInfoRequest.ts} +3 -3
  339. package/src/api/protocol-v2/helpers.ts +58 -62
  340. package/src/api/ton/TonSignData.ts +1 -5
  341. package/src/api/utils.ts +7 -3
  342. package/src/constants/index.ts +7 -1
  343. package/src/core/RequestQueue.ts +124 -4
  344. package/src/core/deviceEventRegistration.ts +23 -0
  345. package/src/core/index.ts +171 -60
  346. package/src/data/messages/messages-protocol-v2.json +825 -709
  347. package/src/data/messages/messages.json +286 -1
  348. package/src/data-manager/DataManager.ts +13 -6
  349. package/src/data-manager/connectSettings.ts +4 -0
  350. package/src/device/Device.ts +480 -192
  351. package/src/device/DeviceCommands.ts +81 -25
  352. package/src/device/DeviceFeaturesState.ts +34 -0
  353. package/src/device/DevicePool.ts +67 -19
  354. package/src/device/DeviceStateMapper.ts +348 -0
  355. package/src/device/DeviceStateProjector.ts +95 -0
  356. package/src/device/DeviceStateStore.ts +201 -0
  357. package/src/device/DeviceWalletSessionStore.ts +105 -0
  358. package/src/device/cloneDeviceState.ts +39 -0
  359. package/src/device/deviceIdentity.ts +18 -0
  360. package/src/deviceProfile/buildDeviceFeatures.ts +233 -209
  361. package/src/deviceProfile/index.ts +0 -1
  362. package/src/events/call.ts +6 -0
  363. package/src/events/core.ts +2 -0
  364. package/src/events/device.ts +17 -1
  365. package/src/events/iframe.ts +1 -0
  366. package/src/events/logBlockEvent.ts +8 -1
  367. package/src/events/ui-request.ts +24 -2
  368. package/src/index.ts +4 -0
  369. package/src/inject.ts +33 -34
  370. package/src/lowLevelInject.ts +3 -0
  371. package/src/protocols/protocol-v2/deviceSession.ts +24 -0
  372. package/src/protocols/protocol-v2/features.ts +68 -82
  373. package/src/protocols/protocol-v2/firmware.ts +12 -36
  374. package/src/protocols/protocol-v2/index.ts +3 -1
  375. package/src/protocols/protocol-v2/lockedError.ts +10 -0
  376. package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +61 -0
  377. package/src/protocols/protocol-v2/uiInteraction.ts +210 -0
  378. package/src/protocols/protocol-v2/unlockRetry.ts +76 -0
  379. package/src/protocols/protocol-v2/walletSession.ts +107 -0
  380. package/src/topLevelInject.ts +2 -0
  381. package/src/types/api/checkAllFirmwareRelease.ts +1 -2
  382. package/src/types/api/deviceSettings.ts +9 -0
  383. package/src/types/api/deviceUnlock.ts +1 -1
  384. package/src/types/api/firmwareUpdate.ts +28 -20
  385. package/src/types/api/getDeviceState.ts +19 -0
  386. package/src/types/api/getFeatures.ts +3 -0
  387. package/src/types/api/getOnekeyFeatures.ts +3 -0
  388. package/src/types/api/getPassphraseState.ts +8 -11
  389. package/src/types/api/index.ts +37 -53
  390. package/src/types/api/kaspaSignTransaction.ts +40 -2
  391. package/src/types/api/openWalletSession.ts +64 -0
  392. package/src/types/api/protocolV2.ts +88 -54
  393. package/src/types/api/sessionCache.ts +14 -0
  394. package/src/types/device.ts +167 -3
  395. package/src/types/params.ts +4 -0
  396. package/src/types/settings.ts +42 -30
  397. package/src/utils/assets.ts +4 -1
  398. package/src/utils/deviceFeaturesCompat.ts +173 -0
  399. package/src/utils/deviceFeaturesUtils.ts +68 -24
  400. package/src/utils/deviceInfoUtils.ts +26 -64
  401. package/src/utils/deviceSettings.ts +48 -0
  402. package/src/utils/deviceVersionUtils.ts +25 -44
  403. package/src/utils/findDefectiveBatchDevice.ts +3 -3
  404. package/src/utils/homescreen.ts +10 -0
  405. package/src/utils/index.ts +3 -0
  406. package/src/utils/networkUtils.ts +270 -14
  407. package/src/utils/pro2Wallpaper.ts +109 -0
  408. package/src/utils/tracing.ts +3 -1
  409. package/dist/api/GetDeviceInfo.d.ts +0 -9
  410. package/dist/api/GetDeviceInfo.d.ts.map +0 -1
  411. package/dist/api/protocol-v2/DevReboot.d.ts +0 -7
  412. package/dist/api/protocol-v2/DevReboot.d.ts.map +0 -1
  413. package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts +0 -29
  414. package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
  415. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
  416. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
  417. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
  418. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
  419. package/dist/api/protocol-v2/FilesystemDiskControl.d.ts +0 -13
  420. package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +0 -1
  421. package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
  422. package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
  423. package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
  424. package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
  425. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
  426. package/dist/types/api/getDeviceInfo.d.ts +0 -85
  427. package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
  428. package/src/api/GetDeviceInfo.ts +0 -145
  429. package/src/api/protocol-v2/DevReboot.ts +0 -24
  430. package/src/api/protocol-v2/DeviceGetDeviceInfo.ts +0 -118
  431. package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -29
  432. package/src/api/protocol-v2/FilesystemDiskControl.ts +0 -50
  433. package/src/deviceProfile/buildDeviceProfile.ts +0 -334
  434. package/src/types/api/getDeviceInfo.ts +0 -99
@@ -1,5 +1,5 @@
1
1
  import { BaseMethod } from './BaseMethod';
2
- import { validateNonEmptyString } from './helpers/filesystemValidation';
2
+ import { validateProtocolV2FilesystemPath } from './helpers/filesystemValidation';
3
3
 
4
4
  export type DirRemoveParams = {
5
5
  path: string;
@@ -7,11 +7,11 @@ export type DirRemoveParams = {
7
7
 
8
8
  export default class DirRemove extends BaseMethod<DirRemoveParams> {
9
9
  init() {
10
- // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
10
+ // Protocol V2 (Pro2) only; Core rejects non-V2 devices.
11
11
  this.requireProtocolV2 = true;
12
12
  this.skipForceUpdateCheck = true;
13
13
  this.useDevicePassphraseState = false;
14
- this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
14
+ this.params = { path: validateProtocolV2FilesystemPath(this.payload.path, 'path') };
15
15
  }
16
16
 
17
17
  async run() {
@@ -1,5 +1,5 @@
1
1
  import { BaseMethod } from './BaseMethod';
2
- import { validateNonEmptyString } from './helpers/filesystemValidation';
2
+ import { validateProtocolV2FilesystemPath } from './helpers/filesystemValidation';
3
3
 
4
4
  export type FileDeleteParams = {
5
5
  path: string;
@@ -7,11 +7,11 @@ export type FileDeleteParams = {
7
7
 
8
8
  export default class FileDelete extends BaseMethod<FileDeleteParams> {
9
9
  init() {
10
- // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
10
+ // Protocol V2 (Pro2) only; Core rejects non-V2 devices.
11
11
  this.requireProtocolV2 = true;
12
12
  this.skipForceUpdateCheck = true;
13
13
  this.useDevicePassphraseState = false;
14
- this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
14
+ this.params = { path: validateProtocolV2FilesystemPath(this.payload.path, 'path') };
15
15
  }
16
16
 
17
17
  async run() {
@@ -1,15 +1,15 @@
1
1
  import {
2
- PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
2
+ PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE,
3
3
  PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
4
4
  } from '@onekeyfe/hd-transport';
5
5
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
6
6
 
7
7
  import { BaseMethod } from './BaseMethod';
8
8
  import {
9
- validateNonEmptyString,
10
9
  validateNonNegativeInteger,
11
10
  validateOptionalNonNegativeInteger,
12
11
  validateOptionalPercentage,
12
+ validateProtocolV2FilesystemPath,
13
13
  } from './helpers/filesystemValidation';
14
14
  import { hexToBytes, isHexString, stripHexPrefix } from './helpers/hexUtils';
15
15
  import { DataManager } from '../data-manager';
@@ -27,7 +27,7 @@ const MIN_FILE_READ_CHUNK_SIZE = 64;
27
27
  function getProtocolV2FileReadChunkLimit() {
28
28
  const env = DataManager.getSettings('env');
29
29
  if (env && DataManager.isBleConnect(env)) {
30
- return PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
30
+ return PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE;
31
31
  }
32
32
  return PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
33
33
  }
@@ -69,13 +69,30 @@ function toUint8Array(value: unknown): Uint8Array {
69
69
  return new Uint8Array(0);
70
70
  }
71
71
 
72
+ function getDeviceTransferProgress(
73
+ bytesBeforeChunk: number,
74
+ bytesAfterChunk: number,
75
+ totalBytes: number
76
+ ) {
77
+ if (!Number.isFinite(totalBytes) || totalBytes <= 0) {
78
+ return 100;
79
+ }
80
+ if (bytesBeforeChunk <= 0 && bytesAfterChunk < totalBytes) {
81
+ return 0;
82
+ }
83
+ if (bytesAfterChunk >= totalBytes) {
84
+ return 100;
85
+ }
86
+ return Math.min(Math.max(Math.ceil((bytesAfterChunk / totalBytes) * 100), 1), 99);
87
+ }
88
+
72
89
  export default class FileRead extends BaseMethod<FileReadParams> {
73
90
  init() {
74
- // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
91
+ // Protocol V2 (Pro2) only; Core rejects non-V2 devices.
75
92
  this.requireProtocolV2 = true;
76
93
  this.skipForceUpdateCheck = true;
77
94
  this.useDevicePassphraseState = false;
78
- const path = validateNonEmptyString(this.payload.path, 'path');
95
+ const path = validateProtocolV2FilesystemPath(this.payload.path, 'path');
79
96
  this.params = {
80
97
  path,
81
98
  offset: validateNonNegativeInteger(this.payload.offset, 'offset', 0),
@@ -123,8 +140,7 @@ export default class FileRead extends BaseMethod<FileReadParams> {
123
140
  const readLen = Math.min(chunkSize, totalLength - read);
124
141
  const offset = startOffset + read;
125
142
  const progress =
126
- this.params.uiPercentage ??
127
- Math.min(Math.ceil(((read + readLen) / Math.max(totalLength, 1)) * 100), 99);
143
+ this.params.uiPercentage ?? getDeviceTransferProgress(read, read + readLen, totalLength);
128
144
  const res = await this.device.commands.typedCall('FilesystemFileRead', 'FilesystemFile', {
129
145
  file: {
130
146
  path: this.params.path,
@@ -1,19 +1,13 @@
1
- import {
2
- PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
3
- PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
4
- } from '@onekeyfe/hd-transport';
5
- import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
6
-
7
1
  import { BaseMethod } from './BaseMethod';
8
2
  import {
9
- validateNonEmptyString,
10
3
  validateNonNegativeInteger,
11
4
  validateOptionalNonNegativeInteger,
12
5
  validateOptionalPercentage,
6
+ validateProtocolV2FilesystemPath,
13
7
  validateRequiredData,
14
8
  } from './helpers/filesystemValidation';
9
+ import { writeProtocolV2File } from './helpers/protocolV2FileWrite';
15
10
  import { UI_REQUEST, createUiMessage } from '../events/ui-request';
16
- import { DataManager } from '../data-manager';
17
11
 
18
12
  export type FileWriteParams = {
19
13
  path: string;
@@ -24,74 +18,19 @@ export type FileWriteParams = {
24
18
  chunkLen?: number;
25
19
  overwrite?: boolean;
26
20
  append?: boolean;
21
+ emitProgress?: boolean;
27
22
  uiPercentage?: number;
28
23
  timeoutMs?: number | string;
29
24
  };
30
25
 
31
- const MIN_FILE_CHUNK_SIZE = 64;
32
-
33
- function getProtocolV2FileChunkLimit() {
34
- const env = DataManager.getSettings('env');
35
- if (env && DataManager.isBleConnect(env)) {
36
- return PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
37
- }
38
- return PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
39
- }
40
-
41
- async function dataToUint8Array(data: FileWriteParams['data'] | Blob): Promise<Uint8Array> {
42
- if (typeof data === 'string') {
43
- return new TextEncoder().encode(data);
44
- }
45
-
46
- if (data instanceof ArrayBuffer) {
47
- return new Uint8Array(data);
48
- }
49
-
50
- if (ArrayBuffer.isView(data)) {
51
- return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
52
- }
53
-
54
- if (typeof Blob !== 'undefined' && data instanceof Blob) {
55
- return new Uint8Array(await data.arrayBuffer());
56
- }
57
-
58
- throw ERRORS.TypedError(
59
- HardwareErrorCode.CallMethodInvalidParameter,
60
- 'Unsupported FilesystemFileWrite data'
61
- );
62
- }
63
-
64
- function normalizeChunkSize(value: unknown, maxChunkSize: number): number {
65
- const numeric = Number(value);
66
- if (!Number.isFinite(numeric) || numeric <= 0) return maxChunkSize;
67
- return Math.min(Math.max(Math.floor(numeric), MIN_FILE_CHUNK_SIZE), maxChunkSize);
68
- }
69
-
70
- function getConfirmedProgress(
71
- processedByte: number,
72
- totalSize: number,
73
- written: number,
74
- dataLength: number
75
- ) {
76
- if (Number.isFinite(processedByte) && Number.isFinite(totalSize) && totalSize > 0) {
77
- if (processedByte >= totalSize) return 100;
78
- return Math.min(Math.max(Math.floor((processedByte / totalSize) * 100), 0), 99);
79
- }
80
- if (dataLength > 0) {
81
- if (written >= dataLength) return 100;
82
- return Math.min(Math.max(Math.floor((written / dataLength) * 100), 0), 99);
83
- }
84
- return 100;
85
- }
86
-
87
26
  export default class FileWrite extends BaseMethod<FileWriteParams> {
88
27
  init() {
89
- // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
28
+ // Protocol V2 (Pro2) only; Core rejects non-V2 devices.
90
29
  this.requireProtocolV2 = true;
91
30
  this.skipForceUpdateCheck = true;
92
31
  this.useDevicePassphraseState = false;
93
32
  validateRequiredData(this.payload.data, 'data');
94
- const path = validateNonEmptyString(this.payload.path, 'path');
33
+ const path = validateProtocolV2FilesystemPath(this.payload.path, 'path');
95
34
  const offset = validateNonNegativeInteger(this.payload.offset, 'offset', 0);
96
35
  this.params = {
97
36
  path,
@@ -102,115 +41,31 @@ export default class FileWrite extends BaseMethod<FileWriteParams> {
102
41
  chunkLen: validateOptionalNonNegativeInteger(this.payload.chunkLen, 'chunkLen'),
103
42
  overwrite: this.payload.overwrite ?? offset === 0,
104
43
  append: this.payload.append ?? false,
44
+ emitProgress: this.payload.emitProgress ?? true,
105
45
  uiPercentage: validateOptionalPercentage(this.payload.uiPercentage, 'uiPercentage'),
106
46
  timeoutMs: validateOptionalNonNegativeInteger(this.payload.timeoutMs, 'timeoutMs'),
107
47
  };
108
48
  }
109
49
 
110
50
  async run() {
111
- const data = await dataToUint8Array(this.params.data);
112
- const dataLength = data.byteLength;
113
- const offsetValue = Number(this.params.offset ?? 0);
114
- const startOffset = Number.isFinite(offsetValue) && offsetValue > 0 ? offsetValue : 0;
115
- const payloadTotalSize = Number(this.params.totalSize);
116
- const totalSize =
117
- Number.isFinite(payloadTotalSize) && payloadTotalSize > 0
118
- ? payloadTotalSize
119
- : startOffset + dataLength;
120
-
121
- if (totalSize < startOffset + dataLength) {
122
- throw ERRORS.TypedError(
123
- HardwareErrorCode.RuntimeError,
124
- `FilesystemFileWrite totalSize ${totalSize} is smaller than offset + data length ${
125
- startOffset + dataLength
126
- }`
127
- );
128
- }
129
-
130
- const chunkSize = normalizeChunkSize(
131
- this.params.chunkSize ?? this.params.chunkLen,
132
- getProtocolV2FileChunkLimit()
133
- );
134
- const overwrite = this.params.overwrite ?? false;
135
- const append = this.params.append ?? false;
136
- let written = 0;
137
- let chunkIndex = 0;
138
- let lastMessage: Record<string, unknown> | undefined;
139
- const startTime = Date.now();
140
- const timeoutMs =
141
- this.params.timeoutMs === undefined ? undefined : Number(this.params.timeoutMs);
142
-
143
- while (written < dataLength) {
144
- const chunkEnd = Math.min(written + chunkSize, dataLength);
145
- const chunk = data.slice(written, chunkEnd);
146
- const offset = startOffset + written;
147
- const isFirstChunk = chunkIndex === 0;
148
- const progress =
149
- this.params.uiPercentage ??
150
- Math.min(Math.ceil(((written + chunk.byteLength) / dataLength) * 100), 99);
151
-
152
- const res = await this.device.commands.typedCall(
153
- 'FilesystemFileWrite',
154
- 'FilesystemFile',
155
- {
156
- file: {
157
- path: this.params.path,
158
- offset,
159
- total_size: totalSize,
160
- data: chunk,
161
- },
162
- overwrite: isFirstChunk ? overwrite : false,
163
- append,
164
- ui_percentage: progress,
165
- },
166
- {
167
- timeoutMs,
168
- }
169
- );
170
-
171
- lastMessage = res.message;
172
- const processedByte = Number(res.message?.processed_byte);
173
- if (Number.isFinite(processedByte) && processedByte > offset) {
174
- written = processedByte - startOffset;
175
- } else {
176
- written += chunk.byteLength;
177
- }
178
-
179
- if (written > dataLength) {
180
- throw ERRORS.TypedError(
181
- HardwareErrorCode.RuntimeError,
182
- `FilesystemFileWrite invalid processed_byte ${processedByte}`
183
- );
184
- }
185
-
186
- const confirmedProcessedByte =
187
- Number.isFinite(processedByte) && processedByte > offset
188
- ? processedByte
189
- : startOffset + written;
190
- if (typeof this.postMessage === 'function') {
191
- const elapsedMs = Date.now() - startTime;
192
- const transferredBytes = Math.min(written, dataLength);
193
- this.postMessage(
194
- createUiMessage(UI_REQUEST.DEVICE_PROGRESS, {
195
- progress: getConfirmedProgress(confirmedProcessedByte, totalSize, written, dataLength),
196
- transferredBytes,
197
- totalBytes: dataLength,
198
- rateBytesPerSecond:
199
- elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
200
- elapsedMs,
201
- })
202
- );
203
- }
204
- chunkIndex += 1;
205
- }
206
-
207
- return Promise.resolve({
208
- ...lastMessage,
51
+ return writeProtocolV2File({
52
+ commands: this.device.commands,
209
53
  path: this.params.path,
210
- offset: startOffset,
211
- total_size: totalSize,
212
- processed_byte: startOffset + written,
213
- chunks: chunkIndex,
54
+ data: this.params.data,
55
+ offset: this.params.offset,
56
+ totalSize: this.params.totalSize,
57
+ chunkSize: this.params.chunkSize,
58
+ chunkLen: this.params.chunkLen,
59
+ overwrite: this.params.overwrite,
60
+ append: this.params.append,
61
+ uiPercentage: this.params.uiPercentage,
62
+ timeoutMs: this.params.timeoutMs === undefined ? undefined : Number(this.params.timeoutMs),
63
+ throwIfAborted: () => this.throwIfAborted(),
64
+ onProgress: payload => {
65
+ if (this.params.emitProgress && typeof this.postMessage === 'function') {
66
+ this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, payload));
67
+ }
68
+ },
214
69
  });
215
70
  }
216
71
  }
@@ -14,7 +14,7 @@ import { uploadFirmware } from './firmware/uploadFirmware';
14
14
  import { createUiMessage } from '../events';
15
15
  import { DeviceModelToTypes, type KnownDevice } from '../types';
16
16
  import { isEnteredManuallyBoot } from './firmware/bootloaderHelper';
17
- import { LoggerNames, getDeviceUUID, getLogger, wait } from '../utils';
17
+ import { LoggerNames, getLogger, wait } from '../utils';
18
18
  import { DataManager } from '../data-manager';
19
19
  import { DevicePool } from '../device/DevicePool';
20
20
 
@@ -133,7 +133,7 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
133
133
  const { features, commands } = device;
134
134
  const deviceType = device.getCurrentDeviceType();
135
135
 
136
- // Protocol V2 (Pro2) 固件升级走 DeviceFirmwareUpdate 流程,禁止进入 legacy 入口
136
+ // Protocol V2 (Pro2) uses DeviceFirmwareUpdate and must not enter this legacy flow.
137
137
  if (device.isProtocolV2()) {
138
138
  throw ERRORS.TypedError(
139
139
  HardwareErrorCode.RuntimeError,
@@ -142,7 +142,7 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
142
142
  }
143
143
 
144
144
  if (!device.isBootloader() && features) {
145
- const uuid = getDeviceUUID(features);
145
+ const serialNo = device.getCurrentSerialNo();
146
146
  // should go to bootloader mode manually
147
147
  if (isEnteredManuallyBoot(features, params.updateType)) {
148
148
  return Promise.reject(ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateManuallyEnterBoot));
@@ -161,7 +161,7 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
161
161
 
162
162
  // force clean classic device cache so that the device can initialize again
163
163
  if (DeviceModelToTypes.model_classic.includes(deviceType)) {
164
- DevicePool.clearDeviceCache(uuid);
164
+ DevicePool.clearDeviceCache(serialNo);
165
165
  }
166
166
  delete DevicePool.devicesCache[''];
167
167
  await this.checkPromise?.promise;
@@ -15,20 +15,14 @@ import { validateParams } from './helpers/paramsValidator';
15
15
  import { DevicePool } from '../device/DevicePool';
16
16
  import { getBinary, getInfo, getSysResourceBinary } from './firmware/getBinary';
17
17
  import { updateResources, uploadFirmware } from './firmware/uploadFirmware';
18
- import {
19
- LoggerNames,
20
- getDeviceBootloaderVersion,
21
- getDeviceFirmwareVersion,
22
- getDeviceUUID,
23
- getLogger,
24
- wait,
25
- } from '../utils';
18
+ import { LoggerNames, getLogger, wait } from '../utils';
26
19
  import { FirmwareUpdateTipMessage, createUiMessage } from '../events/ui-request';
27
20
  import { DeviceModelToTypes } from '../types';
28
21
  import { DataManager } from '../data-manager';
29
22
  import { DEVICE } from '../events';
30
23
 
31
24
  import type { Features, KnownDevice } from '../types';
25
+ import type { FirmwareBinary } from './firmware/getBinary';
32
26
 
33
27
  type Params = {
34
28
  binary?: ArrayBuffer;
@@ -41,6 +35,77 @@ type Params = {
41
35
 
42
36
  const Log = getLogger(LoggerNames.Method);
43
37
 
38
+ const FIRMWARE_DOWNLOAD_REQUEST_OPTIONS = {
39
+ connectTimeoutMs: 60_000,
40
+ readTimeoutMs: 60_000,
41
+ overallTimeoutMs: 180_000,
42
+ maxRetries: 2,
43
+ retryDelayMs: 500,
44
+ } as const;
45
+
46
+ const normalizeFirmwareBinary = (binary: unknown): FirmwareBinary | undefined => {
47
+ if (typeof binary !== 'object' || binary === null) {
48
+ return undefined;
49
+ }
50
+
51
+ const isNodeBuffer =
52
+ typeof Buffer !== 'undefined' &&
53
+ typeof Buffer.isBuffer === 'function' &&
54
+ Buffer.isBuffer(binary);
55
+ if (isNodeBuffer) {
56
+ return binary.byteLength > 0 ? binary : undefined;
57
+ }
58
+
59
+ if (typeof ArrayBuffer !== 'undefined' && binary instanceof ArrayBuffer) {
60
+ return binary.byteLength > 0 ? binary : undefined;
61
+ }
62
+
63
+ if (
64
+ typeof ArrayBuffer !== 'undefined' &&
65
+ typeof ArrayBuffer.isView === 'function' &&
66
+ ArrayBuffer.isView(binary)
67
+ ) {
68
+ if (binary.byteLength <= 0) {
69
+ return undefined;
70
+ }
71
+ const source = new Uint8Array(binary.buffer, binary.byteOffset, binary.byteLength);
72
+ const normalized = new Uint8Array(binary.byteLength);
73
+ normalized.set(source);
74
+ return normalized.buffer;
75
+ }
76
+
77
+ const customBuffer = binary as {
78
+ [index: number]: unknown;
79
+ byteLength?: unknown;
80
+ constructor?: {
81
+ isBuffer?: (value: unknown) => boolean;
82
+ };
83
+ length?: unknown;
84
+ };
85
+ if (
86
+ typeof customBuffer.constructor?.isBuffer !== 'function' ||
87
+ !customBuffer.constructor.isBuffer(binary) ||
88
+ typeof customBuffer.byteLength !== 'number' ||
89
+ !Number.isSafeInteger(customBuffer.byteLength) ||
90
+ customBuffer.byteLength <= 0 ||
91
+ typeof customBuffer.length !== 'number' ||
92
+ customBuffer.length !== customBuffer.byteLength
93
+ ) {
94
+ return undefined;
95
+ }
96
+
97
+ const { byteLength } = customBuffer;
98
+ const normalized = new Uint8Array(byteLength);
99
+ for (let index = 0; index < byteLength; index += 1) {
100
+ const { [index]: byte } = customBuffer;
101
+ if (typeof byte !== 'number' || !Number.isInteger(byte) || byte < 0 || byte > 255) {
102
+ return undefined;
103
+ }
104
+ normalized[index] = byte;
105
+ }
106
+ return normalized.buffer;
107
+ };
108
+
44
109
  export default class FirmwareUpdateV2 extends BaseMethod<Params> {
45
110
  checkPromise: Deferred<any> | null = null;
46
111
 
@@ -223,22 +288,22 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
223
288
  return false;
224
289
  }
225
290
 
226
- isEnteredManuallyBoot(features: Features) {
291
+ isEnteredManuallyBoot() {
227
292
  const deviceType = this.device.getCurrentDeviceType();
228
293
  const isMini = deviceType === EDeviceType.Mini;
229
294
  const isBoot183ClassicUpBle =
230
295
  this.params.updateType === 'firmware' &&
231
296
  deviceType === EDeviceType.Classic &&
232
- getDeviceBootloaderVersion(features).join('.') === '1.8.3';
297
+ this.device.getCurrentBootloaderVersionString() === '1.8.3';
233
298
  return isMini || isBoot183ClassicUpBle;
234
299
  }
235
300
 
236
- isSupportResourceUpdate(features: Features, updateType: string) {
301
+ isSupportResourceUpdate(updateType: string) {
237
302
  if (updateType !== 'firmware') return false;
238
303
 
239
304
  const deviceType = this.device.getCurrentDeviceType();
240
305
  const isTouchMode = deviceType === EDeviceType.Touch || deviceType === EDeviceType.Pro;
241
- const currentVersion = getDeviceFirmwareVersion(features).join('.');
306
+ const currentVersion = this.device.getCurrentFirmwareVersionString() ?? '0.0.0';
242
307
 
243
308
  return isTouchMode && semver.gte(currentVersion, '3.2.0');
244
309
  }
@@ -250,7 +315,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
250
315
  checkVersionForCopyTouchResource(features: Features | undefined, firmwareType: EFirmwareType) {
251
316
  if (!features) return;
252
317
  const deviceType = this.device.getCurrentDeviceType();
253
- const currentVersion = getDeviceFirmwareVersion(features).join('.');
318
+ const currentVersion = this.device.getCurrentFirmwareVersionString() ?? '0.0.0';
254
319
  const targetVersion = this.params.version?.join('.');
255
320
  const { updateType } = this.params;
256
321
 
@@ -276,7 +341,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
276
341
  const { features, commands } = device;
277
342
  const deviceType = device.getCurrentDeviceType();
278
343
 
279
- // Protocol V2 (Pro2) 固件升级走 DeviceFirmwareUpdate 流程,禁止进入 legacy 入口
344
+ // Protocol V2 (Pro2) uses DeviceFirmwareUpdate and must not enter this legacy flow.
280
345
  if (device.isProtocolV2()) {
281
346
  throw ERRORS.TypedError(
282
347
  HardwareErrorCode.RuntimeError,
@@ -289,15 +354,57 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
289
354
 
290
355
  this.checkVersionForCopyTouchResource(features, firmwareType);
291
356
 
357
+ let preparedBinary: FirmwareBinary | undefined;
358
+ const acquireFirmwareBinary = async (): Promise<FirmwareBinary> => {
359
+ try {
360
+ if (preparedBinary) {
361
+ return preparedBinary;
362
+ }
363
+
364
+ if (params.binary !== undefined) {
365
+ preparedBinary = normalizeFirmwareBinary(params.binary);
366
+ if (!preparedBinary) {
367
+ throw new Error('firmware binary is empty or invalid');
368
+ }
369
+ return preparedBinary;
370
+ }
371
+
372
+ if (!device.features) {
373
+ throw ERRORS.TypedError(
374
+ HardwareErrorCode.RuntimeError,
375
+ 'no features found for this device'
376
+ );
377
+ }
378
+
379
+ this.postTipMessage('DownloadFirmware');
380
+ const firmware = await getBinary({
381
+ features: device.features,
382
+ version: params.version,
383
+ updateType: params.updateType,
384
+ isUpdateBootloader: params.isUpdateBootloader,
385
+ firmwareType,
386
+ requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
387
+ });
388
+ preparedBinary = normalizeFirmwareBinary(firmware.binary);
389
+ if (!preparedBinary) {
390
+ throw new Error('downloaded firmware binary is empty or invalid');
391
+ }
392
+ this.postTipMessage('DownloadFirmwareSuccess');
393
+ return preparedBinary;
394
+ } catch (err) {
395
+ throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
396
+ }
397
+ };
398
+
292
399
  if (!device.isBootloader() && features) {
293
- const uuid = getDeviceUUID(features);
400
+ const serialNo = device.getCurrentSerialNo();
294
401
  // should go to bootloader mode manually
295
- if (this.isEnteredManuallyBoot(features)) {
402
+ if (this.isEnteredManuallyBoot()) {
296
403
  return Promise.reject(ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateManuallyEnterBoot));
297
404
  }
298
405
 
299
406
  // check & upgrade firmware resource
300
- if (features && this.isSupportResourceUpdate(features, params.updateType)) {
407
+ if (this.isSupportResourceUpdate(params.updateType)) {
301
408
  this.postTipMessage('CheckLatestUiResource');
302
409
  const resourceUrl = DataManager.getSysResourcesLatestRelease({
303
410
  features,
@@ -322,6 +429,12 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
322
429
  // check if the device commands has been disposed
323
430
  this.device?.commands?.checkDisposed();
324
431
 
432
+ // A failed firmware download must leave the device in normal mode.
433
+ await acquireFirmwareBinary();
434
+
435
+ // The request may outlive the current transport command instance.
436
+ this.device?.commands?.checkDisposed();
437
+
325
438
  // auto go to bootloader mode
326
439
  try {
327
440
  this.postTipMessage('AutoRebootToBootloader');
@@ -335,7 +448,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
335
448
 
336
449
  // force clean classic device cache so that the device can initialize again
337
450
  if (DeviceModelToTypes.model_classic.includes(deviceType)) {
338
- DevicePool.clearDeviceCache(uuid);
451
+ DevicePool.clearDeviceCache(serialNo);
339
452
  }
340
453
  delete DevicePool.devicesCache[''];
341
454
  await this.checkPromise?.promise;
@@ -360,33 +473,8 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
360
473
  }
361
474
  }
362
475
 
363
- let binary;
364
-
365
- try {
366
- if (params.binary) {
367
- binary = this.params.binary;
368
- } else {
369
- if (!device.features) {
370
- throw ERRORS.TypedError(
371
- HardwareErrorCode.RuntimeError,
372
- 'no features found for this device'
373
- );
374
- }
375
- this.postTipMessage('DownloadFirmware');
376
-
377
- const firmware = await getBinary({
378
- features: device.features,
379
- version: params.version,
380
- updateType: params.updateType,
381
- isUpdateBootloader: params.isUpdateBootloader,
382
- firmwareType,
383
- });
384
- binary = firmware.binary;
385
- this.postTipMessage('DownloadFirmwareSuccess');
386
- }
387
- } catch (err) {
388
- throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
389
- }
476
+ // Devices already in bootloader mode still acquire through the same helper.
477
+ const binary = await acquireFirmwareBinary();
390
478
 
391
479
  // check if the device commands has been disposed
392
480
  this.device?.commands?.checkDisposed();
@@ -9,8 +9,6 @@ import {
9
9
  getDeviceBLEFirmwareVersion,
10
10
  getDeviceBootloaderVersion,
11
11
  getDeviceFirmwareVersion,
12
- getDeviceType,
13
- getFirmwareType,
14
12
  getLogger,
15
13
  } from '../utils';
16
14
  import { getBinary, getSysResourceBinary } from './firmware/getBinary';
@@ -97,8 +95,8 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
97
95
  const { device } = this;
98
96
  const { features } = device;
99
97
 
100
- const deviceType = getDeviceType(features);
101
- const bootloaderCurrVersion = getDeviceBootloaderVersion(features).join('.');
98
+ const deviceType = device.getCurrentDeviceType();
99
+ const bootloaderCurrVersion = device.getCurrentBootloaderVersionString() ?? '0.0.0';
102
100
 
103
101
  this.validateDeviceAndVersion(deviceType, bootloaderCurrVersion);
104
102
 
@@ -106,7 +104,7 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
106
104
  throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device features not available');
107
105
  }
108
106
 
109
- const deviceFirmwareType = getFirmwareType(features);
107
+ const deviceFirmwareType = device.getCurrentFirmwareType();
110
108
  const firmwareType = this.params.firmwareType ?? deviceFirmwareType;
111
109
  this.isSwitchFirmware = firmwareType !== deviceFirmwareType;
112
110