@onekeyfe/hd-core 1.2.0-alpha.10 → 1.2.0-alpha.11

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 (98) hide show
  1. package/__tests__/DeviceCommands.test.ts +25 -0
  2. package/__tests__/RequestQueue.test.ts +34 -0
  3. package/__tests__/pro2Wallpaper.test.ts +50 -0
  4. package/__tests__/protocol-v2.test.ts +426 -60
  5. package/dist/api/BaseMethod.d.ts +4 -0
  6. package/dist/api/BaseMethod.d.ts.map +1 -1
  7. package/dist/api/FileWrite.d.ts.map +1 -1
  8. package/dist/api/FirmwareUpdateV4.d.ts +0 -4
  9. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  10. package/dist/api/GetPassphraseState.d.ts +1 -6
  11. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  12. package/dist/api/UploadPortfolio.d.ts +18 -0
  13. package/dist/api/UploadPortfolio.d.ts.map +1 -0
  14. package/dist/api/index.d.ts +5 -0
  15. package/dist/api/index.d.ts.map +1 -1
  16. package/dist/api/protocol-v2/DeviceSessionGet.d.ts +1 -4
  17. package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -1
  18. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +6 -0
  19. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +1 -0
  20. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +16 -0
  21. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -0
  22. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +12 -0
  23. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -0
  24. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
  25. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
  26. package/dist/core/RequestQueue.d.ts +2 -0
  27. package/dist/core/RequestQueue.d.ts.map +1 -1
  28. package/dist/core/index.d.ts +1 -0
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/device/Device.d.ts.map +1 -1
  31. package/dist/device/DeviceCommands.d.ts +4 -4
  32. package/dist/device/DeviceCommands.d.ts.map +1 -1
  33. package/dist/events/call.d.ts +7 -0
  34. package/dist/events/call.d.ts.map +1 -1
  35. package/dist/events/core.d.ts +2 -2
  36. package/dist/events/core.d.ts.map +1 -1
  37. package/dist/events/iframe.d.ts +1 -0
  38. package/dist/events/iframe.d.ts.map +1 -1
  39. package/dist/index.d.ts +76 -21
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +694 -253
  42. package/dist/inject.d.ts +3 -2
  43. package/dist/inject.d.ts.map +1 -1
  44. package/dist/lowLevelInject.d.ts +2 -1
  45. package/dist/lowLevelInject.d.ts.map +1 -1
  46. package/dist/protocols/protocol-v2/unlockRetry.d.ts +9 -0
  47. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
  48. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  49. package/dist/topLevelInject.d.ts.map +1 -1
  50. package/dist/types/api/firmwareUpdate.d.ts +2 -0
  51. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  52. package/dist/types/api/getPassphraseState.d.ts +2 -10
  53. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  54. package/dist/types/api/index.d.ts +8 -2
  55. package/dist/types/api/index.d.ts.map +1 -1
  56. package/dist/types/api/protocolV2.d.ts +19 -4
  57. package/dist/types/api/protocolV2.d.ts.map +1 -1
  58. package/dist/utils/deviceFeaturesUtils.d.ts +0 -2
  59. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  60. package/dist/utils/index.d.ts +2 -0
  61. package/dist/utils/index.d.ts.map +1 -1
  62. package/dist/utils/patch.d.ts +1 -1
  63. package/dist/utils/patch.d.ts.map +1 -1
  64. package/dist/utils/pro2Wallpaper.d.ts +12 -0
  65. package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
  66. package/package.json +4 -4
  67. package/src/api/BaseMethod.ts +18 -0
  68. package/src/api/FileWrite.ts +9 -1
  69. package/src/api/FirmwareUpdateV4.ts +21 -91
  70. package/src/api/GetPassphraseState.ts +9 -18
  71. package/src/api/UploadPortfolio.ts +37 -0
  72. package/src/api/index.ts +5 -0
  73. package/src/api/protocol-v2/DeviceSessionGet.ts +3 -14
  74. package/src/api/protocol-v2/DeviceSettingsGet.ts +16 -0
  75. package/src/api/protocol-v2/DeviceSettingsPageShow.ts +59 -0
  76. package/src/api/protocol-v2/DeviceSettingsSet.ts +39 -0
  77. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +160 -0
  78. package/src/core/RequestQueue.ts +19 -0
  79. package/src/core/index.ts +10 -1
  80. package/src/data/messages/messages-protocol-v2.json +92 -8
  81. package/src/device/Device.ts +17 -3
  82. package/src/device/DeviceCommands.ts +9 -3
  83. package/src/events/call.ts +6 -0
  84. package/src/events/core.ts +2 -0
  85. package/src/events/iframe.ts +1 -0
  86. package/src/index.ts +4 -0
  87. package/src/inject.ts +13 -0
  88. package/src/lowLevelInject.ts +3 -0
  89. package/src/protocols/protocol-v2/unlockRetry.ts +46 -0
  90. package/src/protocols/protocol-v2/walletSession.ts +14 -5
  91. package/src/topLevelInject.ts +2 -0
  92. package/src/types/api/firmwareUpdate.ts +12 -0
  93. package/src/types/api/getPassphraseState.ts +2 -11
  94. package/src/types/api/index.ts +12 -1
  95. package/src/types/api/protocolV2.ts +46 -3
  96. package/src/utils/deviceFeaturesUtils.ts +3 -8
  97. package/src/utils/index.ts +6 -0
  98. package/src/utils/pro2Wallpaper.ts +111 -0
@@ -467,6 +467,7 @@
467
467
  "MessageType_DeviceSettings": 60410,
468
468
  "MessageType_DeviceSettingsGet": 60411,
469
469
  "MessageType_DeviceSettingsSet": 60412,
470
+ "MessageType_DeviceSettingsPageShow": 60413,
470
471
  "MessageType_DeviceCertificate": 60420,
471
472
  "MessageType_DeviceCertificateWrite": 60421,
472
473
  "MessageType_DeviceCertificateRead": 60422,
@@ -7045,14 +7046,6 @@
7045
7046
  "passphrase_state": {
7046
7047
  "type": "string",
7047
7048
  "id": 1
7048
- },
7049
- "_only_main_pin": {
7050
- "type": "bool",
7051
- "id": 2
7052
- },
7053
- "allow_create_attach_pin": {
7054
- "type": "bool",
7055
- "id": 3
7056
7049
  }
7057
7050
  }
7058
7051
  },
@@ -11394,6 +11387,20 @@
11394
11387
  }
11395
11388
  }
11396
11389
  },
11390
+ "DeviceErrorCode": {
11391
+ "values": {
11392
+ "DeviceError_None": 0,
11393
+ "DeviceError_Busy": 1,
11394
+ "DeviceError_NotInitialized": 2,
11395
+ "DeviceError_ActionCancelled": 3,
11396
+ "DeviceError_PinAlreadyUsed": 4,
11397
+ "DeviceError_PersistFailed": 5,
11398
+ "DeviceError_SeError": 6,
11399
+ "DeviceError_InvalidLanguage": 7,
11400
+ "DeviceError_WallpaperNotUsable": 8,
11401
+ "DeviceError_DeviceLocked": 9
11402
+ }
11403
+ },
11397
11404
  "DeviceRebootType": {
11398
11405
  "values": {
11399
11406
  "Normal": 0,
@@ -11423,6 +11430,62 @@
11423
11430
  "language": {
11424
11431
  "type": "string",
11425
11432
  "id": 3
11433
+ },
11434
+ "wallpaper_path": {
11435
+ "type": "string",
11436
+ "id": 4
11437
+ },
11438
+ "passphrase_enable": {
11439
+ "type": "bool",
11440
+ "id": 6
11441
+ },
11442
+ "brightness": {
11443
+ "type": "uint32",
11444
+ "id": 7
11445
+ },
11446
+ "autolock_delay_ms": {
11447
+ "type": "uint32",
11448
+ "id": 8
11449
+ },
11450
+ "autoshutdown_delay_ms": {
11451
+ "type": "uint32",
11452
+ "id": 9
11453
+ },
11454
+ "animation_enable": {
11455
+ "type": "bool",
11456
+ "id": 10
11457
+ },
11458
+ "tap_to_wake": {
11459
+ "type": "bool",
11460
+ "id": 11
11461
+ },
11462
+ "haptic_feedback": {
11463
+ "type": "bool",
11464
+ "id": 12
11465
+ },
11466
+ "device_name_display_enabled": {
11467
+ "type": "bool",
11468
+ "id": 13
11469
+ },
11470
+ "airgap_mode": {
11471
+ "type": "bool",
11472
+ "id": 14
11473
+ },
11474
+ "fido_enabled": {
11475
+ "type": "bool",
11476
+ "id": 15
11477
+ },
11478
+ "experimental_features": {
11479
+ "type": "bool",
11480
+ "id": 16
11481
+ },
11482
+ "usb_lock_enable": {
11483
+ "type": "bool",
11484
+ "id": 17
11485
+ },
11486
+ "random_keypad": {
11487
+ "type": "bool",
11488
+ "id": 18
11426
11489
  }
11427
11490
  }
11428
11491
  },
@@ -11438,6 +11501,27 @@
11438
11501
  }
11439
11502
  }
11440
11503
  },
11504
+ "DeviceSettingsPage": {
11505
+ "values": {
11506
+ "DeviceReset": 0,
11507
+ "DevicePinChange": 1,
11508
+ "DevicePassphrase": 2,
11509
+ "DeviceAirgap": 3
11510
+ }
11511
+ },
11512
+ "DeviceSettingsPageShow": {
11513
+ "fields": {
11514
+ "page": {
11515
+ "rule": "required",
11516
+ "type": "DeviceSettingsPage",
11517
+ "id": 1
11518
+ },
11519
+ "field_name": {
11520
+ "type": "string",
11521
+ "id": 2
11522
+ }
11523
+ }
11524
+ },
11441
11525
  "DeviceCertificate": {
11442
11526
  "fields": {
11443
11527
  "cert_and_pubkey": {
@@ -55,7 +55,6 @@ import {
55
55
  PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
56
56
  requestProtocolV2DeviceInfo,
57
57
  } from '../protocols/protocol-v2/features';
58
- import { refreshProtocolV2DeviceStatus } from '../protocols/protocol-v2/walletSession';
59
58
  import { buildProtocolV1FeaturesPayload, buildProtocolV2FeaturesPayload } from '../deviceProfile';
60
59
 
61
60
  import type { PROTO } from '../constants';
@@ -68,6 +67,7 @@ import type { PassphrasePromptResponse } from './DeviceCommands';
68
67
  import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
69
68
  import type {
70
69
  OneKeyDeviceInfo as DeviceDescriptor,
70
+ DeviceSessionPinResult,
71
71
  DeviceStatus,
72
72
  ProtocolV2DeviceInfo,
73
73
  Success,
@@ -1190,8 +1190,12 @@ export class Device extends EventEmitter {
1190
1190
 
1191
1191
  async unlockDevice() {
1192
1192
  if (this.isProtocolV2()) {
1193
+ let pinResult: DeviceSessionPinResult;
1193
1194
  try {
1194
- await this.commands.typedCall('DeviceSessionAskPin', 'DeviceSessionPinResult');
1195
+ ({ message: pinResult } = await this.commands.typedCall(
1196
+ 'DeviceSessionAskPin',
1197
+ 'DeviceSessionPinResult'
1198
+ ));
1195
1199
  } catch (error) {
1196
1200
  const errorText =
1197
1201
  error instanceof Error
@@ -1203,7 +1207,17 @@ export class Device extends EventEmitter {
1203
1207
  throw error;
1204
1208
  }
1205
1209
 
1206
- return refreshProtocolV2DeviceStatus(this);
1210
+ const status: DeviceStatus = {};
1211
+ if (pinResult.unlocked != null) {
1212
+ status.unlocked = pinResult.unlocked;
1213
+ }
1214
+ if (pinResult.unlocked_attach_pin != null) {
1215
+ status.unlocked_by_attach_to_pin = pinResult.unlocked_attach_pin;
1216
+ }
1217
+ if (pinResult.passphrase_protection != null) {
1218
+ status.passphrase_enabled = pinResult.passphrase_protection;
1219
+ }
1220
+ return this.updateProtocolV2Status(status);
1207
1221
  }
1208
1222
 
1209
1223
  const firmwareVersion = this.getCurrentFirmwareVersionString() ?? '0.0.0';
@@ -532,8 +532,9 @@ export class DeviceCommands {
532
532
 
533
533
  this.device.clearCancelableAction();
534
534
  if (res.type === 'Failure') {
535
- const { code, message } = res.message as {
535
+ const { code, subcode, message } = res.message as {
536
536
  code?: string | FailureType;
537
+ subcode?: number;
537
538
  message?: string;
538
539
  };
539
540
  let error: HardwareError | null = null;
@@ -577,8 +578,13 @@ export class DeviceCommands {
577
578
  }
578
579
 
579
580
  if (code === 'Failure_ProcessError') {
580
- // Handle firmware verification failures
581
- if (
581
+ if (subcode === 9) {
582
+ error = ERRORS.TypedError(HardwareErrorCode.DeviceLocked, message, {
583
+ failureCode: code,
584
+ subcode,
585
+ firmwareMessage: message,
586
+ });
587
+ } else if (
582
588
  message?.includes('Bootloader file verify failed') ||
583
589
  message?.includes('verify failed')
584
590
  ) {
@@ -53,6 +53,12 @@ export interface IFrameCancelMessage {
53
53
  payload: { connectId?: string };
54
54
  }
55
55
 
56
+ export interface IFrameCancelOperationMessage {
57
+ event: typeof IFRAME.CANCEL_OPERATION;
58
+ type: typeof IFRAME.CANCEL_OPERATION;
59
+ payload: { operationId: string };
60
+ }
61
+
56
62
  export interface IFrameSwitchTransportMessage {
57
63
  event: typeof IFRAME.SWITCH_TRANSPORT;
58
64
  type: typeof IFRAME.SWITCH_TRANSPORT;
@@ -5,6 +5,7 @@ import type {
5
5
  IFrameCallMessage,
6
6
  IFrameCallbackMessage,
7
7
  IFrameCancelMessage,
8
+ IFrameCancelOperationMessage,
8
9
  IFrameSwitchTransportMessage,
9
10
  } from './call';
10
11
  import type { DeviceEventMessage } from './device';
@@ -23,6 +24,7 @@ export type CoreMessage = {
23
24
  | IFrameEventMessage
24
25
  | IFrameCallMessage
25
26
  | IFrameCancelMessage
27
+ | IFrameCancelOperationMessage
26
28
  | IFrameSwitchTransportMessage
27
29
  | IFrameCallbackMessage
28
30
  | UiResponseMessage
@@ -8,6 +8,7 @@ export const IFRAME = {
8
8
  INIT_BRIDGE: 'iframe-init-bridge',
9
9
  CALL: 'iframe-call',
10
10
  CANCEL: 'iframe-cancel',
11
+ CANCEL_OPERATION: 'iframe-cancel-operation',
11
12
  SWITCH_TRANSPORT: 'iframe-switch-transport',
12
13
  CALLBACK: 'iframe-callback',
13
14
  } as const;
package/src/index.ts CHANGED
@@ -27,6 +27,7 @@ const HardwareSdk = ({
27
27
  eventEmitter,
28
28
  uiResponse,
29
29
  cancel,
30
+ cancelOperation,
30
31
  updateSettings,
31
32
  switchTransport,
32
33
  }: InjectApi): CoreApi =>
@@ -37,6 +38,7 @@ const HardwareSdk = ({
37
38
  eventEmitter,
38
39
  uiResponse,
39
40
  cancel,
41
+ cancelOperation,
40
42
  updateSettings,
41
43
  switchTransport,
42
44
  });
@@ -49,6 +51,7 @@ const HardwareSDKLowLevel = ({
49
51
  addHardwareGlobalEventListener,
50
52
  uiResponse,
51
53
  cancel,
54
+ cancelOperation,
52
55
  updateSettings,
53
56
  switchTransport,
54
57
  }: LowLevelInjectApi): LowLevelCoreApi =>
@@ -60,6 +63,7 @@ const HardwareSDKLowLevel = ({
60
63
  addHardwareGlobalEventListener,
61
64
  uiResponse,
62
65
  cancel,
66
+ cancelOperation,
63
67
  updateSettings,
64
68
  switchTransport,
65
69
  });
package/src/inject.ts CHANGED
@@ -36,12 +36,14 @@ export interface InjectApi {
36
36
  dispose: CoreApi['dispose'];
37
37
  uiResponse: CoreApi['uiResponse'];
38
38
  cancel: CoreApi['cancel'];
39
+ cancelOperation: CoreApi['cancelOperation'];
39
40
  switchTransport: CoreApi['switchTransport'];
40
41
  }
41
42
 
42
43
  export const inject = ({
43
44
  call,
44
45
  cancel,
46
+ cancelOperation,
45
47
  dispose,
46
48
  eventEmitter,
47
49
  init,
@@ -73,6 +75,7 @@ export const inject = ({
73
75
  uiResponse,
74
76
 
75
77
  cancel,
78
+ cancelOperation,
76
79
 
77
80
  updateSettings,
78
81
 
@@ -96,6 +99,7 @@ export const createCoreApi = (
96
99
  | 'dispose'
97
100
  | 'uiResponse'
98
101
  | 'cancel'
102
+ | 'cancelOperation'
99
103
  | 'updateSettings'
100
104
  | 'switchTransport'
101
105
  > => ({
@@ -168,6 +172,14 @@ export const createCoreApi = (
168
172
  call({ ...params, connectId, method: 'deviceFactoryInfoSet' }),
169
173
  deviceFactoryInfoGet: (connectId, params) =>
170
174
  call({ ...params, connectId, method: 'deviceFactoryInfoGet' }),
175
+ deviceSettingsGet: (connectId, params) =>
176
+ call({ ...params, connectId, method: 'deviceSettingsGet' }),
177
+ deviceSettingsSet: (connectId, params) =>
178
+ call({ ...params, connectId, method: 'deviceSettingsSet' }),
179
+ deviceSettingsPageShow: (connectId, params) =>
180
+ call({ ...params, connectId, method: 'deviceSettingsPageShow' }),
181
+ deviceUploadWallpaper: (connectId, params) =>
182
+ call({ ...params, connectId, method: 'deviceUploadWallpaper' }),
171
183
  filesystemPermissionFix: (connectId, params) =>
172
184
  call({ ...params, connectId, method: 'filesystemPermissionFix' }),
173
185
  fileRead: (connectId, params) => call({ ...params, connectId, method: 'fileRead' }),
@@ -181,6 +193,7 @@ export const createCoreApi = (
181
193
  call({ ...params, connectId, method: 'filesystemFileRead' }),
182
194
  filesystemFileWrite: (connectId, params) =>
183
195
  call({ ...params, connectId, method: 'filesystemFileWrite' }),
196
+ uploadPortfolio: (connectId, params) => call({ ...params, connectId, method: 'uploadPortfolio' }),
184
197
  filesystemFileDelete: (connectId, params) =>
185
198
  call({ ...params, connectId, method: 'filesystemFileDelete' }),
186
199
  filesystemDirList: (connectId, params) =>
@@ -13,6 +13,7 @@ export interface LowLevelInjectApi {
13
13
  dispose: CoreApi['dispose'];
14
14
  uiResponse: CoreApi['uiResponse'];
15
15
  cancel: CoreApi['cancel'];
16
+ cancelOperation: CoreApi['cancelOperation'];
16
17
  updateSettings: CoreApi['updateSettings'];
17
18
  switchTransport: CoreApi['switchTransport'];
18
19
  addHardwareGlobalEventListener: (listener: IAddHardwareGlobalEventListener) => void;
@@ -25,6 +26,7 @@ export type LowLevelCoreApi = Omit<CoreApi, 'on' | 'off'> & {
25
26
  export const lowLevelInject = ({
26
27
  call,
27
28
  cancel,
29
+ cancelOperation,
28
30
  dispose,
29
31
  eventEmitter,
30
32
  init,
@@ -48,6 +50,7 @@ export const lowLevelInject = ({
48
50
  uiResponse,
49
51
 
50
52
  cancel,
53
+ cancelOperation,
51
54
 
52
55
  updateSettings,
53
56
 
@@ -0,0 +1,46 @@
1
+ import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+
3
+ import { LoggerNames, getLogger } from '../../utils';
4
+
5
+ import type { BaseMethod } from '../../api/BaseMethod';
6
+ import type { Device } from '../../device/Device';
7
+
8
+ const Log = getLogger(LoggerNames.Core);
9
+
10
+ type RunnableMethod = Pick<BaseMethod, 'run' | 'unlockPolicy'> & { name?: string };
11
+ type UnlockableDevice = Pick<Device, 'isProtocolV2' | 'unlockDevice'>;
12
+
13
+ function isDeviceLockedError(error: unknown): boolean {
14
+ return (
15
+ typeof error === 'object' &&
16
+ error !== null &&
17
+ 'errorCode' in error &&
18
+ error.errorCode === HardwareErrorCode.DeviceLocked
19
+ );
20
+ }
21
+
22
+ export async function runMethodWithUnlockRetry(method: RunnableMethod, device: UnlockableDevice) {
23
+ try {
24
+ return await method.run();
25
+ } catch (error) {
26
+ if (
27
+ !device.isProtocolV2() ||
28
+ method.unlockPolicy !== 'retry-on-locked' ||
29
+ !isDeviceLockedError(error)
30
+ ) {
31
+ throw error;
32
+ }
33
+
34
+ Log.debug('Protocol V2 unlock retry triggered', { method: method.name });
35
+ await device.unlockDevice();
36
+ Log.debug('Protocol V2 unlock completed', { method: method.name });
37
+ try {
38
+ const response = await method.run();
39
+ Log.debug('Protocol V2 method retry completed', { method: method.name, success: true });
40
+ return response;
41
+ } catch (retryError) {
42
+ Log.debug('Protocol V2 method retry completed', { method: method.name, success: false });
43
+ throw retryError;
44
+ }
45
+ }
46
+ }
@@ -43,11 +43,20 @@ export async function getProtocolV2WalletSession(
43
43
  typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
44
44
 
45
45
  try {
46
- const { message } = await device.commands.typedCall(
47
- 'DeviceSessionGet',
48
- 'DeviceSession',
49
- cachedSessionId ? { session_id: cachedSessionId } : {}
50
- );
46
+ const requestDeviceSession = (sessionId?: string) =>
47
+ device.commands.typedCall(
48
+ 'DeviceSessionGet',
49
+ 'DeviceSession',
50
+ sessionId ? { session_id: sessionId } : {}
51
+ );
52
+
53
+ const { message } = await requestDeviceSession(cachedSessionId).catch(async error => {
54
+ if (!cachedSessionId || !isProtocolV2InvalidSessionError(error)) {
55
+ throw error;
56
+ }
57
+ device.clearInternalState();
58
+ return requestDeviceSession();
59
+ });
51
60
 
52
61
  if (
53
62
  options?.expectedPassphraseState &&
@@ -52,6 +52,8 @@ export const topLevelInject = () => {
52
52
 
53
53
  cancel: (connectId?: string) => lowLevelApi?.cancel(connectId),
54
54
 
55
+ cancelOperation: (operationId: string) => lowLevelApi?.cancelOperation(operationId),
56
+
55
57
  updateSettings: settings => lowLevelApi?.updateSettings(settings) ?? Promise.resolve(false),
56
58
 
57
59
  switchTransport: (env: ConnectSettings['env']) =>
@@ -61,10 +61,22 @@ export interface FirmwareUpdateV3Params {
61
61
  * firmwareUpdateV4(Protocol V2)按 DeviceFirmwareTargetType 拆分的目标二进制。
62
62
  * 除 romloader 外,每个字段对应一个 bootloader 可接受的固件升级 target。
63
63
  */
64
+ export type FirmwareUpdateV4Target =
65
+ | 'boot'
66
+ | 'app_v1'
67
+ | 'app_v2'
68
+ | 'coprocessor'
69
+ | 'resource'
70
+ | 'se01'
71
+ | 'se02'
72
+ | 'se03'
73
+ | 'se04';
74
+
64
75
  export interface FirmwareUpdateV4Params {
65
76
  platform: IPlatform;
66
77
  chunkSize?: number;
67
78
  firmwareType?: EFirmwareType;
79
+ targetsToUpdate?: FirmwareUpdateV4Target[];
68
80
 
69
81
  /** FW_MGMT_TARGET_ROMLOADER = 2;当前 Pro2 bootloader 不接受通过 firmwareUpdateV4 安装 */
70
82
  romloaderBinary?: ArrayBuffer;
@@ -1,17 +1,8 @@
1
1
  import type { CommonParams, Response } from '../params';
2
2
 
3
- export type GetPassphraseStatePayload = {
4
- passphraseState?: string;
5
- sessionId?: string;
6
- unlockedAttachPin?: boolean;
7
- passphraseProtection?: boolean | null;
8
- };
9
-
10
- export type GetPassphraseStateParams = CommonParams & {
11
- allowCreateAttachPin?: boolean;
12
- };
3
+ export type GetPassphraseStateParams = CommonParams;
13
4
 
14
5
  export declare function getPassphraseState(
15
6
  connectId?: string,
16
7
  params?: GetPassphraseStateParams
17
- ): Response<GetPassphraseStatePayload>;
8
+ ): Response<string | undefined>;
@@ -6,7 +6,11 @@ import type {
6
6
  deviceInfoGet,
7
7
  deviceReboot,
8
8
  deviceSessionGet,
9
+ deviceSettingsGet,
10
+ deviceSettingsPageShow,
11
+ deviceSettingsSet,
9
12
  deviceStatusGet,
13
+ deviceUploadWallpaper,
10
14
  dirList,
11
15
  dirMake,
12
16
  dirRemove,
@@ -26,6 +30,7 @@ import type {
26
30
  pathInfo,
27
31
  ping,
28
32
  protocolInfoRequest,
33
+ uploadPortfolio,
29
34
  } from './protocolV2';
30
35
  import type { off, on, removeAllListeners } from './event';
31
36
  import type { uiResponse } from './uiResponse';
@@ -179,7 +184,7 @@ export type {
179
184
  DeviceProfileVerify,
180
185
  DeviceProfileVersions,
181
186
  } from './getDeviceInfo';
182
- export type { GetPassphraseStateParams, GetPassphraseStatePayload } from './getPassphraseState';
187
+ export type { GetPassphraseStateParams } from './getPassphraseState';
183
188
  export type { ClearSessionCacheParams, ClearSessionCachePayload } from './sessionCache';
184
189
 
185
190
  export type CoreApi = {
@@ -195,6 +200,7 @@ export type CoreApi = {
195
200
  call: (params: any) => Promise<any>;
196
201
  uiResponse: typeof uiResponse;
197
202
  cancel: (connectId?: string) => void;
203
+ cancelOperation: (operationId: string) => void;
198
204
  updateSettings: typeof updateSettings;
199
205
  switchTransport: (env: ConnectSettings['env']) => Promise<{ success: boolean }>;
200
206
  getLogs: typeof getLogs;
@@ -265,6 +271,10 @@ export type CoreApi = {
265
271
  deviceGetFirmwareUpdateStatus: typeof deviceGetFirmwareUpdateStatus;
266
272
  deviceFactoryInfoSet: typeof deviceFactoryInfoSet;
267
273
  deviceFactoryInfoGet: typeof deviceFactoryInfoGet;
274
+ deviceSettingsGet: typeof deviceSettingsGet;
275
+ deviceSettingsSet: typeof deviceSettingsSet;
276
+ deviceSettingsPageShow: typeof deviceSettingsPageShow;
277
+ deviceUploadWallpaper: typeof deviceUploadWallpaper;
268
278
  filesystemPermissionFix: typeof filesystemPermissionFix;
269
279
  fileRead: typeof fileRead;
270
280
  fileWrite: typeof fileWrite;
@@ -275,6 +285,7 @@ export type CoreApi = {
275
285
  pathInfo: typeof pathInfo;
276
286
  filesystemFileRead: typeof filesystemFileRead;
277
287
  filesystemFileWrite: typeof filesystemFileWrite;
288
+ uploadPortfolio: typeof uploadPortfolio;
278
289
  filesystemFileDelete: typeof filesystemFileDelete;
279
290
  filesystemDirList: typeof filesystemDirList;
280
291
  filesystemDirMake: typeof filesystemDirMake;
@@ -3,6 +3,7 @@ import type {
3
3
  DeviceFactoryInfo,
4
4
  DeviceFirmwareUpdateStatus,
5
5
  DeviceSession,
6
+ DeviceSettings,
6
7
  DeviceStatus,
7
8
  ProtocolInfo,
8
9
  ProtocolV2DeviceInfo,
@@ -15,7 +16,12 @@ import type {
15
16
  DeviceRebootParams,
16
17
  } from '../../api/protocol-v2/helpers';
17
18
  import type { DeviceInfoGetParams } from '../../api/protocol-v2/DeviceInfoGet';
18
- import type { DeviceSessionGetParams } from '../../api/protocol-v2/DeviceSessionGet';
19
+ import type { DeviceSettingsSetParams } from '../../api/protocol-v2/DeviceSettingsSet';
20
+ import type { DeviceSettingsPageShowParams } from '../../api/protocol-v2/DeviceSettingsPageShow';
21
+ import type {
22
+ DeviceUploadWallpaperParams,
23
+ DeviceUploadWallpaperResponse,
24
+ } from '../../api/protocol-v2/DeviceUploadWallpaper';
19
25
 
20
26
  // 参数类型单源:以 api/protocol-v2 的实现为准(type-only re-export,无运行时依赖)
21
27
  export type {
@@ -31,7 +37,15 @@ export type {
31
37
  DeviceInfoGetTargets,
32
38
  DeviceInfoGetTypes,
33
39
  } from '../../api/protocol-v2/DeviceInfoGet';
34
- export type { DeviceSessionGetParams } from '../../api/protocol-v2/DeviceSessionGet';
40
+ export type { DeviceSettingsSetParams } from '../../api/protocol-v2/DeviceSettingsSet';
41
+ export type {
42
+ DeviceSettingsPageShowParams,
43
+ SupportedDeviceSettingsPage,
44
+ } from '../../api/protocol-v2/DeviceSettingsPageShow';
45
+ export type {
46
+ DeviceUploadWallpaperParams,
47
+ DeviceUploadWallpaperResponse,
48
+ } from '../../api/protocol-v2/DeviceUploadWallpaper';
35
49
 
36
50
  // ── Shared response shapes (Protocol V2 file system) ────────────────────
37
51
 
@@ -99,7 +113,7 @@ export declare function deviceStatusGet(
99
113
 
100
114
  export declare function deviceSessionGet(
101
115
  connectId: string,
102
- params?: CommonParams & DeviceSessionGetParams
116
+ params?: CommonParams
103
117
  ): Response<DeviceSession>;
104
118
 
105
119
  export declare function deviceFirmwareUpdate(
@@ -122,6 +136,26 @@ export declare function deviceFactoryInfoGet(
122
136
  params?: CommonParams
123
137
  ): Response<DeviceFactoryInfo>;
124
138
 
139
+ export declare function deviceSettingsGet(
140
+ connectId: string,
141
+ params?: CommonParams
142
+ ): Response<DeviceSettings>;
143
+
144
+ export declare function deviceSettingsSet(
145
+ connectId: string,
146
+ params: CommonParams & DeviceSettingsSetParams
147
+ ): Response<Success>;
148
+
149
+ export declare function deviceSettingsPageShow(
150
+ connectId: string,
151
+ params: CommonParams & DeviceSettingsPageShowParams
152
+ ): Response<Success>;
153
+
154
+ export declare function deviceUploadWallpaper(
155
+ connectId: string,
156
+ params: CommonParams & DeviceUploadWallpaperParams
157
+ ): Response<DeviceUploadWallpaperResponse>;
158
+
125
159
  export declare function filesystemPermissionFix(
126
160
  connectId: string,
127
161
  params?: CommonParams
@@ -181,6 +215,15 @@ export declare function pathInfo(
181
215
 
182
216
  export declare const filesystemFileRead: typeof fileRead;
183
217
  export declare const filesystemFileWrite: typeof fileWrite;
218
+
219
+ export declare function uploadPortfolio(
220
+ connectId: string,
221
+ params: {
222
+ operationId?: string;
223
+ packageBytes: ArrayBuffer | Uint8Array | Blob;
224
+ timeoutMs?: number | string;
225
+ }
226
+ ): Response<FileInfo & { portfolioUpdated: true }>;
184
227
  export declare const filesystemFileDelete: typeof fileDelete;
185
228
  export declare const filesystemDirList: typeof dirList;
186
229
  export declare const filesystemDirMake: typeof dirMake;
@@ -89,7 +89,6 @@ export const getPassphraseStateWithRefreshDeviceInfo = async (
89
89
  options?: {
90
90
  expectPassphraseState?: string;
91
91
  onlyMainPin?: boolean;
92
- allowCreateAttachPin?: boolean;
93
92
  initSession?: boolean;
94
93
  }
95
94
  ) => {
@@ -164,7 +163,6 @@ export const getPassphraseState = async (
164
163
  options?: {
165
164
  expectPassphraseState?: string;
166
165
  onlyMainPin?: boolean;
167
- allowCreateAttachPin?: boolean;
168
166
  initSession?: boolean;
169
167
  }
170
168
  ): Promise<{
@@ -196,12 +194,9 @@ export const getPassphraseState = async (
196
194
  supportAttachPinCapability || supportProSeriesAttachPinPassphrase(deviceType, firmwareVersion);
197
195
 
198
196
  if (supportGetPassphraseState) {
199
- const payload: GetPassphraseState = options?.onlyMainPin
200
- ? { _only_main_pin: true }
201
- : { passphrase_state: options?.expectPassphraseState };
202
- if (options?.allowCreateAttachPin) {
203
- payload.allow_create_attach_pin = true;
204
- }
197
+ const payload: GetPassphraseState = {
198
+ passphrase_state: options?.onlyMainPin ? undefined : options?.expectPassphraseState,
199
+ };
205
200
 
206
201
  const { message, type } = await commands.typedCall(
207
202
  'GetPassphraseState',
@@ -38,6 +38,12 @@ export { getHDPath, getScriptType, getOutputScriptType } from '../api/helpers/pa
38
38
  export const isBleConnect = (env: string) => env === 'react-native' || env === 'lowlevel';
39
39
 
40
40
  export { getHomeScreenHex, getHomeScreenDefaultList, getHomeScreenSize } from './homescreen';
41
+ export {
42
+ encodePro2Wallpaper,
43
+ PRO2_WALLPAPER_HEIGHT,
44
+ PRO2_WALLPAPER_WIDTH,
45
+ } from './pro2Wallpaper';
46
+ export type { Pro2WallpaperColorFormat } from './pro2Wallpaper';
41
47
 
42
48
  export const wait = (ms: number) =>
43
49
  new Promise(resolve => {