@onekeyfe/hd-core 1.2.0-alpha.1 → 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.
- package/__tests__/DeviceCommands.test.ts +25 -0
- package/__tests__/RequestQueue.test.ts +34 -0
- package/__tests__/connectSettings.test.ts +19 -0
- package/__tests__/device-wallet-session-store.test.ts +131 -0
- package/__tests__/preInitialize.test.ts +33 -0
- package/__tests__/pro2Wallpaper.test.ts +50 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
- package/__tests__/protocol-v2.test.ts +3253 -1605
- package/dist/api/BaseMethod.d.ts +4 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts +9 -0
- package/dist/api/ClearSessionCache.d.ts.map +1 -0
- package/dist/api/FileRead.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +20 -3
- 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/firmware/FirmwareUpdateBaseMethod.d.ts +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +4 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/progressThrottle.d.ts +3 -0
- package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
- package/dist/api/index.d.ts +13 -10
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +3 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/{DeviceGetDeviceInfo.d.ts → DeviceInfoGet.d.ts} +10 -10
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -0
- 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/DeviceStatusGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceStatusGet.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/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/{FilesystemFixPermission.d.ts → FilesystemPermissionFix.d.ts} +2 -2
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +6 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -0
- package/dist/api/protocol-v2/helpers.d.ts +27 -18
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +1 -5
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +0 -1
- package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
- package/dist/api/tron/TronSignTransaction.d.ts +0 -1
- package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
- 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/data-manager/DataManager.d.ts +1 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +6 -3
- 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/device/DeviceWalletSessionStore.d.ts +15 -0
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
- 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 +166 -70
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2659 -1750
- 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 +12 -14
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts +11 -9
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +1 -0
- 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 +13 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +6 -6
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceInfo.d.ts +2 -0
- 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 +18 -12
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +31 -17
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +10 -0
- package/dist/types/api/sessionCache.d.ts.map +1 -0
- package/dist/types/device.d.ts +1 -0
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +21 -2
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +2 -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/ClearSessionCache.ts +28 -0
- package/src/api/FileRead.ts +16 -3
- package/src/api/FileWrite.ts +22 -1
- package/src/api/FirmwareUpdateV4.ts +1006 -265
- package/src/api/GetOnekeyFeatures.ts +1 -1
- package/src/api/GetPassphraseState.ts +9 -15
- package/src/api/UploadPortfolio.ts +37 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +4 -4
- package/src/api/device/DeviceRebootToBootloader.ts +4 -4
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +18 -4
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/index.ts +13 -10
- package/src/api/protocol-v2/{FactoryGetDeviceInfo.ts → DeviceFactoryInfoGet.ts} +3 -3
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +32 -0
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +3 -5
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +39 -5
- package/src/api/protocol-v2/{DeviceGetDeviceInfo.ts → DeviceInfoGet.ts} +52 -22
- package/src/api/protocol-v2/DeviceReboot.ts +1 -1
- package/src/api/protocol-v2/DeviceSessionGet.ts +15 -0
- package/src/api/protocol-v2/{DeviceGetOnboardingStatus.ts → DeviceSettingsGet.ts} +3 -3
- package/src/api/protocol-v2/DeviceSettingsPageShow.ts +59 -0
- package/src/api/protocol-v2/DeviceSettingsSet.ts +39 -0
- package/src/api/protocol-v2/DeviceStatusGet.ts +14 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +160 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +4 -1
- package/src/api/protocol-v2/{FilesystemFixPermission.ts → FilesystemPermissionFix.ts} +2 -2
- package/src/api/protocol-v2/{GetProtoVersion.ts → ProtocolInfoRequest.ts} +2 -2
- package/src/api/protocol-v2/helpers.ts +71 -47
- package/src/api/ton/TonSignData.ts +1 -5
- package/src/api/tron/TronSignMessage.ts +0 -1
- package/src/api/tron/TronSignTransaction.ts +0 -1
- package/src/core/RequestQueue.ts +19 -0
- package/src/core/index.ts +29 -6
- package/src/data/messages/messages-protocol-v2.json +760 -1110
- package/src/data/messages/messages.json +8 -0
- package/src/data-manager/DataManager.ts +7 -0
- package/src/data-manager/connectSettings.ts +2 -4
- package/src/device/Device.ts +103 -70
- package/src/device/DeviceCommands.ts +9 -3
- package/src/device/DeviceWalletSessionStore.ts +78 -0
- package/src/deviceProfile/buildDeviceFeatures.ts +60 -63
- package/src/deviceProfile/buildDeviceProfile.ts +77 -58
- 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 +26 -16
- package/src/lowLevelInject.ts +3 -0
- package/src/protocols/protocol-v2/features.ts +26 -63
- package/src/protocols/protocol-v2/firmware.ts +12 -36
- package/src/protocols/protocol-v2/index.ts +1 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +46 -0
- package/src/protocols/protocol-v2/walletSession.ts +92 -0
- package/src/topLevelInject.ts +2 -0
- package/src/types/api/firmwareUpdate.ts +28 -20
- package/src/types/api/getDeviceInfo.ts +2 -0
- package/src/types/api/getPassphraseState.ts +2 -11
- package/src/types/api/index.ts +29 -21
- package/src/types/api/protocolV2.ts +74 -35
- package/src/types/api/sessionCache.ts +14 -0
- package/src/types/device.ts +1 -0
- package/src/types/params.ts +4 -0
- package/src/types/settings.ts +42 -35
- package/src/utils/deviceFeaturesUtils.ts +46 -20
- package/src/utils/index.ts +6 -0
- package/src/utils/pro2Wallpaper.ts +111 -0
- package/dist/api/protocol-v2/DevReboot.d.ts +0 -7
- package/dist/api/protocol-v2/DevReboot.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +0 -6
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
- package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
- package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
- package/src/api/protocol-v2/DevReboot.ts +0 -24
- package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -29
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceSEState, DeviceSeType } from '@onekeyfe/hd-transport';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { DeviceInfoGet, DeviceSEInfo, ProtocolV2DeviceInfo } from '@onekeyfe/hd-transport';
|
|
4
4
|
import type { DeviceCommands } from '../../device/DeviceCommands';
|
|
5
5
|
|
|
6
|
-
// 单源类型:直接使用 hd-transport 生成的 ProtocolV2DeviceInfo /
|
|
7
|
-
//
|
|
6
|
+
// 单源类型:直接使用 hd-transport 生成的 ProtocolV2DeviceInfo / DeviceSEInfo /
|
|
7
|
+
// DeviceFirmwareImageInfo(与 firmware-pro2 proto 一致),不再维护手写副本。
|
|
8
8
|
export type { ProtocolV2DeviceInfo };
|
|
9
|
-
export type {
|
|
10
|
-
export type {
|
|
9
|
+
export type { DeviceFirmwareImageInfo as ProtocolV2FirmwareImageInfo } from '@onekeyfe/hd-transport';
|
|
10
|
+
export type { DeviceSEInfo as ProtocolV2SEInfo } from '@onekeyfe/hd-transport';
|
|
11
11
|
|
|
12
12
|
export type ProtocolV2SeStateLabel = 'BOOT' | 'APP_FACTORY' | 'APP';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* 传输层沿用历史 decode 语义:单值 proto enum 输出为名称字符串。
|
|
16
|
+
* 这里按 SDK decode 后的字符串语义处理,同时接受数字枚举,便于低层调用复用。
|
|
17
17
|
*/
|
|
18
18
|
const normalizeEnumValue = <T extends Record<string | number, string | number>>(
|
|
19
19
|
enumObject: T,
|
|
@@ -26,11 +26,11 @@ const normalizeEnumValue = <T extends Record<string | number, string | number>>(
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* DeviceSEInfo.state → 可读标签。SDK 内唯一的 SE 状态映射实现,
|
|
30
30
|
* DeviceProfile 与标准 Features 构建都从这里取。
|
|
31
31
|
*/
|
|
32
|
-
export const getProtocolV2SeState = (se?:
|
|
33
|
-
const label = normalizeEnumValue(
|
|
32
|
+
export const getProtocolV2SeState = (se?: DeviceSEInfo): ProtocolV2SeStateLabel | null => {
|
|
33
|
+
const label = normalizeEnumValue(DeviceSEState, se?.state);
|
|
34
34
|
switch (label) {
|
|
35
35
|
case 'BOOT':
|
|
36
36
|
return 'BOOT';
|
|
@@ -44,17 +44,20 @@ export const getProtocolV2SeState = (se?: DevSEInfo): ProtocolV2SeStateLabel | n
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* DeviceSEInfo.type → 可读标签(如 'THD89')。DeviceProfile / Features
|
|
48
48
|
* 的 SE 类型归一化从这里取。
|
|
49
49
|
*/
|
|
50
|
-
export const getProtocolV2SeType = (se?:
|
|
51
|
-
normalizeEnumValue(
|
|
50
|
+
export const getProtocolV2SeType = (se?: DeviceSEInfo): string | null =>
|
|
51
|
+
normalizeEnumValue(DeviceSeType, se?.type);
|
|
52
|
+
|
|
53
|
+
export const isProtocolV2BootloaderDeviceInfo = (deviceInfo?: ProtocolV2DeviceInfo | null) =>
|
|
54
|
+
!!deviceInfo && deviceInfo.status == null;
|
|
52
55
|
|
|
53
56
|
export const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
|
|
54
57
|
targets: {
|
|
55
58
|
hw: true,
|
|
56
59
|
fw: true,
|
|
57
|
-
|
|
60
|
+
coprocessor: true,
|
|
58
61
|
status: true,
|
|
59
62
|
},
|
|
60
63
|
types: {
|
|
@@ -66,13 +69,13 @@ export const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
|
|
|
66
69
|
/**
|
|
67
70
|
* 轻量状态刷新请求(每次 run 前使用)。
|
|
68
71
|
*
|
|
69
|
-
* status 提供 init_states /
|
|
70
|
-
* hw /
|
|
72
|
+
* status 提供 init_states / passphrase_enabled 等会在设备端变化的字段;
|
|
73
|
+
* hw / coprocessor 提供 serialNo / bleName 等身份字段;不含 fw/SE targets,单帧请求开销很小。
|
|
71
74
|
*/
|
|
72
75
|
export const PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST = {
|
|
73
76
|
targets: {
|
|
74
77
|
hw: true,
|
|
75
|
-
|
|
78
|
+
coprocessor: true,
|
|
76
79
|
status: true,
|
|
77
80
|
},
|
|
78
81
|
types: {
|
|
@@ -85,7 +88,7 @@ export const PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST = {
|
|
|
85
88
|
targets: {
|
|
86
89
|
hw: true,
|
|
87
90
|
fw: true,
|
|
88
|
-
|
|
91
|
+
coprocessor: true,
|
|
89
92
|
se1: true,
|
|
90
93
|
se2: true,
|
|
91
94
|
se3: true,
|
|
@@ -102,7 +105,7 @@ export const PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST = {
|
|
|
102
105
|
targets: {
|
|
103
106
|
hw: true,
|
|
104
107
|
fw: true,
|
|
105
|
-
|
|
108
|
+
coprocessor: true,
|
|
106
109
|
se1: true,
|
|
107
110
|
se2: true,
|
|
108
111
|
se3: true,
|
|
@@ -120,43 +123,6 @@ export const PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST = {
|
|
|
120
123
|
export const PROTOCOL_V2_DEVICE_INFO_REQUEST = PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST;
|
|
121
124
|
export const PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS = 10 * 1000;
|
|
122
125
|
|
|
123
|
-
/**
|
|
124
|
-
* 临时开关(默认关闭):当前正式链路直接调用 DevGetDeviceInfo。
|
|
125
|
-
* 仅当 Pro2 测试固件 / 早期工程板尚未实现 DevGetDeviceInfo 时,才显式开启 mock。
|
|
126
|
-
* 开启时跳过 wire 调用,直接返回 mock DeviceInfo;
|
|
127
|
-
* DevGetDeviceInfo 尚未返回的字段保持为空,不再用 transport path 兜底成设备身份。
|
|
128
|
-
*
|
|
129
|
-
* 固件实现 DevGetDeviceInfo 稳定后:删除开关与 mock。
|
|
130
|
-
* 注意:开启期间 FirmwareUpdateV4 的“升级完成版本比对”拿到的也是 mock 版本,
|
|
131
|
-
* 不能作为升级成功的依据。
|
|
132
|
-
*/
|
|
133
|
-
let protocolV2DeviceInfoMockEnabled = false;
|
|
134
|
-
|
|
135
|
-
export const setProtocolV2DeviceInfoMock = (enabled: boolean) => {
|
|
136
|
-
protocolV2DeviceInfoMockEnabled = enabled;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export const isProtocolV2DeviceInfoMockEnabled = () => protocolV2DeviceInfoMockEnabled;
|
|
140
|
-
|
|
141
|
-
/** 每次调用返回新对象,避免调用方原地修改互相污染。 */
|
|
142
|
-
export const buildMockProtocolV2DeviceInfo = (): ProtocolV2DeviceInfo => ({
|
|
143
|
-
protocol_version: 2,
|
|
144
|
-
hw: {
|
|
145
|
-
// 留空:协议未上报时 SDK 不再用 transport path 伪造身份字段
|
|
146
|
-
serial_no: '',
|
|
147
|
-
},
|
|
148
|
-
fw: {
|
|
149
|
-
app: { version: '0.1.0' },
|
|
150
|
-
},
|
|
151
|
-
bt: {},
|
|
152
|
-
status: {
|
|
153
|
-
init_states: true,
|
|
154
|
-
language: 'en_US',
|
|
155
|
-
passphrase_protection: false,
|
|
156
|
-
bt_enable: true,
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
|
|
160
126
|
export async function requestProtocolV2DeviceInfo({
|
|
161
127
|
commands,
|
|
162
128
|
timeoutMs = PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS,
|
|
@@ -164,15 +130,12 @@ export async function requestProtocolV2DeviceInfo({
|
|
|
164
130
|
}: {
|
|
165
131
|
commands: DeviceCommands;
|
|
166
132
|
timeoutMs?: number;
|
|
167
|
-
request?:
|
|
133
|
+
request?: DeviceInfoGet;
|
|
168
134
|
}): Promise<ProtocolV2DeviceInfo> {
|
|
169
|
-
|
|
170
|
-
return buildMockProtocolV2DeviceInfo();
|
|
171
|
-
}
|
|
172
|
-
const { message } = await commands.typedCall('DevGetDeviceInfo', 'DeviceInfo', request, {
|
|
135
|
+
const { message } = await commands.typedCall('DeviceInfoGet', 'DeviceInfo', request, {
|
|
173
136
|
timeoutMs,
|
|
174
137
|
});
|
|
175
138
|
// 'DeviceInfo' 在生成类型里是 V1 DeviceInfo | ProtocolV2DeviceInfo 的合并;
|
|
176
|
-
//
|
|
139
|
+
// DeviceInfoGet 是 V2-only 消息,这里收窄到 V2 形态。
|
|
177
140
|
return message as ProtocolV2DeviceInfo;
|
|
178
141
|
}
|
|
@@ -1,43 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 当前 firmware-pro2 子模块的
|
|
3
|
-
*
|
|
4
|
-
* 注意:仓库里的 hd-transport 生成物暂时仍带旧 target 名称;这里显式按
|
|
5
|
-
* submodules/firmware-pro2/sys/protobuf/onekey_protocol/latest/messages_device.proto
|
|
6
|
-
* 对齐当前子模块,避免运行时取到 undefined。
|
|
2
|
+
* 当前 firmware-pro2 子模块的 DeviceFirmwareTargetType。
|
|
7
3
|
*/
|
|
8
4
|
export const ProtocolV2FirmwareTargetType = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
FW_MGMT_TARGET_INVALID: 0,
|
|
6
|
+
FW_MGMT_TARGET_CRATE: 1,
|
|
7
|
+
FW_MGMT_TARGET_ROMLOADER: 2,
|
|
8
|
+
FW_MGMT_TARGET_BOOTLOADER: 3,
|
|
9
|
+
FW_MGMT_TARGET_APPLICATION_P1: 4,
|
|
10
|
+
FW_MGMT_TARGET_APPLICATION_P2: 5,
|
|
11
|
+
FW_MGMT_TARGET_COPROCESSOR: 6,
|
|
12
|
+
FW_MGMT_TARGET_SE01: 7,
|
|
13
|
+
FW_MGMT_TARGET_SE02: 8,
|
|
14
|
+
FW_MGMT_TARGET_SE03: 9,
|
|
15
|
+
FW_MGMT_TARGET_SE04: 10,
|
|
17
16
|
} as const;
|
|
18
17
|
|
|
19
18
|
export type ProtocolV2FirmwareTargetType =
|
|
20
19
|
(typeof ProtocolV2FirmwareTargetType)[keyof typeof ProtocolV2FirmwareTargetType];
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Map Protocol V2 firmware file name to DevFirmwareUpdate target_id.
|
|
24
|
-
*/
|
|
25
|
-
export function protocolV2FileNameToTargetId(fileName: string): ProtocolV2FirmwareTargetType {
|
|
26
|
-
const normalized = fileName.toLowerCase();
|
|
27
|
-
if (normalized.includes('bootloader') || normalized.includes('update_rom')) {
|
|
28
|
-
return ProtocolV2FirmwareTargetType.TARGET_MAIN_BOOT;
|
|
29
|
-
}
|
|
30
|
-
if (
|
|
31
|
-
normalized.includes('coprocessor') ||
|
|
32
|
-
normalized.includes('ble') ||
|
|
33
|
-
normalized.includes('bluetooth') ||
|
|
34
|
-
normalized.includes('bt')
|
|
35
|
-
) {
|
|
36
|
-
return ProtocolV2FirmwareTargetType.TARGET_BT;
|
|
37
|
-
}
|
|
38
|
-
if (normalized.includes('se4')) return ProtocolV2FirmwareTargetType.TARGET_SE4;
|
|
39
|
-
if (normalized.includes('se3')) return ProtocolV2FirmwareTargetType.TARGET_SE3;
|
|
40
|
-
if (normalized.includes('se2')) return ProtocolV2FirmwareTargetType.TARGET_SE2;
|
|
41
|
-
if (normalized.includes('se')) return ProtocolV2FirmwareTargetType.TARGET_SE1;
|
|
42
|
-
return ProtocolV2FirmwareTargetType.TARGET_MAIN_APP;
|
|
43
|
-
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import type { Device } from '../../device/Device';
|
|
4
|
+
|
|
5
|
+
const getErrorText = (error: unknown) => {
|
|
6
|
+
if (error instanceof Error) return `${error.name} ${error.message}`;
|
|
7
|
+
if (typeof error === 'string') return error;
|
|
8
|
+
if (error && typeof error === 'object') {
|
|
9
|
+
const record = error as Record<string, unknown>;
|
|
10
|
+
return [record.code, record.errorCode, record.message, record.reason]
|
|
11
|
+
.filter(value => value !== undefined && value !== null)
|
|
12
|
+
.join(' ');
|
|
13
|
+
}
|
|
14
|
+
return String(error ?? '');
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const isProtocolV2InvalidSessionError = (error: unknown) =>
|
|
18
|
+
getErrorText(error).toLowerCase().includes('failure_invalidsession');
|
|
19
|
+
|
|
20
|
+
export async function requestProtocolV2DeviceStatus(device: Device) {
|
|
21
|
+
const { message } = await device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
|
|
22
|
+
return message;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function refreshProtocolV2DeviceStatus(device: Device) {
|
|
26
|
+
const status = await requestProtocolV2DeviceStatus(device);
|
|
27
|
+
return device.updateProtocolV2Status(status);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function getProtocolV2WalletSession(
|
|
31
|
+
device: Device,
|
|
32
|
+
options?: { initSession?: boolean; expectedPassphraseState?: string }
|
|
33
|
+
) {
|
|
34
|
+
if (device.features?.unlocked === false) {
|
|
35
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device is locked');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (options?.initSession) {
|
|
39
|
+
device.clearInternalState();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const cachedSessionId =
|
|
43
|
+
typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
|
|
44
|
+
|
|
45
|
+
try {
|
|
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
|
+
});
|
|
60
|
+
|
|
61
|
+
if (
|
|
62
|
+
options?.expectedPassphraseState &&
|
|
63
|
+
options.expectedPassphraseState !== message.btc_test_address
|
|
64
|
+
) {
|
|
65
|
+
device.clearInternalState();
|
|
66
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (message.btc_test_address && device.getCurrentPassphraseProtection() !== true) {
|
|
70
|
+
await refreshProtocolV2DeviceStatus(device);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
device.updateInternalState(
|
|
74
|
+
(device.getCurrentPassphraseProtection() ?? false) || Boolean(message.btc_test_address),
|
|
75
|
+
message.btc_test_address,
|
|
76
|
+
device.getCurrentDeviceId(),
|
|
77
|
+
message.session_id,
|
|
78
|
+
options?.initSession ? null : device.features?.sessionId
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
passphraseState: message.btc_test_address,
|
|
83
|
+
newSession: message.session_id,
|
|
84
|
+
unlockedAttachPin: device.features?.unlockedAttachPin ?? undefined,
|
|
85
|
+
};
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (isProtocolV2InvalidSessionError(error)) {
|
|
88
|
+
device.clearInternalState();
|
|
89
|
+
}
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
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']) =>
|
|
@@ -58,42 +58,50 @@ export interface FirmwareUpdateV3Params {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* firmwareUpdateV4(Protocol V2)按
|
|
62
|
-
*
|
|
61
|
+
* firmwareUpdateV4(Protocol V2)按 DeviceFirmwareTargetType 拆分的目标二进制。
|
|
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;
|
|
71
|
-
/**
|
|
83
|
+
/** FW_MGMT_TARGET_BOOTLOADER = 3 */
|
|
72
84
|
bootloaderBinary?: ArrayBuffer;
|
|
73
|
-
/**
|
|
85
|
+
/** FW_MGMT_TARGET_APPLICATION_P1 = 4 */
|
|
74
86
|
applicationP1Binary?: ArrayBuffer;
|
|
75
|
-
/**
|
|
87
|
+
/** FW_MGMT_TARGET_APPLICATION_P2 = 5 */
|
|
76
88
|
applicationP2Binary?: ArrayBuffer;
|
|
77
|
-
/**
|
|
89
|
+
/** FW_MGMT_TARGET_COPROCESSOR = 6 */
|
|
78
90
|
coprocessorBinary?: ArrayBuffer;
|
|
79
|
-
/**
|
|
91
|
+
/** FW_MGMT_TARGET_SE01-04 = 7-10 */
|
|
80
92
|
se01Binary?: ArrayBuffer;
|
|
81
93
|
se02Binary?: ArrayBuffer;
|
|
82
94
|
se03Binary?: ArrayBuffer;
|
|
83
95
|
se04Binary?: ArrayBuffer;
|
|
84
|
-
/** TARGET_RESOURCE = 10(zip 包,解压后逐文件上传) */
|
|
85
|
-
resourceBinary?: ArrayBuffer;
|
|
86
96
|
forcedUpdateRes?: boolean;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
/** legacy 别名:等价 coprocessorBinary */
|
|
96
|
-
bleBinary?: ArrayBuffer;
|
|
97
|
+
/**
|
|
98
|
+
* RESC bundle okpkg 列表,通过 FilesystemFileWrite 直写到 devicePath(vol0:/bundles/...)。
|
|
99
|
+
* 手动传入模式:SDK 直接 FileWrite 安装,不做版本比对。
|
|
100
|
+
*/
|
|
101
|
+
resourceBundleFiles?: Array<{
|
|
102
|
+
binary: ArrayBuffer;
|
|
103
|
+
devicePath: string;
|
|
104
|
+
}>;
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
export declare function firmwareUpdateV3(
|
|
@@ -24,6 +24,8 @@ export type DeviceInfoStatus = {
|
|
|
24
24
|
bootloaderMode: boolean | null;
|
|
25
25
|
unlocked: boolean | null;
|
|
26
26
|
passphraseProtection: boolean | null;
|
|
27
|
+
attachToPinEnabled?: boolean | null;
|
|
28
|
+
unlockedAttachPin?: boolean | null;
|
|
27
29
|
backupRequired: boolean | null;
|
|
28
30
|
noBackup: boolean | null;
|
|
29
31
|
language: string | null;
|
|
@@ -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
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
deviceFactoryInfoGet,
|
|
3
|
+
deviceFactoryInfoSet,
|
|
2
4
|
deviceFirmwareUpdate,
|
|
3
|
-
deviceGetDeviceInfo,
|
|
4
5
|
deviceGetFirmwareUpdateStatus,
|
|
5
|
-
|
|
6
|
+
deviceInfoGet,
|
|
6
7
|
deviceReboot,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
deviceSessionGet,
|
|
9
|
+
deviceSettingsGet,
|
|
10
|
+
deviceSettingsPageShow,
|
|
11
|
+
deviceSettingsSet,
|
|
12
|
+
deviceStatusGet,
|
|
13
|
+
deviceUploadWallpaper,
|
|
11
14
|
dirList,
|
|
12
15
|
dirMake,
|
|
13
16
|
dirRemove,
|
|
14
|
-
factoryDeviceInfoSettings,
|
|
15
|
-
factoryGetDeviceInfo,
|
|
16
17
|
fileDelete,
|
|
17
18
|
fileRead,
|
|
18
19
|
fileWrite,
|
|
@@ -23,12 +24,13 @@ import type {
|
|
|
23
24
|
filesystemFileDelete,
|
|
24
25
|
filesystemFileRead,
|
|
25
26
|
filesystemFileWrite,
|
|
26
|
-
filesystemFixPermission,
|
|
27
27
|
filesystemFormat,
|
|
28
28
|
filesystemPathInfoQuery,
|
|
29
|
-
|
|
29
|
+
filesystemPermissionFix,
|
|
30
30
|
pathInfo,
|
|
31
31
|
ping,
|
|
32
|
+
protocolInfoRequest,
|
|
33
|
+
uploadPortfolio,
|
|
32
34
|
} from './protocolV2';
|
|
33
35
|
import type { off, on, removeAllListeners } from './event';
|
|
34
36
|
import type { uiResponse } from './uiResponse';
|
|
@@ -36,6 +38,7 @@ import type { init, updateSettings } from './init';
|
|
|
36
38
|
import type { testInitializeDeviceDuration } from './testInitializeDeviceDuration';
|
|
37
39
|
import type { preInitialize } from './preInitialize';
|
|
38
40
|
import type { getLogs } from './getLogs';
|
|
41
|
+
import type { clearSessionCache } from './sessionCache';
|
|
39
42
|
import type { checkBridgeStatus } from './checkBridgeStatus';
|
|
40
43
|
import type { checkBridgeRelease } from './checkBridgeRelease';
|
|
41
44
|
import type { checkBootloaderRelease } from './checkBootloaderRelease';
|
|
@@ -181,7 +184,8 @@ export type {
|
|
|
181
184
|
DeviceProfileVerify,
|
|
182
185
|
DeviceProfileVersions,
|
|
183
186
|
} from './getDeviceInfo';
|
|
184
|
-
export type { GetPassphraseStateParams
|
|
187
|
+
export type { GetPassphraseStateParams } from './getPassphraseState';
|
|
188
|
+
export type { ClearSessionCacheParams, ClearSessionCachePayload } from './sessionCache';
|
|
185
189
|
|
|
186
190
|
export type CoreApi = {
|
|
187
191
|
/**
|
|
@@ -196,9 +200,11 @@ export type CoreApi = {
|
|
|
196
200
|
call: (params: any) => Promise<any>;
|
|
197
201
|
uiResponse: typeof uiResponse;
|
|
198
202
|
cancel: (connectId?: string) => void;
|
|
203
|
+
cancelOperation: (operationId: string) => void;
|
|
199
204
|
updateSettings: typeof updateSettings;
|
|
200
205
|
switchTransport: (env: ConnectSettings['env']) => Promise<{ success: boolean }>;
|
|
201
206
|
getLogs: typeof getLogs;
|
|
207
|
+
clearSessionCache: typeof clearSessionCache;
|
|
202
208
|
|
|
203
209
|
/**
|
|
204
210
|
* Test function
|
|
@@ -255,20 +261,21 @@ export type CoreApi = {
|
|
|
255
261
|
/**
|
|
256
262
|
* File system & device control API (Protocol V2 only)
|
|
257
263
|
*/
|
|
258
|
-
|
|
264
|
+
protocolInfoRequest: typeof protocolInfoRequest;
|
|
259
265
|
ping: typeof ping;
|
|
260
266
|
deviceReboot: typeof deviceReboot;
|
|
261
|
-
|
|
262
|
-
|
|
267
|
+
deviceInfoGet: typeof deviceInfoGet;
|
|
268
|
+
deviceStatusGet: typeof deviceStatusGet;
|
|
269
|
+
deviceSessionGet: typeof deviceSessionGet;
|
|
263
270
|
deviceFirmwareUpdate: typeof deviceFirmwareUpdate;
|
|
264
271
|
deviceGetFirmwareUpdateStatus: typeof deviceGetFirmwareUpdateStatus;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
+
deviceFactoryInfoSet: typeof deviceFactoryInfoSet;
|
|
273
|
+
deviceFactoryInfoGet: typeof deviceFactoryInfoGet;
|
|
274
|
+
deviceSettingsGet: typeof deviceSettingsGet;
|
|
275
|
+
deviceSettingsSet: typeof deviceSettingsSet;
|
|
276
|
+
deviceSettingsPageShow: typeof deviceSettingsPageShow;
|
|
277
|
+
deviceUploadWallpaper: typeof deviceUploadWallpaper;
|
|
278
|
+
filesystemPermissionFix: typeof filesystemPermissionFix;
|
|
272
279
|
fileRead: typeof fileRead;
|
|
273
280
|
fileWrite: typeof fileWrite;
|
|
274
281
|
fileDelete: typeof fileDelete;
|
|
@@ -278,6 +285,7 @@ export type CoreApi = {
|
|
|
278
285
|
pathInfo: typeof pathInfo;
|
|
279
286
|
filesystemFileRead: typeof filesystemFileRead;
|
|
280
287
|
filesystemFileWrite: typeof filesystemFileWrite;
|
|
288
|
+
uploadPortfolio: typeof uploadPortfolio;
|
|
281
289
|
filesystemFileDelete: typeof filesystemFileDelete;
|
|
282
290
|
filesystemDirList: typeof filesystemDirList;
|
|
283
291
|
filesystemDirMake: typeof filesystemDirMake;
|