@onekeyfe/hd-core 1.2.0-alpha.6 → 1.2.0-alpha.61

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