@onekeyfe/hd-core 1.2.0-alpha.50 → 1.2.0-alpha.52

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 (238) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +0 -78
  2. package/__tests__/DeviceEventRegistration.test.ts +0 -6
  3. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -111
  4. package/__tests__/connectSettings.test.ts +47 -5
  5. package/__tests__/device-initialize-timeout.test.ts +56 -0
  6. package/__tests__/device-lifecycle-events.test.ts +3 -105
  7. package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
  8. package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
  9. package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
  10. package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
  11. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
  12. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
  13. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +294 -0
  14. package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
  15. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +213 -0
  16. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
  17. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
  18. package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
  19. package/__tests__/get-device-state.test.ts +12 -132
  20. package/__tests__/homescreen.test.ts +1 -41
  21. package/__tests__/logBlockEvent.test.ts +1 -1
  22. package/__tests__/method-protocol-support.test.ts +0 -19
  23. package/__tests__/open-wallet-session.test.ts +33 -446
  24. package/__tests__/protocol-v2-unlock-policy.test.ts +35 -196
  25. package/__tests__/protocol-v2.test.ts +1032 -1056
  26. package/__tests__/protocolV2UiInteraction.test.ts +0 -63
  27. package/__tests__/public-pro2-api-boundary.test.ts +0 -1
  28. package/__tests__/search-devices.test.ts +3 -12
  29. package/dist/api/BaseMethod.d.ts +1 -3
  30. package/dist/api/BaseMethod.d.ts.map +1 -1
  31. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  32. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  33. package/dist/api/FirmwareUpdateV2.d.ts +11 -0
  34. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  35. package/dist/api/FirmwareUpdateV3.d.ts +7 -3
  36. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  37. package/dist/api/FirmwareUpdateV4.d.ts +25 -9
  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/DeviceUpdateBootloader.d.ts +5 -1
  44. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  45. package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
  46. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
  47. package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
  48. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
  49. package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
  50. package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
  51. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +9 -0
  52. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  53. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
  54. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
  55. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
  56. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
  57. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
  58. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
  59. package/dist/api/firmware/getBinary.d.ts +7 -0
  60. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  61. package/dist/api/firmware/progressThrottle.d.ts +3 -0
  62. package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
  63. package/dist/api/firmware/updateBootloader.d.ts +2 -0
  64. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  65. package/dist/api/firmware/uploadFirmware.d.ts +9 -1
  66. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  67. package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -2
  68. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  69. package/dist/api/index.d.ts +0 -2
  70. package/dist/api/index.d.ts.map +1 -1
  71. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  72. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  73. package/dist/core/deviceEventRegistration.d.ts +0 -2
  74. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  75. package/dist/core/index.d.ts.map +1 -1
  76. package/dist/data-manager/DataManager.d.ts +2 -4
  77. package/dist/data-manager/DataManager.d.ts.map +1 -1
  78. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  79. package/dist/device/Device.d.ts +6 -29
  80. package/dist/device/Device.d.ts.map +1 -1
  81. package/dist/device/DeviceCommands.d.ts +4 -4
  82. package/dist/device/DevicePool.d.ts.map +1 -1
  83. package/dist/events/device.d.ts +0 -4
  84. package/dist/events/device.d.ts.map +1 -1
  85. package/dist/events/logBlockEvent.d.ts.map +1 -1
  86. package/dist/events/ui-promise.d.ts +2 -4
  87. package/dist/events/ui-promise.d.ts.map +1 -1
  88. package/dist/events/ui-request.d.ts +2 -31
  89. package/dist/events/ui-request.d.ts.map +1 -1
  90. package/dist/events/ui-response.d.ts +2 -10
  91. package/dist/events/ui-response.d.ts.map +1 -1
  92. package/dist/index.d.ts +230 -203
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +3469 -2419
  95. package/dist/inject.d.ts +1 -6
  96. package/dist/inject.d.ts.map +1 -1
  97. package/dist/lowLevelInject.d.ts.map +1 -1
  98. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  99. package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
  100. package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
  101. package/dist/protocols/protocol-v2/uiInteraction.d.ts +4 -7
  102. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  103. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
  104. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  105. package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
  106. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
  107. package/dist/protocols/protocol-v2/walletSession.d.ts +1 -4
  108. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  109. package/dist/topLevelInject.d.ts.map +1 -1
  110. package/dist/types/api/checkAllFirmwareRelease.d.ts +4 -1
  111. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  112. package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
  113. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  114. package/dist/types/api/export.d.ts +4 -1
  115. package/dist/types/api/export.d.ts.map +1 -1
  116. package/dist/types/api/firmwareUpdate.d.ts +70 -2
  117. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  118. package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
  119. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
  120. package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
  121. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
  122. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
  123. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
  124. package/dist/types/api/index.d.ts +10 -7
  125. package/dist/types/api/index.d.ts.map +1 -1
  126. package/dist/types/api/protocolV2.d.ts +0 -3
  127. package/dist/types/api/protocolV2.d.ts.map +1 -1
  128. package/dist/types/params.d.ts +0 -1
  129. package/dist/types/params.d.ts.map +1 -1
  130. package/dist/types/settings.d.ts +13 -22
  131. package/dist/types/settings.d.ts.map +1 -1
  132. package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
  133. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  134. package/dist/utils/deviceFeaturesUtils.d.ts +0 -2
  135. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  136. package/dist/utils/homescreen.d.ts +0 -4
  137. package/dist/utils/homescreen.d.ts.map +1 -1
  138. package/dist/utils/index.d.ts +1 -1
  139. package/dist/utils/index.d.ts.map +1 -1
  140. package/dist/utils/patch.d.ts +1 -1
  141. package/dist/utils/patch.d.ts.map +1 -1
  142. package/dist/utils/pro2Wallpaper.d.ts +0 -10
  143. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  144. package/package.json +4 -4
  145. package/src/api/BaseMethod.ts +10 -8
  146. package/src/api/CheckAllFirmwareRelease.ts +53 -41
  147. package/src/api/FirmwareUpdate.ts +15 -7
  148. package/src/api/FirmwareUpdateV2.ts +316 -126
  149. package/src/api/FirmwareUpdateV3.ts +265 -63
  150. package/src/api/FirmwareUpdateV4.ts +937 -430
  151. package/src/api/GetPassphraseState.ts +1 -7
  152. package/src/api/OpenWalletSession.ts +17 -54
  153. package/src/api/SearchDevices.ts +1 -3
  154. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -32
  155. package/src/api/device/DeviceUnlock.ts +1 -1
  156. package/src/api/device/DeviceUpdateBootloader.ts +122 -6
  157. package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
  158. package/src/api/firmware/FirmwareHostBinding.ts +100 -0
  159. package/src/api/firmware/FirmwarePreparationError.ts +12 -0
  160. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -16
  161. package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
  162. package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
  163. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +415 -0
  164. package/src/api/firmware/progressThrottle.ts +44 -0
  165. package/src/api/firmware/updateBootloader.ts +19 -4
  166. package/src/api/firmware/uploadFirmware.ts +144 -39
  167. package/src/api/helpers/protocolV2FileWrite.ts +4 -11
  168. package/src/api/index.ts +0 -2
  169. package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
  170. package/src/core/deviceEventRegistration.ts +0 -4
  171. package/src/core/index.ts +83 -167
  172. package/src/data/messages/messages-protocol-v2.json +0 -25
  173. package/src/data-manager/DataManager.ts +38 -67
  174. package/src/data-manager/connectSettings.ts +11 -0
  175. package/src/device/Device.ts +42 -257
  176. package/src/device/DevicePool.ts +2 -7
  177. package/src/events/device.ts +0 -4
  178. package/src/events/logBlockEvent.ts +0 -1
  179. package/src/events/ui-promise.ts +2 -4
  180. package/src/events/ui-request.ts +2 -36
  181. package/src/events/ui-response.ts +2 -12
  182. package/src/index.ts +5 -0
  183. package/src/inject.ts +24 -60
  184. package/src/lowLevelInject.ts +8 -7
  185. package/src/protocols/protocol-v2/features.ts +2 -9
  186. package/src/protocols/protocol-v2/lockedError.ts +10 -0
  187. package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
  188. package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
  189. package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
  190. package/src/protocols/protocol-v2/walletSession.ts +30 -169
  191. package/src/topLevelInject.ts +8 -7
  192. package/src/types/api/checkAllFirmwareRelease.ts +4 -1
  193. package/src/types/api/deviceUpdateBootloader.ts +6 -0
  194. package/src/types/api/export.ts +18 -0
  195. package/src/types/api/firmwareUpdate.ts +76 -3
  196. package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
  197. package/src/types/api/firmwareUpdatePlan.ts +38 -0
  198. package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
  199. package/src/types/api/index.ts +14 -13
  200. package/src/types/api/protocolV2.ts +0 -13
  201. package/src/types/params.ts +1 -7
  202. package/src/types/settings.ts +13 -42
  203. package/src/utils/deviceFeaturesCompat.ts +6 -0
  204. package/src/utils/deviceFeaturesUtils.ts +0 -4
  205. package/src/utils/homescreen.ts +6 -32
  206. package/src/utils/index.ts +1 -6
  207. package/src/utils/pro2Wallpaper.ts +8 -35
  208. package/__tests__/deviceUploadNft.test.ts +0 -293
  209. package/__tests__/pro2Nft.test.ts +0 -108
  210. package/__tests__/protocol-binding.test.ts +0 -89
  211. package/__tests__/protocol-v2-resources.test.ts +0 -284
  212. package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
  213. package/__tests__/uiProgressThrottle.test.ts +0 -74
  214. package/__tests__/uiPromiseRegistry.test.ts +0 -86
  215. package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
  216. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
  217. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
  218. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
  219. package/dist/core/uiPromiseRegistry.d.ts +0 -4
  220. package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
  221. package/dist/protocols/protocol-v2/resources.d.ts +0 -30
  222. package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
  223. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
  224. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
  225. package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
  226. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
  227. package/dist/utils/pro2Nft.d.ts +0 -31
  228. package/dist/utils/pro2Nft.d.ts.map +0 -1
  229. package/dist/utils/uiProgressThrottle.d.ts +0 -3
  230. package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
  231. package/src/api/DetectDeviceConnectProtocol.ts +0 -18
  232. package/src/api/protocol-v2/DeviceUploadNft.ts +0 -189
  233. package/src/core/uiPromiseRegistry.ts +0 -41
  234. package/src/protocols/protocol-v2/resources.ts +0 -359
  235. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -124
  236. package/src/types/api/detectDeviceConnectProtocol.ts +0 -7
  237. package/src/utils/pro2Nft.ts +0 -142
  238. package/src/utils/uiProgressThrottle.ts +0 -63
@@ -18,83 +18,6 @@ class TestAllNetworkMethod extends AllNetworkGetAddressBase {
18
18
  }
19
19
 
20
20
  describe('AllNetworkGetAddressBase tracing', () => {
21
- test('resumes a Protocol V2 hidden wallet before running a nested chain method', async () => {
22
- const calls: string[] = [];
23
- const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
24
- calls.push('resume-hidden-session');
25
- return Promise.resolve(true);
26
- });
27
- const innerMethod = {
28
- checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
29
- connectId: 'connect-id',
30
- deviceId: 'device-id',
31
- getVersionRange: jest.fn().mockReturnValue({}),
32
- assertProtocolSupported: jest.fn(),
33
- init: jest.fn(),
34
- name: 'evmGetAddress',
35
- responseID: 43,
36
- unlockPolicy: 'unlock-before-run',
37
- run: jest.fn().mockImplementation(() => {
38
- calls.push('run-chain-method');
39
- return Promise.resolve([{ address: '0xhidden' }]);
40
- }),
41
- setDevice: jest.fn(),
42
- strictCheckDeviceSupport: false,
43
- };
44
- (findMethod as jest.Mock).mockReturnValue(innerMethod);
45
- const method = new TestAllNetworkMethod({
46
- id: 1,
47
- payload: {
48
- method: 'allNetworkGetAddress',
49
- connectId: 'connect-id',
50
- deviceId: 'device-id',
51
- passphraseState: 'hidden-state',
52
- bundle: [],
53
- },
54
- });
55
- method.protocolV2UnlockContext = { preflightCompleted: true };
56
- const typedCall = jest.fn();
57
- method.device = {
58
- checkPassphraseStateSafety,
59
- commands: {
60
- typedCall,
61
- },
62
- getCurrentFirmwareType: jest.fn(),
63
- getProtocol: jest.fn().mockReturnValue('V2'),
64
- getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
65
- getCurrentMethodVersionRange: jest
66
- .fn()
67
- .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
68
- instanceId: 'device-instance',
69
- isProtocolV2: jest.fn().mockReturnValue(true),
70
- isBootloader: jest.fn().mockReturnValue(false),
71
- isRomloader: jest.fn().mockReturnValue(false),
72
- off: jest.fn(),
73
- on: jest.fn(),
74
- state: { status: { unlocked: true } },
75
- updateProtocolV2Status: jest.fn(),
76
- } as any;
77
-
78
- await method.callMethod(
79
- 'evmGetAddress',
80
- {
81
- bundle: [
82
- {
83
- _originRequestParams: {
84
- network: 'evm',
85
- path: "m/44'/60'/0'/0/0",
86
- },
87
- },
88
- ],
89
- },
90
- 0
91
- );
92
-
93
- expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined);
94
- expect(calls).toEqual(['resume-hidden-session', 'run-chain-method']);
95
- expect(typedCall).not.toHaveBeenCalled();
96
- });
97
-
98
21
  test('releases the nested request context when an unhandled error escapes', async () => {
99
22
  const deviceInstanceId = 'device-instance';
100
23
  const innerMethod = {
@@ -128,7 +51,6 @@ describe('AllNetworkGetAddressBase tracing', () => {
128
51
  getCurrentMethodVersionRange: jest
129
52
  .fn()
130
53
  .mockImplementation((getRange: (type: string) => unknown) => getRange('classic')),
131
- isProtocolV2: jest.fn().mockReturnValue(false),
132
54
  off: jest.fn(),
133
55
  on: jest.fn(),
134
56
  } as any;
@@ -3,8 +3,6 @@ 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(),
8
6
  button: jest.fn(),
9
7
  passphrase: jest.fn(),
10
8
  passphraseOnDevice: jest.fn(),
@@ -23,8 +21,6 @@ describe('hardware UI event registration', () => {
23
21
  expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(true);
24
22
  expect(device.on.mock.calls.map(([type]) => type)).toEqual([
25
23
  DEVICE.PIN,
26
- DEVICE.PIN_ON_DEVICE,
27
- DEVICE.PIN_ON_DEVICE_COMPLETE,
28
24
  DEVICE.BUTTON,
29
25
  DEVICE.PASSPHRASE,
30
26
  DEVICE.PASSPHRASE_ON_DEVICE,
@@ -38,8 +34,6 @@ describe('hardware UI event registration', () => {
38
34
  expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(true);
39
35
  expect(device.on.mock.calls.map(([type]) => type)).toEqual([
40
36
  DEVICE.PIN,
41
- DEVICE.PIN_ON_DEVICE,
42
- DEVICE.PIN_ON_DEVICE_COMPLETE,
43
37
  DEVICE.BUTTON,
44
38
  DEVICE.PASSPHRASE,
45
39
  DEVICE.PASSPHRASE_ON_DEVICE,
@@ -5,7 +5,6 @@ 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';
9
8
 
10
9
  import type { CoreApi } from '../src/types/api';
11
10
  import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
@@ -73,74 +72,7 @@ const release: IFirmwareReleaseInfo = {
73
72
  ],
74
73
  };
75
74
 
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
-
139
75
  describe('checkAllFirmwareRelease Protocol V2 support', () => {
140
- afterEach(() => {
141
- jest.restoreAllMocks();
142
- });
143
-
144
76
  test('builds ordered firmwareUpdateV4 targets from recommended component versions', () => {
145
77
  const result = buildProtocolV2FirmwareRelease({
146
78
  currentVersions,
@@ -152,7 +84,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
152
84
  status: 'required',
153
85
  hasUpgrade: true,
154
86
  required: true,
155
- targetsToUpdate: ['boot', 'app_v1'],
87
+ targetsToUpdate: ['boot', 'app_v1', 'resource'],
156
88
  components: [
157
89
  { configKey: 'bootloader', status: 'outdated', updateTarget: 'boot' },
158
90
  { configKey: 'applicationP1', status: 'outdated', updateTarget: 'app_v1' },
@@ -291,7 +223,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
291
223
  expect(result.targetsToUpdate).toEqual(['app_v1', 'app_v2']);
292
224
  });
293
225
 
294
- test('does not read vol0 resource inventory while Protocol V2 is in Application mode', async () => {
226
+ test('uses the existing method on Protocol V2 and keeps its public API name', async () => {
295
227
  const method = new CheckAllFirmwareRelease({
296
228
  id: 1,
297
229
  payload: {
@@ -308,7 +240,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
308
240
  status: { mode: 'normal' },
309
241
  versions: currentVersions,
310
242
  });
311
- const typedCall = createFilesystemTypedCall(true);
312
243
  method.device = {
313
244
  isProtocolV2: () => true,
314
245
  features: {
@@ -316,60 +247,21 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
316
247
  firmwareVersion: '1.0.0',
317
248
  },
318
249
  getDeviceState,
319
- getCommands: () => ({ typedCall }),
320
250
  } as unknown as CheckAllFirmwareRelease['device'];
321
251
  jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
322
- jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
323
252
 
324
253
  await expect(method.run()).resolves.toMatchObject({
325
254
  protocol: 'V2',
326
255
  deviceType: 'pro2',
327
256
  status: 'required',
328
- resourceStatus: 'unknown',
329
- targetsToUpdate: ['boot', 'app_v1'],
257
+ targetsToUpdate: ['boot', 'app_v1', 'resource'],
330
258
  firmware: {
331
259
  status: 'required',
332
260
  },
333
261
  });
334
- expect(typedCall).not.toHaveBeenCalled();
335
262
  expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
336
263
  });
337
264
 
338
- test.each(['bootloader', 'romloader'] as const)(
339
- 'uses filesystem inventory in %s mode instead of forcing all resources',
340
- async mode => {
341
- const method = new CheckAllFirmwareRelease({
342
- id: 1,
343
- payload: {
344
- method: 'checkAllFirmwareRelease',
345
- firmwareType: EFirmwareType.Universal,
346
- },
347
- });
348
- method.init();
349
- const typedCall = createFilesystemTypedCall();
350
- method.device = {
351
- isProtocolV2: () => true,
352
- features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
353
- getDeviceState: jest.fn().mockResolvedValue({
354
- identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
355
- status: { mode },
356
- versions: currentVersions,
357
- }),
358
- getCommands: () => ({ typedCall }),
359
- } as unknown as CheckAllFirmwareRelease['device'];
360
- jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
361
- jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
362
-
363
- await expect(method.run()).resolves.toMatchObject({
364
- protocol: 'V2',
365
- resourceStatus: 'valid',
366
- targetsToUpdate: ['boot', 'app_v1'],
367
- });
368
- expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
369
- expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
370
- }
371
- );
372
-
373
265
  test('continues forwarding the existing public method', async () => {
374
266
  const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
375
267
  const api = createCoreApi(call as CoreApi['call']) as CoreApi;
@@ -1,19 +1,61 @@
1
+ import DataManager from '../src/data-manager/DataManager';
1
2
  import { parseConnectSettings } from '../src/data-manager/connectSettings';
2
3
 
4
+ import type { RemoteConfigResponse } from '../src/types';
5
+
6
+ jest.mock('axios', () => ({
7
+ get: jest.fn(),
8
+ }));
9
+
3
10
  jest.mock('../src/data/config', () => ({
4
11
  getSDKVersion: jest.fn(() => '1.0.0'),
5
12
  DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
6
13
  }));
7
14
 
15
+ const mockAxiosGet: jest.Mock = jest.requireMock('axios').get;
16
+
8
17
  describe('parseConnectSettings', () => {
9
- it('keeps custom configFetcher in parsed settings', () => {
10
- const configFetcher = jest.fn();
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
+ });
11
50
 
51
+ it('fails closed without a preloaded config in external-only mode', async () => {
12
52
  const settings = parseConnectSettings({
13
- fetchConfig: true,
14
- configFetcher,
53
+ firmwareManifestMode: 'external-only',
15
54
  });
16
55
 
17
- expect(settings.configFetcher).toBe(configFetcher);
56
+ await expect(DataManager.load(settings)).rejects.toThrow(
57
+ 'External firmware config snapshot is required'
58
+ );
59
+ expect(mockAxiosGet).not.toHaveBeenCalled();
18
60
  });
19
61
  });
@@ -0,0 +1,56 @@
1
+ import { Device } from '../src/device/Device';
2
+ import TransportManager from '../src/data-manager/TransportManager';
3
+
4
+ jest.mock('../src/data/config', () => ({
5
+ getSDKVersion: jest.fn(() => '1.0.0'),
6
+ DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
7
+ }));
8
+
9
+ function buildV1Device() {
10
+ const device = Object.create(Device.prototype) as Device;
11
+ const typedCall = jest.fn(() => Promise.resolve({ message: { device_id: 'device' } }));
12
+ Object.assign(device, {
13
+ commands: { typedCall },
14
+ stateStore: { getState: () => undefined },
15
+ isProtocolV2: () => false,
16
+ _updateFeatures: jest.fn(),
17
+ getInternalState: jest.fn(() => undefined),
18
+ });
19
+ return { device, typedCall };
20
+ }
21
+
22
+ describe('Device.initialize Protocol V1 timeout', () => {
23
+ beforeEach(() => {
24
+ jest.spyOn(TransportManager, 'reconfigure').mockResolvedValue(undefined);
25
+ });
26
+
27
+ afterEach(() => {
28
+ jest.restoreAllMocks();
29
+ });
30
+
31
+ test('passes a custom Initialize timeout through to typedCall', async () => {
32
+ const { device, typedCall } = buildV1Device();
33
+
34
+ await device.initialize({ timeoutMs: 2500 });
35
+
36
+ expect(typedCall).toHaveBeenCalledWith(
37
+ 'Initialize',
38
+ 'Features',
39
+ expect.objectContaining({ is_contains_attach: true }),
40
+ { timeoutMs: 2500 }
41
+ );
42
+ });
43
+
44
+ test('keeps the 25s Initialize timeout by default', async () => {
45
+ const { device, typedCall } = buildV1Device();
46
+
47
+ await device.initialize();
48
+
49
+ expect(typedCall).toHaveBeenCalledWith(
50
+ 'Initialize',
51
+ 'Features',
52
+ expect.objectContaining({ is_contains_attach: true }),
53
+ { timeoutMs: 25 * 1000 }
54
+ );
55
+ });
56
+ });
@@ -1,4 +1,3 @@
1
- import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
1
  import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
3
2
 
4
3
  import { initConnector, initCore } from '../src/core';
@@ -96,25 +95,7 @@ describe('public device lifecycle events', () => {
96
95
  expect(messages.filter(message => message.type === DEVICE.DISCONNECT)).toHaveLength(1);
97
96
  });
98
97
 
99
- test('uses a verified cached protocol as a strict expected protocol', async () => {
100
- jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
101
- const device = Device.fromDescriptor({
102
- id: 'ble-id',
103
- path: 'ble-id',
104
- commType: 'ble',
105
- protocolType: 'V1',
106
- } as never);
107
- const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V1' });
108
- device.deviceConnector = { acquire } as never;
109
-
110
- await device.acquire();
111
-
112
- expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, 'V1', undefined);
113
- expect(device.getProtocol()).toBe('V1');
114
- expect(device.originalDescriptor.protocolType).toBe('V1');
115
- });
116
-
117
- test('bypasses a cached protocol only for explicit active detection', async () => {
98
+ test('uses a cached protocol as a fallback-capable acquire hint', async () => {
118
99
  jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
119
100
  const device = Device.fromDescriptor({
120
101
  id: 'ble-id',
@@ -125,96 +106,13 @@ describe('public device lifecycle events', () => {
125
106
  const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V2' });
126
107
  device.deviceConnector = { acquire } as never;
127
108
 
128
- await device.acquire(undefined, { forceProtocolDetection: true });
109
+ await device.acquire();
129
110
 
130
- expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined, undefined);
111
+ expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined, 'V1');
131
112
  expect(device.getProtocol()).toBe('V2');
132
113
  expect(device.originalDescriptor.protocolType).toBe('V2');
133
114
  });
134
115
 
135
- test('does not reuse a stale protocol when active detection returns no protocol', async () => {
136
- jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
137
- const device = Device.fromDescriptor({
138
- id: 'ble-id',
139
- path: 'ble-id',
140
- commType: 'ble',
141
- protocolType: 'V1',
142
- } as never);
143
- const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id' });
144
- const release = jest.fn().mockResolvedValue(undefined);
145
- device.deviceConnector = { acquire, release } as never;
146
- await expect(
147
- device.acquire(undefined, {
148
- forceProtocolDetection: true,
149
- throwOnRunPromiseError: true,
150
- })
151
- ).rejects.toMatchObject({ errorCode: HardwareErrorCode.RuntimeError });
152
- expect(device.originalDescriptor.protocolType).toBe('V1');
153
- expect(device.hasDeviceAcquire()).toBe(false);
154
- expect(release).toHaveBeenCalledWith('ble-id', false);
155
- });
156
-
157
- test('actively reacquires an already connected device without initializing it', async () => {
158
- jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
159
- const device = Device.fromDescriptor({
160
- id: 'usb-device',
161
- path: 'usb-device',
162
- session: 'old-session',
163
- protocolType: 'V1',
164
- } as never);
165
- device.mainId = 'old-session';
166
- device.commands = { disposed: false } as never;
167
- const release = jest.spyOn(device, 'release').mockImplementation(() => {
168
- device.mainId = null;
169
- device.originalDescriptor.session = null;
170
- device.commands.disposed = true;
171
- return Promise.resolve();
172
- });
173
- const acquire = jest.spyOn(device, 'acquire').mockImplementation(() => {
174
- device.mainId = 'new-session';
175
- device.originalDescriptor.session = 'new-session';
176
- device.originalDescriptor.protocolType = 'V2';
177
- device.commands.disposed = false;
178
- return Promise.resolve();
179
- });
180
- const initialize = jest.spyOn(device, 'initialize').mockResolvedValue(undefined);
181
-
182
- await device.run(() => Promise.resolve(undefined), {
183
- forceProtocolDetection: true,
184
- skipInitialize: true,
185
- });
186
-
187
- expect(release).toHaveBeenCalled();
188
- expect(acquire).toHaveBeenCalledWith(undefined, {
189
- forceProtocolDetection: true,
190
- });
191
- expect(initialize).not.toHaveBeenCalled();
192
- expect(device.getProtocol()).toBe('V2');
193
- });
194
-
195
- test('keeps the freshly probed React Native BLE session until the call completes', async () => {
196
- jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
197
- const device = Device.fromDescriptor({
198
- id: 'ble-device',
199
- path: 'ble-device',
200
- commType: 'ble',
201
- protocolType: 'V1',
202
- } as never);
203
- device.mainId = 'ble-device';
204
- device.commands = { disposed: false } as never;
205
- (device as unknown as { deviceAcquired: boolean }).deviceAcquired = true;
206
- const release = jest.spyOn(device, 'release').mockResolvedValue(undefined);
207
- const run = jest.fn().mockResolvedValue(undefined);
208
-
209
- await device.run(run, {
210
- forceProtocolDetection: true,
211
- skipInitialize: true,
212
- });
213
-
214
- expect(run).toHaveBeenCalledTimes(1);
215
- expect(release).toHaveBeenCalledTimes(1);
216
- });
217
-
218
116
  test('keeps an explicit connectProtocol as a strict expected protocol', async () => {
219
117
  jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
220
118
  const device = Device.fromDescriptor({