@onekeyfe/hd-core 1.2.0-alpha.33 → 1.2.0-alpha.35

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 (108) hide show
  1. package/__tests__/DeviceCommands.test.ts +84 -0
  2. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +31 -0
  3. package/__tests__/core-dispose.test.ts +3 -3
  4. package/__tests__/device-lifecycle-events.test.ts +52 -0
  5. package/__tests__/device-pool-state.test.ts +14 -2
  6. package/__tests__/device-settings.test.ts +25 -0
  7. package/__tests__/device-state-mapper.test.ts +13 -2
  8. package/__tests__/device-state-projector.test.ts +2 -2
  9. package/__tests__/device-utils.test.ts +1 -0
  10. package/__tests__/device-wallet-session-store.test.ts +137 -17
  11. package/__tests__/evmSignTransaction.test.ts +69 -0
  12. package/__tests__/get-device-state.test.ts +78 -30
  13. package/__tests__/kaspaSignTransaction.test.ts +9 -0
  14. package/__tests__/known-device-public-types.type-test.ts +3 -0
  15. package/__tests__/logBlockEvent.test.ts +89 -5
  16. package/__tests__/open-wallet-session.test.ts +499 -60
  17. package/__tests__/pro2Wallpaper.test.ts +1 -1
  18. package/__tests__/protocol-v2.test.ts +1180 -169
  19. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  20. package/dist/api/FirmwareUpdateV4.d.ts +2 -0
  21. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  22. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  23. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  24. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  25. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  26. package/dist/api/evm/protocol.d.ts +3 -0
  27. package/dist/api/evm/protocol.d.ts.map +1 -0
  28. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  29. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +1 -1
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/device/Device.d.ts +10 -4
  32. package/dist/device/Device.d.ts.map +1 -1
  33. package/dist/device/DeviceCommands.d.ts.map +1 -1
  34. package/dist/device/DeviceConnector.d.ts +1 -1
  35. package/dist/device/DeviceConnector.d.ts.map +1 -1
  36. package/dist/device/DevicePool.d.ts +1 -0
  37. package/dist/device/DevicePool.d.ts.map +1 -1
  38. package/dist/device/DeviceStateMapper.d.ts.map +1 -1
  39. package/dist/device/DeviceStateProjector.d.ts.map +1 -1
  40. package/dist/device/DeviceWalletSessionStore.d.ts +7 -0
  41. package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -1
  42. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  43. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts +7 -0
  44. package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -0
  45. package/dist/events/logBlockEvent.d.ts +2 -0
  46. package/dist/events/logBlockEvent.d.ts.map +1 -1
  47. package/dist/index.d.ts +25 -11
  48. package/dist/index.js +1037 -838
  49. package/dist/protocols/protocol-v2/features.d.ts +17 -6
  50. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  51. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  52. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  53. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +1 -0
  54. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -1
  55. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
  56. package/dist/protocols/protocol-v2/walletSession.d.ts +1 -10
  57. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  58. package/dist/types/api/protocolV2.d.ts +2 -2
  59. package/dist/types/api/protocolV2.d.ts.map +1 -1
  60. package/dist/types/device.d.ts +6 -3
  61. package/dist/types/device.d.ts.map +1 -1
  62. package/dist/types/params.d.ts.map +1 -1
  63. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  64. package/dist/utils/deviceFeaturesUtils.d.ts +0 -5
  65. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  66. package/dist/utils/patch.d.ts +1 -1
  67. package/dist/utils/patch.d.ts.map +1 -1
  68. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  69. package/package.json +4 -4
  70. package/src/api/CheckAllFirmwareRelease.ts +11 -81
  71. package/src/api/FirmwareUpdateV4.ts +59 -25
  72. package/src/api/GetPassphraseState.ts +11 -2
  73. package/src/api/OpenWalletSession.ts +16 -8
  74. package/src/api/device/DeviceSettings.ts +8 -1
  75. package/src/api/evm/EVMGetAddress.ts +2 -2
  76. package/src/api/evm/EVMGetPublicKey.ts +2 -2
  77. package/src/api/evm/EVMSignMessage.ts +2 -2
  78. package/src/api/evm/EVMSignTransaction.ts +2 -2
  79. package/src/api/evm/EVMSignTypedData.ts +35 -45
  80. package/src/api/evm/EVMVerifyMessage.ts +2 -2
  81. package/src/api/evm/protocol.ts +6 -0
  82. package/src/api/kaspa/KaspaSignTransaction.ts +7 -0
  83. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +2 -2
  84. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +1 -1
  85. package/src/core/index.ts +7 -5
  86. package/src/data/messages/messages-protocol-v2.json +393 -485
  87. package/src/device/Device.ts +98 -44
  88. package/src/device/DeviceCommands.ts +12 -2
  89. package/src/device/DeviceConnector.ts +10 -7
  90. package/src/device/DevicePool.ts +5 -3
  91. package/src/device/DeviceStateMapper.ts +5 -3
  92. package/src/device/DeviceStateProjector.ts +0 -7
  93. package/src/device/DeviceWalletSessionStore.ts +43 -4
  94. package/src/deviceProfile/buildDeviceFeatures.ts +11 -4
  95. package/src/deviceProfile/protocolV2DeviceIdentity.ts +32 -0
  96. package/src/events/logBlockEvent.ts +84 -1
  97. package/src/protocols/protocol-v2/deviceSession.ts +1 -1
  98. package/src/protocols/protocol-v2/features.ts +58 -16
  99. package/src/protocols/protocol-v2/index.ts +5 -0
  100. package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +8 -3
  101. package/src/protocols/protocol-v2/unlockRetry.ts +18 -7
  102. package/src/protocols/protocol-v2/walletSession.ts +144 -62
  103. package/src/types/api/protocolV2.ts +2 -2
  104. package/src/types/device.ts +8 -2
  105. package/src/types/params.ts +2 -1
  106. package/src/utils/deviceFeaturesCompat.ts +8 -1
  107. package/src/utils/pro2Wallpaper.ts +3 -9
  108. package/tsconfig.type-tests.json +5 -1
@@ -1,4 +1,4 @@
1
- import { ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
1
+ import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
2
2
  import {
3
3
  DeviceRebootType,
4
4
  PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
@@ -767,10 +767,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
767
767
  const targetsToUpdate = new Set(this.params.targetsToUpdate ?? []);
768
768
 
769
769
  for (const [key, component] of entries) {
770
- const target = this.getRemoteComponentTarget(key, component);
771
- const updateTarget = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId);
772
- const shouldInstall = updateTarget ? targetsToUpdate.has(updateTarget) : false;
773
- if (shouldInstall) {
770
+ const targetName = component.target?.toUpperCase();
771
+ const target = PROTOCOL_V2_REMOTE_COMPONENT_TARGETS[targetName];
772
+ const updateTarget = target
773
+ ? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
774
+ : undefined;
775
+ if (updateTarget && targetsToUpdate.has(updateTarget)) {
774
776
  const remoteBinary = await this.downloadRemoteProtocolV2Component(key, component);
775
777
  if (remoteBinary.kind === 'bootloader') {
776
778
  bootloaderBinary = remoteBinary.binary;
@@ -992,14 +994,31 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
992
994
  if (typeof this.device.isBootloader === 'function') {
993
995
  return this.device.isBootloader();
994
996
  }
995
- return !!this.device.features?.bootloaderMode;
997
+ return (
998
+ this.device.features?.mode === 'bootloader' ||
999
+ (this.device.features?.mode == null && !!this.device.features?.bootloaderMode)
1000
+ );
1001
+ }
1002
+
1003
+ private isProtocolV2RomloaderMode() {
1004
+ if (!this.device.isProtocolV2() || this.device.getCurrentDeviceType() !== EDeviceType.Pro2) {
1005
+ return false;
1006
+ }
1007
+ if (typeof this.device.isRomloader === 'function') {
1008
+ return this.device.isRomloader();
1009
+ }
1010
+ return this.device.features?.mode === 'romloader';
996
1011
  }
997
1012
 
998
1013
  async enterProtocolV2BootloaderMode() {
999
1014
  // romloader is the first update environment and forwards targets to bootloader.
1000
1015
  // It rejects DeviceRebootType.Bootloader, so reuse the current connection.
1001
- if (this.isProtocolV2BootloaderMode() || this.device.features?.mode === 'romloader') {
1002
- Log.debug('Protocol V2 device is already in loader mode, skip reboot to bootloader');
1016
+ if (this.isProtocolV2RomloaderMode()) {
1017
+ Log.debug('Protocol V2 device is in romloader mode; start firmware update directly');
1018
+ return false;
1019
+ }
1020
+ if (this.isProtocolV2BootloaderMode()) {
1021
+ Log.debug('Protocol V2 device is already in bootloader mode, skip reboot');
1003
1022
  return false;
1004
1023
  }
1005
1024
 
@@ -1034,10 +1053,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1034
1053
  timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
1035
1054
  });
1036
1055
  this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
1037
- // This is a reconnect probe after a Bootloader reboot. Bootloader does not
1038
- // support DeviceStatusGet, so the generic runtime-mode probe is invalid here.
1039
- const features = this.device.updateProtocolV2Features(deviceInfo, null, 'bootloader');
1040
- if (features?.bootloaderMode) {
1056
+ const features = await this.device.probeProtocolV2RuntimeState(
1057
+ deviceInfo,
1058
+ PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
1059
+ );
1060
+ if (features?.mode === 'bootloader') {
1041
1061
  return features;
1042
1062
  }
1043
1063
  lastError = new Error('Protocol V2 device is reachable but is not in bootloader mode');
@@ -1289,7 +1309,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1289
1309
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
1290
1310
  try {
1291
1311
  await this.reconnectProtocolV2Device();
1292
- await this.verifyProtocolV2ReconnectIdentity();
1312
+ const deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
1293
1313
  try {
1294
1314
  const statusResponse = await this.device.getCommands().typedCall(
1295
1315
  'DeviceFirmwareUpdateStatusGet',
@@ -1319,20 +1339,25 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1319
1339
  ) {
1320
1340
  throw error;
1321
1341
  }
1322
- // App firmware does not register DeviceFirmwareUpdateStatusGet. If the
1323
- // device already rebooted into App, this endpoint error signals that the
1324
- // install phase ended; the later phase performs the final readiness check.
1342
+ // App firmware does not register DeviceFirmwareUpdateStatusGet. Treat the
1343
+ // missing endpoint as completion only after the runtime probe confirms App mode.
1325
1344
  if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
1345
+ if (await this.probeProtocolV2NormalMode(deviceInfo)) {
1346
+ Log.log(
1347
+ '[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot'
1348
+ );
1349
+ return;
1350
+ }
1351
+ lastError = new Error(
1352
+ 'Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode'
1353
+ );
1354
+ } else {
1355
+ lastError = error;
1326
1356
  Log.log(
1327
- '[FirmwareUpdateV4] firmware status endpoint unavailable after reboot; continue with normal-mode verification'
1357
+ '[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ',
1358
+ error
1328
1359
  );
1329
- return;
1330
1360
  }
1331
- lastError = error;
1332
- Log.log(
1333
- '[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ',
1334
- error
1335
- );
1336
1361
  }
1337
1362
  } catch (error) {
1338
1363
  lastError = error;
@@ -1361,6 +1386,14 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1361
1386
  await this.protocolV2Reboot(DeviceRebootType.Normal);
1362
1387
  }
1363
1388
 
1389
+ private async probeProtocolV2NormalMode(deviceInfo: ProtocolV2DeviceInfo) {
1390
+ const features = await this.device.probeProtocolV2RuntimeState(
1391
+ deviceInfo,
1392
+ PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
1393
+ );
1394
+ return features.mode === 'normal' && !features.bootloaderMode;
1395
+ }
1396
+
1364
1397
  private async waitForProtocolV2FinalFeatures() {
1365
1398
  const features = await this.waitForProtocolV2ReconnectAndFeatures(
1366
1399
  PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT
@@ -1613,9 +1646,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
1613
1646
  const env = DataManager.getSettings('env');
1614
1647
  if (DataManager.isBleConnect(env)) {
1615
1648
  await wait(3000);
1616
- await this.acquireProtocolV2BleDevice();
1617
- await this.device.initialize();
1618
1649
  }
1650
+ await this.reconnectProtocolV2Device();
1651
+ await this.verifyProtocolV2ReconnectIdentity();
1652
+ await this.device.initialize();
1619
1653
  await wait(2000);
1620
1654
  }
1621
1655
 
@@ -1,6 +1,7 @@
1
1
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
2
 
3
3
  import { UI_REQUEST } from '../constants/ui-request';
4
+ import { refreshProtocolV2DeviceStatus } from '../protocols/protocol-v2/walletSession';
4
5
  import { getPassphraseStateWithRefreshDeviceInfo } from '../utils/deviceFeaturesUtils';
5
6
  import { BaseMethod } from './BaseMethod';
6
7
 
@@ -20,6 +21,12 @@ export default class GetPassphraseState extends BaseMethod {
20
21
  }
21
22
 
22
23
  const isProtocolV2 = this.device.isProtocolV2();
24
+ if (isProtocolV2 && this.payload.useEmptyPassphrase !== true) {
25
+ const features = await refreshProtocolV2DeviceStatus(this.device);
26
+ if (features.unlocked === false) {
27
+ await this.device.unlockDevice();
28
+ }
29
+ }
23
30
  const { passphraseState } = await getPassphraseStateWithRefreshDeviceInfo(
24
31
  this.device,
25
32
  isProtocolV2
@@ -30,8 +37,10 @@ export default class GetPassphraseState extends BaseMethod {
30
37
  : undefined
31
38
  );
32
39
 
33
- const passphraseProtection = this.device.getCurrentPassphraseProtection();
40
+ if (!isProtocolV2 && this.device.getCurrentPassphraseProtection() !== true) {
41
+ return undefined;
42
+ }
34
43
 
35
- return Promise.resolve(passphraseProtection === true ? passphraseState : undefined);
44
+ return passphraseState;
36
45
  }
37
46
  }
@@ -103,6 +103,11 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
103
103
  currentDeviceId = refreshedState.identity.deviceId;
104
104
  return requireDeviceId();
105
105
  };
106
+ const unlockProtocolV2IfLocked = async () => {
107
+ if (isProtocolV2 && state.status.unlocked === false) {
108
+ await this.device.unlockDevice();
109
+ }
110
+ };
106
111
 
107
112
  const protocol = isProtocolV2 ? 'V2' : 'V1';
108
113
 
@@ -135,9 +140,7 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
135
140
 
136
141
  if (this.params.mode === OpenWalletSessionMode.ResumeHidden) {
137
142
  if (isProtocolV2) {
138
- if (this.device.features?.unlocked === false) {
139
- await this.device.unlockDevice();
140
- }
143
+ await unlockProtocolV2IfLocked();
141
144
  const refreshedDeviceId = await refreshProtocolV2DeviceId();
142
145
  if (refreshedDeviceId !== this.params.deviceId) {
143
146
  deviceWalletSessionStore.delete(this.params.deviceId, this.params.passphraseState);
@@ -151,7 +154,7 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
151
154
  this.params.deviceId,
152
155
  this.params.passphraseState
153
156
  );
154
- if (!cachedSessionId) {
157
+ if (!cachedSessionId && !isProtocolV2) {
155
158
  throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
156
159
  }
157
160
  if (!isProtocolV2) {
@@ -168,7 +171,7 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
168
171
  expectPassphraseState: this.params.passphraseState,
169
172
  });
170
173
  const deviceId = requireDeviceId();
171
- if (!session.passphraseState) {
174
+ if (session.passphraseState !== this.params.passphraseState) {
172
175
  this.device.clearInternalState();
173
176
  throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
174
177
  }
@@ -177,21 +180,26 @@ export default class OpenWalletSession extends BaseMethod<OpenWalletSessionParam
177
180
  walletType: 'hidden',
178
181
  deviceId,
179
182
  ...requireHiddenWalletResponse(session),
180
- resumed: wasResumed(session) || session.newSession === cachedSessionId,
183
+ resumed: wasResumed(session) || (!isProtocolV2 && session.newSession === cachedSessionId),
181
184
  };
182
185
  }
183
186
 
184
187
  this.device.passphraseState = undefined;
188
+ await unlockProtocolV2IfLocked();
185
189
  const session = isProtocolV2
186
- ? await getProtocolV2WalletSession(this.device, { initSession: true })
190
+ ? await getProtocolV2WalletSession(this.device, { forceWalletSelection: true })
187
191
  : await getPassphraseStateWithRefreshDeviceInfo(this.device, { initSession: true });
188
192
  const deviceId = isProtocolV2 ? await refreshProtocolV2DeviceId() : requireDeviceId();
193
+ if (isProtocolV2 && this.device.getCurrentPassphraseProtection() !== true) {
194
+ this.device.clearInternalState();
195
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase);
196
+ }
189
197
  const responseBase = {
190
198
  protocol,
191
199
  deviceId,
192
200
  resumed: wasResumed(session),
193
201
  } as const;
194
- return this.device.getCurrentPassphraseProtection() === false
202
+ return !isProtocolV2 && this.device.getCurrentPassphraseProtection() === false
195
203
  ? {
196
204
  ...responseBase,
197
205
  walletType: 'standard',
@@ -195,7 +195,14 @@ export default class DeviceSettings extends BaseMethod<ApplySettings> {
195
195
  page: DeviceSettingsPage.DevicePassphrase,
196
196
  });
197
197
  const updated = await this.device.getDeviceState({ refreshSections: ['status'] });
198
- if (updated.status.passphraseProtection !== requestedPassphrase) {
198
+ const lockedAfterDisabling =
199
+ requestedPassphrase === false &&
200
+ current.status.unlocked === true &&
201
+ updated.status.unlocked === false;
202
+ if (
203
+ updated.status.passphraseProtection !== requestedPassphrase &&
204
+ !lockedAfterDisabling
205
+ ) {
199
206
  throw TypedError(
200
207
  HardwareErrorCode.RuntimeError,
201
208
  'Protocol V2 passphrase setting did not reach the requested value.'
@@ -2,9 +2,9 @@ import { UI_REQUEST } from '../../constants/ui-request';
2
2
  import { serializedPath, validatePath } from '../helpers/pathUtils';
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
  import { validateParams, validateResult } from '../helpers/paramsValidator';
5
- import TransportManager from '../../data-manager/TransportManager';
6
5
  import getAddressLegacyV1 from './legacyV1/getAddress';
7
6
  import getAddress from './latest/getAddress';
7
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
8
8
 
9
9
  import type { EVMAddress, EVMGetAddressParams } from '../../types';
10
10
  import type { EthereumGetAddressOneKey } from '@onekeyfe/hd-transport';
@@ -48,7 +48,7 @@ export default class EvmGetAddress extends BaseMethod<EthereumGetAddressOneKey[]
48
48
  }
49
49
 
50
50
  async getEvmAddress(param: EthereumGetAddressOneKey) {
51
- if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
51
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
52
52
  return getAddressLegacyV1({
53
53
  typedCall: this.device.commands.typedCall.bind(this.device.commands),
54
54
  param,
@@ -2,9 +2,9 @@ import { UI_REQUEST } from '../../constants/ui-request';
2
2
  import { serializedPath, validatePath } from '../helpers/pathUtils';
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
  import { validateParams, validateResult } from '../helpers/paramsValidator';
5
- import TransportManager from '../../data-manager/TransportManager';
6
5
  import getPublicKey from './latest/getPublicKey';
7
6
  import getPublicKeyLegacyV1 from './legacyV1/getPublicKey';
7
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
8
8
  import { batchGetPublickeys, supportBatchPublicKeyByDevice } from '../helpers/batchGetPublickeys';
9
9
 
10
10
  import type { EVMGetPublicKeyParams, EVMPublicKey } from '../../types';
@@ -60,7 +60,7 @@ export default class EVMGetPublicKey extends BaseMethod<EthereumGetPublicKeyOneK
60
60
  }
61
61
 
62
62
  getEvmPublicKey(param: EthereumGetPublicKey) {
63
- if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
63
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
64
64
  return getPublicKeyLegacyV1({
65
65
  typedCall: this.device.commands.typedCall.bind(this.device.commands),
66
66
  param,
@@ -3,9 +3,9 @@ import { validatePath } from '../helpers/pathUtils';
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
  import { validateParams } from '../helpers/paramsValidator';
5
5
  import { formatAnyHex } from '../helpers/hexUtils';
6
- import TransportManager from '../../data-manager/TransportManager';
7
6
  import signMessage from './latest/signMessage';
8
7
  import signMessageLegacyV1 from './legacyV1/signMessage';
8
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
9
9
 
10
10
  import type { EthereumSignMessageOneKey } from '@onekeyfe/hd-transport';
11
11
 
@@ -40,7 +40,7 @@ export default class EVMSignMessage extends BaseMethod<EthereumSignMessageOneKey
40
40
  }
41
41
 
42
42
  async run() {
43
- if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
43
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
44
44
  return signMessageLegacyV1({
45
45
  typedCall: this.device.commands.typedCall.bind(this.device.commands),
46
46
  params: this.params,
@@ -5,9 +5,9 @@ import { validatePath } from '../helpers/pathUtils';
5
5
  import { BaseMethod } from '../BaseMethod';
6
6
  import { validateParams } from '../helpers/paramsValidator';
7
7
  import { formatAnyHex } from '../helpers/hexUtils';
8
- import TransportManager from '../../data-manager/TransportManager';
9
8
  import { signTransaction } from './latest/signTransaction';
10
9
  import { signTransaction as signTransactionLegacyV1 } from './legacyV1/signTransaction';
10
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
11
11
 
12
12
  import type {
13
13
  EVMSignTransactionParams,
@@ -126,7 +126,7 @@ export default class EVMSignTransaction extends BaseMethod {
126
126
 
127
127
  if (formattedTx == null) throw ERRORS.TypedError('Runtime', 'formattedTx is not set');
128
128
 
129
- if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
129
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
130
130
  return signTransactionLegacyV1({
131
131
  typedCall: this.device.commands.typedCall.bind(this.device.commands),
132
132
  addressN,
@@ -15,8 +15,8 @@ import {
15
15
  type EthereumSignTypedDataMessage,
16
16
  type EthereumSignTypedDataTypes,
17
17
  } from '../../types';
18
- import TransportManager from '../../data-manager/TransportManager';
19
18
  import { signTypedHash as signTypedHashLegacyV1 } from './legacyV1/signTypedHash';
19
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
20
20
  import { signTypedHash } from './latest/signTypedHash';
21
21
  import { signTypedData as signTypedDataLegacyV1 } from './legacyV1/signTypedData';
22
22
  import { signTypedData } from './latest/signTypedData';
@@ -278,29 +278,23 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
278
278
 
279
279
  let supportTrezor = false;
280
280
  let response: MessageResponse<MessageKey>;
281
- switch (TransportManager.getProtocolV1MessageSchema()) {
282
- case 'v1LegacySchema':
283
- supportTrezor = true;
284
- response = await signTypedDataLegacyV1({
285
- typedCall: this.device.commands.typedCall.bind(this.device.commands),
286
- addressN,
287
- data,
288
- metamaskV4Compat,
289
- chainId,
290
- });
291
- break;
292
-
293
- case 'v1CurrentSchema':
294
- default:
295
- supportTrezor = false;
296
- response = await signTypedData({
297
- typedCall: this.device.commands.typedCall.bind(this.device.commands),
298
- addressN,
299
- data,
300
- metamaskV4Compat,
301
- chainId,
302
- });
303
- break;
281
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
282
+ supportTrezor = true;
283
+ response = await signTypedDataLegacyV1({
284
+ typedCall: this.device.commands.typedCall.bind(this.device.commands),
285
+ addressN,
286
+ data,
287
+ metamaskV4Compat,
288
+ chainId,
289
+ });
290
+ } else {
291
+ response = await signTypedData({
292
+ typedCall: this.device.commands.typedCall.bind(this.device.commands),
293
+ addressN,
294
+ data,
295
+ metamaskV4Compat,
296
+ chainId,
297
+ });
304
298
  }
305
299
 
306
300
  return this.handleSignTypedData({
@@ -326,28 +320,24 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
326
320
  }) {
327
321
  if (!domainHash) throw ERRORS.TypedError('Runtime', 'domainHash is required');
328
322
 
329
- switch (TransportManager.getProtocolV1MessageSchema()) {
330
- case 'v1LegacySchema':
331
- return signTypedHashLegacyV1({
332
- typedCall,
333
- addressN,
334
- domainHash,
335
- messageHash,
336
- chainId,
337
- device: this.device,
338
- });
339
-
340
- case 'v1CurrentSchema':
341
- default:
342
- return signTypedHash({
343
- typedCall,
344
- addressN,
345
- domainHash,
346
- messageHash,
347
- chainId,
348
- device: this.device,
349
- });
323
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
324
+ return signTypedHashLegacyV1({
325
+ typedCall,
326
+ addressN,
327
+ domainHash,
328
+ messageHash,
329
+ chainId,
330
+ device: this.device,
331
+ });
350
332
  }
333
+ return signTypedHash({
334
+ typedCall,
335
+ addressN,
336
+ domainHash,
337
+ messageHash,
338
+ chainId,
339
+ device: this.device,
340
+ });
351
341
  }
352
342
 
353
343
  getVersionRange() {
@@ -2,9 +2,9 @@ import { UI_REQUEST } from '../../constants/ui-request';
2
2
  import { BaseMethod } from '../BaseMethod';
3
3
  import { validateParams } from '../helpers/paramsValidator';
4
4
  import { formatAnyHex } from '../helpers/hexUtils';
5
- import TransportManager from '../../data-manager/TransportManager';
6
5
  import verifyMessageLegacyV1 from './legacyV1/verifyMessage';
7
6
  import verifyMessage from './latest/verifyMessage';
7
+ import { shouldUseLegacyV1EvmMessages } from './protocol';
8
8
 
9
9
  import type { EthereumVerifyMessageOneKey } from '@onekeyfe/hd-transport';
10
10
 
@@ -35,7 +35,7 @@ export default class EVMSignMessage extends BaseMethod<EthereumVerifyMessageOneK
35
35
  }
36
36
 
37
37
  async run() {
38
- if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
38
+ if (shouldUseLegacyV1EvmMessages(this.device)) {
39
39
  return verifyMessageLegacyV1({
40
40
  typedCall: this.device.commands.typedCall.bind(this.device.commands),
41
41
  params: this.params,
@@ -0,0 +1,6 @@
1
+ import TransportManager from '../../data-manager/TransportManager';
2
+
3
+ import type { Device } from '../../device/Device';
4
+
5
+ export const shouldUseLegacyV1EvmMessages = (device: Pick<Device, 'isProtocolV2'>): boolean =>
6
+ !device.isProtocolV2() && TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema';
@@ -104,7 +104,14 @@ export default class KaspaSignTransaction extends BaseMethod<KaspaSignTransactio
104
104
  });
105
105
 
106
106
  const outputs: KaspaSignTransactionParams['outputs'] = payload.outputs.map(output => {
107
+ const address = getOutputAddress(output);
107
108
  const addressN = getOutputAddressN(output);
109
+ if (address !== undefined && addressN !== undefined) {
110
+ throw ERRORS.TypedError(
111
+ HardwareErrorCode.CallMethodInvalidParameter,
112
+ 'KaspaSignTransaction: outputs must not contain both address and addressN'
113
+ );
114
+ }
108
115
  validateParams(output, [
109
116
  { name: 'satoshis', required: true },
110
117
  { name: 'address', type: 'string' },
@@ -12,8 +12,8 @@ export default class DeviceGetOnboardingStatus extends BaseMethod {
12
12
 
13
13
  async run() {
14
14
  const { message } = await this.device.commands.typedCall(
15
- 'DevGetOnboardingStatus',
16
- 'DevOnboardingStatus',
15
+ 'OnboardingStatusGet',
16
+ 'OnboardingStatus',
17
17
  {}
18
18
  );
19
19
  return message;
@@ -74,7 +74,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
74
74
  this.encoded = encodePro2Wallpaper({ width, height, rgba: rgbaBytes });
75
75
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
76
76
  this.params = { width, height, rgba: rgbaBytes, fileName, chunkSize };
77
- this.unlockPolicy = 'unlock-before-run';
77
+ this.unlockPolicy = 'none';
78
78
  this.skipForceUpdateCheck = true;
79
79
  this.useDevicePassphraseState = false;
80
80
  }
package/src/core/index.ts CHANGED
@@ -46,7 +46,9 @@ import {
46
46
  createDeviceMessage,
47
47
  createResponseMessage,
48
48
  createUiMessage,
49
+ formatLogMethodLabel,
49
50
  getLogBlockLabel,
51
+ getSafeLogPayload,
50
52
  } from '../events';
51
53
  import TransportManager from '../data-manager/TransportManager';
52
54
  import DeviceConnector from '../device/DeviceConnector';
@@ -1451,14 +1453,14 @@ export default class Core extends EventEmitter {
1451
1453
  case IFRAME.CALL: {
1452
1454
  const logBlockLabel = getLogBlockLabel(message);
1453
1455
  Log.log(
1454
- `[${Date.now()}][CALL_API]`,
1455
- logBlockLabel ? { method: logBlockLabel, payload: '[REDACTED]' } : message
1456
+ formatLogMethodLabel(`[${Date.now()}][CALL_API]`, logBlockLabel),
1457
+ getSafeLogPayload(message, logBlockLabel)
1456
1458
  );
1457
1459
  const response = await callAPI(this.getCoreContext(), message);
1458
1460
  const { success, payload } = response;
1459
1461
  Log.log(
1460
- `[${Date.now()}][CALL_API_RESPONSE]`,
1461
- logBlockLabel ? { method: logBlockLabel, payload: '[REDACTED]' } : response
1462
+ formatLogMethodLabel(`[${Date.now()}][CALL_API_RESPONSE]`, logBlockLabel),
1463
+ getSafeLogPayload(response, logBlockLabel)
1462
1464
  );
1463
1465
  if (success) {
1464
1466
  return response;
@@ -1516,7 +1518,7 @@ export default class Core extends EventEmitter {
1516
1518
  // Preserve synchronous dispose semantics for in-memory state and listeners.
1517
1519
  _deviceList = undefined;
1518
1520
  _connector = undefined;
1519
- DevicePool.resetState();
1521
+ DevicePool.dispose();
1520
1522
  deviceCacheMap.clear();
1521
1523
  preWarmInflight.clear();
1522
1524
  preWarmDoneAt.clear();