@onekeyfe/hd-core 1.2.0-alpha.67 → 1.2.0-alpha.69

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 (316) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +313 -0
  2. package/__tests__/DeviceCommands.test.ts +59 -13
  3. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +226 -3
  5. package/__tests__/connectSettings.test.ts +5 -47
  6. package/__tests__/core-initialization.test.ts +23 -0
  7. package/__tests__/device-connector-protocol.test.ts +81 -0
  8. package/__tests__/device-lifecycle-events.test.ts +105 -3
  9. package/__tests__/device-pool-state.test.ts +22 -0
  10. package/__tests__/device-settings.test.ts +39 -18
  11. package/__tests__/device-state-contract.test.ts +1 -0
  12. package/__tests__/device-state-mapper.test.ts +13 -1
  13. package/__tests__/device-utils.test.ts +48 -1
  14. package/__tests__/deviceSettings.test.ts +11 -1
  15. package/__tests__/deviceUploadNft.test.ts +316 -0
  16. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  17. package/__tests__/get-device-state.test.ts +132 -12
  18. package/__tests__/homescreen.test.ts +41 -1
  19. package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
  20. package/__tests__/kaspaSignTransaction.test.ts +3 -26
  21. package/__tests__/logBlockEvent.test.ts +1 -1
  22. package/__tests__/method-protocol-support.test.ts +19 -0
  23. package/__tests__/open-wallet-session.test.ts +568 -37
  24. package/__tests__/pro2Nft.test.ts +108 -0
  25. package/__tests__/protocol-binding.test.ts +89 -0
  26. package/__tests__/protocol-v2-firmware-targets.test.ts +33 -1
  27. package/__tests__/protocol-v2-resources.test.ts +343 -0
  28. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  29. package/__tests__/protocol-v2-unlock-policy.test.ts +300 -37
  30. package/__tests__/protocol-v2.test.ts +1586 -1213
  31. package/__tests__/protocolV2FileWrite.test.ts +193 -0
  32. package/__tests__/protocolV2UiInteraction.test.ts +63 -0
  33. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  34. package/__tests__/search-devices.test.ts +12 -3
  35. package/__tests__/tron-sign-message-init.test.ts +2 -2
  36. package/__tests__/uiProgressThrottle.test.ts +74 -0
  37. package/__tests__/uiPromiseRegistry.test.ts +115 -0
  38. package/dist/api/BaseMethod.d.ts +3 -1
  39. package/dist/api/BaseMethod.d.ts.map +1 -1
  40. package/dist/api/CheckAllFirmwareRelease.d.ts +3 -1
  41. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  42. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  43. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  44. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  45. package/dist/api/FirmwareUpdateV2.d.ts +0 -10
  46. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  47. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  48. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  49. package/dist/api/FirmwareUpdateV4.d.ts +15 -27
  50. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  51. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  52. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  53. package/dist/api/SearchDevices.d.ts.map +1 -1
  54. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  55. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  56. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  57. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  58. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  59. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  60. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -11
  61. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  62. package/dist/api/firmware/getBinary.d.ts +0 -7
  63. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  64. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  65. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  66. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  67. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  68. package/dist/api/helpers/protocolV2FileWrite.d.ts +9 -0
  69. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  70. package/dist/api/index.d.ts +2 -0
  71. package/dist/api/index.d.ts.map +1 -1
  72. package/dist/api/kaspa/KaspaGetAddress.d.ts +1 -1
  73. package/dist/api/kaspa/KaspaSignTransaction.d.ts +1 -1
  74. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  75. package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -1
  76. package/dist/api/polkadot/networks.d.ts +1 -1
  77. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  78. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  79. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  80. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  81. package/dist/api/solana/SolSignMessage.d.ts +1 -1
  82. package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -1
  83. package/dist/api/solana/SolSignTransaction.d.ts +2 -2
  84. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  85. package/dist/api/sui/SuiGetAddress.d.ts +1 -1
  86. package/dist/api/sui/SuiGetPublicKey.d.ts +1 -1
  87. package/dist/api/sui/SuiSignMessage.d.ts +1 -1
  88. package/dist/api/sui/SuiSignTransaction.d.ts +1 -1
  89. package/dist/api/ton/TonGetAddress.d.ts +1 -1
  90. package/dist/api/ton/TonSignMessage.d.ts +1 -1
  91. package/dist/api/ton/TonSignProof.d.ts +1 -1
  92. package/dist/api/tron/TronSignMessage.d.ts +2 -2
  93. package/dist/api/tron/TronSignTransaction.d.ts +1 -1
  94. package/dist/core/deviceEventRegistration.d.ts +2 -0
  95. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  96. package/dist/core/index.d.ts.map +1 -1
  97. package/dist/core/uiPromiseRegistry.d.ts +6 -0
  98. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  99. package/dist/data-manager/DataManager.d.ts +9 -4
  100. package/dist/data-manager/DataManager.d.ts.map +1 -1
  101. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  102. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  103. package/dist/device/Device.d.ts +29 -6
  104. package/dist/device/Device.d.ts.map +1 -1
  105. package/dist/device/DeviceCommands.d.ts +4 -4
  106. package/dist/device/DeviceCommands.d.ts.map +1 -1
  107. package/dist/device/DeviceConnector.d.ts +2 -1
  108. package/dist/device/DeviceConnector.d.ts.map +1 -1
  109. package/dist/device/DevicePool.d.ts.map +1 -1
  110. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -1
  111. package/dist/events/device.d.ts +4 -0
  112. package/dist/events/device.d.ts.map +1 -1
  113. package/dist/events/logBlockEvent.d.ts.map +1 -1
  114. package/dist/events/ui-promise.d.ts +4 -2
  115. package/dist/events/ui-promise.d.ts.map +1 -1
  116. package/dist/events/ui-request.d.ts +31 -2
  117. package/dist/events/ui-request.d.ts.map +1 -1
  118. package/dist/events/ui-response.d.ts +10 -2
  119. package/dist/events/ui-response.d.ts.map +1 -1
  120. package/dist/index.d.ts +243 -247
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +3135 -3785
  123. package/dist/inject.d.ts +6 -1
  124. package/dist/inject.d.ts.map +1 -1
  125. package/dist/lowLevelInject.d.ts.map +1 -1
  126. package/dist/protocols/protocol-v2/features.d.ts +0 -4
  127. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  128. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  129. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  130. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  131. package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
  132. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  133. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  134. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  135. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  136. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  137. package/dist/protocols/protocol-v2/walletSession.d.ts +6 -1
  138. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  139. package/dist/topLevelInject.d.ts.map +1 -1
  140. package/dist/types/api/checkAllFirmwareRelease.d.ts +3 -5
  141. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  142. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  143. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  144. package/dist/types/api/deviceUnlock.d.ts +5 -1
  145. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  146. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  147. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  148. package/dist/types/api/export.d.ts +2 -4
  149. package/dist/types/api/export.d.ts.map +1 -1
  150. package/dist/types/api/firmwareUpdate.d.ts +4 -70
  151. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  152. package/dist/types/api/index.d.ts +7 -10
  153. package/dist/types/api/index.d.ts.map +1 -1
  154. package/dist/types/api/protocolV2.d.ts +3 -0
  155. package/dist/types/api/protocolV2.d.ts.map +1 -1
  156. package/dist/types/device.d.ts +2 -2
  157. package/dist/types/device.d.ts.map +1 -1
  158. package/dist/types/params.d.ts +1 -0
  159. package/dist/types/params.d.ts.map +1 -1
  160. package/dist/types/settings.d.ts +38 -21
  161. package/dist/types/settings.d.ts.map +1 -1
  162. package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
  163. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  164. package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
  165. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  166. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  167. package/dist/utils/deviceSettings.d.ts.map +1 -1
  168. package/dist/utils/homescreen.d.ts +4 -0
  169. package/dist/utils/homescreen.d.ts.map +1 -1
  170. package/dist/utils/index.d.ts +1 -1
  171. package/dist/utils/index.d.ts.map +1 -1
  172. package/dist/utils/patch.d.ts +1 -1
  173. package/dist/utils/patch.d.ts.map +1 -1
  174. package/dist/utils/pro2Nft.d.ts +31 -0
  175. package/dist/utils/pro2Nft.d.ts.map +1 -0
  176. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  177. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  178. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  179. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  180. package/package.json +4 -4
  181. package/src/api/BaseMethod.ts +8 -10
  182. package/src/api/CheckAllFirmwareRelease.ts +78 -64
  183. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  184. package/src/api/FirmwareUpdate.ts +7 -15
  185. package/src/api/FirmwareUpdateV2.ts +126 -298
  186. package/src/api/FirmwareUpdateV3.ts +63 -265
  187. package/src/api/FirmwareUpdateV4.ts +645 -1018
  188. package/src/api/GetPassphraseState.ts +7 -1
  189. package/src/api/OpenWalletSession.ts +71 -17
  190. package/src/api/SearchDevices.ts +3 -1
  191. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  192. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +36 -11
  193. package/src/api/device/DeviceSettings.ts +5 -4
  194. package/src/api/device/DeviceUnlock.ts +8 -3
  195. package/src/api/device/DeviceUpdateBootloader.ts +6 -125
  196. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +27 -83
  197. package/src/api/firmware/updateBootloader.ts +4 -19
  198. package/src/api/firmware/uploadFirmware.ts +39 -144
  199. package/src/api/helpers/protocolV2FileWrite.ts +252 -63
  200. package/src/api/index.ts +2 -0
  201. package/src/api/kaspa/KaspaGetAddress.ts +1 -1
  202. package/src/api/kaspa/KaspaSignTransaction.ts +2 -13
  203. package/src/api/polkadot/networks.ts +3 -3
  204. package/src/api/protocol-v2/DeviceUploadNft.ts +197 -0
  205. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  206. package/src/api/protocol-v2/helpers.ts +1 -1
  207. package/src/api/solana/SolSignMessage.ts +1 -1
  208. package/src/api/solana/SolSignOffchainMessage.ts +1 -1
  209. package/src/api/solana/SolSignTransaction.ts +2 -2
  210. package/src/api/sui/SuiGetAddress.ts +1 -1
  211. package/src/api/sui/SuiGetPublicKey.ts +1 -1
  212. package/src/api/sui/SuiSignMessage.ts +1 -1
  213. package/src/api/sui/SuiSignTransaction.ts +1 -1
  214. package/src/api/ton/TonGetAddress.ts +1 -1
  215. package/src/api/ton/TonSignMessage.ts +1 -1
  216. package/src/api/ton/TonSignProof.ts +1 -1
  217. package/src/api/tron/TronSignMessage.ts +2 -2
  218. package/src/api/tron/TronSignTransaction.ts +1 -1
  219. package/src/core/deviceEventRegistration.ts +4 -0
  220. package/src/core/index.ts +213 -111
  221. package/src/core/uiPromiseRegistry.ts +63 -0
  222. package/src/data/messages/messages-protocol-v2.json +25 -0
  223. package/src/data-manager/DataManager.ts +113 -41
  224. package/src/data-manager/TransportManager.ts +6 -0
  225. package/src/data-manager/connectSettings.ts +0 -11
  226. package/src/device/Device.ts +274 -49
  227. package/src/device/DeviceCommands.ts +31 -4
  228. package/src/device/DeviceConnector.ts +33 -13
  229. package/src/device/DevicePool.ts +21 -7
  230. package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
  231. package/src/deviceProfile/protocolV2DeviceIdentity.ts +3 -0
  232. package/src/events/device.ts +4 -0
  233. package/src/events/logBlockEvent.ts +1 -0
  234. package/src/events/ui-promise.ts +4 -2
  235. package/src/events/ui-request.ts +36 -2
  236. package/src/events/ui-response.ts +12 -2
  237. package/src/index.ts +0 -5
  238. package/src/inject.ts +60 -24
  239. package/src/lowLevelInject.ts +7 -8
  240. package/src/protocols/protocol-v2/features.ts +10 -7
  241. package/src/protocols/protocol-v2/firmware.ts +2 -0
  242. package/src/protocols/protocol-v2/resources.ts +394 -0
  243. package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
  244. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  245. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +131 -0
  246. package/src/protocols/protocol-v2/walletSession.ts +214 -36
  247. package/src/topLevelInject.ts +7 -8
  248. package/src/types/api/checkAllFirmwareRelease.ts +3 -5
  249. package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
  250. package/src/types/api/deviceUnlock.ts +12 -1
  251. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  252. package/src/types/api/export.ts +1 -18
  253. package/src/types/api/firmwareUpdate.ts +6 -78
  254. package/src/types/api/index.ts +13 -14
  255. package/src/types/api/protocolV2.ts +13 -0
  256. package/src/types/device.ts +15 -3
  257. package/src/types/params.ts +7 -1
  258. package/src/types/settings.ts +61 -22
  259. package/src/utils/deviceFeaturesCompat.ts +5 -6
  260. package/src/utils/deviceFeaturesUtils.ts +14 -3
  261. package/src/utils/deviceInfoUtils.ts +2 -0
  262. package/src/utils/deviceSettings.ts +3 -0
  263. package/src/utils/homescreen.ts +32 -6
  264. package/src/utils/index.ts +6 -1
  265. package/src/utils/pro2Nft.ts +142 -0
  266. package/src/utils/pro2Wallpaper.ts +35 -8
  267. package/src/utils/uiProgressThrottle.ts +63 -0
  268. package/__tests__/device-initialize-timeout.test.ts +0 -56
  269. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  270. package/__tests__/firmware-update/device-update-bootloader.test.ts +0 -87
  271. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  272. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  273. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  274. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
  275. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  276. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -394
  277. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  278. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -231
  279. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
  280. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  281. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  282. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  283. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  284. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  285. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  286. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  287. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  288. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  289. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  290. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  291. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
  292. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  293. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  294. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  295. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  296. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  297. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  298. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  299. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  300. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  301. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  302. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  303. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  304. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  305. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  306. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  307. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  308. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  309. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
  310. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -449
  311. package/src/api/firmware/progressThrottle.ts +0 -44
  312. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  313. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
  314. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  315. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  316. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
package/src/core/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import semver from 'semver';
2
2
  import EventEmitter from 'events';
3
- import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
3
+ import { DeviceSessionPinType, TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
4
4
  import {
5
5
  ERRORS,
6
6
  ERROR_CODES_REQUIRE_RELEASE,
@@ -26,6 +26,7 @@ import {
26
26
  createRequestContext,
27
27
  createSdkTracingContext,
28
28
  formatRequestContext,
29
+ generateInstanceId,
29
30
  getActiveRequestsByDeviceInstance,
30
31
  updateRequestContext,
31
32
  } from '../utils/tracing';
@@ -53,13 +54,15 @@ import {
53
54
  import TransportManager from '../data-manager/TransportManager';
54
55
  import DeviceConnector from '../device/DeviceConnector';
55
56
  import RequestQueue from './RequestQueue';
57
+ import { consumeUiPromise, findUiPromiseForResponse, rejectUiPromises } from './uiPromiseRegistry';
56
58
  import { registerHardwareUiEventListeners } from './deviceEventRegistration';
57
59
  import { getSynchronize } from '../utils/getSynchronize';
58
- import { runMethodWithUnlockRetry } from '../protocols/protocol-v2/unlockRetry';
60
+ import { runMethodWithUnlockPolicy } from '../protocols/protocol-v2/unlockPolicyRunner';
59
61
  import {
60
62
  ProtocolV2UiInteractionCoordinator,
61
63
  isProtocolV2UiEnabled,
62
64
  } from '../protocols/protocol-v2/uiInteraction';
65
+ import { createUiProgressMessageFilter } from '../utils/uiProgressThrottle';
63
66
 
64
67
  import type { ConnectSettings, Features, KnownDevice } from '../types';
65
68
  import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
@@ -103,6 +106,7 @@ const parseInitOptions = (method?: BaseMethod): InitOptions => ({
103
106
  deviceId: method?.payload.deviceId,
104
107
  deriveCardano: method && hasDeriveCardano(method),
105
108
  connectProtocol: method?.payload.connectProtocol,
109
+ forceProtocolDetection: method?.payload.forceProtocolDetection,
106
110
  protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
107
111
  });
108
112
 
@@ -154,7 +158,12 @@ export const callAPI = async (context: CoreContext, message: CoreMessage) => {
154
158
  try {
155
159
  method = findMethod(message as IFrameCallMessage);
156
160
  method.connector = _connector;
157
- method.postMessage = postMessage;
161
+ const shouldPostMessage = createUiProgressMessageFilter();
162
+ method.postMessage = event => {
163
+ if (shouldPostMessage(event)) {
164
+ postMessage(event);
165
+ }
166
+ };
158
167
  method.setContext?.(context);
159
168
 
160
169
  method.requestContext = createRequestContext(method.responseID, method.name, {
@@ -406,6 +415,8 @@ const onCallDevice = async (
406
415
 
407
416
  registerHardwareUiEventListeners(device, {
408
417
  pin: onDevicePinHandler,
418
+ pinOnDevice: onEnterPinOnDeviceHandler,
419
+ pinOnDeviceComplete: onPinOnDeviceCompleteHandler,
409
420
  button: onDeviceButtonHandler,
410
421
  passphrase: message.payload.useEmptyPassphrase
411
422
  ? onEmptyPassphraseHandler
@@ -421,6 +432,9 @@ const onCallDevice = async (
421
432
  );
422
433
 
423
434
  const protocolV2UiCoordinator = new ProtocolV2UiInteractionCoordinator(device, postMessage);
435
+ let protocolV2Operation = false;
436
+ let protocolV2CloseEmitted = false;
437
+ device.beginProtocolV2UiInteraction();
424
438
  device.on(
425
439
  DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE,
426
440
  onSelectDeviceForSwitchFirmwareWebDeviceHandler
@@ -438,6 +452,7 @@ const onCallDevice = async (
438
452
  // Protocol is established from an active device response during acquire/initialize.
439
453
  // Reject unsupported methods before any method-specific device command is sent.
440
454
  method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
455
+ protocolV2Operation = device.isProtocolV2();
441
456
 
442
457
  // check firmware version
443
458
  const versionRange = device.getCurrentMethodVersionRange(
@@ -547,93 +562,102 @@ const onCallDevice = async (
547
562
  );
548
563
  }
549
564
 
550
- if (method.deviceId && method.checkDeviceId) {
551
- const isSameDeviceID = await checkLiveDeviceId(device, method.deviceId);
552
- if (!isSameDeviceID) {
553
- return Promise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError));
554
- }
555
- }
556
-
557
- /**
558
- * check firmware release info
559
- */
560
- method.checkFirmwareRelease();
565
+ try {
566
+ let deviceIdCheckedDuringUnlockPreflight = false;
567
+ const response = await runMethodWithUnlockPolicy<object>(method, device, {
568
+ uiCoordinator: protocolV2UiCoordinator,
569
+ afterStatusBeforeUnlock: () => {
570
+ if (method.deviceId && method.checkDeviceId) {
571
+ if (!device.checkDeviceId(method.deviceId)) {
572
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
573
+ }
574
+ deviceIdCheckedDuringUnlockPreflight = true;
575
+ }
576
+ },
577
+ prepare: async () => {
578
+ if (method.deviceId && method.checkDeviceId && !deviceIdCheckedDuringUnlockPreflight) {
579
+ const isSameDeviceID = await checkLiveDeviceId(device, method.deviceId);
580
+ if (!isSameDeviceID) {
581
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
582
+ }
583
+ }
561
584
 
562
- /**
563
- * check additional supported feature
564
- */
565
- method.checkDeviceSupportFeature();
585
+ /**
586
+ * check firmware release info
587
+ */
588
+ method.checkFirmwareRelease();
566
589
 
567
- // reconfigure messages
568
- if (_deviceList && device.features && !device.isProtocolV2()) {
569
- await TransportManager.reconfigure(device.features);
570
- }
590
+ /**
591
+ * check additional supported feature
592
+ */
593
+ method.checkDeviceSupportFeature();
571
594
 
572
- // Check to see if it is safe to use Passphrase
573
- checkPassphraseEnableState(method, device.features);
595
+ // reconfigure messages
596
+ if (_deviceList && device.features && !device.isProtocolV2()) {
597
+ await TransportManager.reconfigure(device.features);
598
+ }
574
599
 
575
- if (shouldCheckPassphraseState(method, device)) {
576
- // check version
577
- const support = device.supportNewPassphrase();
578
- if (!support.support) {
579
- return Promise.reject(
580
- ERRORS.TypedError(
581
- HardwareErrorCode.DeviceNotSupportPassphrase,
582
- `Device not support passphrase, please update to ${support.require}`,
583
- {
584
- require: support.require,
600
+ // Check to see if it is safe to use Passphrase
601
+ checkPassphraseEnableState(method, device.features);
602
+
603
+ if (shouldCheckPassphraseState(method, device)) {
604
+ // check version
605
+ const support = device.supportNewPassphrase();
606
+ if (!support.support) {
607
+ throw ERRORS.TypedError(
608
+ HardwareErrorCode.DeviceNotSupportPassphrase,
609
+ `Device not support passphrase, please update to ${support.require}`,
610
+ {
611
+ require: support.require,
612
+ }
613
+ );
585
614
  }
586
- )
587
- );
588
- }
589
615
 
590
- // Check Device passphrase State
591
- const passphraseStateSafety = await device.checkPassphraseStateSafety(
592
- method.payload?.passphraseState,
593
- method.payload?.useEmptyPassphrase,
594
- method.payload?.skipPassphraseCheck
595
- );
616
+ // Check Device passphrase State after the Protocol V2 pre-unlock gate.
617
+ const passphraseStateSafety = await device.checkPassphraseStateSafety(
618
+ method.payload?.passphraseState,
619
+ method.payload?.useEmptyPassphrase,
620
+ method.payload?.skipPassphraseCheck,
621
+ hasDeriveCardano(method)
622
+ );
596
623
 
597
- // Double check, handles the special case of Touch/Pro
598
- checkPassphraseEnableState(method, device.features);
624
+ // Double check, handles the special case of Touch/Pro
625
+ checkPassphraseEnableState(method, device.features);
599
626
 
600
- if (!passphraseStateSafety) {
601
- DevicePool.clearDeviceCache(method.payload.connectId);
602
- return Promise.reject(
603
- ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError)
604
- );
605
- }
606
-
607
- // close pin popup window
608
- postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
609
- }
627
+ if (!passphraseStateSafety) {
628
+ DevicePool.clearDeviceCache(method.payload.connectId);
629
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
630
+ }
610
631
 
611
- // Automatic check safety_check level for Kovan, Ropsten, Rinkeby, Goerli test networks.
612
- try {
613
- await method.checkSafetyLevelOnTestNet();
614
- } catch (e) {
615
- const error =
616
- e instanceof HardwareError
617
- ? e
618
- : ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'open safety check failed.');
619
- // messageResponse = createResponseMessage(method.responseID, false, { error });
620
- // requestQueue.resolveRequest(method.responseID, messageResponse);
621
- // return;
622
- throw error;
623
- }
632
+ // Protocol V2 emits the PIN phase completion from DeviceSessionAskPin.
633
+ // Keep the legacy compatibility close for Protocol V1 only.
634
+ if (!device.isProtocolV2()) {
635
+ postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
636
+ }
637
+ }
624
638
 
625
- method.device?.commands?.checkDisposed();
639
+ // Automatic check safety_check level for Kovan, Ropsten, Rinkeby, Goerli test networks.
640
+ try {
641
+ await method.checkSafetyLevelOnTestNet();
642
+ } catch (e) {
643
+ throw e instanceof HardwareError
644
+ ? e
645
+ : ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'open safety check failed.');
646
+ }
626
647
 
627
- try {
628
- const response: object = await runMethodWithUnlockRetry(
629
- method,
630
- device,
631
- protocolV2UiCoordinator
632
- );
648
+ method.device?.commands?.checkDisposed();
649
+ },
650
+ });
633
651
  messageResponse = createResponseMessage(method.responseID, true, response);
634
652
  requestQueue.resolveRequest(method.responseID, messageResponse);
635
653
  completeMethodRequestContext(method);
636
654
  } catch (error) {
655
+ // Device.run may release the request before transport callbacks finish after a timeout.
656
+ // Ignore the stale callback because the caller already received the connection error.
657
+ if (!requestQueue.getTask(method.responseID)) {
658
+ Log.debug(`Call API - Ignore late inner method result`, error);
659
+ return;
660
+ }
637
661
  Log.debug(`Call API - Inner Method Run Error`, error);
638
662
  messageResponse = createResponseMessage(method.responseID, false, { error });
639
663
  requestQueue.resolveRequest(method.responseID, messageResponse);
@@ -647,7 +671,12 @@ const onCallDevice = async (
647
671
  throw error;
648
672
  }
649
673
  } finally {
650
- protocolV2UiCoordinator.close();
674
+ if (isProtocolV2UiEnabled(method)) {
675
+ protocolV2CloseEmitted = protocolV2UiCoordinator.close({
676
+ ensureOperationClose: protocolV2Operation,
677
+ protocolV2Operation,
678
+ });
679
+ }
651
680
  }
652
681
  };
653
682
  Log.debug('Call API - Device Run: ', device.mainId);
@@ -702,7 +731,15 @@ const onCallDevice = async (
702
731
  requestQueue.releaseTask(method.responseID);
703
732
 
704
733
  if (isProtocolV2UiEnabled(method)) {
705
- closePopup();
734
+ if (!protocolV2CloseEmitted && protocolV2Operation) {
735
+ protocolV2CloseEmitted = protocolV2UiCoordinator.close({
736
+ ensureOperationClose: true,
737
+ protocolV2Operation: true,
738
+ });
739
+ }
740
+ if (!protocolV2CloseEmitted) {
741
+ closePopup();
742
+ }
706
743
  }
707
744
 
708
745
  cleanup();
@@ -865,10 +902,18 @@ function isRetryableBleProtocolV2ProbeError(method: BaseMethod, error: unknown)
865
902
  */
866
903
  async function connectDeviceForBle(method: BaseMethod, device: Device, retryCount = 0) {
867
904
  try {
905
+ if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
906
+ await device.release();
907
+ }
868
908
  const shouldAcquire =
869
- !device.hasDeviceAcquire() || !device.commands || device.commands.disposed;
909
+ method.payload.forceProtocolDetection ||
910
+ !device.hasDeviceAcquire() ||
911
+ !device.commands ||
912
+ device.commands.disposed;
870
913
  if (shouldAcquire) {
871
- await device.acquire(method.payload.connectProtocol);
914
+ await device.acquire(method.payload.connectProtocol, {
915
+ forceProtocolDetection: method.payload.forceProtocolDetection,
916
+ });
872
917
  }
873
918
  if (method.payload?.onlyConnectBleDevice) {
874
919
  if (shouldAcquire) {
@@ -1181,7 +1226,12 @@ const shouldCheckPassphraseState = (method: BaseMethod, device: Device) => {
1181
1226
  };
1182
1227
 
1183
1228
  const cleanup = () => {
1229
+ const pendingUiPromises = _uiPromises;
1184
1230
  _uiPromises = [];
1231
+ rejectUiPromises(
1232
+ pendingUiPromises,
1233
+ ERRORS.TypedError(HardwareErrorCode.ActionCancelled, 'UI request was cancelled')
1234
+ );
1185
1235
  Log.debug('Cleanup...');
1186
1236
  };
1187
1237
 
@@ -1223,7 +1273,7 @@ const onTransportDeviceDisconnectHandler = (event: TransportDeviceDisconnectEven
1223
1273
  DevicePool.emitter.emit(DEVICE.DISCONNECT, device);
1224
1274
  };
1225
1275
 
1226
- const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin']) => {
1276
+ const onDevicePinHandler = (...[device, type, callback]: DeviceEvents['pin']) => {
1227
1277
  Log.log('request Input PIN');
1228
1278
  // create ui promise
1229
1279
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PIN, device);
@@ -1232,12 +1282,14 @@ const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin
1232
1282
  createUiMessage(UI_REQUEST.REQUEST_PIN, {
1233
1283
  device: device.toMessageObject() as unknown as KnownDevice,
1234
1284
  type,
1285
+ responseCorrelation: uiPromise.responseCorrelation,
1235
1286
  })
1236
1287
  );
1237
- // wait for pin
1238
- const uiResp = await uiPromise.promise;
1239
- // callback.apply(null, [null, pin]);
1240
- callback(null, uiResp.payload);
1288
+ consumeUiPromise(
1289
+ uiPromise.promise,
1290
+ uiResp => callback(null, uiResp.payload),
1291
+ error => callback(error, '')
1292
+ );
1241
1293
  };
1242
1294
 
1243
1295
  export const onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
@@ -1265,7 +1317,7 @@ const onDeviceStateHandler = (...[_, stateEvent]: [...DeviceEvents['state']]) =>
1265
1317
  postMessage(createDeviceMessage(DEVICE.STATE, stateEvent));
1266
1318
  };
1267
1319
 
1268
- const onDevicePassphraseHandler = async (
1320
+ const onDevicePassphraseHandler = (
1269
1321
  ...[device, requestPayload, callback]: DeviceEvents['passphrase']
1270
1322
  ) => {
1271
1323
  Log.debug('onDevicePassphraseHandler');
@@ -1279,18 +1331,23 @@ const onDevicePassphraseHandler = async (
1279
1331
  source: requestPayload.source,
1280
1332
  reason: requestPayload.reason,
1281
1333
  expectedPassphraseState: requestPayload.expectedPassphraseState,
1334
+ ...(requestPayload.interaction ? { interaction: requestPayload.interaction } : {}),
1335
+ responseCorrelation: uiPromise.responseCorrelation,
1282
1336
  })
1283
1337
  );
1284
- // wait for passphrase
1285
- const uiResp = await uiPromise.promise;
1286
- const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
1287
- // send as PassphrasePromptResponse
1288
- callback({
1289
- passphrase: value.normalize('NFKD'),
1290
- passphraseOnDevice,
1291
- attachPinOnDevice,
1292
- cache: save,
1293
- });
1338
+ consumeUiPromise(
1339
+ uiPromise.promise,
1340
+ uiResp => {
1341
+ const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
1342
+ callback({
1343
+ passphrase: value.normalize('NFKD'),
1344
+ passphraseOnDevice,
1345
+ attachPinOnDevice,
1346
+ cache: save,
1347
+ });
1348
+ },
1349
+ error => callback({}, error)
1350
+ );
1294
1351
  };
1295
1352
 
1296
1353
  const onEmptyPassphraseHandler = (...[_, , callback]: DeviceEvents['passphrase']) => {
@@ -1308,6 +1365,7 @@ const onEnterPassphraseOnDeviceHandler = (
1308
1365
  passphraseState: device.passphraseState,
1309
1366
  source: requestPayload?.source,
1310
1367
  reason: requestPayload?.reason,
1368
+ ...(requestPayload?.interaction ? { interaction: requestPayload.interaction } : {}),
1311
1369
  })
1312
1370
  );
1313
1371
  };
@@ -1321,11 +1379,40 @@ const onEnterAttachPinOnDeviceHandler = (
1321
1379
  type: 'ButtonRequest_AttachPin',
1322
1380
  source: requestPayload?.source,
1323
1381
  reason: requestPayload?.reason,
1382
+ ...(requestPayload?.interaction ? { interaction: requestPayload.interaction } : {}),
1324
1383
  })
1325
1384
  );
1326
1385
  };
1327
1386
 
1328
- const onSelectDeviceInBootloaderForWebDeviceHandler = async (
1387
+ const onEnterPinOnDeviceHandler = (
1388
+ ...[device, pinType, metadata]: [...DeviceEvents['pin_on_device']]
1389
+ ) => {
1390
+ postMessage(
1391
+ createUiMessage(UI_REQUEST.REQUEST_PIN, {
1392
+ device: device.toMessageObject() as KnownDevice,
1393
+ type:
1394
+ pinType === DeviceSessionPinType.AttachToPin
1395
+ ? 'ButtonRequest_AttachPin'
1396
+ : 'ButtonRequest_PinEntry',
1397
+ source: metadata?.source,
1398
+ reason: metadata?.reason,
1399
+ deviceOnly: metadata?.deviceOnly ?? true,
1400
+ completion: metadata?.completion,
1401
+ method: metadata?.method,
1402
+ page: metadata?.page,
1403
+ operation: metadata?.operation,
1404
+ ...(metadata?.interaction ? { interaction: metadata.interaction } : {}),
1405
+ })
1406
+ );
1407
+ };
1408
+
1409
+ const onPinOnDeviceCompleteHandler = (
1410
+ ...[_, metadata]: [...DeviceEvents['pin_on_device_complete']]
1411
+ ) => {
1412
+ postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW, metadata));
1413
+ };
1414
+
1415
+ const onSelectDeviceInBootloaderForWebDeviceHandler = (
1329
1416
  ...[device, callback]: [...DeviceEvents['select_device_in_bootloader_for_web_device']]
1330
1417
  ) => {
1331
1418
  Log.debug('onSelectDeviceInBootloaderForWebDeviceHandler');
@@ -1335,11 +1422,14 @@ const onSelectDeviceInBootloaderForWebDeviceHandler = async (
1335
1422
  device: device.toMessageObject() as KnownDevice,
1336
1423
  })
1337
1424
  );
1338
- const uiResp = await uiPromise.promise;
1339
- callback(null, uiResp.payload.deviceId);
1425
+ consumeUiPromise(
1426
+ uiPromise.promise,
1427
+ uiResp => callback(null, uiResp.payload.deviceId),
1428
+ error => callback(error, '')
1429
+ );
1340
1430
  };
1341
1431
 
1342
- const onSelectDeviceForSwitchFirmwareWebDeviceHandler = async (
1432
+ const onSelectDeviceForSwitchFirmwareWebDeviceHandler = (
1343
1433
  ...[device, callback]: [...DeviceEvents['select_device_for_switch_firmware_web_device']]
1344
1434
  ) => {
1345
1435
  Log.debug('onSelectDeviceForSwitchFirmwareWebDeviceHandler');
@@ -1352,8 +1442,11 @@ const onSelectDeviceForSwitchFirmwareWebDeviceHandler = async (
1352
1442
  device: device.toMessageObject() as KnownDevice,
1353
1443
  })
1354
1444
  );
1355
- const uiResp = await uiPromise.promise;
1356
- callback(null, uiResp.payload.deviceId);
1445
+ consumeUiPromise(
1446
+ uiPromise.promise,
1447
+ uiResp => callback(null, uiResp.payload.deviceId),
1448
+ error => callback(error, '')
1449
+ );
1357
1450
  };
1358
1451
 
1359
1452
  /**
@@ -1372,14 +1465,21 @@ const postMessage = (message: CoreMessage) => {
1372
1465
 
1373
1466
  const createUiPromise = <T extends UiPromiseResponse['type']>(promiseEvent: T, device?: Device) => {
1374
1467
  const uiPromise: UiPromise<T> = createDeferred(promiseEvent, device);
1468
+ if (
1469
+ device &&
1470
+ (promiseEvent === UI_RESPONSE.RECEIVE_PIN || promiseEvent === UI_RESPONSE.RECEIVE_PASSPHRASE)
1471
+ ) {
1472
+ const publicDeviceId = device.toMessageObject()?.deviceId;
1473
+ uiPromise.responseCorrelation = {
1474
+ interactionId: generateInstanceId('UiResponse', device.sdkInstanceId),
1475
+ deviceId: publicDeviceId || device.instanceId,
1476
+ };
1477
+ }
1375
1478
  _uiPromises.push(uiPromise as any);
1376
1479
 
1377
1480
  return uiPromise;
1378
1481
  };
1379
1482
 
1380
- const findUiPromise = <T extends UiPromiseResponse['type']>(promiseEvent: T) =>
1381
- _uiPromises.find(p => p.id === promiseEvent);
1382
-
1383
1483
  const removeUiPromise = (promise: Deferred<any>) => {
1384
1484
  _uiPromises = _uiPromises.filter(p => p !== promise);
1385
1485
  };
@@ -1431,11 +1531,16 @@ export default class Core extends EventEmitter {
1431
1531
  case UI_RESPONSE.RECEIVE_PASSPHRASE:
1432
1532
  case UI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE:
1433
1533
  case UI_RESPONSE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE: {
1434
- const uiPromise = findUiPromise(message.type);
1534
+ const uiPromise = findUiPromiseForResponse(_uiPromises, message);
1435
1535
  if (uiPromise) {
1436
1536
  Log.log('receive UI Response: ', message.type);
1437
1537
  uiPromise.resolve(message);
1438
1538
  removeUiPromise(uiPromise);
1539
+ } else if (
1540
+ message.type === UI_RESPONSE.RECEIVE_PIN ||
1541
+ message.type === UI_RESPONSE.RECEIVE_PASSPHRASE
1542
+ ) {
1543
+ Log.warn('Ignored unmatched or ambiguous sensitive UI response:', message.type);
1439
1544
  }
1440
1545
  break;
1441
1546
  }
@@ -1563,12 +1668,8 @@ export const init = async (
1563
1668
  plugin?: LowlevelTransportSharedPlugin
1564
1669
  ) => {
1565
1670
  try {
1566
- try {
1567
- await DataManager.load(settings);
1568
- initTransport(Transport, plugin);
1569
- } catch {
1570
- Log.error('DataManager.load error');
1571
- }
1671
+ await DataManager.load(settings);
1672
+ initTransport(Transport, plugin);
1572
1673
  enableLog(DataManager.getSettings('debug'));
1573
1674
  if (DataManager.getSettings('env') !== 'react-native') {
1574
1675
  setLoggerPostMessage(postMessage);
@@ -1579,6 +1680,7 @@ export const init = async (
1579
1680
  return _core;
1580
1681
  } catch (error) {
1581
1682
  Log.error('core init', error);
1683
+ throw error;
1582
1684
  }
1583
1685
  };
1584
1686
 
@@ -0,0 +1,63 @@
1
+ import { UI_RESPONSE } from '../events/ui-response';
2
+
3
+ import type { UiPromise, UiPromiseResponse } from '../events/ui-promise';
4
+ import type { UiResponseEvent } from '../events/ui-response';
5
+
6
+ const normalizeUiPromiseError = (error: unknown) =>
7
+ error instanceof Error ? error : new Error(String(error));
8
+
9
+ export const consumeUiPromise = <T>(
10
+ promise: Promise<T>,
11
+ onFulfilled: (value: T) => void,
12
+ onRejected: (error: Error) => void
13
+ ) => {
14
+ promise.then(onFulfilled, error => {
15
+ onRejected(normalizeUiPromiseError(error));
16
+ });
17
+ };
18
+
19
+ export const rejectUiPromises = (
20
+ uiPromises: UiPromise<UiPromiseResponse['type']>[],
21
+ error: Error
22
+ ) => {
23
+ for (const uiPromise of uiPromises) {
24
+ uiPromise.reject(error);
25
+ }
26
+ };
27
+
28
+ const isSensitiveUiResponse = (
29
+ response: UiResponseEvent
30
+ ): response is Extract<
31
+ UiResponseEvent,
32
+ { type: typeof UI_RESPONSE.RECEIVE_PIN | typeof UI_RESPONSE.RECEIVE_PASSPHRASE }
33
+ > => response.type === UI_RESPONSE.RECEIVE_PIN || response.type === UI_RESPONSE.RECEIVE_PASSPHRASE;
34
+
35
+ export const findUiPromiseForResponse = (
36
+ uiPromises: UiPromise<UiPromiseResponse['type']>[],
37
+ response: UiResponseEvent
38
+ ) => {
39
+ const candidates = uiPromises.filter(promise => promise.id === response.type);
40
+ if (!isSensitiveUiResponse(response)) {
41
+ return candidates[0];
42
+ }
43
+
44
+ const hasInteractionId = typeof response.interactionId === 'string';
45
+ const hasDeviceId = typeof response.deviceId === 'string';
46
+ if (hasInteractionId !== hasDeviceId) {
47
+ return undefined;
48
+ }
49
+
50
+ if (hasInteractionId && hasDeviceId) {
51
+ return candidates.find(promise => {
52
+ const correlation = promise.responseCorrelation;
53
+ return (
54
+ correlation?.interactionId === response.interactionId &&
55
+ correlation?.deviceId === response.deviceId
56
+ );
57
+ });
58
+ }
59
+
60
+ // Legacy clients do not return correlation metadata. Preserve their single-request
61
+ // behavior, but never guess when multiple sensitive requests are pending.
62
+ return candidates.length === 1 ? candidates[0] : undefined;
63
+ };
@@ -470,6 +470,7 @@
470
470
  "MessageType_DeviceSessionAskPin": 61202,
471
471
  "MessageType_DeviceSessionAskPassphrase": 61203,
472
472
  "MessageType_PortfolioUpdate": 61400,
473
+ "MessageType_NftUpdate": 61500,
473
474
  "MessageType_OnboardingStatusGet": 61600,
474
475
  "MessageType_OnboardingStatus": 61601
475
476
  },
@@ -12200,11 +12201,26 @@
12200
12201
  "DeviceSessionError_Busy": 5
12201
12202
  }
12202
12203
  },
12204
+ "DeviceSessionSeedDomain": {
12205
+ "values": {
12206
+ "SeedDomain_Standard": 1,
12207
+ "SeedDomain_Cardano": 2
12208
+ }
12209
+ },
12203
12210
  "DeviceSessionGet": {
12204
12211
  "fields": {
12205
12212
  "session_id": {
12206
12213
  "type": "bytes",
12207
12214
  "id": 1
12215
+ },
12216
+ "btc_test_address": {
12217
+ "type": "string",
12218
+ "id": 2
12219
+ },
12220
+ "seed_domains": {
12221
+ "rule": "repeated",
12222
+ "type": "DeviceSessionSeedDomain",
12223
+ "id": 3
12208
12224
  }
12209
12225
  }
12210
12226
  },
@@ -12538,6 +12554,15 @@
12538
12554
  }
12539
12555
  }
12540
12556
  },
12557
+ "NftUpdate": {
12558
+ "fields": {
12559
+ "file_name_no_ext": {
12560
+ "rule": "required",
12561
+ "type": "string",
12562
+ "id": 1
12563
+ }
12564
+ }
12565
+ },
12541
12566
  "OnboardingStep": {
12542
12567
  "values": {
12543
12568
  "ONBOARDING_STEP_UNKNOWN": 0,