@onekeyfe/hd-core 1.2.0-alpha.67 → 1.2.0-alpha.68

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 (254) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +313 -0
  2. package/__tests__/DeviceCommands.test.ts +59 -13
  3. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +198 -3
  5. package/__tests__/core-initialization.test.ts +23 -0
  6. package/__tests__/device-connector-protocol.test.ts +81 -0
  7. package/__tests__/device-lifecycle-events.test.ts +105 -3
  8. package/__tests__/device-pool-state.test.ts +22 -0
  9. package/__tests__/device-settings.test.ts +39 -18
  10. package/__tests__/device-state-contract.test.ts +1 -0
  11. package/__tests__/device-state-mapper.test.ts +13 -1
  12. package/__tests__/device-utils.test.ts +48 -1
  13. package/__tests__/deviceSettings.test.ts +11 -1
  14. package/__tests__/deviceUploadNft.test.ts +316 -0
  15. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +5 -0
  16. package/__tests__/get-device-state.test.ts +132 -12
  17. package/__tests__/homescreen.test.ts +41 -1
  18. package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
  19. package/__tests__/kaspaSignTransaction.test.ts +3 -26
  20. package/__tests__/logBlockEvent.test.ts +1 -1
  21. package/__tests__/method-protocol-support.test.ts +19 -0
  22. package/__tests__/open-wallet-session.test.ts +568 -37
  23. package/__tests__/pro2Nft.test.ts +108 -0
  24. package/__tests__/protocol-binding.test.ts +89 -0
  25. package/__tests__/protocol-v2-resources.test.ts +340 -0
  26. package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
  27. package/__tests__/protocol-v2-unlock-policy.test.ts +300 -37
  28. package/__tests__/protocol-v2.test.ts +1449 -867
  29. package/__tests__/protocolV2FileWrite.test.ts +152 -0
  30. package/__tests__/protocolV2UiInteraction.test.ts +63 -0
  31. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  32. package/__tests__/search-devices.test.ts +12 -3
  33. package/__tests__/tron-sign-message-init.test.ts +2 -2
  34. package/__tests__/uiProgressThrottle.test.ts +74 -0
  35. package/__tests__/uiPromiseRegistry.test.ts +115 -0
  36. package/dist/api/BaseMethod.d.ts +3 -1
  37. package/dist/api/BaseMethod.d.ts.map +1 -1
  38. package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
  39. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  40. package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
  41. package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
  42. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  43. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  44. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  45. package/dist/api/FirmwareUpdateV4.d.ts +11 -4
  46. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  47. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  48. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  49. package/dist/api/SearchDevices.d.ts.map +1 -1
  50. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  51. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  52. package/dist/api/device/DeviceUnlock.d.ts +2 -2
  53. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  54. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -3
  55. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  56. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  57. package/dist/api/helpers/protocolV2FileWrite.d.ts +9 -0
  58. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  59. package/dist/api/index.d.ts +2 -0
  60. package/dist/api/index.d.ts.map +1 -1
  61. package/dist/api/kaspa/KaspaGetAddress.d.ts +1 -1
  62. package/dist/api/kaspa/KaspaSignTransaction.d.ts +1 -1
  63. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  64. package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -1
  65. package/dist/api/polkadot/networks.d.ts +1 -1
  66. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
  67. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  68. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  69. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  70. package/dist/api/solana/SolSignMessage.d.ts +1 -1
  71. package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -1
  72. package/dist/api/solana/SolSignTransaction.d.ts +2 -2
  73. package/dist/api/sui/SuiGetAddress.d.ts +1 -1
  74. package/dist/api/sui/SuiGetPublicKey.d.ts +1 -1
  75. package/dist/api/sui/SuiSignMessage.d.ts +1 -1
  76. package/dist/api/sui/SuiSignTransaction.d.ts +1 -1
  77. package/dist/api/ton/TonGetAddress.d.ts +1 -1
  78. package/dist/api/ton/TonSignMessage.d.ts +1 -1
  79. package/dist/api/ton/TonSignProof.d.ts +1 -1
  80. package/dist/api/tron/TronSignMessage.d.ts +2 -2
  81. package/dist/api/tron/TronSignTransaction.d.ts +1 -1
  82. package/dist/core/deviceEventRegistration.d.ts +2 -0
  83. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  84. package/dist/core/index.d.ts.map +1 -1
  85. package/dist/core/uiPromiseRegistry.d.ts +6 -0
  86. package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
  87. package/dist/data-manager/DataManager.d.ts +9 -3
  88. package/dist/data-manager/DataManager.d.ts.map +1 -1
  89. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  90. package/dist/device/Device.d.ts +29 -5
  91. package/dist/device/Device.d.ts.map +1 -1
  92. package/dist/device/DeviceCommands.d.ts +4 -4
  93. package/dist/device/DeviceCommands.d.ts.map +1 -1
  94. package/dist/device/DeviceConnector.d.ts +2 -1
  95. package/dist/device/DeviceConnector.d.ts.map +1 -1
  96. package/dist/device/DevicePool.d.ts.map +1 -1
  97. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -1
  98. package/dist/events/device.d.ts +4 -0
  99. package/dist/events/device.d.ts.map +1 -1
  100. package/dist/events/logBlockEvent.d.ts.map +1 -1
  101. package/dist/events/ui-promise.d.ts +4 -2
  102. package/dist/events/ui-promise.d.ts.map +1 -1
  103. package/dist/events/ui-request.d.ts +31 -2
  104. package/dist/events/ui-request.d.ts.map +1 -1
  105. package/dist/events/ui-response.d.ts +10 -2
  106. package/dist/events/ui-response.d.ts.map +1 -1
  107. package/dist/index.d.ts +243 -69
  108. package/dist/index.js +2563 -1217
  109. package/dist/inject.d.ts +6 -1
  110. package/dist/inject.d.ts.map +1 -1
  111. package/dist/lowLevelInject.d.ts.map +1 -1
  112. package/dist/protocols/protocol-v2/features.d.ts +0 -4
  113. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  114. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  115. package/dist/protocols/protocol-v2/resources.d.ts +30 -0
  116. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
  117. package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
  118. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  119. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  120. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  121. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  122. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  123. package/dist/protocols/protocol-v2/walletSession.d.ts +6 -1
  124. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  125. package/dist/topLevelInject.d.ts.map +1 -1
  126. package/dist/types/api/checkAllFirmwareRelease.d.ts +3 -1
  127. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  128. package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
  129. package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
  130. package/dist/types/api/deviceUnlock.d.ts +5 -1
  131. package/dist/types/api/deviceUnlock.d.ts.map +1 -1
  132. package/dist/types/api/export.d.ts +1 -0
  133. package/dist/types/api/export.d.ts.map +1 -1
  134. package/dist/types/api/firmwareUpdate.d.ts +4 -2
  135. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  136. package/dist/types/api/index.d.ts +6 -1
  137. package/dist/types/api/index.d.ts.map +1 -1
  138. package/dist/types/api/protocolV2.d.ts +3 -0
  139. package/dist/types/api/protocolV2.d.ts.map +1 -1
  140. package/dist/types/device.d.ts +2 -2
  141. package/dist/types/device.d.ts.map +1 -1
  142. package/dist/types/params.d.ts +1 -0
  143. package/dist/types/params.d.ts.map +1 -1
  144. package/dist/types/settings.d.ts +38 -8
  145. package/dist/types/settings.d.ts.map +1 -1
  146. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  147. package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
  148. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  149. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  150. package/dist/utils/deviceSettings.d.ts.map +1 -1
  151. package/dist/utils/homescreen.d.ts +4 -0
  152. package/dist/utils/homescreen.d.ts.map +1 -1
  153. package/dist/utils/index.d.ts +1 -1
  154. package/dist/utils/index.d.ts.map +1 -1
  155. package/dist/utils/patch.d.ts +1 -1
  156. package/dist/utils/patch.d.ts.map +1 -1
  157. package/dist/utils/pro2Nft.d.ts +31 -0
  158. package/dist/utils/pro2Nft.d.ts.map +1 -0
  159. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  160. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  161. package/dist/utils/uiProgressThrottle.d.ts +3 -0
  162. package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
  163. package/package.json +4 -4
  164. package/src/api/BaseMethod.ts +8 -10
  165. package/src/api/CheckAllFirmwareRelease.ts +61 -11
  166. package/src/api/DetectDeviceConnectProtocol.ts +18 -0
  167. package/src/api/FirmwareUpdate.ts +6 -2
  168. package/src/api/FirmwareUpdateV2.ts +5 -2
  169. package/src/api/FirmwareUpdateV3.ts +6 -2
  170. package/src/api/FirmwareUpdateV4.ts +463 -258
  171. package/src/api/GetPassphraseState.ts +7 -1
  172. package/src/api/OpenWalletSession.ts +71 -17
  173. package/src/api/SearchDevices.ts +3 -1
  174. package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
  175. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +36 -11
  176. package/src/api/device/DeviceSettings.ts +5 -4
  177. package/src/api/device/DeviceUnlock.ts +8 -3
  178. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +27 -12
  179. package/src/api/firmware/uploadFirmware.ts +17 -4
  180. package/src/api/helpers/protocolV2FileWrite.ts +202 -63
  181. package/src/api/index.ts +2 -0
  182. package/src/api/kaspa/KaspaGetAddress.ts +1 -1
  183. package/src/api/kaspa/KaspaSignTransaction.ts +2 -13
  184. package/src/api/polkadot/networks.ts +3 -3
  185. package/src/api/protocol-v2/DeviceUploadNft.ts +197 -0
  186. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  187. package/src/api/protocol-v2/helpers.ts +1 -1
  188. package/src/api/solana/SolSignMessage.ts +1 -1
  189. package/src/api/solana/SolSignOffchainMessage.ts +1 -1
  190. package/src/api/solana/SolSignTransaction.ts +2 -2
  191. package/src/api/sui/SuiGetAddress.ts +1 -1
  192. package/src/api/sui/SuiGetPublicKey.ts +1 -1
  193. package/src/api/sui/SuiSignMessage.ts +1 -1
  194. package/src/api/sui/SuiSignTransaction.ts +1 -1
  195. package/src/api/ton/TonGetAddress.ts +1 -1
  196. package/src/api/ton/TonSignMessage.ts +1 -1
  197. package/src/api/ton/TonSignProof.ts +1 -1
  198. package/src/api/tron/TronSignMessage.ts +2 -2
  199. package/src/api/tron/TronSignTransaction.ts +1 -1
  200. package/src/core/deviceEventRegistration.ts +4 -0
  201. package/src/core/index.ts +213 -111
  202. package/src/core/uiPromiseRegistry.ts +63 -0
  203. package/src/data/messages/messages-protocol-v2.json +25 -0
  204. package/src/data-manager/DataManager.ts +88 -11
  205. package/src/data-manager/TransportManager.ts +6 -0
  206. package/src/device/Device.ts +273 -43
  207. package/src/device/DeviceCommands.ts +31 -4
  208. package/src/device/DeviceConnector.ts +33 -13
  209. package/src/device/DevicePool.ts +21 -7
  210. package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
  211. package/src/deviceProfile/protocolV2DeviceIdentity.ts +3 -0
  212. package/src/events/device.ts +4 -0
  213. package/src/events/logBlockEvent.ts +1 -0
  214. package/src/events/ui-promise.ts +4 -2
  215. package/src/events/ui-request.ts +36 -2
  216. package/src/events/ui-response.ts +12 -2
  217. package/src/inject.ts +58 -2
  218. package/src/lowLevelInject.ts +6 -3
  219. package/src/protocols/protocol-v2/features.ts +10 -7
  220. package/src/protocols/protocol-v2/firmware.ts +2 -0
  221. package/src/protocols/protocol-v2/resources.ts +390 -0
  222. package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
  223. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  224. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +131 -0
  225. package/src/protocols/protocol-v2/walletSession.ts +214 -36
  226. package/src/topLevelInject.ts +6 -3
  227. package/src/types/api/checkAllFirmwareRelease.ts +3 -1
  228. package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
  229. package/src/types/api/deviceUnlock.ts +12 -1
  230. package/src/types/api/export.ts +1 -0
  231. package/src/types/api/firmwareUpdate.ts +6 -3
  232. package/src/types/api/index.ts +13 -0
  233. package/src/types/api/protocolV2.ts +13 -0
  234. package/src/types/device.ts +15 -3
  235. package/src/types/params.ts +7 -1
  236. package/src/types/settings.ts +60 -9
  237. package/src/utils/deviceFeaturesCompat.ts +5 -0
  238. package/src/utils/deviceFeaturesUtils.ts +14 -3
  239. package/src/utils/deviceInfoUtils.ts +2 -0
  240. package/src/utils/deviceSettings.ts +3 -0
  241. package/src/utils/homescreen.ts +32 -6
  242. package/src/utils/index.ts +6 -1
  243. package/src/utils/pro2Nft.ts +142 -0
  244. package/src/utils/pro2Wallpaper.ts +35 -8
  245. package/src/utils/uiProgressThrottle.ts +63 -0
  246. package/dist/api/firmware/progressThrottle.d.ts +0 -3
  247. package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
  248. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  249. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  250. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  251. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  252. package/src/api/firmware/progressThrottle.ts +0 -44
  253. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  254. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
@@ -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,317 @@ 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(
95
+ 'hidden-state',
96
+ false,
97
+ undefined,
98
+ false
99
+ );
100
+ expect(calls).toEqual(['resume-hidden-session', 'run-chain-method']);
101
+ expect(typedCall).not.toHaveBeenCalled();
102
+ });
103
+
104
+ test('resumes a Protocol V2 Cardano hidden wallet with the Cardano seed domain', async () => {
105
+ const calls: string[] = [];
106
+ const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
107
+ calls.push('resume-cardano-session');
108
+ return Promise.resolve(true);
109
+ });
110
+ const innerMethod = {
111
+ checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
112
+ connectId: 'connect-id',
113
+ deviceId: 'device-id',
114
+ getVersionRange: jest.fn().mockReturnValue({}),
115
+ assertProtocolSupported: jest.fn(),
116
+ init: jest.fn(),
117
+ name: 'cardanoGetAddress',
118
+ responseID: 45,
119
+ unlockPolicy: 'unlock-before-run',
120
+ run: jest.fn().mockImplementation(() => {
121
+ calls.push('run-cardano-method');
122
+ return Promise.resolve([{ address: 'addr1hidden' }]);
123
+ }),
124
+ setDevice: jest.fn(),
125
+ strictCheckDeviceSupport: false,
126
+ };
127
+ (findMethod as jest.Mock).mockReturnValue(innerMethod);
128
+ const method = new TestAllNetworkMethod({
129
+ id: 5,
130
+ payload: {
131
+ method: 'allNetworkGetAddress',
132
+ connectId: 'connect-id',
133
+ deviceId: 'device-id',
134
+ passphraseState: 'hidden-state',
135
+ bundle: [],
136
+ },
137
+ });
138
+ method.protocolV2UnlockContext = { preflightCompleted: true };
139
+ const typedCall = jest.fn();
140
+ method.device = {
141
+ checkPassphraseStateSafety,
142
+ commands: {
143
+ typedCall,
144
+ },
145
+ getCurrentFirmwareType: jest.fn(),
146
+ getProtocol: jest.fn().mockReturnValue('V2'),
147
+ getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
148
+ getCurrentMethodVersionRange: jest
149
+ .fn()
150
+ .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
151
+ instanceId: 'device-instance',
152
+ isProtocolV2: jest.fn().mockReturnValue(true),
153
+ isBootloader: jest.fn().mockReturnValue(false),
154
+ isRomloader: jest.fn().mockReturnValue(false),
155
+ off: jest.fn(),
156
+ on: jest.fn(),
157
+ state: { status: { unlocked: true } },
158
+ updateProtocolV2Status: jest.fn(),
159
+ } as any;
160
+
161
+ await method.callMethod(
162
+ 'cardanoGetAddress',
163
+ {
164
+ bundle: [
165
+ {
166
+ _originRequestParams: {
167
+ network: 'ada',
168
+ path: "m/1852'/1815'/0'/0/0",
169
+ },
170
+ },
171
+ ],
172
+ },
173
+ 0
174
+ );
175
+
176
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined, true);
177
+ expect(calls).toEqual(['resume-cardano-session', 'run-cardano-method']);
178
+ expect(typedCall).not.toHaveBeenCalled();
179
+ });
180
+
181
+ test('resumes a Protocol V2 standard wallet before running a nested chain method', async () => {
182
+ const calls: string[] = [];
183
+ const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
184
+ calls.push('resume-standard-session');
185
+ return Promise.resolve(true);
186
+ });
187
+ const innerMethod = {
188
+ checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
189
+ connectId: 'connect-id',
190
+ deviceId: 'device-id',
191
+ getVersionRange: jest.fn().mockReturnValue({}),
192
+ assertProtocolSupported: jest.fn(),
193
+ init: jest.fn(),
194
+ name: 'evmGetAddress',
195
+ responseID: 44,
196
+ unlockPolicy: 'unlock-before-run',
197
+ run: jest.fn().mockImplementation(() => {
198
+ calls.push('run-chain-method');
199
+ return Promise.resolve([{ address: '0xstandard' }]);
200
+ }),
201
+ setDevice: jest.fn(),
202
+ strictCheckDeviceSupport: false,
203
+ };
204
+ (findMethod as jest.Mock).mockReturnValue(innerMethod);
205
+ const method = new TestAllNetworkMethod({
206
+ id: 2,
207
+ payload: {
208
+ method: 'allNetworkGetAddress',
209
+ connectId: 'connect-id',
210
+ deviceId: 'device-id',
211
+ useEmptyPassphrase: true,
212
+ bundle: [],
213
+ },
214
+ });
215
+ method.protocolV2UnlockContext = { preflightCompleted: true };
216
+ const typedCall = jest.fn();
217
+ method.device = {
218
+ checkPassphraseStateSafety,
219
+ commands: {
220
+ typedCall,
221
+ },
222
+ getCurrentFirmwareType: jest.fn(),
223
+ getProtocol: jest.fn().mockReturnValue('V2'),
224
+ getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
225
+ getCurrentMethodVersionRange: jest
226
+ .fn()
227
+ .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
228
+ instanceId: 'device-instance',
229
+ isProtocolV2: jest.fn().mockReturnValue(true),
230
+ isBootloader: jest.fn().mockReturnValue(false),
231
+ isRomloader: jest.fn().mockReturnValue(false),
232
+ off: jest.fn(),
233
+ on: jest.fn(),
234
+ state: { status: { unlocked: true } },
235
+ updateProtocolV2Status: jest.fn(),
236
+ } as any;
237
+
238
+ await method.callMethod(
239
+ 'evmGetAddress',
240
+ {
241
+ bundle: [
242
+ {
243
+ _originRequestParams: {
244
+ network: 'evm',
245
+ path: "m/44'/60'/0'/0/0",
246
+ },
247
+ },
248
+ ],
249
+ },
250
+ 0
251
+ );
252
+
253
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined, false);
254
+ expect(calls).toEqual(['resume-standard-session', 'run-chain-method']);
255
+ expect(typedCall).not.toHaveBeenCalled();
256
+ });
257
+
258
+ test('runs Protocol V2 addresses one at a time so each command receives a wallet session', async () => {
259
+ const method = new AllNetworkGetAddress({
260
+ id: 3,
261
+ payload: {
262
+ method: 'allNetworkGetAddress',
263
+ connectId: 'connect-id',
264
+ deviceId: 'device-id',
265
+ useEmptyPassphrase: true,
266
+ bundle: [
267
+ { network: 'evm', path: "m/44'/60'/0'/0/0" },
268
+ { network: 'evm', path: "m/44'/60'/0'/0/1" },
269
+ ],
270
+ },
271
+ });
272
+ method.device = {
273
+ isProtocolV2: jest.fn().mockReturnValue(true),
274
+ } as any;
275
+ method.postMessage = jest.fn();
276
+ const callMethod = jest
277
+ .fn()
278
+ .mockResolvedValueOnce([{ payload: { address: '0x1' }, success: true }])
279
+ .mockResolvedValueOnce([{ payload: { address: '0x2' }, success: true }]);
280
+ method.callMethod = callMethod;
281
+
282
+ await method.getAllNetworkAddress(7);
283
+
284
+ expect(callMethod).toHaveBeenCalledTimes(2);
285
+ expect(callMethod).toHaveBeenNthCalledWith(
286
+ 1,
287
+ 'evmGetAddress',
288
+ expect.objectContaining({ bundle: [expect.any(Object)] }),
289
+ 7
290
+ );
291
+ expect(callMethod).toHaveBeenNthCalledWith(
292
+ 2,
293
+ 'evmGetAddress',
294
+ expect.objectContaining({ bundle: [expect.any(Object)] }),
295
+ 7
296
+ );
297
+ });
298
+
299
+ test('keeps same-method address batching for Protocol V1', async () => {
300
+ const method = new AllNetworkGetAddress({
301
+ id: 4,
302
+ payload: {
303
+ method: 'allNetworkGetAddress',
304
+ connectId: 'connect-id',
305
+ deviceId: 'device-id',
306
+ useEmptyPassphrase: true,
307
+ bundle: [
308
+ { network: 'evm', path: "m/44'/60'/0'/0/0" },
309
+ { network: 'evm', path: "m/44'/60'/0'/0/1" },
310
+ ],
311
+ },
312
+ });
313
+ method.device = {
314
+ isProtocolV2: jest.fn().mockReturnValue(false),
315
+ } as any;
316
+ method.postMessage = jest.fn();
317
+ const callMethod = jest.fn().mockResolvedValue([
318
+ { payload: { address: '0x1' }, success: true },
319
+ { payload: { address: '0x2' }, success: true },
320
+ ]);
321
+ method.callMethod = callMethod;
322
+
323
+ await method.getAllNetworkAddress(7);
324
+
325
+ expect(callMethod).toHaveBeenCalledTimes(1);
326
+ expect(callMethod).toHaveBeenCalledWith(
327
+ 'evmGetAddress',
328
+ expect.objectContaining({ bundle: [expect.any(Object), expect.any(Object)] }),
329
+ 7
330
+ );
331
+ });
332
+
21
333
  test('releases the nested request context when an unhandled error escapes', async () => {
22
334
  const deviceInstanceId = 'device-instance';
23
335
  const innerMethod = {
@@ -51,6 +363,7 @@ describe('AllNetworkGetAddressBase tracing', () => {
51
363
  getCurrentMethodVersionRange: jest
52
364
  .fn()
53
365
  .mockImplementation((getRange: (type: string) => unknown) => getRange('classic')),
366
+ isProtocolV2: jest.fn().mockReturnValue(false),
54
367
  off: jest.fn(),
55
368
  on: jest.fn(),
56
369
  } 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
 
@@ -318,9 +363,9 @@ describe('DeviceCommands failure mapping', () => {
318
363
  }
319
364
  );
320
365
 
321
- it.each(['Cancelled', 'User cancelled typed data signing'])(
322
- 'maps the Protocol V2 MP engine cancellation response "%s" to ActionCancelled',
323
- async message => {
366
+ it.each(['SignTx', 'EthereumSignTypedDataOneKey', 'SolanaSignTx', 'GetAddress'] as const)(
367
+ 'does not treat domain-ambiguous Protocol V2 subcode 1 for %s as cancellation',
368
+ async callType => {
324
369
  const commands = createCommands();
325
370
 
326
371
  await expect(
@@ -330,18 +375,13 @@ describe('DeviceCommands failure mapping', () => {
330
375
  message: {
331
376
  code: 'Failure_ProcessError',
332
377
  subcode: 1,
333
- message,
378
+ message: 'Domain-specific failure',
334
379
  },
335
380
  } as any,
336
- 'SignTx'
381
+ callType
337
382
  )
338
383
  ).rejects.toMatchObject({
339
- errorCode: HardwareErrorCode.ActionCancelled,
340
- params: {
341
- failureCode: 'Failure_ProcessError',
342
- subcode: 1,
343
- firmwareMessage: message,
344
- },
384
+ errorCode: HardwareErrorCode.RuntimeError,
345
385
  });
346
386
  }
347
387
  );
@@ -356,6 +396,7 @@ describe('DeviceCommands failure mapping', () => {
356
396
  type: 'Failure',
357
397
  message: {
358
398
  code: 'Failure_ProcessError',
399
+ subcode: 1,
359
400
  message: 'Cancelled on device',
360
401
  },
361
402
  } as any,
@@ -366,7 +407,7 @@ describe('DeviceCommands failure mapping', () => {
366
407
  });
367
408
  });
368
409
 
369
- it('keeps an unrecognized Protocol V2 process subcode generic', async () => {
410
+ it('maps the DeviceError subcode 1 exception to DeviceBusy', async () => {
370
411
  const commands = createCommands();
371
412
 
372
413
  await expect(
@@ -382,7 +423,12 @@ describe('DeviceCommands failure mapping', () => {
382
423
  'DeviceSettingsPageShow'
383
424
  )
384
425
  ).rejects.toMatchObject({
385
- errorCode: HardwareErrorCode.RuntimeError,
426
+ errorCode: HardwareErrorCode.DeviceBusy,
427
+ params: {
428
+ failureCode: 'Failure_ProcessError',
429
+ subcode: 1,
430
+ firmwareMessage: 'Another process error',
431
+ },
386
432
  });
387
433
  });
388
434
 
@@ -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,