@onekeyfe/hd-core 1.2.0-alpha.4 → 1.2.0-alpha.40

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