@onekeyfe/hd-core 1.2.0-alpha.104 → 1.2.0-alpha.106

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 (46) hide show
  1. package/__tests__/DeviceCommands.test.ts +100 -28
  2. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +0 -2
  3. package/__tests__/device-lifecycle-events.test.ts +113 -2
  4. package/__tests__/device-pool-state.test.ts +1 -5
  5. package/__tests__/deviceSettings.test.ts +0 -1
  6. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +145 -0
  7. package/__tests__/get-device-state.test.ts +0 -50
  8. package/__tests__/logBlockEvent.test.ts +13 -1
  9. package/__tests__/protocol-v2.test.ts +466 -126
  10. package/__tests__/refresh-device-state.test.ts +0 -1
  11. package/__tests__/search-devices.test.ts +0 -2
  12. package/dist/api/FirmwareUpdateV4.d.ts +7 -3
  13. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  14. package/dist/api/GetDeviceState.d.ts.map +1 -1
  15. package/dist/api/SearchDevices.d.ts.map +1 -1
  16. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/device/Device.d.ts +1 -3
  19. package/dist/device/Device.d.ts.map +1 -1
  20. package/dist/device/DeviceCommands.d.ts.map +1 -1
  21. package/dist/device/DevicePool.d.ts +1 -1
  22. package/dist/device/DevicePool.d.ts.map +1 -1
  23. package/dist/events/logBlockEvent.d.ts.map +1 -1
  24. package/dist/index.d.ts +1 -6
  25. package/dist/index.js +260 -196
  26. package/dist/protocols/protocol-v2/features.d.ts +1 -1
  27. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  28. package/dist/types/api/getDeviceState.d.ts +0 -1
  29. package/dist/types/api/getDeviceState.d.ts.map +1 -1
  30. package/package.json +4 -4
  31. package/src/api/FirmwareUpdateV4.ts +262 -172
  32. package/src/api/GetDeviceState.ts +0 -1
  33. package/src/api/SearchDevices.ts +0 -2
  34. package/src/api/firmware/protocolV2Release.ts +0 -1
  35. package/src/core/index.ts +6 -6
  36. package/src/device/Device.ts +27 -63
  37. package/src/device/DeviceCommands.ts +4 -14
  38. package/src/device/DevicePool.ts +3 -11
  39. package/src/events/logBlockEvent.ts +14 -1
  40. package/src/protocols/protocol-v2/features.ts +9 -2
  41. package/src/types/api/getDeviceState.ts +0 -2
  42. package/src/utils/deviceSettings.ts +1 -1
  43. package/__tests__/protocol-v2-legacy-recovery.test.ts +0 -29
  44. package/dist/core/protocolV2LegacyRecovery.d.ts +0 -5
  45. package/dist/core/protocolV2LegacyRecovery.d.ts.map +0 -1
  46. package/src/core/protocolV2LegacyRecovery.ts +0 -12
@@ -60,7 +60,6 @@ export async function loadProtocolV2FirmwareReleaseContext({
60
60
  refreshSections: checkFirmwareHash
61
61
  ? ['identity', 'versions', 'verification']
62
62
  : ['identity', 'versions'],
63
- allowLegacyProtocolV2ProtocolInfo: true,
64
63
  });
65
64
  if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
66
65
  throw ERRORS.TypedError(
package/src/core/index.ts CHANGED
@@ -64,7 +64,6 @@ import {
64
64
  isProtocolV2UiEnabled,
65
65
  } from '../protocols/protocol-v2/uiInteraction';
66
66
  import { createUiProgressMessageFilter } from '../utils/uiProgressThrottle';
67
- import { isLegacyProtocolV2FirmwareRecoveryMethod } from './protocolV2LegacyRecovery';
68
67
 
69
68
  import type { ConnectSettings, Features, KnownDevice } from '../types';
70
69
  import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
@@ -110,9 +109,6 @@ const parseInitOptions = (method?: BaseMethod): InitOptions => ({
110
109
  connectProtocol: method?.payload.connectProtocol,
111
110
  forceProtocolDetection: method?.payload.forceProtocolDetection,
112
111
  protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
113
- ...(isLegacyProtocolV2FirmwareRecoveryMethod(method)
114
- ? { allowLegacyProtocolV2ProtocolInfo: true }
115
- : {}),
116
112
  });
117
113
 
118
114
  let _core: Core | undefined;
@@ -140,6 +136,9 @@ const toError = (error: unknown): Error | undefined => {
140
136
  }
141
137
  };
142
138
 
139
+ const isExpectedCompatibilityError = (error: unknown) =>
140
+ error instanceof HardwareError && error.errorCode === HardwareErrorCode.DeviceNotSupportMethod;
141
+
143
142
  const updateMethodRequestContext = (method: BaseMethod, updates: any) => {
144
143
  if (method.requestContext) {
145
144
  updateRequestContext(method.requestContext.responseID, updates);
@@ -697,7 +696,9 @@ const onCallDevice = async (
697
696
  try {
698
697
  return await task.callPromise.promise;
699
698
  } catch (e) {
700
- Log.debug('Device Run Error: ', e);
699
+ if (!isExpectedCompatibilityError(e)) {
700
+ Log.debug('Device Run Error: ', e);
701
+ }
701
702
  completeMethodRequestContext(method, e);
702
703
  return createResponseMessage(method.responseID, false, { error: e });
703
704
  }
@@ -1252,7 +1253,6 @@ const cleanup = () => {
1252
1253
  pendingUiPromises,
1253
1254
  ERRORS.TypedError(HardwareErrorCode.ActionCancelled, 'UI request was cancelled')
1254
1255
  );
1255
- Log.debug('Cleanup...');
1256
1256
  };
1257
1257
 
1258
1258
  const removeDeviceListener = (device: Device) => {
@@ -100,8 +100,6 @@ export type InitOptions = {
100
100
  protocolV2DeviceInfoTimeoutMs?: number;
101
101
  /** Refresh Protocol V2 runtime state before returning discovery results. */
102
102
  refreshRuntimeState?: boolean;
103
- /** Recovery-only compatibility used by discovery and Protocol V2 firmware updates. */
104
- allowLegacyProtocolV2ProtocolInfo?: boolean;
105
103
  /**
106
104
  * Protocol V1 Initialize response timeout override. Reboot-wait polling passes a
107
105
  * short value so an unanswered probe settles before the next poll tick.
@@ -488,6 +486,10 @@ export class Device extends EventEmitter {
488
486
  }
489
487
 
490
488
  this.commands = new DeviceCommands(this, this.mainId ?? '');
489
+ // Protocol V2 runtime metadata belongs to one active transport link. A
490
+ // successful acquire creates a fresh link/session, so never carry cached
491
+ // ProtocolInfo or pre-initialize state across that boundary.
492
+ this.invalidateProtocolV2RuntimeState();
491
493
  } catch (error) {
492
494
  if (options?.forceProtocolDetection) {
493
495
  this.originalDescriptor.protocolType = previousProtocol;
@@ -980,17 +982,7 @@ export class Device extends EventEmitter {
980
982
  });
981
983
  // The default request excludes SE/hash data and therefore uses basic scope.
982
984
  // Full version and verification data require getDeviceState({ scope: 'firmware' }).
983
- const features = options?.allowLegacyProtocolV2ProtocolInfo
984
- ? await this.probeProtocolV2RuntimeState(
985
- deviceInfo,
986
- options.protocolV2DeviceInfoTimeoutMs,
987
- { allowLegacyProtocolV2ProtocolInfo: true }
988
- )
989
- : await this.probeProtocolV2RuntimeState(
990
- deviceInfo,
991
- options?.protocolV2DeviceInfoTimeoutMs
992
- );
993
- Log.debug('Protocol V2 features:', features);
985
+ await this.probeProtocolV2RuntimeState(deviceInfo, options?.protocolV2DeviceInfoTimeoutMs);
994
986
  } catch (error) {
995
987
  Log.error('Protocol V2 initialization failed:', error);
996
988
  throw error;
@@ -1026,13 +1018,7 @@ export class Device extends EventEmitter {
1026
1018
  commands: this.commands,
1027
1019
  request: getProtocolV2DeviceInfoRequest(),
1028
1020
  });
1029
- if (params.allowLegacyProtocolV2ProtocolInfo) {
1030
- await this.probeProtocolV2RuntimeState(deviceInfo, undefined, {
1031
- allowLegacyProtocolV2ProtocolInfo: true,
1032
- });
1033
- } else {
1034
- await this.probeProtocolV2RuntimeState(deviceInfo);
1035
- }
1021
+ await this.probeProtocolV2RuntimeState(deviceInfo);
1036
1022
  refreshedDeviceInfo = deviceInfo;
1037
1023
  initializedWithDeviceInfo = true;
1038
1024
  } else {
@@ -1074,9 +1060,6 @@ export class Device extends EventEmitter {
1074
1060
  // during an explicit refresh so a device rebooted into application firmware
1075
1061
  // can leave the cached loader state.
1076
1062
  forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader',
1077
- ...(params.allowLegacyProtocolV2ProtocolInfo
1078
- ? { allowLegacyProtocolV2ProtocolInfo: true }
1079
- : {}),
1080
1063
  });
1081
1064
  }
1082
1065
 
@@ -1125,9 +1108,10 @@ export class Device extends EventEmitter {
1125
1108
  source,
1126
1109
  changedKeys: result.changedKeys,
1127
1110
  };
1128
- Log.debug('Device state patch committed', {
1111
+ Log.debug('Device state updated', {
1129
1112
  source,
1130
- keys: result.changedKeys,
1113
+ revision: result.revision,
1114
+ changedKeyCount: result.changedKeys.length,
1131
1115
  });
1132
1116
  this.emit(DEVICE.STATE, this, event);
1133
1117
  if (result.state.protocol === 'V1') {
@@ -1150,23 +1134,8 @@ export class Device extends EventEmitter {
1150
1134
 
1151
1135
  async ensureProtocolV2RuntimeContext(
1152
1136
  timeoutMs?: number,
1153
- options?: {
1154
- forceRefresh?: boolean;
1155
- allowLegacyProtocolV2ProtocolInfo?: boolean;
1156
- }
1137
+ options?: { forceRefresh?: boolean }
1157
1138
  ): Promise<ProtocolInfo> {
1158
- const assertProtocolInfoAllowed = (protocolInfo: ProtocolInfo) => {
1159
- if (
1160
- isLegacyProtocolV2ProtocolInfo(protocolInfo) &&
1161
- options?.allowLegacyProtocolV2ProtocolInfo !== true
1162
- ) {
1163
- throw ERRORS.TypedError(
1164
- HardwareErrorCode.DeviceInitializeFailed,
1165
- 'Legacy Protocol V2 ProtocolInfo is supported only during device discovery and firmware update.'
1166
- );
1167
- }
1168
- return protocolInfo;
1169
- };
1170
1139
  const cachedProtocolInfo =
1171
1140
  options?.forceRefresh === true
1172
1141
  ? undefined
@@ -1176,11 +1145,11 @@ export class Device extends EventEmitter {
1176
1145
  : undefined);
1177
1146
  if (cachedProtocolInfo) {
1178
1147
  this.protocolV2RuntimeContext = cachedProtocolInfo;
1179
- return assertProtocolInfoAllowed(cachedProtocolInfo);
1148
+ return cachedProtocolInfo;
1180
1149
  }
1181
1150
 
1182
1151
  if (this.protocolV2RuntimeContextPromise) {
1183
- return assertProtocolInfoAllowed(await this.protocolV2RuntimeContextPromise);
1152
+ return this.protocolV2RuntimeContextPromise;
1184
1153
  }
1185
1154
 
1186
1155
  const requestToken = {};
@@ -1202,7 +1171,7 @@ export class Device extends EventEmitter {
1202
1171
  this.protocolV2RuntimeContextPromise = pendingRequest;
1203
1172
 
1204
1173
  try {
1205
- return assertProtocolInfoAllowed(await pendingRequest);
1174
+ return await pendingRequest;
1206
1175
  } finally {
1207
1176
  if (this.protocolV2RuntimeContextPromise === pendingRequest) {
1208
1177
  this.protocolV2RuntimeContextPromise = undefined;
@@ -1218,16 +1187,14 @@ export class Device extends EventEmitter {
1218
1187
  timeoutMs?: number,
1219
1188
  options?: {
1220
1189
  forceRuntimeContextRefresh?: boolean;
1221
- allowLegacyProtocolV2ProtocolInfo?: boolean;
1222
1190
  }
1223
1191
  ) {
1224
1192
  const protocolInfo = await this.ensureProtocolV2RuntimeContext(timeoutMs, {
1225
1193
  forceRefresh: options?.forceRuntimeContextRefresh,
1226
- allowLegacyProtocolV2ProtocolInfo: options?.allowLegacyProtocolV2ProtocolInfo,
1227
1194
  });
1228
- const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
1229
- const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
1230
1195
  const runtimeDeviceInfo = deviceInfo ?? this.state?.raw?.protocolV2DeviceInfo;
1196
+ const runtimeMode = getProtocolV2RuntimeMode(protocolInfo, runtimeDeviceInfo);
1197
+ const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
1231
1198
  const protocolV2DeviceType = runtimeDeviceInfo
1232
1199
  ? resolveProtocolV2DeviceIdentity(runtimeDeviceInfo.hw?.Device_type).deviceType
1233
1200
  : this.getCurrentDeviceType();
@@ -1304,8 +1271,7 @@ export class Device extends EventEmitter {
1304
1271
  });
1305
1272
  }
1306
1273
 
1307
- markTransportDisconnected() {
1308
- this.deviceAcquired = false;
1274
+ private invalidateProtocolV2RuntimeState() {
1309
1275
  if (!this.isProtocolV2()) return;
1310
1276
  this.protocolV2StateNeedsReload = true;
1311
1277
  this.protocolV2RuntimeContext = undefined;
@@ -1314,6 +1280,11 @@ export class Device extends EventEmitter {
1314
1280
  this.clearPreInitialized();
1315
1281
  }
1316
1282
 
1283
+ markTransportDisconnected() {
1284
+ this.deviceAcquired = false;
1285
+ this.invalidateProtocolV2RuntimeState();
1286
+ }
1287
+
1317
1288
  invalidateAfterWipe() {
1318
1289
  const deviceId = this.getCurrentDeviceId();
1319
1290
  if (deviceId) {
@@ -1323,10 +1294,7 @@ export class Device extends EventEmitter {
1323
1294
  if (this.originalDescriptor.path !== deviceId) {
1324
1295
  deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
1325
1296
  }
1326
- this.protocolV2StateNeedsReload = true;
1327
- this.protocolV2RuntimeContext = undefined;
1328
- this.protocolV2RuntimeContextPromise = undefined;
1329
- this.protocolV2RuntimeContextRequestToken = undefined;
1297
+ this.invalidateProtocolV2RuntimeState();
1330
1298
  }
1331
1299
 
1332
1300
  this.passphraseState = undefined;
@@ -1338,11 +1306,7 @@ export class Device extends EventEmitter {
1338
1306
  markProtocolV2Reboot(rebootType: DeviceRebootType) {
1339
1307
  if (!this.isProtocolV2()) return;
1340
1308
 
1341
- this.protocolV2StateNeedsReload = true;
1342
- this.protocolV2RuntimeContext = undefined;
1343
- this.protocolV2RuntimeContextPromise = undefined;
1344
- this.protocolV2RuntimeContextRequestToken = undefined;
1345
- this.clearPreInitialized();
1309
+ this.invalidateProtocolV2RuntimeState();
1346
1310
  let loaderMode: 'bootloader' | 'romloader' | undefined;
1347
1311
  if (rebootType === DeviceRebootType.Bootloader) {
1348
1312
  loaderMode = 'bootloader';
@@ -1416,6 +1380,10 @@ export class Device extends EventEmitter {
1416
1380
  if (device.features) {
1417
1381
  this._updateFeatures(device.features);
1418
1382
  }
1383
+ // Adopting another Device instance's command channel also crosses an active
1384
+ // link boundary. Renegotiate runtime metadata on that channel instead of
1385
+ // retaining ProtocolInfo from the previous instance/session.
1386
+ this.invalidateProtocolV2RuntimeState();
1419
1387
  }
1420
1388
 
1421
1389
  async run(fn?: () => Promise<void>, options?: RunOptions) {
@@ -1545,10 +1513,6 @@ export class Device extends EventEmitter {
1545
1513
 
1546
1514
  async interruptionFromUser() {
1547
1515
  const error = ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
1548
- // Cancellation often ends the transport session, especially during firmware
1549
- // update reboot or exit. Invalidate V2 state before awaiting asynchronous
1550
- // cancellation callbacks so the next request cannot reuse a stale runtime mode.
1551
- this.markTransportDisconnected();
1552
1516
  await this.cancelableAction?.(error);
1553
1517
  await this.commands?.cancel();
1554
1518
 
@@ -304,13 +304,6 @@ export class DeviceCommands {
304
304
  const promise = this.transport.call(this.mainId, type, msg ?? {}, options) as any;
305
305
  this.callPromise = promise;
306
306
  const res = await promise;
307
- if (!shouldReduceDebug) {
308
- LogCore.debug(
309
- '[DeviceCommands] [call] Received',
310
- res.type,
311
- getSafeTransportLogPayload(res.message, res.type)
312
- );
313
- }
314
307
  return res;
315
308
  } catch (error) {
316
309
  LogCore.debug('[DeviceCommands] [call] Received error', {
@@ -445,13 +438,10 @@ export class DeviceCommands {
445
438
  if (!shouldReduceDebugForCall(callType)) {
446
439
  Log.debug('_filterCommonTypes: ', {
447
440
  request: callType,
448
- response:
449
- callType === 'DeviceFirmwareUpdateStatusGet'
450
- ? {
451
- type: res.type,
452
- message: getSafeTransportLogPayload(res.message, res.type),
453
- }
454
- : res.type,
441
+ response: {
442
+ type: res.type,
443
+ message: getSafeTransportLogPayload(res.message, res.type),
444
+ },
455
445
  });
456
446
  }
457
447
  } catch (error) {
@@ -182,7 +182,7 @@ export class DevicePool extends EventEmitter {
182
182
  try {
183
183
  await device.initialize(initOptions);
184
184
  if (initOptions?.refreshRuntimeState && device.isProtocolV2()) {
185
- await this._refreshProtocolV2DiscoveryState(device, initOptions);
185
+ await this._refreshProtocolV2DiscoveryState(device);
186
186
  }
187
187
  } finally {
188
188
  await device.release();
@@ -197,7 +197,7 @@ export class DevicePool extends EventEmitter {
197
197
  await device.run(
198
198
  async () => {
199
199
  try {
200
- await this._refreshProtocolV2DiscoveryState(device, initOptions);
200
+ await this._refreshProtocolV2DiscoveryState(device);
201
201
  } catch (error) {
202
202
  // Device.run releases after the callback; then propagate the actual read error.
203
203
  refreshError = error;
@@ -206,9 +206,6 @@ export class DevicePool extends EventEmitter {
206
206
  {
207
207
  connectProtocol: initOptions.connectProtocol,
208
208
  forceProtocolDetection: initOptions.forceProtocolDetection,
209
- ...(initOptions.allowLegacyProtocolV2ProtocolInfo
210
- ? { allowLegacyProtocolV2ProtocolInfo: true }
211
- : {}),
212
209
  }
213
210
  );
214
211
  if (refreshError instanceof Error) throw refreshError;
@@ -220,18 +217,13 @@ export class DevicePool extends EventEmitter {
220
217
  * error; settings only supplies a label, so its failure retains the existing name.
221
218
  * Device.getDeviceState skips unsupported status/settings calls in loader mode.
222
219
  */
223
- static async _refreshProtocolV2DiscoveryState(device: Device, initOptions?: InitOptions) {
224
- const stateReadOptions = initOptions?.allowLegacyProtocolV2ProtocolInfo
225
- ? { allowLegacyProtocolV2ProtocolInfo: true as const }
226
- : {};
220
+ static async _refreshProtocolV2DiscoveryState(device: Device) {
227
221
  await device.getDeviceState({
228
222
  refreshSections: ['status'],
229
- ...stateReadOptions,
230
223
  });
231
224
  try {
232
225
  await device.getDeviceState({
233
226
  refreshSections: ['settings'],
234
- ...stateReadOptions,
235
227
  });
236
228
  } catch (error) {
237
229
  Log.debug('Unable to refresh Protocol V2 device label during discovery', error);
@@ -17,6 +17,14 @@ const LogLabelMethod: Set<string> = new Set([
17
17
  'fileRead',
18
18
  ]);
19
19
 
20
+ // 资源上传参数可能包含很大的 Base64 字符串。这里按方法整段跳过,避免日志层
21
+ // 递归复制和序列化这些数据;资源 API 与传输内容本身保持不变。
22
+ const LogPayloadBlockMethod: Set<string> = new Set([
23
+ 'deviceUploadNft',
24
+ 'deviceUploadWallpaper',
25
+ 'uploadPortfolio',
26
+ ]);
27
+
20
28
  const SensitiveLogKeys: Set<string> = new Set([
21
29
  'devicestate',
22
30
  'entropy',
@@ -86,7 +94,12 @@ export function getLogBlockLabel(message: unknown): string | undefined {
86
94
  }
87
95
 
88
96
  export function getSafeLogPayload(value: unknown, blockLabel?: string): unknown {
89
- if (blockLabel && (LogBlockEvent.has(blockLabel) || isSigningMethod(blockLabel))) {
97
+ if (
98
+ blockLabel &&
99
+ (LogBlockEvent.has(blockLabel) ||
100
+ LogPayloadBlockMethod.has(blockLabel) ||
101
+ isSigningMethod(blockLabel))
102
+ ) {
90
103
  return { method: blockLabel, payload: '[REDACTED]' };
91
104
  }
92
105
 
@@ -97,11 +97,18 @@ export const parseProtocolV2BuildFingerprint = (
97
97
  };
98
98
 
99
99
  export const getProtocolV2RuntimeMode = (
100
- protocolInfo: ProtocolInfo
100
+ protocolInfo: ProtocolInfo,
101
+ deviceInfo?: ProtocolV2DeviceInfo
101
102
  ): ProtocolV2RuntimeMode | undefined => {
102
103
  const binary = parseProtocolV2BuildFingerprint(protocolInfo.build_fingerprint)?.binary;
103
104
  if (binary === 'application') return 'normal';
104
- return binary;
105
+ if (binary) return binary;
106
+
107
+ if (isLegacyProtocolV2ProtocolInfo(protocolInfo) && !deviceInfo?.fw?.application) {
108
+ if (deviceInfo?.fw?.romloader) return 'romloader';
109
+ if (deviceInfo?.fw?.bootloader) return 'bootloader';
110
+ }
111
+ return undefined;
105
112
  };
106
113
 
107
114
  // MessageType_DeviceStatusGet in the Protocol V2 protobuf registry.
@@ -11,8 +11,6 @@ export type GetDeviceStateParams = CommonParams & {
11
11
  export type DeviceStateReadOptions = {
12
12
  refreshSections?: DeviceStateSection[];
13
13
  includeRaw?: boolean;
14
- /** Internal recovery-only compatibility used by discovery and firmware update flows. */
15
- allowLegacyProtocolV2ProtocolInfo?: boolean;
16
14
  };
17
15
 
18
16
  export declare function getDeviceState(
@@ -200,7 +200,7 @@ export const getAutoShutDownOptions = (
200
200
  return withNever([60_000, 120_000, 300_000, 600_000], protocol);
201
201
  case EDeviceType.Pro2:
202
202
  case EDeviceType.Neo:
203
- return withNever([60_000, 120_000, 300_000, 600_000, 1_800_000], protocol);
203
+ return withNever([60_000, 120_000, 300_000, 600_000], protocol);
204
204
  default:
205
205
  return [];
206
206
  }
@@ -1,29 +0,0 @@
1
- import { isLegacyProtocolV2FirmwareRecoveryMethod } from '../src/core/protocolV2LegacyRecovery';
2
-
3
- import type { BaseMethod } from '../src/api/BaseMethod';
4
-
5
- const createMethod = (
6
- name: string,
7
- payload: Record<string, unknown>
8
- ): Pick<BaseMethod, 'name' | 'payload'> => ({
9
- name,
10
- payload: { method: name, ...payload },
11
- });
12
-
13
- describe('Protocol V2 legacy firmware recovery policy', () => {
14
- test.each([
15
- ['firmware state read', 'getDeviceState', { scope: 'firmware' }],
16
- ['firmware release check', 'checkAllFirmwareRelease', {}],
17
- ['firmware update', 'firmwareUpdateV4', {}],
18
- ])('allows legacy ProtocolInfo for %s', (_label, name, payload) => {
19
- expect(isLegacyProtocolV2FirmwareRecoveryMethod(createMethod(name, payload))).toBe(true);
20
- });
21
-
22
- test.each([
23
- ['runtime state read', 'getDeviceState', { scope: 'runtime' }],
24
- ['settings state read', 'getDeviceState', { scope: 'settings' }],
25
- ['ordinary API', 'getFeatures', {}],
26
- ])('rejects legacy ProtocolInfo for %s', (_label, name, payload) => {
27
- expect(isLegacyProtocolV2FirmwareRecoveryMethod(createMethod(name, payload))).toBe(false);
28
- });
29
- });
@@ -1,5 +0,0 @@
1
- import type { BaseMethod } from '../api/BaseMethod';
2
- type CoreMethodDescriptor = Pick<BaseMethod, 'name' | 'payload'>;
3
- export declare const isLegacyProtocolV2FirmwareRecoveryMethod: (method?: CoreMethodDescriptor) => boolean;
4
- export {};
5
- //# sourceMappingURL=protocolV2LegacyRecovery.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocolV2LegacyRecovery.d.ts","sourceRoot":"","sources":["../../src/core/protocolV2LegacyRecovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,KAAK,oBAAoB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAMjE,eAAO,MAAM,wCAAwC,YAAa,oBAAoB,KAAG,OAGb,CAAC"}
@@ -1,12 +0,0 @@
1
- import type { BaseMethod } from '../api/BaseMethod';
2
-
3
- type CoreMethodDescriptor = Pick<BaseMethod, 'name' | 'payload'>;
4
-
5
- /**
6
- * TEMPORARY COMPATIBILITY: Legacy ProtocolInfo is accepted only by the
7
- * firmware recovery entry points used before and during Protocol V2 updates.
8
- */
9
- export const isLegacyProtocolV2FirmwareRecoveryMethod = (method?: CoreMethodDescriptor): boolean =>
10
- method?.name === 'firmwareUpdateV4' ||
11
- method?.name === 'checkAllFirmwareRelease' ||
12
- (method?.name === 'getDeviceState' && method.payload.scope === 'firmware');