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

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 (256) 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__/deviceUploadNft.test.ts +293 -0
  8. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
  9. package/__tests__/get-device-state.test.ts +132 -12
  10. package/__tests__/homescreen.test.ts +41 -1
  11. package/__tests__/kaspaSignTransaction.test.ts +3 -26
  12. package/__tests__/logBlockEvent.test.ts +1 -1
  13. package/__tests__/method-protocol-support.test.ts +19 -0
  14. package/__tests__/open-wallet-session.test.ts +568 -37
  15. package/__tests__/pro2Nft.test.ts +108 -0
  16. package/__tests__/protocol-binding.test.ts +89 -0
  17. package/__tests__/protocol-v2-resources.test.ts +286 -0
  18. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  19. package/__tests__/protocol-v2-unlock-policy.test.ts +201 -35
  20. package/__tests__/protocol-v2.test.ts +1350 -1012
  21. package/__tests__/protocolV2UiInteraction.test.ts +63 -0
  22. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  23. package/__tests__/search-devices.test.ts +12 -3
  24. package/__tests__/uiProgressThrottle.test.ts +74 -0
  25. package/__tests__/uiPromiseRegistry.test.ts +86 -0
  26. package/dist/api/BaseMethod.d.ts +3 -1
  27. package/dist/api/BaseMethod.d.ts.map +1 -1
  28. package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
  29. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  30. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  31. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  32. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  33. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  34. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  35. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  36. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  37. package/dist/api/FirmwareUpdateV4.d.ts +11 -25
  38. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  39. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  40. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  41. package/dist/api/SearchDevices.d.ts.map +1 -1
  42. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  43. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  44. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  45. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  46. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  47. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -9
  48. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  49. package/dist/api/firmware/getBinary.d.ts +0 -7
  50. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  51. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  52. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  53. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  54. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  55. package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
  56. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  57. package/dist/api/index.d.ts +2 -0
  58. package/dist/api/index.d.ts.map +1 -1
  59. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  60. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  61. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  62. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  63. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  64. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  65. package/dist/core/deviceEventRegistration.d.ts +2 -0
  66. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  67. package/dist/core/index.d.ts.map +1 -1
  68. package/dist/core/uiPromiseRegistry.d.ts +4 -0
  69. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  70. package/dist/data-manager/DataManager.d.ts +4 -2
  71. package/dist/data-manager/DataManager.d.ts.map +1 -1
  72. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  73. package/dist/device/Device.d.ts +29 -6
  74. package/dist/device/Device.d.ts.map +1 -1
  75. package/dist/device/DeviceCommands.d.ts +4 -4
  76. package/dist/device/DeviceCommands.d.ts.map +1 -1
  77. package/dist/device/DevicePool.d.ts.map +1 -1
  78. package/dist/events/device.d.ts +4 -0
  79. package/dist/events/device.d.ts.map +1 -1
  80. package/dist/events/logBlockEvent.d.ts.map +1 -1
  81. package/dist/events/ui-promise.d.ts +4 -2
  82. package/dist/events/ui-promise.d.ts.map +1 -1
  83. package/dist/events/ui-request.d.ts +31 -2
  84. package/dist/events/ui-request.d.ts.map +1 -1
  85. package/dist/events/ui-response.d.ts +10 -2
  86. package/dist/events/ui-response.d.ts.map +1 -1
  87. package/dist/index.d.ts +214 -231
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +2616 -3527
  90. package/dist/inject.d.ts +6 -1
  91. package/dist/inject.d.ts.map +1 -1
  92. package/dist/lowLevelInject.d.ts.map +1 -1
  93. package/dist/protocols/protocol-v2/features.d.ts +0 -4
  94. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  95. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  96. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  97. package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
  98. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  99. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  100. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  101. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  102. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  103. package/dist/protocols/protocol-v2/walletSession.d.ts +6 -1
  104. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  105. package/dist/topLevelInject.d.ts.map +1 -1
  106. package/dist/types/api/checkAllFirmwareRelease.d.ts +2 -4
  107. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  108. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  109. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  110. package/dist/types/api/deviceUnlock.d.ts +5 -1
  111. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  112. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  113. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  114. package/dist/types/api/export.d.ts +2 -4
  115. package/dist/types/api/export.d.ts.map +1 -1
  116. package/dist/types/api/firmwareUpdate.d.ts +2 -70
  117. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  118. package/dist/types/api/index.d.ts +7 -10
  119. package/dist/types/api/index.d.ts.map +1 -1
  120. package/dist/types/api/protocolV2.d.ts +3 -0
  121. package/dist/types/api/protocolV2.d.ts.map +1 -1
  122. package/dist/types/device.d.ts.map +1 -1
  123. package/dist/types/params.d.ts +1 -0
  124. package/dist/types/params.d.ts.map +1 -1
  125. package/dist/types/settings.d.ts +22 -13
  126. package/dist/types/settings.d.ts.map +1 -1
  127. package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
  128. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  129. package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
  130. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  131. package/dist/utils/homescreen.d.ts +4 -0
  132. package/dist/utils/homescreen.d.ts.map +1 -1
  133. package/dist/utils/index.d.ts +1 -1
  134. package/dist/utils/index.d.ts.map +1 -1
  135. package/dist/utils/patch.d.ts +1 -1
  136. package/dist/utils/patch.d.ts.map +1 -1
  137. package/dist/utils/pro2Nft.d.ts +31 -0
  138. package/dist/utils/pro2Nft.d.ts.map +1 -0
  139. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  140. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  141. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  142. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  143. package/package.json +4 -4
  144. package/src/api/BaseMethod.ts +8 -10
  145. package/src/api/CheckAllFirmwareRelease.ts +54 -57
  146. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  147. package/src/api/FirmwareUpdate.ts +7 -15
  148. package/src/api/FirmwareUpdateV2.ts +126 -316
  149. package/src/api/FirmwareUpdateV3.ts +63 -265
  150. package/src/api/FirmwareUpdateV4.ts +569 -965
  151. package/src/api/GetPassphraseState.ts +7 -1
  152. package/src/api/OpenWalletSession.ts +70 -17
  153. package/src/api/SearchDevices.ts +3 -1
  154. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  155. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +34 -11
  156. package/src/api/device/DeviceUnlock.ts +8 -3
  157. package/src/api/device/DeviceUpdateBootloader.ts +6 -122
  158. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -83
  159. package/src/api/firmware/updateBootloader.ts +4 -19
  160. package/src/api/firmware/uploadFirmware.ts +39 -144
  161. package/src/api/helpers/protocolV2FileWrite.ts +11 -4
  162. package/src/api/index.ts +2 -0
  163. package/src/api/kaspa/KaspaSignTransaction.ts +1 -12
  164. package/src/api/protocol-v2/DeviceUploadNft.ts +189 -0
  165. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  166. package/src/api/protocol-v2/helpers.ts +1 -0
  167. package/src/core/deviceEventRegistration.ts +4 -0
  168. package/src/core/index.ts +167 -83
  169. package/src/core/uiPromiseRegistry.ts +41 -0
  170. package/src/data/messages/messages-protocol-v2.json +25 -0
  171. package/src/data-manager/DataManager.ts +71 -39
  172. package/src/data-manager/connectSettings.ts +0 -11
  173. package/src/device/Device.ts +259 -43
  174. package/src/device/DeviceCommands.ts +7 -1
  175. package/src/device/DevicePool.ts +7 -2
  176. package/src/events/device.ts +4 -0
  177. package/src/events/logBlockEvent.ts +1 -0
  178. package/src/events/ui-promise.ts +4 -2
  179. package/src/events/ui-request.ts +36 -2
  180. package/src/events/ui-response.ts +12 -2
  181. package/src/index.ts +0 -5
  182. package/src/inject.ts +60 -24
  183. package/src/lowLevelInject.ts +7 -8
  184. package/src/protocols/protocol-v2/features.ts +10 -7
  185. package/src/protocols/protocol-v2/resources.ts +359 -0
  186. package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
  187. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  188. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +118 -0
  189. package/src/protocols/protocol-v2/walletSession.ts +214 -36
  190. package/src/topLevelInject.ts +7 -8
  191. package/src/types/api/checkAllFirmwareRelease.ts +2 -4
  192. package/src/types/api/detectDeviceConnectProtocol.ts +7 -0
  193. package/src/types/api/deviceUnlock.ts +12 -1
  194. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  195. package/src/types/api/export.ts +1 -18
  196. package/src/types/api/firmwareUpdate.ts +3 -76
  197. package/src/types/api/index.ts +13 -14
  198. package/src/types/api/protocolV2.ts +13 -0
  199. package/src/types/device.ts +3 -0
  200. package/src/types/params.ts +7 -1
  201. package/src/types/settings.ts +42 -13
  202. package/src/utils/deviceFeaturesCompat.ts +0 -6
  203. package/src/utils/deviceFeaturesUtils.ts +8 -0
  204. package/src/utils/homescreen.ts +32 -6
  205. package/src/utils/index.ts +6 -1
  206. package/src/utils/pro2Nft.ts +142 -0
  207. package/src/utils/pro2Wallpaper.ts +35 -8
  208. package/src/utils/uiProgressThrottle.ts +63 -0
  209. package/__tests__/device-initialize-timeout.test.ts +0 -56
  210. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
  211. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  212. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  213. package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
  214. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
  215. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  216. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -294
  217. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
  218. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
  219. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
  220. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  221. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  222. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  223. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  224. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  225. package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
  226. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
  227. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  228. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  229. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
  230. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  231. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
  232. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  233. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  234. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  235. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  236. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  237. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  238. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  239. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  240. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  241. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
  242. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  243. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  244. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  245. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  246. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  247. package/src/api/firmware/FirmwarePreparationError.ts +0 -12
  248. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  249. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
  250. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -415
  251. package/src/api/firmware/progressThrottle.ts +0 -44
  252. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  253. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
  254. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  255. package/src/types/api/firmwareUpdatePlan.ts +0 -38
  256. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
@@ -1,4 +1,4 @@
1
- import { HardwareErrorCode } from '@onekeyfe/hd-shared';
1
+ import { EDeviceType, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
2
  import { DeviceType } from '@onekeyfe/hd-transport';
3
3
 
4
4
  import { Device } from '../src/device/Device';
@@ -43,6 +43,70 @@ const getProtocolV2LoaderInfo = (mode: 'bootloader' | 'romloader') => ({
43
43
  });
44
44
 
45
45
  describe('getDeviceState', () => {
46
+ test('coalesces concurrent Protocol V2 runtime-context negotiation', async () => {
47
+ let resolveProtocolInfo:
48
+ | ((value: { message: typeof protocolV2ApplicationInfo }) => void)
49
+ | undefined;
50
+ const typedCall = jest.fn(
51
+ () =>
52
+ new Promise<{ message: typeof protocolV2ApplicationInfo }>(resolve => {
53
+ resolveProtocolInfo = resolve;
54
+ })
55
+ );
56
+ const device = createV2Device(typedCall);
57
+
58
+ const first = device.ensureProtocolV2RuntimeContext();
59
+ const second = device.ensureProtocolV2RuntimeContext();
60
+ resolveProtocolInfo?.({ message: protocolV2ApplicationInfo });
61
+
62
+ await expect(Promise.all([first, second])).resolves.toEqual([
63
+ protocolV2ApplicationInfo,
64
+ protocolV2ApplicationInfo,
65
+ ]);
66
+ expect(typedCall).toHaveBeenCalledTimes(1);
67
+ expect(typedCall).toHaveBeenCalledWith('ProtocolInfoRequest', 'ProtocolInfo', {
68
+ eventless_wallet_session: true,
69
+ });
70
+ });
71
+
72
+ test('renegotiates Protocol V2 runtime context after transport disconnect', async () => {
73
+ const typedCall = jest.fn().mockResolvedValue({ message: protocolV2ApplicationInfo });
74
+ const device = createV2Device(typedCall);
75
+
76
+ await device.ensureProtocolV2RuntimeContext();
77
+ await device.ensureProtocolV2RuntimeContext();
78
+ device.markTransportDisconnected();
79
+ await device.ensureProtocolV2RuntimeContext();
80
+
81
+ expect(typedCall).toHaveBeenCalledTimes(2);
82
+ });
83
+
84
+ test('rejects every waiter when runtime-context negotiation is invalidated', async () => {
85
+ let resolveProtocolInfo:
86
+ | ((value: { message: typeof protocolV2ApplicationInfo }) => void)
87
+ | undefined;
88
+ const typedCall = jest.fn(
89
+ () =>
90
+ new Promise<{ message: typeof protocolV2ApplicationInfo }>(resolve => {
91
+ resolveProtocolInfo = resolve;
92
+ })
93
+ );
94
+ const device = createV2Device(typedCall);
95
+
96
+ const first = device.ensureProtocolV2RuntimeContext();
97
+ const second = device.ensureProtocolV2RuntimeContext();
98
+ const firstExpectation = expect(first).rejects.toMatchObject({
99
+ errorCode: HardwareErrorCode.DeviceInitializeFailed,
100
+ });
101
+ const secondExpectation = expect(second).rejects.toMatchObject({
102
+ errorCode: HardwareErrorCode.DeviceInitializeFailed,
103
+ });
104
+ device.markTransportDisconnected();
105
+ resolveProtocolInfo?.({ message: protocolV2ApplicationInfo });
106
+
107
+ await Promise.all([firstExpectation, secondExpectation]);
108
+ });
109
+
46
110
  test('does not expose the internal wallet session', async () => {
47
111
  const device = createV2Device(jest.fn());
48
112
  device.updateState({ protocol: 'V2' }, 'initialize');
@@ -159,15 +223,20 @@ describe('getDeviceState', () => {
159
223
  throw new Error(`Unexpected request: ${requestType}`);
160
224
  });
161
225
  const device = createV2Device(typedCall);
162
- device.updateState({ protocol: 'V2', status: { mode } }, 'initialize');
226
+ device.updateState(
227
+ {
228
+ protocol: 'V2',
229
+ identity: { deviceType: EDeviceType.Pro2 },
230
+ status: { mode },
231
+ raw: { protocolV2ProtocolInfo: getProtocolV2LoaderInfo(mode) },
232
+ },
233
+ 'initialize'
234
+ );
163
235
 
164
236
  const state = await device.getDeviceState({ refreshSections: ['status'] });
165
237
 
166
238
  expect(state.status.mode).toBe(mode);
167
- expect(typedCall.mock.calls.map(call => call[0])).toEqual([
168
- 'DeviceInfoGet',
169
- 'ProtocolInfoRequest',
170
- ]);
239
+ expect(typedCall).not.toHaveBeenCalled();
171
240
  }
172
241
  );
173
242
 
@@ -187,7 +256,14 @@ describe('getDeviceState', () => {
187
256
  return { message: { init_states: true, unlocked: true, device_id: 'device-1' } };
188
257
  });
189
258
  const device = createV2Device(typedCall);
190
- device.updateState({ protocol: 'V2', status: { mode: 'normal' } }, 'initialize');
259
+ device.updateState(
260
+ {
261
+ protocol: 'V2',
262
+ status: { mode: 'normal' },
263
+ raw: { protocolV2ProtocolInfo: protocolV2ApplicationInfo },
264
+ },
265
+ 'initialize'
266
+ );
191
267
 
192
268
  const state = await device.getDeviceState({ refreshSections: ['status'] });
193
269
 
@@ -205,7 +281,14 @@ describe('getDeviceState', () => {
205
281
  },
206
282
  });
207
283
  const device = createV2Device(typedCall);
208
- device.updateState({ protocol: 'V2', status: { mode: 'normal' } }, 'initialize');
284
+ device.updateState(
285
+ {
286
+ protocol: 'V2',
287
+ status: { mode: 'normal' },
288
+ raw: { protocolV2ProtocolInfo: protocolV2ApplicationInfo },
289
+ },
290
+ 'initialize'
291
+ );
209
292
  const onState = jest.fn();
210
293
  device.on(DEVICE.STATE, onState);
211
294
 
@@ -250,13 +333,18 @@ describe('getDeviceState', () => {
250
333
  throw new Error(`Unexpected request: ${requestType}`);
251
334
  });
252
335
  const device = createV2Device(typedCall);
253
- device.updateState({ protocol: 'V2', status: { mode: 'normal' } }, 'initialize');
336
+ device.updateState(
337
+ {
338
+ protocol: 'V2',
339
+ status: { mode: 'normal' },
340
+ raw: { protocolV2ProtocolInfo: protocolV2ApplicationInfo },
341
+ },
342
+ 'initialize'
343
+ );
254
344
 
255
345
  const state = await device.getDeviceState({ refreshSections: ['status', 'settings'] });
256
346
 
257
347
  expect(typedCall.mock.calls.map(call => call[0])).toEqual([
258
- 'DeviceInfoGet',
259
- 'ProtocolInfoRequest',
260
348
  'DeviceStatusGet',
261
349
  'DeviceSettingsGet',
262
350
  ]);
@@ -288,7 +376,11 @@ describe('getDeviceState', () => {
288
376
  });
289
377
  const device = createV2Device(typedCall);
290
378
  device.updateState(
291
- { protocol: 'V2', status: { mode: 'normal', unlocked: true } },
379
+ {
380
+ protocol: 'V2',
381
+ status: { mode: 'normal', unlocked: true },
382
+ raw: { protocolV2ProtocolInfo: protocolV2ApplicationInfo },
383
+ },
292
384
  'initialize'
293
385
  );
294
386
 
@@ -374,6 +466,34 @@ describe('getDeviceState', () => {
374
466
  });
375
467
  });
376
468
 
469
+ test.each([
470
+ EDeviceType.Classic,
471
+ EDeviceType.Classic1s,
472
+ EDeviceType.ClassicPure,
473
+ EDeviceType.Mini,
474
+ ])('keeps the GetFeatures-only firmware path for %s', async deviceType => {
475
+ const typedCall = jest.fn().mockResolvedValue({
476
+ message: {
477
+ onekey_device_type: deviceType.toUpperCase(),
478
+ initialized: true,
479
+ onekey_firmware_version: '3.5.0',
480
+ se_ver: '1.1.0.2',
481
+ },
482
+ });
483
+ const device = createV1Device(typedCall);
484
+
485
+ const state = await device.getDeviceState({
486
+ refreshSections: ['identity', 'versions', 'verification'],
487
+ });
488
+
489
+ expect(typedCall.mock.calls.map(call => call[0])).toEqual(['GetFeatures']);
490
+ expect(state.versions).toMatchObject({
491
+ firmware: '3.5.0',
492
+ se: '1.1.0.2',
493
+ se01: '1.1.0.2',
494
+ });
495
+ });
496
+
377
497
  test('does not clear Protocol V1 firmware details during a later runtime refresh', async () => {
378
498
  let getFeaturesCount = 0;
379
499
  const typedCall = jest.fn().mockImplementation((requestType: string) => {
@@ -1,6 +1,6 @@
1
1
  import { EDeviceType } from '@onekeyfe/hd-shared';
2
2
 
3
- import { getHomeScreenSize } from '../src/utils/homescreen';
3
+ import { getHomeScreenSize, getNftSize } from '../src/utils/homescreen';
4
4
 
5
5
  describe('getHomeScreenSize', () => {
6
6
  it('returns the Pro 2 wallpaper dimensions', () => {
@@ -21,4 +21,44 @@ describe('getHomeScreenSize', () => {
21
21
  })
22
22
  ).toBeUndefined();
23
23
  });
24
+
25
+ it('does not reuse the wallpaper homeScreenType for Pro 2 NFT dimensions', () => {
26
+ expect(
27
+ getHomeScreenSize({
28
+ deviceType: EDeviceType.Pro2,
29
+ homeScreenType: 'Nft',
30
+ thumbnail: false,
31
+ })
32
+ ).toEqual({ width: 604, height: 1024 });
33
+ expect(
34
+ getHomeScreenSize({
35
+ deviceType: EDeviceType.Pro2,
36
+ homeScreenType: 'Nft',
37
+ thumbnail: true,
38
+ })
39
+ ).toBeUndefined();
40
+ });
41
+ });
42
+
43
+ describe('getNftSize', () => {
44
+ it('returns the Pro 2 NFT image and thumbnail dimensions independently', () => {
45
+ expect(getNftSize({ deviceType: EDeviceType.Pro2 })).toEqual({ width: 540, height: 540 });
46
+ expect(getNftSize({ deviceType: EDeviceType.Pro2, thumbnail: true })).toEqual({
47
+ width: 263,
48
+ height: 263,
49
+ });
50
+ });
51
+
52
+ it('preserves the legacy NFT dimensions', () => {
53
+ expect(getNftSize({ deviceType: EDeviceType.Touch })).toEqual({ width: 480, height: 800 });
54
+ expect(getNftSize({ deviceType: EDeviceType.Touch, thumbnail: true })).toEqual({
55
+ width: 238,
56
+ height: 238,
57
+ });
58
+ expect(getNftSize({ deviceType: EDeviceType.Pro, thumbnail: true })).toEqual({
59
+ width: 226,
60
+ height: 226,
61
+ radius: 40,
62
+ });
63
+ });
24
64
  });
@@ -465,7 +465,7 @@ describe('KaspaSignTransaction protocol negotiation', () => {
465
465
  expect(mockTypedCall.mock.calls[4][0]).toBe('KaspaTxAckInput');
466
466
  });
467
467
 
468
- describe('previous-transaction id mismatch', () => {
468
+ describe('streaming error propagation', () => {
469
469
  const PREV_ID = 'aa'.repeat(32);
470
470
  const withRefTxs = {
471
471
  outputs: [{ satoshis: 100000, script: SCRIPT, address: ADDRESS }],
@@ -486,7 +486,7 @@ describe('KaspaSignTransaction protocol negotiation', () => {
486
486
  )
487
487
  .mockRejectedValueOnce(error);
488
488
 
489
- it('surfaces the device rejection under its own error code', async () => {
489
+ it('propagates a previous-transaction id mismatch without retrying', async () => {
490
490
  streamThenReject(
491
491
  ERRORS.TypedError(
492
492
  HardwareErrorCode.RuntimeError,
@@ -494,32 +494,9 @@ describe('KaspaSignTransaction protocol negotiation', () => {
494
494
  )
495
495
  );
496
496
 
497
- await expect(runMethod(withRefTxs)).rejects.toMatchObject({
498
- errorCode: HardwareErrorCode.KaspaPrevTxIdMismatch,
499
- });
500
- // Never silently re-signs without refTxs.
501
- expect(mockTypedCall).toHaveBeenCalledTimes(2);
502
- });
503
-
504
- it('leaves an unrelated device error untouched', async () => {
505
- streamThenReject(
506
- ERRORS.TypedError(
507
- HardwareErrorCode.RuntimeError,
508
- 'Failure_ProcessError,some other device error'
509
- )
510
- );
511
-
512
497
  await expect(runMethod(withRefTxs)).rejects.toMatchObject({
513
498
  errorCode: HardwareErrorCode.RuntimeError,
514
- });
515
- expect(mockTypedCall).toHaveBeenCalledTimes(2);
516
- });
517
-
518
- it('leaves user cancellation untouched', async () => {
519
- streamThenReject(ERRORS.TypedError(HardwareErrorCode.ActionCancelled));
520
-
521
- await expect(runMethod(withRefTxs)).rejects.toMatchObject({
522
- errorCode: HardwareErrorCode.ActionCancelled,
499
+ message: expect.stringContaining('Kaspa previous transaction id mismatch'),
523
500
  });
524
501
  expect(mockTypedCall).toHaveBeenCalledTimes(2);
525
502
  });
@@ -104,7 +104,7 @@ describe('getLogBlockLabel', () => {
104
104
  });
105
105
  });
106
106
 
107
- it.each(['deviceUploadWallpaper', 'uploadPortfolio', 'fileWrite', 'fileRead'])(
107
+ it.each(['deviceUploadNft', 'deviceUploadWallpaper', 'uploadPortfolio', 'fileWrite', 'fileRead'])(
108
108
  'keeps metadata and replaces binary payloads with their size for %s',
109
109
  method => {
110
110
  const request = { method, path: 'resource.bin', data: new Uint8Array(1024) };
@@ -1,6 +1,7 @@
1
1
  import { EFirmwareType, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
2
 
3
3
  import { BaseMethod } from '../src/api/BaseMethod';
4
+ import { findMethod } from '../src/api/utils';
4
5
  import BTCGetAddress from '../src/api/btc/BTCGetAddress';
5
6
  import DeviceReboot from '../src/api/protocol-v2/DeviceReboot';
6
7
  import SolGetAddress from '../src/api/solana/SolGetAddress';
@@ -20,6 +21,24 @@ class DefaultMethod extends BaseMethod {
20
21
  }
21
22
 
22
23
  describe('method protocol support', () => {
24
+ test('creates a protocol detection method that returns only the current protocol', async () => {
25
+ const method = findMethod({
26
+ id: 6,
27
+ payload: {
28
+ method: 'detectDeviceConnectProtocol',
29
+ connectId: 'ble-device',
30
+ },
31
+ } as never);
32
+
33
+ method.init();
34
+ (method as unknown as { device: unknown }).device = {
35
+ getProtocol: () => 'V2',
36
+ };
37
+
38
+ expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
39
+ await expect(method.run()).resolves.toBe('V2');
40
+ });
41
+
23
42
  test('defaults existing methods to Protocol V1 only', () => {
24
43
  const method = new DefaultMethod({
25
44
  id: 1,