@onekeyfe/hd-core 1.1.19-alpha.0 → 1.1.19-alpha.2

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 (52) hide show
  1. package/dist/api/BaseMethod.d.ts +5 -0
  2. package/dist/api/BaseMethod.d.ts.map +1 -1
  3. package/dist/api/FirmwareUpdate.d.ts.map +1 -1
  4. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  5. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  6. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  7. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  8. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -4
  9. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  10. package/dist/api/firmware/bootloaderHelper.d.ts +1 -1
  11. package/dist/api/firmware/bootloaderHelper.d.ts.map +1 -1
  12. package/dist/api/firmware/updateBootloader.d.ts +1 -1
  13. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  14. package/dist/api/firmware/uploadFirmware.d.ts +5 -5
  15. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  16. package/dist/core/index.d.ts +6 -3
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/device/Device.d.ts +5 -2
  19. package/dist/device/Device.d.ts.map +1 -1
  20. package/dist/device/DeviceCommands.d.ts +8 -6
  21. package/dist/device/DeviceCommands.d.ts.map +1 -1
  22. package/dist/index.d.ts +51 -6
  23. package/dist/index.js +404 -76
  24. package/dist/types/device.d.ts +3 -0
  25. package/dist/types/device.d.ts.map +1 -1
  26. package/dist/utils/index.d.ts +1 -0
  27. package/dist/utils/index.d.ts.map +1 -1
  28. package/dist/utils/logger.d.ts +1 -1
  29. package/dist/utils/logger.d.ts.map +1 -1
  30. package/dist/utils/patch.d.ts +1 -1
  31. package/dist/utils/patch.d.ts.map +1 -1
  32. package/dist/utils/tracing.d.ts +34 -0
  33. package/dist/utils/tracing.d.ts.map +1 -0
  34. package/package.json +4 -4
  35. package/src/api/BaseMethod.ts +38 -1
  36. package/src/api/FirmwareUpdate.ts +2 -1
  37. package/src/api/FirmwareUpdateV2.ts +2 -1
  38. package/src/api/FirmwareUpdateV3.ts +2 -0
  39. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +46 -15
  40. package/src/api/evm/EVMSignTypedData.ts +8 -2
  41. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -18
  42. package/src/api/firmware/bootloaderHelper.ts +3 -1
  43. package/src/api/firmware/updateBootloader.ts +6 -3
  44. package/src/api/firmware/uploadFirmware.ts +87 -21
  45. package/src/core/index.ts +135 -27
  46. package/src/data/messages/messages.json +11 -1
  47. package/src/device/Device.ts +24 -3
  48. package/src/device/DeviceCommands.ts +55 -13
  49. package/src/types/device.ts +5 -0
  50. package/src/utils/index.ts +1 -0
  51. package/src/utils/logger.ts +3 -2
  52. package/src/utils/tracing.ts +238 -0
@@ -15,6 +15,11 @@ import { DEVICE, IFRAME, createUiMessage } from '../../events';
15
15
  import { getDeviceFirmwareVersion, getMethodVersionRange } from '../../utils';
16
16
  import { UI_REQUEST } from '../../constants/ui-request';
17
17
  import { onDeviceButtonHandler } from '../../core';
18
+ import {
19
+ completeRequestContext,
20
+ createRequestContext,
21
+ updateRequestContext,
22
+ } from '../../utils/tracing';
18
23
 
19
24
  import type { Device, DeviceEvents } from '../../device/Device';
20
25
  import type { CoreApi } from '../../types';
@@ -321,6 +326,27 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
321
326
 
322
327
  method.connector = this.connector;
323
328
  method.postMessage = this.postMessage;
329
+ if (this.context) {
330
+ method.setContext?.(this.context);
331
+ }
332
+
333
+ method.requestContext = createRequestContext(method.responseID, methodName, {
334
+ sdkInstanceId: this.sdkInstanceId,
335
+ connectId: this.payload.connectId,
336
+ parentResponseID: this.responseID,
337
+ });
338
+
339
+ const onSignalAbort = () => {
340
+ this.abortController?.abort(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
341
+ };
342
+
343
+ const buttonListener = (...[device, request]: [...DeviceEvents['button']]) => {
344
+ if (request.code === 'ButtonRequest_PinEntry' || request.code === 'ButtonRequest_AttachPin') {
345
+ onSignalAbort();
346
+ } else {
347
+ onDeviceButtonHandler(device, request);
348
+ }
349
+ };
324
350
 
325
351
  let result: AllNetworkAddress[];
326
352
  try {
@@ -328,23 +354,15 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
328
354
  method.setDevice?.(this.device);
329
355
  method.context = this.context;
330
356
 
331
- const onSignalAbort = () => {
332
- this.abortController?.abort(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
333
- };
334
-
335
- const _onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
336
- if (
337
- request.code === 'ButtonRequest_PinEntry' ||
338
- request.code === 'ButtonRequest_AttachPin'
339
- ) {
340
- onSignalAbort();
341
- } else {
342
- onDeviceButtonHandler(device, request);
343
- }
344
- };
357
+ if (method.requestContext && this.device) {
358
+ updateRequestContext(method.requestContext.responseID, {
359
+ deviceInstanceId: this.device.instanceId,
360
+ commandsInstanceId: this.device.commands?.instanceId,
361
+ });
362
+ }
345
363
 
346
364
  // pro pin event
347
- this.device.on(DEVICE.BUTTON, _onDeviceButtonHandler);
365
+ this.device.on(DEVICE.BUTTON, buttonListener);
348
366
  // classic pin event
349
367
  this.device.on(DEVICE.PIN, onSignalAbort);
350
368
  this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
@@ -365,6 +383,9 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
365
383
  rootFingerprint,
366
384
  },
367
385
  }));
386
+ if (method.requestContext) {
387
+ completeRequestContext(method.requestContext.responseID);
388
+ }
368
389
  } catch (e: any) {
369
390
  const error = handleSkippableHardwareError(e, this.device, method);
370
391
 
@@ -383,6 +404,16 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
383
404
  } else {
384
405
  throw e;
385
406
  }
407
+ if (method.requestContext) {
408
+ completeRequestContext(
409
+ method.requestContext.responseID,
410
+ e instanceof Error ? e : new Error(String(e))
411
+ );
412
+ }
413
+ } finally {
414
+ this.device.off(DEVICE.BUTTON, buttonListener);
415
+ this.device.off(DEVICE.PIN, onSignalAbort);
416
+ this.device.off(DEVICE.PASSPHRASE, onSignalAbort);
386
417
  }
387
418
 
388
419
  return result;
@@ -1,7 +1,7 @@
1
1
  import semver from 'semver';
2
2
  import { get } from 'lodash';
3
3
  import BigNumber from 'bignumber.js';
4
- import { ERRORS, HardwareErrorCode, EDeviceType } from '@onekeyfe/hd-shared';
4
+ import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
5
5
  import {
6
6
  EthereumTypedDataSignature,
7
7
  EthereumTypedDataStructAck,
@@ -337,9 +337,15 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
337
337
  let biggerLimit = 1024; // 1k
338
338
 
339
339
  const currentVersion = getDeviceFirmwareVersion(this.device.features).join('.');
340
+ const currentDeviceType = getDeviceType(this.device.features);
340
341
  const supportBiggerDataVersion = '4.4.0';
341
342
 
342
- if (semver.gte(currentVersion, supportBiggerDataVersion)) {
343
+ const supportBiggerData =
344
+ DeviceModelToTypes.model_classic1s.includes(currentDeviceType) ||
345
+ (DeviceModelToTypes.model_touch.includes(currentDeviceType) &&
346
+ semver.gte(currentVersion, supportBiggerDataVersion));
347
+
348
+ if (supportBiggerData) {
343
349
  biggerLimit = 1536; // 1.5k
344
350
  }
345
351
 
@@ -1,29 +1,27 @@
1
1
  import {
2
- createDeferred,
3
- Deferred,
4
2
  EDeviceType,
5
3
  ERRORS,
6
4
  HardwareError,
7
5
  HardwareErrorCode,
6
+ createDeferred,
8
7
  } from '@onekeyfe/hd-shared';
9
- import { RebootType } from '@onekeyfe/hd-transport';
10
- import type { KnownDevice } from '../../types';
11
8
 
12
- import {
13
- UI_REQUEST,
14
- createUiMessage,
15
- FirmwareUpdateTipMessage,
16
- IFirmwareUpdateTipMessage,
17
- IFirmwareUpdateProgressType,
18
- } from '../../events/ui-request';
9
+ import { FirmwareUpdateTipMessage, UI_REQUEST, createUiMessage } from '../../events/ui-request';
19
10
  import { DevicePool } from '../../device/DevicePool';
20
- import { getDeviceType, wait, getLogger, LoggerNames, getDeviceUUID } from '../../utils';
11
+ import { LoggerNames, getDeviceType, getDeviceUUID, getLogger, wait } from '../../utils';
21
12
  import { DeviceModelToTypes } from '../../types';
22
13
  import { DataManager } from '../../data-manager';
23
-
24
14
  import { BaseMethod } from '../BaseMethod';
25
15
  import { DEVICE } from '../../events';
26
- import { PROTO } from '../../constants';
16
+
17
+ import type {
18
+ IFirmwareUpdateProgressType,
19
+ IFirmwareUpdateTipMessage,
20
+ } from '../../events/ui-request';
21
+ import type { PROTO } from '../../constants';
22
+ import type { RebootType } from '@onekeyfe/hd-transport';
23
+ import type { Deferred } from '@onekeyfe/hd-shared';
24
+ import type { KnownDevice } from '../../types';
27
25
  import type { TypedResponseMessage } from '../../device/DeviceCommands';
28
26
 
29
27
  const Log = getLogger(LoggerNames.Method);
@@ -266,16 +264,16 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
266
264
  */
267
265
  async startEmmcFirmwareUpdate({ path }: { path: string }) {
268
266
  const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
269
- let updaeteResponse: TypedResponseMessage<'Success'>;
267
+ let updateResponse: TypedResponseMessage<'Success'>;
270
268
  try {
271
- updaeteResponse = await typedCall('FirmwareUpdateEmmc', 'Success', {
269
+ updateResponse = await typedCall('FirmwareUpdateEmmc', 'Success', {
272
270
  path,
273
271
  reboot_on_success: true,
274
272
  });
275
273
  } catch (error) {
276
274
  if (isDeviceDisconnectedError(error)) {
277
275
  Log.log('Rebooting device');
278
- updaeteResponse = {
276
+ updateResponse = {
279
277
  type: 'Success',
280
278
  message: { message: FIRMWARE_UPDATE_CONFIRM },
281
279
  };
@@ -283,7 +281,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
283
281
  throw error;
284
282
  }
285
283
  }
286
- if (updaeteResponse.type !== 'Success') {
284
+ if (updateResponse.type !== 'Success') {
287
285
  throw ERRORS.TypedError(HardwareErrorCode.FirmwareError, 'firmware update error');
288
286
  }
289
287
  this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdating);
@@ -1,8 +1,10 @@
1
1
  import semver from 'semver';
2
2
  import { EDeviceType } from '@onekeyfe/hd-shared';
3
- import { Features, IVersionArray } from '../../types';
3
+
4
4
  import { getDeviceType } from '../../utils';
5
5
 
6
+ import type { Features, IVersionArray } from '../../types';
7
+
6
8
  export function shouldUpdateBootloaderForClassicAndMini({
7
9
  currentVersion,
8
10
  bootloaderVersion,
@@ -1,11 +1,14 @@
1
1
  import ByteBuffer from 'bytebuffer';
2
2
  import semver from 'semver';
3
- import type { EFirmwareType } from '@onekeyfe/hd-shared';
4
- import { DeviceModelToTypes, Features } from '../../types';
5
- import { getDeviceType, getDeviceBootloaderVersion, getDeviceFirmwareVersion } from '../../utils';
3
+
4
+ import { DeviceModelToTypes } from '../../types';
5
+ import { getDeviceBootloaderVersion, getDeviceFirmwareVersion, getDeviceType } from '../../utils';
6
6
  import { DataManager } from '../../data-manager';
7
7
  import { shouldUpdateBootloaderForClassicAndMini } from './bootloaderHelper';
8
8
 
9
+ import type { Features } from '../../types';
10
+ import type { EFirmwareType } from '@onekeyfe/hd-shared';
11
+
9
12
  export function checkNeedUpdateBootForTouch(features: Features, firmwareType: EFirmwareType) {
10
13
  const deviceType = getDeviceType(features);
11
14
  if (!DeviceModelToTypes.model_touch.includes(deviceType)) return false;
@@ -2,29 +2,28 @@ import semver from 'semver';
2
2
  import { blake2s } from '@noble/hashes/blake2s';
3
3
  import JSZip from 'jszip';
4
4
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
5
- import { Success } from '@onekeyfe/hd-transport';
5
+
6
+ import { getDeviceFirmwareVersion } from '../../utils/deviceVersionUtils';
6
7
  import {
7
- wait,
8
+ LoggerNames,
8
9
  getDeviceBootloaderVersion,
9
10
  getDeviceType,
10
- LoggerNames,
11
11
  getLogger,
12
+ wait,
12
13
  } from '../../utils';
13
- import {
14
- DEVICE,
15
- CoreMessage,
16
- createUiMessage,
17
- UI_REQUEST,
18
- IFirmwareUpdateProgressType,
19
- } from '../../events';
20
- import { PROTO } from '../../constants';
21
- import type { Device } from '../../device/Device';
22
- import type { TypedCall, TypedResponseMessage } from '../../device/DeviceCommands';
23
- import { DeviceModelToTypes, KnownDevice } from '../../types';
14
+ import { DEVICE, UI_REQUEST, createUiMessage } from '../../events';
15
+ import { DeviceModelToTypes } from '../../types';
24
16
  import { bytesToHex } from '../helpers/hexUtils';
25
17
  import { DataManager } from '../../data-manager';
26
18
  import { DevicePool } from '../../device/DevicePool';
27
19
 
20
+ import type { KnownDevice } from '../../types';
21
+ import type { TypedCall, TypedResponseMessage } from '../../device/DeviceCommands';
22
+ import type { PROTO } from '../../constants';
23
+ import type { CoreMessage, IFirmwareUpdateProgressType } from '../../events';
24
+ import type { Success } from '@onekeyfe/hd-transport';
25
+ import type { Device } from '../../device/Device';
26
+
28
27
  const NEW_BOOT_UPRATE_FIRMWARE_VERSION = '2.4.5';
29
28
  const SESSION_ERROR = 'session not found';
30
29
  const FIRMWARE_UPDATE_CONFIRM = 'Firmware install confirmed';
@@ -105,29 +104,96 @@ export const uploadFirmware = async (
105
104
  rebootOnSuccess,
106
105
  }: PROTO.FirmwareUpload & {
107
106
  rebootOnSuccess?: boolean;
108
- }
107
+ },
108
+ isUpdateBootloader?: boolean
109
109
  ) => {
110
110
  const deviceType = getDeviceType(device.features);
111
111
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
112
112
  postConfirmationMessage(device);
113
113
  postProgressTip(device, 'ConfirmOnDevice', postMessage);
114
- const eraseCommand = updateType === 'firmware' ? 'FirmwareErase' : 'FirmwareErase_ex';
114
+
115
+ const isFirmware = updateType === 'firmware';
116
+
117
+ if (isFirmware && !isUpdateBootloader) {
118
+ const newFeatures = await typedCall('GetFeatures', 'Features', {});
119
+ const deviceBootloaderVersion = getDeviceBootloaderVersion(newFeatures.message).join('.');
120
+ const supportUpgradeFileHeader = semver.gte(deviceBootloaderVersion, '2.1.0');
121
+ Log.debug('supportUpgradeFileHeader:', supportUpgradeFileHeader);
122
+
123
+ if (supportUpgradeFileHeader) {
124
+ // Extract and validate firmware header (first 1KB)
125
+ const HEADER_SIZE = 1024;
126
+ if (payload.byteLength < HEADER_SIZE) {
127
+ throw ERRORS.TypedError(
128
+ HardwareErrorCode.RuntimeError,
129
+ `firmware payload too small: ${payload.byteLength} bytes, expected at least ${HEADER_SIZE} bytes`
130
+ );
131
+ }
132
+
133
+ Log.debug('Uploading firmware header:', {
134
+ size: HEADER_SIZE,
135
+ totalSize: payload.byteLength,
136
+ });
137
+ postProgressTip(device, 'UploadingFirmwareHeader', postMessage);
138
+
139
+ const header = new Uint8Array(payload.slice(0, HEADER_SIZE));
140
+
141
+ try {
142
+ const headerRes = await typedCall('UpgradeFileHeader', 'Success', {
143
+ data: bytesToHex(header),
144
+ });
145
+
146
+ const isUnknownMessage = headerRes.message?.message?.includes('Failure_UnknownMessage');
147
+
148
+ if (headerRes.type !== 'Success' && !isUnknownMessage) {
149
+ Log.error('Firmware header upload failed:', headerRes);
150
+ throw ERRORS.TypedError(
151
+ HardwareErrorCode.RuntimeError,
152
+ 'failed to upload firmware header'
153
+ );
154
+ }
155
+ } catch (error) {
156
+ Log.error('Firmware header upload failed:', error);
157
+ const message = error instanceof Error ? error.message : String(error ?? '');
158
+ if (!message.includes('Failure_UnknownMessage')) {
159
+ throw error;
160
+ }
161
+ }
162
+ Log.debug('Firmware header uploaded successfully');
163
+ }
164
+ }
165
+
166
+ const eraseCommand = isFirmware ? 'FirmwareErase' : 'FirmwareErase_ex';
115
167
  const eraseRes = await typedCall(eraseCommand as unknown as any, 'Success', {});
116
168
  if (eraseRes.type !== 'Success') {
117
169
  throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'erase firmware error');
118
170
  }
119
171
  postProgressTip(device, 'FirmwareEraseSuccess', postMessage);
172
+
120
173
  postProgressMessage(device, 0, 'installingFirmware', postMessage);
121
- const { message, type } = await typedCall('FirmwareUpload', 'Success', {
122
- payload,
123
- });
174
+ let updateResponse: TypedResponseMessage<'Success'>;
175
+ try {
176
+ updateResponse = await typedCall('FirmwareUpload', 'Success', {
177
+ payload,
178
+ });
179
+ } catch (error) {
180
+ if (isDeviceDisconnectedError(error)) {
181
+ Log.log('Rebooting device');
182
+ updateResponse = {
183
+ type: 'Success',
184
+ message: { message: FIRMWARE_UPDATE_CONFIRM },
185
+ };
186
+ } else {
187
+ throw error;
188
+ }
189
+ }
124
190
  postProgressMessage(device, 100, 'installingFirmware', postMessage);
125
191
 
126
192
  await waitBleInstall(updateType);
127
- if (type !== 'Success') {
193
+ if (updateResponse.type !== 'Success') {
128
194
  throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'install firmware error');
129
195
  }
130
- return message;
196
+ return updateResponse.message;
131
197
  }
132
198
 
133
199
  if (DeviceModelToTypes.model_touch.includes(deviceType)) {