@onekeyfe/hd-core 1.2.0-alpha.8 → 1.2.0-alpha.80

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 (810) 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 +492 -0
  6. package/__tests__/check-firmware-release-protocol-v2.test.ts +164 -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 +478 -0
  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-update/check-all-firmware-release.test.ts +175 -0
  34. package/__tests__/firmware-update/device-update-bootloader.test.ts +87 -0
  35. package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
  36. package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
  37. package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
  38. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
  39. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
  40. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +394 -0
  41. package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
  42. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +231 -0
  43. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +457 -0
  44. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +121 -0
  45. package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
  46. package/__tests__/get-device-state.test.ts +578 -0
  47. package/__tests__/homescreen.test.ts +81 -0
  48. package/__tests__/kaspa-public-types.type-test.ts +16 -0
  49. package/__tests__/kaspa-use-tweak-pro2.test.ts +20 -0
  50. package/__tests__/kaspaSignTransaction.test.ts +578 -0
  51. package/__tests__/known-device-public-types.type-test.ts +3 -0
  52. package/__tests__/logBlockEvent.test.ts +128 -1
  53. package/__tests__/method-protocol-support.test.ts +144 -0
  54. package/__tests__/networkUtils.test.ts +406 -0
  55. package/__tests__/open-wallet-session-error-response.test.ts +43 -0
  56. package/__tests__/open-wallet-session.test.ts +1899 -0
  57. package/__tests__/pro2Nft.test.ts +108 -0
  58. package/__tests__/pro2Wallpaper.test.ts +39 -0
  59. package/__tests__/protocol-binding.test.ts +89 -0
  60. package/__tests__/protocol-v2-bootloader-mode.test.ts +37 -0
  61. package/__tests__/protocol-v2-firmware-targets.test.ts +85 -0
  62. package/__tests__/protocol-v2-ping.test.ts +28 -0
  63. package/__tests__/protocol-v2-resources.test.ts +250 -0
  64. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  65. package/__tests__/protocol-v2-unlock-policy.test.ts +308 -0
  66. package/__tests__/protocol-v2.test.ts +7034 -2497
  67. package/__tests__/protocolV2FileWrite.test.ts +285 -0
  68. package/__tests__/protocolV2UiInteraction.test.ts +329 -0
  69. package/__tests__/public-device-state-api.test.ts +275 -0
  70. package/__tests__/public-pro2-api-boundary.test.ts +107 -0
  71. package/__tests__/refresh-device-state.test.ts +101 -0
  72. package/__tests__/request-context-logging.test.ts +16 -0
  73. package/__tests__/search-devices.test.ts +145 -0
  74. package/__tests__/tron-sign-message-init.test.ts +74 -0
  75. package/__tests__/uiProgressThrottle.test.ts +74 -0
  76. package/__tests__/uiPromiseRegistry.test.ts +115 -0
  77. package/dist/api/BaseMethod.d.ts +16 -1
  78. package/dist/api/BaseMethod.d.ts.map +1 -1
  79. package/dist/api/CheckAllFirmwareRelease.d.ts +25 -1
  80. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  81. package/dist/api/CheckBLEFirmwareRelease.d.ts +2 -1
  82. package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
  83. package/dist/api/CheckBootloaderRelease.d.ts +3 -2
  84. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  85. package/dist/api/CheckFirmwareRelease.d.ts +2 -1
  86. package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
  87. package/dist/api/CipherKeyValue.d.ts +1 -0
  88. package/dist/api/CipherKeyValue.d.ts.map +1 -1
  89. package/dist/api/ClearSessionCache.d.ts +9 -0
  90. package/dist/api/ClearSessionCache.d.ts.map +1 -0
  91. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  92. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  93. package/dist/api/DirList.d.ts +1 -0
  94. package/dist/api/DirList.d.ts.map +1 -1
  95. package/dist/api/DirMake.d.ts +1 -0
  96. package/dist/api/DirMake.d.ts.map +1 -1
  97. package/dist/api/DirRemove.d.ts +1 -0
  98. package/dist/api/DirRemove.d.ts.map +1 -1
  99. package/dist/api/FileDelete.d.ts +1 -0
  100. package/dist/api/FileDelete.d.ts.map +1 -1
  101. package/dist/api/FileRead.d.ts +1 -0
  102. package/dist/api/FileRead.d.ts.map +1 -1
  103. package/dist/api/FileWrite.d.ts +2 -0
  104. package/dist/api/FileWrite.d.ts.map +1 -1
  105. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  106. package/dist/api/FirmwareUpdateV2.d.ts +12 -2
  107. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  108. package/dist/api/FirmwareUpdateV3.d.ts +7 -3
  109. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  110. package/dist/api/FirmwareUpdateV4.d.ts +47 -18
  111. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  112. package/dist/api/GetDeviceState.d.ts +8 -0
  113. package/dist/api/GetDeviceState.d.ts.map +1 -0
  114. package/dist/api/GetFeatures.d.ts +1 -1
  115. package/dist/api/GetFeatures.d.ts.map +1 -1
  116. package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
  117. package/dist/api/GetPassphraseState.d.ts +2 -6
  118. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  119. package/dist/api/OpenWalletSession.d.ts +8 -0
  120. package/dist/api/OpenWalletSession.d.ts.map +1 -0
  121. package/dist/api/PathInfo.d.ts +1 -0
  122. package/dist/api/PathInfo.d.ts.map +1 -1
  123. package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
  124. package/dist/api/SearchDevices.d.ts +3 -0
  125. package/dist/api/SearchDevices.d.ts.map +1 -1
  126. package/dist/api/UploadPortfolio.d.ts +17 -0
  127. package/dist/api/UploadPortfolio.d.ts.map +1 -0
  128. package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
  129. package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
  130. package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
  131. package/dist/api/algo/AlgoGetAddress.d.ts +1 -0
  132. package/dist/api/algo/AlgoGetAddress.d.ts.map +1 -1
  133. package/dist/api/algo/AlgoSignTransaction.d.ts +1 -0
  134. package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
  135. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +1 -0
  136. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  137. package/dist/api/aptos/AptosGetAddress.d.ts +1 -0
  138. package/dist/api/aptos/AptosGetAddress.d.ts.map +1 -1
  139. package/dist/api/aptos/AptosGetPublicKey.d.ts +1 -0
  140. package/dist/api/aptos/AptosGetPublicKey.d.ts.map +1 -1
  141. package/dist/api/aptos/AptosSignInMessage.d.ts +1 -0
  142. package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
  143. package/dist/api/aptos/AptosSignMessage.d.ts +1 -0
  144. package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
  145. package/dist/api/aptos/AptosSignTransaction.d.ts +1 -0
  146. package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
  147. package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
  148. package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
  149. package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
  150. package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
  151. package/dist/api/btc/BTCGetAddress.d.ts +1 -0
  152. package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
  153. package/dist/api/btc/BTCGetPublicKey.d.ts +1 -0
  154. package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
  155. package/dist/api/btc/BTCSignMessage.d.ts +1 -0
  156. package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
  157. package/dist/api/btc/BTCSignPsbt.d.ts +1 -0
  158. package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
  159. package/dist/api/btc/BTCSignTransaction.d.ts +1 -0
  160. package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
  161. package/dist/api/btc/BTCVerifyMessage.d.ts +1 -0
  162. package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
  163. package/dist/api/btc/helpers/versionLimit.d.ts +2 -0
  164. package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
  165. package/dist/api/cardano/CardanoGetAddress.d.ts +1 -0
  166. package/dist/api/cardano/CardanoGetAddress.d.ts.map +1 -1
  167. package/dist/api/cardano/CardanoGetPublicKey.d.ts +1 -0
  168. package/dist/api/cardano/CardanoGetPublicKey.d.ts.map +1 -1
  169. package/dist/api/cardano/CardanoSignMessage.d.ts +1 -0
  170. package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
  171. package/dist/api/cardano/CardanoSignTransaction.d.ts +1 -0
  172. package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
  173. package/dist/api/conflux/ConfluxGetAddress.d.ts +2 -0
  174. package/dist/api/conflux/ConfluxGetAddress.d.ts.map +1 -1
  175. package/dist/api/conflux/ConfluxSignMessage.d.ts +2 -0
  176. package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
  177. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts +2 -0
  178. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
  179. package/dist/api/conflux/ConfluxSignTransaction.d.ts +2 -0
  180. package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
  181. package/dist/api/cosmos/CosmosGetAddress.d.ts +1 -0
  182. package/dist/api/cosmos/CosmosGetAddress.d.ts.map +1 -1
  183. package/dist/api/cosmos/CosmosGetPublicKey.d.ts +1 -0
  184. package/dist/api/cosmos/CosmosGetPublicKey.d.ts.map +1 -1
  185. package/dist/api/cosmos/CosmosSignTransaction.d.ts +1 -0
  186. package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
  187. package/dist/api/device/DeviceCancel.d.ts +1 -0
  188. package/dist/api/device/DeviceCancel.d.ts.map +1 -1
  189. package/dist/api/device/DeviceChangePin.d.ts +1 -0
  190. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  191. package/dist/api/device/DeviceFullyUploadResource.d.ts +1 -2
  192. package/dist/api/device/DeviceFullyUploadResource.d.ts.map +1 -1
  193. package/dist/api/device/DeviceLock.d.ts +1 -0
  194. package/dist/api/device/DeviceLock.d.ts.map +1 -1
  195. package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -0
  196. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  197. package/dist/api/device/DeviceRebootToBootloader.d.ts +1 -0
  198. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  199. package/dist/api/device/DeviceSettings.d.ts +1 -0
  200. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  201. package/dist/api/device/DeviceSupportFeatures.d.ts +1 -0
  202. package/dist/api/device/DeviceSupportFeatures.d.ts.map +1 -1
  203. package/dist/api/device/DeviceUnlock.d.ts +3 -2
  204. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  205. package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
  206. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  207. package/dist/api/device/DeviceWipe.d.ts +1 -0
  208. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  209. package/dist/api/device/PreInitialize.d.ts +1 -0
  210. package/dist/api/device/PreInitialize.d.ts.map +1 -1
  211. package/dist/api/dynex/DnxGetAddress.d.ts.map +1 -1
  212. package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
  213. package/dist/api/evm/EVMGetAddress.d.ts +1 -0
  214. package/dist/api/evm/EVMGetAddress.d.ts.map +1 -1
  215. package/dist/api/evm/EVMGetPublicKey.d.ts +1 -0
  216. package/dist/api/evm/EVMGetPublicKey.d.ts.map +1 -1
  217. package/dist/api/evm/EVMSignMessage.d.ts +1 -0
  218. package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
  219. package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
  220. package/dist/api/evm/EVMSignTransaction.d.ts +1 -0
  221. package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
  222. package/dist/api/evm/EVMSignTypedData.d.ts +1 -0
  223. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  224. package/dist/api/evm/EVMVerifyMessage.d.ts +1 -0
  225. package/dist/api/evm/EVMVerifyMessage.d.ts.map +1 -1
  226. package/dist/api/evm/protocol.d.ts +3 -0
  227. package/dist/api/evm/protocol.d.ts.map +1 -0
  228. package/dist/api/filecoin/FilecoinGetAddress.d.ts +1 -0
  229. package/dist/api/filecoin/FilecoinGetAddress.d.ts.map +1 -1
  230. package/dist/api/filecoin/FilecoinSignTransaction.d.ts +1 -0
  231. package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
  232. package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
  233. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
  234. package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
  235. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
  236. package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
  237. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
  238. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +12 -3
  239. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  240. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
  241. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
  242. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
  243. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
  244. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
  245. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
  246. package/dist/api/firmware/getBinary.d.ts +15 -4
  247. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  248. package/dist/api/firmware/protocolV2Release.d.ts +33 -0
  249. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -0
  250. package/dist/api/firmware/updateBootloader.d.ts +2 -0
  251. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  252. package/dist/api/firmware/uploadFirmware.d.ts +9 -1
  253. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  254. package/dist/api/helpers/filesystemValidation.d.ts +3 -0
  255. package/dist/api/helpers/filesystemValidation.d.ts.map +1 -1
  256. package/dist/api/helpers/paramsValidator.d.ts +1 -0
  257. package/dist/api/helpers/paramsValidator.d.ts.map +1 -1
  258. package/dist/api/helpers/protocolV2FileWrite.d.ts +43 -0
  259. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
  260. package/dist/api/index.d.ts +9 -25
  261. package/dist/api/index.d.ts.map +1 -1
  262. package/dist/api/kaspa/KaspaGetAddress.d.ts +4 -0
  263. package/dist/api/kaspa/KaspaGetAddress.d.ts.map +1 -1
  264. package/dist/api/kaspa/KaspaSignTransaction.d.ts +9 -1
  265. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  266. package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
  267. package/dist/api/lightning/LnurlAuth.d.ts +0 -4
  268. package/dist/api/lightning/LnurlAuth.d.ts.map +1 -1
  269. package/dist/api/near/NearGetAddress.d.ts +1 -0
  270. package/dist/api/near/NearGetAddress.d.ts.map +1 -1
  271. package/dist/api/near/NearSignTransaction.d.ts +1 -0
  272. package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
  273. package/dist/api/nem/NEMGetAddress.d.ts +1 -0
  274. package/dist/api/nem/NEMGetAddress.d.ts.map +1 -1
  275. package/dist/api/nem/NEMSignTransaction.d.ts +1 -0
  276. package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
  277. package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
  278. package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
  279. package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
  280. package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
  281. package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
  282. package/dist/api/nexa/NexaSignTransaction.d.ts +1 -0
  283. package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
  284. package/dist/api/nostr/NostrDecryptMessage.d.ts +1 -0
  285. package/dist/api/nostr/NostrDecryptMessage.d.ts.map +1 -1
  286. package/dist/api/nostr/NostrEncryptMessage.d.ts +1 -0
  287. package/dist/api/nostr/NostrEncryptMessage.d.ts.map +1 -1
  288. package/dist/api/nostr/NostrGetPublicKey.d.ts +1 -0
  289. package/dist/api/nostr/NostrGetPublicKey.d.ts.map +1 -1
  290. package/dist/api/nostr/NostrSignEvent.d.ts +1 -0
  291. package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
  292. package/dist/api/nostr/NostrSignSchnorr.d.ts +1 -0
  293. package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
  294. package/dist/api/polkadot/PolkadotGetAddress.d.ts +2 -1
  295. package/dist/api/polkadot/PolkadotGetAddress.d.ts.map +1 -1
  296. package/dist/api/polkadot/PolkadotSignTransaction.d.ts +1 -0
  297. package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
  298. package/dist/api/polkadot/networks.d.ts +1 -1
  299. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +1 -0
  300. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -1
  301. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +1 -0
  302. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -1
  303. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -0
  304. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  305. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +1 -0
  306. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
  307. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +7 -0
  308. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -0
  309. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
  310. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  311. package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -0
  312. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  313. package/dist/api/protocol-v2/DeviceStatusGet.d.ts +7 -0
  314. package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
  315. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  316. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  317. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +27 -0
  318. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
  319. package/dist/api/protocol-v2/FilesystemFormat.d.ts +1 -0
  320. package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
  321. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts +1 -0
  322. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -1
  323. package/dist/api/protocol-v2/Ping.d.ts +3 -0
  324. package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
  325. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +1 -0
  326. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  327. package/dist/api/protocol-v2/helpers.d.ts +1 -1
  328. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  329. package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
  330. package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
  331. package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
  332. package/dist/api/solana/SolGetAddress.d.ts +1 -0
  333. package/dist/api/solana/SolGetAddress.d.ts.map +1 -1
  334. package/dist/api/solana/SolSignMessage.d.ts +2 -1
  335. package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
  336. package/dist/api/solana/SolSignOffchainMessage.d.ts +2 -1
  337. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  338. package/dist/api/solana/SolSignTransaction.d.ts +3 -2
  339. package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
  340. package/dist/api/starcoin/StarcoinGetAddress.d.ts +1 -0
  341. package/dist/api/starcoin/StarcoinGetAddress.d.ts.map +1 -1
  342. package/dist/api/starcoin/StarcoinGetPublicKey.d.ts +1 -0
  343. package/dist/api/starcoin/StarcoinGetPublicKey.d.ts.map +1 -1
  344. package/dist/api/starcoin/StarcoinSignMessage.d.ts +1 -0
  345. package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
  346. package/dist/api/starcoin/StarcoinSignTransaction.d.ts +1 -0
  347. package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
  348. package/dist/api/starcoin/StarcoinVerifyMessage.d.ts +1 -0
  349. package/dist/api/starcoin/StarcoinVerifyMessage.d.ts.map +1 -1
  350. package/dist/api/stellar/StellarGetAddress.d.ts +1 -2
  351. package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
  352. package/dist/api/stellar/StellarSignTransaction.d.ts +2 -3
  353. package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
  354. package/dist/api/sui/SuiGetAddress.d.ts +2 -1
  355. package/dist/api/sui/SuiGetAddress.d.ts.map +1 -1
  356. package/dist/api/sui/SuiGetPublicKey.d.ts +2 -1
  357. package/dist/api/sui/SuiGetPublicKey.d.ts.map +1 -1
  358. package/dist/api/sui/SuiSignMessage.d.ts +2 -1
  359. package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
  360. package/dist/api/sui/SuiSignTransaction.d.ts +2 -1
  361. package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
  362. package/dist/api/ton/TonGetAddress.d.ts +2 -1
  363. package/dist/api/ton/TonGetAddress.d.ts.map +1 -1
  364. package/dist/api/ton/TonSignData.d.ts +1 -0
  365. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  366. package/dist/api/ton/TonSignMessage.d.ts +2 -1
  367. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  368. package/dist/api/ton/TonSignProof.d.ts +2 -1
  369. package/dist/api/ton/TonSignProof.d.ts.map +1 -1
  370. package/dist/api/tron/TronGetAddress.d.ts +1 -0
  371. package/dist/api/tron/TronGetAddress.d.ts.map +1 -1
  372. package/dist/api/tron/TronSignMessage.d.ts +6 -1
  373. package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
  374. package/dist/api/tron/TronSignTransaction.d.ts +2 -1
  375. package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
  376. package/dist/api/utils.d.ts +4 -1
  377. package/dist/api/utils.d.ts.map +1 -1
  378. package/dist/api/xrp/XrpGetAddress.d.ts +1 -0
  379. package/dist/api/xrp/XrpGetAddress.d.ts.map +1 -1
  380. package/dist/api/xrp/XrpSignTransaction.d.ts +1 -0
  381. package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
  382. package/dist/constants/index.d.ts +1 -1
  383. package/dist/constants/index.d.ts.map +1 -1
  384. package/dist/core/RequestQueue.d.ts.map +1 -1
  385. package/dist/core/deviceEventRegistration.d.ts +13 -0
  386. package/dist/core/deviceEventRegistration.d.ts.map +1 -0
  387. package/dist/core/index.d.ts +3 -1
  388. package/dist/core/index.d.ts.map +1 -1
  389. package/dist/core/uiPromiseRegistry.d.ts +6 -0
  390. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  391. package/dist/data-manager/DataManager.d.ts +9 -3
  392. package/dist/data-manager/DataManager.d.ts.map +1 -1
  393. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  394. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  395. package/dist/device/Device.d.ts +72 -17
  396. package/dist/device/Device.d.ts.map +1 -1
  397. package/dist/device/DeviceCommands.d.ts +8 -6
  398. package/dist/device/DeviceCommands.d.ts.map +1 -1
  399. package/dist/device/DeviceConnector.d.ts +4 -3
  400. package/dist/device/DeviceConnector.d.ts.map +1 -1
  401. package/dist/device/DeviceFeaturesState.d.ts +3 -0
  402. package/dist/device/DeviceFeaturesState.d.ts.map +1 -0
  403. package/dist/device/DevicePool.d.ts +6 -2
  404. package/dist/device/DevicePool.d.ts.map +1 -1
  405. package/dist/device/DeviceStateMapper.d.ts +13 -0
  406. package/dist/device/DeviceStateMapper.d.ts.map +1 -0
  407. package/dist/device/DeviceStateProjector.d.ts +7 -0
  408. package/dist/device/DeviceStateProjector.d.ts.map +1 -0
  409. package/dist/device/DeviceStateStore.d.ts +21 -0
  410. package/dist/device/DeviceStateStore.d.ts.map +1 -0
  411. package/dist/device/DeviceWalletSessionStore.d.ts +27 -0
  412. package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
  413. package/dist/device/cloneDeviceState.d.ts +2 -0
  414. package/dist/device/cloneDeviceState.d.ts.map +1 -0
  415. package/dist/device/deviceIdentity.d.ts +5 -0
  416. package/dist/device/deviceIdentity.d.ts.map +1 -0
  417. package/dist/deviceProfile/buildDeviceFeatures.d.ts +9 -3
  418. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  419. package/dist/deviceProfile/index.d.ts +0 -1
  420. package/dist/deviceProfile/index.d.ts.map +1 -1
  421. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts +7 -0
  422. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -0
  423. package/dist/events/device.d.ts +16 -2
  424. package/dist/events/device.d.ts.map +1 -1
  425. package/dist/events/logBlockEvent.d.ts +2 -0
  426. package/dist/events/logBlockEvent.d.ts.map +1 -1
  427. package/dist/events/ui-promise.d.ts +4 -2
  428. package/dist/events/ui-promise.d.ts.map +1 -1
  429. package/dist/events/ui-request.d.ts +50 -4
  430. package/dist/events/ui-request.d.ts.map +1 -1
  431. package/dist/events/ui-response.d.ts +10 -2
  432. package/dist/events/ui-response.d.ts.map +1 -1
  433. package/dist/index.d.ts +1818 -770
  434. package/dist/index.d.ts.map +1 -1
  435. package/dist/index.js +11157 -4209
  436. package/dist/inject.d.ts +6 -1
  437. package/dist/inject.d.ts.map +1 -1
  438. package/dist/lowLevelInject.d.ts.map +1 -1
  439. package/dist/protocols/protocol-v2/deviceSession.d.ts +7 -0
  440. package/dist/protocols/protocol-v2/deviceSession.d.ts.map +1 -0
  441. package/dist/protocols/protocol-v2/features.d.ts +21 -17
  442. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  443. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  444. package/dist/protocols/protocol-v2/index.d.ts +3 -2
  445. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  446. package/dist/protocols/protocol-v2/resources.d.ts +29 -0
  447. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  448. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +17 -0
  449. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
  450. package/dist/protocols/protocol-v2/uiInteraction.d.ts +42 -0
  451. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
  452. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +2 -0
  453. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -0
  454. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  455. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  456. package/dist/protocols/protocol-v2/walletSession.d.ts +27 -0
  457. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
  458. package/dist/topLevelInject.d.ts.map +1 -1
  459. package/dist/types/api/checkAllFirmwareRelease.d.ts +48 -9
  460. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  461. package/dist/types/api/checkBLEFirmwareRelease.d.ts +2 -13
  462. package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
  463. package/dist/types/api/checkBootloaderRelease.d.ts +2 -6
  464. package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
  465. package/dist/types/api/checkFirmwareRelease.d.ts +2 -13
  466. package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
  467. package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
  468. package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
  469. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  470. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  471. package/dist/types/api/deviceSettings.d.ts +11 -2
  472. package/dist/types/api/deviceSettings.d.ts.map +1 -1
  473. package/dist/types/api/deviceUnlock.d.ts +6 -2
  474. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  475. package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
  476. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  477. package/dist/types/api/export.d.ts +9 -3
  478. package/dist/types/api/export.d.ts.map +1 -1
  479. package/dist/types/api/firmwareUpdate.d.ts +76 -1
  480. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  481. package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
  482. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
  483. package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
  484. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
  485. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
  486. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
  487. package/dist/types/api/getDeviceState.d.ts +12 -0
  488. package/dist/types/api/getDeviceState.d.ts.map +1 -0
  489. package/dist/types/api/getFeatures.d.ts.map +1 -1
  490. package/dist/types/api/getOnekeyFeatures.d.ts.map +1 -1
  491. package/dist/types/api/getPassphraseState.d.ts +2 -10
  492. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  493. package/dist/types/api/index.d.ts +34 -31
  494. package/dist/types/api/index.d.ts.map +1 -1
  495. package/dist/types/api/kaspaSignTransaction.d.ts +42 -4
  496. package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
  497. package/dist/types/api/openWalletSession.d.ts +35 -0
  498. package/dist/types/api/openWalletSession.d.ts.map +1 -0
  499. package/dist/types/api/protocolV2.d.ts +18 -84
  500. package/dist/types/api/protocolV2.d.ts.map +1 -1
  501. package/dist/types/api/protocolV2ResourceManifest.d.ts +17 -0
  502. package/dist/types/api/protocolV2ResourceManifest.d.ts.map +1 -0
  503. package/dist/types/api/sessionCache.d.ts +13 -0
  504. package/dist/types/api/sessionCache.d.ts.map +1 -0
  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 +69 -22
  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 +380 -4
  541. package/src/api/CheckBLEFirmwareRelease.ts +41 -3
  542. package/src/api/CheckBootloaderRelease.ts +41 -3
  543. package/src/api/CheckFirmwareRelease.ts +38 -5
  544. package/src/api/CipherKeyValue.ts +4 -0
  545. package/src/api/ClearSessionCache.ts +32 -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 +15 -9
  552. package/src/api/FileWrite.ts +26 -181
  553. package/src/api/FirmwareUpdate.ts +30 -15
  554. package/src/api/FirmwareUpdateV2.ts +385 -115
  555. package/src/api/FirmwareUpdateV3.ts +274 -71
  556. package/src/api/FirmwareUpdateV4.ts +1465 -660
  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 +126 -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 +100 -0
  632. package/src/api/firmware/FirmwarePreparationError.ts +12 -0
  633. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +102 -16
  634. package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
  635. package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
  636. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +449 -0
  637. package/src/api/firmware/getBinary.ts +8 -3
  638. package/src/api/firmware/protocolV2Release.ts +166 -0
  639. package/src/api/firmware/updateBootloader.ts +19 -4
  640. package/src/api/firmware/uploadFirmware.ts +157 -26
  641. package/src/api/helpers/batchGetPublickeys.ts +2 -2
  642. package/src/api/helpers/filesystemValidation.ts +61 -0
  643. package/src/api/helpers/paramsValidator.ts +1 -1
  644. package/src/api/helpers/protocolV2FileWrite.ts +392 -0
  645. package/src/api/index.ts +10 -26
  646. package/src/api/kaspa/KaspaGetAddress.ts +7 -0
  647. package/src/api/kaspa/KaspaSignTransaction.ts +369 -29
  648. package/src/api/kaspa/helpers/TransferSerialize.ts +17 -7
  649. package/src/api/lightning/LnurlAuth.ts +0 -4
  650. package/src/api/near/NearGetAddress.ts +4 -0
  651. package/src/api/near/NearSignTransaction.ts +4 -0
  652. package/src/api/nem/NEMGetAddress.ts +4 -0
  653. package/src/api/nem/NEMSignTransaction.ts +4 -0
  654. package/src/api/neo/NeoGetAddress.ts +0 -4
  655. package/src/api/neo/NeoSignTransaction.ts +0 -4
  656. package/src/api/nervos/NervosGetAddress.ts +0 -4
  657. package/src/api/nervos/NervosSignTransaction.ts +2 -6
  658. package/src/api/nexa/NexaGetAddress.ts +0 -4
  659. package/src/api/nexa/NexaSignTransaction.ts +3 -5
  660. package/src/api/nostr/NostrDecryptMessage.ts +4 -0
  661. package/src/api/nostr/NostrEncryptMessage.ts +4 -0
  662. package/src/api/nostr/NostrGetPublicKey.ts +4 -0
  663. package/src/api/nostr/NostrSignEvent.ts +4 -0
  664. package/src/api/nostr/NostrSignSchnorr.ts +4 -0
  665. package/src/api/polkadot/PolkadotGetAddress.ts +4 -0
  666. package/src/api/polkadot/PolkadotSignTransaction.ts +4 -0
  667. package/src/api/polkadot/networks.ts +3 -3
  668. package/src/api/protocol-v2/DeviceFactoryInfoGet.ts +5 -2
  669. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +5 -2
  670. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +8 -5
  671. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +10 -6
  672. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +21 -0
  673. package/src/api/protocol-v2/DeviceInfoGet.ts +8 -15
  674. package/src/api/protocol-v2/DeviceReboot.ts +7 -3
  675. package/src/api/protocol-v2/DeviceStatusGet.ts +19 -0
  676. package/src/api/protocol-v2/DeviceUploadNft.ts +197 -0
  677. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +134 -0
  678. package/src/api/protocol-v2/FilesystemFormat.ts +9 -3
  679. package/src/api/protocol-v2/FilesystemPermissionFix.ts +5 -2
  680. package/src/api/protocol-v2/Ping.ts +37 -3
  681. package/src/api/protocol-v2/ProtocolInfoRequest.ts +8 -3
  682. package/src/api/protocol-v2/helpers.ts +17 -17
  683. package/src/api/scdo/ScdoGetAddress.ts +0 -4
  684. package/src/api/scdo/ScdoSignMessage.ts +0 -4
  685. package/src/api/scdo/ScdoSignTransaction.ts +0 -4
  686. package/src/api/solana/SolGetAddress.ts +4 -0
  687. package/src/api/solana/SolSignMessage.ts +5 -1
  688. package/src/api/solana/SolSignOffchainMessage.ts +5 -1
  689. package/src/api/solana/SolSignTransaction.ts +6 -2
  690. package/src/api/starcoin/StarcoinGetAddress.ts +4 -0
  691. package/src/api/starcoin/StarcoinGetPublicKey.ts +4 -0
  692. package/src/api/starcoin/StarcoinSignMessage.ts +4 -0
  693. package/src/api/starcoin/StarcoinSignTransaction.ts +4 -0
  694. package/src/api/starcoin/StarcoinVerifyMessage.ts +4 -0
  695. package/src/api/stellar/StellarGetAddress.ts +1 -10
  696. package/src/api/stellar/StellarSignTransaction.ts +1 -14
  697. package/src/api/sui/SuiGetAddress.ts +5 -1
  698. package/src/api/sui/SuiGetPublicKey.ts +5 -1
  699. package/src/api/sui/SuiSignMessage.ts +5 -1
  700. package/src/api/sui/SuiSignTransaction.ts +5 -1
  701. package/src/api/ton/TonGetAddress.ts +5 -1
  702. package/src/api/ton/TonSignData.ts +5 -1
  703. package/src/api/ton/TonSignMessage.ts +5 -1
  704. package/src/api/ton/TonSignProof.ts +5 -1
  705. package/src/api/tron/TronGetAddress.ts +4 -0
  706. package/src/api/tron/TronSignMessage.ts +19 -8
  707. package/src/api/tron/TronSignTransaction.ts +5 -1
  708. package/src/api/utils.ts +32 -3
  709. package/src/api/xrp/XrpGetAddress.ts +4 -0
  710. package/src/api/xrp/XrpSignTransaction.ts +5 -1
  711. package/src/constants/index.ts +1 -4
  712. package/src/core/RequestQueue.ts +1 -0
  713. package/src/core/deviceEventRegistration.ts +27 -0
  714. package/src/core/index.ts +381 -152
  715. package/src/core/uiPromiseRegistry.ts +63 -0
  716. package/src/data/messages/messages-protocol-v2.json +1138 -441
  717. package/src/data/messages/messages.json +286 -1
  718. package/src/data-manager/DataManager.ts +132 -41
  719. package/src/data-manager/TransportManager.ts +7 -1
  720. package/src/data-manager/connectSettings.ts +11 -0
  721. package/src/device/Device.ts +898 -296
  722. package/src/device/DeviceCommands.ts +193 -158
  723. package/src/device/DeviceConnector.ts +44 -21
  724. package/src/device/DeviceFeaturesState.ts +25 -0
  725. package/src/device/DevicePool.ts +101 -23
  726. package/src/device/DeviceStateMapper.ts +416 -0
  727. package/src/device/DeviceStateProjector.ts +152 -0
  728. package/src/device/DeviceStateStore.ts +232 -0
  729. package/src/device/DeviceWalletSessionStore.ts +144 -0
  730. package/src/device/cloneDeviceState.ts +39 -0
  731. package/src/device/deviceIdentity.ts +18 -0
  732. package/src/deviceProfile/buildDeviceFeatures.ts +223 -189
  733. package/src/deviceProfile/index.ts +0 -1
  734. package/src/deviceProfile/protocolV2DeviceIdentity.ts +35 -0
  735. package/src/events/device.ts +22 -1
  736. package/src/events/logBlockEvent.ts +80 -2
  737. package/src/events/ui-promise.ts +4 -2
  738. package/src/events/ui-request.ts +61 -4
  739. package/src/events/ui-response.ts +12 -2
  740. package/src/index.ts +12 -0
  741. package/src/inject.ts +97 -45
  742. package/src/lowLevelInject.ts +11 -4
  743. package/src/protocols/protocol-v2/deviceSession.ts +24 -0
  744. package/src/protocols/protocol-v2/features.ts +100 -33
  745. package/src/protocols/protocol-v2/firmware.ts +3 -1
  746. package/src/protocols/protocol-v2/index.ts +8 -1
  747. package/src/protocols/protocol-v2/resources.ts +257 -0
  748. package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +65 -0
  749. package/src/protocols/protocol-v2/uiInteraction.ts +250 -0
  750. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -0
  751. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +131 -0
  752. package/src/protocols/protocol-v2/walletSession.ts +463 -0
  753. package/src/topLevelInject.ts +11 -4
  754. package/src/types/api/checkAllFirmwareRelease.ts +72 -9
  755. package/src/types/api/checkBLEFirmwareRelease.ts +4 -13
  756. package/src/types/api/checkBootloaderRelease.ts +2 -6
  757. package/src/types/api/checkFirmwareRelease.ts +2 -13
  758. package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
  759. package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
  760. package/src/types/api/deviceSettings.ts +26 -2
  761. package/src/types/api/deviceUnlock.ts +13 -2
  762. package/src/types/api/deviceUpdateBootloader.ts +6 -0
  763. package/src/types/api/export.ts +37 -1
  764. package/src/types/api/firmwareUpdate.ts +101 -5
  765. package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
  766. package/src/types/api/firmwareUpdatePlan.ts +38 -0
  767. package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
  768. package/src/types/api/getDeviceState.ts +19 -0
  769. package/src/types/api/getFeatures.ts +3 -0
  770. package/src/types/api/getOnekeyFeatures.ts +3 -0
  771. package/src/types/api/getPassphraseState.ts +9 -11
  772. package/src/types/api/index.ts +54 -64
  773. package/src/types/api/kaspaSignTransaction.ts +60 -4
  774. package/src/types/api/openWalletSession.ts +54 -0
  775. package/src/types/api/protocolV2.ts +33 -141
  776. package/src/types/api/protocolV2ResourceManifest.ts +19 -0
  777. package/src/types/api/sessionCache.ts +19 -0
  778. package/src/types/device.ts +216 -10
  779. package/src/types/params.ts +9 -2
  780. package/src/types/settings.ts +86 -24
  781. package/src/utils/assets.ts +4 -1
  782. package/src/utils/deviceFeaturesCompat.ts +191 -0
  783. package/src/utils/deviceFeaturesUtils.ts +65 -47
  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/FilesystemDiskControl.d.ts +0 -13
  801. package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +0 -1
  802. package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
  803. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
  804. package/dist/types/api/getDeviceInfo.d.ts +0 -87
  805. package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
  806. package/src/api/GetDeviceInfo.ts +0 -145
  807. package/src/api/firmware/progressThrottle.ts +0 -44
  808. package/src/api/protocol-v2/FilesystemDiskControl.ts +0 -50
  809. package/src/deviceProfile/buildDeviceProfile.ts +0 -352
  810. package/src/types/api/getDeviceInfo.ts +0 -101
@@ -1,39 +1,45 @@
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,
9
10
  HardwareError,
10
11
  HardwareErrorCode,
11
12
  createDeferred,
13
+ createDeviceNotSupportMethodError,
12
14
  } from '@onekeyfe/hd-shared';
13
15
 
14
- import {
15
- LoggerNames,
16
- getDeviceBLEFirmwareVersion,
17
- getDeviceBleName,
18
- getDeviceFirmwareVersion,
19
- getDeviceLabel,
20
- getDeviceType,
21
- getDeviceUUID,
22
- getFirmwareType,
23
- getLogger,
24
- } from '../utils';
16
+ import { LoggerNames, getLogger } from '../utils';
25
17
  import {
26
18
  fixFeaturesFirmwareVersion,
27
19
  getPassphraseStateWithRefreshDeviceInfo,
28
- supportInputPinOnSoftware,
29
- supportModifyHomescreen,
30
20
  } from '../utils/deviceFeaturesUtils';
21
+ import { parseDeviceVersion } from '../utils/deviceVersionUtils';
31
22
  import { generateInstanceId } from '../utils/tracing';
32
23
  // eslint-disable-next-line import/no-cycle
33
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';
36
+ import { deviceWalletSessionStore } from './DeviceWalletSessionStore';
34
37
  import {
35
38
  type DeviceFirmwareRange,
36
39
  DeviceModelToTypes,
40
+ type DeviceStateEvent,
41
+ type DeviceStatePatch,
42
+ type DeviceStateUpdateSource,
37
43
  DeviceTypeToModels,
38
44
  type Device as DeviceTyped,
39
45
  EOneKeyDeviceMode,
@@ -48,23 +54,36 @@ import { DEVICE, UI_REQUEST } from '../events';
48
54
  import { DataManager } from '../data-manager';
49
55
  import TransportManager from '../data-manager/TransportManager';
50
56
  import { toHardened } from '../api/helpers/pathUtils';
51
- import { existCapability } from '../utils/capabilitieUtils';
52
57
  import {
53
- 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,
54
64
  requestProtocolV2DeviceInfo,
65
+ requestProtocolV2DeviceStatus,
66
+ requestProtocolV2ProtocolInfo,
67
+ supportsProtocolV2Message,
55
68
  } from '../protocols/protocol-v2/features';
56
- import { buildProtocolV1FeaturesPayload, buildProtocolV2FeaturesPayload } from '../deviceProfile';
69
+ import { buildProtocolV1FeaturesPayload } from '../deviceProfile';
70
+ import { resolveProtocolV2DeviceIdentity } from '../deviceProfile/protocolV2DeviceIdentity';
57
71
 
58
72
  import type { PROTO } from '../constants';
73
+ import type { DeviceStateReadOptions } from '../types/api/getDeviceState';
59
74
  import type {
60
75
  DeviceButtonRequestPayload,
61
76
  DeviceFeaturesPayload,
77
+ HardwareUiInteractionMeta,
62
78
  PassphraseRequestPayload,
79
+ ProtocolV2UiEventMetadata,
63
80
  } from '../events';
64
81
  import type { PassphrasePromptResponse } from './DeviceCommands';
65
82
  import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
66
83
  import type {
67
84
  OneKeyDeviceInfo as DeviceDescriptor,
85
+ DeviceStatus,
86
+ ProtocolInfo,
68
87
  ProtocolV2DeviceInfo,
69
88
  Success,
70
89
  } from '@onekeyfe/hd-transport';
@@ -76,7 +95,15 @@ export type InitOptions = {
76
95
  passphraseState?: string;
77
96
  deriveCardano?: boolean;
78
97
  connectProtocol?: HardwareConnectProtocol;
98
+ forceProtocolDetection?: boolean;
79
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;
80
107
  };
81
108
 
82
109
  export type RunOptions = {
@@ -91,11 +118,35 @@ const parseRunOptions = (options?: RunOptions): RunOptions => {
91
118
 
92
119
  const Log = getLogger(LoggerNames.Device);
93
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
+
94
141
  export interface DeviceEvents {
95
142
  [DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
96
- [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?];
97
147
  [DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
98
148
  [DEVICE.FEATURES]: [Device, DeviceFeaturesPayload];
149
+ [DEVICE.STATE]: [Device, DeviceStateEvent];
99
150
  [DEVICE.PASSPHRASE]: [
100
151
  Device,
101
152
  PassphraseRequestPayload,
@@ -119,15 +170,14 @@ export interface Device {
119
170
  emit<K extends keyof DeviceEvents>(type: K, ...args: DeviceEvents[K]): boolean;
120
171
  }
121
172
 
122
- const deviceSessionCache: Record<string, string> = {};
123
-
124
173
  /**
125
174
  * Pre-populate the device session cache with a known session ID.
126
175
  *
127
176
  * This allows short-lived processes (e.g. CLI) to restore a previously
128
177
  * obtained session, avoiding the need to re-enter passphrase on every
129
178
  * invocation. The session must have been obtained from a prior
130
- * 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.
131
181
  *
132
182
  * @param deviceId - The device's device_id (from features)
133
183
  * @param passphraseState - The passphrase state token
@@ -138,8 +188,7 @@ export function preloadSessionCache(
138
188
  passphraseState: string,
139
189
  sessionId: string
140
190
  ): void {
141
- const key = `${deviceId}@${passphraseState}`;
142
- deviceSessionCache[key] = sessionId;
191
+ deviceWalletSessionStore.set(deviceId, passphraseState, sessionId);
143
192
  }
144
193
 
145
194
  export class Device extends EventEmitter {
@@ -185,22 +234,52 @@ export class Device extends EventEmitter {
185
234
  */
186
235
  private deviceAcquired = false;
187
236
 
188
- /**
189
- * 唯一设备状态缓存。
190
- *
191
- * V1 直接保存原生 Features;V2 保存由 DeviceInfoGet 映射出的
192
- * Features 视图。Device 不再保存 profile,结构化 DeviceProfile 只作为
193
- * getDeviceInfo() 的 API 返回值存在。
194
- */
195
- features: Features | undefined = undefined;
237
+ /** Canonical device-state cache; legacy Features is a compatibility projection. */
238
+ private stateStore = new DeviceStateStore();
196
239
 
197
- /**
198
- * 是否需要更新设备信息。
199
- *
200
- * 历史名称保留用于兼容现有调用语义;对 V2 表示 features 需要由
201
- * DeviceInfoGet 刷新。
202
- */
203
- 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
+ }
204
283
 
205
284
  runPromise?: Deferred<void> | null;
206
285
 
@@ -254,38 +333,46 @@ export class Device extends EventEmitter {
254
333
 
255
334
  // simplified object to pass via postMessage
256
335
  toMessageObject(): DeviceTyped | null {
257
- if (this.isUnacquired()) return null;
336
+ if (this.isUnacquired() || !this.features) return null;
258
337
 
259
338
  const env = DataManager.getSettings('env');
260
339
  const deviceType = this.getCurrentDeviceType();
261
340
 
262
341
  const bleName = this.getCurrentBleName();
263
- const label = this.getCurrentLabel();
342
+ const displayName = this.getCurrentDisplayName();
264
343
  const serialNo = this.getCurrentSerialNo();
265
344
  const connectId = this.getConnectId();
266
345
  const deviceId = this.getCurrentDeviceId() || null;
267
346
 
268
- const features = this.features;
347
+ const { features } = this;
348
+ const state = this.state ? createPublicDeviceState(this.state) : undefined;
269
349
 
270
350
  return {
271
- /** Android uses Mac address, iOS uses uuid, USB uses uuid */
351
+ /** Android uses a MAC address, while iOS and USB use transport-specific identifiers. */
272
352
  connectId: DataManager.isBleConnect(env) ? this.mainId || null : connectId,
273
- /** 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. */
274
358
  uuid: serialNo,
275
359
  commType: this.originalDescriptor.commType,
276
360
  sdkInstanceId: this.sdkInstanceId,
277
361
  instanceId: this.instanceId,
278
362
  createdAt: this.createdAt,
279
363
  deviceType,
280
- /** 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. */
281
365
  deviceId,
282
366
  path: this.originalDescriptor?.path,
283
367
  bleName,
284
- name: bleName || label || `OneKey ${deviceType?.toUpperCase()}`,
285
- 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(),
286
373
  mode: this.getMode(),
287
374
  features,
288
- sessionId: this.features?.sessionId ?? null,
375
+ state,
289
376
  firmwareVersion: this.getFirmwareVersion(),
290
377
  bleFirmwareVersion: this.getBLEFirmwareVersion(),
291
378
  unavailableCapabilities: this.unavailableCapabilities,
@@ -296,13 +383,20 @@ export class Device extends EventEmitter {
296
383
  * Device connect
297
384
  * @returns {Promise<boolean>}
298
385
  */
299
- connect(connectProtocol?: HardwareConnectProtocol) {
386
+ connect(
387
+ connectProtocol?: HardwareConnectProtocol,
388
+ options?: { forceProtocolDetection?: boolean }
389
+ ) {
300
390
  const env = DataManager.getSettings('env');
301
391
  // eslint-disable-next-line no-async-promise-executor
302
392
  return new Promise<boolean>(async (resolve, reject) => {
303
393
  if (DataManager.isBleConnect(env)) {
394
+ if (this.hasDeviceAcquire() && this.commands && !this.commands.disposed) {
395
+ resolve(true);
396
+ return;
397
+ }
304
398
  try {
305
- await this.acquire(connectProtocol);
399
+ await this.acquire(connectProtocol, options);
306
400
  resolve(true);
307
401
  } catch (error) {
308
402
  reject(error);
@@ -312,7 +406,7 @@ export class Device extends EventEmitter {
312
406
  // 不存在 Session ID 或存在 Session ID 但设备在别处使用,都需要 acquire 获取最新 sessionID
313
407
  if (!this.mainId || (!this.isUsedHere() && this.originalDescriptor)) {
314
408
  try {
315
- await this.acquire(connectProtocol);
409
+ await this.acquire(connectProtocol, options);
316
410
  resolve(true);
317
411
  } catch (error) {
318
412
  reject(error);
@@ -328,25 +422,30 @@ export class Device extends EventEmitter {
328
422
  }
329
423
 
330
424
  async acquire(
331
- connectProtocol?: HardwareConnectProtocol,
332
- options?: { throwOnRunPromiseError?: boolean }
425
+ expectedProtocol?: HardwareConnectProtocol,
426
+ options?: { throwOnRunPromiseError?: boolean; forceProtocolDetection?: boolean }
333
427
  ) {
334
428
  const env = DataManager.getSettings('env');
335
429
  const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
336
- 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;
337
436
  try {
338
437
  let acquireResult: unknown;
339
438
  if (DataManager.isBleConnect(env)) {
340
- // forceCleanRunPromise=true(自 e21b83c6 引入,修复 Pro2 BLE 重连):
341
- // acquire 意味着开启一个全新会话,transport 里残留的上一次 runPromise
342
- // 必然属于已死亡的会话(如固件升级重启、探测中断),不清理会让新会话的
343
- // 调用被旧 promise 卡死。无法在 Device 层面区分“重连恢复”与普通 acquire,
344
- // 因此对 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.
345
443
  acquireResult = await this.deviceConnector?.acquire(
346
444
  this.originalDescriptor.id,
347
445
  undefined,
348
446
  true,
349
- expectedProtocol
447
+ strictProtocol,
448
+ undefined
350
449
  );
351
450
  this.mainId = (acquireResult as any)?.uuid ?? '';
352
451
  Log.debug('Expected uuid:', this.mainId);
@@ -355,23 +454,31 @@ export class Device extends EventEmitter {
355
454
  this.originalDescriptor.path,
356
455
  this.originalDescriptor.session,
357
456
  undefined,
358
- expectedProtocol
457
+ strictProtocol,
458
+ undefined
359
459
  );
360
460
  this.mainId = acquireResult as string | undefined;
361
461
  Log.debug('Expected session id:', this.mainId);
362
462
  }
363
- this.deviceAcquired = true;
364
- this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
365
-
366
463
  // Propagate protocol version detected during acquire.
367
464
  const detectedProtocol =
368
465
  (acquireResult as { protocolType?: HardwareConnectProtocol } | undefined)?.protocolType ??
369
466
  TransportManager.transport?.getProtocolType?.(
370
467
  DataManager.isBleConnect(env) ? this.originalDescriptor.id : this.originalDescriptor.path
371
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
+ }
372
477
  if (detectedProtocol) {
373
478
  this.originalDescriptor.protocolType = detectedProtocol;
374
479
  }
480
+ this.deviceAcquired = true;
481
+ this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
375
482
 
376
483
  if (this.commands) {
377
484
  await this.commands.dispose(false);
@@ -379,6 +486,22 @@ export class Device extends EventEmitter {
379
486
 
380
487
  this.commands = new DeviceCommands(this, this.mainId ?? '');
381
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
+ }
382
505
  if (options?.throwOnRunPromiseError) {
383
506
  throw error;
384
507
  }
@@ -420,7 +543,8 @@ export class Device extends EventEmitter {
420
543
  }
421
544
  }
422
545
  try {
423
- 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);
424
548
  this.updateDescriptor({ session: null } as DeviceDescriptor);
425
549
  } catch (err) {
426
550
  Log.error('[Device] release error: ', err);
@@ -482,12 +606,11 @@ export class Device extends EventEmitter {
482
606
  }
483
607
 
484
608
  /**
485
- * 唯一协议判别器。
609
+ * Canonical protocol discriminator.
486
610
  *
487
- * descriptor.protocolType 是协议探测后的结果;V2 features DeviceInfoGet
488
- * 映射产生。
489
- * SDK 的协议分支都必须走这里,不要直接读 originalDescriptor.protocolType
490
- * 或从 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.
491
614
  */
492
615
  getProtocol(): 'V1' | 'V2' {
493
616
  return this.originalDescriptor.protocolType === 'V2' ? 'V2' : 'V1';
@@ -498,53 +621,75 @@ export class Device extends EventEmitter {
498
621
  }
499
622
 
500
623
  getCurrentDeviceType() {
501
- return getDeviceType(this.features);
624
+ return this.state?.identity.deviceType ?? EDeviceType.Unknown;
502
625
  }
503
626
 
504
627
  getCurrentDeviceId() {
505
- return this.features?.deviceId || undefined;
628
+ return this.state?.identity.deviceId || undefined;
506
629
  }
507
630
 
508
631
  getCurrentSerialNo() {
509
- return this.features ? getDeviceUUID(this.features) : '';
632
+ return this.state?.identity.serialNo ?? '';
510
633
  }
511
634
 
512
635
  getConnectId() {
513
636
  const serialNo = this.getCurrentSerialNo();
514
637
  if (serialNo) return serialNo;
515
638
 
516
- // connectId SDK 内部连接路由 key。这里兜底到 transport descriptor
517
- // 不改变 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.
518
641
  return this.originalDescriptor.path || this.originalDescriptor.id || '';
519
642
  }
520
643
 
521
644
  getCurrentBleName() {
522
- return getDeviceBleName(this.features);
645
+ return this.state?.identity.bleName ?? null;
523
646
  }
524
647
 
525
648
  getCurrentLabel() {
526
- 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)}`;
527
667
  }
528
668
 
529
669
  getCurrentPassphraseProtection() {
530
- return this.features?.passphraseProtection;
670
+ return this.state?.status.passphraseProtection;
531
671
  }
532
672
 
533
673
  getCurrentFirmwareType() {
534
- return getFirmwareType(this.features);
674
+ return this.state?.identity.firmwareType ?? EFirmwareType.Universal;
535
675
  }
536
676
 
537
677
  getCurrentFirmwareVersionString() {
538
- return getDeviceFirmwareVersion(this.features)?.join('.');
678
+ return parseDeviceVersion(this.state?.versions.firmware).join('.');
539
679
  }
540
680
 
541
681
  getCurrentBLEFirmwareVersionString() {
542
- if (!this.features) return undefined;
543
- 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('.');
544
689
  }
545
690
 
546
691
  getCurrentSafetyChecks() {
547
- return this.features?.safetyChecks;
692
+ return this.state?.settings.safetyChecks;
548
693
  }
549
694
 
550
695
  getCurrentMethodVersionRange(
@@ -557,6 +702,7 @@ export class Device extends EventEmitter {
557
702
  // Most-specific model first; must match getMethodVersionRange in deviceInfoUtils,
558
703
  // otherwise e.g. Classic1s resolves the looser model_mini range before model_classic1s.
559
704
  const modelFallbacks: IDeviceModel[] = [
705
+ 'model_pro2',
560
706
  'model_classic1s',
561
707
  'model_classic',
562
708
  'model_mini',
@@ -576,7 +722,8 @@ export class Device extends EventEmitter {
576
722
  if (
577
723
  deviceType === EDeviceType.Touch ||
578
724
  deviceType === EDeviceType.Pro ||
579
- deviceType === EDeviceType.Pro2
725
+ deviceType === EDeviceType.Pro2 ||
726
+ deviceType === EDeviceType.Neo
580
727
  ) {
581
728
  return { support: true };
582
729
  }
@@ -589,13 +736,12 @@ export class Device extends EventEmitter {
589
736
  }
590
737
 
591
738
  supportInputPinOnSoftware(): SupportFeatureType {
592
- if (this.features) return supportInputPinOnSoftware(this.features);
593
-
594
739
  const deviceType = this.getCurrentDeviceType();
595
740
  if (
596
741
  deviceType === EDeviceType.Touch ||
597
742
  deviceType === EDeviceType.Pro ||
598
- deviceType === EDeviceType.Pro2
743
+ deviceType === EDeviceType.Pro2 ||
744
+ deviceType === EDeviceType.Neo
599
745
  ) {
600
746
  return { support: false };
601
747
  }
@@ -608,15 +754,12 @@ export class Device extends EventEmitter {
608
754
  }
609
755
 
610
756
  supportModifyHomescreen(): SupportFeatureType {
611
- // Pro2 走独立 1.x 版本线,不能套用 Touch/Pro 3.4.0 门槛(恒 false 且未来会误判)。
612
- // 依据:firmware-pro2 协议 schema(messages-protocol-v2.json)的 ApplySettings
613
- // 包含 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.
614
759
  if (this.isProtocolV2()) {
615
760
  return { support: true };
616
761
  }
617
762
 
618
- if (this.features) return supportModifyHomescreen(this.features);
619
-
620
763
  const deviceType = this.getCurrentDeviceType();
621
764
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
622
765
  return { support: true };
@@ -628,29 +771,29 @@ export class Device extends EventEmitter {
628
771
  };
629
772
  }
630
773
 
631
- private generateStateKey(deviceId: string, passphraseState?: string) {
632
- if (passphraseState) {
633
- return `${deviceId}@${passphraseState}`;
634
- }
635
- return deviceId;
636
- }
637
-
638
774
  private getSessionCacheDeviceKey(_deviceId?: string) {
639
775
  const deviceId = _deviceId || this.getCurrentDeviceId();
640
776
  if (deviceId) return deviceId;
641
777
  if (this.isProtocolV2()) {
642
- return this.originalDescriptor.path || this.originalDescriptor.id;
778
+ return this.originalDescriptor.path;
643
779
  }
644
780
  return undefined;
645
781
  }
646
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
+
647
791
  getInternalState(_deviceId?: string) {
648
- Log.debug('getInternalState session cache: ', deviceSessionCache);
649
792
  Log.debug(
650
793
  'getInternalState session param: ',
651
794
  `device_id: ${_deviceId}`,
652
- `features.deviceId: ${this.features?.deviceId}`,
653
- `passphraseState: ${this.passphraseState}`
795
+ `currentDeviceId: ${this.getCurrentDeviceId()}`,
796
+ `hasPassphraseState: ${Boolean(this.passphraseState)}`
654
797
  );
655
798
 
656
799
  const deviceId = this.getSessionCacheDeviceKey(_deviceId);
@@ -663,8 +806,13 @@ export class Device extends EventEmitter {
663
806
  // downstream call carries it and hits the primary lookup below.
664
807
  if (!this.passphraseState) return undefined;
665
808
 
666
- const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
667
- return deviceSessionCache[usePassKey];
809
+ return deviceWalletSessionStore.get(deviceId, this.passphraseState);
810
+ }
811
+
812
+ getStandardInternalState(_deviceId?: string) {
813
+ const deviceId = this.getSessionCacheDeviceKey(_deviceId);
814
+ if (!deviceId) return undefined;
815
+ return deviceWalletSessionStore.getStandard(deviceId);
668
816
  }
669
817
 
670
818
  // attach to pin to fix internal state
@@ -673,46 +821,45 @@ export class Device extends EventEmitter {
673
821
  passphraseState: string | undefined,
674
822
  deviceId: string | undefined,
675
823
  sessionId: string | null = null,
676
- featuresSessionId: string | null = null
824
+ featuresSessionId: string | null = null,
825
+ walletType: 'standard' | 'hidden' = 'hidden'
677
826
  ) {
678
827
  Log.debug(
679
828
  'updateInternalState session param: ',
680
829
  `device_id: ${deviceId}`,
681
830
  `enablePassphrase: ${enablePassphrase}`,
682
- `passphraseState: ${passphraseState}`,
683
- `sessionId: ${sessionId}`,
684
- `featuresSessionId: ${featuresSessionId}`
831
+ `hasPassphraseState: ${Boolean(passphraseState)}`,
832
+ `hasSessionId: ${Boolean(sessionId)}`,
833
+ `hasFeaturesSessionId: ${Boolean(featuresSessionId)}`
685
834
  );
686
835
 
687
836
  const cacheDeviceKey = this.getSessionCacheDeviceKey(deviceId);
688
837
  if (!cacheDeviceKey) return;
689
838
 
690
839
  if (enablePassphrase) {
691
- // update the sessionId
692
- if (sessionId) {
693
- deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] = sessionId;
694
- } else if (featuresSessionId) {
695
- deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] =
696
- featuresSessionId;
840
+ const walletSessionId =
841
+ sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
842
+ if (walletType === 'standard') {
843
+ deviceWalletSessionStore.setStandard(
844
+ cacheDeviceKey,
845
+ passphraseState,
846
+ walletSessionId ?? undefined
847
+ );
848
+ } else {
849
+ deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
697
850
  }
698
851
  }
699
852
 
700
- // delete the old sessionId
701
- const oldKey = `${cacheDeviceKey}`;
702
- if (deviceSessionCache[oldKey]) {
703
- delete deviceSessionCache[oldKey];
704
- }
705
-
706
- Log.debug('updateInternalState session cache: ', deviceSessionCache);
853
+ deviceWalletSessionStore.deletePending(cacheDeviceKey);
707
854
  }
708
855
 
709
856
  private setInternalState(state: string, initSession?: boolean) {
710
857
  Log.debug(
711
858
  'setInternalState session param: ',
712
- `state: ${state}`,
859
+ `hasState: ${Boolean(state)}`,
713
860
  `initSession: ${initSession}`,
714
- `deviceId: ${this.features?.deviceId}`,
715
- `passphraseState: ${this.passphraseState}`
861
+ `deviceId: ${this.getCurrentDeviceId()}`,
862
+ `hasPassphraseState: ${Boolean(this.passphraseState)}`
716
863
  );
717
864
 
718
865
  if (!this.passphraseState && !initSession) return;
@@ -720,12 +867,11 @@ export class Device extends EventEmitter {
720
867
  const deviceId = this.getSessionCacheDeviceKey();
721
868
  if (!deviceId) return;
722
869
 
723
- const key = this.generateStateKey(deviceId, this.passphraseState);
724
-
725
- if (state) {
726
- deviceSessionCache[key] = state;
870
+ if (this.passphraseState) {
871
+ deviceWalletSessionStore.set(deviceId, this.passphraseState, state);
872
+ } else if (initSession) {
873
+ deviceWalletSessionStore.setPending(deviceId, state);
727
874
  }
728
- Log.debug('setInternalState done session cache: ', deviceSessionCache);
729
875
  }
730
876
 
731
877
  clearInternalState(_deviceId?: string) {
@@ -733,70 +879,80 @@ export class Device extends EventEmitter {
733
879
 
734
880
  const deviceId = this.getSessionCacheDeviceKey(_deviceId);
735
881
  if (!deviceId) return;
736
- const key = `${deviceId}`;
737
- delete deviceSessionCache[key];
882
+ deviceWalletSessionStore.deletePending(deviceId);
738
883
 
739
884
  if (this.passphraseState) {
740
- const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
741
- delete deviceSessionCache[usePassKey];
885
+ deviceWalletSessionStore.delete(deviceId, this.passphraseState);
742
886
  }
743
887
  }
744
888
 
889
+ clearStandardInternalState(_deviceId?: string) {
890
+ const deviceId = this.getSessionCacheDeviceKey(_deviceId);
891
+ if (!deviceId) return;
892
+ deviceWalletSessionStore.deleteStandard(deviceId);
893
+ }
894
+
745
895
  async initialize(options?: InitOptions) {
746
- // Protocol V2 不支持传统 Initialize,直接使用协议专用初始化流程。
896
+ // Protocol V2 does not support legacy Initialize; use its dedicated flow.
747
897
  if (this.isProtocolV2()) {
748
898
  this.passphraseState = options?.passphraseState;
749
- if (this.features && !this.featuresNeedsReload && !options?.initSession) {
750
- if (this.features.bootloaderMode) {
899
+ if (this.state && !options?.initSession && !this.protocolV2StateNeedsReload) {
900
+ if (this.state.status.mode === 'bootloader' || this.state.status.mode === 'romloader') {
751
901
  return;
752
902
  }
753
- // 不能直接信任缓存 features:设备端 wipe / 完成初始化 / label
754
- // features 会永久陈旧。每次 run 做一次轻量 status 刷新(不含 fw/SE),
755
- // 用字段级合并保留已有版本和 SE 信息。
756
- 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.
757
905
  return;
758
906
  }
759
907
  await this._initializeProtocolV2(options);
908
+ this.protocolV2StateNeedsReload = false;
760
909
  return;
761
910
  }
762
911
 
763
- // 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
+ };
764
923
 
765
- 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
+ }
766
936
 
767
- if (options?.initSession) {
768
- this.clearInternalState(options?.deviceId);
769
- }
937
+ this.passphraseState = options?.passphraseState;
770
938
 
771
- const internalState = this.getInternalState(options?.deviceId);
772
- const payload: any = {};
773
- if (internalState) {
774
- payload.session_id = internalState;
775
- }
939
+ if (options?.initSession) {
940
+ this.clearInternalState(options?.deviceId);
941
+ }
776
942
 
777
- if (options?.deriveCardano) {
778
- payload.derive_cardano = true;
779
- }
780
- payload.passphrase_state = options?.passphraseState;
781
- 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
+ }
782
954
 
783
- const initStartAt = Date.now();
784
- try {
785
- // @ts-expect-error
786
- const { message } = await Promise.race([
787
- this.commands.typedCall('Initialize', 'Features', payload),
788
- new Promise((_, reject) => {
789
- setTimeout(() => {
790
- reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
791
- // iOS ble bound device timeout 20s
792
- }, 25 * 1000);
793
- }),
794
- ]);
795
-
796
- const initCostMs = Date.now() - initStartAt;
797
- this.setLastInitializeDuration(initCostMs);
798
- this._updateFeatures(message, options?.initSession);
799
- await TransportManager.reconfigure(this.features);
955
+ await callInitialize(payload, options?.initSession);
800
956
  } catch (error) {
801
957
  Log.error('Initialization failed:', error);
802
958
  throw error;
@@ -806,59 +962,38 @@ export class Device extends EventEmitter {
806
962
  /**
807
963
  * Device initialization over Protocol V2.
808
964
  *
809
- * Protocol V2 不走传统 Initialize/GetFeatures;直接用 DeviceInfoGet
810
- * 生成唯一的 features 状态。
965
+ * Protocol V2 bypasses legacy Initialize/GetFeatures and builds its canonical
966
+ * features state directly from DeviceInfoGet.
811
967
  */
812
968
  private async _initializeProtocolV2(options?: InitOptions) {
813
969
  Log.debug('Initialize device via Protocol V2 features adapter');
814
970
 
815
971
  try {
816
- // 超时由 requestProtocolV2DeviceInfo 内部的 typedCall timeoutMs(默认 10s)负责,
817
- // 不再额外包一层 Promise.race:外层 race timer 不会清理,
818
- // 且 reject 后底层调用仍会残留。
972
+ // typedCall applies the request timeout. An outer Promise.race would leak its
973
+ // timer and leave the underlying call active after rejection.
819
974
  const deviceInfo = await requestProtocolV2DeviceInfo({
820
975
  commands: this.commands,
821
976
  timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
822
977
  });
823
- // 默认请求不含 SE/hash 数据,scope 如实标注为 basic
824
- // 完整数据由 getDeviceInfo(scope:'verify'|'full') 获取。
825
- 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
+ );
826
984
  Log.debug('Protocol V2 features:', features);
827
- this.featuresNeedsReload = false;
828
985
  } catch (error) {
829
986
  Log.error('Protocol V2 initialization failed:', error);
830
987
  throw error;
831
988
  }
832
989
  }
833
990
 
834
- /**
835
- * Protocol V2 的轻量状态刷新(每次 run 前调用)。
836
- *
837
- * 请求 hw + coprocessor + status(不含 fw/SE target):status 提供 init_states / label /
838
- * passphrase_enabled 等会在设备端变化的字段;hw/coprocessor 提供 serialNo / bleName。
839
- * versions 为空时按字段级合并保留旧值,verify 数据不会被降级。
840
- */
841
- private async _refreshProtocolV2Status(options?: InitOptions) {
842
- try {
843
- const deviceInfo = await requestProtocolV2DeviceInfo({
844
- commands: this.commands,
845
- request: PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
846
- timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
847
- });
848
- const features = this.updateProtocolV2Features(deviceInfo);
849
- Log.debug('Protocol V2 features (status refresh):', features);
850
- } catch (error) {
851
- Log.error('Protocol V2 status refresh failed:', error);
852
- throw error;
853
- }
854
- }
855
-
856
991
  async getFeatures() {
857
992
  if (this.isProtocolV2()) {
858
993
  const deviceInfo = await requestProtocolV2DeviceInfo({
859
994
  commands: this.commands,
860
995
  });
861
- return this.updateProtocolV2Features(deviceInfo);
996
+ return this.probeProtocolV2RuntimeState(deviceInfo);
862
997
  }
863
998
 
864
999
  const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
@@ -866,36 +1001,332 @@ export class Device extends EventEmitter {
866
1001
  return this.features;
867
1002
  }
868
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
+
869
1075
  _updateFeatures(protoFeatures: PROTO.Features | Features, initSession?: boolean) {
1076
+ const previousDeviceId = this.getCurrentDeviceId();
870
1077
  let feat =
871
1078
  'protocol' in protoFeatures
872
1079
  ? protoFeatures
873
1080
  : buildProtocolV1FeaturesPayload(protoFeatures, this.features);
874
1081
 
875
- // GetFeatures doesn't return 'session_id'
876
- if (this.features?.sessionId && !feat.sessionId) {
877
- feat.sessionId = this.features.sessionId;
878
- }
879
- if (this.getCurrentDeviceId() && feat.sessionId) {
880
- this.setInternalState(feat.sessionId, initSession);
881
- }
882
1082
  feat.unlocked = feat.unlocked ?? true;
883
1083
 
884
1084
  feat = fixFeaturesFirmwareVersion(feat);
885
1085
 
886
- this.features = feat;
887
- this.featuresNeedsReload = false;
888
- this.emit(DEVICE.FEATURES, this, feat);
1086
+ this.updateState(mapFeaturesToState(feat), 'initialize');
1087
+ this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
1088
+ if (feat.deviceId && feat.sessionId) {
1089
+ this.setInternalState(feat.sessionId, initSession);
1090
+ }
1091
+ }
1092
+
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
1192
+ );
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;
1219
+ }
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;
889
1242
  }
890
1243
 
891
- updateProtocolV2Features(deviceInfo?: ProtocolV2DeviceInfo) {
892
- const features = fixFeaturesFirmwareVersion(
893
- buildProtocolV2FeaturesPayload(deviceInfo, this.features)
1244
+ updateProtocolV2Status(status: DeviceStatus) {
1245
+ const previousDeviceInfo = this.state?.raw?.protocolV2DeviceInfo;
1246
+ const previousStatus = this.state?.raw?.protocolV2DeviceStatus;
1247
+ return this.updateProtocolV2Features(previousDeviceInfo, {
1248
+ ...previousStatus,
1249
+ ...status,
1250
+ });
1251
+ }
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'
894
1329
  );
895
- this.features = features;
896
- this.featuresNeedsReload = false;
897
- this.emit(DEVICE.FEATURES, this, features);
898
- return features;
899
1330
  }
900
1331
 
901
1332
  /**
@@ -916,8 +1347,7 @@ export class Device extends EventEmitter {
916
1347
  }
917
1348
 
918
1349
  if (forceUpdate) {
919
- // 枚举得到的 descriptor 可能不带 protocolType(如 WebUSB enumerate),
920
- // 不能让覆盖丢掉已探测的协议结果。
1350
+ // Enumerated descriptors may omit protocolType, so preserve an actively probed value.
921
1351
  this.originalDescriptor = {
922
1352
  ...descriptor,
923
1353
  protocolType: descriptor.protocolType ?? this.originalDescriptor.protocolType,
@@ -942,19 +1372,43 @@ export class Device extends EventEmitter {
942
1372
 
943
1373
  options = parseRunOptions(options);
944
1374
 
945
- this.runPromise = createDeferred(this._runInner.bind(this, fn, options));
946
- 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;
947
1384
  }
948
1385
 
949
- async _runInner<T>(fn: (() => Promise<T>) | undefined, options: RunOptions) {
950
- if (!this.isUsedHere() || this.commands.disposed) {
951
- 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) {
952
1403
  if (env !== 'react-native') {
953
1404
  try {
954
- await this.acquire(options.connectProtocol);
1405
+ await this.acquire(options.connectProtocol, {
1406
+ forceProtocolDetection: options.forceProtocolDetection,
1407
+ });
955
1408
  } catch (error) {
956
- this.runPromise = null;
957
- return Promise.reject(error);
1409
+ clearRunPromise();
1410
+ runPromise.reject(error);
1411
+ return;
958
1412
  }
959
1413
 
960
1414
  try {
@@ -964,16 +1418,19 @@ export class Device extends EventEmitter {
964
1418
  }
965
1419
  }
966
1420
  } catch (error) {
967
- this.runPromise = null;
1421
+ await this.release();
1422
+ clearRunPromise();
968
1423
  if (error instanceof HardwareError) {
969
- return Promise.reject(error);
1424
+ runPromise.reject(error);
1425
+ return;
970
1426
  }
971
- return Promise.reject(
1427
+ runPromise.reject(
972
1428
  ERRORS.TypedError(
973
1429
  HardwareErrorCode.DeviceInitializeFailed,
974
1430
  `Initialize failed: ${error.message as string}, code: ${error.code as string}`
975
1431
  )
976
1432
  );
1433
+ return;
977
1434
  }
978
1435
  } else if (env === 'react-native') {
979
1436
  // TODO: implement react-native acquire
@@ -992,9 +1449,7 @@ export class Device extends EventEmitter {
992
1449
  try {
993
1450
  await fn();
994
1451
  } catch (e) {
995
- if (this.runPromise) {
996
- this.runPromise.reject(e);
997
- }
1452
+ runPromise.reject(e);
998
1453
 
999
1454
  if (
1000
1455
  e instanceof HardwareError &&
@@ -1007,7 +1462,7 @@ export class Device extends EventEmitter {
1007
1462
  Log.debug(`error code ${e.errorCode} release device, mainId: ${this.mainId}`);
1008
1463
  }
1009
1464
 
1010
- this.runPromise = null;
1465
+ clearRunPromise();
1011
1466
  return;
1012
1467
  }
1013
1468
  }
@@ -1021,11 +1476,8 @@ export class Device extends EventEmitter {
1021
1476
  Log.debug('release device, mainId: ', this.mainId);
1022
1477
  }
1023
1478
 
1024
- if (this.runPromise) {
1025
- this.runPromise.resolve();
1026
- }
1027
-
1028
- this.runPromise = null;
1479
+ runPromise.resolve();
1480
+ clearRunPromise();
1029
1481
  }
1030
1482
 
1031
1483
  async interruptionFromOutside() {
@@ -1064,33 +1516,37 @@ export class Device extends EventEmitter {
1064
1516
  }
1065
1517
 
1066
1518
  getMode() {
1067
- if (this.features?.bootloaderMode) {
1068
- // bootloader mode
1069
- return EOneKeyDeviceMode.bootloader;
1070
- }
1071
-
1072
- if (!this.features?.initialized) {
1073
- // not initialized
1074
- return EOneKeyDeviceMode.notInitialized;
1075
- }
1076
-
1077
- if (this.features?.noBackup) {
1078
- // backup mode
1079
- 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;
1080
1531
  }
1081
1532
 
1082
- // normal mode
1083
1533
  return EOneKeyDeviceMode.normal;
1084
1534
  }
1085
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
+
1086
1542
  getFirmwareVersion() {
1087
- if (!this.features) return null;
1088
- return getDeviceFirmwareVersion(this.features);
1543
+ if (!this.state) return null;
1544
+ return parseDeviceVersion(this.state.versions.firmware);
1089
1545
  }
1090
1546
 
1091
1547
  getBLEFirmwareVersion() {
1092
- if (!this.features) return null;
1093
- return getDeviceBLEFirmwareVersion(this.features);
1548
+ if (!this.state) return null;
1549
+ return parseDeviceVersion(this.state.versions.ble);
1094
1550
  }
1095
1551
 
1096
1552
  isUsed() {
@@ -1108,7 +1564,7 @@ export class Device extends EventEmitter {
1108
1564
  isUsedHere() {
1109
1565
  const env = DataManager.getSettings('env');
1110
1566
  if (DataManager.isBleConnect(env)) {
1111
- return false;
1567
+ return this.deviceAcquired;
1112
1568
  }
1113
1569
  return this.isUsed() && this.originalDescriptor.session === this.mainId;
1114
1570
  }
@@ -1118,26 +1574,39 @@ export class Device extends EventEmitter {
1118
1574
  }
1119
1575
 
1120
1576
  isBootloader() {
1121
- 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
+ );
1122
1589
  }
1123
1590
 
1124
1591
  isInitialized() {
1125
- return this.features && !!this.features.initialized;
1592
+ if (!this.state) return undefined;
1593
+ return this.state.status.initialized === true;
1126
1594
  }
1127
1595
 
1128
1596
  isSeedless() {
1129
- return this.features && !!this.features.noBackup;
1597
+ if (!this.state) return undefined;
1598
+ return this.state.status.noBackup === true;
1130
1599
  }
1131
1600
 
1132
1601
  isUnacquired(): boolean {
1133
- return this.features === undefined;
1602
+ return this.state === undefined;
1134
1603
  }
1135
1604
 
1136
1605
  hasUnexpectedMode(allow: string[], require: string[]) {
1137
1606
  // both allow and require cases might generate single unexpected mode
1138
1607
  if (!this.isUnacquired()) {
1139
1608
  // allow cases
1140
- if (this.isBootloader() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
1609
+ if (this.isBootloader() && !this.isProtocolV2() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
1141
1610
  return UI_REQUEST.BOOTLOADER;
1142
1611
  }
1143
1612
  if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {
@@ -1160,8 +1629,9 @@ export class Device extends EventEmitter {
1160
1629
  const isModeT =
1161
1630
  deviceType === EDeviceType.Touch ||
1162
1631
  deviceType === EDeviceType.Pro ||
1163
- deviceType === EDeviceType.Pro2;
1164
- const unlocked = this.features?.unlocked;
1632
+ deviceType === EDeviceType.Pro2 ||
1633
+ deviceType === EDeviceType.Neo;
1634
+ const unlocked = this.state?.status.unlocked;
1165
1635
  const preCheckTouch = isModeT && unlocked === false;
1166
1636
  const passphraseProtection = this.getCurrentPassphraseProtection();
1167
1637
 
@@ -1174,12 +1644,91 @@ export class Device extends EventEmitter {
1174
1644
 
1175
1645
  async lockDevice(): Promise<Success> {
1176
1646
  const res = await this.commands.typedCall('LockDevice', 'Success', {});
1647
+ this.updateState({ status: { unlocked: false } }, 'lock');
1177
1648
  return res.message;
1178
1649
  }
1179
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
+
1180
1730
  supportUnlockVersionRange(): DeviceFirmwareRange {
1181
- // 仅适用于 Protocol V1 Pro 系列;Pro2 走独立版本线,
1182
- // 且 Protocol V2 固件从首个版本即支持 UnLockDevice(见 unlockDevice 的 isProtocolV2 短路)。
1731
+ // This range applies to Protocol V1 Pro devices; Pro2 has a dedicated unlock flow.
1183
1732
  return {
1184
1733
  pro: {
1185
1734
  min: '4.15.0',
@@ -1187,19 +1736,62 @@ export class Device extends EventEmitter {
1187
1736
  };
1188
1737
  }
1189
1738
 
1190
- async unlockDevice() {
1739
+ async unlockDevice(
1740
+ pinType?: DeviceSessionPinType,
1741
+ options?: ProtocolV2UiEventMetadata & { emitUiEvent?: boolean }
1742
+ ) {
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
+ }
1762
+ try {
1763
+ await this.commands.typedCall('DeviceSessionAskPin', 'Success', {
1764
+ type: requestedPinType,
1765
+ });
1766
+ } catch (error) {
1767
+ const errorText =
1768
+ error instanceof Error
1769
+ ? `${error.name} ${error.message}`
1770
+ : String((error as { message?: unknown } | null)?.message ?? error ?? '');
1771
+ if (errorText.includes('Failure_UnexpectedMessage')) {
1772
+ throw createDeviceNotSupportMethodError('deviceUnlock', this.getCurrentFirmwareType());
1773
+ }
1774
+ throw error;
1775
+ }
1776
+
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);
1784
+ }
1785
+
1191
1786
  const firmwareVersion = this.getCurrentFirmwareVersionString() ?? '0.0.0';
1192
1787
  const versionRange = this.getCurrentMethodVersionRange(
1193
1788
  type => this.supportUnlockVersionRange()[type]
1194
1789
  );
1195
1790
 
1196
- const supportAttachPinCapability = existCapability(
1197
- this.features,
1791
+ const supportAttachPinCapability = this.state?.capabilities.includes(
1198
1792
  Enum_Capability.Capability_AttachToPin
1199
1793
  );
1200
- // Pro2 (Protocol V2) 版本线独立于 Pro 系列,固件从首个版本即支持 UnLockDevice
1201
1794
  const supportUnlock =
1202
- this.isProtocolV2() ||
1203
1795
  supportAttachPinCapability ||
1204
1796
  (versionRange &&
1205
1797
  semver.valid(firmwareVersion) &&
@@ -1207,12 +1799,21 @@ export class Device extends EventEmitter {
1207
1799
 
1208
1800
  if (supportUnlock) {
1209
1801
  const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
1210
- if (this.features) {
1211
- this.features.unlocked = res.message.unlocked == null ? null : res.message.unlocked;
1212
- this.features.unlockedAttachPin =
1213
- res.message.unlocked_attach_pin == null ? undefined : res.message.unlocked_attach_pin;
1214
- this.features.passphraseProtection =
1215
- 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
+ );
1216
1817
 
1217
1818
  return Promise.resolve(this.features);
1218
1819
  }
@@ -1221,14 +1822,6 @@ export class Device extends EventEmitter {
1221
1822
  return Promise.resolve(features);
1222
1823
  }
1223
1824
 
1224
- // legacy 解锁探测仅适用于 Protocol V1 老固件;V2 固件必然支持 UnLockDevice
1225
- if (this.isProtocolV2()) {
1226
- throw ERRORS.TypedError(
1227
- HardwareErrorCode.RuntimeError,
1228
- 'unlock device error: device firmware does not support UnLockDevice'
1229
- );
1230
- }
1231
-
1232
1825
  const { type } = await this.commands.typedCall('GetAddress', 'Address', {
1233
1826
  address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
1234
1827
  coin_name: 'Testnet',
@@ -1247,25 +1840,34 @@ export class Device extends EventEmitter {
1247
1840
  async checkPassphraseStateSafety(
1248
1841
  passphraseState?: string,
1249
1842
  useEmptyPassphrase?: boolean,
1250
- skipPassphraseCheck?: boolean
1843
+ skipPassphraseCheck?: boolean,
1844
+ deriveCardano?: boolean
1251
1845
  ) {
1252
1846
  if (this.isUnacquired()) return false;
1253
1847
 
1848
+ const expectedPassphraseState = useEmptyPassphrase ? undefined : passphraseState;
1254
1849
  const { passphraseState: newPassphraseState, unlockedAttachPin } =
1255
1850
  await getPassphraseStateWithRefreshDeviceInfo(this, {
1256
- expectPassphraseState: passphraseState,
1851
+ expectPassphraseState: expectedPassphraseState,
1257
1852
  onlyMainPin: useEmptyPassphrase,
1853
+ deriveCardano,
1854
+ rejectAttachPinForMainWallet: useEmptyPassphrase === true,
1258
1855
  });
1259
1856
 
1260
1857
  // Main wallet and unlock Attach Pin, throw safe error
1261
1858
  const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
1262
1859
  const useErrorAttachPin =
1263
- unlockedAttachPin && passphraseState && passphraseState !== newPassphraseState;
1264
- const passphraseStateMismatch = !!passphraseState && passphraseState !== newPassphraseState;
1860
+ unlockedAttachPin &&
1861
+ expectedPassphraseState &&
1862
+ expectedPassphraseState !== newPassphraseState;
1863
+ const passphraseStateMismatch =
1864
+ !!expectedPassphraseState && expectedPassphraseState !== newPassphraseState;
1265
1865
 
1266
1866
  Log.debug('Check passphrase state safety: ', {
1267
- passphraseState,
1268
- newPassphraseState,
1867
+ hasExpectedPassphraseState: Boolean(expectedPassphraseState),
1868
+ hasNewPassphraseState: Boolean(newPassphraseState),
1869
+ passphraseStateMatches:
1870
+ Boolean(expectedPassphraseState) && expectedPassphraseState === newPassphraseState,
1269
1871
  unlockedAttachPin,
1270
1872
  useEmptyPassphrase,
1271
1873
  });