@onekeyfe/hd-core 1.2.0-alpha.3 → 1.2.0-alpha.4

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 (112) hide show
  1. package/__tests__/preInitialize.test.ts +33 -0
  2. package/__tests__/protocol-v2.test.ts +1377 -480
  3. package/dist/api/FileRead.d.ts.map +1 -1
  4. package/dist/api/FileWrite.d.ts.map +1 -1
  5. package/dist/api/FirmwareUpdateV4.d.ts +20 -2
  6. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  7. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  8. package/dist/api/firmware/getBinary.d.ts +4 -0
  9. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  10. package/dist/api/index.d.ts +5 -10
  11. package/dist/api/index.d.ts.map +1 -1
  12. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +6 -0
  13. package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -0
  14. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +7 -0
  15. package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -0
  16. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -1
  17. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  18. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +1 -1
  19. package/dist/api/protocol-v2/{DeviceGetDeviceInfo.d.ts → DeviceInfoGet.d.ts} +10 -10
  20. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -0
  21. package/dist/api/protocol-v2/{FilesystemFixPermission.d.ts → FilesystemPermissionFix.d.ts} +2 -2
  22. package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -0
  23. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +6 -0
  24. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -0
  25. package/dist/api/protocol-v2/helpers.d.ts +24 -18
  26. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  27. package/dist/api/ton/TonSignData.d.ts +1 -5
  28. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/data-manager/DataManager.d.ts +1 -1
  31. package/dist/data-manager/DataManager.d.ts.map +1 -1
  32. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  33. package/dist/device/Device.d.ts +4 -1
  34. package/dist/device/Device.d.ts.map +1 -1
  35. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  36. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -1
  37. package/dist/index.d.ts +79 -54
  38. package/dist/index.js +1537 -1528
  39. package/dist/inject.d.ts.map +1 -1
  40. package/dist/protocols/protocol-v2/features.d.ts +12 -14
  41. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  42. package/dist/protocols/protocol-v2/firmware.d.ts +10 -9
  43. package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
  44. package/dist/types/api/firmwareUpdate.d.ts +1 -6
  45. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  46. package/dist/types/api/getDeviceInfo.d.ts +2 -0
  47. package/dist/types/api/getDeviceInfo.d.ts.map +1 -1
  48. package/dist/types/api/index.d.ts +6 -11
  49. package/dist/types/api/index.d.ts.map +1 -1
  50. package/dist/types/api/protocolV2.d.ts +12 -17
  51. package/dist/types/api/protocolV2.d.ts.map +1 -1
  52. package/dist/types/device.d.ts +1 -0
  53. package/dist/types/device.d.ts.map +1 -1
  54. package/dist/types/params.d.ts +1 -0
  55. package/dist/types/params.d.ts.map +1 -1
  56. package/dist/types/settings.d.ts +29 -2
  57. package/dist/types/settings.d.ts.map +1 -1
  58. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  59. package/dist/utils/patch.d.ts +1 -1
  60. package/dist/utils/patch.d.ts.map +1 -1
  61. package/package.json +4 -4
  62. package/src/api/FileRead.ts +14 -1
  63. package/src/api/FileWrite.ts +14 -1
  64. package/src/api/FirmwareUpdateV4.ts +933 -197
  65. package/src/api/GetOnekeyFeatures.ts +1 -1
  66. package/src/api/device/DeviceRebootToBoardloader.ts +4 -4
  67. package/src/api/device/DeviceRebootToBootloader.ts +4 -4
  68. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +11 -4
  69. package/src/api/index.ts +5 -10
  70. package/src/api/protocol-v2/{FactoryGetDeviceInfo.ts → DeviceFactoryInfoGet.ts} +3 -3
  71. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +32 -0
  72. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +3 -5
  73. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +2 -2
  74. package/src/api/protocol-v2/{DeviceGetDeviceInfo.ts → DeviceInfoGet.ts} +52 -22
  75. package/src/api/protocol-v2/DeviceReboot.ts +1 -1
  76. package/src/api/protocol-v2/{FilesystemFixPermission.ts → FilesystemPermissionFix.ts} +2 -2
  77. package/src/api/protocol-v2/{GetProtoVersion.ts → ProtocolInfoRequest.ts} +2 -2
  78. package/src/api/protocol-v2/helpers.ts +59 -43
  79. package/src/api/ton/TonSignData.ts +1 -5
  80. package/src/core/index.ts +19 -5
  81. package/src/data/messages/messages-protocol-v2.json +486 -1072
  82. package/src/data-manager/DataManager.ts +7 -0
  83. package/src/data-manager/connectSettings.ts +0 -6
  84. package/src/device/Device.ts +25 -14
  85. package/src/deviceProfile/buildDeviceFeatures.ts +60 -63
  86. package/src/deviceProfile/buildDeviceProfile.ts +77 -58
  87. package/src/inject.ts +10 -16
  88. package/src/protocols/protocol-v2/features.ts +26 -63
  89. package/src/protocols/protocol-v2/firmware.ts +11 -36
  90. package/src/types/api/firmwareUpdate.ts +10 -20
  91. package/src/types/api/getDeviceInfo.ts +2 -0
  92. package/src/types/api/index.ts +10 -20
  93. package/src/types/api/protocolV2.ts +22 -42
  94. package/src/types/device.ts +1 -0
  95. package/src/types/params.ts +4 -0
  96. package/src/types/settings.ts +44 -35
  97. package/src/utils/deviceFeaturesUtils.ts +45 -10
  98. package/dist/api/protocol-v2/DevReboot.d.ts +0 -7
  99. package/dist/api/protocol-v2/DevReboot.d.ts.map +0 -1
  100. package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
  101. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +0 -6
  102. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +0 -1
  103. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
  104. package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
  105. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
  106. package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
  107. package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
  108. package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
  109. package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
  110. package/src/api/protocol-v2/DevReboot.ts +0 -24
  111. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +0 -16
  112. package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -29
@@ -90,7 +90,7 @@ export default class GetOnekeyFeatures extends BaseMethod {
90
90
  async run() {
91
91
  if (this.device.isProtocolV2()) {
92
92
  // V2 没有 OnekeyGetFeatures 消息:
93
- // 取完整 DevGetDeviceInfo(含 SE/hash/build_id)后刷新结构化 features 缓存。
93
+ // 取完整 DeviceInfoGet(含 SE/hash/build_id)后刷新结构化 features 缓存。
94
94
  const deviceInfo = await requestProtocolV2DeviceInfo({
95
95
  commands: this.device.commands,
96
96
  request: PROTOCOL_V2_DEVICE_INFO_REQUEST,
@@ -1,4 +1,4 @@
1
- import { DevRebootType } from '@onekeyfe/hd-transport';
1
+ import { DeviceRebootType } from '@onekeyfe/hd-transport';
2
2
 
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
 
@@ -23,10 +23,10 @@ export default class DeviceRebootToBoardloader extends BaseMethod<RebootToBoardl
23
23
  }
24
24
 
25
25
  async run() {
26
- // Protocol V2 submodule firmware uses DevReboot with reboot_type enum.
26
+ // Protocol V2 submodule firmware uses DeviceReboot with reboot_type enum.
27
27
  if (this.device.isProtocolV2()) {
28
- const res = await this.device.commands.typedCall('DevReboot', 'Success', {
29
- reboot_type: DevRebootType.Boardloader,
28
+ const res = await this.device.commands.typedCall('DeviceReboot', 'Success', {
29
+ reboot_type: DeviceRebootType.Romloader,
30
30
  });
31
31
  return Promise.resolve(res.message);
32
32
  }
@@ -1,4 +1,4 @@
1
- import { DevRebootType } from '@onekeyfe/hd-transport';
1
+ import { DeviceRebootType } from '@onekeyfe/hd-transport';
2
2
 
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
 
@@ -23,10 +23,10 @@ export default class DeviceRebootToBootloader extends BaseMethod<RebootToBootloa
23
23
  }
24
24
 
25
25
  async run() {
26
- // Protocol V2 submodule firmware uses DevReboot with reboot_type enum.
26
+ // Protocol V2 submodule firmware uses DeviceReboot with reboot_type enum.
27
27
  if (this.device.isProtocolV2()) {
28
- const res = await this.device.commands.typedCall('DevReboot', 'Success', {
29
- reboot_type: DevRebootType.Bootloader,
28
+ const res = await this.device.commands.typedCall('DeviceReboot', 'Success', {
29
+ reboot_type: DeviceRebootType.Bootloader,
30
30
  });
31
31
  return Promise.resolve(res.message);
32
32
  }
@@ -138,6 +138,8 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
138
138
  // check device goto bootloader mode
139
139
  let isFirstCheck = true;
140
140
  let checkCount = 0;
141
+ let hasPromptedWebDevice = false;
142
+ let isPromptingWebDevice = false;
141
143
  // eslint-disable-next-line prefer-const
142
144
  let timeoutTimer: ReturnType<typeof setTimeout> | undefined;
143
145
 
@@ -158,23 +160,28 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
158
160
  if (
159
161
  checkCount > 4 &&
160
162
  DataManager.isBrowserWebUsb(DataManager.getSettings('env')) &&
161
- !this.payload.skipWebDevicePrompt
163
+ !this.payload.skipWebDevicePrompt &&
164
+ !hasPromptedWebDevice &&
165
+ !isPromptingWebDevice
162
166
  ) {
163
- clearInterval(intervalTimer);
164
- clearTimeout(timeoutTimer);
165
-
167
+ isPromptingWebDevice = true;
166
168
  try {
167
169
  this.postTipMessage(FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
168
170
  const confirmed = await this._promptDeviceInBootloaderForWebDevice();
171
+ hasPromptedWebDevice = true;
169
172
  if (confirmed) {
170
173
  await this._checkDeviceInBootloaderMode(connectId, intervalTimer, timeoutTimer);
171
174
  }
172
175
  } catch (e) {
176
+ clearInterval(intervalTimer);
177
+ clearTimeout(timeoutTimer);
173
178
  Log.log(
174
179
  'FirmwareUpdateBaseMethod [checkDeviceToBootloader] _promptDeviceInBootloaderForWebDevice failed: ',
175
180
  e
176
181
  );
177
182
  this.checkPromise?.reject(e);
183
+ } finally {
184
+ isPromptingWebDevice = false;
178
185
  }
179
186
  return;
180
187
  }
package/src/api/index.ts CHANGED
@@ -43,20 +43,15 @@ export { default as firmwareUpdateV4 } from './FirmwareUpdateV4';
43
43
  export { default as promptWebDeviceAccess } from './PromptWebDeviceAccess';
44
44
 
45
45
  // File system & device control API (Protocol V2 only)
46
- export { default as getProtoVersion } from './protocol-v2/GetProtoVersion';
46
+ export { default as protocolInfoRequest } from './protocol-v2/ProtocolInfoRequest';
47
47
  export { default as ping } from './protocol-v2/Ping';
48
48
  export { default as deviceReboot } from './protocol-v2/DeviceReboot';
49
- export { default as deviceGetDeviceInfo } from './protocol-v2/DeviceGetDeviceInfo';
50
- export { default as deviceGetOnboardingStatus } from './protocol-v2/DeviceGetOnboardingStatus';
49
+ export { default as deviceInfoGet } from './protocol-v2/DeviceInfoGet';
51
50
  export { default as deviceFirmwareUpdate } from './protocol-v2/DeviceFirmwareUpdate';
52
51
  export { default as deviceGetFirmwareUpdateStatus } from './protocol-v2/DeviceGetFirmwareUpdateStatus';
53
- export { default as devReboot } from './protocol-v2/DevReboot';
54
- export { default as devGetDeviceInfo } from './protocol-v2/DeviceGetDeviceInfo';
55
- export { default as devFirmwareUpdate } from './protocol-v2/DeviceFirmwareUpdate';
56
- export { default as devGetFirmwareUpdateStatus } from './protocol-v2/DeviceGetFirmwareUpdateStatus';
57
- export { default as factoryDeviceInfoSettings } from './protocol-v2/FactoryDeviceInfoSettings';
58
- export { default as factoryGetDeviceInfo } from './protocol-v2/FactoryGetDeviceInfo';
59
- export { default as filesystemFixPermission } from './protocol-v2/FilesystemFixPermission';
52
+ export { default as deviceFactoryInfoSet } from './protocol-v2/DeviceFactoryInfoSet';
53
+ export { default as deviceFactoryInfoGet } from './protocol-v2/DeviceFactoryInfoGet';
54
+ export { default as filesystemPermissionFix } from './protocol-v2/FilesystemPermissionFix';
60
55
  export { default as filesystemFormat } from './protocol-v2/FilesystemFormat';
61
56
  export { default as filesystemDiskControl } from './protocol-v2/FilesystemDiskControl';
62
57
  export { default as fileRead } from './FileRead';
@@ -1,6 +1,6 @@
1
1
  import { BaseMethod } from '../BaseMethod';
2
2
 
3
- export default class FactoryGetDeviceInfo extends BaseMethod {
3
+ export default class DeviceFactoryInfoGet extends BaseMethod {
4
4
  init() {
5
5
  // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
6
6
  this.requireProtocolV2 = true;
@@ -11,8 +11,8 @@ export default class FactoryGetDeviceInfo extends BaseMethod {
11
11
 
12
12
  async run() {
13
13
  const res = await this.device.commands.typedCall(
14
- 'FactoryGetDeviceInfo',
15
- 'FactoryDeviceInfo',
14
+ 'DeviceFactoryInfoGet',
15
+ 'DeviceFactoryInfo',
16
16
  {}
17
17
  );
18
18
  return Promise.resolve(res.message);
@@ -0,0 +1,32 @@
1
+ import { BaseMethod } from '../BaseMethod';
2
+
3
+ import type { DeviceFactoryInfoSetParams } from './helpers';
4
+
5
+ export default class DeviceFactoryInfoSet extends BaseMethod<DeviceFactoryInfoSetParams> {
6
+ init() {
7
+ // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
8
+ this.requireProtocolV2 = true;
9
+ this.skipForceUpdateCheck = true;
10
+ this.useDevicePassphraseState = false;
11
+ this.params = {
12
+ version: this.payload.version,
13
+ serial_number: this.payload.serial_number,
14
+ burn_in_completed: this.payload.burn_in_completed,
15
+ factory_test_completed: this.payload.factory_test_completed,
16
+ manufacture_time: this.payload.manufacture_time,
17
+ };
18
+ }
19
+
20
+ async run() {
21
+ const res = await this.device.commands.typedCall('DeviceFactoryInfoSet', 'Success', {
22
+ info: {
23
+ version: this.params.version,
24
+ serial_number: this.params.serial_number,
25
+ burn_in_completed: this.params.burn_in_completed,
26
+ factory_test_completed: this.params.factory_test_completed,
27
+ manufacture_time: this.params.manufacture_time,
28
+ },
29
+ });
30
+ return Promise.resolve(res.message);
31
+ }
32
+ }
@@ -29,7 +29,7 @@ export default class DeviceFirmwareUpdate extends BaseMethod<DeviceFirmwareUpdat
29
29
  const targets = normalizeFirmwareTargets(this.params);
30
30
  try {
31
31
  const res = await this.device.commands.typedCall(
32
- 'DevFirmwareUpdate',
32
+ 'DeviceFirmwareUpdateRequest',
33
33
  PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES,
34
34
  {
35
35
  targets,
@@ -37,13 +37,11 @@ export default class DeviceFirmwareUpdate extends BaseMethod<DeviceFirmwareUpdat
37
37
  {
38
38
  ...PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS,
39
39
  onIntermediateResponse: (response: MessageFromOneKey) => {
40
- if (response.type !== 'DevFirmwareInstallProgress') return;
41
- const progress = Number(response.message?.progress);
42
- if (!Number.isFinite(progress)) return;
40
+ if (response.type !== 'DeviceFirmwareUpdateStatus') return;
43
41
  this.postMessage(
44
42
  createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
45
43
  device: this.device.toMessageObject() as KnownDevice,
46
- progress: Math.min(Math.max(progress, 0), 100),
44
+ progress: 99,
47
45
  progressType: 'installingFirmware',
48
46
  })
49
47
  );
@@ -11,8 +11,8 @@ export default class DeviceGetFirmwareUpdateStatus extends BaseMethod {
11
11
 
12
12
  async run() {
13
13
  const res = await this.device.commands.typedCall(
14
- 'DevGetFirmwareUpdateStatus',
15
- 'DevFirmwareUpdateStatus',
14
+ 'DeviceFirmwareUpdateStatusGet',
15
+ 'DeviceFirmwareUpdateStatus',
16
16
  {}
17
17
  );
18
18
  return Promise.resolve(res.message);
@@ -3,11 +3,12 @@ import { createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
3
3
  import { UI_REQUEST } from '../../constants/ui-request';
4
4
  import { PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS } from '../../protocols/protocol-v2';
5
5
  import { BaseMethod } from '../BaseMethod';
6
+ import { invalidParameter } from '../helpers/filesystemValidation';
6
7
 
7
- export type DeviceGetDeviceInfoTargets = {
8
+ export type DeviceInfoGetTargets = {
8
9
  hw?: boolean;
9
10
  fw?: boolean;
10
- bt?: boolean;
11
+ coprocessor?: boolean;
11
12
  se1?: boolean;
12
13
  se2?: boolean;
13
14
  se3?: boolean;
@@ -15,22 +16,22 @@ export type DeviceGetDeviceInfoTargets = {
15
16
  status?: boolean;
16
17
  };
17
18
 
18
- export type DeviceGetDeviceInfoTypes = {
19
+ export type DeviceInfoGetTypes = {
19
20
  version?: boolean;
20
21
  build_id?: boolean;
21
22
  hash?: boolean;
22
23
  specific?: boolean;
23
24
  };
24
25
 
25
- export type DeviceGetDeviceInfoParams = {
26
- targets?: DeviceGetDeviceInfoTargets;
27
- types?: DeviceGetDeviceInfoTypes;
26
+ export type DeviceInfoGetParams = {
27
+ targets?: DeviceInfoGetTargets;
28
+ types?: DeviceInfoGetTypes;
28
29
  };
29
30
 
30
- const TARGET_KEYS: (keyof DeviceGetDeviceInfoTargets)[] = [
31
+ const TARGET_KEYS: (keyof DeviceInfoGetTargets)[] = [
31
32
  'hw',
32
33
  'fw',
33
- 'bt',
34
+ 'coprocessor',
34
35
  'se1',
35
36
  'se2',
36
37
  'se3',
@@ -38,16 +39,16 @@ const TARGET_KEYS: (keyof DeviceGetDeviceInfoTargets)[] = [
38
39
  'status',
39
40
  ];
40
41
 
41
- const TYPE_KEYS: (keyof DeviceGetDeviceInfoTypes)[] = ['version', 'build_id', 'hash', 'specific'];
42
+ const TYPE_KEYS: (keyof DeviceInfoGetTypes)[] = ['version', 'build_id', 'hash', 'specific'];
42
43
 
43
- const DEFAULT_TARGETS: DeviceGetDeviceInfoTargets = {
44
+ const DEFAULT_TARGETS: DeviceInfoGetTargets = {
44
45
  hw: true,
45
46
  fw: true,
46
- bt: true,
47
+ coprocessor: true,
47
48
  status: true,
48
49
  };
49
50
 
50
- const DEFAULT_TYPES: DeviceGetDeviceInfoTypes = {
51
+ const DEFAULT_TYPES: DeviceInfoGetTypes = {
51
52
  version: true,
52
53
  specific: true,
53
54
  };
@@ -69,16 +70,48 @@ function pickBooleanKeys<T extends Record<string, boolean | undefined>>(
69
70
  return hasKey ? result : undefined;
70
71
  }
71
72
 
73
+ function assertKnownKeys(value: unknown, keys: string[], name: string) {
74
+ if (value == null) return;
75
+ if (typeof value !== 'object' || Array.isArray(value)) {
76
+ throw invalidParameter(`Parameter [${name}] must be an object.`);
77
+ }
78
+ const allowed = new Set(keys);
79
+ const unknownKeys = Object.keys(value).filter(key => !allowed.has(key));
80
+ if (unknownKeys.length > 0) {
81
+ throw invalidParameter(
82
+ `Parameter [${name}] contains unsupported key(s): ${unknownKeys.join(', ')}.`
83
+ );
84
+ }
85
+ }
86
+
87
+ function normalizeTargets(value: unknown): DeviceInfoGetTargets | undefined {
88
+ assertKnownKeys(
89
+ value,
90
+ TARGET_KEYS.map(key => String(key)),
91
+ 'targets'
92
+ );
93
+ return pickBooleanKeys<DeviceInfoGetTargets>(value, TARGET_KEYS);
94
+ }
95
+
96
+ function normalizeTypes(value: unknown): DeviceInfoGetTypes | undefined {
97
+ assertKnownKeys(
98
+ value,
99
+ TYPE_KEYS.map(key => String(key)),
100
+ 'types'
101
+ );
102
+ return pickBooleanKeys<DeviceInfoGetTypes>(value, TYPE_KEYS);
103
+ }
104
+
72
105
  /**
73
- * 原生 DevGetDeviceInfo(Protocol V2 only)。
106
+ * 原生 DeviceInfoGet(Protocol V2 only)。
74
107
  *
75
108
  * 与 getDeviceInfo 不同:不构建 DeviceProfile、不更新设备缓存,
76
109
  * 按调用方给定的 targets/types 原样请求并返回未加工的 DeviceInfo 消息,
77
110
  * 用于调试固件字段上报。
78
111
  */
79
- export default class DeviceGetDeviceInfo extends BaseMethod<{
80
- targets: DeviceGetDeviceInfoTargets;
81
- types: DeviceGetDeviceInfoTypes;
112
+ export default class DeviceInfoGet extends BaseMethod<{
113
+ targets: DeviceInfoGetTargets;
114
+ types: DeviceInfoGetTypes;
82
115
  }> {
83
116
  init() {
84
117
  // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
@@ -91,11 +124,8 @@ export default class DeviceGetDeviceInfo extends BaseMethod<{
91
124
  this.useDevicePassphraseState = false;
92
125
  this.skipForceUpdateCheck = true;
93
126
  this.params = {
94
- targets:
95
- pickBooleanKeys<DeviceGetDeviceInfoTargets>(this.payload.targets, TARGET_KEYS) ??
96
- DEFAULT_TARGETS,
97
- types:
98
- pickBooleanKeys<DeviceGetDeviceInfoTypes>(this.payload.types, TYPE_KEYS) ?? DEFAULT_TYPES,
127
+ targets: normalizeTargets(this.payload.targets) ?? DEFAULT_TARGETS,
128
+ types: normalizeTypes(this.payload.types) ?? DEFAULT_TYPES,
99
129
  };
100
130
  }
101
131
 
@@ -105,7 +135,7 @@ export default class DeviceGetDeviceInfo extends BaseMethod<{
105
135
  }
106
136
 
107
137
  const res = await this.device.commands.typedCall(
108
- 'DevGetDeviceInfo',
138
+ 'DeviceInfoGet',
109
139
  'DeviceInfo',
110
140
  {
111
141
  targets: this.params.targets,
@@ -16,7 +16,7 @@ export default class DeviceReboot extends BaseMethod<DeviceRebootParams> {
16
16
  }
17
17
 
18
18
  async run() {
19
- const res = await this.device.commands.typedCall('DevReboot', 'Success', {
19
+ const res = await this.device.commands.typedCall('DeviceReboot', 'Success', {
20
20
  reboot_type: normalizeRebootType(this.params.reboot_type ?? this.params.rebootType),
21
21
  });
22
22
  return Promise.resolve(res.message);
@@ -1,6 +1,6 @@
1
1
  import { BaseMethod } from '../BaseMethod';
2
2
 
3
- export default class FilesystemFixPermission extends BaseMethod {
3
+ export default class FilesystemPermissionFix extends BaseMethod {
4
4
  init() {
5
5
  // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
6
6
  this.requireProtocolV2 = true;
@@ -10,7 +10,7 @@ export default class FilesystemFixPermission extends BaseMethod {
10
10
  }
11
11
 
12
12
  async run() {
13
- const res = await this.device.commands.typedCall('FilesystemFixPermission', 'Success', {});
13
+ const res = await this.device.commands.typedCall('FilesystemPermissionFix', 'Success', {});
14
14
  return Promise.resolve(res.message);
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  import { BaseMethod } from '../BaseMethod';
2
2
 
3
- export default class GetProtoVersion extends BaseMethod {
3
+ export default class ProtocolInfoRequest extends BaseMethod {
4
4
  init() {
5
5
  // Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
6
6
  this.requireProtocolV2 = true;
@@ -10,7 +10,7 @@ export default class GetProtoVersion extends BaseMethod {
10
10
  }
11
11
 
12
12
  async run() {
13
- const res = await this.device.commands.typedCall('GetProtoVersion', 'ProtoVersion', {});
13
+ const res = await this.device.commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {});
14
14
  return Promise.resolve(res.message);
15
15
  }
16
16
  }
@@ -1,18 +1,15 @@
1
- import { DevRebootType } from '@onekeyfe/hd-transport';
1
+ import { DeviceRebootType } from '@onekeyfe/hd-transport';
2
2
 
3
3
  import { invalidParameter, validateNonEmptyString } from '../helpers/filesystemValidation';
4
+ import { ProtocolV2FirmwareTargetType } from '../../protocols/protocol-v2/firmware';
4
5
 
5
6
  import type {
6
- DevFirmwareTarget,
7
- DevFirmwareTargetType,
7
+ DeviceFirmwareTarget,
8
+ DeviceFirmwareTargetType,
8
9
  TransportCallOptions,
9
10
  } from '@onekeyfe/hd-transport';
10
11
 
11
- export type RebootTypeInput =
12
- | DevRebootType
13
- | keyof typeof DevRebootType
14
- | string
15
- | number;
12
+ export type RebootTypeInput = DeviceRebootType | keyof typeof DeviceRebootType | string | number;
16
13
 
17
14
  export type DeviceRebootParams = {
18
15
  rebootType?: RebootTypeInput;
@@ -20,48 +17,54 @@ export type DeviceRebootParams = {
20
17
  };
21
18
 
22
19
  export type DeviceFirmwareTargetInput =
23
- | DevFirmwareTarget
20
+ | DeviceFirmwareTarget
24
21
  | {
25
- targetId?: DevFirmwareTargetType | string | number;
26
- target_id?: DevFirmwareTargetType | string | number;
22
+ targetId?: DeviceFirmwareTargetType | string | number;
23
+ target_id?: DeviceFirmwareTargetType | string | number;
27
24
  path: string;
28
25
  };
29
26
 
30
27
  export type DeviceFirmwareUpdateParams = {
31
28
  targets?: DeviceFirmwareTargetInput[];
32
- targetId?: DevFirmwareTargetType | string | number;
33
- target_id?: DevFirmwareTargetType | string | number;
29
+ targetId?: DeviceFirmwareTargetType | string | number;
30
+ target_id?: DeviceFirmwareTargetType | string | number;
34
31
  path?: string;
35
32
  };
36
33
 
37
- export type FactoryDeviceInfoSettingsParams = {
38
- serial_no?: string;
39
- serialNo?: string;
40
- cpu_info?: string;
41
- cpuInfo?: string;
42
- pre_firmware?: string;
43
- preFirmware?: string;
34
+ export type DeviceFactoryInfoSetParams = {
35
+ version?: number;
36
+ serial_number?: string;
37
+ burn_in_completed?: boolean;
38
+ factory_test_completed?: boolean;
39
+ manufacture_time?: {
40
+ year: number;
41
+ month: number;
42
+ day: number;
43
+ hour: number;
44
+ minute: number;
45
+ second: number;
46
+ };
44
47
  };
45
48
 
46
- const DEV_REBOOT_TYPES: Record<string, DevRebootType> = {
47
- Normal: DevRebootType.Normal,
48
- normal: DevRebootType.Normal,
49
- Romloader: DevRebootType.Boardloader,
50
- romloader: DevRebootType.Boardloader,
51
- Boardloader: DevRebootType.Boardloader,
52
- boardloader: DevRebootType.Boardloader,
53
- Bootloader: DevRebootType.Bootloader,
54
- bootloader: DevRebootType.Bootloader,
49
+ const DEVICE_REBOOT_TYPES: Record<string, DeviceRebootType> = {
50
+ Normal: DeviceRebootType.Normal,
51
+ normal: DeviceRebootType.Normal,
52
+ Romloader: DeviceRebootType.Romloader,
53
+ romloader: DeviceRebootType.Romloader,
54
+ Boardloader: DeviceRebootType.Romloader,
55
+ boardloader: DeviceRebootType.Romloader,
56
+ Bootloader: DeviceRebootType.Bootloader,
57
+ bootloader: DeviceRebootType.Bootloader,
55
58
  };
56
59
 
57
60
  export const PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS: TransportCallOptions = {
58
- intermediateTypes: ['DevFirmwareInstallProgress'],
61
+ intermediateTypes: ['DeviceFirmwareUpdateStatus'],
59
62
  };
60
63
 
61
64
  export const PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES: (
62
65
  | 'Success'
63
- | 'DevFirmwareUpdateStatus'
64
- )[] = ['Success', 'DevFirmwareUpdateStatus'];
66
+ | 'DeviceFirmwareUpdateStatus'
67
+ )[] = ['Success', 'DeviceFirmwareUpdateStatus'];
65
68
 
66
69
  export const getProtocolV2UnknownErrorText = (error: unknown) => {
67
70
  if (!error) {
@@ -120,31 +123,42 @@ export const isProtocolV2DeviceDisconnectedError = (error: unknown) => {
120
123
  );
121
124
  };
122
125
 
123
- export function normalizeRebootType(value: RebootTypeInput | undefined): DevRebootType {
126
+ export function normalizeRebootType(value: RebootTypeInput | undefined): DeviceRebootType {
124
127
  if (typeof value === 'number') return value;
125
128
  if (typeof value === 'string') {
126
129
  const numeric = Number(value);
127
130
  if (Number.isFinite(numeric)) return numeric;
128
- if (value in DEV_REBOOT_TYPES) return DEV_REBOOT_TYPES[value];
131
+ if (value in DEVICE_REBOOT_TYPES) return DEVICE_REBOOT_TYPES[value];
129
132
  }
130
- return DevRebootType.Normal;
133
+ return DeviceRebootType.Normal;
131
134
  }
132
135
 
133
- // 当前 firmware-pro2 子模块的 DevFirmwareTargetType 合法值。
134
- const VALID_FIRMWARE_TARGET_IDS = new Set<number>([0, 1, 2, 3, 4, 5, 6, 10]);
136
+ // 当前 firmware-pro2 子模块的 DeviceFirmwareTargetType 合法值从生成 enum 派生,
137
+ // 避免协议枚举增减时这里继续保留过期手写编号。
138
+ const VALID_FIRMWARE_TARGET_IDS = new Set<number>(
139
+ Object.values(ProtocolV2FirmwareTargetType).filter(value => typeof value === 'number') as number[]
140
+ );
141
+ const FIRMWARE_TARGET_ID_BY_NAME = new Map<string, DeviceFirmwareTargetType>(
142
+ Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) =>
143
+ VALID_FIRMWARE_TARGET_IDS.has(value)
144
+ ? [[key, value as DeviceFirmwareTargetType]]
145
+ : []
146
+ )
147
+ );
135
148
 
136
149
  function normalizeTargetId(
137
- value: DevFirmwareTargetType | string | number | undefined,
150
+ value: DeviceFirmwareTargetType | string | number | undefined,
138
151
  name: string
139
- ): DevFirmwareTargetType {
152
+ ): DeviceFirmwareTargetType {
140
153
  if (value === undefined || value === null) {
141
154
  throw invalidParameter(`Missing required parameter: ${name}`);
142
155
  }
143
- const numeric = typeof value === 'number' ? value : Number(value);
144
- // 校验值域:仅接受 DevFirmwareTargetType 中定义的 target id,
156
+ const named = typeof value === 'string' ? FIRMWARE_TARGET_ID_BY_NAME.get(value) : undefined;
157
+ const numeric = named ?? (typeof value === 'number' ? value : Number(value));
158
+ // 校验值域:仅接受 DeviceFirmwareTargetType 中定义的 target id,
145
159
  // 不再放行任意非负整数。
146
160
  if (Number.isSafeInteger(numeric) && VALID_FIRMWARE_TARGET_IDS.has(numeric)) {
147
- return numeric as DevFirmwareTargetType;
161
+ return numeric as DeviceFirmwareTargetType;
148
162
  }
149
163
  throw invalidParameter(
150
164
  `Parameter [${name}] must be a valid firmware target id (one of ${[
@@ -153,7 +167,9 @@ function normalizeTargetId(
153
167
  );
154
168
  }
155
169
 
156
- export function normalizeFirmwareTargets(params: DeviceFirmwareUpdateParams): DevFirmwareTarget[] {
170
+ export function normalizeFirmwareTargets(
171
+ params: DeviceFirmwareUpdateParams
172
+ ): DeviceFirmwareTarget[] {
157
173
  const targets =
158
174
  params.targets ??
159
175
  (params.path
@@ -51,11 +51,7 @@ export default class TonSignData extends BaseMethod<HardwareTonSignData> {
51
51
  }
52
52
 
53
53
  getVersionRange() {
54
- return {
55
- pro2: {
56
- min: '0.0.0',
57
- },
58
- };
54
+ return {};
59
55
  }
60
56
 
61
57
  async run() {
package/src/core/index.ts CHANGED
@@ -56,7 +56,6 @@ import TransportManager from '../data-manager/TransportManager';
56
56
  import DeviceConnector from '../device/DeviceConnector';
57
57
  import RequestQueue from './RequestQueue';
58
58
  import { getSynchronize } from '../utils/getSynchronize';
59
- import { setProtocolV2DeviceInfoMock } from '../protocols/protocol-v2/features';
60
59
 
61
60
  import type { ConnectSettings, Features, KnownDevice } from '../types';
62
61
  import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
@@ -96,6 +95,7 @@ const parseInitOptions = (method?: BaseMethod): InitOptions => ({
96
95
  deviceId: method?.payload.deviceId,
97
96
  deriveCardano: method && hasDeriveCardano(method),
98
97
  connectProtocol: method?.payload.connectProtocol,
98
+ protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
99
99
  });
100
100
 
101
101
  let _core: Core;
@@ -223,9 +223,15 @@ const handlePreWarmSignal = async (
223
223
  message: CoreMessage,
224
224
  method: BaseMethod
225
225
  ): Promise<any> => {
226
+ const createAckResponse = () => {
227
+ completeMethodRequestContext(method);
228
+ method.dispose();
229
+ return createResponseMessage(method.responseID, true, true);
230
+ };
231
+
226
232
  // no connectId: can't target a device safely, skip pre-warm (ack only)
227
233
  if (!method.connectId) {
228
- return createResponseMessage(method.responseID, true, true);
234
+ return createAckResponse();
229
235
  }
230
236
 
231
237
  const key = method.getPreWarmKey();
@@ -238,12 +244,12 @@ const handlePreWarmSignal = async (
238
244
  } catch {
239
245
  // pre-warm is best-effort; ignore its failure for the coalesced caller
240
246
  }
241
- return createResponseMessage(method.responseID, true, true);
247
+ return createAckResponse();
242
248
  }
243
249
 
244
250
  const doneAt = preWarmDoneAt.get(key);
245
251
  if (typeof doneAt === 'number' && Date.now() - doneAt <= method.preWarmTtl) {
246
- return createResponseMessage(method.responseID, true, true);
252
+ return createAckResponse();
247
253
  }
248
254
 
249
255
  const run = onCallDevice(context, message, method);
@@ -732,6 +738,15 @@ function initDevice(method: BaseMethod) {
732
738
 
733
739
  if (method.connectId) {
734
740
  device = _deviceList.getDevice(method.connectId);
741
+ if (!device && method.name === 'firmwareUpdateV4' && allDevices.length === 1) {
742
+ const [singleDevice] = allDevices;
743
+ if (singleDevice.isBootloader()) {
744
+ Log.debug(
745
+ 'firmwareUpdateV4 uses the only bootloader device when connectId changed after reboot'
746
+ );
747
+ device = singleDevice;
748
+ }
749
+ }
735
750
  } else if (allDevices.length === 1) {
736
751
  [device] = allDevices;
737
752
  } else if (allDevices.length > 1) {
@@ -1439,7 +1454,6 @@ export const init = async (
1439
1454
  try {
1440
1455
  try {
1441
1456
  await DataManager.load(settings);
1442
- setProtocolV2DeviceInfoMock(settings.protocolV2DeviceInfoMockEnabled ?? false);
1443
1457
  initTransport(Transport, plugin);
1444
1458
  } catch {
1445
1459
  Log.error('DataManager.load error');