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

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 (122) 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 +511 -61
  5. package/__tests__/protocolV2FileWrite.test.ts +55 -0
  6. package/dist/api/BaseMethod.d.ts +4 -0
  7. package/dist/api/BaseMethod.d.ts.map +1 -1
  8. package/dist/api/FileWrite.d.ts.map +1 -1
  9. package/dist/api/FirmwareUpdateV4.d.ts +0 -4
  10. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  11. package/dist/api/GetPassphraseState.d.ts +1 -6
  12. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  13. package/dist/api/UploadPortfolio.d.ts +18 -0
  14. package/dist/api/UploadPortfolio.d.ts.map +1 -0
  15. package/dist/api/helpers/protocolV2FileWrite.d.ts +32 -0
  16. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
  17. package/dist/api/index.d.ts +6 -0
  18. package/dist/api/index.d.ts.map +1 -1
  19. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +6 -0
  20. package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -0
  21. package/dist/api/protocol-v2/DeviceSessionGet.d.ts +1 -4
  22. package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -1
  23. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +6 -0
  24. package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +1 -0
  25. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +16 -0
  26. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -0
  27. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +12 -0
  28. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -0
  29. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
  30. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
  31. package/dist/core/RequestQueue.d.ts +2 -0
  32. package/dist/core/RequestQueue.d.ts.map +1 -1
  33. package/dist/core/index.d.ts +1 -0
  34. package/dist/core/index.d.ts.map +1 -1
  35. package/dist/device/Device.d.ts.map +1 -1
  36. package/dist/device/DeviceCommands.d.ts +4 -4
  37. package/dist/device/DeviceCommands.d.ts.map +1 -1
  38. package/dist/deviceProfile/buildDeviceFeatures.d.ts +2 -2
  39. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  40. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -1
  41. package/dist/events/call.d.ts +7 -0
  42. package/dist/events/call.d.ts.map +1 -1
  43. package/dist/events/core.d.ts +2 -2
  44. package/dist/events/core.d.ts.map +1 -1
  45. package/dist/events/iframe.d.ts +1 -0
  46. package/dist/events/iframe.d.ts.map +1 -1
  47. package/dist/index.d.ts +80 -23
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +922 -472
  50. package/dist/inject.d.ts +3 -2
  51. package/dist/inject.d.ts.map +1 -1
  52. package/dist/lowLevelInject.d.ts +2 -1
  53. package/dist/lowLevelInject.d.ts.map +1 -1
  54. package/dist/protocols/protocol-v2/features.d.ts +1 -0
  55. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  56. package/dist/protocols/protocol-v2/index.d.ts +1 -1
  57. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  58. package/dist/protocols/protocol-v2/unlockRetry.d.ts +9 -0
  59. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
  60. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  61. package/dist/topLevelInject.d.ts.map +1 -1
  62. package/dist/types/api/firmwareUpdate.d.ts +2 -0
  63. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  64. package/dist/types/api/getDeviceInfo.d.ts +1 -1
  65. package/dist/types/api/getDeviceInfo.d.ts.map +1 -1
  66. package/dist/types/api/getPassphraseState.d.ts +2 -10
  67. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  68. package/dist/types/api/index.d.ts +9 -2
  69. package/dist/types/api/index.d.ts.map +1 -1
  70. package/dist/types/api/protocolV2.d.ts +20 -4
  71. package/dist/types/api/protocolV2.d.ts.map +1 -1
  72. package/dist/types/device.d.ts +1 -1
  73. package/dist/types/device.d.ts.map +1 -1
  74. package/dist/utils/deviceFeaturesUtils.d.ts +0 -2
  75. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  76. package/dist/utils/index.d.ts +2 -0
  77. package/dist/utils/index.d.ts.map +1 -1
  78. package/dist/utils/patch.d.ts +1 -1
  79. package/dist/utils/patch.d.ts.map +1 -1
  80. package/dist/utils/pro2Wallpaper.d.ts +12 -0
  81. package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
  82. package/package.json +4 -4
  83. package/src/api/BaseMethod.ts +18 -0
  84. package/src/api/FileWrite.ts +18 -178
  85. package/src/api/FirmwareUpdateV4.ts +21 -91
  86. package/src/api/GetPassphraseState.ts +9 -18
  87. package/src/api/UploadPortfolio.ts +37 -0
  88. package/src/api/helpers/protocolV2FileWrite.ts +164 -0
  89. package/src/api/index.ts +6 -0
  90. package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +18 -0
  91. package/src/api/protocol-v2/DeviceSessionGet.ts +3 -14
  92. package/src/api/protocol-v2/DeviceSettingsGet.ts +16 -0
  93. package/src/api/protocol-v2/DeviceSettingsPageShow.ts +59 -0
  94. package/src/api/protocol-v2/DeviceSettingsSet.ts +39 -0
  95. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +124 -0
  96. package/src/core/RequestQueue.ts +19 -0
  97. package/src/core/index.ts +10 -1
  98. package/src/data/messages/messages-protocol-v2.json +92 -8
  99. package/src/device/Device.ts +17 -3
  100. package/src/device/DeviceCommands.ts +9 -3
  101. package/src/deviceProfile/buildDeviceFeatures.ts +20 -12
  102. package/src/deviceProfile/buildDeviceProfile.ts +8 -6
  103. package/src/events/call.ts +6 -0
  104. package/src/events/core.ts +2 -0
  105. package/src/events/iframe.ts +1 -0
  106. package/src/index.ts +4 -0
  107. package/src/inject.ts +15 -0
  108. package/src/lowLevelInject.ts +3 -0
  109. package/src/protocols/protocol-v2/features.ts +19 -1
  110. package/src/protocols/protocol-v2/index.ts +2 -0
  111. package/src/protocols/protocol-v2/unlockRetry.ts +46 -0
  112. package/src/protocols/protocol-v2/walletSession.ts +14 -5
  113. package/src/topLevelInject.ts +2 -0
  114. package/src/types/api/firmwareUpdate.ts +12 -0
  115. package/src/types/api/getDeviceInfo.ts +1 -1
  116. package/src/types/api/getPassphraseState.ts +2 -11
  117. package/src/types/api/index.ts +14 -1
  118. package/src/types/api/protocolV2.ts +52 -3
  119. package/src/types/device.ts +1 -0
  120. package/src/utils/deviceFeaturesUtils.ts +3 -8
  121. package/src/utils/index.ts +6 -0
  122. package/src/utils/pro2Wallpaper.ts +111 -0
@@ -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
  > => ({
@@ -158,6 +162,8 @@ export const createCoreApi = (
158
162
  deviceReboot: (connectId, params) => call({ ...params, connectId, method: 'deviceReboot' }),
159
163
  deviceInfoGet: (connectId, params) => call({ ...params, connectId, method: 'deviceInfoGet' }),
160
164
  deviceStatusGet: (connectId, params) => call({ ...params, connectId, method: 'deviceStatusGet' }),
165
+ deviceGetOnboardingStatus: (connectId, params) =>
166
+ call({ ...params, connectId, method: 'deviceGetOnboardingStatus' }),
161
167
  deviceSessionGet: (connectId, params) =>
162
168
  call({ ...params, connectId, method: 'deviceSessionGet' }),
163
169
  deviceFirmwareUpdate: (connectId, params) =>
@@ -168,6 +174,14 @@ export const createCoreApi = (
168
174
  call({ ...params, connectId, method: 'deviceFactoryInfoSet' }),
169
175
  deviceFactoryInfoGet: (connectId, params) =>
170
176
  call({ ...params, connectId, method: 'deviceFactoryInfoGet' }),
177
+ deviceSettingsGet: (connectId, params) =>
178
+ call({ ...params, connectId, method: 'deviceSettingsGet' }),
179
+ deviceSettingsSet: (connectId, params) =>
180
+ call({ ...params, connectId, method: 'deviceSettingsSet' }),
181
+ deviceSettingsPageShow: (connectId, params) =>
182
+ call({ ...params, connectId, method: 'deviceSettingsPageShow' }),
183
+ deviceUploadWallpaper: (connectId, params) =>
184
+ call({ ...params, connectId, method: 'deviceUploadWallpaper' }),
171
185
  filesystemPermissionFix: (connectId, params) =>
172
186
  call({ ...params, connectId, method: 'filesystemPermissionFix' }),
173
187
  fileRead: (connectId, params) => call({ ...params, connectId, method: 'fileRead' }),
@@ -181,6 +195,7 @@ export const createCoreApi = (
181
195
  call({ ...params, connectId, method: 'filesystemFileRead' }),
182
196
  filesystemFileWrite: (connectId, params) =>
183
197
  call({ ...params, connectId, method: 'filesystemFileWrite' }),
198
+ uploadPortfolio: (connectId, params) => call({ ...params, connectId, method: 'uploadPortfolio' }),
184
199
  filesystemFileDelete: (connectId, params) =>
185
200
  call({ ...params, connectId, method: 'filesystemFileDelete' }),
186
201
  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
 
@@ -50,8 +50,26 @@ export const getProtocolV2SeState = (se?: DeviceSEInfo): ProtocolV2SeStateLabel
50
50
  export const getProtocolV2SeType = (se?: DeviceSEInfo): string | null =>
51
51
  normalizeEnumValue(DeviceSeType, se?.type);
52
52
 
53
+ /**
54
+ * 兼容尚未提供显式 runtime mode 的 Protocol V2 固件。
55
+ *
56
+ * 当前 romloader 只上报 hw、fw.romloader 和 fw.bootloader;bootloader
57
+ * 还会上报 application/application_data、coprocessor 或 SE 信息。
58
+ */
59
+ export const isProtocolV2RomloaderDeviceInfo = (deviceInfo?: ProtocolV2DeviceInfo | null) =>
60
+ !!deviceInfo &&
61
+ deviceInfo.status == null &&
62
+ deviceInfo.fw?.romloader != null &&
63
+ deviceInfo.fw?.application == null &&
64
+ deviceInfo.fw?.application_data == null &&
65
+ deviceInfo.coprocessor == null &&
66
+ deviceInfo.se1 == null &&
67
+ deviceInfo.se2 == null &&
68
+ deviceInfo.se3 == null &&
69
+ deviceInfo.se4 == null;
70
+
53
71
  export const isProtocolV2BootloaderDeviceInfo = (deviceInfo?: ProtocolV2DeviceInfo | null) =>
54
- !!deviceInfo && deviceInfo.status == null;
72
+ !!deviceInfo && deviceInfo.status == null && !isProtocolV2RomloaderDeviceInfo(deviceInfo);
55
73
 
56
74
  export const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
57
75
  targets: {
@@ -4,6 +4,8 @@ export {
4
4
  PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST,
5
5
  PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
6
6
  PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
7
+ isProtocolV2BootloaderDeviceInfo,
8
+ isProtocolV2RomloaderDeviceInfo,
7
9
  getProtocolV2SeState,
8
10
  getProtocolV2SeType,
9
11
  } from './features';
@@ -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;
@@ -16,7 +16,7 @@ export type GetDeviceInfoParams = {
16
16
  includeRaw?: boolean;
17
17
  };
18
18
 
19
- export type DeviceInfoMode = 'normal' | 'bootloader' | 'notInitialized' | 'unknown';
19
+ export type DeviceInfoMode = 'normal' | 'bootloader' | 'romloader' | 'notInitialized' | 'unknown';
20
20
 
21
21
  export type DeviceInfoStatus = {
22
22
  mode: DeviceInfoMode;
@@ -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>;
@@ -3,10 +3,15 @@ import type {
3
3
  deviceFactoryInfoSet,
4
4
  deviceFirmwareUpdate,
5
5
  deviceGetFirmwareUpdateStatus,
6
+ deviceGetOnboardingStatus,
6
7
  deviceInfoGet,
7
8
  deviceReboot,
8
9
  deviceSessionGet,
10
+ deviceSettingsGet,
11
+ deviceSettingsPageShow,
12
+ deviceSettingsSet,
9
13
  deviceStatusGet,
14
+ deviceUploadWallpaper,
10
15
  dirList,
11
16
  dirMake,
12
17
  dirRemove,
@@ -26,6 +31,7 @@ import type {
26
31
  pathInfo,
27
32
  ping,
28
33
  protocolInfoRequest,
34
+ uploadPortfolio,
29
35
  } from './protocolV2';
30
36
  import type { off, on, removeAllListeners } from './event';
31
37
  import type { uiResponse } from './uiResponse';
@@ -179,7 +185,7 @@ export type {
179
185
  DeviceProfileVerify,
180
186
  DeviceProfileVersions,
181
187
  } from './getDeviceInfo';
182
- export type { GetPassphraseStateParams, GetPassphraseStatePayload } from './getPassphraseState';
188
+ export type { GetPassphraseStateParams } from './getPassphraseState';
183
189
  export type { ClearSessionCacheParams, ClearSessionCachePayload } from './sessionCache';
184
190
 
185
191
  export type CoreApi = {
@@ -195,6 +201,7 @@ export type CoreApi = {
195
201
  call: (params: any) => Promise<any>;
196
202
  uiResponse: typeof uiResponse;
197
203
  cancel: (connectId?: string) => void;
204
+ cancelOperation: (operationId: string) => void;
198
205
  updateSettings: typeof updateSettings;
199
206
  switchTransport: (env: ConnectSettings['env']) => Promise<{ success: boolean }>;
200
207
  getLogs: typeof getLogs;
@@ -260,11 +267,16 @@ export type CoreApi = {
260
267
  deviceReboot: typeof deviceReboot;
261
268
  deviceInfoGet: typeof deviceInfoGet;
262
269
  deviceStatusGet: typeof deviceStatusGet;
270
+ deviceGetOnboardingStatus: typeof deviceGetOnboardingStatus;
263
271
  deviceSessionGet: typeof deviceSessionGet;
264
272
  deviceFirmwareUpdate: typeof deviceFirmwareUpdate;
265
273
  deviceGetFirmwareUpdateStatus: typeof deviceGetFirmwareUpdateStatus;
266
274
  deviceFactoryInfoSet: typeof deviceFactoryInfoSet;
267
275
  deviceFactoryInfoGet: typeof deviceFactoryInfoGet;
276
+ deviceSettingsGet: typeof deviceSettingsGet;
277
+ deviceSettingsSet: typeof deviceSettingsSet;
278
+ deviceSettingsPageShow: typeof deviceSettingsPageShow;
279
+ deviceUploadWallpaper: typeof deviceUploadWallpaper;
268
280
  filesystemPermissionFix: typeof filesystemPermissionFix;
269
281
  fileRead: typeof fileRead;
270
282
  fileWrite: typeof fileWrite;
@@ -275,6 +287,7 @@ export type CoreApi = {
275
287
  pathInfo: typeof pathInfo;
276
288
  filesystemFileRead: typeof filesystemFileRead;
277
289
  filesystemFileWrite: typeof filesystemFileWrite;
290
+ uploadPortfolio: typeof uploadPortfolio;
278
291
  filesystemFileDelete: typeof filesystemFileDelete;
279
292
  filesystemDirList: typeof filesystemDirList;
280
293
  filesystemDirMake: typeof filesystemDirMake;
@@ -2,7 +2,9 @@ import type { CommonParams, Response } from '../params';
2
2
  import type {
3
3
  DeviceFactoryInfo,
4
4
  DeviceFirmwareUpdateStatus,
5
+ DevOnboardingStatus,
5
6
  DeviceSession,
7
+ DeviceSettings,
6
8
  DeviceStatus,
7
9
  ProtocolInfo,
8
10
  ProtocolV2DeviceInfo,
@@ -15,7 +17,12 @@ import type {
15
17
  DeviceRebootParams,
16
18
  } from '../../api/protocol-v2/helpers';
17
19
  import type { DeviceInfoGetParams } from '../../api/protocol-v2/DeviceInfoGet';
18
- import type { DeviceSessionGetParams } from '../../api/protocol-v2/DeviceSessionGet';
20
+ import type { DeviceSettingsSetParams } from '../../api/protocol-v2/DeviceSettingsSet';
21
+ import type { DeviceSettingsPageShowParams } from '../../api/protocol-v2/DeviceSettingsPageShow';
22
+ import type {
23
+ DeviceUploadWallpaperParams,
24
+ DeviceUploadWallpaperResponse,
25
+ } from '../../api/protocol-v2/DeviceUploadWallpaper';
19
26
 
20
27
  // 参数类型单源:以 api/protocol-v2 的实现为准(type-only re-export,无运行时依赖)
21
28
  export type {
@@ -31,7 +38,15 @@ export type {
31
38
  DeviceInfoGetTargets,
32
39
  DeviceInfoGetTypes,
33
40
  } from '../../api/protocol-v2/DeviceInfoGet';
34
- export type { DeviceSessionGetParams } from '../../api/protocol-v2/DeviceSessionGet';
41
+ export type { DeviceSettingsSetParams } from '../../api/protocol-v2/DeviceSettingsSet';
42
+ export type {
43
+ DeviceSettingsPageShowParams,
44
+ SupportedDeviceSettingsPage,
45
+ } from '../../api/protocol-v2/DeviceSettingsPageShow';
46
+ export type {
47
+ DeviceUploadWallpaperParams,
48
+ DeviceUploadWallpaperResponse,
49
+ } from '../../api/protocol-v2/DeviceUploadWallpaper';
35
50
 
36
51
  // ── Shared response shapes (Protocol V2 file system) ────────────────────
37
52
 
@@ -97,9 +112,14 @@ export declare function deviceStatusGet(
97
112
  params?: CommonParams
98
113
  ): Response<DeviceStatus>;
99
114
 
115
+ export declare function deviceGetOnboardingStatus(
116
+ connectId: string,
117
+ params?: CommonParams
118
+ ): Response<DevOnboardingStatus>;
119
+
100
120
  export declare function deviceSessionGet(
101
121
  connectId: string,
102
- params?: CommonParams & DeviceSessionGetParams
122
+ params?: CommonParams
103
123
  ): Response<DeviceSession>;
104
124
 
105
125
  export declare function deviceFirmwareUpdate(
@@ -122,6 +142,26 @@ export declare function deviceFactoryInfoGet(
122
142
  params?: CommonParams
123
143
  ): Response<DeviceFactoryInfo>;
124
144
 
145
+ export declare function deviceSettingsGet(
146
+ connectId: string,
147
+ params?: CommonParams
148
+ ): Response<DeviceSettings>;
149
+
150
+ export declare function deviceSettingsSet(
151
+ connectId: string,
152
+ params: CommonParams & DeviceSettingsSetParams
153
+ ): Response<Success>;
154
+
155
+ export declare function deviceSettingsPageShow(
156
+ connectId: string,
157
+ params: CommonParams & DeviceSettingsPageShowParams
158
+ ): Response<Success>;
159
+
160
+ export declare function deviceUploadWallpaper(
161
+ connectId: string,
162
+ params: CommonParams & DeviceUploadWallpaperParams
163
+ ): Response<DeviceUploadWallpaperResponse>;
164
+
125
165
  export declare function filesystemPermissionFix(
126
166
  connectId: string,
127
167
  params?: CommonParams
@@ -181,6 +221,15 @@ export declare function pathInfo(
181
221
 
182
222
  export declare const filesystemFileRead: typeof fileRead;
183
223
  export declare const filesystemFileWrite: typeof fileWrite;
224
+
225
+ export declare function uploadPortfolio(
226
+ connectId: string,
227
+ params: {
228
+ operationId?: string;
229
+ packageBytes: ArrayBuffer | Uint8Array | Blob;
230
+ timeoutMs?: number | string;
231
+ }
232
+ ): Response<FileInfo & { portfolioUpdated: true }>;
184
233
  export declare const filesystemFileDelete: typeof fileDelete;
185
234
  export declare const filesystemDirList: typeof dirList;
186
235
  export declare const filesystemDirMake: typeof dirMake;
@@ -91,6 +91,7 @@ export type DeviceFeaturesProtocol = 'V1' | 'V2' | 'unknown';
91
91
  export type DeviceFeaturesMode =
92
92
  | 'normal'
93
93
  | 'bootloader'
94
+ | 'romloader'
94
95
  | 'notInitialized'
95
96
  | 'backupMode'
96
97
  | 'unknown';
@@ -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 => {
@@ -0,0 +1,111 @@
1
+ import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+
3
+ export const PRO2_WALLPAPER_WIDTH = 604;
4
+ export const PRO2_WALLPAPER_HEIGHT = 1024;
5
+
6
+ export type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8';
7
+
8
+ const COLOR_FORMAT_RGB565 = 0x12;
9
+ const COLOR_FORMAT_RGB565A8 = 0x14;
10
+
11
+ const RED_THRESHOLD = [
12
+ 1, 7, 3, 5, 0, 8, 2, 6, 7, 1, 5, 3, 8, 0, 6, 2, 3, 5, 0, 8, 2, 6, 1, 7, 5, 3, 8,
13
+ 0, 6, 2, 7, 1, 0, 8, 2, 6, 1, 7, 3, 5, 8, 0, 6, 2, 7, 1, 5, 3, 2, 6, 1, 7, 3, 5, 0,
14
+ 8, 6, 2, 7, 1, 5, 3, 8, 0,
15
+ ];
16
+ const GREEN_THRESHOLD = [
17
+ 1, 3, 2, 2, 3, 1, 2, 2, 2, 2, 0, 4, 2, 2, 4, 0, 3, 1, 2, 2, 1, 3, 2, 2, 2, 2, 4,
18
+ 0, 2, 2, 0, 4, 1, 3, 2, 2, 3, 1, 2, 2, 2, 2, 0, 4, 2, 2, 4, 0, 3, 1, 2, 2, 1, 3, 2,
19
+ 2, 2, 2, 4, 0, 2, 2, 0, 4,
20
+ ];
21
+ const BLUE_THRESHOLD = [
22
+ 5, 3, 8, 0, 6, 2, 7, 1, 3, 5, 0, 8, 2, 6, 1, 7, 8, 0, 6, 2, 7, 1, 5, 3, 0, 8, 2,
23
+ 6, 1, 7, 3, 5, 6, 2, 7, 1, 5, 3, 8, 0, 2, 6, 1, 7, 3, 5, 0, 8, 7, 1, 5, 3, 8, 0, 6,
24
+ 2, 1, 7, 3, 5, 0, 8, 2, 6,
25
+ ];
26
+
27
+ function invalidParameter(message: string): Error {
28
+ return ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter, message);
29
+ }
30
+
31
+ function asBytes(rgba: Uint8Array | ArrayBuffer): Uint8Array {
32
+ return rgba instanceof Uint8Array ? rgba : new Uint8Array(rgba);
33
+ }
34
+
35
+ function align(value: number, boundary: number): number {
36
+ return Math.ceil(value / boundary) * boundary;
37
+ }
38
+
39
+ export function encodePro2Wallpaper(options: {
40
+ width: number;
41
+ height: number;
42
+ rgba: Uint8Array | ArrayBuffer;
43
+ }): { data: Uint8Array; colorFormat: Pro2WallpaperColorFormat } {
44
+ const { width, height } = options;
45
+ if (!Number.isInteger(width) || width <= 0 || width > 0xffff) {
46
+ throw invalidParameter('Wallpaper width must be an integer between 1 and 65535.');
47
+ }
48
+ if (!Number.isInteger(height) || height <= 0 || height > 0xffff) {
49
+ throw invalidParameter('Wallpaper height must be an integer between 1 and 65535.');
50
+ }
51
+
52
+ const rgba = asBytes(options.rgba);
53
+ const expectedLength = width * height * 4;
54
+ if (rgba.byteLength !== expectedLength) {
55
+ throw invalidParameter(
56
+ `Wallpaper RGBA data length must be ${expectedLength} bytes, received ${rgba.byteLength}.`
57
+ );
58
+ }
59
+
60
+ let hasTransparency = false;
61
+ for (let index = 3; index < rgba.length; index += 4) {
62
+ if (rgba[index] !== 0xff) {
63
+ hasTransparency = true;
64
+ break;
65
+ }
66
+ }
67
+
68
+ const colorFormat: Pro2WallpaperColorFormat = hasTransparency ? 'RGB565A8' : 'RGB565';
69
+ const stride = align(width * 2, 4);
70
+ const alphaStride = stride / 2;
71
+ const rgbSize = stride * height;
72
+ const alphaSize = hasTransparency ? alphaStride * height : 0;
73
+ const data = new Uint8Array(12 + rgbSize + alphaSize);
74
+ const view = new DataView(data.buffer);
75
+
76
+ data[0] = 0x19;
77
+ data[1] = hasTransparency ? COLOR_FORMAT_RGB565A8 : COLOR_FORMAT_RGB565;
78
+ view.setUint16(2, 0, true);
79
+ view.setUint16(4, width, true);
80
+ view.setUint16(6, height, true);
81
+ view.setUint16(8, stride, true);
82
+ view.setUint16(10, 0, true);
83
+
84
+ for (let y = 0; y < height; y += 1) {
85
+ for (let x = 0; x < width; x += 1) {
86
+ const sourceOffset = (y * width + x) * 4;
87
+ const thresholdIndex = ((y & 7) << 3) + (x & 7);
88
+ let red = Math.min(rgba[sourceOffset] + RED_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
89
+ let green =
90
+ Math.min(rgba[sourceOffset + 1] + GREEN_THRESHOLD[thresholdIndex], 0xff) & 0xfc;
91
+ let blue =
92
+ Math.min(rgba[sourceOffset + 2] + BLUE_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
93
+ if (!hasTransparency) {
94
+ const alpha = rgba[sourceOffset + 3];
95
+ red = (red * alpha) >> 8;
96
+ green = (green * alpha) >> 8;
97
+ blue = (blue * alpha) >> 8;
98
+ }
99
+ const rgb565 = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
100
+ const rgbOffset = 12 + y * stride + x * 2;
101
+ data[rgbOffset] = rgb565 & 0xff;
102
+ data[rgbOffset + 1] = rgb565 >> 8;
103
+
104
+ if (hasTransparency) {
105
+ data[12 + rgbSize + y * alphaStride + x] = rgba[sourceOffset + 3];
106
+ }
107
+ }
108
+ }
109
+
110
+ return { data, colorFormat };
111
+ }