@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,5 @@
1
1
  import AllNetworkGetAddressBase from '../src/api/allnetwork/AllNetworkGetAddressBase';
2
+ import AllNetworkGetAddress from '../src/api/allnetwork/AllNetworkGetAddress';
2
3
  import { findMethod } from '../src/api/utils';
3
4
  import { getActiveRequestsByDeviceInstance } from '../src/utils/tracing';
4
5
 
@@ -18,6 +19,235 @@ class TestAllNetworkMethod extends AllNetworkGetAddressBase {
18
19
  }
19
20
 
20
21
  describe('AllNetworkGetAddressBase tracing', () => {
22
+ test('resumes a Protocol V2 hidden wallet before running a nested chain method', async () => {
23
+ const calls: string[] = [];
24
+ const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
25
+ calls.push('resume-hidden-session');
26
+ return Promise.resolve(true);
27
+ });
28
+ const innerMethod = {
29
+ checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
30
+ connectId: 'connect-id',
31
+ deviceId: 'device-id',
32
+ getVersionRange: jest.fn().mockReturnValue({}),
33
+ assertProtocolSupported: jest.fn(),
34
+ init: jest.fn(),
35
+ name: 'evmGetAddress',
36
+ responseID: 43,
37
+ unlockPolicy: 'unlock-before-run',
38
+ run: jest.fn().mockImplementation(() => {
39
+ calls.push('run-chain-method');
40
+ return Promise.resolve([{ address: '0xhidden' }]);
41
+ }),
42
+ setDevice: jest.fn(),
43
+ strictCheckDeviceSupport: false,
44
+ };
45
+ (findMethod as jest.Mock).mockReturnValue(innerMethod);
46
+ const method = new TestAllNetworkMethod({
47
+ id: 1,
48
+ payload: {
49
+ method: 'allNetworkGetAddress',
50
+ connectId: 'connect-id',
51
+ deviceId: 'device-id',
52
+ passphraseState: 'hidden-state',
53
+ bundle: [],
54
+ },
55
+ });
56
+ method.protocolV2UnlockContext = { preflightCompleted: true };
57
+ const typedCall = jest.fn();
58
+ method.device = {
59
+ checkPassphraseStateSafety,
60
+ commands: {
61
+ typedCall,
62
+ },
63
+ getCurrentFirmwareType: jest.fn(),
64
+ getProtocol: jest.fn().mockReturnValue('V2'),
65
+ getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
66
+ getCurrentMethodVersionRange: jest
67
+ .fn()
68
+ .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
69
+ instanceId: 'device-instance',
70
+ isProtocolV2: jest.fn().mockReturnValue(true),
71
+ isBootloader: jest.fn().mockReturnValue(false),
72
+ isRomloader: jest.fn().mockReturnValue(false),
73
+ off: jest.fn(),
74
+ on: jest.fn(),
75
+ state: { status: { unlocked: true } },
76
+ updateProtocolV2Status: jest.fn(),
77
+ } as any;
78
+
79
+ await method.callMethod(
80
+ 'evmGetAddress',
81
+ {
82
+ bundle: [
83
+ {
84
+ _originRequestParams: {
85
+ network: 'evm',
86
+ path: "m/44'/60'/0'/0/0",
87
+ },
88
+ },
89
+ ],
90
+ },
91
+ 0
92
+ );
93
+
94
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined);
95
+ expect(calls).toEqual(['resume-hidden-session', 'run-chain-method']);
96
+ expect(typedCall).not.toHaveBeenCalled();
97
+ });
98
+
99
+ test('resumes a Protocol V2 standard wallet before running a nested chain method', async () => {
100
+ const calls: string[] = [];
101
+ const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
102
+ calls.push('resume-standard-session');
103
+ return Promise.resolve(true);
104
+ });
105
+ const innerMethod = {
106
+ checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
107
+ connectId: 'connect-id',
108
+ deviceId: 'device-id',
109
+ getVersionRange: jest.fn().mockReturnValue({}),
110
+ assertProtocolSupported: jest.fn(),
111
+ init: jest.fn(),
112
+ name: 'evmGetAddress',
113
+ responseID: 44,
114
+ unlockPolicy: 'unlock-before-run',
115
+ run: jest.fn().mockImplementation(() => {
116
+ calls.push('run-chain-method');
117
+ return Promise.resolve([{ address: '0xstandard' }]);
118
+ }),
119
+ setDevice: jest.fn(),
120
+ strictCheckDeviceSupport: false,
121
+ };
122
+ (findMethod as jest.Mock).mockReturnValue(innerMethod);
123
+ const method = new TestAllNetworkMethod({
124
+ id: 2,
125
+ payload: {
126
+ method: 'allNetworkGetAddress',
127
+ connectId: 'connect-id',
128
+ deviceId: 'device-id',
129
+ useEmptyPassphrase: true,
130
+ bundle: [],
131
+ },
132
+ });
133
+ method.protocolV2UnlockContext = { preflightCompleted: true };
134
+ const typedCall = jest.fn();
135
+ method.device = {
136
+ checkPassphraseStateSafety,
137
+ commands: {
138
+ typedCall,
139
+ },
140
+ getCurrentFirmwareType: jest.fn(),
141
+ getProtocol: jest.fn().mockReturnValue('V2'),
142
+ getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
143
+ getCurrentMethodVersionRange: jest
144
+ .fn()
145
+ .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
146
+ instanceId: 'device-instance',
147
+ isProtocolV2: jest.fn().mockReturnValue(true),
148
+ isBootloader: jest.fn().mockReturnValue(false),
149
+ isRomloader: jest.fn().mockReturnValue(false),
150
+ off: jest.fn(),
151
+ on: jest.fn(),
152
+ state: { status: { unlocked: true } },
153
+ updateProtocolV2Status: jest.fn(),
154
+ } as any;
155
+
156
+ await method.callMethod(
157
+ 'evmGetAddress',
158
+ {
159
+ bundle: [
160
+ {
161
+ _originRequestParams: {
162
+ network: 'evm',
163
+ path: "m/44'/60'/0'/0/0",
164
+ },
165
+ },
166
+ ],
167
+ },
168
+ 0
169
+ );
170
+
171
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined);
172
+ expect(calls).toEqual(['resume-standard-session', 'run-chain-method']);
173
+ expect(typedCall).not.toHaveBeenCalled();
174
+ });
175
+
176
+ test('runs Protocol V2 addresses one at a time so each command receives a wallet session', async () => {
177
+ const method = new AllNetworkGetAddress({
178
+ id: 3,
179
+ payload: {
180
+ method: 'allNetworkGetAddress',
181
+ connectId: 'connect-id',
182
+ deviceId: 'device-id',
183
+ useEmptyPassphrase: true,
184
+ bundle: [
185
+ { network: 'evm', path: "m/44'/60'/0'/0/0" },
186
+ { network: 'evm', path: "m/44'/60'/0'/0/1" },
187
+ ],
188
+ },
189
+ });
190
+ method.device = {
191
+ isProtocolV2: jest.fn().mockReturnValue(true),
192
+ } as any;
193
+ method.postMessage = jest.fn();
194
+ const callMethod = jest
195
+ .fn()
196
+ .mockResolvedValueOnce([{ payload: { address: '0x1' }, success: true }])
197
+ .mockResolvedValueOnce([{ payload: { address: '0x2' }, success: true }]);
198
+ method.callMethod = callMethod;
199
+
200
+ await method.getAllNetworkAddress(7);
201
+
202
+ expect(callMethod).toHaveBeenCalledTimes(2);
203
+ expect(callMethod).toHaveBeenNthCalledWith(
204
+ 1,
205
+ 'evmGetAddress',
206
+ expect.objectContaining({ bundle: [expect.any(Object)] }),
207
+ 7
208
+ );
209
+ expect(callMethod).toHaveBeenNthCalledWith(
210
+ 2,
211
+ 'evmGetAddress',
212
+ expect.objectContaining({ bundle: [expect.any(Object)] }),
213
+ 7
214
+ );
215
+ });
216
+
217
+ test('keeps same-method address batching for Protocol V1', async () => {
218
+ const method = new AllNetworkGetAddress({
219
+ id: 4,
220
+ payload: {
221
+ method: 'allNetworkGetAddress',
222
+ connectId: 'connect-id',
223
+ deviceId: 'device-id',
224
+ useEmptyPassphrase: true,
225
+ bundle: [
226
+ { network: 'evm', path: "m/44'/60'/0'/0/0" },
227
+ { network: 'evm', path: "m/44'/60'/0'/0/1" },
228
+ ],
229
+ },
230
+ });
231
+ method.device = {
232
+ isProtocolV2: jest.fn().mockReturnValue(false),
233
+ } as any;
234
+ method.postMessage = jest.fn();
235
+ const callMethod = jest.fn().mockResolvedValue([
236
+ { payload: { address: '0x1' }, success: true },
237
+ { payload: { address: '0x2' }, success: true },
238
+ ]);
239
+ method.callMethod = callMethod;
240
+
241
+ await method.getAllNetworkAddress(7);
242
+
243
+ expect(callMethod).toHaveBeenCalledTimes(1);
244
+ expect(callMethod).toHaveBeenCalledWith(
245
+ 'evmGetAddress',
246
+ expect.objectContaining({ bundle: [expect.any(Object), expect.any(Object)] }),
247
+ 7
248
+ );
249
+ });
250
+
21
251
  test('releases the nested request context when an unhandled error escapes', async () => {
22
252
  const deviceInstanceId = 'device-instance';
23
253
  const innerMethod = {
@@ -51,6 +281,7 @@ describe('AllNetworkGetAddressBase tracing', () => {
51
281
  getCurrentMethodVersionRange: jest
52
282
  .fn()
53
283
  .mockImplementation((getRange: (type: string) => unknown) => getRange('classic')),
284
+ isProtocolV2: jest.fn().mockReturnValue(false),
54
285
  off: jest.fn(),
55
286
  on: jest.fn(),
56
287
  } as any;
@@ -125,6 +125,51 @@ describe('DeviceCommands failure mapping', () => {
125
125
  expect(JSON.stringify(log.messages)).not.toContain('secret-wallet-address');
126
126
  });
127
127
 
128
+ it('logs the sanitized DeviceFirmwareUpdateStatus response payload', async () => {
129
+ const commands = createCommands();
130
+ const log = getLogger(LoggerNames.DeviceCommands);
131
+ log.messages.length = 0;
132
+
133
+ await expect(
134
+ commands._filterCommonTypes(
135
+ {
136
+ type: 'DeviceFirmwareUpdateStatus',
137
+ message: {
138
+ records: [
139
+ {
140
+ target_id: 4,
141
+ status: 2,
142
+ payload_version: 0x010203,
143
+ path: 'vol0:/application_p1.bin',
144
+ },
145
+ ],
146
+ },
147
+ } as any,
148
+ 'DeviceFirmwareUpdateStatusGet'
149
+ )
150
+ ).resolves.toMatchObject({ type: 'DeviceFirmwareUpdateStatus' });
151
+
152
+ expect(log.messages.at(-1)?.message).toEqual([
153
+ '_filterCommonTypes: ',
154
+ {
155
+ request: 'DeviceFirmwareUpdateStatusGet',
156
+ response: {
157
+ type: 'DeviceFirmwareUpdateStatus',
158
+ message: {
159
+ records: [
160
+ {
161
+ target_id: 4,
162
+ status: 2,
163
+ payload_version: 0x010203,
164
+ path: 'vol0:/application_p1.bin',
165
+ },
166
+ ],
167
+ },
168
+ },
169
+ },
170
+ ]);
171
+ });
172
+
128
173
  it('maps an invalid DeviceSessionGet resume to WalletSessionInvalid', async () => {
129
174
  const commands = createCommands();
130
175
 
@@ -3,6 +3,8 @@ import { registerHardwareUiEventListeners } from '../src/core/deviceEventRegistr
3
3
 
4
4
  const handlers = {
5
5
  pin: jest.fn(),
6
+ pinOnDevice: jest.fn(),
7
+ pinOnDeviceComplete: jest.fn(),
6
8
  button: jest.fn(),
7
9
  passphrase: jest.fn(),
8
10
  passphraseOnDevice: jest.fn(),
@@ -21,6 +23,8 @@ describe('hardware UI event registration', () => {
21
23
  expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(true);
22
24
  expect(device.on.mock.calls.map(([type]) => type)).toEqual([
23
25
  DEVICE.PIN,
26
+ DEVICE.PIN_ON_DEVICE,
27
+ DEVICE.PIN_ON_DEVICE_COMPLETE,
24
28
  DEVICE.BUTTON,
25
29
  DEVICE.PASSPHRASE,
26
30
  DEVICE.PASSPHRASE_ON_DEVICE,
@@ -34,6 +38,8 @@ describe('hardware UI event registration', () => {
34
38
  expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(true);
35
39
  expect(device.on.mock.calls.map(([type]) => type)).toEqual([
36
40
  DEVICE.PIN,
41
+ DEVICE.PIN_ON_DEVICE,
42
+ DEVICE.PIN_ON_DEVICE_COMPLETE,
37
43
  DEVICE.BUTTON,
38
44
  DEVICE.PASSPHRASE,
39
45
  DEVICE.PASSPHRASE_ON_DEVICE,
@@ -5,6 +5,7 @@ import CheckAllFirmwareRelease, {
5
5
  } from '../src/api/CheckAllFirmwareRelease';
6
6
  import { DataManager } from '../src/data-manager';
7
7
  import { createCoreApi } from '../src/inject';
8
+ import { PROTOCOL_V2_RESOURCE_DEVICE_PATHS } from '../src/protocols/protocol-v2/resources';
8
9
 
9
10
  import type { CoreApi } from '../src/types/api';
10
11
  import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
@@ -72,7 +73,74 @@ const release: IFirmwareReleaseInfo = {
72
73
  ],
73
74
  };
74
75
 
76
+ const stableResources = ['images', 'animation', 'wallpaper', 'translations', 'roobert', 'noto'].map(
77
+ (type, index) => ({
78
+ type,
79
+ url: `https://example.com/${type}.okpkg`,
80
+ size: 0x52a0 + index + 1,
81
+ fileHash: 'a'.repeat(64),
82
+ headerHash: index.toString(16).padStart(128, '0'),
83
+ })
84
+ );
85
+
86
+ const createFilesystemTypedCall = (missingAll = false) => {
87
+ const resourceByPath = new Map(
88
+ stableResources.map(resource => [
89
+ PROTOCOL_V2_RESOURCE_DEVICE_PATHS[
90
+ resource.type as keyof typeof PROTOCOL_V2_RESOURCE_DEVICE_PATHS
91
+ ],
92
+ resource,
93
+ ])
94
+ );
95
+ return jest.fn((requestType: string, _responseType: string, payload: Record<string, any>) => {
96
+ if (requestType === 'ResourceInventoryGet') {
97
+ throw new Error('ResourceInventoryGet is unavailable on released firmware');
98
+ }
99
+ if (requestType === 'FilesystemPathInfoQuery') {
100
+ const resource = resourceByPath.get(payload.path);
101
+ return {
102
+ message: {
103
+ exist: Boolean(resource) && !missingAll,
104
+ directory: false,
105
+ size: missingAll ? 0 : resource?.size,
106
+ },
107
+ };
108
+ }
109
+ if (requestType === 'FilesystemFileRead') {
110
+ const resource = resourceByPath.get(payload.file.path);
111
+ if (!resource || missingAll) throw new Error('missing resource');
112
+ const header = new Uint8Array(0x52a0);
113
+ const view = new DataView(header.buffer);
114
+ 'OKPP'.split('').forEach((char, index) => {
115
+ header[index] = char.charCodeAt(0);
116
+ });
117
+ 'RESC'.split('').forEach((char, index) => {
118
+ header[0x08 + index] = char.charCodeAt(0);
119
+ });
120
+ view.setUint32(0x0c, header.byteLength, true);
121
+ for (let index = 0; index < resource.headerHash.length / 2; index++) {
122
+ header[0x240 + index] = Number.parseInt(
123
+ resource.headerHash.slice(index * 2, index * 2 + 2),
124
+ 16
125
+ );
126
+ }
127
+ const offset = Number(payload.file.offset);
128
+ const chunkLength = Number(payload.chunk_len);
129
+ return {
130
+ message: {
131
+ data: header.slice(offset, offset + chunkLength),
132
+ },
133
+ };
134
+ }
135
+ throw new Error(`Unexpected request: ${requestType}`);
136
+ });
137
+ };
138
+
75
139
  describe('checkAllFirmwareRelease Protocol V2 support', () => {
140
+ afterEach(() => {
141
+ jest.restoreAllMocks();
142
+ });
143
+
76
144
  test('builds ordered firmwareUpdateV4 targets from recommended component versions', () => {
77
145
  const result = buildProtocolV2FirmwareRelease({
78
146
  currentVersions,
@@ -84,7 +152,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
84
152
  status: 'required',
85
153
  hasUpgrade: true,
86
154
  required: true,
87
- targetsToUpdate: ['boot', 'app_v1', 'resource'],
155
+ targetsToUpdate: ['boot', 'app_v1'],
88
156
  components: [
89
157
  { configKey: 'bootloader', status: 'outdated', updateTarget: 'boot' },
90
158
  { configKey: 'applicationP1', status: 'outdated', updateTarget: 'app_v1' },
@@ -142,6 +210,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
142
210
  applicationP1Hash: 'aa'.repeat(32),
143
211
  applicationP2Hash: 'bb'.repeat(32),
144
212
  },
213
+ checkFirmwareHash: true,
145
214
  remotePayloadHashes: {
146
215
  applicationP1: 'aa'.repeat(64),
147
216
  applicationP2: 'cc'.repeat(64),
@@ -160,6 +229,37 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
160
229
  });
161
230
  });
162
231
 
232
+ test('uses version-only comparison for same-version packages by default', () => {
233
+ const packageSet: IFirmwareReleaseInfo = {
234
+ ...release,
235
+ required: false,
236
+ resourceBundles: undefined,
237
+ installOrder: ['applicationP1'],
238
+ components: {
239
+ applicationP1: {
240
+ target: 'APPLICATION_P1',
241
+ version: [1, 0, 0],
242
+ url: 'https://example.com/application-p1.okpkg',
243
+ payloadHash: 'cc'.repeat(64),
244
+ },
245
+ },
246
+ };
247
+
248
+ expect(
249
+ buildProtocolV2FirmwareRelease({
250
+ currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
251
+ currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
252
+ firmwareType: EFirmwareType.Universal,
253
+ release: packageSet,
254
+ })
255
+ ).toMatchObject({
256
+ status: 'valid',
257
+ hasUpgrade: false,
258
+ targetsToUpdate: [],
259
+ components: [{ configKey: 'applicationP1', status: 'valid' }],
260
+ });
261
+ });
262
+
163
263
  test('keeps same-version hash-aware components unknown without metadata payloadHash', () => {
164
264
  const packageSet: IFirmwareReleaseInfo = {
165
265
  ...release,
@@ -180,6 +280,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
180
280
  buildProtocolV2FirmwareRelease({
181
281
  currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
182
282
  currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
283
+ checkFirmwareHash: true,
183
284
  firmwareType: EFirmwareType.Universal,
184
285
  release: packageSet,
185
286
  })
@@ -215,6 +316,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
215
316
  const result = buildProtocolV2FirmwareRelease({
216
317
  currentVersions,
217
318
  currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
319
+ checkFirmwareHash: true,
218
320
  remotePayloadHashes: { applicationP1: 'cc'.repeat(64) },
219
321
  firmwareType: EFirmwareType.Universal,
220
322
  release: packageSet,
@@ -223,7 +325,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
223
325
  expect(result.targetsToUpdate).toEqual(['app_v1', 'app_v2']);
224
326
  });
225
327
 
226
- test('uses the existing method on Protocol V2 and keeps its public API name', async () => {
328
+ test('does not read vol0 resource inventory while Protocol V2 is in Application mode', async () => {
227
329
  const method = new CheckAllFirmwareRelease({
228
330
  id: 1,
229
331
  payload: {
@@ -240,6 +342,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
240
342
  status: { mode: 'normal' },
241
343
  versions: currentVersions,
242
344
  });
345
+ const typedCall = createFilesystemTypedCall(true);
243
346
  method.device = {
244
347
  isProtocolV2: () => true,
245
348
  features: {
@@ -247,32 +350,124 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
247
350
  firmwareVersion: '1.0.0',
248
351
  },
249
352
  getDeviceState,
353
+ getCommands: () => ({ typedCall }),
250
354
  } as unknown as CheckAllFirmwareRelease['device'];
251
355
  jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
356
+ jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
252
357
 
253
358
  await expect(method.run()).resolves.toMatchObject({
254
359
  protocol: 'V2',
255
360
  deviceType: 'pro2',
256
361
  status: 'required',
257
- targetsToUpdate: ['boot', 'app_v1', 'resource'],
362
+ resourceStatus: 'unknown',
363
+ targetsToUpdate: ['boot', 'app_v1'],
258
364
  firmware: {
259
365
  status: 'required',
260
366
  },
261
367
  });
368
+ expect(typedCall).not.toHaveBeenCalled();
369
+ expect(getDeviceState).toHaveBeenCalledWith({
370
+ refreshSections: ['identity', 'versions'],
371
+ });
262
372
  expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
263
373
  });
264
374
 
375
+ test('requests and compares firmware hashes only when explicitly enabled', async () => {
376
+ const packageSet: IFirmwareReleaseInfo = {
377
+ ...release,
378
+ required: false,
379
+ resourceBundles: undefined,
380
+ installOrder: ['applicationP1'],
381
+ components: {
382
+ applicationP1: {
383
+ target: 'APPLICATION_P1',
384
+ version: [1, 0, 0],
385
+ url: 'https://example.com/application-p1.okpkg',
386
+ payloadHash: 'cc'.repeat(64),
387
+ },
388
+ },
389
+ };
390
+ const method = new CheckAllFirmwareRelease({
391
+ id: 1,
392
+ payload: {
393
+ method: 'checkAllFirmwareRelease',
394
+ firmwareType: EFirmwareType.Universal,
395
+ checkFirmwareHash: true,
396
+ },
397
+ });
398
+ method.init();
399
+ const getDeviceState = jest.fn().mockResolvedValue({
400
+ identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
401
+ status: { mode: 'normal' },
402
+ versions: { ...currentVersions, applicationP1: '1.0.0' },
403
+ verification: { applicationP1Hash: 'aa'.repeat(32) },
404
+ });
405
+ method.device = {
406
+ isProtocolV2: () => true,
407
+ features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
408
+ getDeviceState,
409
+ getCommands: () => ({ typedCall: jest.fn() }),
410
+ } as unknown as CheckAllFirmwareRelease['device'];
411
+ jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(packageSet);
412
+ jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(undefined);
413
+
414
+ await expect(method.run()).resolves.toMatchObject({
415
+ status: 'outdated',
416
+ targetsToUpdate: ['app_v1'],
417
+ });
418
+ expect(getDeviceState).toHaveBeenCalledWith({
419
+ refreshSections: ['identity', 'versions', 'verification'],
420
+ });
421
+ });
422
+
423
+ test.each(['bootloader', 'romloader'] as const)(
424
+ 'uses filesystem inventory in %s mode instead of forcing all resources',
425
+ async mode => {
426
+ const method = new CheckAllFirmwareRelease({
427
+ id: 1,
428
+ payload: {
429
+ method: 'checkAllFirmwareRelease',
430
+ firmwareType: EFirmwareType.Universal,
431
+ },
432
+ });
433
+ method.init();
434
+ const typedCall = createFilesystemTypedCall();
435
+ method.device = {
436
+ isProtocolV2: () => true,
437
+ features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
438
+ getDeviceState: jest.fn().mockResolvedValue({
439
+ identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
440
+ status: { mode },
441
+ versions: currentVersions,
442
+ }),
443
+ getCommands: () => ({ typedCall }),
444
+ } as unknown as CheckAllFirmwareRelease['device'];
445
+ jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
446
+ jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
447
+
448
+ await expect(method.run()).resolves.toMatchObject({
449
+ protocol: 'V2',
450
+ resourceStatus: 'valid',
451
+ targetsToUpdate: ['boot', 'app_v1'],
452
+ });
453
+ expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
454
+ expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
455
+ }
456
+ );
457
+
265
458
  test('continues forwarding the existing public method', async () => {
266
459
  const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
267
460
  const api = createCoreApi(call as CoreApi['call']) as CoreApi;
268
461
 
269
462
  await api.checkAllFirmwareRelease('pro2-connect-id', {
463
+ checkFirmwareHash: true,
270
464
  firmwareType: EFirmwareType.Universal,
271
465
  retryCount: 0,
272
466
  });
273
467
 
274
468
  expect(call).toHaveBeenCalledWith({
275
469
  connectId: 'pro2-connect-id',
470
+ checkFirmwareHash: true,
276
471
  firmwareType: EFirmwareType.Universal,
277
472
  retryCount: 0,
278
473
  method: 'checkAllFirmwareRelease',
@@ -1,61 +1,19 @@
1
- import DataManager from '../src/data-manager/DataManager';
2
1
  import { parseConnectSettings } from '../src/data-manager/connectSettings';
3
2
 
4
- import type { RemoteConfigResponse } from '../src/types';
5
-
6
- jest.mock('axios', () => ({
7
- get: jest.fn(),
8
- }));
9
-
10
3
  jest.mock('../src/data/config', () => ({
11
4
  getSDKVersion: jest.fn(() => '1.0.0'),
12
5
  DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
13
6
  }));
14
7
 
15
- const mockAxiosGet: jest.Mock = jest.requireMock('axios').get;
16
-
17
8
  describe('parseConnectSettings', () => {
18
- const preloadedConfig = {
19
- bridge: {},
20
- classic: { firmware: [], ble: [] },
21
- classic1s: { firmware: [], ble: [] },
22
- classicpure: { firmware: [], ble: [] },
23
- mini: { firmware: [], ble: [] },
24
- touch: { firmware: [], ble: [] },
25
- pro: { firmware: [], ble: [] },
26
- pro2: { firmware: [], ble: [] },
27
- } as unknown as RemoteConfigResponse;
28
-
29
- it('keeps a serializable preloaded config in parsed settings', () => {
30
- const settings = parseConnectSettings({
31
- firmwareManifestMode: 'sdk-managed',
32
- preloadedConfig,
33
- });
34
-
35
- expect(settings.firmwareManifestMode).toBe('sdk-managed');
36
- expect(settings.preloadedConfig).toBe(preloadedConfig);
37
- });
38
-
39
- it('uses the preloaded config before the SDK network client', async () => {
40
- const settings = parseConnectSettings({
41
- firmwareManifestMode: 'sdk-managed',
42
- preloadedConfig,
43
- });
44
-
45
- await DataManager.load(settings);
46
-
47
- expect(mockAxiosGet).not.toHaveBeenCalled();
48
- expect(DataManager.deviceMap.classic).toEqual({ firmware: [], ble: [] });
49
- });
9
+ it('keeps custom configFetcher in parsed settings', () => {
10
+ const configFetcher = jest.fn();
50
11
 
51
- it('fails closed without a preloaded config in external-only mode', async () => {
52
12
  const settings = parseConnectSettings({
53
- firmwareManifestMode: 'external-only',
13
+ fetchConfig: true,
14
+ configFetcher,
54
15
  });
55
16
 
56
- await expect(DataManager.load(settings)).rejects.toThrow(
57
- 'External firmware config snapshot is required'
58
- );
59
- expect(mockAxiosGet).not.toHaveBeenCalled();
17
+ expect(settings.configFetcher).toBe(configFetcher);
60
18
  });
61
19
  });