@onekeyfe/hd-core 1.2.0-alpha.14 → 1.2.0-alpha.141

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