@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.
- package/__tests__/DeviceCommands.test.ts +25 -0
- package/__tests__/RequestQueue.test.ts +34 -0
- package/__tests__/pro2Wallpaper.test.ts +50 -0
- package/__tests__/protocol-v2.test.ts +511 -61
- package/__tests__/protocolV2FileWrite.test.ts +55 -0
- package/dist/api/BaseMethod.d.ts +4 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +0 -4
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts +1 -6
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +18 -0
- package/dist/api/UploadPortfolio.d.ts.map +1 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts +32 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts +1 -4
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +16 -0
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +12 -0
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
- package/dist/core/RequestQueue.d.ts +2 -0
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/deviceProfile/buildDeviceFeatures.d.ts +2 -2
- package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -1
- package/dist/events/call.d.ts +7 -0
- package/dist/events/call.d.ts.map +1 -1
- package/dist/events/core.d.ts +2 -2
- package/dist/events/core.d.ts.map +1 -1
- package/dist/events/iframe.d.ts +1 -0
- package/dist/events/iframe.d.ts.map +1 -1
- package/dist/index.d.ts +80 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +922 -472
- package/dist/inject.d.ts +3 -2
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts +2 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +1 -0
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +1 -1
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +9 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +2 -0
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceInfo.d.ts +1 -1
- package/dist/types/api/getDeviceInfo.d.ts.map +1 -1
- package/dist/types/api/getPassphraseState.d.ts +2 -10
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +9 -2
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +20 -4
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/device.d.ts +1 -1
- package/dist/types/device.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -2
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Wallpaper.d.ts +12 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +18 -0
- package/src/api/FileWrite.ts +18 -178
- package/src/api/FirmwareUpdateV4.ts +21 -91
- package/src/api/GetPassphraseState.ts +9 -18
- package/src/api/UploadPortfolio.ts +37 -0
- package/src/api/helpers/protocolV2FileWrite.ts +164 -0
- package/src/api/index.ts +6 -0
- package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +18 -0
- package/src/api/protocol-v2/DeviceSessionGet.ts +3 -14
- package/src/api/protocol-v2/DeviceSettingsGet.ts +16 -0
- package/src/api/protocol-v2/DeviceSettingsPageShow.ts +59 -0
- package/src/api/protocol-v2/DeviceSettingsSet.ts +39 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +124 -0
- package/src/core/RequestQueue.ts +19 -0
- package/src/core/index.ts +10 -1
- package/src/data/messages/messages-protocol-v2.json +92 -8
- package/src/device/Device.ts +17 -3
- package/src/device/DeviceCommands.ts +9 -3
- package/src/deviceProfile/buildDeviceFeatures.ts +20 -12
- package/src/deviceProfile/buildDeviceProfile.ts +8 -6
- package/src/events/call.ts +6 -0
- package/src/events/core.ts +2 -0
- package/src/events/iframe.ts +1 -0
- package/src/index.ts +4 -0
- package/src/inject.ts +15 -0
- package/src/lowLevelInject.ts +3 -0
- package/src/protocols/protocol-v2/features.ts +19 -1
- package/src/protocols/protocol-v2/index.ts +2 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +46 -0
- package/src/protocols/protocol-v2/walletSession.ts +14 -5
- package/src/topLevelInject.ts +2 -0
- package/src/types/api/firmwareUpdate.ts +12 -0
- package/src/types/api/getDeviceInfo.ts +1 -1
- package/src/types/api/getPassphraseState.ts +2 -11
- package/src/types/api/index.ts +14 -1
- package/src/types/api/protocolV2.ts +52 -3
- package/src/types/device.ts +1 -0
- package/src/utils/deviceFeaturesUtils.ts +3 -8
- package/src/utils/index.ts +6 -0
- package/src/utils/pro2Wallpaper.ts +111 -0
package/src/events/call.ts
CHANGED
|
@@ -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;
|
package/src/events/core.ts
CHANGED
|
@@ -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
|
package/src/events/iframe.ts
CHANGED
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) =>
|
package/src/lowLevelInject.ts
CHANGED
|
@@ -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
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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 &&
|
package/src/topLevelInject.ts
CHANGED
|
@@ -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
|
|
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<
|
|
8
|
+
): Response<string | undefined>;
|
package/src/types/api/index.ts
CHANGED
|
@@ -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
|
|
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 {
|
|
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 {
|
|
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
|
|
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;
|
package/src/types/device.ts
CHANGED
|
@@ -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 =
|
|
200
|
-
?
|
|
201
|
-
|
|
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',
|
package/src/utils/index.ts
CHANGED
|
@@ -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
|
+
}
|