@onekeyfe/hd-core 1.2.0-alpha.54 → 1.2.0-alpha.56

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 (262) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +231 -0
  2. package/__tests__/DeviceCommands.test.ts +45 -0
  3. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +198 -3
  5. package/__tests__/connectSettings.test.ts +5 -47
  6. package/__tests__/device-lifecycle-events.test.ts +105 -3
  7. package/__tests__/device-state-contract.test.ts +1 -0
  8. package/__tests__/device-state-mapper.test.ts +1 -1
  9. package/__tests__/deviceSettings.test.ts +1 -1
  10. package/__tests__/deviceUploadNft.test.ts +293 -0
  11. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  12. package/__tests__/get-device-state.test.ts +132 -12
  13. package/__tests__/homescreen.test.ts +41 -1
  14. package/__tests__/kaspaSignTransaction.test.ts +3 -26
  15. package/__tests__/logBlockEvent.test.ts +1 -1
  16. package/__tests__/method-protocol-support.test.ts +19 -0
  17. package/__tests__/open-wallet-session.test.ts +568 -37
  18. package/__tests__/pro2Nft.test.ts +108 -0
  19. package/__tests__/protocol-binding.test.ts +89 -0
  20. package/__tests__/protocol-v2-resources.test.ts +286 -0
  21. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  22. package/__tests__/protocol-v2-unlock-policy.test.ts +201 -35
  23. package/__tests__/protocol-v2.test.ts +1353 -1011
  24. package/__tests__/protocolV2FileWrite.test.ts +39 -0
  25. package/__tests__/protocolV2UiInteraction.test.ts +63 -0
  26. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  27. package/__tests__/search-devices.test.ts +12 -3
  28. package/__tests__/uiProgressThrottle.test.ts +74 -0
  29. package/__tests__/uiPromiseRegistry.test.ts +86 -0
  30. package/dist/api/BaseMethod.d.ts +3 -1
  31. package/dist/api/BaseMethod.d.ts.map +1 -1
  32. package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
  33. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  34. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  35. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  36. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  37. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  38. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  39. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  40. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  41. package/dist/api/FirmwareUpdateV4.d.ts +11 -25
  42. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  43. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  44. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  45. package/dist/api/SearchDevices.d.ts.map +1 -1
  46. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  47. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  48. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  49. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  50. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  51. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -9
  52. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  53. package/dist/api/firmware/getBinary.d.ts +0 -7
  54. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  55. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  56. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  57. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  58. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  59. package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
  60. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  61. package/dist/api/index.d.ts +2 -0
  62. package/dist/api/index.d.ts.map +1 -1
  63. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  64. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  65. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  66. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  67. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  68. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  69. package/dist/core/deviceEventRegistration.d.ts +2 -0
  70. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  71. package/dist/core/index.d.ts.map +1 -1
  72. package/dist/core/uiPromiseRegistry.d.ts +4 -0
  73. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  74. package/dist/data-manager/DataManager.d.ts +4 -2
  75. package/dist/data-manager/DataManager.d.ts.map +1 -1
  76. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  77. package/dist/device/Device.d.ts +29 -6
  78. package/dist/device/Device.d.ts.map +1 -1
  79. package/dist/device/DeviceCommands.d.ts +4 -4
  80. package/dist/device/DeviceCommands.d.ts.map +1 -1
  81. package/dist/device/DevicePool.d.ts.map +1 -1
  82. package/dist/events/device.d.ts +4 -0
  83. package/dist/events/device.d.ts.map +1 -1
  84. package/dist/events/logBlockEvent.d.ts.map +1 -1
  85. package/dist/events/ui-promise.d.ts +4 -2
  86. package/dist/events/ui-promise.d.ts.map +1 -1
  87. package/dist/events/ui-request.d.ts +31 -2
  88. package/dist/events/ui-request.d.ts.map +1 -1
  89. package/dist/events/ui-response.d.ts +10 -2
  90. package/dist/events/ui-response.d.ts.map +1 -1
  91. package/dist/index.d.ts +214 -231
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +2634 -3530
  94. package/dist/inject.d.ts +6 -1
  95. package/dist/inject.d.ts.map +1 -1
  96. package/dist/lowLevelInject.d.ts.map +1 -1
  97. package/dist/protocols/protocol-v2/features.d.ts +0 -4
  98. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  99. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  100. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  101. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  102. package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
  103. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  104. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  105. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  106. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  107. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  108. package/dist/protocols/protocol-v2/walletSession.d.ts +6 -1
  109. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  110. package/dist/topLevelInject.d.ts.map +1 -1
  111. package/dist/types/api/checkAllFirmwareRelease.d.ts +2 -4
  112. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  113. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  114. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  115. package/dist/types/api/deviceUnlock.d.ts +5 -1
  116. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  117. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  118. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  119. package/dist/types/api/export.d.ts +2 -4
  120. package/dist/types/api/export.d.ts.map +1 -1
  121. package/dist/types/api/firmwareUpdate.d.ts +2 -70
  122. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  123. package/dist/types/api/index.d.ts +7 -10
  124. package/dist/types/api/index.d.ts.map +1 -1
  125. package/dist/types/api/protocolV2.d.ts +3 -0
  126. package/dist/types/api/protocolV2.d.ts.map +1 -1
  127. package/dist/types/device.d.ts.map +1 -1
  128. package/dist/types/params.d.ts +1 -0
  129. package/dist/types/params.d.ts.map +1 -1
  130. package/dist/types/settings.d.ts +22 -13
  131. package/dist/types/settings.d.ts.map +1 -1
  132. package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
  133. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  134. package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
  135. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  136. package/dist/utils/homescreen.d.ts +4 -0
  137. package/dist/utils/homescreen.d.ts.map +1 -1
  138. package/dist/utils/index.d.ts +1 -1
  139. package/dist/utils/index.d.ts.map +1 -1
  140. package/dist/utils/patch.d.ts +1 -1
  141. package/dist/utils/patch.d.ts.map +1 -1
  142. package/dist/utils/pro2Nft.d.ts +31 -0
  143. package/dist/utils/pro2Nft.d.ts.map +1 -0
  144. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  145. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  146. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  147. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  148. package/package.json +4 -4
  149. package/src/api/BaseMethod.ts +8 -10
  150. package/src/api/CheckAllFirmwareRelease.ts +54 -57
  151. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  152. package/src/api/FirmwareUpdate.ts +7 -15
  153. package/src/api/FirmwareUpdateV2.ts +126 -316
  154. package/src/api/FirmwareUpdateV3.ts +63 -265
  155. package/src/api/FirmwareUpdateV4.ts +584 -975
  156. package/src/api/GetPassphraseState.ts +7 -1
  157. package/src/api/OpenWalletSession.ts +70 -17
  158. package/src/api/SearchDevices.ts +3 -1
  159. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  160. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +34 -11
  161. package/src/api/device/DeviceUnlock.ts +8 -3
  162. package/src/api/device/DeviceUpdateBootloader.ts +6 -122
  163. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -83
  164. package/src/api/firmware/updateBootloader.ts +4 -19
  165. package/src/api/firmware/uploadFirmware.ts +39 -144
  166. package/src/api/helpers/protocolV2FileWrite.ts +27 -7
  167. package/src/api/index.ts +2 -0
  168. package/src/api/kaspa/KaspaSignTransaction.ts +1 -12
  169. package/src/api/protocol-v2/DeviceUploadNft.ts +189 -0
  170. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  171. package/src/api/protocol-v2/helpers.ts +1 -0
  172. package/src/core/deviceEventRegistration.ts +4 -0
  173. package/src/core/index.ts +167 -83
  174. package/src/core/uiPromiseRegistry.ts +41 -0
  175. package/src/data/messages/messages-protocol-v2.json +25 -0
  176. package/src/data-manager/DataManager.ts +71 -39
  177. package/src/data-manager/connectSettings.ts +0 -11
  178. package/src/device/Device.ts +259 -43
  179. package/src/device/DeviceCommands.ts +7 -1
  180. package/src/device/DevicePool.ts +7 -2
  181. package/src/events/device.ts +4 -0
  182. package/src/events/logBlockEvent.ts +1 -0
  183. package/src/events/ui-promise.ts +4 -2
  184. package/src/events/ui-request.ts +36 -2
  185. package/src/events/ui-response.ts +12 -2
  186. package/src/index.ts +0 -5
  187. package/src/inject.ts +60 -24
  188. package/src/lowLevelInject.ts +7 -8
  189. package/src/protocols/protocol-v2/features.ts +10 -7
  190. package/src/protocols/protocol-v2/firmware.ts +2 -0
  191. package/src/protocols/protocol-v2/resources.ts +359 -0
  192. package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
  193. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  194. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +118 -0
  195. package/src/protocols/protocol-v2/walletSession.ts +214 -36
  196. package/src/topLevelInject.ts +7 -8
  197. package/src/types/api/checkAllFirmwareRelease.ts +2 -4
  198. package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
  199. package/src/types/api/deviceUnlock.ts +12 -1
  200. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  201. package/src/types/api/export.ts +1 -18
  202. package/src/types/api/firmwareUpdate.ts +3 -76
  203. package/src/types/api/index.ts +13 -14
  204. package/src/types/api/protocolV2.ts +13 -0
  205. package/src/types/device.ts +3 -0
  206. package/src/types/params.ts +7 -1
  207. package/src/types/settings.ts +42 -13
  208. package/src/utils/deviceFeaturesCompat.ts +0 -6
  209. package/src/utils/deviceFeaturesUtils.ts +8 -0
  210. package/src/utils/homescreen.ts +32 -6
  211. package/src/utils/index.ts +6 -1
  212. package/src/utils/pro2Nft.ts +142 -0
  213. package/src/utils/pro2Wallpaper.ts +35 -8
  214. package/src/utils/uiProgressThrottle.ts +63 -0
  215. package/__tests__/device-initialize-timeout.test.ts +0 -56
  216. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  217. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  218. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  219. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  220. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
  221. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  222. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -294
  223. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  224. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
  225. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
  226. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  227. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  228. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  229. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  230. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  231. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  232. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  233. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  234. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  235. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  236. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  237. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
  238. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  239. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  240. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  241. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  242. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  243. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  244. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  245. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  246. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  247. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  248. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  249. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  250. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  251. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  252. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  253. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  254. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  255. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
  256. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -415
  257. package/src/api/firmware/progressThrottle.ts +0 -44
  258. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  259. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
  260. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  261. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  262. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
@@ -1,4 +1,5 @@
1
1
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
2
3
 
3
4
  import { UI_REQUEST } from '../constants/ui-request';
4
5
  import { refreshProtocolV2DeviceStatus } from '../protocols/protocol-v2/walletSession';
@@ -24,7 +25,12 @@ export default class GetPassphraseState extends BaseMethod {
24
25
  if (isProtocolV2 && this.payload.useEmptyPassphrase !== true) {
25
26
  const features = await refreshProtocolV2DeviceStatus(this.device);
26
27
  if (features.unlocked === false) {
27
- await this.device.unlockDevice();
28
+ await this.device.unlockDevice(DeviceSessionPinType.Main, {
29
+ source: 'unlock-coordinator',
30
+ reason: 'device-locked',
31
+ deviceOnly: true,
32
+ method: 'getPassphraseState',
33
+ });
28
34
  }
29
35
  }
30
36
  const { passphraseState } = await getPassphraseStateWithRefreshDeviceInfo(
@@ -1,4 +1,5 @@
1
1
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
2
3
 
3
4
  import { deviceWalletSessionStore } from '../device/DeviceWalletSessionStore';
4
5
  import { getProtocolV2WalletSession } from '../protocols/protocol-v2/walletSession';
@@ -90,23 +91,40 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
90
91
 
91
92
  async run(): Promise<OpenWalletSessionPayload> {
92
93
  const isProtocolV2 = this.device.isProtocolV2();
93
- const state = await this.device.getDeviceState({ refreshSections: ['status'] });
94
+ let state = await this.device.getDeviceState({ refreshSections: ['status'] });
94
95
  let currentDeviceId = state.identity.deviceId;
96
+ const hasAuthoritativeProtocolV2WalletStatus = (candidate: typeof state) =>
97
+ candidate.status.unlocked === true &&
98
+ typeof candidate.status.passphraseProtection === 'boolean' &&
99
+ typeof candidate.status.unlockedAttachPin === 'boolean';
100
+ const requireAuthoritativeProtocolV2WalletStatus = (candidate: typeof state) => {
101
+ if (!hasAuthoritativeProtocolV2WalletStatus(candidate)) {
102
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed);
103
+ }
104
+ return candidate;
105
+ };
95
106
  const requireDeviceId = () => {
96
107
  if (!currentDeviceId) {
97
108
  throw ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed);
98
109
  }
99
110
  return currentDeviceId;
100
111
  };
101
- const refreshProtocolV2DeviceId = async () => {
102
- const refreshedState = await this.device.getDeviceState({ refreshSections: ['status'] });
103
- currentDeviceId = refreshedState.identity.deviceId;
104
- return requireDeviceId();
112
+ const refreshProtocolV2DeviceState = async () => {
113
+ state = await this.device.getDeviceState({ refreshSections: ['status'] });
114
+ currentDeviceId = state.identity.deviceId;
115
+ return state;
105
116
  };
106
- const unlockProtocolV2IfLocked = async () => {
107
- if (isProtocolV2 && state.status.unlocked === false) {
108
- await this.device.unlockDevice();
117
+ const ensureProtocolV2WalletStatus = async () => {
118
+ if (isProtocolV2 && !hasAuthoritativeProtocolV2WalletStatus(state)) {
119
+ await this.device.unlockDevice(DeviceSessionPinType.Main, {
120
+ source: 'unlock-coordinator',
121
+ reason: 'device-locked',
122
+ deviceOnly: true,
123
+ method: 'openWalletSession',
124
+ });
125
+ requireAuthoritativeProtocolV2WalletStatus(await refreshProtocolV2DeviceState());
109
126
  }
127
+ return state;
110
128
  };
111
129
 
112
130
  const protocol = isProtocolV2 ? 'V2' : 'V1';
@@ -114,13 +132,25 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
114
132
  if (this.params.mode === OpenWalletSessionMode.Standard) {
115
133
  this.device.passphraseState = undefined;
116
134
  const session = isProtocolV2
117
- ? await getProtocolV2WalletSession(this.device, { onlyMainPin: true })
135
+ ? await getProtocolV2WalletSession(this.device, {
136
+ onlyMainPin: true,
137
+ deriveCardano: this.payload.deriveCardano,
138
+ selectMainWalletBeforeRestore:
139
+ !hasAuthoritativeProtocolV2WalletStatus(state) ||
140
+ state.status.unlockedAttachPin === true,
141
+ })
118
142
  : await getPassphraseStateWithRefreshDeviceInfo(this.device, {
119
143
  onlyMainPin: true,
120
144
  initSession: this.payload.initSession,
121
145
  });
122
- const deviceId = isProtocolV2 ? await refreshProtocolV2DeviceId() : requireDeviceId();
123
- if (session.unlockedAttachPin) {
146
+ const refreshedState = isProtocolV2
147
+ ? requireAuthoritativeProtocolV2WalletStatus(await refreshProtocolV2DeviceState())
148
+ : state;
149
+ const deviceId = requireDeviceId();
150
+ if (
151
+ session.unlockedAttachPin ||
152
+ (isProtocolV2 && refreshedState.status.unlockedAttachPin === true)
153
+ ) {
124
154
  try {
125
155
  await this.device.lockDevice();
126
156
  } catch {
@@ -140,8 +170,8 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
140
170
 
141
171
  if (this.params.mode === OpenWalletSessionMode.ResumeHidden) {
142
172
  if (isProtocolV2) {
143
- await unlockProtocolV2IfLocked();
144
- const refreshedDeviceId = await refreshProtocolV2DeviceId();
173
+ await ensureProtocolV2WalletStatus();
174
+ const refreshedDeviceId = requireDeviceId();
145
175
  if (refreshedDeviceId !== this.params.deviceId) {
146
176
  deviceWalletSessionStore.delete(this.params.deviceId, this.params.passphraseState);
147
177
  throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
@@ -166,6 +196,7 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
166
196
  const session = isProtocolV2
167
197
  ? await getProtocolV2WalletSession(this.device, {
168
198
  expectedPassphraseState: this.params.passphraseState,
199
+ deriveCardano: this.payload.deriveCardano,
169
200
  })
170
201
  : await getPassphraseStateWithRefreshDeviceInfo(this.device, {
171
202
  expectPassphraseState: this.params.passphraseState,
@@ -185,15 +216,37 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
185
216
  }
186
217
 
187
218
  this.device.passphraseState = undefined;
188
- await unlockProtocolV2IfLocked();
219
+ const walletStatus = await ensureProtocolV2WalletStatus();
220
+ if (isProtocolV2 && walletStatus.status.passphraseProtection !== true) {
221
+ this.device.clearInternalState();
222
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase);
223
+ }
224
+ const readCurrentAttachPinSession =
225
+ isProtocolV2 && walletStatus.status.unlockedAttachPin === true;
189
226
  const session = isProtocolV2
190
- ? await getProtocolV2WalletSession(this.device, { forceWalletSelection: true })
227
+ ? await getProtocolV2WalletSession(this.device, {
228
+ ...(readCurrentAttachPinSession
229
+ ? { readCurrentAttachPinSession: true }
230
+ : { forceWalletSelection: true }),
231
+ deriveCardano: this.payload.deriveCardano,
232
+ })
191
233
  : await getPassphraseStateWithRefreshDeviceInfo(this.device, { initSession: true });
192
- const deviceId = isProtocolV2 ? await refreshProtocolV2DeviceId() : requireDeviceId();
193
- if (isProtocolV2 && this.device.getCurrentPassphraseProtection() !== true) {
234
+ const refreshedState = isProtocolV2
235
+ ? requireAuthoritativeProtocolV2WalletStatus(await refreshProtocolV2DeviceState())
236
+ : state;
237
+ const deviceId = requireDeviceId();
238
+ if (isProtocolV2 && refreshedState.status.passphraseProtection !== true) {
194
239
  this.device.clearInternalState();
195
240
  throw ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase);
196
241
  }
242
+ if (
243
+ isProtocolV2 &&
244
+ readCurrentAttachPinSession &&
245
+ refreshedState.status.unlockedAttachPin !== true
246
+ ) {
247
+ this.device.clearInternalState();
248
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError);
249
+ }
197
250
  const responseBase = {
198
251
  protocol,
199
252
  deviceId,
@@ -59,7 +59,9 @@ export default class SearchDevices extends BaseMethod {
59
59
  // Discovery is best effort. Browsers may retain WebUSB grants for devices that
60
60
  // are offline, busy, or not ready, so one descriptor must not abort the scan.
61
61
  const result = await DevicePool.getDevices([descriptor], descriptor.path, {
62
- connectProtocol: this.payload.connectProtocol,
62
+ // Discovery must actively identify the protocol instead of trusting a caller hint.
63
+ connectProtocol: undefined,
64
+ forceProtocolDetection: true,
63
65
  refreshRuntimeState: true,
64
66
  });
65
67
  deviceList.push(...result.deviceList);
@@ -24,24 +24,28 @@ export default class AllNetworkGetAddress extends AllNetworkGetAddressBase {
24
24
  const resultMap: Record<string, AllNetworkAddress> = {};
25
25
  const { bundle } = this.payload as AllNetworkGetAddressParams;
26
26
 
27
- const methodGroups = bundle
28
- .map((param, index) =>
29
- this.generateMethodName({
30
- network: param.network,
31
- payload: param,
32
- originalIndex: index,
33
- })
34
- )
35
- .reduce((acc, cur) => {
36
- if (!acc[cur.methodName]) {
37
- acc[cur.methodName] = [];
38
- }
39
- acc[cur.methodName].push(cur);
40
- return acc;
41
- }, {} as Record<keyof CoreApi, MethodParams[]>);
27
+ const methodParams = bundle.map((param, index) =>
28
+ this.generateMethodName({
29
+ network: param.network,
30
+ payload: param,
31
+ originalIndex: index,
32
+ })
33
+ );
34
+ const groupedMethodParams = methodParams.reduce((groups, param) => {
35
+ const group = groups.get(param.methodName) ?? [];
36
+ group.push(param);
37
+ groups.set(param.methodName, group);
38
+ return groups;
39
+ }, new Map<keyof CoreApi, MethodParams[]>());
40
+ const requiresProtocolV2WalletHandoff =
41
+ this.device.isProtocolV2() &&
42
+ (this.payload.useEmptyPassphrase === true || !!this.payload.passphraseState);
43
+ const methodGroups: [keyof CoreApi, MethodParams[]][] = requiresProtocolV2WalletHandoff
44
+ ? methodParams.map(param => [param.methodName, [param]])
45
+ : Array.from(groupedMethodParams.entries());
42
46
 
43
47
  let i = 0;
44
- for (const [methodName, params] of Object.entries(methodGroups)) {
48
+ for (const [methodName, params] of methodGroups) {
45
49
  const methodParams = {
46
50
  bundle: params.map(param => ({
47
51
  ...param.params,
@@ -52,11 +56,7 @@ export default class AllNetworkGetAddress extends AllNetworkGetAddressBase {
52
56
  throw new Error(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
53
57
  }
54
58
  // call method
55
- const response = await this.callMethod(
56
- methodName as keyof CoreApi,
57
- methodParams,
58
- rootFingerprint
59
- );
59
+ const response = await this.callMethod(methodName, methodParams, rootFingerprint);
60
60
 
61
61
  if (this.abortController?.signal.aborted) {
62
62
  throw new Error(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
@@ -14,6 +14,7 @@ import { findMethod } from '../utils';
14
14
  import { DEVICE, IFRAME, createUiMessage } from '../../events';
15
15
  import { UI_REQUEST } from '../../constants/ui-request';
16
16
  import { onDeviceButtonHandler } from '../../core';
17
+ import { runMethodWithUnlockPolicy } from '../../protocols/protocol-v2/unlockPolicyRunner';
17
18
  import {
18
19
  completeRequestContext,
19
20
  createRequestContext,
@@ -375,16 +376,36 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
375
376
  this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
376
377
 
377
378
  preCheckDeviceSupport(this.device, method);
378
- if (this.temporarySafetyCheckPrompted) {
379
- method.temporarySafetyCheckPrompted = true;
380
- } else {
381
- const appliedTemporarySafetyCheck = await method.checkSafetyLevelOnTestNet();
382
- if (appliedTemporarySafetyCheck) {
383
- this.temporarySafetyCheckPrompted = true;
384
- }
385
- }
386
-
387
- const response = await method.run();
379
+ const response = await runMethodWithUnlockPolicy<any[]>(method, this.device, {
380
+ context: this.protocolV2UnlockContext,
381
+ prepare: async () => {
382
+ if (this.temporarySafetyCheckPrompted) {
383
+ method.temporarySafetyCheckPrompted = true;
384
+ } else {
385
+ const appliedTemporarySafetyCheck = await method.checkSafetyLevelOnTestNet();
386
+ if (appliedTemporarySafetyCheck) {
387
+ this.temporarySafetyCheckPrompted = true;
388
+ }
389
+ }
390
+
391
+ // Protocol V2 hands a wallet session to exactly one blockchain request.
392
+ // The parent all-network call consumes its first handoff while fetching
393
+ // the root fingerprint, so each nested chain method must resume the
394
+ // requested standard or hidden wallet before sending its device command.
395
+ const useEmptyPassphrase = this.payload.useEmptyPassphrase === true;
396
+ const shouldResumeWalletSession = useEmptyPassphrase || !!this.payload.passphraseState;
397
+ if (this.device.isProtocolV2() && shouldResumeWalletSession) {
398
+ const passphraseStateSafety = await this.device.checkPassphraseStateSafety(
399
+ this.payload.passphraseState,
400
+ useEmptyPassphrase,
401
+ this.payload.skipPassphraseCheck
402
+ );
403
+ if (!passphraseStateSafety) {
404
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
405
+ }
406
+ }
407
+ },
408
+ });
388
409
 
389
410
  if (!Array.isArray(response) || response.length === 0) {
390
411
  throw new Error('No response');
@@ -439,7 +460,9 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
439
460
  show_display: false,
440
461
  });
441
462
 
442
- this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
463
+ if (!this.device.isProtocolV2()) {
464
+ this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
465
+ }
443
466
 
444
467
  if (res.message.root_fingerprint == null) {
445
468
  throw ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter);
@@ -1,13 +1,18 @@
1
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
2
+
1
3
  import { BaseMethod } from '../BaseMethod';
2
4
 
3
- import type { LockDevice } from '@onekeyfe/hd-transport';
5
+ import type { DeviceUnlockParams } from '../../types/api/deviceUnlock';
4
6
 
5
- export default class DeviceUnlock extends BaseMethod<LockDevice> {
7
+ export default class DeviceUnlock extends BaseMethod<DeviceUnlockParams> {
6
8
  getSupportedProtocols() {
7
9
  return ['V1', 'V2'] as const;
8
10
  }
9
11
 
10
12
  init() {
13
+ this.params = {
14
+ pinType: this.payload.pinType ?? DeviceSessionPinType.Main,
15
+ };
11
16
  this.useDevicePassphraseState = false;
12
17
  this.unlockPolicy = 'none';
13
18
  this.protocolV2UiInteraction = {
@@ -21,6 +26,6 @@ export default class DeviceUnlock extends BaseMethod<LockDevice> {
21
26
  }
22
27
 
23
28
  async run() {
24
- return this.device.unlockDevice();
29
+ return this.device.unlockDevice(this.params.pinType, { emitUiEvent: false });
25
30
  }
26
31
  }
@@ -5,23 +5,15 @@ import { UI_REQUEST } from '../../constants/ui-request';
5
5
  import { FirmwareUpdateTipMessage } from '../../events/ui-request';
6
6
  import { FirmwareUpdateBaseMethod } from '../firmware/FirmwareUpdateBaseMethod';
7
7
  import { getSysResourceBinary } from '../firmware/getBinary';
8
- import { updateBootloader, updateBootloaderFromSource } from '../firmware/uploadFirmware';
8
+ import { updateBootloader } from '../firmware/uploadFirmware';
9
9
  import { DeviceModelToTypes } from '../../types';
10
10
  import { DataManager } from '../../data-manager';
11
- import { checkBootloaderLength, checkBootloaderSourceLength } from '../firmware/updateBootloader';
12
- import { openFirmwareByteSource } from '../firmware/FirmwareArtifactSource';
13
- import { resolveFirmwareUpdateHostBinding } from '../firmware/FirmwareHostBinding';
14
- import {
15
- assertFirmwareUpdatePreparedPlanBinding,
16
- assertFirmwareUpdatePreparedPlanDeviceIdentity,
17
- } from '../firmware/FirmwareUpdatePreparedPlan';
18
- import { getDeviceUUID } from '../../utils';
11
+ import { checkBootloaderLength } from '../firmware/updateBootloader';
19
12
 
20
13
  import type { DeviceUpdateBootloaderParams } from '../../types/api/deviceUpdateBootloader';
21
14
  import type { EFirmwareType } from '@onekeyfe/hd-shared';
22
15
  import type { Device } from '../../device/Device';
23
16
  import type { Features } from '../../types';
24
- import type { FirmwareByteSource } from '../firmware/FirmwareArtifactSource';
25
17
 
26
18
  export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any> {
27
19
  init() {
@@ -51,68 +43,17 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
51
43
  return true;
52
44
  }
53
45
 
54
- async updateBootloaderWithEmmcFileWriteFromSource(_device: Device, source: FirmwareByteSource) {
55
- const filePath = '0:boot/bootloader.bin';
56
-
57
- this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
58
- await this.emmcCommonUpdateProcessFromSource({
59
- source,
60
- filePath,
61
- });
62
- this.postTipMessage(FirmwareUpdateTipMessage.ConfirmOnDevice);
63
- await this.reboot(RebootType.Normal);
64
- this.postTipMessage(FirmwareUpdateTipMessage.UpdateBootloaderSuccess);
65
- return true;
66
- }
67
-
68
46
  async updateTouchBootloader({
69
47
  device,
70
48
  features,
71
49
  firmwareType,
72
- binary: preparedBinary,
73
- source: preparedSource,
74
50
  }: {
75
51
  device: Device;
76
52
  features?: Features;
77
53
  firmwareType: EFirmwareType;
78
- binary?: ArrayBuffer;
79
- source?: FirmwareByteSource;
80
54
  }) {
81
- if (preparedSource) {
82
- if (!(await checkBootloaderSourceLength(preparedSource))) {
83
- throw ERRORS.TypedError(HardwareErrorCode.CheckDownloadFileError);
84
- }
85
- if (features && device.isBootloader()) {
86
- this.postTipMessage(FirmwareUpdateTipMessage.UpdateBootloader);
87
- const result = await this.updateBootloaderWithEmmcFileWriteFromSource(
88
- device,
89
- preparedSource
90
- );
91
- return result;
92
- }
93
- if (features && !device.isBootloader()) {
94
- await updateBootloaderFromSource(
95
- this.device.getCommands().typedCall.bind(this.device.getCommands()),
96
- this.postMessage,
97
- device,
98
- preparedSource
99
- );
100
- return true;
101
- }
102
- }
103
-
104
- let binary = preparedBinary;
55
+ let { binary } = this.payload;
105
56
  if (!binary) {
106
- if (DataManager.getSettings('firmwareManifestMode') === 'external-only') {
107
- throw ERRORS.TypedError(
108
- HardwareErrorCode.RuntimeError,
109
- 'Bootloader must be prepared by the external firmware host',
110
- {
111
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
112
- artifactName: 'bootloader',
113
- }
114
- );
115
- }
116
57
  this.postTipMessage(FirmwareUpdateTipMessage.CheckLatestUiResource);
117
58
  const resourceUrl = features
118
59
  ? DataManager.getBootloaderResource(features, firmwareType)
@@ -127,7 +68,7 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
127
68
  }
128
69
  }
129
70
 
130
- if (!binary || !checkBootloaderLength(binary)) {
71
+ if (!checkBootloaderLength(binary)) {
131
72
  throw ERRORS.TypedError(HardwareErrorCode.CheckDownloadFileError);
132
73
  }
133
74
 
@@ -135,8 +76,7 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
135
76
  if (features && device.isBootloader()) {
136
77
  // Use emmcFileWrite + reboot logic for bootloader mode
137
78
  this.postTipMessage(FirmwareUpdateTipMessage.UpdateBootloader);
138
- const result = await this.updateBootloaderWithEmmcFileWrite(device, binary);
139
- return result;
79
+ return this.updateBootloaderWithEmmcFileWrite(device, binary);
140
80
  }
141
81
 
142
82
  if (features && !device.isBootloader()) {
@@ -156,69 +96,13 @@ export default class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod<any
156
96
  const { features } = device;
157
97
 
158
98
  const payload = this.payload as DeviceUpdateBootloaderParams;
159
- const hostBinding = payload.artifact
160
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
161
- : undefined;
162
- const executionParams = {
163
- ...payload,
164
- artifactReader: hostBinding?.artifactReader ?? payload.artifactReader,
165
- };
166
- if (payload.artifact) {
167
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
168
- preparedPlan: payload.preparedPlan,
169
- deviceIdentity: getDeviceUUID(features) || undefined,
170
- });
171
- assertFirmwareUpdatePreparedPlanBinding({
172
- preparedPlan: payload.preparedPlan,
173
- executor: 'v2',
174
- scopeTargets: ['bootloader'],
175
- bindings: [
176
- {
177
- target: 'bootloader',
178
- artifact: payload.artifact,
179
- },
180
- ],
181
- });
182
- const source = await openFirmwareByteSource({
183
- artifact: payload.artifact,
184
- reader: executionParams.artifactReader,
185
- });
186
- if (!source) {
187
- throw ERRORS.TypedError(
188
- HardwareErrorCode.RuntimeError,
189
- 'Bootloader artifact is not prepared'
190
- );
191
- }
192
- try {
193
- const deviceType = device.getCurrentDeviceType();
194
- const deviceFirmwareType = device.getCurrentFirmwareType();
195
- const firmwareType = payload.firmwareType ?? deviceFirmwareType;
196
- if (DeviceModelToTypes.model_touch.includes(deviceType)) {
197
- return await this.updateTouchBootloader({
198
- device,
199
- features,
200
- firmwareType,
201
- source,
202
- });
203
- }
204
- return true;
205
- } finally {
206
- await source.close();
207
- }
208
- }
209
99
 
210
- const { binary } = payload;
211
100
  const deviceType = device.getCurrentDeviceType();
212
101
  const deviceFirmwareType = device.getCurrentFirmwareType();
213
102
  const firmwareType = payload.firmwareType ?? deviceFirmwareType;
214
103
 
215
104
  if (DeviceModelToTypes.model_touch.includes(deviceType)) {
216
- return this.updateTouchBootloader({
217
- device,
218
- features,
219
- firmwareType,
220
- binary,
221
- });
105
+ return this.updateTouchBootloader({ device, features, firmwareType });
222
106
  }
223
107
 
224
108
  return Promise.resolve(true);