@onekeyfe/hd-core 1.1.27-alpha.34 → 1.1.27-alpha.4

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 (351) hide show
  1. package/__tests__/DeviceCommands.test.ts +99 -0
  2. package/__tests__/evmLedgerLegacySafety.test.ts +261 -0
  3. package/__tests__/evmSignTransaction.test.ts +1 -1
  4. package/__tests__/evmSignTypedData.test.ts +1 -1
  5. package/__tests__/preInitialize.test.ts +22 -0
  6. package/dist/api/BaseMethod.d.ts +7 -1
  7. package/dist/api/BaseMethod.d.ts.map +1 -1
  8. package/dist/api/FirmwareUpdateV3.d.ts +0 -1
  9. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  10. package/dist/api/GetFeatures.d.ts +1 -1
  11. package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
  12. package/dist/api/GetPassphraseState.d.ts +1 -6
  13. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  14. package/dist/api/SearchDevices.d.ts +1 -2
  15. package/dist/api/SearchDevices.d.ts.map +1 -1
  16. package/dist/api/alephium/AlephiumGetAddress.d.ts +6 -2
  17. package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
  18. package/dist/api/alephium/AlephiumSignMessage.d.ts +5 -2
  19. package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
  20. package/dist/api/alephium/AlephiumSignTransaction.d.ts +5 -2
  21. package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
  22. package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
  23. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  24. package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
  25. package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
  26. package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
  27. package/dist/api/benfen/BenfenGetAddress.d.ts +9 -2
  28. package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
  29. package/dist/api/benfen/BenfenGetPublicKey.d.ts +9 -2
  30. package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
  31. package/dist/api/benfen/BenfenSignMessage.d.ts +8 -2
  32. package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
  33. package/dist/api/benfen/BenfenSignTransaction.d.ts +8 -2
  34. package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
  35. package/dist/api/btc/BTCGetAddress.d.ts +11 -1
  36. package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
  37. package/dist/api/btc/BTCGetPublicKey.d.ts +11 -1
  38. package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
  39. package/dist/api/btc/BTCSignMessage.d.ts +15 -1
  40. package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
  41. package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
  42. package/dist/api/btc/BTCSignTransaction.d.ts +11 -1
  43. package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
  44. package/dist/api/btc/BTCVerifyMessage.d.ts +11 -1
  45. package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
  46. package/dist/api/btc/helpers/versionLimit.d.ts +11 -2
  47. package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
  48. package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
  49. package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
  50. package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
  51. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
  52. package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
  53. package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
  54. package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -1
  55. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  56. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  57. package/dist/api/device/PreInitialize.d.ts +6 -0
  58. package/dist/api/device/PreInitialize.d.ts.map +1 -0
  59. package/dist/api/dynex/DnxGetAddress.d.ts.map +1 -1
  60. package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
  61. package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
  62. package/dist/api/evm/EVMSignMessageEIP712.d.ts +8 -2
  63. package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
  64. package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
  65. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  66. package/dist/api/evm/latest/signTypedData.d.ts +1 -1
  67. package/dist/api/evm/latest/signTypedData.d.ts.map +1 -1
  68. package/dist/api/evm/legacyV1/signTypedData.d.ts +1 -1
  69. package/dist/api/evm/legacyV1/signTypedData.d.ts.map +1 -1
  70. package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
  71. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -10
  72. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  73. package/dist/api/index.d.ts +1 -28
  74. package/dist/api/index.d.ts.map +1 -1
  75. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  76. package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
  77. package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
  78. package/dist/api/neo/NeoGetAddress.d.ts +8 -2
  79. package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
  80. package/dist/api/neo/NeoSignTransaction.d.ts +8 -2
  81. package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
  82. package/dist/api/nervos/NervosGetAddress.d.ts +9 -2
  83. package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
  84. package/dist/api/nervos/NervosSignTransaction.d.ts +9 -2
  85. package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
  86. package/dist/api/nexa/NexaGetAddress.d.ts +8 -2
  87. package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
  88. package/dist/api/nexa/NexaSignTransaction.d.ts +9 -2
  89. package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
  90. package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
  91. package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
  92. package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
  93. package/dist/api/scdo/ScdoGetAddress.d.ts +6 -2
  94. package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
  95. package/dist/api/scdo/ScdoSignMessage.d.ts +5 -2
  96. package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
  97. package/dist/api/scdo/ScdoSignTransaction.d.ts +5 -2
  98. package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
  99. package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
  100. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  101. package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
  102. package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
  103. package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
  104. package/dist/api/stellar/StellarGetAddress.d.ts +1 -2
  105. package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
  106. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -2
  107. package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
  108. package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
  109. package/dist/api/sui/SuiSignTransaction.d.ts +2 -2
  110. package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
  111. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  112. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  113. package/dist/api/ton/TonSignProof.d.ts.map +1 -1
  114. package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
  115. package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
  116. package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
  117. package/dist/core/PollingStateManager.d.ts +8 -0
  118. package/dist/core/PollingStateManager.d.ts.map +1 -0
  119. package/dist/core/RequestQueue.d.ts +1 -1
  120. package/dist/core/RequestQueue.d.ts.map +1 -1
  121. package/dist/core/index.d.ts.map +1 -1
  122. package/dist/data-manager/DataManager.d.ts +4 -7
  123. package/dist/data-manager/DataManager.d.ts.map +1 -1
  124. package/dist/data-manager/MessagesConfig.d.ts +2 -2
  125. package/dist/data-manager/MessagesConfig.d.ts.map +1 -1
  126. package/dist/data-manager/TransportManager.d.ts +4 -5
  127. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  128. package/dist/device/Device.d.ts +18 -5
  129. package/dist/device/Device.d.ts.map +1 -1
  130. package/dist/device/DeviceCommands.d.ts +8 -8
  131. package/dist/device/DeviceCommands.d.ts.map +1 -1
  132. package/dist/device/DeviceConnector.d.ts +1 -2
  133. package/dist/device/DeviceConnector.d.ts.map +1 -1
  134. package/dist/events/ui-request.d.ts +0 -8
  135. package/dist/events/ui-request.d.ts.map +1 -1
  136. package/dist/index.d.ts +43 -292
  137. package/dist/index.js +998 -16134
  138. package/dist/inject.d.ts.map +1 -1
  139. package/dist/types/api/export.d.ts +1 -1
  140. package/dist/types/api/export.d.ts.map +1 -1
  141. package/dist/types/api/firmwareUpdate.d.ts +0 -7
  142. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  143. package/dist/types/api/getPassphraseState.d.ts +1 -10
  144. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  145. package/dist/types/api/index.d.ts +3 -33
  146. package/dist/types/api/index.d.ts.map +1 -1
  147. package/dist/types/api/preInitialize.d.ts +3 -0
  148. package/dist/types/api/preInitialize.d.ts.map +1 -0
  149. package/dist/types/api/searchDevices.d.ts +2 -2
  150. package/dist/types/api/searchDevices.d.ts.map +1 -1
  151. package/dist/types/device.d.ts +2 -6
  152. package/dist/types/device.d.ts.map +1 -1
  153. package/dist/types/params.d.ts +1 -2
  154. package/dist/types/params.d.ts.map +1 -1
  155. package/dist/types/settings.d.ts +1 -1
  156. package/dist/types/settings.d.ts.map +1 -1
  157. package/dist/utils/deviceFeaturesUtils.d.ts +3 -5
  158. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  159. package/dist/utils/deviceInfoUtils.d.ts +0 -1
  160. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  161. package/dist/utils/index.d.ts +1 -1
  162. package/dist/utils/index.d.ts.map +1 -1
  163. package/dist/utils/patch.d.ts +1 -1
  164. package/dist/utils/patch.d.ts.map +1 -1
  165. package/dist/utils/versionUtils.d.ts +1 -1
  166. package/package.json +4 -4
  167. package/src/api/BaseMethod.ts +82 -7
  168. package/src/api/FirmwareUpdateV3.ts +4 -21
  169. package/src/api/GetOnekeyFeatures.ts +3 -75
  170. package/src/api/GetPassphraseState.ts +2 -18
  171. package/src/api/SearchDevices.ts +2 -7
  172. package/src/api/alephium/AlephiumGetAddress.ts +2 -6
  173. package/src/api/alephium/AlephiumSignMessage.ts +2 -6
  174. package/src/api/alephium/AlephiumSignTransaction.ts +3 -6
  175. package/src/api/algo/AlgoSignTransaction.ts +1 -0
  176. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +9 -18
  177. package/src/api/aptos/AptosSignInMessage.ts +1 -0
  178. package/src/api/aptos/AptosSignMessage.ts +1 -0
  179. package/src/api/aptos/AptosSignTransaction.ts +1 -0
  180. package/src/api/benfen/BenfenGetAddress.ts +2 -6
  181. package/src/api/benfen/BenfenGetPublicKey.ts +2 -6
  182. package/src/api/benfen/BenfenSignMessage.ts +2 -6
  183. package/src/api/benfen/BenfenSignTransaction.ts +2 -6
  184. package/src/api/btc/BTCSignMessage.ts +1 -0
  185. package/src/api/btc/BTCSignPsbt.ts +1 -0
  186. package/src/api/btc/BTCSignTransaction.ts +1 -0
  187. package/src/api/btc/helpers/versionLimit.ts +1 -7
  188. package/src/api/cardano/CardanoSignMessage.ts +1 -0
  189. package/src/api/cardano/CardanoSignTransaction.ts +1 -0
  190. package/src/api/conflux/ConfluxSignMessage.ts +1 -0
  191. package/src/api/conflux/ConfluxSignMessageCIP23.ts +1 -0
  192. package/src/api/conflux/ConfluxSignTransaction.ts +3 -5
  193. package/src/api/cosmos/CosmosSignTransaction.ts +1 -0
  194. package/src/api/device/DeviceRebootToBoardloader.ts +1 -10
  195. package/src/api/device/DeviceRebootToBootloader.ts +1 -10
  196. package/src/api/device/PreInitialize.ts +41 -0
  197. package/src/api/dynex/DnxGetAddress.ts +0 -7
  198. package/src/api/dynex/DnxSignTransaction.ts +1 -7
  199. package/src/api/evm/EVMGetAddress.ts +1 -1
  200. package/src/api/evm/EVMGetPublicKey.ts +1 -1
  201. package/src/api/evm/EVMSignMessage.ts +3 -1
  202. package/src/api/evm/EVMSignMessageEIP712.ts +2 -14
  203. package/src/api/evm/EVMSignTransaction.ts +3 -1
  204. package/src/api/evm/EVMSignTypedData.ts +8 -6
  205. package/src/api/evm/EVMVerifyMessage.ts +1 -1
  206. package/src/api/filecoin/FilecoinSignTransaction.ts +1 -0
  207. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +4 -27
  208. package/src/api/index.ts +1 -30
  209. package/src/api/kaspa/KaspaSignTransaction.ts +1 -0
  210. package/src/api/near/NearSignTransaction.ts +1 -0
  211. package/src/api/nem/NEMSignTransaction.ts +1 -0
  212. package/src/api/neo/NeoGetAddress.ts +1 -6
  213. package/src/api/neo/NeoSignTransaction.ts +2 -6
  214. package/src/api/nervos/NervosGetAddress.ts +2 -6
  215. package/src/api/nervos/NervosSignTransaction.ts +3 -6
  216. package/src/api/nexa/NexaGetAddress.ts +2 -6
  217. package/src/api/nexa/NexaSignTransaction.ts +4 -6
  218. package/src/api/nostr/NostrSignEvent.ts +1 -0
  219. package/src/api/nostr/NostrSignSchnorr.ts +1 -0
  220. package/src/api/polkadot/PolkadotSignTransaction.ts +1 -0
  221. package/src/api/scdo/ScdoGetAddress.ts +2 -6
  222. package/src/api/scdo/ScdoSignMessage.ts +2 -6
  223. package/src/api/scdo/ScdoSignTransaction.ts +3 -6
  224. package/src/api/solana/SolSignMessage.ts +1 -0
  225. package/src/api/solana/SolSignOffchainMessage.ts +1 -0
  226. package/src/api/solana/SolSignTransaction.ts +1 -0
  227. package/src/api/starcoin/StarcoinSignMessage.ts +1 -0
  228. package/src/api/starcoin/StarcoinSignTransaction.ts +1 -0
  229. package/src/api/stellar/StellarGetAddress.ts +1 -10
  230. package/src/api/stellar/StellarSignTransaction.ts +2 -14
  231. package/src/api/sui/SuiSignMessage.ts +1 -0
  232. package/src/api/sui/SuiSignTransaction.ts +10 -12
  233. package/src/api/ton/TonSignData.ts +1 -0
  234. package/src/api/ton/TonSignMessage.ts +1 -0
  235. package/src/api/ton/TonSignProof.ts +1 -0
  236. package/src/api/tron/TronSignMessage.ts +2 -1
  237. package/src/api/tron/TronSignTransaction.ts +1 -0
  238. package/src/api/xrp/XrpSignTransaction.ts +2 -1
  239. package/src/core/PollingStateManager.ts +47 -0
  240. package/src/core/RequestQueue.ts +10 -3
  241. package/src/core/index.ts +153 -62
  242. package/src/data-manager/DataManager.ts +7 -12
  243. package/src/data-manager/MessagesConfig.ts +14 -14
  244. package/src/data-manager/TransportManager.ts +12 -38
  245. package/src/device/Device.ts +75 -82
  246. package/src/device/DeviceCommands.ts +26 -162
  247. package/src/device/DeviceConnector.ts +4 -29
  248. package/src/device/DevicePool.ts +1 -1
  249. package/src/events/ui-request.ts +0 -8
  250. package/src/inject.ts +2 -46
  251. package/src/types/api/export.ts +0 -1
  252. package/src/types/api/firmwareUpdate.ts +0 -12
  253. package/src/types/api/getPassphraseState.ts +2 -15
  254. package/src/types/api/index.ts +3 -80
  255. package/src/types/api/preInitialize.ts +3 -0
  256. package/src/types/api/searchDevices.ts +2 -2
  257. package/src/types/device.ts +2 -33
  258. package/src/types/params.ts +2 -4
  259. package/src/types/settings.ts +1 -1
  260. package/src/utils/deviceFeaturesUtils.ts +21 -62
  261. package/src/utils/deviceInfoUtils.ts +8 -15
  262. package/src/utils/index.ts +0 -1
  263. package/__tests__/protocol-v2.test.ts +0 -1501
  264. package/dist/api/DirList.d.ts +0 -10
  265. package/dist/api/DirList.d.ts.map +0 -1
  266. package/dist/api/DirMake.d.ts +0 -9
  267. package/dist/api/DirMake.d.ts.map +0 -1
  268. package/dist/api/DirRemove.d.ts +0 -9
  269. package/dist/api/DirRemove.d.ts.map +0 -1
  270. package/dist/api/FileDelete.d.ts +0 -9
  271. package/dist/api/FileDelete.d.ts.map +0 -1
  272. package/dist/api/FileRead.d.ts +0 -19
  273. package/dist/api/FileRead.d.ts.map +0 -1
  274. package/dist/api/FileWrite.d.ts +0 -23
  275. package/dist/api/FileWrite.d.ts.map +0 -1
  276. package/dist/api/FirmwareUpdateV4.d.ts +0 -32
  277. package/dist/api/FirmwareUpdateV4.d.ts.map +0 -1
  278. package/dist/api/GetDeviceInfo.d.ts +0 -9
  279. package/dist/api/GetDeviceInfo.d.ts.map +0 -1
  280. package/dist/api/PathInfo.d.ts +0 -9
  281. package/dist/api/PathInfo.d.ts.map +0 -1
  282. package/dist/api/helpers/deviceInfo.d.ts +0 -15
  283. package/dist/api/helpers/deviceInfo.d.ts.map +0 -1
  284. package/dist/api/helpers/filesystemValidation.d.ts +0 -7
  285. package/dist/api/helpers/filesystemValidation.d.ts.map +0 -1
  286. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +0 -7
  287. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +0 -1
  288. package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts +0 -7
  289. package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
  290. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +0 -6
  291. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +0 -1
  292. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +0 -6
  293. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +0 -1
  294. package/dist/api/protocol-v2/DeviceReboot.d.ts +0 -7
  295. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +0 -1
  296. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
  297. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
  298. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
  299. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
  300. package/dist/api/protocol-v2/FilesystemDiskControl.d.ts +0 -10
  301. package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +0 -1
  302. package/dist/api/protocol-v2/FilesystemFixPermission.d.ts +0 -6
  303. package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
  304. package/dist/api/protocol-v2/FilesystemFormat.d.ts +0 -6
  305. package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +0 -1
  306. package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
  307. package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
  308. package/dist/api/protocol-v2/Ping.d.ts +0 -8
  309. package/dist/api/protocol-v2/Ping.d.ts.map +0 -1
  310. package/dist/api/protocol-v2/helpers.d.ts +0 -49
  311. package/dist/api/protocol-v2/helpers.d.ts.map +0 -1
  312. package/dist/protocols/protocol-v2/features.d.ts +0 -74
  313. package/dist/protocols/protocol-v2/features.d.ts.map +0 -1
  314. package/dist/protocols/protocol-v2/firmware.d.ts +0 -12
  315. package/dist/protocols/protocol-v2/firmware.d.ts.map +0 -1
  316. package/dist/protocols/protocol-v2/index.d.ts +0 -3
  317. package/dist/protocols/protocol-v2/index.d.ts.map +0 -1
  318. package/dist/types/api/getDeviceInfo.d.ts +0 -84
  319. package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
  320. package/dist/types/api/protocolV2.d.ts +0 -127
  321. package/dist/types/api/protocolV2.d.ts.map +0 -1
  322. package/src/api/DirList.ts +0 -29
  323. package/src/api/DirMake.ts +0 -21
  324. package/src/api/DirRemove.ts +0 -21
  325. package/src/api/FileDelete.ts +0 -21
  326. package/src/api/FileRead.ts +0 -165
  327. package/src/api/FileWrite.ts +0 -203
  328. package/src/api/FirmwareUpdateV4.ts +0 -810
  329. package/src/api/GetDeviceInfo.ts +0 -153
  330. package/src/api/PathInfo.ts +0 -25
  331. package/src/api/helpers/deviceInfo.ts +0 -205
  332. package/src/api/helpers/filesystemValidation.ts +0 -51
  333. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +0 -50
  334. package/src/api/protocol-v2/DeviceGetDeviceInfo.ts +0 -35
  335. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +0 -18
  336. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +0 -18
  337. package/src/api/protocol-v2/DeviceReboot.ts +0 -22
  338. package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -27
  339. package/src/api/protocol-v2/FactoryGetDeviceInfo.ts +0 -18
  340. package/src/api/protocol-v2/FilesystemDiskControl.ts +0 -34
  341. package/src/api/protocol-v2/FilesystemFixPermission.ts +0 -14
  342. package/src/api/protocol-v2/FilesystemFormat.ts +0 -14
  343. package/src/api/protocol-v2/GetProtoVersion.ts +0 -14
  344. package/src/api/protocol-v2/Ping.ts +0 -16
  345. package/src/api/protocol-v2/helpers.ts +0 -161
  346. package/src/data/messages/messages-protocol-v2.json +0 -13116
  347. package/src/protocols/protocol-v2/features.ts +0 -278
  348. package/src/protocols/protocol-v2/firmware.ts +0 -26
  349. package/src/protocols/protocol-v2/index.ts +0 -2
  350. package/src/types/api/getDeviceInfo.ts +0 -97
  351. package/src/types/api/protocolV2.ts +0 -226
@@ -1,1501 +0,0 @@
1
- import JSZip from 'jszip';
2
- import { HardwareErrorCode } from '@onekeyfe/hd-shared';
3
- import { DeviceRebootType } from '@onekeyfe/hd-transport';
4
-
5
- import ConfluxSignTransaction from '../src/api/conflux/ConfluxSignTransaction';
6
- import DnxGetAddress from '../src/api/dynex/DnxGetAddress';
7
- import DnxSignTransaction from '../src/api/dynex/DnxSignTransaction';
8
- import DirList from '../src/api/DirList';
9
- import FileRead from '../src/api/FileRead';
10
- import FileWrite from '../src/api/FileWrite';
11
- import DeviceFirmwareUpdate from '../src/api/protocol-v2/DeviceFirmwareUpdate';
12
- import DeviceGetOnboardingStatus from '../src/api/protocol-v2/DeviceGetOnboardingStatus';
13
- import EVMSignMessageEIP712 from '../src/api/evm/EVMSignMessageEIP712';
14
- import FirmwareUpdateV3 from '../src/api/FirmwareUpdateV3';
15
- import FirmwareUpdateV4 from '../src/api/FirmwareUpdateV4';
16
- import GetOnekeyFeatures from '../src/api/GetOnekeyFeatures';
17
- import { batchGetPublickeys } from '../src/api/helpers/batchGetPublickeys';
18
- import SuiSignTransaction from '../src/api/sui/SuiSignTransaction';
19
- import TronSignMessage from '../src/api/tron/TronSignMessage';
20
- import XrpSignTransaction from '../src/api/xrp/XrpSignTransaction';
21
- import StellarGetAddress from '../src/api/stellar/StellarGetAddress';
22
- import BenfenSignMessage from '../src/api/benfen/BenfenSignMessage';
23
- import { getBitcoinForkVersionRange } from '../src/api/btc/helpers/versionLimit';
24
- import { DataManager } from '../src/data-manager';
25
- import { Device } from '../src/device/Device';
26
- import { UI_REQUEST } from '../src/events/ui-request';
27
- import { getProtocolV2Features, normalizeProtocolV2Features } from '../src/protocols/protocol-v2';
28
- import { getMethodVersionRange, isMethodVersionRangeUnsupported } from '../src/utils';
29
- import {
30
- getPassphraseState,
31
- getPassphraseStateWithRefreshDeviceInfo,
32
- } from '../src/utils/deviceFeaturesUtils';
33
-
34
- import type { DeviceCommands } from '../src/device/DeviceCommands';
35
-
36
- jest.mock('../src/data/config', () => ({
37
- getSDKVersion: jest.fn(() => '1.0.0'),
38
- DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
39
- }));
40
-
41
- const descriptor = {
42
- id: 'ble-id',
43
- path: 'usb-path',
44
- };
45
-
46
- describe('Protocol V2 feature adapter', () => {
47
- test('normalizes Protocol V2 DeviceInfo into existing Features fields', () => {
48
- const features = normalizeProtocolV2Features(descriptor as any, {
49
- protocol_version: 1,
50
- hw: {
51
- serial_no: 'PR2SERIAL',
52
- },
53
- fw: {
54
- board: {
55
- version: '0.1.0',
56
- hash: [1, 2, 255],
57
- },
58
- boot: {
59
- version: '0.2.0',
60
- build_id: 'boot-build',
61
- hash: new Uint8Array([10, 11]),
62
- },
63
- app: {
64
- version: '1.2.3',
65
- build_id: 'app-build',
66
- hash: 'abc123',
67
- },
68
- },
69
- bt: {
70
- app: {
71
- version: '4.5.6',
72
- build_id: 'bt-build',
73
- hash: [12, 13],
74
- },
75
- adv_name: 'Pro2 BLE',
76
- },
77
- se1: {
78
- app: {
79
- version: '7.8.9',
80
- build_id: 'se-build',
81
- hash: [14, 15],
82
- },
83
- state: 85,
84
- },
85
- se2: {
86
- app: {
87
- version: '8.0.0',
88
- },
89
- state: 0,
90
- },
91
- status: {
92
- label: 'My Pro2',
93
- language: 'en-US',
94
- bt_enable: true,
95
- init_states: false,
96
- backup_required: true,
97
- passphrase_protection: true,
98
- },
99
- });
100
-
101
- expect(features.device_id).toBe('PR2SERIAL');
102
- expect(features.serial_no).toBe('PR2SERIAL');
103
- expect(features.onekey_serial_no).toBe('PR2SERIAL');
104
- expect(features.onekey_device_type).toBe('pro2');
105
- expect(features.protocol_version).toBe(1);
106
- expect(features.major_version).toBe(1);
107
- expect(features.minor_version).toBe(2);
108
- expect(features.patch_version).toBe(3);
109
- expect(features.onekey_firmware_version).toBe('1.2.3');
110
- expect(features.onekey_firmware_build_id).toBe('app-build');
111
- expect(features.onekey_firmware_hash).toBe('abc123');
112
- expect(features.bootloader_version).toBe('0.2.0');
113
- expect(features.onekey_boot_build_id).toBe('boot-build');
114
- expect(features.onekey_boot_hash).toBe('0a0b');
115
- expect(features.onekey_board_hash).toBe('0102ff');
116
- expect(features.ble_name).toBe('Pro2 BLE');
117
- expect(features.onekey_ble_version).toBe('4.5.6');
118
- expect(features.onekey_ble_hash).toBe('0c0d');
119
- expect(features.onekey_se01_version).toBe('7.8.9');
120
- expect(features.onekey_se01_hash).toBe('0e0f');
121
- expect(features.onekey_se01_state).toBe('APP');
122
- expect(features.onekey_se02_state).toBe('BOOT');
123
- expect(features.label).toBe('My Pro2');
124
- expect(features.language).toBe('en-US');
125
- expect(features.initialized).toBe(false);
126
- expect(features.needs_backup).toBe(true);
127
- expect(features.passphrase_protection).toBe(true);
128
- expect(features.ble_enable).toBe(true);
129
- });
130
-
131
- test('uses GetPassphraseState payloads compatible with Pro1 passphrase flow', async () => {
132
- const features = normalizeProtocolV2Features(descriptor as any);
133
- const typedCall = jest.fn().mockResolvedValue({
134
- type: 'PassphraseState',
135
- message: {
136
- passphrase_state: 'state-1',
137
- session_id: 'session-1',
138
- unlocked_attach_pin: false,
139
- },
140
- });
141
- const commands = { typedCall } as unknown as DeviceCommands;
142
-
143
- await getPassphraseState(features, commands, {
144
- expectPassphraseState: 'state-1',
145
- });
146
- expect(typedCall).toHaveBeenLastCalledWith('GetPassphraseState', 'PassphraseState', {
147
- passphrase_state: 'state-1',
148
- });
149
-
150
- await getPassphraseState(features, commands, {
151
- expectPassphraseState: 'state-2',
152
- allowCreateAttachPin: true,
153
- });
154
- expect(typedCall).toHaveBeenLastCalledWith('GetPassphraseState', 'PassphraseState', {
155
- passphrase_state: 'state-2',
156
- allow_create_attach_pin: true,
157
- });
158
-
159
- await getPassphraseState(features, commands, {
160
- onlyMainPin: true,
161
- });
162
- expect(typedCall).toHaveBeenLastCalledWith('GetPassphraseState', 'PassphraseState', {
163
- _only_main_pin: true,
164
- });
165
- });
166
-
167
- test('stores Pro2 passphrase sessions without selecting them implicitly', async () => {
168
- const device = Device.fromDescriptor({ ...descriptor, protocolType: 'V2' } as any);
169
- const typedCall = jest.fn().mockResolvedValue({
170
- type: 'PassphraseState',
171
- message: {
172
- passphrase_state: 'state-auto',
173
- session_id: 'session-auto',
174
- unlocked_attach_pin: false,
175
- },
176
- });
177
-
178
- (device as any).features = normalizeProtocolV2Features({
179
- ...descriptor,
180
- protocolType: 'V2',
181
- } as any);
182
- (device as any).commands = { typedCall };
183
-
184
- await expect(getPassphraseStateWithRefreshDeviceInfo(device)).resolves.toMatchObject({
185
- passphraseState: 'state-auto',
186
- newSession: 'session-auto',
187
- });
188
-
189
- expect(device.passphraseState).toBeUndefined();
190
- expect(device.features?.passphrase_protection).toBe(true);
191
- expect(device.features?.session_id).toBe('session-auto');
192
- expect(device.getInternalState()).toBeUndefined();
193
- device.passphraseState = 'state-auto';
194
- expect(device.getInternalState()).toBe('session-auto');
195
- expect(typedCall).toHaveBeenLastCalledWith('GetPassphraseState', 'PassphraseState', {
196
- passphrase_state: undefined,
197
- });
198
- });
199
-
200
- test('does not mark Pro2 passphrase enabled from a main PIN session alone', async () => {
201
- const device = Device.fromDescriptor({ ...descriptor, protocolType: 'V2' } as any);
202
- const typedCall = jest.fn().mockResolvedValue({
203
- type: 'PassphraseState',
204
- message: {
205
- session_id: 'main-pin-session',
206
- unlocked_attach_pin: false,
207
- },
208
- });
209
-
210
- (device as any).features = normalizeProtocolV2Features(
211
- {
212
- ...descriptor,
213
- protocolType: 'V2',
214
- } as any,
215
- {
216
- status: {
217
- passphrase_protection: false,
218
- },
219
- }
220
- );
221
- (device as any).commands = { typedCall };
222
-
223
- await expect(
224
- getPassphraseStateWithRefreshDeviceInfo(device, { onlyMainPin: true })
225
- ).resolves.toMatchObject({
226
- passphraseState: undefined,
227
- newSession: 'main-pin-session',
228
- });
229
-
230
- expect(device.features?.passphrase_protection).toBe(false);
231
- expect(device.features?.session_id).toBe('main-pin-session');
232
- expect(device.getInternalState()).toBeUndefined();
233
- expect(typedCall).toHaveBeenLastCalledWith('GetPassphraseState', 'PassphraseState', {
234
- _only_main_pin: true,
235
- });
236
- });
237
-
238
- test('marks fallback features as unavailable when DeviceInfo is missing', () => {
239
- const features = normalizeProtocolV2Features(descriptor as any);
240
-
241
- expect(features.device_id).toBe('usb-path');
242
- expect(features.serial_no).toBe('usb-path');
243
- expect(features.onekey_serial_no).toBe('usb-path');
244
- expect(features.initialized).toBe(false);
245
- expect(features.unlocked).toBe(false);
246
- expect(features.firmware_present).toBe(false);
247
- });
248
-
249
- test('initializes Protocol V2 features from DeviceGetDeviceInfo after Ping', async () => {
250
- const commands = {
251
- typedCall: jest
252
- .fn()
253
- .mockResolvedValueOnce({ type: 'Success', message: { message: 'pong' } })
254
- .mockResolvedValueOnce({
255
- type: 'DeviceInfo',
256
- message: {
257
- hw: { serial_no: 'PR2SERIAL' },
258
- status: {
259
- init_states: true,
260
- passphrase_protection: true,
261
- },
262
- },
263
- }),
264
- };
265
-
266
- const features = await getProtocolV2Features({
267
- commands: commands as unknown as DeviceCommands,
268
- descriptor: descriptor as any,
269
- });
270
-
271
- expect(features.device_id).toBe('PR2SERIAL');
272
- expect(features.initialized).toBe(true);
273
- expect(features.passphrase_protection).toBe(true);
274
- expect(commands.typedCall).toHaveBeenNthCalledWith(1, 'Ping', 'Success', { message: 'init' });
275
- expect(commands.typedCall).toHaveBeenNthCalledWith(2, 'DeviceGetDeviceInfo', 'DeviceInfo', {
276
- targets: expect.objectContaining({ status: true }),
277
- types: expect.objectContaining({ specific: true }),
278
- });
279
- });
280
-
281
- test('fails initialization when Protocol V2 DeviceGetDeviceInfo fails', async () => {
282
- const commands = {
283
- typedCall: jest
284
- .fn()
285
- .mockResolvedValueOnce({ type: 'Success', message: { message: 'pong' } })
286
- .mockRejectedValueOnce(new Error('DeviceInfo not supported')),
287
- };
288
-
289
- await expect(
290
- getProtocolV2Features({
291
- commands: commands as unknown as DeviceCommands,
292
- descriptor: descriptor as any,
293
- })
294
- ).rejects.toThrow('DeviceInfo not supported');
295
- });
296
-
297
- test('does not inherit Pro or Pro model fallback ranges for Protocol V2 devices', () => {
298
- const features = normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any);
299
- const checkedTypes: string[] = [];
300
-
301
- const versionRange = getMethodVersionRange(features, type => {
302
- checkedTypes.push(type);
303
- if (type === 'pro' || type === 'model_touch') {
304
- return { min: '4.10.0' };
305
- }
306
- return undefined;
307
- });
308
-
309
- expect(versionRange).toBeUndefined();
310
- expect(checkedTypes).toEqual(['pro2']);
311
- });
312
-
313
- test('marks known unsupported public-chain methods as unsupported on Protocol V2', () => {
314
- const features = normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any, {
315
- fw: {
316
- app: {
317
- version: '9.9.9',
318
- },
319
- },
320
- });
321
- const stellar = new StellarGetAddress({
322
- id: 1,
323
- payload: {
324
- method: 'stellarGetAddress',
325
- path: "m/44'/148'/0'",
326
- },
327
- });
328
- const benfen = new BenfenSignMessage({
329
- id: 1,
330
- payload: {
331
- method: 'benfenSignMessage',
332
- path: "m/44'/728'/0'/0'/0'",
333
- messageHex: '0x1234',
334
- },
335
- });
336
-
337
- stellar.init();
338
- benfen.init();
339
-
340
- const stellarRange = getMethodVersionRange(
341
- features,
342
- type => stellar.getVersionRange()[type]
343
- );
344
- const benfenRange = getMethodVersionRange(features, type => benfen.getVersionRange()[type]);
345
- const neuraiRange = getMethodVersionRange(
346
- features,
347
- type => getBitcoinForkVersionRange(['Neurai'])[type]
348
- );
349
-
350
- expect(isMethodVersionRangeUnsupported(stellarRange)).toBe(true);
351
- expect(isMethodVersionRangeUnsupported(benfenRange)).toBe(true);
352
- expect(isMethodVersionRangeUnsupported(neuraiRange)).toBe(true);
353
- });
354
-
355
- test('does not block legacy batch public key support checks on Protocol V2', async () => {
356
- const paths = [{ address_n: [0x8000002c, 0x80000000, 0x80000000] }] as any;
357
- const typedCall = jest.fn().mockResolvedValue({
358
- type: 'EcdsaPublicKeys',
359
- message: {
360
- root_fingerprint: 123,
361
- public_keys: [],
362
- hd_nodes: [{}],
363
- },
364
- });
365
- const device = {
366
- originalDescriptor: { protocolType: 'V2' },
367
- features: normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any, {
368
- fw: {
369
- app: {
370
- version: '4.14.0',
371
- },
372
- },
373
- }),
374
- commands: { typedCall },
375
- };
376
-
377
- await expect(
378
- batchGetPublickeys(device as any, paths, 'secp256k1', 0, { includeNode: true })
379
- ).resolves.toMatchObject({
380
- root_fingerprint: 123,
381
- hd_nodes: [{}],
382
- });
383
- expect(typedCall).toHaveBeenCalledWith('BatchGetPublickeys', 'EcdsaPublicKeys', {
384
- paths,
385
- ecdsa_curve_name: 'secp256k1',
386
- include_node: true,
387
- });
388
- });
389
-
390
- test('returns Protocol V2 oneKey fields without calling legacy OnekeyGetFeatures', async () => {
391
- const method = new GetOnekeyFeatures({
392
- id: 1,
393
- payload: {
394
- method: 'getOnekeyFeatures',
395
- },
396
- });
397
- const typedCall = jest.fn();
398
-
399
- (method as any).device = {
400
- originalDescriptor: { protocolType: 'V2' },
401
- commands: { typedCall },
402
- features: {
403
- label: 'ignored label',
404
- onekey_device_type: 'pro2',
405
- onekey_firmware_version: '1.2.3',
406
- onekey_firmware_build_id: 'app-build',
407
- onekey_serial_no: 'PR2SERIAL',
408
- onekey_ble_name: 'Pro2 BLE',
409
- },
410
- };
411
-
412
- const message = await method.run();
413
-
414
- expect(typedCall).not.toHaveBeenCalled();
415
- expect(message).toMatchObject({
416
- onekey_device_type: 'pro2',
417
- onekey_firmware_version: '1.2.3',
418
- onekey_firmware_build_id: 'app-build',
419
- onekey_serial_no: 'PR2SERIAL',
420
- onekey_ble_name: 'Pro2 BLE',
421
- });
422
- expect(message).not.toHaveProperty('label');
423
- });
424
-
425
- test('reuses cached Protocol V2 features after the first initialization', async () => {
426
- const device = Device.fromDescriptor({
427
- path: 'usb-path',
428
- protocolType: 'V2',
429
- } as any);
430
- const typedCall = jest
431
- .fn()
432
- .mockResolvedValueOnce({ type: 'Success', message: { message: 'init' } })
433
- .mockResolvedValueOnce({
434
- type: 'DeviceInfo',
435
- message: {
436
- hw: { serial_no: 'PR2SERIAL' },
437
- status: {
438
- passphrase_protection: true,
439
- },
440
- },
441
- });
442
-
443
- (device as any).commands = { typedCall };
444
-
445
- await device.initialize();
446
- await device.initialize();
447
-
448
- expect(device.features?.device_id).toBe('PR2SERIAL');
449
- expect(device.features?.passphrase_protection).toBe(true);
450
- expect(typedCall).toHaveBeenCalledTimes(2);
451
- expect(typedCall).toHaveBeenNthCalledWith(
452
- 1,
453
- 'Ping',
454
- 'Success',
455
- { message: 'init' },
456
- {
457
- timeoutMs: 10000,
458
- }
459
- );
460
- expect(typedCall).toHaveBeenNthCalledWith(
461
- 2,
462
- 'DeviceGetDeviceInfo',
463
- 'DeviceInfo',
464
- {
465
- targets: expect.objectContaining({ status: true }),
466
- types: expect.objectContaining({ specific: true }),
467
- },
468
- {
469
- timeoutMs: 10000,
470
- }
471
- );
472
- });
473
- });
474
-
475
- describe('API compatibility handling', () => {
476
- test('returns a typed unsupported error for deprecated EIP712 message signing on Protocol V2', async () => {
477
- const method = new EVMSignMessageEIP712({
478
- id: 1,
479
- payload: {
480
- method: 'evmSignMessageEIP712',
481
- path: "m/44'/60'/0'/0/0",
482
- domainHash: '0x'.concat('11'.repeat(32)),
483
- messageHash: '0x'.concat('22'.repeat(32)),
484
- },
485
- });
486
-
487
- method.init();
488
- (method as any).device = {
489
- features: {
490
- onekey_device_type: 'pro2',
491
- },
492
- originalDescriptor: {
493
- protocolType: 'V2',
494
- },
495
- };
496
-
497
- await expect(method.run()).rejects.toEqual(
498
- expect.objectContaining({
499
- errorCode: HardwareErrorCode.DeviceNotSupportMethod,
500
- })
501
- );
502
- });
503
-
504
- test('returns a typed unsupported error for Tron sign message V1 before device binding', () => {
505
- const method = new TronSignMessage({
506
- id: 1,
507
- payload: {
508
- method: 'tronSignMessage',
509
- path: "m/44'/195'/0'/0/0",
510
- messageHex: '0x1234',
511
- messageType: 'V1',
512
- },
513
- });
514
-
515
- expect(() => method.init()).toThrow(
516
- expect.objectContaining({
517
- errorCode: HardwareErrorCode.DeviceNotSupportMethod,
518
- })
519
- );
520
- });
521
-
522
- test('uses chunk transfer for large Sui transactions on Protocol V2', async () => {
523
- const rawTx = '0x'.concat('ab'.repeat(5000));
524
- const typedCall = jest.fn(async () => ({
525
- type: 'SuiSignedTx',
526
- message: {
527
- public_key: '',
528
- signature: '',
529
- },
530
- }));
531
- const method = new SuiSignTransaction({
532
- id: 1,
533
- payload: {
534
- method: 'suiSignTransaction',
535
- path: "m/44'/784'/0'/0'/0'",
536
- rawTx,
537
- },
538
- });
539
-
540
- method.init();
541
- (method as any).device = {
542
- features: {
543
- onekey_device_type: 'pro2',
544
- },
545
- originalDescriptor: {
546
- protocolType: 'V2',
547
- },
548
- getCommands: () => ({
549
- typedCall,
550
- }),
551
- };
552
-
553
- await method.run();
554
-
555
- expect(typedCall).toHaveBeenCalledTimes(1);
556
- const [, , params] = typedCall.mock.calls[0];
557
- expect(params).toEqual(
558
- expect.objectContaining({
559
- raw_tx: '',
560
- data_length: 5000,
561
- })
562
- );
563
- expect(params.data_initial_chunk).toHaveLength(2048);
564
- });
565
-
566
- test('accepts string XRP payment amount values', () => {
567
- const method = new XrpSignTransaction({
568
- id: 1,
569
- payload: {
570
- method: 'xrpSignTransaction',
571
- path: "m/44'/144'/0'/0/0",
572
- transaction: {
573
- fee: '100000',
574
- flags: 2147483648,
575
- sequence: 25,
576
- maxLedgerVersion: 8820051,
577
- payment: {
578
- amount: '100000000',
579
- destination: 'rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws',
580
- },
581
- },
582
- },
583
- });
584
-
585
- expect(() => method.init()).not.toThrow();
586
- expect(method.params.payment?.amount).toBe('100000000');
587
- });
588
-
589
- test('accepts Conflux base32 recipient addresses without hex formatting them', () => {
590
- const to = 'cfx:aak2rra2njvd77ezwjvx04kkds9fzagfe6ku8scz91';
591
- const method = new ConfluxSignTransaction({
592
- id: 1,
593
- payload: {
594
- method: 'confluxSignTransaction',
595
- path: "m/44'/503'/0'/0/0",
596
- transaction: {
597
- to,
598
- value: '0x0',
599
- data: '0x',
600
- chainId: 1,
601
- nonce: '0x00',
602
- epochHeight: '0x00',
603
- gasLimit: '0x5208',
604
- storageLimit: '0x5208',
605
- gasPrice: '0xbebc200',
606
- },
607
- },
608
- });
609
-
610
- expect(() => method.init()).not.toThrow();
611
- expect(method.formattedTx?.to).toBe(to);
612
- });
613
-
614
- test('returns a typed unsupported error for Dynex signing on Protocol V2', async () => {
615
- const method = new DnxSignTransaction({
616
- id: 1,
617
- payload: {
618
- method: 'dnxSignTransaction',
619
- path: "m/44'/29538'/0'/0/0",
620
- inputs: [
621
- {
622
- prevIndex: 1,
623
- globalIndex: 1,
624
- txPubkey: '00',
625
- prevOutPubkey: '00',
626
- amount: '1',
627
- },
628
- ],
629
- toAddress: 'dnx-address',
630
- amount: '1',
631
- fee: '1',
632
- },
633
- });
634
-
635
- method.init();
636
- (method as any).device = {
637
- originalDescriptor: { protocolType: 'V2' },
638
- features: normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any),
639
- };
640
-
641
- await expect(method.run()).rejects.toMatchObject({
642
- errorCode: HardwareErrorCode.DeviceNotSupportMethod,
643
- });
644
- });
645
-
646
- test('returns a typed unsupported error for Dynex address on Protocol V2', async () => {
647
- const method = new DnxGetAddress({
648
- id: 1,
649
- payload: {
650
- method: 'dnxGetAddress',
651
- path: "m/44'/29538'/0'/0/0",
652
- showOnOneKey: false,
653
- },
654
- });
655
-
656
- method.init();
657
- (method as any).device = {
658
- originalDescriptor: { protocolType: 'V2' },
659
- features: normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any),
660
- };
661
-
662
- await expect(method.run()).rejects.toMatchObject({
663
- errorCode: HardwareErrorCode.DeviceNotSupportMethod,
664
- });
665
- });
666
- });
667
-
668
- describe('Protocol V2 firmware update targets', () => {
669
- test('keeps Protocol V2 firmware updates off the legacy firmwareUpdateV3 path', async () => {
670
- const method = new FirmwareUpdateV3({
671
- id: 1,
672
- payload: {
673
- method: 'firmwareUpdateV3',
674
- },
675
- });
676
- (method as any).device = {
677
- originalDescriptor: { protocolType: 'V2' },
678
- };
679
-
680
- await expect(method.run()).rejects.toThrow('firmwareUpdateV4');
681
- });
682
-
683
- test('uses Protocol V2 features after BLE final reconnect without legacy Initialize', async () => {
684
- const method = new FirmwareUpdateV4({
685
- id: 1,
686
- payload: {
687
- method: 'firmwareUpdateV4',
688
- },
689
- });
690
- const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-session' });
691
- const typedCall = jest.fn().mockImplementation((name: string) => {
692
- if (name === 'Ping') {
693
- return Promise.resolve({ type: 'Success', message: { message: 'init' } });
694
- }
695
- if (name === 'DeviceGetDeviceInfo') {
696
- return Promise.resolve({ type: 'DeviceInfo', message: {} });
697
- }
698
- return Promise.reject(new Error(`unexpected call ${name}`));
699
- });
700
- const commands = { typedCall };
701
-
702
- (method as any).isBleReconnect = jest.fn(() => true);
703
- (method as any).device = {
704
- originalDescriptor: { id: 'ble-id', path: 'ble-path', protocolType: 'V2' },
705
- deviceConnector: { acquire },
706
- getCommands: () => commands,
707
- _updateFeatures: jest.fn(),
708
- };
709
-
710
- const versions = await (method as any).waitForProtocolV2FinalFeatures();
711
-
712
- expect(acquire).toHaveBeenCalledWith('ble-id', null, true, 'V2');
713
- expect(typedCall).toHaveBeenNthCalledWith(
714
- 1,
715
- 'Ping',
716
- 'Success',
717
- { message: 'init' },
718
- { timeoutMs: 5000 }
719
- );
720
- expect(typedCall).toHaveBeenNthCalledWith(
721
- 2,
722
- 'DeviceGetDeviceInfo',
723
- 'DeviceInfo',
724
- {
725
- targets: expect.objectContaining({ status: true }),
726
- types: expect.objectContaining({ specific: true }),
727
- },
728
- { timeoutMs: 5000 }
729
- );
730
- expect(typedCall).toHaveBeenCalledTimes(2);
731
- expect(typedCall).not.toHaveBeenCalledWith('Initialize', 'Features', {});
732
- expect(versions).toEqual({
733
- bootloaderVersion: '0.0.0',
734
- bleVersion: '0.0.0',
735
- firmwareVersion: '0.0.0',
736
- });
737
- });
738
-
739
- test('runs Protocol V2 upload and install without rebooting to bootloader first', async () => {
740
- const method = new FirmwareUpdateV4({
741
- id: 1,
742
- payload: {
743
- method: 'firmwareUpdateV4',
744
- },
745
- });
746
- method.init();
747
-
748
- (method as any).device = {
749
- originalDescriptor: { id: 'ble-id', path: 'ble-path', protocolType: 'V2' },
750
- features: { capabilities: [] },
751
- };
752
- (method as any).prepareResourceBinary = jest.fn().mockResolvedValue(null);
753
- (method as any).prepareFirmwareAndBleBinary = jest.fn().mockResolvedValue([
754
- {
755
- fileName: 'ble-firmware.bin',
756
- binary: new Uint8Array([1, 2, 3]).buffer,
757
- },
758
- ]);
759
- (method as any).prepareBootloaderBinary = jest.fn().mockResolvedValue(null);
760
- (method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
761
- (method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
762
- (method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({
763
- bootloaderVersion: '0.2.0',
764
- bleVersion: '4.5.6',
765
- firmwareVersion: '1.2.3',
766
- });
767
- (method as any).protocolV2Reboot = jest.fn();
768
- method.postTipMessage = jest.fn();
769
-
770
- await method.run();
771
-
772
- expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
773
- resourceBinary: null,
774
- fwBinaryMap: [
775
- {
776
- fileName: 'ble-firmware.bin',
777
- binary: expect.any(ArrayBuffer),
778
- },
779
- ],
780
- bootloaderBinary: null,
781
- });
782
- expect((method as any).protocolV2Reboot).not.toHaveBeenCalledWith(DeviceRebootType.Bootloader);
783
- expect(method.postTipMessage).not.toHaveBeenCalledWith('AutoRebootToBootloader');
784
- });
785
-
786
- test('reboots Protocol V2 firmware flow back to normal before final feature polling', async () => {
787
- const method = new FirmwareUpdateV4({
788
- id: 1,
789
- payload: {
790
- method: 'firmwareUpdateV4',
791
- },
792
- });
793
- method.postTipMessage = jest.fn();
794
- (method as any).protocolV2Reboot = jest.fn().mockResolvedValue({
795
- message: 'Device rebooted successfully',
796
- });
797
-
798
- await (method as any).exitProtocolV2BootloaderToNormal();
799
-
800
- expect(method.postTipMessage).toHaveBeenCalledWith('SwitchFirmwareReconnectDevice');
801
- expect((method as any).protocolV2Reboot).toHaveBeenCalledWith(DeviceRebootType.Normal);
802
- });
803
-
804
- test('treats iOS BLE RxError 6 during Protocol V2 reboot as expected disconnect', async () => {
805
- const method = new FirmwareUpdateV4({
806
- id: 1,
807
- payload: {
808
- method: 'firmwareUpdateV4',
809
- },
810
- });
811
- const typedCall = jest
812
- .fn()
813
- .mockRejectedValue(
814
- new Error("The operation couldn't be completed. (MultiplatformBleAdapter.RxError error 6.)")
815
- );
816
-
817
- (method as any).device = {
818
- getCommands: () => ({ typedCall }),
819
- };
820
-
821
- await expect((method as any).protocolV2Reboot(DeviceRebootType.Normal)).resolves.toEqual({
822
- message: 'Device rebooted successfully',
823
- });
824
- });
825
-
826
- test('treats direct disconnect during Protocol V2 normal reboot as expected', async () => {
827
- const method = new FirmwareUpdateV4({
828
- id: 1,
829
- payload: {
830
- method: 'firmwareUpdateV4',
831
- },
832
- });
833
- const typedCall = jest
834
- .fn()
835
- .mockRejectedValue(new Error('Connection error has occured: Device disconnected'));
836
-
837
- (method as any).device = {
838
- getCommands: () => ({ typedCall }),
839
- };
840
-
841
- await expect((method as any).protocolV2Reboot(DeviceRebootType.Normal)).resolves.toEqual({
842
- message: 'Device rebooted successfully',
843
- });
844
- });
845
-
846
- test('continues Protocol V2 install polling through temporary expected V2 probe failures', async () => {
847
- const method = new FirmwareUpdateV4({
848
- id: 1,
849
- payload: {
850
- method: 'firmwareUpdateV4',
851
- },
852
- });
853
- const typedCall = jest
854
- .fn()
855
- .mockRejectedValueOnce(
856
- new Error(
857
- 'Device protocol mismatch: expected V2, but device did not respond to expected protocol'
858
- )
859
- )
860
- .mockResolvedValueOnce({
861
- type: 'DeviceFirmwareUpdateStatus',
862
- message: {
863
- targets: [{ target_id: 2, status: 0 }],
864
- },
865
- });
866
- const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
867
-
868
- (method as any).device = {
869
- getCommands: () => ({ typedCall }),
870
- };
871
- (method as any).reconnectProtocolV2Device = reconnectProtocolV2Device;
872
- method.postProgressMessage = jest.fn();
873
-
874
- await (method as any).waitForProtocolV2FirmwareUpdateComplete([
875
- { target_id: 2, path: 'vol1:ble-firmware.bin' },
876
- ]);
877
-
878
- expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
879
- expect(typedCall).toHaveBeenCalledTimes(2);
880
- });
881
-
882
- test('passes resource, bootloader, BLE, SE and app files to DeviceFirmwareUpdate targets', async () => {
883
- const resourceZip = new JSZip();
884
- resourceZip.file('icons/home.png', new Uint8Array([1, 2, 3]));
885
- const resourceBinary = await resourceZip.generateAsync({ type: 'arraybuffer' });
886
- const method = new FirmwareUpdateV4({
887
- id: 1,
888
- payload: {
889
- method: 'firmwareUpdateV4',
890
- },
891
- });
892
-
893
- const writtenPaths: string[] = [];
894
- method.postTipMessage = jest.fn();
895
- (method as any).protocolV2CreateFolder = jest.fn().mockResolvedValue(undefined);
896
- (method as any).protocolV2CommonUpdateProcess = jest.fn().mockImplementation(params => {
897
- writtenPaths.push(params.filePath);
898
- return Number(params.processedSize ?? 0) + Number(params.payload.byteLength);
899
- });
900
- (method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
901
- (method as any).waitForProtocolV2FirmwareUpdateComplete = jest
902
- .fn()
903
- .mockResolvedValue(undefined);
904
-
905
- await (method as any).executeProtocolV2Update({
906
- resourceBinary,
907
- bootloaderBinary: new Uint8Array([4, 5]).buffer,
908
- fwBinaryMap: [
909
- {
910
- fileName: 'ble-firmware.bin',
911
- binary: new Uint8Array([6]).buffer,
912
- },
913
- {
914
- fileName: 'se1-firmware.bin',
915
- binary: new Uint8Array([7]).buffer,
916
- },
917
- {
918
- fileName: 'firmware.bin',
919
- binary: new Uint8Array([8]).buffer,
920
- },
921
- ],
922
- });
923
-
924
- expect((method as any).protocolV2CreateFolder).toHaveBeenCalledWith('vol1:res/');
925
- expect(writtenPaths).toEqual([
926
- 'vol1:res/home.png',
927
- 'vol1:bootloader.bin',
928
- 'vol1:ble-firmware.bin',
929
- 'vol1:se1-firmware.bin',
930
- 'vol1:firmware.bin',
931
- ]);
932
- expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledWith({
933
- targets: [
934
- { target_id: 10, path: 'vol1:res/' },
935
- { target_id: 2, path: 'vol1:bootloader.bin' },
936
- { target_id: 5, path: 'vol1:ble-firmware.bin' },
937
- { target_id: 6, path: 'vol1:se1-firmware.bin' },
938
- { target_id: 3, path: 'vol1:firmware.bin' },
939
- ],
940
- });
941
- expect((method as any).waitForProtocolV2FirmwareUpdateComplete).toHaveBeenCalled();
942
- });
943
-
944
- test('uses absolute processed_byte offsets and disables append for firmware file writes', async () => {
945
- const method = new FirmwareUpdateV4({
946
- id: 1,
947
- payload: {
948
- method: 'firmwareUpdateV4',
949
- },
950
- });
951
- const typedCall = jest.fn(
952
- (
953
- _name: string,
954
- _resType: string,
955
- params: { file: { offset: number; data: { byteLength: number } } }
956
- ) =>
957
- Promise.resolve({
958
- type: 'FilesystemFile',
959
- message: {
960
- processed_byte: params.file.offset + params.file.data.byteLength,
961
- },
962
- })
963
- );
964
-
965
- (method as any).device = {
966
- getCommands: () => ({ typedCall }),
967
- };
968
- method.postProgressMessage = jest.fn();
969
-
970
- await (method as any).protocolV2CommonUpdateProcess({
971
- payload: new Uint8Array(4097).buffer,
972
- filePath: 'vol1:firmware.bin',
973
- processedSize: 0,
974
- totalSize: 4097,
975
- transferStartTime: Date.now() - 1000,
976
- });
977
-
978
- const writePayloads = typedCall.mock.calls.map(call => call[2]);
979
- expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 4096]);
980
- expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([4096, 1]);
981
- expect(writePayloads.map(payload => payload.overwrite)).toEqual([true, false]);
982
- expect(writePayloads.every(payload => payload.append === false)).toBe(true);
983
- expect(method.postProgressMessage).toHaveBeenLastCalledWith(
984
- 99,
985
- 'transferData',
986
- expect.objectContaining({
987
- transferredBytes: 4097,
988
- totalBytes: 4097,
989
- rateBytesPerSecond: expect.any(Number),
990
- elapsedMs: expect.any(Number),
991
- })
992
- );
993
- });
994
-
995
- test('caps native BLE firmware upload chunks below the WebUSB limit', async () => {
996
- const method = new FirmwareUpdateV4({
997
- id: 1,
998
- payload: {
999
- method: 'firmwareUpdateV4',
1000
- },
1001
- });
1002
- const typedCall = jest.fn(
1003
- (
1004
- _name: string,
1005
- _resType: string,
1006
- params: { file: { offset: number; data: { byteLength: number } } }
1007
- ) =>
1008
- Promise.resolve({
1009
- type: 'FilesystemFile',
1010
- message: {
1011
- processed_byte: params.file.offset + params.file.data.byteLength,
1012
- },
1013
- })
1014
- );
1015
-
1016
- (method as any).params = {
1017
- platform: 'native',
1018
- chunkSize: 4096,
1019
- };
1020
- (method as any).device = {
1021
- getCommands: () => ({ typedCall }),
1022
- };
1023
- method.postProgressMessage = jest.fn();
1024
-
1025
- await (method as any).protocolV2CommonUpdateProcess({
1026
- payload: new Uint8Array(1801).buffer,
1027
- filePath: 'vol1:ble-firmware.bin',
1028
- processedSize: 0,
1029
- totalSize: 1801,
1030
- });
1031
-
1032
- const writePayloads = typedCall.mock.calls.map(call => call[2]);
1033
- expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1800]);
1034
- expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1800, 1]);
1035
- });
1036
-
1037
- test('consumes Protocol V2 install progress before final update success', async () => {
1038
- const method = new FirmwareUpdateV4({
1039
- id: 1,
1040
- payload: {
1041
- method: 'firmwareUpdateV4',
1042
- },
1043
- });
1044
- const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: { message: 'ok' } });
1045
-
1046
- (method as any).device = {
1047
- getCommands: () => ({ typedCall }),
1048
- };
1049
- method.postProgressMessage = jest.fn();
1050
- method.postTipMessage = jest.fn();
1051
-
1052
- await (method as any).protocolV2StartFirmwareUpdate({
1053
- targets: [{ target_id: 0, path: 'vol1:firmware.bin' }],
1054
- });
1055
-
1056
- const callOptions = typedCall.mock.calls[0][3];
1057
- expect(typedCall.mock.calls[0][1]).toEqual(['Success', 'DeviceFirmwareUpdateStatus']);
1058
- expect(callOptions.intermediateTypes).toEqual(['DeviceFirmwareInstallProgress']);
1059
- callOptions.onIntermediateResponse({
1060
- type: 'DeviceFirmwareInstallProgress',
1061
- message: { target_id: 0, progress: 42 },
1062
- });
1063
-
1064
- expect(method.postProgressMessage).toHaveBeenCalledWith(42, 'installingFirmware');
1065
- });
1066
-
1067
- test('accepts Protocol V2 firmware update status as start response', async () => {
1068
- const method = new FirmwareUpdateV4({
1069
- id: 1,
1070
- payload: {
1071
- method: 'firmwareUpdateV4',
1072
- },
1073
- });
1074
- const typedCall = jest.fn().mockResolvedValue({
1075
- type: 'DeviceFirmwareUpdateStatus',
1076
- message: { targets: [{ target_id: 0, status: 1 }] },
1077
- });
1078
-
1079
- (method as any).device = {
1080
- getCommands: () => ({ typedCall }),
1081
- };
1082
- method.postProgressMessage = jest.fn();
1083
- method.postTipMessage = jest.fn();
1084
-
1085
- await (method as any).protocolV2StartFirmwareUpdate({
1086
- targets: [{ target_id: 0, path: 'vol1:firmware.bin' }],
1087
- });
1088
-
1089
- expect(typedCall.mock.calls[0][1]).toEqual(['Success', 'DeviceFirmwareUpdateStatus']);
1090
- expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
1091
- });
1092
- });
1093
-
1094
- describe('Protocol V2 firmware update method', () => {
1095
- test('returns DeviceFirmwareUpdateStatus from low-level update trigger', async () => {
1096
- const method = new DeviceFirmwareUpdate({
1097
- id: 1,
1098
- payload: {
1099
- method: 'deviceFirmwareUpdate',
1100
- targetId: 3,
1101
- path: 'vol0:firmware.bin',
1102
- },
1103
- });
1104
- method.init();
1105
-
1106
- const typedCall = jest.fn().mockResolvedValue({
1107
- type: 'DeviceFirmwareUpdateStatus',
1108
- message: { targets: [{ target_id: 0, status: 1 }] },
1109
- });
1110
-
1111
- (method as any).device = {
1112
- commands: { typedCall },
1113
- };
1114
-
1115
- await expect(method.run()).resolves.toEqual({
1116
- targets: [{ target_id: 0, status: 1 }],
1117
- });
1118
- expect(typedCall.mock.calls[0][1]).toEqual(['Success', 'DeviceFirmwareUpdateStatus']);
1119
- expect(typedCall.mock.calls[0][2]).toEqual({
1120
- targets: [{ target_id: 3, path: 'vol0:firmware.bin' }],
1121
- });
1122
- });
1123
-
1124
- test('rejects missing or invalid firmware targets before transport call', async () => {
1125
- const typedCall = jest.fn();
1126
- const method = new DeviceFirmwareUpdate({
1127
- id: 1,
1128
- payload: {
1129
- method: 'deviceFirmwareUpdate',
1130
- path: 'vol0:firmware.bin',
1131
- },
1132
- });
1133
- method.init();
1134
- (method as any).device = {
1135
- commands: { typedCall },
1136
- };
1137
-
1138
- await expect(method.run()).rejects.toMatchObject({
1139
- errorCode: HardwareErrorCode.CallMethodInvalidParameter,
1140
- });
1141
- expect(typedCall).not.toHaveBeenCalled();
1142
- });
1143
-
1144
- test('accepts targetId alias inside firmware targets', async () => {
1145
- const typedCall = jest.fn().mockResolvedValue({ message: {} });
1146
- const method = new DeviceFirmwareUpdate({
1147
- id: 1,
1148
- payload: {
1149
- method: 'deviceFirmwareUpdate',
1150
- targets: [
1151
- {
1152
- target_id: undefined,
1153
- targetId: 3,
1154
- path: 'vol0:firmware.bin',
1155
- },
1156
- ],
1157
- } as any,
1158
- });
1159
- method.init();
1160
- (method as any).device = {
1161
- commands: { typedCall },
1162
- };
1163
-
1164
- await method.run();
1165
- expect(typedCall.mock.calls[0][2]).toEqual({
1166
- targets: [{ target_id: 3, path: 'vol0:firmware.bin' }],
1167
- });
1168
- });
1169
- });
1170
-
1171
- describe('Protocol V2 onboarding status method', () => {
1172
- test('returns DeviceOnboardingStatus from low-level status query', async () => {
1173
- const method = new DeviceGetOnboardingStatus({
1174
- id: 1,
1175
- payload: {
1176
- method: 'deviceGetOnboardingStatus',
1177
- },
1178
- });
1179
- method.init();
1180
-
1181
- const typedCall = jest.fn().mockResolvedValue({
1182
- type: 'DeviceOnboardingStatus',
1183
- message: {
1184
- page_index: 2,
1185
- page_count: 5,
1186
- page_name: 'backup',
1187
- },
1188
- });
1189
-
1190
- (method as any).device = {
1191
- commands: { typedCall },
1192
- };
1193
-
1194
- await expect(method.run()).resolves.toEqual({
1195
- page_index: 2,
1196
- page_count: 5,
1197
- page_name: 'backup',
1198
- });
1199
- expect(typedCall).toHaveBeenCalledWith(
1200
- 'DeviceGetOnboardingStatus',
1201
- 'DeviceOnboardingStatus',
1202
- {}
1203
- );
1204
- });
1205
- });
1206
-
1207
- describe('Protocol V2 file write method', () => {
1208
- test('rejects invalid write parameters before transport call', () => {
1209
- expect(() => {
1210
- const method = new FileWrite({
1211
- id: 1,
1212
- payload: {
1213
- method: 'fileWrite',
1214
- path: 'vol1:test.bin',
1215
- offset: -1,
1216
- data: new Uint8Array([1]),
1217
- },
1218
- });
1219
- method.init();
1220
- }).toThrow(
1221
- expect.objectContaining({ errorCode: HardwareErrorCode.CallMethodInvalidParameter })
1222
- );
1223
-
1224
- expect(() => {
1225
- const method = new FileWrite({
1226
- id: 1,
1227
- payload: {
1228
- method: 'fileWrite',
1229
- path: 'vol1:test.bin',
1230
- } as any,
1231
- });
1232
- method.init();
1233
- }).toThrow(
1234
- expect.objectContaining({ errorCode: HardwareErrorCode.CallMethodInvalidParameter })
1235
- );
1236
- });
1237
-
1238
- test('uses demo-aligned overwrite and append defaults', async () => {
1239
- const typedCall = jest.fn().mockResolvedValue({ message: { processed_byte: 1 } });
1240
- const method = new FileWrite({
1241
- id: 1,
1242
- payload: {
1243
- method: 'fileWrite',
1244
- path: 'vol1:test.bin',
1245
- offset: 1,
1246
- totalSize: 2,
1247
- data: new Uint8Array([1]),
1248
- },
1249
- });
1250
- (method as any).device = { commands: { typedCall } };
1251
- method.postMessage = jest.fn();
1252
-
1253
- method.init();
1254
- await method.run();
1255
-
1256
- expect(typedCall).toHaveBeenCalledWith('FilesystemFileWrite', 'FilesystemFile', {
1257
- file: {
1258
- path: 'vol1:test.bin',
1259
- offset: 1,
1260
- total_size: 2,
1261
- data: new Uint8Array([1]),
1262
- },
1263
- overwrite: false,
1264
- append: false,
1265
- ui_percentage: 99,
1266
- });
1267
- expect(method.postMessage).toHaveBeenCalledWith({
1268
- event: 'UI_EVENT',
1269
- type: UI_REQUEST.DEVICE_PROGRESS,
1270
- payload: expect.objectContaining({
1271
- progress: 100,
1272
- transferredBytes: 1,
1273
- totalBytes: 1,
1274
- elapsedMs: expect.any(Number),
1275
- }),
1276
- });
1277
- });
1278
-
1279
- test('splits data larger than the Protocol V2 file payload limit', async () => {
1280
- const data = new Uint8Array(4097);
1281
- const typedCall = jest.fn().mockResolvedValue({ message: {} });
1282
- const method = new FileWrite({
1283
- id: 1,
1284
- payload: {
1285
- method: 'fileWrite',
1286
- path: 'vol1:test.bin',
1287
- offset: 0,
1288
- totalSize: 4097,
1289
- data,
1290
- },
1291
- });
1292
- (method as any).device = { commands: { typedCall } };
1293
- method.postMessage = jest.fn();
1294
-
1295
- method.init();
1296
- const result = await method.run();
1297
-
1298
- expect(typedCall).toHaveBeenCalledTimes(2);
1299
- expect(typedCall).toHaveBeenNthCalledWith(1, 'FilesystemFileWrite', 'FilesystemFile', {
1300
- file: {
1301
- path: 'vol1:test.bin',
1302
- offset: 0,
1303
- total_size: 4097,
1304
- data: data.slice(0, 4096),
1305
- },
1306
- overwrite: true,
1307
- append: false,
1308
- ui_percentage: 99,
1309
- });
1310
- expect(typedCall).toHaveBeenNthCalledWith(2, 'FilesystemFileWrite', 'FilesystemFile', {
1311
- file: {
1312
- path: 'vol1:test.bin',
1313
- offset: 4096,
1314
- total_size: 4097,
1315
- data: data.slice(4096),
1316
- },
1317
- overwrite: false,
1318
- append: false,
1319
- ui_percentage: 99,
1320
- });
1321
- expect(result).toMatchObject({
1322
- path: 'vol1:test.bin',
1323
- processed_byte: 4097,
1324
- chunks: 2,
1325
- });
1326
- expect(method.postMessage).toHaveBeenNthCalledWith(1, {
1327
- event: 'UI_EVENT',
1328
- type: UI_REQUEST.DEVICE_PROGRESS,
1329
- payload: expect.objectContaining({
1330
- progress: 99,
1331
- transferredBytes: 4096,
1332
- totalBytes: 4097,
1333
- elapsedMs: expect.any(Number),
1334
- }),
1335
- });
1336
- expect(method.postMessage).toHaveBeenNthCalledWith(2, {
1337
- event: 'UI_EVENT',
1338
- type: UI_REQUEST.DEVICE_PROGRESS,
1339
- payload: expect.objectContaining({
1340
- progress: 100,
1341
- transferredBytes: 4097,
1342
- totalBytes: 4097,
1343
- elapsedMs: expect.any(Number),
1344
- }),
1345
- });
1346
- });
1347
-
1348
- test('uses the BLE chunk limit by default in BLE environments', async () => {
1349
- const getSettingsSpy = jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native');
1350
- const data = new Uint8Array(1801);
1351
- const typedCall = jest.fn().mockResolvedValue({ message: {} });
1352
- const method = new FileWrite({
1353
- id: 1,
1354
- payload: {
1355
- method: 'fileWrite',
1356
- path: 'vol1:test.bin',
1357
- offset: 0,
1358
- totalSize: 1801,
1359
- data,
1360
- },
1361
- });
1362
- (method as any).device = { commands: { typedCall } };
1363
- method.postMessage = jest.fn();
1364
-
1365
- try {
1366
- method.init();
1367
- await method.run();
1368
- } finally {
1369
- getSettingsSpy.mockRestore();
1370
- }
1371
-
1372
- expect(typedCall).toHaveBeenCalledTimes(2);
1373
- expect(typedCall.mock.calls[0][2].file.data.byteLength).toBe(1800);
1374
- expect(typedCall.mock.calls[1][2].file.offset).toBe(1800);
1375
- expect(typedCall.mock.calls[1][2].file.data.byteLength).toBe(1);
1376
- });
1377
- });
1378
-
1379
- describe('Protocol V2 file read method', () => {
1380
- test('rejects invalid read and directory parameters before transport call', () => {
1381
- expect(() => {
1382
- const method = new FileRead({
1383
- id: 1,
1384
- payload: {
1385
- method: 'fileRead',
1386
- path: '',
1387
- offset: 0,
1388
- },
1389
- });
1390
- method.init();
1391
- }).toThrow(
1392
- expect.objectContaining({ errorCode: HardwareErrorCode.CallMethodInvalidParameter })
1393
- );
1394
-
1395
- expect(() => {
1396
- const method = new FileRead({
1397
- id: 1,
1398
- payload: {
1399
- method: 'fileRead',
1400
- path: 'vol1:test.bin',
1401
- totalSize: -1,
1402
- },
1403
- });
1404
- method.init();
1405
- }).toThrow(
1406
- expect.objectContaining({ errorCode: HardwareErrorCode.CallMethodInvalidParameter })
1407
- );
1408
-
1409
- expect(() => {
1410
- const method = new DirList({
1411
- id: 1,
1412
- payload: {
1413
- method: 'dirList',
1414
- path: 'vol1:',
1415
- depth: -1,
1416
- },
1417
- });
1418
- method.init();
1419
- }).toThrow(
1420
- expect.objectContaining({ errorCode: HardwareErrorCode.CallMethodInvalidParameter })
1421
- );
1422
- });
1423
-
1424
- test('reads full file in chunks when read length is 0', async () => {
1425
- const firstChunk = new Uint8Array(64).fill(1);
1426
- const typedCall = jest
1427
- .fn()
1428
- .mockResolvedValueOnce({ message: { exist: true, size: 65, directory: false } })
1429
- .mockResolvedValueOnce({ message: { data: firstChunk } })
1430
- .mockResolvedValueOnce({ message: { data: new Uint8Array([2]) } });
1431
- const method = new FileRead({
1432
- id: 1,
1433
- payload: {
1434
- method: 'fileRead',
1435
- path: 'vol1:test.bin',
1436
- offset: 0,
1437
- totalSize: 0,
1438
- chunkLen: 64,
1439
- },
1440
- });
1441
- (method as any).device = { commands: { typedCall } };
1442
-
1443
- method.init();
1444
- const result = await method.run();
1445
-
1446
- expect(typedCall).toHaveBeenNthCalledWith(1, 'FilesystemPathInfoQuery', 'FilesystemPathInfo', {
1447
- path: 'vol1:test.bin',
1448
- });
1449
- expect(typedCall).toHaveBeenNthCalledWith(2, 'FilesystemFileRead', 'FilesystemFile', {
1450
- file: {
1451
- path: 'vol1:test.bin',
1452
- offset: 0,
1453
- total_size: 0,
1454
- },
1455
- chunk_len: 64,
1456
- ui_percentage: 99,
1457
- });
1458
- expect(typedCall).toHaveBeenNthCalledWith(3, 'FilesystemFileRead', 'FilesystemFile', {
1459
- file: {
1460
- path: 'vol1:test.bin',
1461
- offset: 64,
1462
- total_size: 0,
1463
- },
1464
- chunk_len: 1,
1465
- ui_percentage: 99,
1466
- });
1467
- expect(result.data.byteLength).toBe(65);
1468
- expect(result.data[0]).toBe(1);
1469
- expect(result.data[64]).toBe(2);
1470
- expect(result).toMatchObject({
1471
- path: 'vol1:test.bin',
1472
- offset: 0,
1473
- total_size: 65,
1474
- chunks: 2,
1475
- });
1476
- });
1477
-
1478
- test('decodes protobuf bytes hex string returned by transport', async () => {
1479
- const typedCall = jest.fn().mockResolvedValue({
1480
- message: {
1481
- data: '0102ff',
1482
- },
1483
- });
1484
- const method = new FileRead({
1485
- id: 1,
1486
- payload: {
1487
- method: 'fileRead',
1488
- path: 'vol0:test.bin',
1489
- offset: 0,
1490
- totalSize: 3,
1491
- chunkLen: 512,
1492
- },
1493
- });
1494
- (method as any).device = { commands: { typedCall } };
1495
-
1496
- method.init();
1497
- const result = await method.run();
1498
-
1499
- expect(result.data).toEqual(new Uint8Array([1, 2, 255]));
1500
- });
1501
- });