@onekeyfe/hd-core 1.2.0-alpha.13 → 1.2.0-alpha.131

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 (845) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +390 -0
  2. package/__tests__/DeviceCommands.test.ts +701 -0
  3. package/__tests__/DeviceEventRegistration.test.ts +49 -0
  4. package/__tests__/base64Data.test.ts +69 -0
  5. package/__tests__/chain-params-onekey-compatibility.test.ts +229 -0
  6. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +830 -0
  7. package/__tests__/check-firmware-release-protocol-v2.test.ts +270 -0
  8. package/__tests__/connectSettings.test.ts +45 -5
  9. package/__tests__/core-dispose.test.ts +34 -0
  10. package/__tests__/core-error-output.test.ts +39 -0
  11. package/__tests__/core-initialization.test.ts +23 -0
  12. package/__tests__/device-connector-protocol.test.ts +102 -0
  13. package/__tests__/device-features-state.test.ts +78 -0
  14. package/__tests__/device-identity.test.ts +52 -0
  15. package/__tests__/device-initialize-timeout.test.ts +56 -0
  16. package/__tests__/device-lifecycle-events.test.ts +535 -0
  17. package/__tests__/device-pool-state.test.ts +191 -0
  18. package/__tests__/device-settings.test.ts +569 -0
  19. package/__tests__/device-state-contract.test.ts +28 -0
  20. package/__tests__/device-state-events.test.ts +286 -0
  21. package/__tests__/device-state-mapper.test.ts +297 -0
  22. package/__tests__/device-state-projector.test.ts +114 -0
  23. package/__tests__/device-state-store.test.ts +109 -0
  24. package/__tests__/device-utils.test.ts +154 -0
  25. package/__tests__/device-wallet-session-store.test.ts +348 -1
  26. package/__tests__/deviceFeaturesUtils.test.ts +39 -0
  27. package/__tests__/devicePoolBootloaderPath.test.ts +64 -0
  28. package/__tests__/deviceSettings.test.ts +117 -0
  29. package/__tests__/deviceUploadNft.test.ts +345 -0
  30. package/__tests__/evmLedgerLegacySafety.test.ts +12 -6
  31. package/__tests__/evmSignTransaction.test.ts +69 -0
  32. package/__tests__/evmSignTypedData.test.ts +80 -0
  33. package/__tests__/filesystemValidation.test.ts +53 -0
  34. package/__tests__/firmware-memory-host.test.ts +126 -0
  35. package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
  36. package/__tests__/firmware-update/device-update-bootloader.test.ts +109 -0
  37. package/__tests__/firmware-update/firmware-artifact-source.test.ts +171 -0
  38. package/__tests__/firmware-update/firmware-host-binding.test.ts +79 -0
  39. package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
  40. package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +583 -0
  41. package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +171 -0
  42. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +438 -0
  43. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
  44. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +474 -0
  45. package/__tests__/firmware-update/firmware-update-plan.test.ts +819 -0
  46. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +287 -0
  47. package/__tests__/firmware-update/firmware-update-prepared-resource-executors.test.ts +326 -0
  48. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +457 -0
  49. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +237 -0
  50. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +130 -0
  51. package/__tests__/firmware-update/firmware-update-v4-parameters.test.ts +85 -0
  52. package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
  53. package/__tests__/get-device-state.test.ts +617 -0
  54. package/__tests__/homescreen.test.ts +81 -0
  55. package/__tests__/kaspa-public-types.type-test.ts +16 -0
  56. package/__tests__/kaspa-use-tweak-pro2.test.ts +20 -0
  57. package/__tests__/kaspaSignTransaction.test.ts +578 -0
  58. package/__tests__/known-device-public-types.type-test.ts +3 -0
  59. package/__tests__/logBlockEvent.test.ts +140 -1
  60. package/__tests__/method-protocol-support.test.ts +144 -0
  61. package/__tests__/networkUtils.test.ts +406 -0
  62. package/__tests__/open-wallet-session-error-response.test.ts +43 -0
  63. package/__tests__/open-wallet-session.test.ts +1899 -0
  64. package/__tests__/pro2Nft.test.ts +108 -0
  65. package/__tests__/pro2Wallpaper.test.ts +8 -19
  66. package/__tests__/protocol-binding.test.ts +89 -0
  67. package/__tests__/protocol-v2-firmware-targets.test.ts +105 -0
  68. package/__tests__/protocol-v2-ping.test.ts +28 -0
  69. package/__tests__/protocol-v2-resources.test.ts +385 -0
  70. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  71. package/__tests__/protocol-v2-unlock-policy.test.ts +339 -0
  72. package/__tests__/protocol-v2.test.ts +8084 -2515
  73. package/__tests__/protocolV2FileWrite.test.ts +221 -3
  74. package/__tests__/protocolV2UiInteraction.test.ts +329 -0
  75. package/__tests__/public-device-state-api.test.ts +275 -0
  76. package/__tests__/public-pro2-api-boundary.test.ts +107 -0
  77. package/__tests__/refresh-device-state.test.ts +103 -0
  78. package/__tests__/request-context-logging.test.ts +16 -0
  79. package/__tests__/resourceBase64Boundary.test.ts +48 -0
  80. package/__tests__/search-devices.test.ts +191 -0
  81. package/__tests__/ton-sign-message.test.ts +84 -0
  82. package/__tests__/tron-sign-message-init.test.ts +74 -0
  83. package/__tests__/uiProgressThrottle.test.ts +74 -0
  84. package/__tests__/uiPromiseRegistry.test.ts +115 -0
  85. package/dist/api/BaseMethod.d.ts +14 -2
  86. package/dist/api/BaseMethod.d.ts.map +1 -1
  87. package/dist/api/CheckAllFirmwareRelease.d.ts +25 -1
  88. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  89. package/dist/api/CheckBLEFirmwareRelease.d.ts +3 -2
  90. package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
  91. package/dist/api/CheckBootloaderRelease.d.ts +2 -1
  92. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  93. package/dist/api/CheckFirmwareRelease.d.ts +3 -2
  94. package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
  95. package/dist/api/CipherKeyValue.d.ts +1 -0
  96. package/dist/api/CipherKeyValue.d.ts.map +1 -1
  97. package/dist/api/ClearSessionCache.d.ts.map +1 -1
  98. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  99. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  100. package/dist/api/DirList.d.ts +1 -0
  101. package/dist/api/DirList.d.ts.map +1 -1
  102. package/dist/api/DirMake.d.ts +1 -0
  103. package/dist/api/DirMake.d.ts.map +1 -1
  104. package/dist/api/DirRemove.d.ts +1 -0
  105. package/dist/api/DirRemove.d.ts.map +1 -1
  106. package/dist/api/FileDelete.d.ts +1 -0
  107. package/dist/api/FileDelete.d.ts.map +1 -1
  108. package/dist/api/FileRead.d.ts +1 -0
  109. package/dist/api/FileRead.d.ts.map +1 -1
  110. package/dist/api/FileWrite.d.ts +2 -0
  111. package/dist/api/FileWrite.d.ts.map +1 -1
  112. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  113. package/dist/api/FirmwareUpdateV2.d.ts +13 -2
  114. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  115. package/dist/api/FirmwareUpdateV3.d.ts +7 -3
  116. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  117. package/dist/api/FirmwareUpdateV4.d.ts +57 -14
  118. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  119. package/dist/api/GetDeviceState.d.ts +8 -0
  120. package/dist/api/GetDeviceState.d.ts.map +1 -0
  121. package/dist/api/GetFeatures.d.ts +1 -1
  122. package/dist/api/GetFeatures.d.ts.map +1 -1
  123. package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
  124. package/dist/api/GetPassphraseState.d.ts +1 -0
  125. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  126. package/dist/api/OpenWalletSession.d.ts +8 -0
  127. package/dist/api/OpenWalletSession.d.ts.map +1 -0
  128. package/dist/api/PathInfo.d.ts +1 -0
  129. package/dist/api/PathInfo.d.ts.map +1 -1
  130. package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
  131. package/dist/api/SearchDevices.d.ts +3 -0
  132. package/dist/api/SearchDevices.d.ts.map +1 -1
  133. package/dist/api/UploadPortfolio.d.ts +1 -2
  134. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  135. package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
  136. package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
  137. package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
  138. package/dist/api/algo/AlgoGetAddress.d.ts +1 -0
  139. package/dist/api/algo/AlgoGetAddress.d.ts.map +1 -1
  140. package/dist/api/algo/AlgoSignTransaction.d.ts +1 -0
  141. package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
  142. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +1 -0
  143. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  144. package/dist/api/aptos/AptosGetAddress.d.ts +1 -0
  145. package/dist/api/aptos/AptosGetAddress.d.ts.map +1 -1
  146. package/dist/api/aptos/AptosGetPublicKey.d.ts +1 -0
  147. package/dist/api/aptos/AptosGetPublicKey.d.ts.map +1 -1
  148. package/dist/api/aptos/AptosSignInMessage.d.ts +1 -0
  149. package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
  150. package/dist/api/aptos/AptosSignMessage.d.ts +1 -0
  151. package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
  152. package/dist/api/aptos/AptosSignTransaction.d.ts +1 -0
  153. package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
  154. package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
  155. package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
  156. package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
  157. package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
  158. package/dist/api/btc/BTCGetAddress.d.ts +1 -0
  159. package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
  160. package/dist/api/btc/BTCGetPublicKey.d.ts +1 -0
  161. package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
  162. package/dist/api/btc/BTCSignMessage.d.ts +1 -0
  163. package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
  164. package/dist/api/btc/BTCSignPsbt.d.ts +1 -0
  165. package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
  166. package/dist/api/btc/BTCSignTransaction.d.ts +1 -0
  167. package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
  168. package/dist/api/btc/BTCVerifyMessage.d.ts +1 -0
  169. package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
  170. package/dist/api/btc/helpers/versionLimit.d.ts +2 -0
  171. package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
  172. package/dist/api/cardano/CardanoGetAddress.d.ts +1 -0
  173. package/dist/api/cardano/CardanoGetAddress.d.ts.map +1 -1
  174. package/dist/api/cardano/CardanoGetPublicKey.d.ts +1 -0
  175. package/dist/api/cardano/CardanoGetPublicKey.d.ts.map +1 -1
  176. package/dist/api/cardano/CardanoSignMessage.d.ts +1 -0
  177. package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
  178. package/dist/api/cardano/CardanoSignTransaction.d.ts +1 -0
  179. package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
  180. package/dist/api/conflux/ConfluxGetAddress.d.ts +2 -0
  181. package/dist/api/conflux/ConfluxGetAddress.d.ts.map +1 -1
  182. package/dist/api/conflux/ConfluxSignMessage.d.ts +2 -0
  183. package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
  184. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts +2 -0
  185. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
  186. package/dist/api/conflux/ConfluxSignTransaction.d.ts +2 -0
  187. package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
  188. package/dist/api/cosmos/CosmosGetAddress.d.ts +1 -0
  189. package/dist/api/cosmos/CosmosGetAddress.d.ts.map +1 -1
  190. package/dist/api/cosmos/CosmosGetPublicKey.d.ts +1 -0
  191. package/dist/api/cosmos/CosmosGetPublicKey.d.ts.map +1 -1
  192. package/dist/api/cosmos/CosmosSignTransaction.d.ts +1 -0
  193. package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
  194. package/dist/api/device/DeviceCancel.d.ts +1 -0
  195. package/dist/api/device/DeviceCancel.d.ts.map +1 -1
  196. package/dist/api/device/DeviceChangePin.d.ts +1 -0
  197. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  198. package/dist/api/device/DeviceFullyUploadResource.d.ts +1 -2
  199. package/dist/api/device/DeviceFullyUploadResource.d.ts.map +1 -1
  200. package/dist/api/device/DeviceLock.d.ts +1 -0
  201. package/dist/api/device/DeviceLock.d.ts.map +1 -1
  202. package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -0
  203. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  204. package/dist/api/device/DeviceRebootToBootloader.d.ts +1 -0
  205. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  206. package/dist/api/device/DeviceSettings.d.ts +1 -0
  207. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  208. package/dist/api/device/DeviceSupportFeatures.d.ts +1 -0
  209. package/dist/api/device/DeviceSupportFeatures.d.ts.map +1 -1
  210. package/dist/api/device/DeviceUnlock.d.ts +3 -2
  211. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  212. package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
  213. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  214. package/dist/api/device/DeviceWipe.d.ts +1 -0
  215. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  216. package/dist/api/device/PreInitialize.d.ts +1 -0
  217. package/dist/api/device/PreInitialize.d.ts.map +1 -1
  218. package/dist/api/dynex/DnxGetAddress.d.ts.map +1 -1
  219. package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
  220. package/dist/api/evm/EVMGetAddress.d.ts +1 -0
  221. package/dist/api/evm/EVMGetAddress.d.ts.map +1 -1
  222. package/dist/api/evm/EVMGetPublicKey.d.ts +1 -0
  223. package/dist/api/evm/EVMGetPublicKey.d.ts.map +1 -1
  224. package/dist/api/evm/EVMSignMessage.d.ts +1 -0
  225. package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
  226. package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
  227. package/dist/api/evm/EVMSignTransaction.d.ts +1 -0
  228. package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
  229. package/dist/api/evm/EVMSignTypedData.d.ts +1 -0
  230. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  231. package/dist/api/evm/EVMVerifyMessage.d.ts +1 -0
  232. package/dist/api/evm/EVMVerifyMessage.d.ts.map +1 -1
  233. package/dist/api/evm/protocol.d.ts +3 -0
  234. package/dist/api/evm/protocol.d.ts.map +1 -0
  235. package/dist/api/filecoin/FilecoinGetAddress.d.ts +1 -0
  236. package/dist/api/filecoin/FilecoinGetAddress.d.ts.map +1 -1
  237. package/dist/api/filecoin/FilecoinSignTransaction.d.ts +1 -0
  238. package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
  239. package/dist/api/firmware/FirmwareArtifactSource.d.ts +29 -0
  240. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
  241. package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
  242. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
  243. package/dist/api/firmware/FirmwareMemoryHost.d.ts +22 -0
  244. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -0
  245. package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
  246. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
  247. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts +11 -0
  248. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -0
  249. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +12 -3
  250. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  251. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
  252. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
  253. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +72 -0
  254. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
  255. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +38 -0
  256. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
  257. package/dist/api/firmware/getBinary.d.ts +15 -4
  258. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  259. package/dist/api/firmware/protocolV2Release.d.ts +33 -0
  260. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -0
  261. package/dist/api/firmware/updateBootloader.d.ts +2 -0
  262. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  263. package/dist/api/firmware/uploadFirmware.d.ts +9 -1
  264. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  265. package/dist/api/helpers/base64Data.d.ts +16 -0
  266. package/dist/api/helpers/base64Data.d.ts.map +1 -0
  267. package/dist/api/helpers/filesystemValidation.d.ts +3 -0
  268. package/dist/api/helpers/filesystemValidation.d.ts.map +1 -1
  269. package/dist/api/helpers/paramsValidator.d.ts +1 -0
  270. package/dist/api/helpers/paramsValidator.d.ts.map +1 -1
  271. package/dist/api/helpers/protocolV2FileWrite.d.ts +11 -0
  272. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  273. package/dist/api/index.d.ts +5 -29
  274. package/dist/api/index.d.ts.map +1 -1
  275. package/dist/api/kaspa/KaspaGetAddress.d.ts +4 -0
  276. package/dist/api/kaspa/KaspaGetAddress.d.ts.map +1 -1
  277. package/dist/api/kaspa/KaspaSignTransaction.d.ts +9 -1
  278. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  279. package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
  280. package/dist/api/lightning/LnurlAuth.d.ts +0 -4
  281. package/dist/api/lightning/LnurlAuth.d.ts.map +1 -1
  282. package/dist/api/near/NearGetAddress.d.ts +1 -0
  283. package/dist/api/near/NearGetAddress.d.ts.map +1 -1
  284. package/dist/api/near/NearSignTransaction.d.ts +1 -0
  285. package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
  286. package/dist/api/nem/NEMGetAddress.d.ts +1 -0
  287. package/dist/api/nem/NEMGetAddress.d.ts.map +1 -1
  288. package/dist/api/nem/NEMSignTransaction.d.ts +1 -0
  289. package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
  290. package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
  291. package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
  292. package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
  293. package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
  294. package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
  295. package/dist/api/nexa/NexaSignTransaction.d.ts +1 -0
  296. package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
  297. package/dist/api/nostr/NostrDecryptMessage.d.ts +1 -0
  298. package/dist/api/nostr/NostrDecryptMessage.d.ts.map +1 -1
  299. package/dist/api/nostr/NostrEncryptMessage.d.ts +1 -0
  300. package/dist/api/nostr/NostrEncryptMessage.d.ts.map +1 -1
  301. package/dist/api/nostr/NostrGetPublicKey.d.ts +1 -0
  302. package/dist/api/nostr/NostrGetPublicKey.d.ts.map +1 -1
  303. package/dist/api/nostr/NostrSignEvent.d.ts +1 -0
  304. package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
  305. package/dist/api/nostr/NostrSignSchnorr.d.ts +1 -0
  306. package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
  307. package/dist/api/polkadot/PolkadotGetAddress.d.ts +2 -1
  308. package/dist/api/polkadot/PolkadotGetAddress.d.ts.map +1 -1
  309. package/dist/api/polkadot/PolkadotSignTransaction.d.ts +1 -0
  310. package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
  311. package/dist/api/polkadot/networks.d.ts +1 -1
  312. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +1 -0
  313. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -1
  314. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +1 -0
  315. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -1
  316. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +4 -1
  317. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  318. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +1 -0
  319. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
  320. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +2 -1
  321. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -1
  322. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +2 -2
  323. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  324. package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -0
  325. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  326. package/dist/api/protocol-v2/DeviceStatusGet.d.ts +1 -0
  327. package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -1
  328. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
  329. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  330. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +3 -3
  331. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  332. package/dist/api/protocol-v2/FilesystemFormat.d.ts +1 -0
  333. package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
  334. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts +1 -0
  335. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -1
  336. package/dist/api/protocol-v2/Ping.d.ts +3 -0
  337. package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
  338. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +1 -0
  339. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  340. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  341. package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
  342. package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
  343. package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
  344. package/dist/api/solana/SolGetAddress.d.ts +1 -0
  345. package/dist/api/solana/SolGetAddress.d.ts.map +1 -1
  346. package/dist/api/solana/SolSignMessage.d.ts +2 -1
  347. package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
  348. package/dist/api/solana/SolSignOffchainMessage.d.ts +2 -1
  349. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  350. package/dist/api/solana/SolSignTransaction.d.ts +3 -2
  351. package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
  352. package/dist/api/starcoin/StarcoinGetAddress.d.ts +1 -0
  353. package/dist/api/starcoin/StarcoinGetAddress.d.ts.map +1 -1
  354. package/dist/api/starcoin/StarcoinGetPublicKey.d.ts +1 -0
  355. package/dist/api/starcoin/StarcoinGetPublicKey.d.ts.map +1 -1
  356. package/dist/api/starcoin/StarcoinSignMessage.d.ts +1 -0
  357. package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
  358. package/dist/api/starcoin/StarcoinSignTransaction.d.ts +1 -0
  359. package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
  360. package/dist/api/starcoin/StarcoinVerifyMessage.d.ts +1 -0
  361. package/dist/api/starcoin/StarcoinVerifyMessage.d.ts.map +1 -1
  362. package/dist/api/stellar/StellarGetAddress.d.ts +1 -2
  363. package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
  364. package/dist/api/stellar/StellarSignTransaction.d.ts +2 -3
  365. package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
  366. package/dist/api/sui/SuiGetAddress.d.ts +2 -1
  367. package/dist/api/sui/SuiGetAddress.d.ts.map +1 -1
  368. package/dist/api/sui/SuiGetPublicKey.d.ts +2 -1
  369. package/dist/api/sui/SuiGetPublicKey.d.ts.map +1 -1
  370. package/dist/api/sui/SuiSignMessage.d.ts +2 -1
  371. package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
  372. package/dist/api/sui/SuiSignTransaction.d.ts +2 -1
  373. package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
  374. package/dist/api/ton/TonGetAddress.d.ts +2 -1
  375. package/dist/api/ton/TonGetAddress.d.ts.map +1 -1
  376. package/dist/api/ton/TonSignData.d.ts +1 -0
  377. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  378. package/dist/api/ton/TonSignMessage.d.ts +2 -1
  379. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  380. package/dist/api/ton/TonSignProof.d.ts +2 -1
  381. package/dist/api/ton/TonSignProof.d.ts.map +1 -1
  382. package/dist/api/tron/TronGetAddress.d.ts +1 -0
  383. package/dist/api/tron/TronGetAddress.d.ts.map +1 -1
  384. package/dist/api/tron/TronSignMessage.d.ts +6 -1
  385. package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
  386. package/dist/api/tron/TronSignTransaction.d.ts +2 -1
  387. package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
  388. package/dist/api/utils.d.ts +4 -1
  389. package/dist/api/utils.d.ts.map +1 -1
  390. package/dist/api/xrp/XrpGetAddress.d.ts +1 -0
  391. package/dist/api/xrp/XrpGetAddress.d.ts.map +1 -1
  392. package/dist/api/xrp/XrpSignTransaction.d.ts +1 -0
  393. package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
  394. package/dist/constants/index.d.ts +1 -1
  395. package/dist/constants/index.d.ts.map +1 -1
  396. package/dist/core/RequestQueue.d.ts +0 -2
  397. package/dist/core/RequestQueue.d.ts.map +1 -1
  398. package/dist/core/deviceEventRegistration.d.ts +13 -0
  399. package/dist/core/deviceEventRegistration.d.ts.map +1 -0
  400. package/dist/core/index.d.ts +4 -3
  401. package/dist/core/index.d.ts.map +1 -1
  402. package/dist/core/uiPromiseRegistry.d.ts +6 -0
  403. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  404. package/dist/data-manager/DataManager.d.ts +14 -5
  405. package/dist/data-manager/DataManager.d.ts.map +1 -1
  406. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  407. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  408. package/dist/device/Device.d.ts +78 -16
  409. package/dist/device/Device.d.ts.map +1 -1
  410. package/dist/device/DeviceCommands.d.ts +8 -6
  411. package/dist/device/DeviceCommands.d.ts.map +1 -1
  412. package/dist/device/DeviceConnector.d.ts +4 -3
  413. package/dist/device/DeviceConnector.d.ts.map +1 -1
  414. package/dist/device/DeviceFeaturesState.d.ts +3 -0
  415. package/dist/device/DeviceFeaturesState.d.ts.map +1 -0
  416. package/dist/device/DevicePool.d.ts +6 -2
  417. package/dist/device/DevicePool.d.ts.map +1 -1
  418. package/dist/device/DeviceStateMapper.d.ts +13 -0
  419. package/dist/device/DeviceStateMapper.d.ts.map +1 -0
  420. package/dist/device/DeviceStateProjector.d.ts +7 -0
  421. package/dist/device/DeviceStateProjector.d.ts.map +1 -0
  422. package/dist/device/DeviceStateStore.d.ts +21 -0
  423. package/dist/device/DeviceStateStore.d.ts.map +1 -0
  424. package/dist/device/DeviceWalletSessionStore.d.ts +13 -1
  425. package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -1
  426. package/dist/device/cloneDeviceState.d.ts +2 -0
  427. package/dist/device/cloneDeviceState.d.ts.map +1 -0
  428. package/dist/device/deviceIdentity.d.ts +5 -0
  429. package/dist/device/deviceIdentity.d.ts.map +1 -0
  430. package/dist/deviceProfile/buildDeviceFeatures.d.ts +8 -2
  431. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  432. package/dist/deviceProfile/index.d.ts +0 -1
  433. package/dist/deviceProfile/index.d.ts.map +1 -1
  434. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts +7 -0
  435. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -0
  436. package/dist/events/call.d.ts +0 -7
  437. package/dist/events/call.d.ts.map +1 -1
  438. package/dist/events/core.d.ts +2 -2
  439. package/dist/events/core.d.ts.map +1 -1
  440. package/dist/events/device.d.ts +16 -2
  441. package/dist/events/device.d.ts.map +1 -1
  442. package/dist/events/iframe.d.ts +0 -1
  443. package/dist/events/iframe.d.ts.map +1 -1
  444. package/dist/events/logBlockEvent.d.ts +2 -0
  445. package/dist/events/logBlockEvent.d.ts.map +1 -1
  446. package/dist/events/ui-promise.d.ts +4 -2
  447. package/dist/events/ui-promise.d.ts.map +1 -1
  448. package/dist/events/ui-request.d.ts +50 -4
  449. package/dist/events/ui-request.d.ts.map +1 -1
  450. package/dist/events/ui-response.d.ts +10 -2
  451. package/dist/events/ui-response.d.ts.map +1 -1
  452. package/dist/index.d.ts +1765 -829
  453. package/dist/index.d.ts.map +1 -1
  454. package/dist/index.js +11723 -4704
  455. package/dist/inject.d.ts +7 -3
  456. package/dist/inject.d.ts.map +1 -1
  457. package/dist/lowLevelInject.d.ts +1 -2
  458. package/dist/lowLevelInject.d.ts.map +1 -1
  459. package/dist/protocols/protocol-v2/deviceSession.d.ts +7 -0
  460. package/dist/protocols/protocol-v2/deviceSession.d.ts.map +1 -0
  461. package/dist/protocols/protocol-v2/features.d.ts +33 -22
  462. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  463. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  464. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  465. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  466. package/dist/protocols/protocol-v2/resources.d.ts +12 -0
  467. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  468. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +17 -0
  469. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
  470. package/dist/protocols/protocol-v2/uiInteraction.d.ts +42 -0
  471. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
  472. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +2 -0
  473. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -0
  474. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  475. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  476. package/dist/protocols/protocol-v2/walletSession.d.ts +18 -4
  477. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  478. package/dist/topLevelInject.d.ts.map +1 -1
  479. package/dist/types/api/checkAllFirmwareRelease.d.ts +48 -9
  480. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  481. package/dist/types/api/checkBLEFirmwareRelease.d.ts +2 -13
  482. package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
  483. package/dist/types/api/checkBootloaderRelease.d.ts +2 -6
  484. package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
  485. package/dist/types/api/checkFirmwareRelease.d.ts +2 -13
  486. package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
  487. package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
  488. package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
  489. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  490. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  491. package/dist/types/api/deviceSettings.d.ts +11 -2
  492. package/dist/types/api/deviceSettings.d.ts.map +1 -1
  493. package/dist/types/api/deviceUnlock.d.ts +6 -2
  494. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  495. package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
  496. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  497. package/dist/types/api/export.d.ts +8 -3
  498. package/dist/types/api/export.d.ts.map +1 -1
  499. package/dist/types/api/firmwareUpdate.d.ts +67 -5
  500. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  501. package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
  502. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
  503. package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
  504. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
  505. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
  506. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
  507. package/dist/types/api/getDeviceState.d.ts +12 -0
  508. package/dist/types/api/getDeviceState.d.ts.map +1 -0
  509. package/dist/types/api/getFeatures.d.ts.map +1 -1
  510. package/dist/types/api/getOnekeyFeatures.d.ts.map +1 -1
  511. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  512. package/dist/types/api/index.d.ts +25 -35
  513. package/dist/types/api/index.d.ts.map +1 -1
  514. package/dist/types/api/kaspaSignTransaction.d.ts +42 -4
  515. package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
  516. package/dist/types/api/openWalletSession.d.ts +35 -0
  517. package/dist/types/api/openWalletSession.d.ts.map +1 -0
  518. package/dist/types/api/protocolV2.d.ts +11 -93
  519. package/dist/types/api/protocolV2.d.ts.map +1 -1
  520. package/dist/types/api/sessionCache.d.ts +4 -1
  521. package/dist/types/api/sessionCache.d.ts.map +1 -1
  522. package/dist/types/device.d.ts +139 -8
  523. package/dist/types/device.d.ts.map +1 -1
  524. package/dist/types/params.d.ts +1 -0
  525. package/dist/types/params.d.ts.map +1 -1
  526. package/dist/types/settings.d.ts +44 -16
  527. package/dist/types/settings.d.ts.map +1 -1
  528. package/dist/utils/assets.d.ts +2 -1
  529. package/dist/utils/assets.d.ts.map +1 -1
  530. package/dist/utils/deviceFeaturesCompat.d.ts +14 -0
  531. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -0
  532. package/dist/utils/deviceFeaturesUtils.d.ts +10 -1
  533. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  534. package/dist/utils/deviceInfoUtils.d.ts +9 -9
  535. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  536. package/dist/utils/deviceSettings.d.ts +39 -7
  537. package/dist/utils/deviceSettings.d.ts.map +1 -1
  538. package/dist/utils/deviceVersionUtils.d.ts +7 -5
  539. package/dist/utils/deviceVersionUtils.d.ts.map +1 -1
  540. package/dist/utils/homescreen.d.ts +4 -0
  541. package/dist/utils/homescreen.d.ts.map +1 -1
  542. package/dist/utils/index.d.ts +5 -4
  543. package/dist/utils/index.d.ts.map +1 -1
  544. package/dist/utils/networkUtils.d.ts +10 -1
  545. package/dist/utils/networkUtils.d.ts.map +1 -1
  546. package/dist/utils/patch.d.ts +1 -1
  547. package/dist/utils/patch.d.ts.map +1 -1
  548. package/dist/utils/pro2Nft.d.ts +38 -0
  549. package/dist/utils/pro2Nft.d.ts.map +1 -0
  550. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  551. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  552. package/dist/utils/tracing.d.ts.map +1 -1
  553. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  554. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  555. package/package.json +6 -4
  556. package/src/api/BaseMethod.ts +45 -23
  557. package/src/api/CheckAllFirmwareRelease.ts +440 -4
  558. package/src/api/CheckBLEFirmwareRelease.ts +37 -5
  559. package/src/api/CheckBootloaderRelease.ts +37 -5
  560. package/src/api/CheckFirmwareRelease.ts +36 -9
  561. package/src/api/CipherKeyValue.ts +4 -0
  562. package/src/api/ClearSessionCache.ts +4 -0
  563. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  564. package/src/api/DirList.ts +9 -4
  565. package/src/api/DirMake.ts +7 -4
  566. package/src/api/DirRemove.ts +7 -4
  567. package/src/api/FileDelete.ts +7 -4
  568. package/src/api/FileRead.ts +13 -7
  569. package/src/api/FileWrite.ts +10 -5
  570. package/src/api/FirmwareUpdate.ts +30 -15
  571. package/src/api/FirmwareUpdateV2.ts +535 -169
  572. package/src/api/FirmwareUpdateV3.ts +349 -91
  573. package/src/api/FirmwareUpdateV4.ts +2300 -710
  574. package/src/api/GetDeviceState.ts +59 -0
  575. package/src/api/GetFeatures.ts +6 -4
  576. package/src/api/GetOnekeyFeatures.ts +1 -75
  577. package/src/api/GetPassphraseState.ts +36 -12
  578. package/src/api/OpenWalletSession.ts +268 -0
  579. package/src/api/PathInfo.ts +9 -4
  580. package/src/api/PromptWebDeviceAccess.ts +2 -7
  581. package/src/api/SearchDevices.ts +35 -5
  582. package/src/api/UploadPortfolio.ts +32 -4
  583. package/src/api/alephium/AlephiumGetAddress.ts +0 -4
  584. package/src/api/alephium/AlephiumSignMessage.ts +0 -4
  585. package/src/api/alephium/AlephiumSignTransaction.ts +2 -6
  586. package/src/api/algo/AlgoGetAddress.ts +4 -0
  587. package/src/api/algo/AlgoSignTransaction.ts +4 -0
  588. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  589. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +45 -32
  590. package/src/api/aptos/AptosGetAddress.ts +4 -0
  591. package/src/api/aptos/AptosGetPublicKey.ts +4 -0
  592. package/src/api/aptos/AptosSignInMessage.ts +4 -0
  593. package/src/api/aptos/AptosSignMessage.ts +4 -0
  594. package/src/api/aptos/AptosSignTransaction.ts +4 -0
  595. package/src/api/benfen/BenfenGetAddress.ts +11 -7
  596. package/src/api/benfen/BenfenGetPublicKey.ts +0 -4
  597. package/src/api/benfen/BenfenSignMessage.ts +0 -4
  598. package/src/api/benfen/BenfenSignTransaction.ts +0 -4
  599. package/src/api/btc/BTCGetAddress.ts +8 -1
  600. package/src/api/btc/BTCGetPublicKey.ts +9 -2
  601. package/src/api/btc/BTCSignMessage.ts +8 -1
  602. package/src/api/btc/BTCSignPsbt.ts +4 -0
  603. package/src/api/btc/BTCSignTransaction.ts +8 -1
  604. package/src/api/btc/BTCVerifyMessage.ts +8 -1
  605. package/src/api/btc/helpers/versionLimit.ts +7 -4
  606. package/src/api/cardano/CardanoGetAddress.ts +4 -0
  607. package/src/api/cardano/CardanoGetPublicKey.ts +4 -0
  608. package/src/api/cardano/CardanoSignMessage.ts +4 -0
  609. package/src/api/cardano/CardanoSignTransaction.ts +4 -0
  610. package/src/api/conflux/ConfluxGetAddress.ts +6 -0
  611. package/src/api/conflux/ConfluxSignMessage.ts +6 -0
  612. package/src/api/conflux/ConfluxSignMessageCIP23.ts +6 -0
  613. package/src/api/conflux/ConfluxSignTransaction.ts +8 -5
  614. package/src/api/cosmos/CosmosGetAddress.ts +4 -0
  615. package/src/api/cosmos/CosmosGetPublicKey.ts +4 -0
  616. package/src/api/cosmos/CosmosSignTransaction.ts +4 -0
  617. package/src/api/device/DeviceCancel.ts +5 -0
  618. package/src/api/device/DeviceChangePin.ts +28 -0
  619. package/src/api/device/DeviceFullyUploadResource.ts +4 -5
  620. package/src/api/device/DeviceLock.ts +5 -0
  621. package/src/api/device/DeviceRebootToBoardloader.ts +5 -0
  622. package/src/api/device/DeviceRebootToBootloader.ts +5 -0
  623. package/src/api/device/DeviceSettings.ts +211 -3
  624. package/src/api/device/DeviceSupportFeatures.ts +4 -0
  625. package/src/api/device/DeviceUnlock.ts +21 -3
  626. package/src/api/device/DeviceUpdateBootloader.ts +152 -8
  627. package/src/api/device/DeviceWipe.ts +25 -0
  628. package/src/api/device/PreInitialize.ts +4 -0
  629. package/src/api/dynex/DnxGetAddress.ts +0 -6
  630. package/src/api/dynex/DnxSignTransaction.ts +0 -6
  631. package/src/api/evm/EVMGetAddress.ts +6 -2
  632. package/src/api/evm/EVMGetPublicKey.ts +6 -2
  633. package/src/api/evm/EVMSignMessage.ts +6 -2
  634. package/src/api/evm/EVMSignMessageEIP712.ts +1 -11
  635. package/src/api/evm/EVMSignTransaction.ts +6 -2
  636. package/src/api/evm/EVMSignTypedData.ts +42 -50
  637. package/src/api/evm/EVMVerifyMessage.ts +6 -2
  638. package/src/api/evm/legacyV1/getAddress.ts +2 -2
  639. package/src/api/evm/legacyV1/getPublicKey.ts +2 -2
  640. package/src/api/evm/legacyV1/signMessage.ts +2 -2
  641. package/src/api/evm/legacyV1/signTypedData.ts +2 -2
  642. package/src/api/evm/legacyV1/signTypedHash.ts +2 -2
  643. package/src/api/evm/legacyV1/verifyMessage.ts +2 -2
  644. package/src/api/evm/protocol.ts +6 -0
  645. package/src/api/filecoin/FilecoinGetAddress.ts +4 -0
  646. package/src/api/filecoin/FilecoinSignTransaction.ts +4 -0
  647. package/src/api/firmware/FirmwareArtifactSource.ts +305 -0
  648. package/src/api/firmware/FirmwareHostBinding.ts +123 -0
  649. package/src/api/firmware/FirmwareMemoryHost.ts +143 -0
  650. package/src/api/firmware/FirmwarePreparationError.ts +12 -0
  651. package/src/api/firmware/FirmwarePreparedResourceArchive.ts +196 -0
  652. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +214 -77
  653. package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
  654. package/src/api/firmware/FirmwareUpdatePlan.ts +946 -0
  655. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +486 -0
  656. package/src/api/firmware/getBinary.ts +8 -3
  657. package/src/api/firmware/protocolV2Release.ts +168 -0
  658. package/src/api/firmware/updateBootloader.ts +19 -4
  659. package/src/api/firmware/uploadFirmware.ts +157 -26
  660. package/src/api/helpers/base64Data.ts +85 -0
  661. package/src/api/helpers/batchGetPublickeys.ts +2 -2
  662. package/src/api/helpers/filesystemValidation.ts +61 -0
  663. package/src/api/helpers/paramsValidator.ts +1 -1
  664. package/src/api/helpers/protocolV2FileWrite.ts +266 -42
  665. package/src/api/index.ts +6 -30
  666. package/src/api/kaspa/KaspaGetAddress.ts +7 -0
  667. package/src/api/kaspa/KaspaSignTransaction.ts +369 -29
  668. package/src/api/kaspa/helpers/TransferSerialize.ts +17 -7
  669. package/src/api/lightning/LnurlAuth.ts +0 -4
  670. package/src/api/near/NearGetAddress.ts +4 -0
  671. package/src/api/near/NearSignTransaction.ts +4 -0
  672. package/src/api/nem/NEMGetAddress.ts +4 -0
  673. package/src/api/nem/NEMSignTransaction.ts +4 -0
  674. package/src/api/neo/NeoGetAddress.ts +0 -4
  675. package/src/api/neo/NeoSignTransaction.ts +0 -4
  676. package/src/api/nervos/NervosGetAddress.ts +0 -4
  677. package/src/api/nervos/NervosSignTransaction.ts +2 -6
  678. package/src/api/nexa/NexaGetAddress.ts +0 -4
  679. package/src/api/nexa/NexaSignTransaction.ts +3 -5
  680. package/src/api/nostr/NostrDecryptMessage.ts +4 -0
  681. package/src/api/nostr/NostrEncryptMessage.ts +4 -0
  682. package/src/api/nostr/NostrGetPublicKey.ts +4 -0
  683. package/src/api/nostr/NostrSignEvent.ts +4 -0
  684. package/src/api/nostr/NostrSignSchnorr.ts +4 -0
  685. package/src/api/polkadot/PolkadotGetAddress.ts +4 -0
  686. package/src/api/polkadot/PolkadotSignTransaction.ts +4 -0
  687. package/src/api/polkadot/networks.ts +3 -3
  688. package/src/api/protocol-v2/DeviceFactoryInfoGet.ts +5 -2
  689. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +6 -3
  690. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +13 -32
  691. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +10 -6
  692. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +6 -3
  693. package/src/api/protocol-v2/DeviceInfoGet.ts +11 -18
  694. package/src/api/protocol-v2/DeviceReboot.ts +7 -3
  695. package/src/api/protocol-v2/DeviceStatusGet.ts +6 -1
  696. package/src/api/protocol-v2/DeviceUploadNft.ts +245 -0
  697. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +45 -21
  698. package/src/api/protocol-v2/FilesystemFormat.ts +5 -2
  699. package/src/api/protocol-v2/FilesystemPermissionFix.ts +5 -2
  700. package/src/api/protocol-v2/Ping.ts +37 -3
  701. package/src/api/protocol-v2/ProtocolInfoRequest.ts +8 -3
  702. package/src/api/protocol-v2/helpers.ts +1 -1
  703. package/src/api/scdo/ScdoGetAddress.ts +0 -4
  704. package/src/api/scdo/ScdoSignMessage.ts +0 -4
  705. package/src/api/scdo/ScdoSignTransaction.ts +0 -4
  706. package/src/api/solana/SolGetAddress.ts +4 -0
  707. package/src/api/solana/SolSignMessage.ts +5 -1
  708. package/src/api/solana/SolSignOffchainMessage.ts +5 -1
  709. package/src/api/solana/SolSignTransaction.ts +6 -2
  710. package/src/api/starcoin/StarcoinGetAddress.ts +4 -0
  711. package/src/api/starcoin/StarcoinGetPublicKey.ts +4 -0
  712. package/src/api/starcoin/StarcoinSignMessage.ts +4 -0
  713. package/src/api/starcoin/StarcoinSignTransaction.ts +4 -0
  714. package/src/api/starcoin/StarcoinVerifyMessage.ts +4 -0
  715. package/src/api/stellar/StellarGetAddress.ts +1 -10
  716. package/src/api/stellar/StellarSignTransaction.ts +1 -14
  717. package/src/api/sui/SuiGetAddress.ts +5 -1
  718. package/src/api/sui/SuiGetPublicKey.ts +5 -1
  719. package/src/api/sui/SuiSignMessage.ts +5 -1
  720. package/src/api/sui/SuiSignTransaction.ts +5 -1
  721. package/src/api/ton/TonGetAddress.ts +5 -1
  722. package/src/api/ton/TonSignData.ts +5 -1
  723. package/src/api/ton/TonSignMessage.ts +10 -4
  724. package/src/api/ton/TonSignProof.ts +5 -1
  725. package/src/api/tron/TronGetAddress.ts +4 -0
  726. package/src/api/tron/TronSignMessage.ts +19 -8
  727. package/src/api/tron/TronSignTransaction.ts +5 -1
  728. package/src/api/utils.ts +32 -3
  729. package/src/api/xrp/XrpGetAddress.ts +4 -0
  730. package/src/api/xrp/XrpSignTransaction.ts +5 -1
  731. package/src/constants/index.ts +1 -4
  732. package/src/core/RequestQueue.ts +0 -18
  733. package/src/core/deviceEventRegistration.ts +27 -0
  734. package/src/core/index.ts +468 -186
  735. package/src/core/uiPromiseRegistry.ts +63 -0
  736. package/src/data/messages/messages-protocol-v2.json +523 -449
  737. package/src/data/messages/messages.json +286 -1
  738. package/src/data-manager/DataManager.ts +162 -44
  739. package/src/data-manager/TransportManager.ts +7 -1
  740. package/src/data-manager/connectSettings.ts +11 -0
  741. package/src/device/Device.ts +909 -269
  742. package/src/device/DeviceCommands.ts +198 -160
  743. package/src/device/DeviceConnector.ts +51 -21
  744. package/src/device/DeviceFeaturesState.ts +25 -0
  745. package/src/device/DevicePool.ts +105 -23
  746. package/src/device/DeviceStateMapper.ts +418 -0
  747. package/src/device/DeviceStateProjector.ts +152 -0
  748. package/src/device/DeviceStateStore.ts +232 -0
  749. package/src/device/DeviceWalletSessionStore.ts +72 -6
  750. package/src/device/cloneDeviceState.ts +39 -0
  751. package/src/device/deviceIdentity.ts +18 -0
  752. package/src/deviceProfile/buildDeviceFeatures.ts +209 -191
  753. package/src/deviceProfile/index.ts +0 -1
  754. package/src/deviceProfile/protocolV2DeviceIdentity.ts +35 -0
  755. package/src/events/call.ts +0 -6
  756. package/src/events/core.ts +0 -2
  757. package/src/events/device.ts +22 -1
  758. package/src/events/iframe.ts +0 -1
  759. package/src/events/logBlockEvent.ts +93 -2
  760. package/src/events/ui-promise.ts +4 -2
  761. package/src/events/ui-request.ts +61 -4
  762. package/src/events/ui-response.ts +12 -2
  763. package/src/index.ts +17 -4
  764. package/src/inject.ts +89 -55
  765. package/src/lowLevelInject.ts +11 -7
  766. package/src/protocols/protocol-v2/deviceSession.ts +24 -0
  767. package/src/protocols/protocol-v2/features.ts +118 -52
  768. package/src/protocols/protocol-v2/firmware.ts +3 -1
  769. package/src/protocols/protocol-v2/index.ts +9 -3
  770. package/src/protocols/protocol-v2/resources.ts +171 -0
  771. package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +65 -0
  772. package/src/protocols/protocol-v2/uiInteraction.ts +250 -0
  773. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -0
  774. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +136 -0
  775. package/src/protocols/protocol-v2/walletSession.ts +420 -49
  776. package/src/topLevelInject.ts +11 -6
  777. package/src/types/api/checkAllFirmwareRelease.ts +72 -9
  778. package/src/types/api/checkBLEFirmwareRelease.ts +4 -13
  779. package/src/types/api/checkBootloaderRelease.ts +2 -6
  780. package/src/types/api/checkFirmwareRelease.ts +2 -13
  781. package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
  782. package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
  783. package/src/types/api/deviceSettings.ts +26 -2
  784. package/src/types/api/deviceUnlock.ts +13 -2
  785. package/src/types/api/deviceUpdateBootloader.ts +7 -0
  786. package/src/types/api/export.ts +33 -1
  787. package/src/types/api/firmwareUpdate.ts +85 -11
  788. package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
  789. package/src/types/api/firmwareUpdatePlan.ts +38 -0
  790. package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
  791. package/src/types/api/getDeviceState.ts +19 -0
  792. package/src/types/api/getFeatures.ts +3 -0
  793. package/src/types/api/getOnekeyFeatures.ts +3 -0
  794. package/src/types/api/getPassphraseState.ts +7 -0
  795. package/src/types/api/index.ts +43 -73
  796. package/src/types/api/kaspaSignTransaction.ts +60 -4
  797. package/src/types/api/openWalletSession.ts +54 -0
  798. package/src/types/api/protocolV2.ts +23 -188
  799. package/src/types/api/sessionCache.ts +9 -4
  800. package/src/types/device.ts +211 -9
  801. package/src/types/params.ts +9 -2
  802. package/src/types/settings.ts +52 -25
  803. package/src/utils/assets.ts +4 -1
  804. package/src/utils/deviceFeaturesCompat.ts +191 -0
  805. package/src/utils/deviceFeaturesUtils.ts +42 -9
  806. package/src/utils/deviceInfoUtils.ts +29 -69
  807. package/src/utils/deviceSettings.ts +181 -39
  808. package/src/utils/deviceVersionUtils.ts +25 -44
  809. package/src/utils/findDefectiveBatchDevice.ts +3 -3
  810. package/src/utils/homescreen.ts +40 -0
  811. package/src/utils/index.ts +26 -7
  812. package/src/utils/networkUtils.ts +274 -16
  813. package/src/utils/pro2Nft.ts +165 -0
  814. package/src/utils/pro2Wallpaper.ts +44 -25
  815. package/src/utils/tracing.ts +3 -1
  816. package/src/utils/uiProgressThrottle.ts +63 -0
  817. package/tsconfig.type-tests.json +12 -0
  818. package/__tests__/RequestQueue.test.ts +0 -34
  819. package/dist/api/GetDeviceInfo.d.ts +0 -9
  820. package/dist/api/GetDeviceInfo.d.ts.map +0 -1
  821. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  822. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  823. package/dist/api/protocol-v2/DeviceSessionGet.d.ts +0 -6
  824. package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +0 -1
  825. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +0 -6
  826. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +0 -1
  827. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +0 -16
  828. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +0 -1
  829. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +0 -12
  830. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +0 -1
  831. package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
  832. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
  833. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -9
  834. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  835. package/dist/types/api/getDeviceInfo.d.ts +0 -87
  836. package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
  837. package/src/api/GetDeviceInfo.ts +0 -145
  838. package/src/api/firmware/progressThrottle.ts +0 -44
  839. package/src/api/protocol-v2/DeviceSessionGet.ts +0 -15
  840. package/src/api/protocol-v2/DeviceSettingsGet.ts +0 -16
  841. package/src/api/protocol-v2/DeviceSettingsPageShow.ts +0 -59
  842. package/src/api/protocol-v2/DeviceSettingsSet.ts +0 -39
  843. package/src/deviceProfile/buildDeviceProfile.ts +0 -354
  844. package/src/protocols/protocol-v2/unlockRetry.ts +0 -46
  845. package/src/types/api/getDeviceInfo.ts +0 -101
@@ -1,8 +1,9 @@
1
1
  import EventEmitter from 'events';
2
2
  import semver from 'semver';
3
- import { Enum_Capability } from '@onekeyfe/hd-transport';
3
+ import { DeviceRebootType, DeviceSessionPinType, Enum_Capability } from '@onekeyfe/hd-transport';
4
4
  import {
5
5
  EDeviceType,
6
+ EFirmwareType,
6
7
  ERRORS,
7
8
  ERROR_CODES_REQUIRE_DISCONNECT,
8
9
  ERROR_CODES_REQUIRE_RELEASE,
@@ -12,30 +13,33 @@ import {
12
13
  createDeviceNotSupportMethodError,
13
14
  } from '@onekeyfe/hd-shared';
14
15
 
15
- import {
16
- LoggerNames,
17
- getDeviceBLEFirmwareVersion,
18
- getDeviceBleName,
19
- getDeviceFirmwareVersion,
20
- getDeviceLabel,
21
- getDeviceType,
22
- getDeviceUUID,
23
- getFirmwareType,
24
- getLogger,
25
- } from '../utils';
16
+ import { LoggerNames, getLogger } from '../utils';
26
17
  import {
27
18
  fixFeaturesFirmwareVersion,
28
19
  getPassphraseStateWithRefreshDeviceInfo,
29
- supportInputPinOnSoftware,
30
- supportModifyHomescreen,
31
20
  } from '../utils/deviceFeaturesUtils';
21
+ import { parseDeviceVersion } from '../utils/deviceVersionUtils';
32
22
  import { generateInstanceId } from '../utils/tracing';
33
23
  // eslint-disable-next-line import/no-cycle
34
24
  import { DeviceCommands } from './DeviceCommands';
25
+ import { mergeDeviceFeaturesPatch } from './DeviceFeaturesState';
26
+ import {
27
+ mapDeviceSettingsToState,
28
+ mapFeaturesToState,
29
+ mapProtocolV1OnekeyFeaturesToState,
30
+ mapProtocolV2DeviceInfoToState,
31
+ mapProtocolV2DeviceStatusToState,
32
+ } from './DeviceStateMapper';
33
+ import { projectFeatures } from './DeviceStateProjector';
34
+ import { DeviceStateStore, createPublicDeviceState } from './DeviceStateStore';
35
+ import { cloneDeviceState } from './cloneDeviceState';
35
36
  import { deviceWalletSessionStore } from './DeviceWalletSessionStore';
36
37
  import {
37
38
  type DeviceFirmwareRange,
38
39
  DeviceModelToTypes,
40
+ type DeviceStateEvent,
41
+ type DeviceStatePatch,
42
+ type DeviceStateUpdateSource,
39
43
  DeviceTypeToModels,
40
44
  type Device as DeviceTyped,
41
45
  EOneKeyDeviceMode,
@@ -50,24 +54,37 @@ import { DEVICE, UI_REQUEST } from '../events';
50
54
  import { DataManager } from '../data-manager';
51
55
  import TransportManager from '../data-manager/TransportManager';
52
56
  import { toHardened } from '../api/helpers/pathUtils';
53
- import { existCapability } from '../utils/capabilitieUtils';
54
57
  import {
55
- PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
58
+ PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE,
59
+ PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST,
60
+ PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST,
61
+ PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
62
+ type ProtocolV2RuntimeMode,
63
+ getProtocolV2RuntimeMode,
64
+ isLegacyProtocolV2ProtocolInfo,
56
65
  requestProtocolV2DeviceInfo,
66
+ requestProtocolV2DeviceStatus,
67
+ requestProtocolV2ProtocolInfo,
68
+ supportsProtocolV2Message,
57
69
  } from '../protocols/protocol-v2/features';
58
- import { buildProtocolV1FeaturesPayload, buildProtocolV2FeaturesPayload } from '../deviceProfile';
70
+ import { buildProtocolV1FeaturesPayload } from '../deviceProfile';
71
+ import { resolveProtocolV2DeviceIdentity } from '../deviceProfile/protocolV2DeviceIdentity';
59
72
 
60
73
  import type { PROTO } from '../constants';
74
+ import type { DeviceStateReadOptions } from '../types/api/getDeviceState';
61
75
  import type {
62
76
  DeviceButtonRequestPayload,
63
77
  DeviceFeaturesPayload,
78
+ HardwareUiInteractionMeta,
64
79
  PassphraseRequestPayload,
80
+ ProtocolV2UiEventMetadata,
65
81
  } from '../events';
66
82
  import type { PassphrasePromptResponse } from './DeviceCommands';
67
83
  import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
68
84
  import type {
69
85
  OneKeyDeviceInfo as DeviceDescriptor,
70
86
  DeviceStatus,
87
+ ProtocolInfo,
71
88
  ProtocolV2DeviceInfo,
72
89
  Success,
73
90
  } from '@onekeyfe/hd-transport';
@@ -79,7 +96,15 @@ export type InitOptions = {
79
96
  passphraseState?: string;
80
97
  deriveCardano?: boolean;
81
98
  connectProtocol?: HardwareConnectProtocol;
99
+ forceProtocolDetection?: boolean;
82
100
  protocolV2DeviceInfoTimeoutMs?: number;
101
+ /** Refresh Protocol V2 runtime state before returning discovery results. */
102
+ refreshRuntimeState?: boolean;
103
+ /**
104
+ * Protocol V1 Initialize response timeout override. Reboot-wait polling passes a
105
+ * short value so an unanswered probe settles before the next poll tick.
106
+ */
107
+ timeoutMs?: number;
83
108
  };
84
109
 
85
110
  export type RunOptions = {
@@ -94,11 +119,35 @@ const parseRunOptions = (options?: RunOptions): RunOptions => {
94
119
 
95
120
  const Log = getLogger(LoggerNames.Device);
96
121
 
122
+ const isProtocolV2DeviceStatusUnsupportedError = (error: unknown) => {
123
+ if (error instanceof HardwareError) {
124
+ if (error.errorCode === HardwareErrorCode.DeviceNotSupportMethod) {
125
+ return true;
126
+ }
127
+ if (error.params?.failureCode === 'Failure_UnexpectedMessage') {
128
+ return true;
129
+ }
130
+ }
131
+
132
+ const message =
133
+ error instanceof Error
134
+ ? error.message
135
+ : String((error as { message?: unknown } | null)?.message ?? error ?? '');
136
+ return (
137
+ /^Failure_UnexpectedMessage(?:,|\b)/i.test(message) ||
138
+ /\b(?:unsupported message|handler not registered|message handler not found)\b/i.test(message)
139
+ );
140
+ };
141
+
97
142
  export interface DeviceEvents {
98
143
  [DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
99
- [DEVICE.PASSPHRASE_ON_DEVICE]: [Device, ((response: any) => void)?];
144
+ [DEVICE.PIN_ON_DEVICE]: [Device, DeviceSessionPinType, ProtocolV2UiEventMetadata?];
145
+ [DEVICE.PIN_ON_DEVICE_COMPLETE]: [Device, HardwareUiInteractionMeta];
146
+ [DEVICE.PASSPHRASE_ON_DEVICE]: [Device, PassphraseRequestPayload?];
147
+ [DEVICE.ATTACH_PIN_ON_DEVICE]: [Device, PassphraseRequestPayload?];
100
148
  [DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
101
149
  [DEVICE.FEATURES]: [Device, DeviceFeaturesPayload];
150
+ [DEVICE.STATE]: [Device, DeviceStateEvent];
102
151
  [DEVICE.PASSPHRASE]: [
103
152
  Device,
104
153
  PassphraseRequestPayload,
@@ -128,7 +177,8 @@ export interface Device {
128
177
  * This allows short-lived processes (e.g. CLI) to restore a previously
129
178
  * obtained session, avoiding the need to re-enter passphrase on every
130
179
  * invocation. The session must have been obtained from a prior
131
- * getPassphraseState() call on the same device.
180
+ * wallet-session call on the same device. This compatibility hook is intended
181
+ * for a trusted CLI process restoring its own OS-keychain entry.
132
182
  *
133
183
  * @param deviceId - The device's device_id (from features)
134
184
  * @param passphraseState - The passphrase state token
@@ -185,25 +235,58 @@ export class Device extends EventEmitter {
185
235
  */
186
236
  private deviceAcquired = false;
187
237
 
188
- /**
189
- * 唯一设备状态缓存。
190
- *
191
- * V1 直接保存原生 Features;V2 保存由 DeviceInfoGet 映射出的
192
- * Features 视图。Device 不再保存 profile,结构化 DeviceProfile 只作为
193
- * getDeviceInfo() 的 API 返回值存在。
194
- */
195
- features: Features | undefined = undefined;
238
+ /** Canonical device-state cache; legacy Features is a compatibility projection. */
239
+ private stateStore = new DeviceStateStore();
196
240
 
197
- /**
198
- * 是否需要更新设备信息。
199
- *
200
- * 历史名称保留用于兼容现有调用语义;对 V2 表示 features 需要由
201
- * DeviceInfoGet 刷新。
202
- */
203
- featuresNeedsReload = false;
241
+ /** Force the next initialization to reload DeviceInfo after reconnect or reboot. */
242
+ private protocolV2StateNeedsReload = false;
243
+
244
+ /** Runtime context negotiated once per active Protocol V2 link. */
245
+ private protocolV2RuntimeContext?: ProtocolInfo;
246
+
247
+ /** Coalesces concurrent first-use runtime negotiation on the same active link. */
248
+ private protocolV2RuntimeContextPromise?: Promise<ProtocolInfo>;
249
+
250
+ /** Invalidates an in-flight runtime-context response without adding a transport epoch. */
251
+ private protocolV2RuntimeContextRequestToken?: object;
252
+
253
+ private protocolV2UiInteraction?: {
254
+ interactionId: string;
255
+ phaseCounter: number;
256
+ sequence: number;
257
+ opened: boolean;
258
+ };
259
+
260
+ private protocolV2UiInteractionCounter = 0;
261
+
262
+ get state() {
263
+ return this.stateStore.getState();
264
+ }
265
+
266
+ get features(): Features | undefined {
267
+ if (!this.state) return undefined;
268
+ return projectFeatures(this.state);
269
+ }
270
+
271
+ set features(features: Features | undefined) {
272
+ this.stateStore = new DeviceStateStore();
273
+ if (features) {
274
+ this.stateStore.update(mapFeaturesToState(features), 'compatibility');
275
+ const { passphraseState } = features;
276
+ const sessionId = features.sessionId ?? features.session_id;
277
+ const deviceKey = this.getSessionCacheDeviceKey(features.deviceId ?? undefined);
278
+ if (passphraseState && sessionId && deviceKey) {
279
+ this.passphraseState = passphraseState;
280
+ deviceWalletSessionStore.set(deviceKey, passphraseState, sessionId);
281
+ }
282
+ }
283
+ }
204
284
 
205
285
  runPromise?: Deferred<void> | null;
206
286
 
287
+ /** Resolves only after the active run has completed its release path. */
288
+ private runCleanupPromise?: Promise<void>;
289
+
207
290
  externalState: string[] = [];
208
291
 
209
292
  unavailableCapabilities: UnavailableCapabilities = {};
@@ -254,38 +337,46 @@ export class Device extends EventEmitter {
254
337
 
255
338
  // simplified object to pass via postMessage
256
339
  toMessageObject(): DeviceTyped | null {
257
- if (this.isUnacquired()) return null;
340
+ if (this.isUnacquired() || !this.features) return null;
258
341
 
259
342
  const env = DataManager.getSettings('env');
260
343
  const deviceType = this.getCurrentDeviceType();
261
344
 
262
345
  const bleName = this.getCurrentBleName();
263
- const label = this.getCurrentLabel();
346
+ const displayName = this.getCurrentDisplayName();
264
347
  const serialNo = this.getCurrentSerialNo();
265
348
  const connectId = this.getConnectId();
266
349
  const deviceId = this.getCurrentDeviceId() || null;
267
350
 
268
351
  const { features } = this;
352
+ const state = this.state ? createPublicDeviceState(this.state) : undefined;
269
353
 
270
354
  return {
271
- /** Android uses Mac address, iOS uses uuid, USB uses uuid */
355
+ /** Android uses a MAC address, while iOS and USB use transport-specific identifiers. */
272
356
  connectId: DataManager.isBleConnect(env) ? this.mainId || null : connectId,
273
- /** Hardware ID, will not change at any time */
357
+ /** Persist this after the first active probe so later calls do not need to guess. */
358
+ connectProtocol: this.originalDescriptor.protocolType,
359
+ /** Stable physical-device identity. */
360
+ serialNo,
361
+ /** @deprecated Use serialNo instead. */
274
362
  uuid: serialNo,
275
363
  commType: this.originalDescriptor.commType,
276
364
  sdkInstanceId: this.sdkInstanceId,
277
365
  instanceId: this.instanceId,
278
366
  createdAt: this.createdAt,
279
367
  deviceType,
280
- /** ID for current seeds, will clear after replace a new seed at device */
368
+ /** Wallet-lifecycle ID; changes after the device is wiped or reinitialized. */
281
369
  deviceId,
282
370
  path: this.originalDescriptor?.path,
283
371
  bleName,
284
- name: bleName || label || `OneKey ${deviceType?.toUpperCase()}`,
285
- label: label || 'OneKey',
372
+ name: bleName || displayName || `OneKey ${deviceType?.toUpperCase()}`,
373
+ // Keep the legacy top-level field string-compatible while preserving
374
+ // the canonical nullable value at state.identity.label.
375
+ label: displayName ?? '',
376
+ status: this.getStatus(),
286
377
  mode: this.getMode(),
287
378
  features,
288
- sessionId: this.features?.sessionId ?? null,
379
+ state,
289
380
  firmwareVersion: this.getFirmwareVersion(),
290
381
  bleFirmwareVersion: this.getBLEFirmwareVersion(),
291
382
  unavailableCapabilities: this.unavailableCapabilities,
@@ -296,13 +387,20 @@ export class Device extends EventEmitter {
296
387
  * Device connect
297
388
  * @returns {Promise<boolean>}
298
389
  */
299
- connect(connectProtocol?: HardwareConnectProtocol) {
390
+ connect(
391
+ connectProtocol?: HardwareConnectProtocol,
392
+ options?: { forceProtocolDetection?: boolean }
393
+ ) {
300
394
  const env = DataManager.getSettings('env');
301
395
  // eslint-disable-next-line no-async-promise-executor
302
396
  return new Promise<boolean>(async (resolve, reject) => {
303
397
  if (DataManager.isBleConnect(env)) {
398
+ if (this.hasDeviceAcquire() && this.commands && !this.commands.disposed) {
399
+ resolve(true);
400
+ return;
401
+ }
304
402
  try {
305
- await this.acquire(connectProtocol);
403
+ await this.acquire(connectProtocol, options);
306
404
  resolve(true);
307
405
  } catch (error) {
308
406
  reject(error);
@@ -312,7 +410,7 @@ export class Device extends EventEmitter {
312
410
  // 不存在 Session ID 或存在 Session ID 但设备在别处使用,都需要 acquire 获取最新 sessionID
313
411
  if (!this.mainId || (!this.isUsedHere() && this.originalDescriptor)) {
314
412
  try {
315
- await this.acquire(connectProtocol);
413
+ await this.acquire(connectProtocol, options);
316
414
  resolve(true);
317
415
  } catch (error) {
318
416
  reject(error);
@@ -328,25 +426,30 @@ export class Device extends EventEmitter {
328
426
  }
329
427
 
330
428
  async acquire(
331
- connectProtocol?: HardwareConnectProtocol,
332
- options?: { throwOnRunPromiseError?: boolean }
429
+ expectedProtocol?: HardwareConnectProtocol,
430
+ options?: { throwOnRunPromiseError?: boolean; forceProtocolDetection?: boolean }
333
431
  ) {
334
432
  const env = DataManager.getSettings('env');
335
433
  const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
336
- const expectedProtocol = connectProtocol ?? this.originalDescriptor.protocolType;
434
+ const previousProtocol = this.originalDescriptor.protocolType;
435
+ // A protocol stored after a successful probe is authoritative. Only the explicit
436
+ // first-connection/recovery path may bypass it and probe both protocols again.
437
+ const strictProtocol = options?.forceProtocolDetection
438
+ ? undefined
439
+ : expectedProtocol ?? this.originalDescriptor.protocolType;
337
440
  try {
338
441
  let acquireResult: unknown;
339
442
  if (DataManager.isBleConnect(env)) {
340
- // forceCleanRunPromise=true(自 e21b83c6 引入,修复 Pro2 BLE 重连):
341
- // acquire 意味着开启一个全新会话,transport 里残留的上一次 runPromise
342
- // 必然属于已死亡的会话(如固件升级重启、探测中断),不清理会让新会话的
343
- // 调用被旧 promise 卡死。无法在 Device 层面区分“重连恢复”与普通 acquire,
344
- // 因此对 BLE acquire 恒清理是有意为之。
443
+ // acquire starts a new BLE session. Any previous runPromise belongs to a dead
444
+ // session, such as an interrupted probe or firmware-update reboot, and would
445
+ // otherwise block the new session. Device cannot distinguish recovery from a
446
+ // regular acquire, so BLE always clears it intentionally.
345
447
  acquireResult = await this.deviceConnector?.acquire(
346
448
  this.originalDescriptor.id,
347
449
  undefined,
348
450
  true,
349
- expectedProtocol
451
+ strictProtocol,
452
+ undefined
350
453
  );
351
454
  this.mainId = (acquireResult as any)?.uuid ?? '';
352
455
  Log.debug('Expected uuid:', this.mainId);
@@ -355,30 +458,58 @@ export class Device extends EventEmitter {
355
458
  this.originalDescriptor.path,
356
459
  this.originalDescriptor.session,
357
460
  undefined,
358
- expectedProtocol
461
+ strictProtocol,
462
+ undefined
359
463
  );
360
464
  this.mainId = acquireResult as string | undefined;
361
465
  Log.debug('Expected session id:', this.mainId);
362
466
  }
363
- this.deviceAcquired = true;
364
- this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
365
-
366
467
  // Propagate protocol version detected during acquire.
367
468
  const detectedProtocol =
368
469
  (acquireResult as { protocolType?: HardwareConnectProtocol } | undefined)?.protocolType ??
369
470
  TransportManager.transport?.getProtocolType?.(
370
471
  DataManager.isBleConnect(env) ? this.originalDescriptor.id : this.originalDescriptor.path
371
472
  );
473
+ if (options?.forceProtocolDetection && !detectedProtocol) {
474
+ throw ERRORS.TypedError(
475
+ HardwareErrorCode.RuntimeError,
476
+ `Active protocol detection returned no protocol for ${
477
+ this.originalDescriptor.path || this.originalDescriptor.id
478
+ }`
479
+ );
480
+ }
372
481
  if (detectedProtocol) {
373
482
  this.originalDescriptor.protocolType = detectedProtocol;
374
483
  }
484
+ this.deviceAcquired = true;
485
+ this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
375
486
 
376
487
  if (this.commands) {
377
488
  await this.commands.dispose(false);
378
489
  }
379
490
 
380
491
  this.commands = new DeviceCommands(this, this.mainId ?? '');
492
+ // Protocol V2 runtime metadata belongs to one active transport link. A
493
+ // successful acquire creates a fresh link/session, so never carry cached
494
+ // ProtocolInfo or pre-initialize state across that boundary.
495
+ this.invalidateProtocolV2RuntimeState();
381
496
  } catch (error) {
497
+ if (options?.forceProtocolDetection) {
498
+ this.originalDescriptor.protocolType = previousProtocol;
499
+ const failedSession = this.mainId;
500
+ this.deviceAcquired = false;
501
+ if (failedSession) {
502
+ try {
503
+ await this.deviceConnector?.release?.(failedSession, false);
504
+ } catch (releaseError) {
505
+ Log.debug('Failed to release an unsuccessful protocol probe', releaseError);
506
+ }
507
+ }
508
+ if (!DataManager.isBleConnect(env)) {
509
+ this.mainId = null;
510
+ this.updateDescriptor({ session: null } as DeviceDescriptor);
511
+ }
512
+ }
382
513
  if (options?.throwOnRunPromiseError) {
383
514
  throw error;
384
515
  }
@@ -420,7 +551,8 @@ export class Device extends EventEmitter {
420
551
  }
421
552
  }
422
553
  try {
423
- await this.deviceConnector?.release(this.mainId, false);
554
+ // BLE releases even when keepSession is set, so forward the intent.
555
+ await this.deviceConnector?.release(this.mainId, false, this.keepSession);
424
556
  this.updateDescriptor({ session: null } as DeviceDescriptor);
425
557
  } catch (err) {
426
558
  Log.error('[Device] release error: ', err);
@@ -482,12 +614,11 @@ export class Device extends EventEmitter {
482
614
  }
483
615
 
484
616
  /**
485
- * 唯一协议判别器。
617
+ * Canonical protocol discriminator.
486
618
  *
487
- * descriptor.protocolType 是协议探测后的结果;V2 features DeviceInfoGet
488
- * 映射产生。
489
- * SDK 的协议分支都必须走这里,不要直接读 originalDescriptor.protocolType
490
- * 或从 features 反推。
619
+ * descriptor.protocolType is established by active probing; V2 features are mapped
620
+ * from DeviceInfoGet. All protocol branches must use this method instead of reading
621
+ * originalDescriptor.protocolType directly or inferring a protocol from features.
491
622
  */
492
623
  getProtocol(): 'V1' | 'V2' {
493
624
  return this.originalDescriptor.protocolType === 'V2' ? 'V2' : 'V1';
@@ -498,53 +629,75 @@ export class Device extends EventEmitter {
498
629
  }
499
630
 
500
631
  getCurrentDeviceType() {
501
- return getDeviceType(this.features);
632
+ return this.state?.identity.deviceType ?? EDeviceType.Unknown;
502
633
  }
503
634
 
504
635
  getCurrentDeviceId() {
505
- return this.features?.deviceId || undefined;
636
+ return this.state?.identity.deviceId || undefined;
506
637
  }
507
638
 
508
639
  getCurrentSerialNo() {
509
- return this.features ? getDeviceUUID(this.features) : '';
640
+ return this.state?.identity.serialNo ?? '';
510
641
  }
511
642
 
512
643
  getConnectId() {
513
644
  const serialNo = this.getCurrentSerialNo();
514
645
  if (serialNo) return serialNo;
515
646
 
516
- // connectId SDK 内部连接路由 key。这里兜底到 transport descriptor
517
- // 不改变 features.serialNo / deviceId 的业务语义。
647
+ // connectId is an internal routing key. Falling back to the transport descriptor
648
+ // does not change the business meaning of features.serialNo or deviceId.
518
649
  return this.originalDescriptor.path || this.originalDescriptor.id || '';
519
650
  }
520
651
 
521
652
  getCurrentBleName() {
522
- return getDeviceBleName(this.features);
653
+ return this.state?.identity.bleName ?? null;
523
654
  }
524
655
 
525
656
  getCurrentLabel() {
526
- return getDeviceLabel(this.features);
657
+ return this.state?.identity.label ?? null;
658
+ }
659
+
660
+ getCurrentDisplayName() {
661
+ if (!this.state) return null;
662
+
663
+ const label = this.getCurrentLabel();
664
+ if (label) return label;
665
+
666
+ const bleName = this.getCurrentBleName();
667
+ if (bleName) return bleName;
668
+
669
+ const deviceType = this.getCurrentDeviceType();
670
+ if (deviceType === EDeviceType.ClassicPure) {
671
+ return 'OneKey Classic 1S';
672
+ }
673
+
674
+ return `OneKey ${deviceType.charAt(0).toUpperCase() + deviceType.slice(1)}`;
527
675
  }
528
676
 
529
677
  getCurrentPassphraseProtection() {
530
- return this.features?.passphraseProtection;
678
+ return this.state?.status.passphraseProtection;
531
679
  }
532
680
 
533
681
  getCurrentFirmwareType() {
534
- return getFirmwareType(this.features);
682
+ return this.state?.identity.firmwareType ?? EFirmwareType.Universal;
535
683
  }
536
684
 
537
685
  getCurrentFirmwareVersionString() {
538
- return getDeviceFirmwareVersion(this.features)?.join('.');
686
+ return parseDeviceVersion(this.state?.versions.firmware).join('.');
539
687
  }
540
688
 
541
689
  getCurrentBLEFirmwareVersionString() {
542
- if (!this.features) return undefined;
543
- return getDeviceBLEFirmwareVersion(this.features).join('.');
690
+ if (!this.state) return undefined;
691
+ return parseDeviceVersion(this.state.versions.ble).join('.');
692
+ }
693
+
694
+ getCurrentBootloaderVersionString() {
695
+ if (!this.state) return undefined;
696
+ return parseDeviceVersion(this.state.versions.bootloader).join('.');
544
697
  }
545
698
 
546
699
  getCurrentSafetyChecks() {
547
- return this.features?.safetyChecks;
700
+ return this.state?.settings.safetyChecks;
548
701
  }
549
702
 
550
703
  getCurrentMethodVersionRange(
@@ -557,6 +710,7 @@ export class Device extends EventEmitter {
557
710
  // Most-specific model first; must match getMethodVersionRange in deviceInfoUtils,
558
711
  // otherwise e.g. Classic1s resolves the looser model_mini range before model_classic1s.
559
712
  const modelFallbacks: IDeviceModel[] = [
713
+ 'model_pro2',
560
714
  'model_classic1s',
561
715
  'model_classic',
562
716
  'model_mini',
@@ -576,7 +730,8 @@ export class Device extends EventEmitter {
576
730
  if (
577
731
  deviceType === EDeviceType.Touch ||
578
732
  deviceType === EDeviceType.Pro ||
579
- deviceType === EDeviceType.Pro2
733
+ deviceType === EDeviceType.Pro2 ||
734
+ deviceType === EDeviceType.Neo
580
735
  ) {
581
736
  return { support: true };
582
737
  }
@@ -589,13 +744,12 @@ export class Device extends EventEmitter {
589
744
  }
590
745
 
591
746
  supportInputPinOnSoftware(): SupportFeatureType {
592
- if (this.features) return supportInputPinOnSoftware(this.features);
593
-
594
747
  const deviceType = this.getCurrentDeviceType();
595
748
  if (
596
749
  deviceType === EDeviceType.Touch ||
597
750
  deviceType === EDeviceType.Pro ||
598
- deviceType === EDeviceType.Pro2
751
+ deviceType === EDeviceType.Pro2 ||
752
+ deviceType === EDeviceType.Neo
599
753
  ) {
600
754
  return { support: false };
601
755
  }
@@ -608,15 +762,12 @@ export class Device extends EventEmitter {
608
762
  }
609
763
 
610
764
  supportModifyHomescreen(): SupportFeatureType {
611
- // Pro2 走独立 1.x 版本线,不能套用 Touch/Pro 3.4.0 门槛(恒 false 且未来会误判)。
612
- // 依据:firmware-pro2 协议 schema(messages-protocol-v2.json)的 ApplySettings
613
- // 包含 homescreen 字段,V2 固件从首个版本即支持修改主屏。
765
+ // Pro2 has an independent 1.x version line and must not use the Touch/Pro 3.4.0
766
+ // threshold. ApplySettings includes homescreen from the first V2 firmware version.
614
767
  if (this.isProtocolV2()) {
615
768
  return { support: true };
616
769
  }
617
770
 
618
- if (this.features) return supportModifyHomescreen(this.features);
619
-
620
771
  const deviceType = this.getCurrentDeviceType();
621
772
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
622
773
  return { support: true };
@@ -632,17 +783,25 @@ export class Device extends EventEmitter {
632
783
  const deviceId = _deviceId || this.getCurrentDeviceId();
633
784
  if (deviceId) return deviceId;
634
785
  if (this.isProtocolV2()) {
635
- return this.originalDescriptor.path || this.originalDescriptor.id;
786
+ return this.originalDescriptor.path;
636
787
  }
637
788
  return undefined;
638
789
  }
639
790
 
791
+ private reconcileSessionCacheDeviceIdentity(previousDeviceId?: string) {
792
+ deviceWalletSessionStore.reconcileDeviceIdentity({
793
+ temporaryKey: this.isProtocolV2() ? this.originalDescriptor.path : undefined,
794
+ previousDeviceId,
795
+ nextDeviceId: this.getCurrentDeviceId(),
796
+ });
797
+ }
798
+
640
799
  getInternalState(_deviceId?: string) {
641
800
  Log.debug(
642
801
  'getInternalState session param: ',
643
802
  `device_id: ${_deviceId}`,
644
- `features.deviceId: ${this.features?.deviceId}`,
645
- `passphraseState: ${this.passphraseState}`
803
+ `currentDeviceId: ${this.getCurrentDeviceId()}`,
804
+ `hasPassphraseState: ${Boolean(this.passphraseState)}`
646
805
  );
647
806
 
648
807
  const deviceId = this.getSessionCacheDeviceKey(_deviceId);
@@ -658,19 +817,26 @@ export class Device extends EventEmitter {
658
817
  return deviceWalletSessionStore.get(deviceId, this.passphraseState);
659
818
  }
660
819
 
820
+ getStandardInternalState(_deviceId?: string) {
821
+ const deviceId = this.getSessionCacheDeviceKey(_deviceId);
822
+ if (!deviceId) return undefined;
823
+ return deviceWalletSessionStore.getStandard(deviceId);
824
+ }
825
+
661
826
  // attach to pin to fix internal state
662
827
  updateInternalState(
663
828
  enablePassphrase: boolean,
664
829
  passphraseState: string | undefined,
665
830
  deviceId: string | undefined,
666
831
  sessionId: string | null = null,
667
- featuresSessionId: string | null = null
832
+ featuresSessionId: string | null = null,
833
+ walletType: 'standard' | 'hidden' = 'hidden'
668
834
  ) {
669
835
  Log.debug(
670
836
  'updateInternalState session param: ',
671
837
  `device_id: ${deviceId}`,
672
838
  `enablePassphrase: ${enablePassphrase}`,
673
- `passphraseState: ${passphraseState}`,
839
+ `hasPassphraseState: ${Boolean(passphraseState)}`,
674
840
  `hasSessionId: ${Boolean(sessionId)}`,
675
841
  `hasFeaturesSessionId: ${Boolean(featuresSessionId)}`
676
842
  );
@@ -681,7 +847,15 @@ export class Device extends EventEmitter {
681
847
  if (enablePassphrase) {
682
848
  const walletSessionId =
683
849
  sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
684
- deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
850
+ if (walletType === 'standard') {
851
+ deviceWalletSessionStore.setStandard(
852
+ cacheDeviceKey,
853
+ passphraseState,
854
+ walletSessionId ?? undefined
855
+ );
856
+ } else {
857
+ deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
858
+ }
685
859
  }
686
860
 
687
861
  deviceWalletSessionStore.deletePending(cacheDeviceKey);
@@ -692,8 +866,8 @@ export class Device extends EventEmitter {
692
866
  'setInternalState session param: ',
693
867
  `hasState: ${Boolean(state)}`,
694
868
  `initSession: ${initSession}`,
695
- `deviceId: ${this.features?.deviceId}`,
696
- `passphraseState: ${this.passphraseState}`
869
+ `deviceId: ${this.getCurrentDeviceId()}`,
870
+ `hasPassphraseState: ${Boolean(this.passphraseState)}`
697
871
  );
698
872
 
699
873
  if (!this.passphraseState && !initSession) return;
@@ -720,61 +894,73 @@ export class Device extends EventEmitter {
720
894
  }
721
895
  }
722
896
 
897
+ clearStandardInternalState(_deviceId?: string) {
898
+ const deviceId = this.getSessionCacheDeviceKey(_deviceId);
899
+ if (!deviceId) return;
900
+ deviceWalletSessionStore.deleteStandard(deviceId);
901
+ }
902
+
723
903
  async initialize(options?: InitOptions) {
724
- // Protocol V2 不支持传统 Initialize,直接使用协议专用初始化流程。
904
+ // Protocol V2 does not support legacy Initialize; use its dedicated flow.
725
905
  if (this.isProtocolV2()) {
726
906
  this.passphraseState = options?.passphraseState;
727
- if (this.features && !this.featuresNeedsReload && !options?.initSession) {
728
- if (this.features.bootloaderMode) {
907
+ if (this.state && !options?.initSession && !this.protocolV2StateNeedsReload) {
908
+ if (this.state.status.mode === 'bootloader' || this.state.status.mode === 'romloader') {
729
909
  return;
730
910
  }
731
- // 不能直接信任缓存 features:设备端 wipe / 完成初始化 / label
732
- // features 会永久陈旧。每次 run 做一次轻量 status 刷新(不含 fw/SE),
733
- // 用字段级合并保留已有版本和 SE 信息。
734
- await this._refreshProtocolV2Status(options);
911
+ // Normal calls reuse the cache. Explicit getDeviceState refreshes, unlock flow,
912
+ // and device events update dynamic state without polling on every SDK call.
735
913
  return;
736
914
  }
737
915
  await this._initializeProtocolV2(options);
916
+ this.protocolV2StateNeedsReload = false;
738
917
  return;
739
918
  }
740
919
 
741
- // Log.debug('initialize param:', options);
920
+ try {
921
+ const callInitialize = async (payload: Record<string, unknown>, initSession?: boolean) => {
922
+ const initStartAt = Date.now();
923
+ const { message } = await this.commands.typedCall('Initialize', 'Features', payload, {
924
+ // iOS BLE bound devices can need close to 20 seconds.
925
+ timeoutMs: options?.timeoutMs ?? 25 * 1000,
926
+ });
927
+ this.setLastInitializeDuration(Date.now() - initStartAt);
928
+ this._updateFeatures(message, initSession);
929
+ await TransportManager.reconfigure(this.features);
930
+ };
742
931
 
743
- this.passphraseState = options?.passphraseState;
932
+ const expectedDeviceId = options?.deviceId;
933
+ if (expectedDeviceId) {
934
+ // 先只读校验物理设备身份;钱包上下文仍由下方携带完整参数的
935
+ // Initialize 选择,避免标准钱包请求复用此前的隐藏钱包上下文。
936
+ this.passphraseState = undefined;
937
+ const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
938
+ this._updateFeatures(message);
939
+ await TransportManager.reconfigure(this.features);
940
+ if (!this.checkDeviceId(expectedDeviceId)) {
941
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
942
+ }
943
+ }
744
944
 
745
- if (options?.initSession) {
746
- this.clearInternalState(options?.deviceId);
747
- }
945
+ this.passphraseState = options?.passphraseState;
748
946
 
749
- const internalState = this.getInternalState(options?.deviceId);
750
- const payload: any = {};
751
- if (internalState) {
752
- payload.session_id = internalState;
753
- }
947
+ if (options?.initSession) {
948
+ this.clearInternalState(options?.deviceId);
949
+ }
754
950
 
755
- if (options?.deriveCardano) {
756
- payload.derive_cardano = true;
757
- }
758
- payload.passphrase_state = options?.passphraseState;
759
- payload.is_contains_attach = true;
951
+ const internalState = this.getInternalState(options?.deviceId);
952
+ const payload: Record<string, unknown> = {
953
+ passphrase_state: options?.passphraseState,
954
+ is_contains_attach: true,
955
+ };
956
+ if (internalState) {
957
+ payload.session_id = internalState;
958
+ }
959
+ if (options?.deriveCardano) {
960
+ payload.derive_cardano = true;
961
+ }
760
962
 
761
- const initStartAt = Date.now();
762
- try {
763
- // @ts-expect-error
764
- const { message } = await Promise.race([
765
- this.commands.typedCall('Initialize', 'Features', payload),
766
- new Promise((_, reject) => {
767
- setTimeout(() => {
768
- reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
769
- // iOS ble bound device timeout 20s
770
- }, 25 * 1000);
771
- }),
772
- ]);
773
-
774
- const initCostMs = Date.now() - initStartAt;
775
- this.setLastInitializeDuration(initCostMs);
776
- this._updateFeatures(message, options?.initSession);
777
- await TransportManager.reconfigure(this.features);
963
+ await callInitialize(payload, options?.initSession);
778
964
  } catch (error) {
779
965
  Log.error('Initialization failed:', error);
780
966
  throw error;
@@ -784,59 +970,34 @@ export class Device extends EventEmitter {
784
970
  /**
785
971
  * Device initialization over Protocol V2.
786
972
  *
787
- * Protocol V2 不走传统 Initialize/GetFeatures;直接用 DeviceInfoGet
788
- * 生成唯一的 features 状态。
973
+ * Protocol V2 bypasses legacy Initialize/GetFeatures and builds its canonical
974
+ * features state directly from DeviceInfoGet.
789
975
  */
790
976
  private async _initializeProtocolV2(options?: InitOptions) {
791
977
  Log.debug('Initialize device via Protocol V2 features adapter');
792
978
 
793
979
  try {
794
- // 超时由 requestProtocolV2DeviceInfo 内部的 typedCall timeoutMs(默认 10s)负责,
795
- // 不再额外包一层 Promise.race:外层 race timer 不会清理,
796
- // 且 reject 后底层调用仍会残留。
980
+ // typedCall applies the request timeout. An outer Promise.race would leak its
981
+ // timer and leave the underlying call active after rejection.
797
982
  const deviceInfo = await requestProtocolV2DeviceInfo({
798
983
  commands: this.commands,
799
984
  timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
800
985
  });
801
- // 默认请求不含 SE/hash 数据,scope 如实标注为 basic
802
- // 完整数据由 getDeviceInfo(scope:'verify'|'full') 获取。
803
- const features = this.updateProtocolV2Features(deviceInfo);
804
- Log.debug('Protocol V2 features:', features);
805
- this.featuresNeedsReload = false;
986
+ // The default request excludes SE/hash data and therefore uses basic scope.
987
+ // Full version and verification data require getDeviceState({ scope: 'firmware' }).
988
+ await this.probeProtocolV2RuntimeState(deviceInfo, options?.protocolV2DeviceInfoTimeoutMs);
806
989
  } catch (error) {
807
990
  Log.error('Protocol V2 initialization failed:', error);
808
991
  throw error;
809
992
  }
810
993
  }
811
994
 
812
- /**
813
- * Protocol V2 的轻量状态刷新(每次 run 前调用)。
814
- *
815
- * 请求 hw + coprocessor + status(不含 fw/SE target):status 提供 init_states / label /
816
- * passphrase_enabled 等会在设备端变化的字段;hw/coprocessor 提供 serialNo / bleName。
817
- * versions 为空时按字段级合并保留旧值,verify 数据不会被降级。
818
- */
819
- private async _refreshProtocolV2Status(options?: InitOptions) {
820
- try {
821
- const deviceInfo = await requestProtocolV2DeviceInfo({
822
- commands: this.commands,
823
- request: PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
824
- timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
825
- });
826
- const features = this.updateProtocolV2Features(deviceInfo);
827
- Log.debug('Protocol V2 features (status refresh):', features);
828
- } catch (error) {
829
- Log.error('Protocol V2 status refresh failed:', error);
830
- throw error;
831
- }
832
- }
833
-
834
995
  async getFeatures() {
835
996
  if (this.isProtocolV2()) {
836
997
  const deviceInfo = await requestProtocolV2DeviceInfo({
837
998
  commands: this.commands,
838
999
  });
839
- return this.updateProtocolV2Features(deviceInfo);
1000
+ return this.probeProtocolV2RuntimeState(deviceInfo);
840
1001
  }
841
1002
 
842
1003
  const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
@@ -844,61 +1005,355 @@ export class Device extends EventEmitter {
844
1005
  return this.features;
845
1006
  }
846
1007
 
1008
+ async getDeviceState(params: DeviceStateReadOptions = {}) {
1009
+ const refresh = new Set(params.refreshSections ?? []);
1010
+ const getProtocolV2DeviceInfoRequest = () => {
1011
+ if (refresh.has('verification')) return PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST;
1012
+ if (refresh.has('versions')) return PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST;
1013
+ return PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST;
1014
+ };
1015
+ let initializedWithDeviceInfo = false;
1016
+ let refreshedDeviceInfo: ProtocolV2DeviceInfo | undefined;
1017
+
1018
+ if (!this.state) {
1019
+ if (this.isProtocolV2()) {
1020
+ const deviceInfo = await requestProtocolV2DeviceInfo({
1021
+ commands: this.commands,
1022
+ request: getProtocolV2DeviceInfoRequest(),
1023
+ });
1024
+ await this.probeProtocolV2RuntimeState(deviceInfo);
1025
+ refreshedDeviceInfo = deviceInfo;
1026
+ initializedWithDeviceInfo = true;
1027
+ } else {
1028
+ await this.getFeatures();
1029
+ }
1030
+ } else if (!this.isProtocolV2() && refresh.size > 0) {
1031
+ await this.getFeatures();
1032
+ }
1033
+
1034
+ const supportsProtocolV1OnekeyFeatures =
1035
+ this.getCurrentDeviceType() === EDeviceType.Touch ||
1036
+ this.getCurrentDeviceType() === EDeviceType.Pro;
1037
+ if (!this.isProtocolV2() && refresh.has('verification') && supportsProtocolV1OnekeyFeatures) {
1038
+ const { message } = await this.commands.typedCall('OnekeyGetFeatures', 'OnekeyFeatures');
1039
+ this.updateState(mapProtocolV1OnekeyFeaturesToState(message), 'device-info');
1040
+ }
1041
+
1042
+ if (this.isProtocolV2()) {
1043
+ const refreshDeviceInfo =
1044
+ refresh.has('identity') || refresh.has('versions') || refresh.has('verification');
1045
+ if (refreshDeviceInfo && !initializedWithDeviceInfo) {
1046
+ const deviceInfo = await requestProtocolV2DeviceInfo({
1047
+ commands: this.commands,
1048
+ request: getProtocolV2DeviceInfoRequest(),
1049
+ });
1050
+ refreshedDeviceInfo = deviceInfo;
1051
+ if (!refresh.has('status')) {
1052
+ this.updateState(
1053
+ mapProtocolV2DeviceInfoToState(deviceInfo, this.state?.status.mode),
1054
+ 'device-info'
1055
+ );
1056
+ }
1057
+ }
1058
+
1059
+ if (refresh.has('status') && !initializedWithDeviceInfo) {
1060
+ const cachedMode = this.state?.status.mode;
1061
+ await this.probeProtocolV2RuntimeState(refreshedDeviceInfo, undefined, {
1062
+ // Loader firmware does not support DeviceStatusGet. Renegotiate ProtocolInfo
1063
+ // during an explicit refresh so a device rebooted into application firmware
1064
+ // can leave the cached loader state.
1065
+ forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader',
1066
+ });
1067
+ }
1068
+
1069
+ if (refresh.has('settings') && this.state?.status.mode === 'normal') {
1070
+ const { message } = await this.commands.typedCall(
1071
+ 'DeviceSettingsGet',
1072
+ 'DeviceSettings',
1073
+ {}
1074
+ );
1075
+ this.updateState(mapDeviceSettingsToState(message), 'settings-read');
1076
+ }
1077
+ }
1078
+
1079
+ if (!this.state) {
1080
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed);
1081
+ }
1082
+ return params.includeRaw ? cloneDeviceState(this.state) : createPublicDeviceState(this.state);
1083
+ }
1084
+
1085
+ async refreshProtocolV2SettingsAfterMutation() {
1086
+ return this.getDeviceState({ refreshSections: ['status', 'settings'] });
1087
+ }
1088
+
847
1089
  _updateFeatures(protoFeatures: PROTO.Features | Features, initSession?: boolean) {
848
- const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
1090
+ const previousDeviceId = this.getCurrentDeviceId();
849
1091
  let feat =
850
1092
  'protocol' in protoFeatures
851
1093
  ? protoFeatures
852
1094
  : buildProtocolV1FeaturesPayload(protoFeatures, this.features);
853
1095
 
854
- // GetFeatures doesn't return 'session_id'
855
- if (this.features?.sessionId && !feat.sessionId) {
856
- feat.sessionId = this.features.sessionId;
857
- }
858
1096
  feat.unlocked = feat.unlocked ?? true;
859
1097
 
860
1098
  feat = fixFeaturesFirmwareVersion(feat);
861
1099
 
862
- this.features = feat;
863
- const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
864
- if (previousCacheDeviceKey && nextCacheDeviceKey) {
865
- deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
866
- }
1100
+ this.updateState(mapFeaturesToState(feat), 'initialize');
1101
+ this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
867
1102
  if (feat.deviceId && feat.sessionId) {
868
1103
  this.setInternalState(feat.sessionId, initSession);
869
1104
  }
870
- this.featuresNeedsReload = false;
871
- this.emit(DEVICE.FEATURES, this, feat);
872
1105
  }
873
1106
 
874
- updateProtocolV2Features(deviceInfo?: ProtocolV2DeviceInfo) {
875
- const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
876
- const features = fixFeaturesFirmwareVersion(
877
- buildProtocolV2FeaturesPayload(deviceInfo, this.features)
878
- );
879
- this.features = features;
880
- const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
881
- if (previousCacheDeviceKey && nextCacheDeviceKey) {
882
- deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
1107
+ updateState(patch: DeviceStatePatch, source: DeviceStateUpdateSource) {
1108
+ const result = this.stateStore.update(patch, source);
1109
+ if (result.changedKeys.length === 0) return result.state;
1110
+
1111
+ const event: DeviceStateEvent = {
1112
+ connectId: this.getConnectId() ?? null,
1113
+ state: createPublicDeviceState(result.state),
1114
+ revision: result.revision,
1115
+ source,
1116
+ changedKeys: result.changedKeys,
1117
+ };
1118
+ Log.debug('Device state updated', {
1119
+ source,
1120
+ revision: result.revision,
1121
+ changedKeyCount: result.changedKeys.length,
1122
+ });
1123
+ this.emit(DEVICE.STATE, this, event);
1124
+ if (result.state.protocol === 'V1') {
1125
+ this.emit(DEVICE.FEATURES, this, projectFeatures(result.state));
883
1126
  }
884
- this.featuresNeedsReload = false;
885
- this.emit(DEVICE.FEATURES, this, features);
886
- return features;
1127
+ return result.state;
1128
+ }
1129
+
1130
+ updateFeaturesPatch(patch: Partial<Features>, source: DeviceStateUpdateSource) {
1131
+ const currentFeatures = this.features;
1132
+ if (!currentFeatures) return undefined;
1133
+
1134
+ const features = mergeDeviceFeaturesPatch(currentFeatures, patch);
1135
+ if (features === currentFeatures) return currentFeatures;
1136
+
1137
+ const normalized = fixFeaturesFirmwareVersion(features);
1138
+ this.updateState(mapFeaturesToState(normalized), source);
1139
+ return this.features;
1140
+ }
1141
+
1142
+ async ensureProtocolV2RuntimeContext(
1143
+ timeoutMs?: number,
1144
+ options?: { forceRefresh?: boolean }
1145
+ ): Promise<ProtocolInfo> {
1146
+ const cachedProtocolInfo =
1147
+ options?.forceRefresh === true
1148
+ ? undefined
1149
+ : this.protocolV2RuntimeContext ??
1150
+ (!this.protocolV2StateNeedsReload
1151
+ ? this.state?.raw?.protocolV2ProtocolInfo ?? undefined
1152
+ : undefined);
1153
+ if (cachedProtocolInfo) {
1154
+ this.protocolV2RuntimeContext = cachedProtocolInfo;
1155
+ return cachedProtocolInfo;
1156
+ }
1157
+
1158
+ if (this.protocolV2RuntimeContextPromise) {
1159
+ return this.protocolV2RuntimeContextPromise;
1160
+ }
1161
+
1162
+ const requestToken = {};
1163
+ const pendingRequest = (async () => {
1164
+ const protocolInfo = await requestProtocolV2ProtocolInfo({
1165
+ commands: this.commands,
1166
+ timeoutMs,
1167
+ });
1168
+ if (this.protocolV2RuntimeContextRequestToken !== requestToken) {
1169
+ throw ERRORS.TypedError(
1170
+ HardwareErrorCode.DeviceInitializeFailed,
1171
+ 'Protocol V2 runtime context was invalidated while loading.'
1172
+ );
1173
+ }
1174
+ this.protocolV2RuntimeContext = protocolInfo;
1175
+ return protocolInfo;
1176
+ })();
1177
+ this.protocolV2RuntimeContextRequestToken = requestToken;
1178
+ this.protocolV2RuntimeContextPromise = pendingRequest;
1179
+
1180
+ try {
1181
+ return await pendingRequest;
1182
+ } finally {
1183
+ if (this.protocolV2RuntimeContextPromise === pendingRequest) {
1184
+ this.protocolV2RuntimeContextPromise = undefined;
1185
+ }
1186
+ if (this.protocolV2RuntimeContextRequestToken === requestToken) {
1187
+ this.protocolV2RuntimeContextRequestToken = undefined;
1188
+ }
1189
+ }
1190
+ }
1191
+
1192
+ async probeProtocolV2RuntimeState(
1193
+ deviceInfo?: ProtocolV2DeviceInfo,
1194
+ timeoutMs?: number,
1195
+ options?: {
1196
+ forceRuntimeContextRefresh?: boolean;
1197
+ }
1198
+ ) {
1199
+ const protocolInfo = await this.ensureProtocolV2RuntimeContext(timeoutMs, {
1200
+ forceRefresh: options?.forceRuntimeContextRefresh,
1201
+ });
1202
+ const runtimeDeviceInfo = deviceInfo ?? this.state?.raw?.protocolV2DeviceInfo;
1203
+ const runtimeMode = getProtocolV2RuntimeMode(protocolInfo, runtimeDeviceInfo);
1204
+ const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
1205
+ const protocolV2DeviceType = runtimeDeviceInfo
1206
+ ? resolveProtocolV2DeviceIdentity(runtimeDeviceInfo.hw?.Device_type).deviceType
1207
+ : this.getCurrentDeviceType();
1208
+ if (
1209
+ runtimeMode === 'romloader' &&
1210
+ protocolV2DeviceType !== EDeviceType.Pro2 &&
1211
+ protocolV2DeviceType !== EDeviceType.Neo
1212
+ ) {
1213
+ throw ERRORS.TypedError(
1214
+ HardwareErrorCode.DeviceInitializeFailed,
1215
+ 'Protocol V2 romloader mode is only supported for Pro2 and Neo.'
1216
+ );
1217
+ }
1218
+ const deviceStatusSupported =
1219
+ legacyProtocolInfo ||
1220
+ supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
1221
+
1222
+ if (runtimeMode === 'bootloader' || runtimeMode === 'romloader') {
1223
+ return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
1224
+ }
1225
+
1226
+ if (!deviceStatusSupported) {
1227
+ if (runtimeMode === 'normal') {
1228
+ return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
1229
+ }
1230
+ throw ERRORS.TypedError(
1231
+ HardwareErrorCode.DeviceInitializeFailed,
1232
+ `Unknown Protocol V2 build fingerprint without DeviceStatusGet capability: ${protocolInfo.build_fingerprint}`
1233
+ );
1234
+ }
1235
+
1236
+ let deviceStatus: DeviceStatus;
1237
+ try {
1238
+ deviceStatus = await requestProtocolV2DeviceStatus({
1239
+ commands: this.commands,
1240
+ timeoutMs,
1241
+ });
1242
+ } catch (error) {
1243
+ if (runtimeMode === undefined && isProtocolV2DeviceStatusUnsupportedError(error)) {
1244
+ return this.updateProtocolV2Features(deviceInfo, null, 'bootloader', protocolInfo);
1245
+ }
1246
+ throw error;
1247
+ }
1248
+ return this.updateProtocolV2Features(deviceInfo, deviceStatus, 'normal', protocolInfo);
1249
+ }
1250
+
1251
+ updateProtocolV2Features(
1252
+ deviceInfo?: ProtocolV2DeviceInfo,
1253
+ deviceStatus?: DeviceStatus | null,
1254
+ runtimeMode?: ProtocolV2RuntimeMode,
1255
+ protocolInfo?: ProtocolInfo
1256
+ ) {
1257
+ const previousDeviceId = this.getCurrentDeviceId();
1258
+ const resolvedMode = runtimeMode ?? (deviceStatus ? 'normal' : this.state?.status.mode);
1259
+ if (deviceInfo) {
1260
+ this.updateState(mapProtocolV2DeviceInfoToState(deviceInfo, resolvedMode), 'device-info');
1261
+ }
1262
+ if (protocolInfo) {
1263
+ this.updateState({ raw: { protocolV2ProtocolInfo: protocolInfo } }, 'device-info');
1264
+ }
1265
+ if (deviceStatus) {
1266
+ this.updateState(mapProtocolV2DeviceStatusToState(deviceStatus), 'device-status');
1267
+ }
1268
+ this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
1269
+ return this.features as Features;
887
1270
  }
888
1271
 
889
1272
  updateProtocolV2Status(status: DeviceStatus) {
890
- const previousDeviceInfo = this.features?.raw?.protocolV2DeviceInfo;
891
- const previousStatus = previousDeviceInfo?.status;
892
- return this.updateProtocolV2Features({
893
- ...(previousDeviceInfo ?? {}),
894
- protocol_version: previousDeviceInfo?.protocol_version ?? this.features?.protocolVersion ?? 2,
895
- status: {
896
- ...previousStatus,
897
- ...status,
898
- },
1273
+ const previousDeviceInfo = this.state?.raw?.protocolV2DeviceInfo;
1274
+ const previousStatus = this.state?.raw?.protocolV2DeviceStatus;
1275
+ return this.updateProtocolV2Features(previousDeviceInfo, {
1276
+ ...previousStatus,
1277
+ ...status,
899
1278
  });
900
1279
  }
901
1280
 
1281
+ private invalidateProtocolV2RuntimeState() {
1282
+ if (!this.isProtocolV2()) return;
1283
+ this.protocolV2StateNeedsReload = true;
1284
+ this.protocolV2RuntimeContext = undefined;
1285
+ this.protocolV2RuntimeContextPromise = undefined;
1286
+ this.protocolV2RuntimeContextRequestToken = undefined;
1287
+ this.clearPreInitialized();
1288
+ }
1289
+
1290
+ markTransportDisconnected() {
1291
+ this.deviceAcquired = false;
1292
+ this.invalidateProtocolV2RuntimeState();
1293
+ }
1294
+
1295
+ invalidateAfterWipe() {
1296
+ const deviceId = this.getCurrentDeviceId();
1297
+ if (deviceId) {
1298
+ deviceWalletSessionStore.deleteDevice(deviceId);
1299
+ }
1300
+ if (this.isProtocolV2()) {
1301
+ if (this.originalDescriptor.path !== deviceId) {
1302
+ deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
1303
+ }
1304
+ this.invalidateProtocolV2RuntimeState();
1305
+ }
1306
+
1307
+ this.passphraseState = undefined;
1308
+ this.stateStore = new DeviceStateStore();
1309
+ this.clearPreInitialized();
1310
+ this.needReloadDevice = true;
1311
+ }
1312
+
1313
+ markProtocolV2Reboot(rebootType: DeviceRebootType) {
1314
+ if (!this.isProtocolV2()) return;
1315
+
1316
+ this.invalidateProtocolV2RuntimeState();
1317
+ let loaderMode: 'bootloader' | 'romloader' | undefined;
1318
+ if (rebootType === DeviceRebootType.Bootloader) {
1319
+ loaderMode = 'bootloader';
1320
+ } else if (rebootType === DeviceRebootType.Romloader) {
1321
+ loaderMode = 'romloader';
1322
+ }
1323
+ if (loaderMode) {
1324
+ this.updateState(
1325
+ {
1326
+ identity: { deviceId: null },
1327
+ status: {
1328
+ mode: loaderMode,
1329
+ initialized: null,
1330
+ unlocked: null,
1331
+ firmwarePresent: null,
1332
+ backupRequired: null,
1333
+ noBackup: null,
1334
+ unfinishedBackup: null,
1335
+ recoveryMode: null,
1336
+ passphraseProtection: null,
1337
+ pinProtection: null,
1338
+ attachToPinEnabled: null,
1339
+ unlockedAttachPin: null,
1340
+ },
1341
+ raw: { protocolV2ProtocolInfo: null, protocolV2DeviceStatus: null },
1342
+ },
1343
+ 'transport-reconnect'
1344
+ );
1345
+ return;
1346
+ }
1347
+
1348
+ this.updateState(
1349
+ {
1350
+ status: { mode: 'normal', unlocked: null },
1351
+ raw: { protocolV2ProtocolInfo: null, protocolV2DeviceStatus: null },
1352
+ },
1353
+ 'transport-reconnect'
1354
+ );
1355
+ }
1356
+
902
1357
  /**
903
1358
  * 暂时只在 acquire 后更新 Session ID
904
1359
  * 后续看是否有需要依据 listen 返回结果更新
@@ -917,8 +1372,7 @@ export class Device extends EventEmitter {
917
1372
  }
918
1373
 
919
1374
  if (forceUpdate) {
920
- // 枚举得到的 descriptor 可能不带 protocolType(如 WebUSB enumerate),
921
- // 不能让覆盖丢掉已探测的协议结果。
1375
+ // Enumerated descriptors may omit protocolType, so preserve an actively probed value.
922
1376
  this.originalDescriptor = {
923
1377
  ...descriptor,
924
1378
  protocolType: descriptor.protocolType ?? this.originalDescriptor.protocolType,
@@ -933,6 +1387,10 @@ export class Device extends EventEmitter {
933
1387
  if (device.features) {
934
1388
  this._updateFeatures(device.features);
935
1389
  }
1390
+ // Adopting another Device instance's command channel also crosses an active
1391
+ // link boundary. Renegotiate runtime metadata on that channel instead of
1392
+ // retaining ProtocolInfo from the previous instance/session.
1393
+ this.invalidateProtocolV2RuntimeState();
936
1394
  }
937
1395
 
938
1396
  async run(fn?: () => Promise<void>, options?: RunOptions) {
@@ -943,19 +1401,51 @@ export class Device extends EventEmitter {
943
1401
 
944
1402
  options = parseRunOptions(options);
945
1403
 
946
- this.runPromise = createDeferred(this._runInner.bind(this, fn, options));
947
- return this.runPromise.promise;
1404
+ const runPromise = createDeferred<void>();
1405
+ this.runPromise = runPromise;
1406
+ const cleanupPromise = this._runInner(fn, options, runPromise).catch(error => {
1407
+ if (this.runPromise === runPromise) {
1408
+ this.runPromise = null;
1409
+ }
1410
+ runPromise.reject(error);
1411
+ });
1412
+ this.runCleanupPromise = cleanupPromise;
1413
+ cleanupPromise
1414
+ .finally(() => {
1415
+ if (this.runCleanupPromise === cleanupPromise) {
1416
+ this.runCleanupPromise = undefined;
1417
+ }
1418
+ })
1419
+ .catch(() => undefined);
1420
+ return runPromise.promise;
948
1421
  }
949
1422
 
950
- async _runInner<T>(fn: (() => Promise<T>) | undefined, options: RunOptions) {
951
- if (!this.isUsedHere() || this.commands.disposed) {
952
- const env = DataManager.getSettings('env');
1423
+ async _runInner<T>(
1424
+ fn: (() => Promise<T>) | undefined,
1425
+ options: RunOptions,
1426
+ runPromise: Deferred<void>
1427
+ ) {
1428
+ const clearRunPromise = () => {
1429
+ if (this.runPromise === runPromise) {
1430
+ this.runPromise = null;
1431
+ }
1432
+ };
1433
+
1434
+ const env = DataManager.getSettings('env');
1435
+ if (options.forceProtocolDetection && env !== 'react-native' && this.isUsedHere()) {
1436
+ await this.release();
1437
+ }
1438
+
1439
+ if (options.forceProtocolDetection || !this.isUsedHere() || this.commands.disposed) {
953
1440
  if (env !== 'react-native') {
954
1441
  try {
955
- await this.acquire(options.connectProtocol);
1442
+ await this.acquire(options.connectProtocol, {
1443
+ forceProtocolDetection: options.forceProtocolDetection,
1444
+ });
956
1445
  } catch (error) {
957
- this.runPromise = null;
958
- return Promise.reject(error);
1446
+ clearRunPromise();
1447
+ runPromise.reject(error);
1448
+ return;
959
1449
  }
960
1450
 
961
1451
  try {
@@ -965,16 +1455,19 @@ export class Device extends EventEmitter {
965
1455
  }
966
1456
  }
967
1457
  } catch (error) {
968
- this.runPromise = null;
1458
+ await this.release();
1459
+ clearRunPromise();
969
1460
  if (error instanceof HardwareError) {
970
- return Promise.reject(error);
1461
+ runPromise.reject(error);
1462
+ return;
971
1463
  }
972
- return Promise.reject(
1464
+ runPromise.reject(
973
1465
  ERRORS.TypedError(
974
1466
  HardwareErrorCode.DeviceInitializeFailed,
975
1467
  `Initialize failed: ${error.message as string}, code: ${error.code as string}`
976
1468
  )
977
1469
  );
1470
+ return;
978
1471
  }
979
1472
  } else if (env === 'react-native') {
980
1473
  // TODO: implement react-native acquire
@@ -993,9 +1486,7 @@ export class Device extends EventEmitter {
993
1486
  try {
994
1487
  await fn();
995
1488
  } catch (e) {
996
- if (this.runPromise) {
997
- this.runPromise.reject(e);
998
- }
1489
+ runPromise.reject(e);
999
1490
 
1000
1491
  if (
1001
1492
  e instanceof HardwareError &&
@@ -1008,7 +1499,7 @@ export class Device extends EventEmitter {
1008
1499
  Log.debug(`error code ${e.errorCode} release device, mainId: ${this.mainId}`);
1009
1500
  }
1010
1501
 
1011
- this.runPromise = null;
1502
+ clearRunPromise();
1012
1503
  return;
1013
1504
  }
1014
1505
  }
@@ -1022,11 +1513,8 @@ export class Device extends EventEmitter {
1022
1513
  Log.debug('release device, mainId: ', this.mainId);
1023
1514
  }
1024
1515
 
1025
- if (this.runPromise) {
1026
- this.runPromise.resolve();
1027
- }
1028
-
1029
- this.runPromise = null;
1516
+ runPromise.resolve();
1517
+ clearRunPromise();
1030
1518
  }
1031
1519
 
1032
1520
  async interruptionFromOutside() {
@@ -1040,13 +1528,26 @@ export class Device extends EventEmitter {
1040
1528
 
1041
1529
  async interruptionFromUser() {
1042
1530
  const error = ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
1043
- await this.cancelableAction?.(error);
1531
+ const cleanupPromise = this.runCleanupPromise;
1532
+ const { cancelableAction } = this;
1533
+ if (cancelableAction) {
1534
+ await cancelableAction(error);
1535
+ } else if (
1536
+ this.isProtocolV2() &&
1537
+ DataManager.isBleConnect(DataManager.getSettings('env')) &&
1538
+ this.hasDeviceAcquire()
1539
+ ) {
1540
+ await this.commands?.cancelDevice?.().catch(cancelError => {
1541
+ Log.debug('Protocol V2 BLE fallback cancel error', cancelError);
1542
+ });
1543
+ }
1044
1544
  await this.commands?.cancel();
1045
1545
 
1046
1546
  if (this.runPromise) {
1047
1547
  this.runPromise.reject(error);
1048
1548
  this.runPromise = null;
1049
1549
  }
1550
+ await cleanupPromise?.catch(() => undefined);
1050
1551
  }
1051
1552
 
1052
1553
  setCancelableAction(callback: (err?: Error) => Promise<unknown>) {
@@ -1065,33 +1566,37 @@ export class Device extends EventEmitter {
1065
1566
  }
1066
1567
 
1067
1568
  getMode() {
1068
- if (this.features?.bootloaderMode) {
1069
- // bootloader mode
1070
- return EOneKeyDeviceMode.bootloader;
1071
- }
1072
-
1073
- if (!this.features?.initialized) {
1074
- // not initialized
1075
- return EOneKeyDeviceMode.notInitialized;
1076
- }
1077
-
1078
- if (this.features?.noBackup) {
1079
- // backup mode
1080
- return EOneKeyDeviceMode.backupMode;
1569
+ switch (this.state?.status.mode) {
1570
+ case 'bootloader':
1571
+ case 'romloader':
1572
+ return EOneKeyDeviceMode.bootloader;
1573
+ case 'notInitialized':
1574
+ return EOneKeyDeviceMode.notInitialized;
1575
+ case 'backupMode':
1576
+ return EOneKeyDeviceMode.backupMode;
1577
+ case 'normal':
1578
+ return EOneKeyDeviceMode.normal;
1579
+ default:
1580
+ break;
1081
1581
  }
1082
1582
 
1083
- // normal mode
1084
1583
  return EOneKeyDeviceMode.normal;
1085
1584
  }
1086
1585
 
1586
+ getStatus() {
1587
+ if (this.isUsedElsewhere()) return 'occupied' as const;
1588
+ if (this.isUsedHere()) return 'used' as const;
1589
+ return 'available' as const;
1590
+ }
1591
+
1087
1592
  getFirmwareVersion() {
1088
- if (!this.features) return null;
1089
- return getDeviceFirmwareVersion(this.features);
1593
+ if (!this.state) return null;
1594
+ return parseDeviceVersion(this.state.versions.firmware);
1090
1595
  }
1091
1596
 
1092
1597
  getBLEFirmwareVersion() {
1093
- if (!this.features) return null;
1094
- return getDeviceBLEFirmwareVersion(this.features);
1598
+ if (!this.state) return null;
1599
+ return parseDeviceVersion(this.state.versions.ble);
1095
1600
  }
1096
1601
 
1097
1602
  isUsed() {
@@ -1109,7 +1614,7 @@ export class Device extends EventEmitter {
1109
1614
  isUsedHere() {
1110
1615
  const env = DataManager.getSettings('env');
1111
1616
  if (DataManager.isBleConnect(env)) {
1112
- return false;
1617
+ return this.deviceAcquired;
1113
1618
  }
1114
1619
  return this.isUsed() && this.originalDescriptor.session === this.mainId;
1115
1620
  }
@@ -1119,19 +1624,32 @@ export class Device extends EventEmitter {
1119
1624
  }
1120
1625
 
1121
1626
  isBootloader() {
1122
- return this.features && !!this.features.bootloaderMode;
1627
+ if (!this.state) return undefined;
1628
+ return this.state.status.mode === 'bootloader';
1629
+ }
1630
+
1631
+ isRomloader() {
1632
+ if (!this.state) return undefined;
1633
+ return (
1634
+ this.isProtocolV2() &&
1635
+ (this.getCurrentDeviceType() === EDeviceType.Pro2 ||
1636
+ this.getCurrentDeviceType() === EDeviceType.Neo) &&
1637
+ this.state.status.mode === 'romloader'
1638
+ );
1123
1639
  }
1124
1640
 
1125
1641
  isInitialized() {
1126
- return this.features && !!this.features.initialized;
1642
+ if (!this.state) return undefined;
1643
+ return this.state.status.initialized === true;
1127
1644
  }
1128
1645
 
1129
1646
  isSeedless() {
1130
- return this.features && !!this.features.noBackup;
1647
+ if (!this.state) return undefined;
1648
+ return this.state.status.noBackup === true;
1131
1649
  }
1132
1650
 
1133
1651
  isUnacquired(): boolean {
1134
- return this.features === undefined;
1652
+ return this.state === undefined;
1135
1653
  }
1136
1654
 
1137
1655
  hasUnexpectedMode(allow: string[], require: string[]) {
@@ -1161,8 +1679,9 @@ export class Device extends EventEmitter {
1161
1679
  const isModeT =
1162
1680
  deviceType === EDeviceType.Touch ||
1163
1681
  deviceType === EDeviceType.Pro ||
1164
- deviceType === EDeviceType.Pro2;
1165
- const unlocked = this.features?.unlocked;
1682
+ deviceType === EDeviceType.Pro2 ||
1683
+ deviceType === EDeviceType.Neo;
1684
+ const unlocked = this.state?.status.unlocked;
1166
1685
  const preCheckTouch = isModeT && unlocked === false;
1167
1686
  const passphraseProtection = this.getCurrentPassphraseProtection();
1168
1687
 
@@ -1175,11 +1694,91 @@ export class Device extends EventEmitter {
1175
1694
 
1176
1695
  async lockDevice(): Promise<Success> {
1177
1696
  const res = await this.commands.typedCall('LockDevice', 'Success', {});
1697
+ this.updateState({ status: { unlocked: false } }, 'lock');
1178
1698
  return res.message;
1179
1699
  }
1180
1700
 
1701
+ beginProtocolV2UiInteraction() {
1702
+ if (!this.isProtocolV2()) return;
1703
+ this.protocolV2UiInteraction = {
1704
+ interactionId: `${this.instanceId}:${Date.now()}:${++this.protocolV2UiInteractionCounter}`,
1705
+ phaseCounter: 0,
1706
+ sequence: 0,
1707
+ opened: false,
1708
+ };
1709
+ }
1710
+
1711
+ createProtocolV2UiPhaseMetadata(
1712
+ phase: HardwareUiInteractionMeta['phase'],
1713
+ transition: HardwareUiInteractionMeta['transition'],
1714
+ options?: {
1715
+ phaseId?: string;
1716
+ outcome?: HardwareUiInteractionMeta['outcome'];
1717
+ }
1718
+ ): HardwareUiInteractionMeta | undefined {
1719
+ if (!this.isProtocolV2()) return undefined;
1720
+ if (!this.protocolV2UiInteraction) this.beginProtocolV2UiInteraction();
1721
+
1722
+ const interaction = this.protocolV2UiInteraction;
1723
+ if (!interaction) return undefined;
1724
+ const phaseId =
1725
+ options?.phaseId ?? `${interaction.interactionId}:phase-${++interaction.phaseCounter}`;
1726
+ interaction.opened = true;
1727
+ interaction.sequence += 1;
1728
+
1729
+ return {
1730
+ interactionId: interaction.interactionId,
1731
+ phaseId,
1732
+ sequence: interaction.sequence,
1733
+ phase,
1734
+ transition,
1735
+ ...(options?.outcome ? { outcome: options.outcome } : {}),
1736
+ protocol: 'V2',
1737
+ };
1738
+ }
1739
+
1740
+ completeProtocolV2UiPhase(
1741
+ phase: HardwareUiInteractionMeta,
1742
+ outcome: HardwareUiInteractionMeta['outcome'] = 'succeeded'
1743
+ ) {
1744
+ return this.createProtocolV2UiPhaseMetadata(phase.phase, 'complete', {
1745
+ phaseId: phase.phaseId,
1746
+ outcome,
1747
+ });
1748
+ }
1749
+
1750
+ finishProtocolV2UiInteraction(
1751
+ outcome?: HardwareUiInteractionMeta['outcome'],
1752
+ options?: { ensureMetadata?: boolean }
1753
+ ) {
1754
+ const interaction = this.protocolV2UiInteraction;
1755
+ if (!interaction || (!interaction.opened && !options?.ensureMetadata)) {
1756
+ this.protocolV2UiInteraction = undefined;
1757
+ return undefined;
1758
+ }
1759
+
1760
+ const phaseId = `${interaction.interactionId}:phase-${Math.max(interaction.phaseCounter, 1)}`;
1761
+ interaction.opened = true;
1762
+ interaction.sequence += 1;
1763
+ const metadata: HardwareUiInteractionMeta = {
1764
+ interactionId: interaction.interactionId,
1765
+ phaseId,
1766
+ sequence: interaction.sequence,
1767
+ phase: 'processing',
1768
+ transition: 'finish',
1769
+ outcome: outcome ?? 'succeeded',
1770
+ protocol: 'V2',
1771
+ };
1772
+ this.protocolV2UiInteraction = undefined;
1773
+ return metadata;
1774
+ }
1775
+
1776
+ hasOpenProtocolV2UiInteraction() {
1777
+ return this.protocolV2UiInteraction?.opened === true;
1778
+ }
1779
+
1181
1780
  supportUnlockVersionRange(): DeviceFirmwareRange {
1182
- // 仅适用于 Protocol V1 Pro 系列;Pro2 走独立的 Protocol V2 解锁流程。
1781
+ // This range applies to Protocol V1 Pro devices; Pro2 has a dedicated unlock flow.
1183
1782
  return {
1184
1783
  pro: {
1185
1784
  min: '4.15.0',
@@ -1187,10 +1786,33 @@ export class Device extends EventEmitter {
1187
1786
  };
1188
1787
  }
1189
1788
 
1190
- async unlockDevice() {
1789
+ async unlockDevice(
1790
+ pinType?: DeviceSessionPinType,
1791
+ options?: ProtocolV2UiEventMetadata & { emitUiEvent?: boolean }
1792
+ ) {
1191
1793
  if (this.isProtocolV2()) {
1794
+ const requestedPinType = pinType ?? DeviceSessionPinType.Main;
1795
+ const interaction =
1796
+ options?.interaction ??
1797
+ (options?.emitUiEvent === false
1798
+ ? undefined
1799
+ : this.createProtocolV2UiPhaseMetadata('pin', 'start'));
1800
+ if (options?.emitUiEvent !== false) {
1801
+ this.emit(DEVICE.PIN_ON_DEVICE, this, requestedPinType, {
1802
+ source: options?.source ?? 'unlock-coordinator',
1803
+ reason: options?.reason ?? 'device-unlock',
1804
+ deviceOnly: options?.deviceOnly ?? true,
1805
+ completion: options?.completion,
1806
+ method: options?.method,
1807
+ page: options?.page,
1808
+ operation: options?.operation,
1809
+ interaction: options?.interaction ?? interaction,
1810
+ });
1811
+ }
1192
1812
  try {
1193
- await this.commands.typedCall('DeviceSessionAskPin', 'Success');
1813
+ await this.commands.typedCall('DeviceSessionAskPin', 'Success', {
1814
+ type: requestedPinType,
1815
+ });
1194
1816
  } catch (error) {
1195
1817
  const errorText =
1196
1818
  error instanceof Error
@@ -1202,11 +1824,12 @@ export class Device extends EventEmitter {
1202
1824
  throw error;
1203
1825
  }
1204
1826
 
1205
- const { message: status } = await this.commands.typedCall(
1206
- 'DeviceStatusGet',
1207
- 'DeviceStatus',
1208
- {}
1209
- );
1827
+ const completion = interaction ? this.completeProtocolV2UiPhase(interaction) : undefined;
1828
+ if (completion) {
1829
+ this.emit(DEVICE.PIN_ON_DEVICE_COMPLETE, this, completion);
1830
+ }
1831
+
1832
+ const status = await requestProtocolV2DeviceStatus({ commands: this.commands });
1210
1833
  return this.updateProtocolV2Status(status);
1211
1834
  }
1212
1835
 
@@ -1215,8 +1838,7 @@ export class Device extends EventEmitter {
1215
1838
  type => this.supportUnlockVersionRange()[type]
1216
1839
  );
1217
1840
 
1218
- const supportAttachPinCapability = existCapability(
1219
- this.features,
1841
+ const supportAttachPinCapability = this.state?.capabilities.includes(
1220
1842
  Enum_Capability.Capability_AttachToPin
1221
1843
  );
1222
1844
  const supportUnlock =
@@ -1227,12 +1849,21 @@ export class Device extends EventEmitter {
1227
1849
 
1228
1850
  if (supportUnlock) {
1229
1851
  const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
1230
- if (this.features) {
1231
- this.features.unlocked = res.message.unlocked == null ? null : res.message.unlocked;
1232
- this.features.unlockedAttachPin =
1233
- res.message.unlocked_attach_pin == null ? undefined : res.message.unlocked_attach_pin;
1234
- this.features.passphraseProtection =
1235
- res.message.passphrase_protection == null ? null : res.message.passphrase_protection;
1852
+ if (this.state) {
1853
+ this.updateState(
1854
+ {
1855
+ status: {
1856
+ unlocked: res.message.unlocked == null ? null : res.message.unlocked,
1857
+ unlockedAttachPin:
1858
+ res.message.unlocked_attach_pin == null ? null : res.message.unlocked_attach_pin,
1859
+ passphraseProtection:
1860
+ res.message.passphrase_protection == null
1861
+ ? null
1862
+ : res.message.passphrase_protection,
1863
+ },
1864
+ },
1865
+ 'unlock'
1866
+ );
1236
1867
 
1237
1868
  return Promise.resolve(this.features);
1238
1869
  }
@@ -1259,25 +1890,34 @@ export class Device extends EventEmitter {
1259
1890
  async checkPassphraseStateSafety(
1260
1891
  passphraseState?: string,
1261
1892
  useEmptyPassphrase?: boolean,
1262
- skipPassphraseCheck?: boolean
1893
+ skipPassphraseCheck?: boolean,
1894
+ deriveCardano?: boolean
1263
1895
  ) {
1264
1896
  if (this.isUnacquired()) return false;
1265
1897
 
1898
+ const expectedPassphraseState = useEmptyPassphrase ? undefined : passphraseState;
1266
1899
  const { passphraseState: newPassphraseState, unlockedAttachPin } =
1267
1900
  await getPassphraseStateWithRefreshDeviceInfo(this, {
1268
- expectPassphraseState: passphraseState,
1901
+ expectPassphraseState: expectedPassphraseState,
1269
1902
  onlyMainPin: useEmptyPassphrase,
1903
+ deriveCardano,
1904
+ rejectAttachPinForMainWallet: useEmptyPassphrase === true,
1270
1905
  });
1271
1906
 
1272
1907
  // Main wallet and unlock Attach Pin, throw safe error
1273
1908
  const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
1274
1909
  const useErrorAttachPin =
1275
- unlockedAttachPin && passphraseState && passphraseState !== newPassphraseState;
1276
- const passphraseStateMismatch = !!passphraseState && passphraseState !== newPassphraseState;
1910
+ unlockedAttachPin &&
1911
+ expectedPassphraseState &&
1912
+ expectedPassphraseState !== newPassphraseState;
1913
+ const passphraseStateMismatch =
1914
+ !!expectedPassphraseState && expectedPassphraseState !== newPassphraseState;
1277
1915
 
1278
1916
  Log.debug('Check passphrase state safety: ', {
1279
- passphraseState,
1280
- newPassphraseState,
1917
+ hasExpectedPassphraseState: Boolean(expectedPassphraseState),
1918
+ hasNewPassphraseState: Boolean(newPassphraseState),
1919
+ passphraseStateMatches:
1920
+ Boolean(expectedPassphraseState) && expectedPassphraseState === newPassphraseState,
1281
1921
  unlockedAttachPin,
1282
1922
  useEmptyPassphrase,
1283
1923
  });