@onekeyfe/hd-core 1.2.0-alpha.77 → 1.2.0-alpha.78
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__/device-state-mapper.test.ts +16 -1
- package/__tests__/device-state-projector.test.ts +20 -0
- package/__tests__/device-state-store.test.ts +27 -0
- package/__tests__/homescreen.test.ts +17 -0
- package/__tests__/method-protocol-support.test.ts +13 -1
- package/__tests__/protocol-v2-resources.test.ts +11 -0
- package/dist/api/utils.d.ts +2 -0
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/device/DeviceStateMapper.d.ts.map +1 -1
- package/dist/device/DeviceStateProjector.d.ts.map +1 -1
- package/dist/device/DeviceStateStore.d.ts.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +260 -98
- package/dist/types/device.d.ts +8 -0
- package/dist/types/device.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/utils.ts +25 -0
- package/src/data-manager/DataManager.ts +15 -0
- package/src/device/DeviceStateMapper.ts +42 -0
- package/src/device/DeviceStateProjector.ts +58 -0
- package/src/device/DeviceStateStore.ts +31 -0
- package/src/index.ts +2 -0
- package/src/types/device.ts +16 -0
- package/src/utils/homescreen.ts +5 -1
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
mapLanguageToProtocolV2,
|
|
8
8
|
normalizeSafetyCheckLevel,
|
|
9
9
|
} from '../utils/deviceSettings';
|
|
10
|
+
import { getProtocolV2SeState, getProtocolV2SeType } from '../protocols/protocol-v2/features';
|
|
10
11
|
|
|
11
12
|
import type {
|
|
12
13
|
ApplySettings,
|
|
@@ -159,6 +160,11 @@ const meaningfulVersion = (version?: string | null) => {
|
|
|
159
160
|
return parts.map(part => (Number.isNaN(Number.parseInt(part, 10)) ? '0' : part)).join('.');
|
|
160
161
|
};
|
|
161
162
|
|
|
163
|
+
const meaningfulText = (value: unknown): string | null => {
|
|
164
|
+
if (value === undefined || value === null || value === '') return null;
|
|
165
|
+
return String(value);
|
|
166
|
+
};
|
|
167
|
+
|
|
162
168
|
export const mapProtocolV1OnekeyFeaturesToState = (features: OnekeyFeatures): DeviceStatePatch => {
|
|
163
169
|
const verification = definedEntries<DeviceFeaturesVerify>({
|
|
164
170
|
firmwareBuildId: features.onekey_firmware_build_id,
|
|
@@ -203,6 +209,24 @@ export const mapProtocolV1OnekeyFeaturesToState = (features: OnekeyFeatures): De
|
|
|
203
209
|
se04Boot: meaningfulVersion(features.onekey_se04_boot_version),
|
|
204
210
|
}),
|
|
205
211
|
...(Object.keys(verification).length > 0 ? { verification } : {}),
|
|
212
|
+
securityElements: {
|
|
213
|
+
se01: {
|
|
214
|
+
type: meaningfulText(features.onekey_se_type),
|
|
215
|
+
state: meaningfulText(features.onekey_se01_state),
|
|
216
|
+
},
|
|
217
|
+
se02: {
|
|
218
|
+
type: null,
|
|
219
|
+
state: meaningfulText(features.onekey_se02_state),
|
|
220
|
+
},
|
|
221
|
+
se03: {
|
|
222
|
+
type: null,
|
|
223
|
+
state: meaningfulText(features.onekey_se03_state),
|
|
224
|
+
},
|
|
225
|
+
se04: {
|
|
226
|
+
type: null,
|
|
227
|
+
state: meaningfulText(features.onekey_se04_state),
|
|
228
|
+
},
|
|
229
|
+
},
|
|
206
230
|
raw: { protocolV1OneKeyFeatures: features },
|
|
207
231
|
};
|
|
208
232
|
};
|
|
@@ -288,6 +312,24 @@ export const mapProtocolV2DeviceInfoToState = (
|
|
|
288
312
|
se04BootBuildId: imageBuildId(info.se4?.bootloader),
|
|
289
313
|
se04BootHash: imageHash(info.se4?.bootloader),
|
|
290
314
|
}),
|
|
315
|
+
securityElements: {
|
|
316
|
+
se01: {
|
|
317
|
+
type: getProtocolV2SeType(info.se1),
|
|
318
|
+
state: getProtocolV2SeState(info.se1),
|
|
319
|
+
},
|
|
320
|
+
se02: {
|
|
321
|
+
type: getProtocolV2SeType(info.se2),
|
|
322
|
+
state: getProtocolV2SeState(info.se2),
|
|
323
|
+
},
|
|
324
|
+
se03: {
|
|
325
|
+
type: getProtocolV2SeType(info.se3),
|
|
326
|
+
state: getProtocolV2SeState(info.se3),
|
|
327
|
+
},
|
|
328
|
+
se04: {
|
|
329
|
+
type: getProtocolV2SeType(info.se4),
|
|
330
|
+
state: getProtocolV2SeState(info.se4),
|
|
331
|
+
},
|
|
332
|
+
},
|
|
291
333
|
raw: {
|
|
292
334
|
protocolV2DeviceInfo: info,
|
|
293
335
|
...(loader ? { protocolV2DeviceStatus: null } : {}),
|
|
@@ -9,6 +9,62 @@ type StoredDeviceState = DeviceState & {
|
|
|
9
9
|
const getBootloaderMode = (state: StoredDeviceState) =>
|
|
10
10
|
state.status.mode === 'bootloader' || state.status.mode === 'romloader';
|
|
11
11
|
|
|
12
|
+
const projectLegacyAdvancedFields = (state: StoredDeviceState) => {
|
|
13
|
+
const verification = state.verification ?? {};
|
|
14
|
+
const securityElements = state.securityElements ?? {};
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
onekey_device_type: state.identity.deviceType,
|
|
18
|
+
onekey_serial_no: state.identity.serialNo,
|
|
19
|
+
onekey_se_type:
|
|
20
|
+
securityElements.se01?.type ??
|
|
21
|
+
securityElements.se02?.type ??
|
|
22
|
+
securityElements.se03?.type ??
|
|
23
|
+
securityElements.se04?.type,
|
|
24
|
+
onekey_board_version: state.versions.board,
|
|
25
|
+
onekey_board_hash: verification.boardHash,
|
|
26
|
+
onekey_board_build_id: verification.boardBuildId,
|
|
27
|
+
onekey_boot_version: state.versions.bootloader,
|
|
28
|
+
onekey_boot_hash: verification.bootloaderHash,
|
|
29
|
+
onekey_boot_build_id: verification.bootloaderBuildId,
|
|
30
|
+
onekey_firmware_version: state.versions.firmware,
|
|
31
|
+
onekey_firmware_hash: verification.firmwareHash,
|
|
32
|
+
onekey_firmware_build_id: verification.firmwareBuildId,
|
|
33
|
+
onekey_ble_version: state.versions.ble,
|
|
34
|
+
onekey_ble_hash: verification.bleHash,
|
|
35
|
+
onekey_ble_build_id: verification.bleBuildId,
|
|
36
|
+
onekey_ble_name: state.identity.bleName,
|
|
37
|
+
onekey_se01_version: state.versions.se01,
|
|
38
|
+
onekey_se01_hash: verification.se01Hash,
|
|
39
|
+
onekey_se01_build_id: verification.se01BuildId,
|
|
40
|
+
onekey_se01_state: securityElements.se01?.state,
|
|
41
|
+
onekey_se01_boot_version: state.versions.se01Boot,
|
|
42
|
+
onekey_se01_boot_hash: verification.se01BootHash,
|
|
43
|
+
onekey_se01_boot_build_id: verification.se01BootBuildId,
|
|
44
|
+
onekey_se02_version: state.versions.se02,
|
|
45
|
+
onekey_se02_hash: verification.se02Hash,
|
|
46
|
+
onekey_se02_build_id: verification.se02BuildId,
|
|
47
|
+
onekey_se02_state: securityElements.se02?.state,
|
|
48
|
+
onekey_se02_boot_version: state.versions.se02Boot,
|
|
49
|
+
onekey_se02_boot_hash: verification.se02BootHash,
|
|
50
|
+
onekey_se02_boot_build_id: verification.se02BootBuildId,
|
|
51
|
+
onekey_se03_version: state.versions.se03,
|
|
52
|
+
onekey_se03_hash: verification.se03Hash,
|
|
53
|
+
onekey_se03_build_id: verification.se03BuildId,
|
|
54
|
+
onekey_se03_state: securityElements.se03?.state,
|
|
55
|
+
onekey_se03_boot_version: state.versions.se03Boot,
|
|
56
|
+
onekey_se03_boot_hash: verification.se03BootHash,
|
|
57
|
+
onekey_se03_boot_build_id: verification.se03BootBuildId,
|
|
58
|
+
onekey_se04_version: state.versions.se04,
|
|
59
|
+
onekey_se04_hash: verification.se04Hash,
|
|
60
|
+
onekey_se04_build_id: verification.se04BuildId,
|
|
61
|
+
onekey_se04_state: securityElements.se04?.state,
|
|
62
|
+
onekey_se04_boot_version: state.versions.se04Boot,
|
|
63
|
+
onekey_se04_boot_hash: verification.se04BootHash,
|
|
64
|
+
onekey_se04_boot_build_id: verification.se04BootBuildId,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
12
68
|
export const projectFeatures = (state: StoredDeviceState): Features => {
|
|
13
69
|
const snapshot = cloneDeviceState(state);
|
|
14
70
|
const rawFeatures = snapshot.raw?.protocolV1Features ?? {};
|
|
@@ -21,10 +77,12 @@ export const projectFeatures = (state: StoredDeviceState): Features => {
|
|
|
21
77
|
snapshot.protocol === 'V1'
|
|
22
78
|
? (rawFeatures as { bootloader_mode?: boolean | null }).bootloader_mode ?? null
|
|
23
79
|
: getBootloaderMode(snapshot);
|
|
80
|
+
const legacyAdvancedFields = projectLegacyAdvancedFields(snapshot);
|
|
24
81
|
|
|
25
82
|
return {
|
|
26
83
|
...publicRawFeatures,
|
|
27
84
|
...rawOneKeyFeatures,
|
|
85
|
+
...legacyAdvancedFields,
|
|
28
86
|
protocol: snapshot.protocol,
|
|
29
87
|
protocolVersion: snapshot.protocolVersion ?? (snapshot.protocol === 'V1' ? 1 : null),
|
|
30
88
|
deviceType: snapshot.identity.deviceType,
|
|
@@ -106,6 +106,27 @@ const applySectionPatch = <T extends object>(
|
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
+
const mergeSecurityElements = (
|
|
110
|
+
current: StoredDeviceState['securityElements'],
|
|
111
|
+
patch: NonNullable<DeviceStatePatch['securityElements']>
|
|
112
|
+
) => {
|
|
113
|
+
const merged = cloneDeviceState(current ?? {});
|
|
114
|
+
|
|
115
|
+
for (const key of Object.keys(patch) as Array<keyof typeof patch>) {
|
|
116
|
+
const elementPatch = patch[key];
|
|
117
|
+
if (elementPatch !== undefined) {
|
|
118
|
+
const currentElement = merged[key];
|
|
119
|
+
merged[key] = {
|
|
120
|
+
type: elementPatch.type !== undefined ? elementPatch.type : currentElement?.type ?? null,
|
|
121
|
+
state:
|
|
122
|
+
elementPatch.state !== undefined ? elementPatch.state : currentElement?.state ?? null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return merged;
|
|
128
|
+
};
|
|
129
|
+
|
|
109
130
|
export class DeviceStateStore {
|
|
110
131
|
private state: StoredDeviceState | undefined;
|
|
111
132
|
|
|
@@ -148,6 +169,16 @@ export class DeviceStateStore {
|
|
|
148
169
|
if (patch.status) applySectionPatch(next.status, patch.status, 'status', changedKeys);
|
|
149
170
|
if (patch.settings) applySectionPatch(next.settings, patch.settings, 'settings', changedKeys);
|
|
150
171
|
if (patch.versions) applySectionPatch(next.versions, patch.versions, 'versions', changedKeys);
|
|
172
|
+
if (patch.securityElements !== undefined) {
|
|
173
|
+
const mergedSecurityElements = mergeSecurityElements(
|
|
174
|
+
next.securityElements,
|
|
175
|
+
patch.securityElements
|
|
176
|
+
);
|
|
177
|
+
if (!isEqual(next.securityElements, mergedSecurityElements)) {
|
|
178
|
+
next.securityElements = mergedSecurityElements;
|
|
179
|
+
changedKeys.push('securityElements');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
151
182
|
|
|
152
183
|
if (patch.capabilities !== undefined && !isEqual(next.capabilities, patch.capabilities)) {
|
|
153
184
|
next.capabilities = cloneDeviceState(patch.capabilities);
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,8 @@ export * from './types';
|
|
|
19
19
|
export { whitelist, whitelistExtension } from './data/config';
|
|
20
20
|
export { executeCallback, cleanupCallback };
|
|
21
21
|
export { preloadSessionCache } from './device/Device';
|
|
22
|
+
export { projectFeatures as projectDeviceStateFeatures } from './device/DeviceStateProjector';
|
|
23
|
+
export { getMethodSupportedProtocols } from './api/utils';
|
|
22
24
|
export {
|
|
23
25
|
getFirmwareUpdateHostBindingGeneration,
|
|
24
26
|
registerFirmwareUpdateHostBinding,
|
package/src/types/device.ts
CHANGED
|
@@ -259,6 +259,19 @@ export type DeviceStateVersions = {
|
|
|
259
259
|
se04Boot?: string | null;
|
|
260
260
|
};
|
|
261
261
|
|
|
262
|
+
export type DeviceStateSecurityElement = {
|
|
263
|
+
type: string | null;
|
|
264
|
+
state: string | null;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export type DeviceStateSecurityElements = Partial<
|
|
268
|
+
Record<'se01' | 'se02' | 'se03' | 'se04', DeviceStateSecurityElement>
|
|
269
|
+
>;
|
|
270
|
+
|
|
271
|
+
export type DeviceStateSecurityElementsPatch = Partial<
|
|
272
|
+
Record<keyof DeviceStateSecurityElements, Partial<DeviceStateSecurityElement>>
|
|
273
|
+
>;
|
|
274
|
+
|
|
262
275
|
export type DeviceState = {
|
|
263
276
|
schemaVersion: 1;
|
|
264
277
|
revision: number;
|
|
@@ -270,6 +283,8 @@ export type DeviceState = {
|
|
|
270
283
|
status: DeviceStateStatus;
|
|
271
284
|
settings: DeviceStateSettings;
|
|
272
285
|
versions: DeviceStateVersions;
|
|
286
|
+
/** Secure-element metadata exposed by the unified firmware information read. */
|
|
287
|
+
securityElements?: DeviceStateSecurityElements;
|
|
273
288
|
capabilities: Array<number | string>;
|
|
274
289
|
verification?: Partial<DeviceFeaturesVerify>;
|
|
275
290
|
};
|
|
@@ -281,6 +296,7 @@ export type DeviceStatePatch = {
|
|
|
281
296
|
status?: Partial<DeviceStateStatus>;
|
|
282
297
|
settings?: Partial<DeviceStateSettings>;
|
|
283
298
|
versions?: Partial<DeviceStateVersions>;
|
|
299
|
+
securityElements?: DeviceStateSecurityElementsPatch;
|
|
284
300
|
capabilities?: Array<number | string>;
|
|
285
301
|
verification?: DeviceFeaturesVerify;
|
|
286
302
|
raw?: DeviceFeaturesRawPatch;
|
package/src/utils/homescreen.ts
CHANGED
|
@@ -328,6 +328,10 @@ export const getNftSize = ({
|
|
|
328
328
|
full: { width: PRO2_NFT_IMAGE_WIDTH, height: PRO2_NFT_IMAGE_HEIGHT },
|
|
329
329
|
thumbnail: { width: PRO2_NFT_THUMBNAIL_WIDTH, height: PRO2_NFT_THUMBNAIL_HEIGHT },
|
|
330
330
|
},
|
|
331
|
+
neo: {
|
|
332
|
+
full: { width: PRO2_NFT_IMAGE_WIDTH, height: PRO2_NFT_IMAGE_HEIGHT },
|
|
333
|
+
thumbnail: { width: PRO2_NFT_THUMBNAIL_WIDTH, height: PRO2_NFT_THUMBNAIL_HEIGHT },
|
|
334
|
+
},
|
|
331
335
|
};
|
|
332
336
|
|
|
333
337
|
return sizes[deviceType]?.[thumbnail ? 'thumbnail' : 'full'];
|
|
@@ -342,7 +346,7 @@ export const getHomeScreenSize = ({
|
|
|
342
346
|
homeScreenType: 'WallPaper' | 'Nft';
|
|
343
347
|
thumbnail?: boolean;
|
|
344
348
|
}) => {
|
|
345
|
-
if (deviceType === EDeviceType.Pro2) {
|
|
349
|
+
if (deviceType === EDeviceType.Pro2 || deviceType === EDeviceType.Neo) {
|
|
346
350
|
return thumbnail ? undefined : { width: PRO2_WALLPAPER_WIDTH, height: PRO2_WALLPAPER_HEIGHT };
|
|
347
351
|
}
|
|
348
352
|
|