@onekeyfe/hd-core 1.2.0-alpha.12 → 1.2.0-alpha.121

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