@onekeyfe/hd-core 1.2.0-alpha.41 → 1.2.0-alpha.42

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 (200) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +78 -0
  2. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  3. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +14 -1
  4. package/__tests__/connectSettings.test.ts +5 -47
  5. package/__tests__/deviceUploadNft.test.ts +187 -0
  6. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  7. package/__tests__/get-device-state.test.ts +132 -12
  8. package/__tests__/homescreen.test.ts +41 -1
  9. package/__tests__/logBlockEvent.test.ts +1 -1
  10. package/__tests__/open-wallet-session.test.ts +259 -18
  11. package/__tests__/pro2Nft.test.ts +108 -0
  12. package/__tests__/protocol-v2-resources.test.ts +204 -0
  13. package/__tests__/protocol-v2-ui-lifecycle.test.ts +56 -0
  14. package/__tests__/protocol-v2-unlock-policy.test.ts +86 -35
  15. package/__tests__/protocol-v2.test.ts +526 -955
  16. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  17. package/__tests__/uiProgressThrottle.test.ts +74 -0
  18. package/dist/api/BaseMethod.d.ts +3 -1
  19. package/dist/api/BaseMethod.d.ts.map +1 -1
  20. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  21. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  22. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  23. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  24. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  25. package/dist/api/FirmwareUpdateV4.d.ts +6 -25
  26. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  27. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  28. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  29. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  30. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  31. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  32. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -8
  33. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  34. package/dist/api/firmware/getBinary.d.ts +0 -7
  35. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  36. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  37. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  38. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  39. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  40. package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
  41. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  42. package/dist/api/index.d.ts +1 -0
  43. package/dist/api/index.d.ts.map +1 -1
  44. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
  45. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  46. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  47. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  48. package/dist/core/deviceEventRegistration.d.ts +2 -0
  49. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  50. package/dist/core/index.d.ts.map +1 -1
  51. package/dist/data-manager/DataManager.d.ts +3 -2
  52. package/dist/data-manager/DataManager.d.ts.map +1 -1
  53. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  54. package/dist/device/Device.d.ts +22 -4
  55. package/dist/device/Device.d.ts.map +1 -1
  56. package/dist/events/device.d.ts +4 -0
  57. package/dist/events/device.d.ts.map +1 -1
  58. package/dist/events/logBlockEvent.d.ts.map +1 -1
  59. package/dist/events/ui-request.d.ts +27 -2
  60. package/dist/events/ui-request.d.ts.map +1 -1
  61. package/dist/index.d.ts +110 -182
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +1919 -3336
  64. package/dist/inject.d.ts.map +1 -1
  65. package/dist/lowLevelInject.d.ts.map +1 -1
  66. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  67. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  68. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  69. package/dist/protocols/protocol-v2/uiInteraction.d.ts +3 -3
  70. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  71. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  72. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  73. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  74. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  75. package/dist/protocols/protocol-v2/walletSession.d.ts +4 -1
  76. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  77. package/dist/topLevelInject.d.ts.map +1 -1
  78. package/dist/types/api/checkAllFirmwareRelease.d.ts +1 -4
  79. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  80. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  81. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  82. package/dist/types/api/export.d.ts +1 -4
  83. package/dist/types/api/export.d.ts.map +1 -1
  84. package/dist/types/api/firmwareUpdate.d.ts +0 -69
  85. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  86. package/dist/types/api/index.d.ts +3 -10
  87. package/dist/types/api/index.d.ts.map +1 -1
  88. package/dist/types/api/protocolV2.d.ts +3 -0
  89. package/dist/types/api/protocolV2.d.ts.map +1 -1
  90. package/dist/types/settings.d.ts +12 -13
  91. package/dist/types/settings.d.ts.map +1 -1
  92. package/dist/utils/deviceFeaturesUtils.d.ts +2 -0
  93. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  94. package/dist/utils/homescreen.d.ts +4 -0
  95. package/dist/utils/homescreen.d.ts.map +1 -1
  96. package/dist/utils/index.d.ts +1 -1
  97. package/dist/utils/index.d.ts.map +1 -1
  98. package/dist/utils/patch.d.ts +1 -1
  99. package/dist/utils/patch.d.ts.map +1 -1
  100. package/dist/utils/pro2Nft.d.ts +29 -0
  101. package/dist/utils/pro2Nft.d.ts.map +1 -0
  102. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  103. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  104. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  105. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  106. package/package.json +4 -4
  107. package/src/api/BaseMethod.ts +8 -10
  108. package/src/api/CheckAllFirmwareRelease.ts +40 -53
  109. package/src/api/FirmwareUpdateV2.ts +120 -298
  110. package/src/api/FirmwareUpdateV3.ts +57 -263
  111. package/src/api/FirmwareUpdateV4.ts +307 -912
  112. package/src/api/GetPassphraseState.ts +7 -1
  113. package/src/api/OpenWalletSession.ts +54 -17
  114. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +32 -11
  115. package/src/api/device/DeviceUnlock.ts +1 -1
  116. package/src/api/device/DeviceUpdateBootloader.ts +6 -122
  117. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +0 -57
  118. package/src/api/firmware/updateBootloader.ts +4 -19
  119. package/src/api/firmware/uploadFirmware.ts +22 -140
  120. package/src/api/helpers/protocolV2FileWrite.ts +11 -4
  121. package/src/api/index.ts +1 -0
  122. package/src/api/protocol-v2/DeviceUploadNft.ts +166 -0
  123. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  124. package/src/core/deviceEventRegistration.ts +4 -0
  125. package/src/core/index.ts +118 -75
  126. package/src/data/messages/messages-protocol-v2.json +53 -0
  127. package/src/data-manager/DataManager.ts +63 -38
  128. package/src/data-manager/connectSettings.ts +0 -11
  129. package/src/device/Device.ts +193 -21
  130. package/src/events/device.ts +4 -0
  131. package/src/events/logBlockEvent.ts +1 -0
  132. package/src/events/ui-request.ts +32 -2
  133. package/src/index.ts +0 -5
  134. package/src/inject.ts +3 -22
  135. package/src/lowLevelInject.ts +1 -5
  136. package/src/protocols/protocol-v2/features.ts +9 -2
  137. package/src/protocols/protocol-v2/resources.ts +233 -0
  138. package/src/protocols/protocol-v2/uiInteraction.ts +31 -5
  139. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  140. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +117 -0
  141. package/src/protocols/protocol-v2/walletSession.ts +93 -18
  142. package/src/topLevelInject.ts +1 -5
  143. package/src/types/api/checkAllFirmwareRelease.ts +1 -4
  144. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  145. package/src/types/api/export.ts +0 -18
  146. package/src/types/api/firmwareUpdate.ts +0 -76
  147. package/src/types/api/index.ts +2 -14
  148. package/src/types/api/protocolV2.ts +13 -0
  149. package/src/types/settings.ts +26 -13
  150. package/src/utils/deviceFeaturesUtils.ts +4 -0
  151. package/src/utils/homescreen.ts +32 -6
  152. package/src/utils/index.ts +6 -1
  153. package/src/utils/pro2Nft.ts +91 -0
  154. package/src/utils/pro2Wallpaper.ts +35 -8
  155. package/src/utils/uiProgressThrottle.ts +63 -0
  156. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  157. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  158. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  159. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  160. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  161. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  162. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
  163. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
  164. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  165. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  166. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  167. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  168. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  169. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  170. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  171. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  172. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  173. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  174. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  175. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -30
  176. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  177. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  178. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  179. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  180. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  181. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  182. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  183. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  184. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  185. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  186. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  187. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  188. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  189. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  190. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  191. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  192. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  193. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -745
  194. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -392
  195. package/src/api/firmware/progressThrottle.ts +0 -44
  196. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  197. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
  198. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  199. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  200. 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,12 +216,18 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
185
216
  }
186
217
 
187
218
  this.device.passphraseState = undefined;
188
- await unlockProtocolV2IfLocked();
219
+ await ensureProtocolV2WalletStatus();
189
220
  const session = isProtocolV2
190
- ? await getProtocolV2WalletSession(this.device, { forceWalletSelection: true })
221
+ ? await getProtocolV2WalletSession(this.device, {
222
+ forceWalletSelection: true,
223
+ deriveCardano: this.payload.deriveCardano,
224
+ })
191
225
  : await getPassphraseStateWithRefreshDeviceInfo(this.device, { initSession: true });
192
- const deviceId = isProtocolV2 ? await refreshProtocolV2DeviceId() : requireDeviceId();
193
- if (isProtocolV2 && this.device.getCurrentPassphraseProtection() !== true) {
226
+ const refreshedState = isProtocolV2
227
+ ? requireAuthoritativeProtocolV2WalletStatus(await refreshProtocolV2DeviceState())
228
+ : state;
229
+ const deviceId = requireDeviceId();
230
+ if (isProtocolV2 && refreshedState.status.passphraseProtection !== true) {
194
231
  this.device.clearInternalState();
195
232
  throw ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase);
196
233
  }
@@ -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,34 @@ 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 hidden wallet before it sends its own device command.
395
+ if (this.device.isProtocolV2() && this.payload.passphraseState) {
396
+ const passphraseStateSafety = await this.device.checkPassphraseStateSafety(
397
+ this.payload.passphraseState,
398
+ false,
399
+ this.payload.skipPassphraseCheck
400
+ );
401
+ if (!passphraseStateSafety) {
402
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
403
+ }
404
+ }
405
+ },
406
+ });
388
407
 
389
408
  if (!Array.isArray(response) || response.length === 0) {
390
409
  throw new Error('No response');
@@ -439,7 +458,9 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
439
458
  show_display: false,
440
459
  });
441
460
 
442
- this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
461
+ if (!this.device.isProtocolV2()) {
462
+ this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
463
+ }
443
464
 
444
465
  if (res.message.root_fingerprint == null) {
445
466
  throw ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter);
@@ -21,6 +21,6 @@ export default class DeviceUnlock extends BaseMethod<LockDevice> {
21
21
  }
22
22
 
23
23
  async run() {
24
- return this.device.unlockDevice();
24
+ return this.device.unlockDevice(undefined, { emitUiEvent: false });
25
25
  }
26
26
  }
@@ -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);
@@ -13,8 +13,6 @@ import { DeviceModelToTypes } from '../../types';
13
13
  import { DataManager } from '../../data-manager';
14
14
  import { BaseMethod } from '../BaseMethod';
15
15
  import { DEVICE } from '../../events';
16
- import { createFirmwareProgressThrottle } from './progressThrottle';
17
- import { writeFirmwareByteSource } from './FirmwareArtifactSource';
18
16
 
19
17
  import type {
20
18
  IFirmwareUpdateProgressType,
@@ -25,7 +23,6 @@ import type { RebootType } from '@onekeyfe/hd-transport';
25
23
  import type { Deferred } from '@onekeyfe/hd-shared';
26
24
  import type { KnownDevice } from '../../types';
27
25
  import type { TypedResponseMessage } from '../../device/DeviceCommands';
28
- import type { FirmwareByteSource } from './FirmwareArtifactSource';
29
26
 
30
27
  const Log = getLogger(LoggerNames.Method);
31
28
  const SESSION_ERROR = 'session not found';
@@ -43,8 +40,6 @@ const isDeviceDisconnectedError = (error: unknown) => {
43
40
  export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
44
41
  checkPromise: Deferred<any> | null = null;
45
42
 
46
- private shouldPostFirmwareProgress = createFirmwareProgressThrottle();
47
-
48
43
  init(): void {}
49
44
 
50
45
  run(): Promise<any> {
@@ -88,10 +83,6 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
88
83
  * @param progress Post the percentage of the progress
89
84
  */
90
85
  postProgressMessage = (progress: number, progressType: IFirmwareUpdateProgressType) => {
91
- if (!this.shouldPostFirmwareProgress(progress, progressType)) {
92
- return;
93
- }
94
-
95
86
  this.postMessage(
96
87
  createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
97
88
  device: this.device.toMessageObject() as KnownDevice,
@@ -389,54 +380,6 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
389
380
  return totalSize !== undefined ? (processedSize ?? 0) + payload.byteLength : 0;
390
381
  }
391
382
 
392
- async emmcCommonUpdateProcessFromSource({
393
- source,
394
- filePath,
395
- processedSize,
396
- totalSize,
397
- }: {
398
- source: FirmwareByteSource;
399
- filePath: string;
400
- processedSize?: number;
401
- totalSize?: number;
402
- }) {
403
- if (!filePath.startsWith('0:')) {
404
- throw new Error('filePath must start with 0:');
405
- }
406
- const env = DataManager.getSettings('env');
407
- const chunkSize = 1024 * (DataManager.isBleConnect(env) ? 16 : 128);
408
-
409
- await writeFirmwareByteSource({
410
- source,
411
- chunkSize,
412
- write: async ({ data, sourceOffset, length, first }) => {
413
- const progress =
414
- totalSize !== undefined && processedSize !== undefined
415
- ? Math.min(Math.ceil(((processedSize + sourceOffset + length) / totalSize) * 100), 99)
416
- : Math.min(Math.ceil(((sourceOffset + length) / source.size) * 100), 99);
417
- const writeRes = await this.emmcFileWriteWithRetry(
418
- filePath,
419
- length,
420
- sourceOffset,
421
- data,
422
- first,
423
- progress
424
- );
425
- if (!writeRes) {
426
- throw ERRORS.TypedError(
427
- HardwareErrorCode.EmmcFileWriteFirmwareError,
428
- 'transfer data error'
429
- );
430
- }
431
- const processedBytes = Number(writeRes.message.processed_byte);
432
- this.postProgressMessage(progress, 'transferData');
433
- return Number.isFinite(processedBytes) ? processedBytes : length;
434
- },
435
- });
436
-
437
- return totalSize !== undefined ? (processedSize ?? 0) + source.size : 0;
438
- }
439
-
440
383
  async emmcFileWriteWithRetry(
441
384
  filePath: string,
442
385
  chunkLength: number,
@@ -8,7 +8,6 @@ import { shouldUpdateBootloaderForClassicAndMini } from './bootloaderHelper';
8
8
 
9
9
  import type { Features } from '../../types';
10
10
  import type { EFirmwareType } from '@onekeyfe/hd-shared';
11
- import type { FirmwareByteSource } from './FirmwareArtifactSource';
12
11
 
13
12
  export function checkNeedUpdateBootForTouch(features: Features, firmwareType: EFirmwareType) {
14
13
  const deviceType = getDeviceType(features);
@@ -63,7 +62,8 @@ export function checkNeedUpdateBootForClassicAndMini({
63
62
  }
64
63
 
65
64
  const INIT_DATA_CHUNK_SIZE = 16 * 1024;
66
- const readBootloaderLength = (chunk: Uint8Array) => {
65
+ export function checkBootloaderLength(data: ArrayBuffer) {
66
+ const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE, data.byteLength)));
67
67
  const buffer = ByteBuffer.wrap(chunk, undefined, undefined, true);
68
68
  buffer.LE();
69
69
  // byte 'O', 'K', 'T', 'B'
@@ -77,21 +77,6 @@ const readBootloaderLength = (chunk: Uint8Array) => {
77
77
  buffer.readUint32();
78
78
  // codelen
79
79
  const codelen = buffer.readUint32();
80
- return hdrlen + codelen;
81
- };
82
-
83
- export function checkBootloaderLength(data: ArrayBuffer) {
84
- if (data.byteLength < 16) {
85
- return false;
86
- }
87
- const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE, data.byteLength)));
88
- return readBootloaderLength(chunk) === data.byteLength;
80
+ const bootloaderLength = hdrlen + codelen;
81
+ return bootloaderLength === data.byteLength;
89
82
  }
90
-
91
- export const checkBootloaderSourceLength = async (source: FirmwareByteSource) => {
92
- if (source.size < 16) {
93
- return false;
94
- }
95
- const chunk = new Uint8Array(await source.readAt(0, Math.min(INIT_DATA_CHUNK_SIZE, source.size)));
96
- return readBootloaderLength(chunk) === source.size;
97
- };