@onetokenfe/hd-core 1.1.23

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 (382) hide show
  1. package/.eslintrc +6 -0
  2. package/README.md +32 -0
  3. package/__tests__/benfen.test.ts +68 -0
  4. package/__tests__/checkBootloaderReleast.test.ts +115 -0
  5. package/__tests__/evmSignTransaction.test.ts +419 -0
  6. package/jest.config.js +6 -0
  7. package/package.json +48 -0
  8. package/src/api/BaseMethod.ts +275 -0
  9. package/src/api/CheckAllFirmwareRelease.ts +73 -0
  10. package/src/api/CheckBLEFirmwareRelease.ts +23 -0
  11. package/src/api/CheckBootloaderRelease.ts +32 -0
  12. package/src/api/CheckBridgeRelease.ts +28 -0
  13. package/src/api/CheckBridgeStatus.ts +32 -0
  14. package/src/api/CheckFirmwareRelease.ts +31 -0
  15. package/src/api/CheckFirmwareTypeAvailable.tsx +30 -0
  16. package/src/api/CipherKeyValue.ts +68 -0
  17. package/src/api/FirmwareUpdate.ts +219 -0
  18. package/src/api/FirmwareUpdateV2.ts +408 -0
  19. package/src/api/FirmwareUpdateV3.ts +560 -0
  20. package/src/api/GetFeatures.ts +23 -0
  21. package/src/api/GetLogs.ts +40 -0
  22. package/src/api/GetOnetokenFeatures.ts +25 -0
  23. package/src/api/GetPassphraseState.ts +28 -0
  24. package/src/api/PromptWebDeviceAccess.ts +77 -0
  25. package/src/api/SearchDevices.ts +50 -0
  26. package/src/api/alephium/AlephiumGetAddress.ts +84 -0
  27. package/src/api/alephium/AlephiumSignMessage.ts +51 -0
  28. package/src/api/alephium/AlephiumSignTransaction.ts +135 -0
  29. package/src/api/algo/AlgoGetAddress.ts +73 -0
  30. package/src/api/algo/AlgoSignTransaction.ts +52 -0
  31. package/src/api/allnetwork/AllNetworkGetAddress.ts +88 -0
  32. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +529 -0
  33. package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +162 -0
  34. package/src/api/aptos/AptosGetAddress.ts +129 -0
  35. package/src/api/aptos/AptosGetPublicKey.ts +64 -0
  36. package/src/api/aptos/AptosSignInMessage.ts +55 -0
  37. package/src/api/aptos/AptosSignMessage.ts +79 -0
  38. package/src/api/aptos/AptosSignTransaction.ts +72 -0
  39. package/src/api/benfen/BenfenGetAddress.ts +122 -0
  40. package/src/api/benfen/BenfenGetPublicKey.ts +68 -0
  41. package/src/api/benfen/BenfenSignMessage.ts +50 -0
  42. package/src/api/benfen/BenfenSignTransaction.ts +105 -0
  43. package/src/api/benfen/normalize.ts +51 -0
  44. package/src/api/btc/BTCGetAddress.ts +91 -0
  45. package/src/api/btc/BTCGetPublicKey.ts +174 -0
  46. package/src/api/btc/BTCSignMessage.ts +73 -0
  47. package/src/api/btc/BTCSignPsbt.ts +65 -0
  48. package/src/api/btc/BTCSignTransaction.ts +148 -0
  49. package/src/api/btc/BTCVerifyMessage.ts +46 -0
  50. package/src/api/btc/helpers/btcParamsUtils.ts +64 -0
  51. package/src/api/btc/helpers/signtx.ts +251 -0
  52. package/src/api/btc/helpers/signtxLegacy.ts +227 -0
  53. package/src/api/btc/helpers/versionLimit.ts +25 -0
  54. package/src/api/btc/helpers/xpubUtils.ts +132 -0
  55. package/src/api/cardano/CardanoGetAddress.ts +139 -0
  56. package/src/api/cardano/CardanoGetPublicKey.ts +72 -0
  57. package/src/api/cardano/CardanoSignMessage.ts +73 -0
  58. package/src/api/cardano/CardanoSignTransaction.ts +404 -0
  59. package/src/api/cardano/helper/addressParameters.ts +120 -0
  60. package/src/api/cardano/helper/auxiliaryData.ts +133 -0
  61. package/src/api/cardano/helper/cardanoInputs.ts +55 -0
  62. package/src/api/cardano/helper/cardanoOutputs.ts +89 -0
  63. package/src/api/cardano/helper/certificate.ts +246 -0
  64. package/src/api/cardano/helper/token.ts +44 -0
  65. package/src/api/cardano/helper/utils.ts +17 -0
  66. package/src/api/cardano/helper/witnesses.ts +62 -0
  67. package/src/api/conflux/ConfluxGetAddress.ts +78 -0
  68. package/src/api/conflux/ConfluxSignMessage.ts +49 -0
  69. package/src/api/conflux/ConfluxSignMessageCIP23.ts +49 -0
  70. package/src/api/conflux/ConfluxSignTransaction.ts +135 -0
  71. package/src/api/cosmos/CosmosGetAddress.ts +80 -0
  72. package/src/api/cosmos/CosmosGetPublicKey.ts +77 -0
  73. package/src/api/cosmos/CosmosSignTransaction.ts +68 -0
  74. package/src/api/device/DeviceBackup.ts +15 -0
  75. package/src/api/device/DeviceCancel.ts +15 -0
  76. package/src/api/device/DeviceChangePin.ts +25 -0
  77. package/src/api/device/DeviceFlags.ts +26 -0
  78. package/src/api/device/DeviceFullyUploadResource.ts +80 -0
  79. package/src/api/device/DeviceLock.ts +15 -0
  80. package/src/api/device/DeviceRebootToBoardloader.ts +30 -0
  81. package/src/api/device/DeviceRebootToBootloader.ts +28 -0
  82. package/src/api/device/DeviceRecovery.ts +44 -0
  83. package/src/api/device/DeviceReset.ts +46 -0
  84. package/src/api/device/DeviceSettings.ts +96 -0
  85. package/src/api/device/DeviceSupportFeatures.ts +29 -0
  86. package/src/api/device/DeviceUnlock.ts +13 -0
  87. package/src/api/device/DeviceUpdateBootloader.ts +111 -0
  88. package/src/api/device/DeviceUpdateReboot.ts +17 -0
  89. package/src/api/device/DeviceUploadResource.ts +204 -0
  90. package/src/api/device/DeviceVerify.ts +65 -0
  91. package/src/api/device/DeviceWipe.ts +15 -0
  92. package/src/api/dynex/DnxGetAddress.ts +75 -0
  93. package/src/api/dynex/DnxSignTransaction.ts +126 -0
  94. package/src/api/evm/EVMGetAddress.ts +88 -0
  95. package/src/api/evm/EVMGetPublicKey.ts +116 -0
  96. package/src/api/evm/EVMSignMessage.ts +49 -0
  97. package/src/api/evm/EVMSignMessageEIP712.ts +56 -0
  98. package/src/api/evm/EVMSignTransaction.ts +141 -0
  99. package/src/api/evm/EVMSignTypedData.ts +477 -0
  100. package/src/api/evm/EVMVerifyMessage.ts +46 -0
  101. package/src/api/evm/latest/getAddress.ts +13 -0
  102. package/src/api/evm/latest/getPublicKey.ts +17 -0
  103. package/src/api/evm/latest/signMessage.ts +19 -0
  104. package/src/api/evm/latest/signTransaction.ts +303 -0
  105. package/src/api/evm/latest/signTypedData.ts +34 -0
  106. package/src/api/evm/latest/signTypedHash.ts +46 -0
  107. package/src/api/evm/latest/verifyMessage.ts +15 -0
  108. package/src/api/evm/legacyV1/getAddress.ts +16 -0
  109. package/src/api/evm/legacyV1/getPublicKey.ts +20 -0
  110. package/src/api/evm/legacyV1/signMessage.ts +22 -0
  111. package/src/api/evm/legacyV1/signTransaction.ts +37 -0
  112. package/src/api/evm/legacyV1/signTypedData.ts +37 -0
  113. package/src/api/evm/legacyV1/signTypedHash.ts +50 -0
  114. package/src/api/evm/legacyV1/verifyMessage.ts +19 -0
  115. package/src/api/filecoin/FilecoinGetAddress.ts +80 -0
  116. package/src/api/filecoin/FilecoinSignTransaction.ts +57 -0
  117. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +476 -0
  118. package/src/api/firmware/bootloaderHelper.ts +46 -0
  119. package/src/api/firmware/getBinary.ts +99 -0
  120. package/src/api/firmware/releaseHelper.ts +78 -0
  121. package/src/api/firmware/updateBootloader.ts +82 -0
  122. package/src/api/firmware/uploadFirmware.ts +541 -0
  123. package/src/api/helpers/batchGetPublickeys.ts +84 -0
  124. package/src/api/helpers/bigNumberUtils.ts +58 -0
  125. package/src/api/helpers/hexUtils.ts +111 -0
  126. package/src/api/helpers/paramsValidator.ts +165 -0
  127. package/src/api/helpers/pathUtils.ts +145 -0
  128. package/src/api/helpers/stringUtils.ts +11 -0
  129. package/src/api/helpers/typeNameUtils.ts +137 -0
  130. package/src/api/index.ts +161 -0
  131. package/src/api/kaspa/KaspaGetAddress.ts +103 -0
  132. package/src/api/kaspa/KaspaSignTransaction.ts +182 -0
  133. package/src/api/kaspa/helpers/BufferWriter.ts +177 -0
  134. package/src/api/kaspa/helpers/HashWriter.ts +74 -0
  135. package/src/api/kaspa/helpers/SignatureType.ts +7 -0
  136. package/src/api/kaspa/helpers/TransferSerialize.ts +144 -0
  137. package/src/api/lightning/LnurlAuth.ts +52 -0
  138. package/src/api/near/NearGetAddress.ts +75 -0
  139. package/src/api/near/NearSignTransaction.ts +46 -0
  140. package/src/api/nem/NEMGetAddress.ts +72 -0
  141. package/src/api/nem/NEMSignTransaction.ts +251 -0
  142. package/src/api/neo/NeoGetAddress.ts +80 -0
  143. package/src/api/neo/NeoSignTransaction.ts +59 -0
  144. package/src/api/nervos/NervosGetAddress.ts +80 -0
  145. package/src/api/nervos/NervosSignTransaction.ts +116 -0
  146. package/src/api/nexa/NexaGetAddress.ts +88 -0
  147. package/src/api/nexa/NexaSignTransaction.ts +107 -0
  148. package/src/api/nostr/NostrDecryptMessage.ts +57 -0
  149. package/src/api/nostr/NostrEncryptMessage.ts +57 -0
  150. package/src/api/nostr/NostrGetPublicKey.ts +74 -0
  151. package/src/api/nostr/NostrSignEvent.ts +65 -0
  152. package/src/api/nostr/NostrSignSchnorr.ts +52 -0
  153. package/src/api/nostr/helper/index.ts +28 -0
  154. package/src/api/polkadot/PolkadotGetAddress.ts +83 -0
  155. package/src/api/polkadot/PolkadotSignTransaction.ts +53 -0
  156. package/src/api/polkadot/networks.ts +72 -0
  157. package/src/api/scdo/ScdoGetAddress.ts +76 -0
  158. package/src/api/scdo/ScdoSignMessage.ts +45 -0
  159. package/src/api/scdo/ScdoSignTransaction.ts +106 -0
  160. package/src/api/solana/SolGetAddress.ts +68 -0
  161. package/src/api/solana/SolSignMessage.ts +61 -0
  162. package/src/api/solana/SolSignOffchainMessage.ts +61 -0
  163. package/src/api/solana/SolSignTransaction.ts +108 -0
  164. package/src/api/starcoin/StarcoinGetAddress.ts +69 -0
  165. package/src/api/starcoin/StarcoinGetPublicKey.ts +70 -0
  166. package/src/api/starcoin/StarcoinSignMessage.ts +42 -0
  167. package/src/api/starcoin/StarcoinSignTransaction.ts +38 -0
  168. package/src/api/starcoin/StarcoinVerifyMessage.ts +35 -0
  169. package/src/api/stellar/StellarGetAddress.ts +68 -0
  170. package/src/api/stellar/StellarSignTransaction.ts +220 -0
  171. package/src/api/sui/SuiGetAddress.ts +117 -0
  172. package/src/api/sui/SuiGetPublicKey.ts +66 -0
  173. package/src/api/sui/SuiSignMessage.ts +48 -0
  174. package/src/api/sui/SuiSignTransaction.ts +126 -0
  175. package/src/api/sui/normalize.ts +28 -0
  176. package/src/api/test/TestInitializeDeviceDuration.ts +22 -0
  177. package/src/api/ton/TonGetAddress.ts +96 -0
  178. package/src/api/ton/TonSignMessage.ts +217 -0
  179. package/src/api/ton/TonSignProof.ts +62 -0
  180. package/src/api/tron/TronGetAddress.ts +75 -0
  181. package/src/api/tron/TronSignMessage.ts +89 -0
  182. package/src/api/tron/TronSignTransaction.ts +214 -0
  183. package/src/api/u2f/GetNextU2FCounter.ts +15 -0
  184. package/src/api/u2f/SetU2FCounter.ts +19 -0
  185. package/src/api/utils.ts +23 -0
  186. package/src/api/xrp/XrpGetAddress.ts +96 -0
  187. package/src/api/xrp/XrpSignTransaction.ts +71 -0
  188. package/src/constants/errors.ts +15 -0
  189. package/src/constants/index.ts +2 -0
  190. package/src/constants/ui-request.ts +3 -0
  191. package/src/core/RequestQueue.ts +134 -0
  192. package/src/core/index.ts +1320 -0
  193. package/src/data/coins/bitcoin.json +44 -0
  194. package/src/data/config.ts +25 -0
  195. package/src/data/messages/messages.json +13167 -0
  196. package/src/data/messages/messages_legacy_v1.json +10282 -0
  197. package/src/data-manager/CoinManager.ts +31 -0
  198. package/src/data-manager/DataManager.ts +499 -0
  199. package/src/data-manager/MessagesConfig.ts +28 -0
  200. package/src/data-manager/TransportManager.ts +140 -0
  201. package/src/data-manager/connectSettings.ts +121 -0
  202. package/src/data-manager/index.ts +3 -0
  203. package/src/device/Device.ts +884 -0
  204. package/src/device/DeviceCommands.ts +631 -0
  205. package/src/device/DeviceConnector.ts +124 -0
  206. package/src/device/DeviceList.ts +39 -0
  207. package/src/device/DevicePool.ts +266 -0
  208. package/src/events/call.ts +95 -0
  209. package/src/events/core.ts +65 -0
  210. package/src/events/device.ts +92 -0
  211. package/src/events/firmware.ts +43 -0
  212. package/src/events/iframe.ts +55 -0
  213. package/src/events/index.ts +10 -0
  214. package/src/events/log.ts +23 -0
  215. package/src/events/logBlockEvent.ts +6 -0
  216. package/src/events/ui-promise.ts +14 -0
  217. package/src/events/ui-request.ts +216 -0
  218. package/src/events/ui-response.ts +59 -0
  219. package/src/events/utils.ts +19 -0
  220. package/src/index.ts +70 -0
  221. package/src/inject.ts +408 -0
  222. package/src/lowLevelInject.ts +61 -0
  223. package/src/topLevelInject.ts +62 -0
  224. package/src/types/api/alephiumGetAddress.ts +31 -0
  225. package/src/types/api/alephiumSignMessage.ts +14 -0
  226. package/src/types/api/alephiumSignTransaction.ts +18 -0
  227. package/src/types/api/algoGetAddress.ts +23 -0
  228. package/src/types/api/algoSignTransaction.ts +17 -0
  229. package/src/types/api/allNetworkGetAddress.ts +130 -0
  230. package/src/types/api/aptosGetAddress.ts +28 -0
  231. package/src/types/api/aptosGetPublicKey.ts +27 -0
  232. package/src/types/api/aptosSignInMessage.ts +17 -0
  233. package/src/types/api/aptosSignMessage.ts +26 -0
  234. package/src/types/api/aptosSignTransaction.ts +18 -0
  235. package/src/types/api/benfenGetAddress.ts +24 -0
  236. package/src/types/api/benfenGetPublicKey.ts +23 -0
  237. package/src/types/api/benfenSignMessage.ts +13 -0
  238. package/src/types/api/benfenSignTransaction.ts +19 -0
  239. package/src/types/api/btcGetAddress.ts +26 -0
  240. package/src/types/api/btcGetPublicKey.ts +26 -0
  241. package/src/types/api/btcSignMessage.ts +16 -0
  242. package/src/types/api/btcSignPsbt.ts +13 -0
  243. package/src/types/api/btcSignTransaction.ts +98 -0
  244. package/src/types/api/btcVerifyMessage.ts +15 -0
  245. package/src/types/api/cardano.ts +212 -0
  246. package/src/types/api/cardanoGetAddress.ts +49 -0
  247. package/src/types/api/cardanoGetPublicKey.ts +33 -0
  248. package/src/types/api/cardanoSignMessage.ts +31 -0
  249. package/src/types/api/cardanoSignTransaction.ts +8 -0
  250. package/src/types/api/checkAllFirmwareRelease.ts +34 -0
  251. package/src/types/api/checkBLEFirmwareRelease.ts +15 -0
  252. package/src/types/api/checkBootloaderRelease.ts +19 -0
  253. package/src/types/api/checkBridgeRelease.ts +14 -0
  254. package/src/types/api/checkBridgeStatus.ts +3 -0
  255. package/src/types/api/checkFirmwareRelease.ts +23 -0
  256. package/src/types/api/checkFirmwareTypeAvailable.ts +12 -0
  257. package/src/types/api/cipherKeyValue.ts +28 -0
  258. package/src/types/api/confluxGetAddress.ts +24 -0
  259. package/src/types/api/confluxSignMessage.ts +13 -0
  260. package/src/types/api/confluxSignMessageCIP23.ts +14 -0
  261. package/src/types/api/confluxSignTransaction.ts +32 -0
  262. package/src/types/api/cosmosGetAddress.ts +24 -0
  263. package/src/types/api/cosmosGetPublicKey.ts +28 -0
  264. package/src/types/api/cosmosSignTransaction.ts +17 -0
  265. package/src/types/api/deviceBackup.ts +4 -0
  266. package/src/types/api/deviceCancel.ts +4 -0
  267. package/src/types/api/deviceChangePin.ts +11 -0
  268. package/src/types/api/deviceFlags.ts +11 -0
  269. package/src/types/api/deviceFullyUploadResource.ts +15 -0
  270. package/src/types/api/deviceLock.ts +4 -0
  271. package/src/types/api/deviceRebootToBoardloader.ts +6 -0
  272. package/src/types/api/deviceRebootToBootloader.ts +4 -0
  273. package/src/types/api/deviceRecovery.ts +19 -0
  274. package/src/types/api/deviceReset.ts +20 -0
  275. package/src/types/api/deviceSettings.ts +23 -0
  276. package/src/types/api/deviceSupportFeatures.ts +6 -0
  277. package/src/types/api/deviceUnlock.ts +4 -0
  278. package/src/types/api/deviceUpdateBootloader.ts +13 -0
  279. package/src/types/api/deviceUpdateReboot.ts +3 -0
  280. package/src/types/api/deviceUploadResource.ts +21 -0
  281. package/src/types/api/deviceVerify.ts +15 -0
  282. package/src/types/api/deviceWipe.ts +4 -0
  283. package/src/types/api/dnxGetAddress.ts +23 -0
  284. package/src/types/api/dnxSignTransaction.ts +36 -0
  285. package/src/types/api/event.ts +8 -0
  286. package/src/types/api/evmGetAddress.ts +24 -0
  287. package/src/types/api/evmGetPublicKey.ts +36 -0
  288. package/src/types/api/evmSignMessage.ts +14 -0
  289. package/src/types/api/evmSignMessageEIP712.ts +14 -0
  290. package/src/types/api/evmSignTransaction.ts +80 -0
  291. package/src/types/api/evmSignTypedData.ts +42 -0
  292. package/src/types/api/evmVerifyMessage.ts +15 -0
  293. package/src/types/api/export.ts +194 -0
  294. package/src/types/api/filecoinGetAddress.ts +24 -0
  295. package/src/types/api/filecoinSignTransaction.ts +24 -0
  296. package/src/types/api/firmwareUpdate.ts +66 -0
  297. package/src/types/api/getFeatures.ts +4 -0
  298. package/src/types/api/getLogs.ts +3 -0
  299. package/src/types/api/getNextU2FCounter.ts +7 -0
  300. package/src/types/api/getOnetokenFeatures.ts +7 -0
  301. package/src/types/api/getPassphraseState.ts +6 -0
  302. package/src/types/api/index.ts +404 -0
  303. package/src/types/api/init.ts +11 -0
  304. package/src/types/api/kaspaGetAddress.ts +26 -0
  305. package/src/types/api/kaspaSignTransaction.ts +44 -0
  306. package/src/types/api/lnurlAuth.ts +22 -0
  307. package/src/types/api/nearGetAddress.ts +23 -0
  308. package/src/types/api/nearSignTransaction.ts +13 -0
  309. package/src/types/api/nemGetAddress.ts +24 -0
  310. package/src/types/api/nemSignTransaction.ts +118 -0
  311. package/src/types/api/neoGetAddress.ts +24 -0
  312. package/src/types/api/neoSignTransaction.ts +18 -0
  313. package/src/types/api/nervosGetAddress.ts +24 -0
  314. package/src/types/api/nervosSignTransaction.ts +19 -0
  315. package/src/types/api/nexaGetAddress.ts +26 -0
  316. package/src/types/api/nexaSignTransaction.ts +28 -0
  317. package/src/types/api/nostrDecryptMessage.ts +25 -0
  318. package/src/types/api/nostrEncryptMessage.ts +25 -0
  319. package/src/types/api/nostrGetPublicKey.ts +28 -0
  320. package/src/types/api/nostrSignEvent.ts +52 -0
  321. package/src/types/api/nostrSignSchnorr.ts +22 -0
  322. package/src/types/api/polkadotGetAddress.ts +30 -0
  323. package/src/types/api/polkadotSignTransaction.ts +19 -0
  324. package/src/types/api/promptWebDeviceAccess.ts +6 -0
  325. package/src/types/api/scdoGetAddress.ts +23 -0
  326. package/src/types/api/scdoSignMessage.ts +13 -0
  327. package/src/types/api/scdoSignTransaction.ts +24 -0
  328. package/src/types/api/searchDevices.ts +4 -0
  329. package/src/types/api/setU2FCounter.ts +7 -0
  330. package/src/types/api/solGetAddress.ts +23 -0
  331. package/src/types/api/solSignMessage.ts +17 -0
  332. package/src/types/api/solSignOffchainMessage.ts +24 -0
  333. package/src/types/api/solSignTransaction.ts +27 -0
  334. package/src/types/api/starcoinGetAddress.ts +23 -0
  335. package/src/types/api/starcoinGetPublicKey.ts +23 -0
  336. package/src/types/api/starcoinSignMessage.ts +13 -0
  337. package/src/types/api/starcoinSignTransaction.ts +13 -0
  338. package/src/types/api/starcoinVerifyMessage.ts +14 -0
  339. package/src/types/api/stellarGetAddress.ts +23 -0
  340. package/src/types/api/stellarSignTransaction.ts +154 -0
  341. package/src/types/api/suiGetAddress.ts +28 -0
  342. package/src/types/api/suiGetPublicKey.ts +27 -0
  343. package/src/types/api/suiSignMessage.ts +13 -0
  344. package/src/types/api/suiSignTransaction.ts +17 -0
  345. package/src/types/api/testInitializeDeviceDuration.ts +6 -0
  346. package/src/types/api/tonGetAddress.ts +34 -0
  347. package/src/types/api/tonSignMessage.ts +42 -0
  348. package/src/types/api/tonSignProof.ts +25 -0
  349. package/src/types/api/tronGetAddress.ts +23 -0
  350. package/src/types/api/tronSignMessage.ts +14 -0
  351. package/src/types/api/tronSignTransaction.ts +89 -0
  352. package/src/types/api/uiResponse.ts +3 -0
  353. package/src/types/api/xrpGetAddress.ts +28 -0
  354. package/src/types/api/xrpSignTransaction.ts +29 -0
  355. package/src/types/device.ts +194 -0
  356. package/src/types/firmware.ts +41 -0
  357. package/src/types/global.d.ts +3 -0
  358. package/src/types/index.ts +5 -0
  359. package/src/types/params.ts +64 -0
  360. package/src/types/settings.ts +144 -0
  361. package/src/utils/arrayUtils.ts +7 -0
  362. package/src/utils/assets.ts +5 -0
  363. package/src/utils/bridgeUpdate.ts +80 -0
  364. package/src/utils/capabilitieUtils.ts +12 -0
  365. package/src/utils/deviceFeaturesUtils.ts +352 -0
  366. package/src/utils/deviceInfoUtils.ts +167 -0
  367. package/src/utils/deviceSettings.ts +109 -0
  368. package/src/utils/deviceVersionUtils.ts +79 -0
  369. package/src/utils/findDefectiveBatchDevice.ts +39 -0
  370. package/src/utils/getMutex.ts +41 -0
  371. package/src/utils/getSynchronize.ts +25 -0
  372. package/src/utils/homescreen.ts +345 -0
  373. package/src/utils/index.ts +44 -0
  374. package/src/utils/logger.ts +190 -0
  375. package/src/utils/networkUtils.ts +25 -0
  376. package/src/utils/patch.ts +14 -0
  377. package/src/utils/promiseUtils.ts +4 -0
  378. package/src/utils/release.ts +42 -0
  379. package/src/utils/semver.test.js +53 -0
  380. package/src/utils/tracing.ts +238 -0
  381. package/src/utils/versionUtils.ts +120 -0
  382. package/tsconfig.json +11 -0
@@ -0,0 +1,884 @@
1
+ import EventEmitter from 'events';
2
+ import semver from 'semver';
3
+ import { Enum_Capability } from '@onetokenfe/hd-transport';
4
+ import {
5
+ EDeviceType,
6
+ ERRORS,
7
+ ERROR_CODES_REQUIRE_DISCONNECT,
8
+ ERROR_CODES_REQUIRE_RELEASE,
9
+ HardwareError,
10
+ HardwareErrorCode,
11
+ createDeferred,
12
+ } from '@onetokenfe/hd-shared';
13
+
14
+ import {
15
+ LoggerNames,
16
+ getDeviceBLEFirmwareVersion,
17
+ getDeviceBleName,
18
+ getDeviceFirmwareVersion,
19
+ getDeviceLabel,
20
+ getDeviceType,
21
+ getDeviceUUID,
22
+ getLogger,
23
+ getMethodVersionRange,
24
+ } from '../utils';
25
+ import {
26
+ fixFeaturesFirmwareVersion,
27
+ getPassphraseStateWithRefreshDeviceInfo,
28
+ } from '../utils/deviceFeaturesUtils';
29
+ import { generateInstanceId } from '../utils/tracing';
30
+
31
+ // eslint-disable-next-line import/no-cycle
32
+ import { DeviceCommands } from './DeviceCommands';
33
+ import {
34
+ type DeviceFirmwareRange,
35
+ type Device as DeviceTyped,
36
+ EOneTokenDeviceMode,
37
+ type Features,
38
+ type UnavailableCapabilities,
39
+ } from '../types';
40
+ import { DEVICE, UI_REQUEST } from '../events';
41
+ import { DataManager } from '../data-manager';
42
+ import TransportManager from '../data-manager/TransportManager';
43
+ import { toHardened } from '../api/helpers/pathUtils';
44
+ import { existCapability } from '../utils/capabilitieUtils';
45
+
46
+ import type { PROTO } from '../constants';
47
+ import type {
48
+ DeviceButtonRequestPayload,
49
+ DeviceFeaturesPayload,
50
+ PassphraseRequestPayload,
51
+ } from '../events';
52
+ import type { PassphrasePromptResponse } from './DeviceCommands';
53
+ import type { Deferred } from '@onetokenfe/hd-shared';
54
+ import type { OneTokenDeviceInfo as DeviceDescriptor } from '@onetokenfe/hd-transport';
55
+ import type DeviceConnector from './DeviceConnector';
56
+
57
+ export type InitOptions = {
58
+ initSession?: boolean;
59
+ deviceId?: string;
60
+ passphraseState?: string;
61
+ deriveCardano?: boolean;
62
+ };
63
+
64
+ export type RunOptions = {
65
+ keepSession?: boolean;
66
+ } & InitOptions;
67
+
68
+ const parseRunOptions = (options?: RunOptions): RunOptions => {
69
+ if (!options) options = {};
70
+ return options;
71
+ };
72
+
73
+ const Log = getLogger(LoggerNames.Device);
74
+
75
+ export interface DeviceEvents {
76
+ [DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
77
+ [DEVICE.PASSPHRASE_ON_DEVICE]: [Device, ((response: any) => void)?];
78
+ [DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
79
+ [DEVICE.FEATURES]: [Device, DeviceFeaturesPayload];
80
+ [DEVICE.PASSPHRASE]: [
81
+ Device,
82
+ PassphraseRequestPayload,
83
+ (response: PassphrasePromptResponse, error?: Error) => void
84
+ ];
85
+ [DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE]: [
86
+ Device,
87
+ (err: any, deviceId: string) => void
88
+ ];
89
+ [DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE]: [
90
+ Device,
91
+ (err: any, deviceId: string) => void
92
+ ];
93
+ }
94
+
95
+ export interface Device {
96
+ on<K extends keyof DeviceEvents>(type: K, listener: (...event: DeviceEvents[K]) => void): this;
97
+
98
+ off<K extends keyof DeviceEvents>(type: K, listener: (...event: DeviceEvents[K]) => void): this;
99
+
100
+ emit<K extends keyof DeviceEvents>(type: K, ...args: DeviceEvents[K]): boolean;
101
+ }
102
+
103
+ const deviceSessionCache: Record<string, string> = {};
104
+
105
+ export class Device extends EventEmitter {
106
+ /**
107
+ * 设备标识对象
108
+ */
109
+ originalDescriptor: DeviceDescriptor;
110
+
111
+ sdkInstanceId?: string;
112
+
113
+ /**
114
+ * 设备实例唯一标识
115
+ */
116
+ instanceId: string;
117
+
118
+ createdAt: number;
119
+
120
+ /**
121
+ * 设备主 ID
122
+ * 蓝牙连接时是设备的 UUID
123
+ * USB连接时是设备的 sessionID
124
+ */
125
+ mainId?: string | null;
126
+
127
+ /**
128
+ * 通信管道,向设备发送请求
129
+ */
130
+ deviceConnector?: DeviceConnector | null = null;
131
+
132
+ /**
133
+ * 固件命令
134
+ */
135
+ // @ts-expect-error: strictPropertyInitialization
136
+ commands: DeviceCommands;
137
+
138
+ /**
139
+ * 可取消的操作
140
+ */
141
+ private cancelableAction?: (err?: Error) => Promise<unknown>;
142
+
143
+ /**
144
+ * 设备是否被占用
145
+ */
146
+ private deviceAcquired = false;
147
+
148
+ /**
149
+ * 设备信息
150
+ */
151
+ features: Features | undefined = undefined;
152
+
153
+ /**
154
+ * 是否需要更新设备信息
155
+ */
156
+ featuresNeedsReload = false;
157
+
158
+ runPromise?: Deferred<void> | null;
159
+
160
+ externalState: string[] = [];
161
+
162
+ unavailableCapabilities: UnavailableCapabilities = {};
163
+
164
+ instance = 0;
165
+
166
+ internalState: string[] = [];
167
+
168
+ needReloadDevice = false;
169
+
170
+ /**
171
+ * 执行 API 方法后是否保留 SessionID
172
+ */
173
+ keepSession = false;
174
+
175
+ passphraseState: string | undefined = undefined;
176
+
177
+ pendingCallbackPromise?: Deferred<void>;
178
+
179
+ constructor(descriptor: DeviceDescriptor, sdkInstanceId?: string) {
180
+ super();
181
+ this.originalDescriptor = descriptor;
182
+ this.sdkInstanceId = sdkInstanceId;
183
+ this.instanceId = generateInstanceId('Device', this.sdkInstanceId);
184
+ this.createdAt = Date.now();
185
+ Log.debug(
186
+ `[Device] Created: ${this.instanceId}${
187
+ this.sdkInstanceId ? ` for SDK: ${this.sdkInstanceId}` : ''
188
+ }`
189
+ );
190
+ }
191
+
192
+ static fromDescriptor(originalDescriptor: DeviceDescriptor, sdkInstanceId?: string) {
193
+ const descriptor = { ...originalDescriptor };
194
+ return new Device(descriptor, sdkInstanceId);
195
+ }
196
+
197
+ // simplified object to pass via postMessage
198
+ toMessageObject(): DeviceTyped | null {
199
+ if (this.isUnacquired() || !this.features) return null;
200
+
201
+ const env = DataManager.getSettings('env');
202
+ const deviceType = getDeviceType(this.features);
203
+
204
+ const bleName = getDeviceBleName(this.features);
205
+ const label = getDeviceLabel(this.features);
206
+
207
+ return {
208
+ /** Android uses Mac address, iOS uses uuid, USB uses uuid */
209
+ connectId: DataManager.isBleConnect(env) ? this.mainId || null : getDeviceUUID(this.features),
210
+ /** Hardware ID, will not change at any time */
211
+ uuid: getDeviceUUID(this.features),
212
+ commType: this.originalDescriptor.commType,
213
+ sdkInstanceId: this.sdkInstanceId,
214
+ instanceId: this.instanceId,
215
+ createdAt: this.createdAt,
216
+ deviceType,
217
+ /** ID for current seeds, will clear after replace a new seed at device */
218
+ deviceId: this.features.device_id || null,
219
+ path: this.originalDescriptor?.path,
220
+ bleName,
221
+ name: bleName || label || `OneToken ${deviceType?.toUpperCase()}`,
222
+ label: label || 'OneToken',
223
+ mode: this.getMode(),
224
+ features: this.features,
225
+ firmwareVersion: this.getFirmwareVersion(),
226
+ bleFirmwareVersion: this.getBLEFirmwareVersion(),
227
+ unavailableCapabilities: this.unavailableCapabilities,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Device connect
233
+ * @returns {Promise<boolean>}
234
+ */
235
+ connect() {
236
+ const env = DataManager.getSettings('env');
237
+ // eslint-disable-next-line no-async-promise-executor
238
+ return new Promise<boolean>(async (resolve, reject) => {
239
+ if (DataManager.isBleConnect(env)) {
240
+ try {
241
+ await this.acquire();
242
+ resolve(true);
243
+ } catch (error) {
244
+ reject(error);
245
+ }
246
+ return;
247
+ }
248
+ // 不存在 Session ID 或存在 Session ID 但设备在别处使用,都需要 acquire 获取最新 sessionID
249
+ if (!this.mainId || (!this.isUsedHere() && this.originalDescriptor)) {
250
+ try {
251
+ await this.acquire();
252
+ resolve(true);
253
+ } catch (error) {
254
+ reject(error);
255
+ }
256
+ return;
257
+ }
258
+ if (this.isUsedHere()) {
259
+ resolve(true);
260
+ return;
261
+ }
262
+ resolve(false);
263
+ });
264
+ }
265
+
266
+ async acquire() {
267
+ const env = DataManager.getSettings('env');
268
+ const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
269
+ try {
270
+ if (DataManager.isBleConnect(env)) {
271
+ const res = await this.deviceConnector?.acquire(this.originalDescriptor.id);
272
+ this.mainId = (res as unknown as any).uuid ?? '';
273
+ Log.debug('Expected uuid:', this.mainId);
274
+ } else {
275
+ this.mainId = await this.deviceConnector?.acquire(
276
+ this.originalDescriptor.path,
277
+ this.originalDescriptor.session
278
+ );
279
+ Log.debug('Expected session id:', this.mainId);
280
+ }
281
+ this.deviceAcquired = true;
282
+ this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
283
+ if (this.commands) {
284
+ await this.commands.dispose(false);
285
+ }
286
+
287
+ this.commands = new DeviceCommands(this, this.mainId ?? '');
288
+ } catch (error) {
289
+ if (this.runPromise) {
290
+ this.runPromise.reject(error);
291
+ } else {
292
+ throw error;
293
+ }
294
+ this.runPromise = null;
295
+ }
296
+ }
297
+
298
+ async release() {
299
+ const env = DataManager.getSettings('env');
300
+ if (
301
+ (this.isUsedHere() && !this.keepSession && this.mainId) ||
302
+ (this.mainId && DataManager.isBleConnect(env))
303
+ ) {
304
+ // wait for callback tasks to complete before releasing device
305
+ if (this.pendingCallbackPromise) {
306
+ try {
307
+ Log.debug(
308
+ 'Waiting for callback tasks to complete before releasing device (in release method)'
309
+ );
310
+ await this.pendingCallbackPromise.promise;
311
+ } catch (error) {
312
+ Log.error('Error waiting for callback tasks in release method:', error);
313
+ }
314
+ }
315
+
316
+ if (this.commands) {
317
+ this.commands.dispose(false);
318
+ if (this.commands.callPromise) {
319
+ try {
320
+ await this.commands.callPromise;
321
+ } catch (error) {
322
+ this.commands.callPromise = undefined;
323
+ }
324
+ }
325
+ }
326
+ try {
327
+ await this.deviceConnector?.release(this.mainId, false);
328
+ this.updateDescriptor({ session: null } as DeviceDescriptor);
329
+ } catch (err) {
330
+ Log.error('[Device] release error: ', err);
331
+ } finally {
332
+ this.needReloadDevice = true;
333
+ }
334
+ }
335
+ this.deviceAcquired = false;
336
+ }
337
+
338
+ getCommands() {
339
+ return this.commands;
340
+ }
341
+
342
+ private generateStateKey(deviceId: string, passphraseState?: string) {
343
+ if (passphraseState) {
344
+ return `${deviceId}@${passphraseState}`;
345
+ }
346
+ return deviceId;
347
+ }
348
+
349
+ getInternalState(_deviceId?: string) {
350
+ Log.debug('getInternalState session cache: ', deviceSessionCache);
351
+ Log.debug(
352
+ 'getInternalState session param: ',
353
+ `device_id: ${_deviceId}`,
354
+ `features.device_id: ${this.features?.device_id}`,
355
+ `passphraseState: ${this.passphraseState}`
356
+ );
357
+
358
+ const deviceId = _deviceId || this.features?.device_id;
359
+ if (!deviceId) return undefined;
360
+ if (!this.passphraseState) return undefined;
361
+
362
+ const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
363
+ return deviceSessionCache[usePassKey];
364
+ }
365
+
366
+ // attach to pin to fix internal state
367
+ updateInternalState(
368
+ enablePassphrase: boolean,
369
+ passphraseState: string | undefined,
370
+ deviceId: string,
371
+ sessionId: string | null = null,
372
+ featuresSessionId: string | null = null
373
+ ) {
374
+ Log.debug(
375
+ 'updateInternalState session param: ',
376
+ `device_id: ${deviceId}`,
377
+ `enablePassphrase: ${enablePassphrase}`,
378
+ `passphraseState: ${passphraseState}`,
379
+ `sessionId: ${sessionId}`,
380
+ `featuresSessionId: ${featuresSessionId}`
381
+ );
382
+
383
+ if (enablePassphrase) {
384
+ // update the sessionId
385
+ if (sessionId) {
386
+ deviceSessionCache[this.generateStateKey(deviceId, passphraseState)] = sessionId;
387
+ } else if (featuresSessionId) {
388
+ deviceSessionCache[this.generateStateKey(deviceId, passphraseState)] = featuresSessionId;
389
+ }
390
+ }
391
+
392
+ // delete the old sessionId
393
+ const oldKey = `${deviceId}`;
394
+ if (deviceSessionCache[oldKey]) {
395
+ delete deviceSessionCache[oldKey];
396
+ }
397
+
398
+ Log.debug('updateInternalState session cache: ', deviceSessionCache);
399
+ }
400
+
401
+ private setInternalState(state: string, initSession?: boolean) {
402
+ Log.debug(
403
+ 'setInternalState session param: ',
404
+ `state: ${state}`,
405
+ `initSession: ${initSession}`,
406
+ `device_id: ${this.features?.device_id}`,
407
+ `passphraseState: ${this.passphraseState}`
408
+ );
409
+
410
+ if (!this.features) return;
411
+ if (!this.passphraseState && !initSession) return;
412
+
413
+ const deviceId = this.features?.device_id;
414
+ if (!deviceId) return;
415
+
416
+ const key = this.generateStateKey(deviceId, this.passphraseState);
417
+
418
+ if (state) {
419
+ deviceSessionCache[key] = state;
420
+ }
421
+ Log.debug('setInternalState done session cache: ', deviceSessionCache);
422
+ }
423
+
424
+ clearInternalState(_deviceId?: string) {
425
+ Log.debug('clearInternalState param: ', _deviceId);
426
+
427
+ const deviceId = _deviceId || this.features?.device_id;
428
+ if (!deviceId) return;
429
+ const key = `${deviceId}`;
430
+ delete deviceSessionCache[key];
431
+
432
+ if (this.passphraseState) {
433
+ const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
434
+ delete deviceSessionCache[usePassKey];
435
+ }
436
+ }
437
+
438
+ async initialize(options?: InitOptions) {
439
+ // Log.debug('initialize param:', options);
440
+
441
+ this.passphraseState = options?.passphraseState;
442
+
443
+ if (options?.initSession) {
444
+ this.clearInternalState(options?.deviceId);
445
+ }
446
+
447
+ const internalState = this.getInternalState(options?.deviceId);
448
+ const payload: any = {};
449
+ if (internalState) {
450
+ payload.session_id = internalState;
451
+ }
452
+
453
+ if (options?.deriveCardano) {
454
+ payload.derive_cardano = true;
455
+ }
456
+ payload.passphrase_state = options?.passphraseState;
457
+ payload.is_contains_attach = true;
458
+
459
+ Log.debug('Initialize device begin:', {
460
+ deviceId: options?.deviceId,
461
+ passphraseState: options?.passphraseState,
462
+ initSession: options?.initSession,
463
+ InitializePayload: payload,
464
+ });
465
+
466
+ try {
467
+ // @ts-expect-error
468
+ const { message } = await Promise.race([
469
+ this.commands.typedCall('Initialize', 'Features', payload),
470
+ new Promise((_, reject) => {
471
+ setTimeout(() => {
472
+ reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
473
+ // iOS ble bound device timeout 20s
474
+ }, 25 * 1000);
475
+ }),
476
+ ]);
477
+
478
+ Log.debug('Initialize device end: ', message);
479
+ this._updateFeatures(message, options?.initSession);
480
+ await TransportManager.reconfigure(this.features);
481
+ } catch (error) {
482
+ Log.error('Initialization failed:', error);
483
+ throw error;
484
+ }
485
+ }
486
+
487
+ async getFeatures() {
488
+ const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
489
+ this._updateFeatures(message);
490
+ }
491
+
492
+ _updateFeatures(feat: Features, initSession?: boolean) {
493
+ // GetFeatures doesn't return 'session_id'
494
+ if (this.features && this.features.session_id && !feat.session_id) {
495
+ feat.session_id = this.features.session_id;
496
+ }
497
+ if (this.features && this.features.device_id && feat.session_id) {
498
+ this.setInternalState(feat.session_id, initSession);
499
+ }
500
+ feat.unlocked = feat.unlocked ?? true;
501
+
502
+ feat = fixFeaturesFirmwareVersion(feat);
503
+
504
+ this.features = feat;
505
+ this.featuresNeedsReload = false;
506
+ this.emit(DEVICE.FEATURES, this, feat);
507
+ }
508
+
509
+ /**
510
+ * 暂时只在 acquire 后更新 Session ID
511
+ * 后续看是否有需要依据 listen 返回结果更新
512
+ * @param descriptor
513
+ */
514
+ updateDescriptor(descriptor: DeviceDescriptor, forceUpdate = false) {
515
+ const env = DataManager.getSettings('env');
516
+ if (DataManager.isBleConnect(env)) {
517
+ return;
518
+ }
519
+ const originalSession = this.originalDescriptor.session;
520
+ const upcomingSession = descriptor.session;
521
+
522
+ if (originalSession !== upcomingSession) {
523
+ this.originalDescriptor.session = upcomingSession;
524
+ }
525
+
526
+ if (forceUpdate) {
527
+ this.originalDescriptor = descriptor;
528
+ }
529
+ }
530
+
531
+ updateFromCache(device: Device) {
532
+ this.mainId = device.mainId;
533
+ this.commands = device.commands;
534
+ this.updateDescriptor(device.originalDescriptor, true);
535
+ if (device.features) {
536
+ this._updateFeatures(device.features);
537
+ }
538
+ }
539
+
540
+ async run(fn?: () => Promise<void>, options?: RunOptions) {
541
+ if (this.runPromise) {
542
+ await this.interruptionFromOutside();
543
+ Log.debug('[Device] run error:', 'Device is running, but will cancel previous operate');
544
+ }
545
+
546
+ options = parseRunOptions(options);
547
+
548
+ this.runPromise = createDeferred(this._runInner.bind(this, fn, options));
549
+ return this.runPromise.promise;
550
+ }
551
+
552
+ async _runInner<T>(fn: (() => Promise<T>) | undefined, options: RunOptions) {
553
+ if (!this.isUsedHere() || this.commands.disposed) {
554
+ const env = DataManager.getSettings('env');
555
+ if (env !== 'react-native') {
556
+ try {
557
+ await this.acquire();
558
+ } catch (error) {
559
+ this.runPromise = null;
560
+ return Promise.reject(error);
561
+ }
562
+
563
+ try {
564
+ if (fn) {
565
+ await this.initialize(options);
566
+ }
567
+ } catch (error) {
568
+ this.runPromise = null;
569
+ if (error instanceof HardwareError) {
570
+ return Promise.reject(error);
571
+ }
572
+ return Promise.reject(
573
+ ERRORS.TypedError(
574
+ HardwareErrorCode.DeviceInitializeFailed,
575
+ `Initialize failed: ${error.message as string}, code: ${error.code as string}`
576
+ )
577
+ );
578
+ }
579
+ } else if (env === 'react-native') {
580
+ // TODO: implement react-native acquire
581
+ // cancel input pin or passphrase on device request, then the following requests will report an error
582
+ if (this.commands) {
583
+ this.commands.disposed = false;
584
+ }
585
+ }
586
+ }
587
+
588
+ if (options.keepSession) {
589
+ this.keepSession = true;
590
+ }
591
+
592
+ if (fn) {
593
+ try {
594
+ await fn();
595
+ } catch (e) {
596
+ if (this.runPromise) {
597
+ this.runPromise.reject(e);
598
+ }
599
+
600
+ if (
601
+ e instanceof HardwareError &&
602
+ ERROR_CODES_REQUIRE_RELEASE.includes(e.errorCode as any)
603
+ ) {
604
+ if (ERROR_CODES_REQUIRE_DISCONNECT.includes(e.errorCode as any)) {
605
+ await this.deviceConnector?.disconnect(this.mainId);
606
+ }
607
+ await this.release();
608
+ Log.debug(`error code ${e.errorCode} release device, mainId: ${this.mainId}`);
609
+ }
610
+
611
+ this.runPromise = null;
612
+ return;
613
+ }
614
+ }
615
+
616
+ if (
617
+ (!this.keepSession && typeof options.keepSession !== 'boolean') ||
618
+ options.keepSession === false
619
+ ) {
620
+ this.keepSession = false;
621
+ await this.release();
622
+ Log.debug('release device, mainId: ', this.mainId);
623
+ }
624
+
625
+ if (this.runPromise) {
626
+ this.runPromise.resolve();
627
+ }
628
+
629
+ this.runPromise = null;
630
+ }
631
+
632
+ async interruptionFromOutside() {
633
+ if (this.commands) {
634
+ await this.commands.dispose(false);
635
+ }
636
+ if (this.runPromise) {
637
+ this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromOutside));
638
+ }
639
+ }
640
+
641
+ async interruptionFromUser() {
642
+ const error = ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
643
+ await this.cancelableAction?.(error);
644
+ await this.commands?.cancel();
645
+
646
+ if (this.runPromise) {
647
+ this.runPromise.reject(error);
648
+ this.runPromise = null;
649
+ }
650
+ }
651
+
652
+ setCancelableAction(callback: (err?: Error) => Promise<unknown>) {
653
+ this.cancelableAction = (e?: Error) =>
654
+ callback(e)
655
+ .catch(e2 => {
656
+ Log.debug('cancelableAction error', e2);
657
+ })
658
+ .finally(() => {
659
+ this.clearCancelableAction();
660
+ });
661
+ }
662
+
663
+ clearCancelableAction() {
664
+ this.cancelableAction = undefined;
665
+ }
666
+
667
+ getMode() {
668
+ if (this.features?.bootloader_mode) {
669
+ // bootloader mode
670
+ return EOneTokenDeviceMode.bootloader;
671
+ }
672
+
673
+ if (!this.features?.initialized) {
674
+ // not initialized
675
+ return EOneTokenDeviceMode.notInitialized;
676
+ }
677
+
678
+ if (this.features?.no_backup) {
679
+ // backup mode
680
+ return EOneTokenDeviceMode.backupMode;
681
+ }
682
+
683
+ // normal mode
684
+ return EOneTokenDeviceMode.normal;
685
+ }
686
+
687
+ getFirmwareVersion() {
688
+ if (!this.features) return null;
689
+ return getDeviceFirmwareVersion(this.features);
690
+ }
691
+
692
+ getBLEFirmwareVersion() {
693
+ if (!this.features) return null;
694
+ return getDeviceBLEFirmwareVersion(this.features);
695
+ }
696
+
697
+ isUsed() {
698
+ return typeof this.originalDescriptor.session === 'string';
699
+ }
700
+
701
+ hasDeviceAcquire() {
702
+ const env = DataManager.getSettings('env');
703
+ if (DataManager.isBleConnect(env)) {
704
+ return this.deviceAcquired;
705
+ }
706
+ return this.isUsed() && this.deviceAcquired;
707
+ }
708
+
709
+ isUsedHere() {
710
+ const env = DataManager.getSettings('env');
711
+ if (DataManager.isBleConnect(env)) {
712
+ return false;
713
+ }
714
+ return this.isUsed() && this.originalDescriptor.session === this.mainId;
715
+ }
716
+
717
+ isUsedElsewhere(): boolean {
718
+ return this.isUsed() && !this.isUsedHere();
719
+ }
720
+
721
+ isBootloader() {
722
+ return this.features && !!this.features.bootloader_mode;
723
+ }
724
+
725
+ isInitialized() {
726
+ return this.features && !!this.features.initialized;
727
+ }
728
+
729
+ isSeedless() {
730
+ return this.features && !!this.features.no_backup;
731
+ }
732
+
733
+ isUnacquired(): boolean {
734
+ return this.features === undefined;
735
+ }
736
+
737
+ hasUnexpectedMode(allow: string[], require: string[]) {
738
+ // both allow and require cases might generate single unexpected mode
739
+ if (this.features) {
740
+ // allow cases
741
+ if (this.isBootloader() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
742
+ return UI_REQUEST.BOOTLOADER;
743
+ }
744
+ if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {
745
+ return UI_REQUEST.NOT_INITIALIZE;
746
+ }
747
+ if (this.isSeedless() && !allow.includes(UI_REQUEST.SEEDLESS)) {
748
+ return UI_REQUEST.SEEDLESS;
749
+ }
750
+
751
+ // require cases
752
+ if (!this.isBootloader() && require.includes(UI_REQUEST.BOOTLOADER)) {
753
+ return UI_REQUEST.NOT_IN_BOOTLOADER;
754
+ }
755
+ }
756
+ return null;
757
+ }
758
+
759
+ hasUsePassphrase() {
760
+ const isModeT =
761
+ getDeviceType(this.features) === EDeviceType.Touch ||
762
+ getDeviceType(this.features) === EDeviceType.Pro;
763
+ const preCheckTouch = isModeT && this.features?.unlocked === false;
764
+
765
+ return this.features && (!!this.features.passphrase_protection || preCheckTouch);
766
+ }
767
+
768
+ checkDeviceId(deviceId: string) {
769
+ if (this.features) {
770
+ return this.features.device_id === deviceId;
771
+ }
772
+ return false;
773
+ }
774
+
775
+ async lockDevice() {
776
+ const res = await this.commands.typedCall('LockDevice', 'Success', {});
777
+ return res.message;
778
+ }
779
+
780
+ supportUnlockVersionRange(): DeviceFirmwareRange {
781
+ return {
782
+ pro: {
783
+ min: '4.15.0',
784
+ },
785
+ };
786
+ }
787
+
788
+ async unlockDevice() {
789
+ const firmwareVersion = getDeviceFirmwareVersion(this.features)?.join('.');
790
+ const versionRange = getMethodVersionRange(
791
+ this.features,
792
+ type => this.supportUnlockVersionRange()[type]
793
+ );
794
+
795
+ const supportAttachPinCapability = existCapability(
796
+ this.features,
797
+ Enum_Capability.Capability_AttachToPin
798
+ );
799
+
800
+ const supportUnlock =
801
+ supportAttachPinCapability || (versionRange && semver.gte(firmwareVersion, versionRange.min));
802
+
803
+ if (supportUnlock) {
804
+ const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
805
+ if (this.features) {
806
+ this.features.unlocked = res.message.unlocked == null ? null : res.message.unlocked;
807
+ this.features.unlocked_attach_pin =
808
+ res.message.unlocked_attach_pin == null ? undefined : res.message.unlocked_attach_pin;
809
+ this.features.passphrase_protection =
810
+ res.message.passphrase_protection == null ? null : res.message.passphrase_protection;
811
+
812
+ return Promise.resolve(this.features);
813
+ }
814
+
815
+ const featuresRes = await this.commands.typedCall('GetFeatures', 'Features');
816
+ this._updateFeatures(featuresRes.message);
817
+ return Promise.resolve(featuresRes.message);
818
+ }
819
+
820
+ const { type } = await this.commands.typedCall('GetAddress', 'Address', {
821
+ address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
822
+ coin_name: 'Testnet',
823
+ script_type: 'SPENDADDRESS',
824
+ show_display: false,
825
+ });
826
+
827
+ // @ts-expect-error
828
+ if (type === 'CallMethodError') {
829
+ throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'unlock device error');
830
+ }
831
+ const res = await this.commands.typedCall('GetFeatures', 'Features');
832
+ this._updateFeatures(res.message);
833
+ return Promise.resolve(res.message);
834
+ }
835
+
836
+ async checkPassphraseStateSafety(
837
+ passphraseState?: string,
838
+ useEmptyPassphrase?: boolean,
839
+ skipPassphraseCheck?: boolean
840
+ ) {
841
+ if (!this.features) return false;
842
+ const { passphraseState: newPassphraseState, unlockedAttachPin } =
843
+ await getPassphraseStateWithRefreshDeviceInfo(this, {
844
+ expectPassphraseState: passphraseState,
845
+ onlyMainPin: useEmptyPassphrase,
846
+ });
847
+
848
+ if (skipPassphraseCheck) {
849
+ return true;
850
+ }
851
+
852
+ // Main wallet and unlock Attach Pin, throw safe error
853
+ const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
854
+ const useErrorAttachPin =
855
+ unlockedAttachPin && passphraseState && passphraseState !== newPassphraseState;
856
+
857
+ Log.debug('Check passphrase state safety: ', {
858
+ passphraseState,
859
+ newPassphraseState,
860
+ unlockedAttachPin,
861
+ useEmptyPassphrase,
862
+ });
863
+
864
+ if (mainWalletUseAttachPin || useErrorAttachPin) {
865
+ try {
866
+ await this.lockDevice();
867
+ } catch (error) {
868
+ // ignore error
869
+ }
870
+ this.clearInternalState();
871
+ return Promise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError));
872
+ }
873
+
874
+ // When exists passphraseState, check passphraseState
875
+ if (passphraseState && passphraseState !== newPassphraseState) {
876
+ this.clearInternalState();
877
+ return false;
878
+ }
879
+
880
+ return true;
881
+ }
882
+ }
883
+
884
+ export default Device;