@onekeyfe/hd-core 1.2.0-alpha.9 → 1.2.0-alpha.90

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