@onekeyfe/hd-core 1.2.0-alpha.7 → 1.2.0-alpha.9
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-wallet-session-store.test.ts +131 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
- package/__tests__/protocol-v2.test.ts +742 -536
- package/dist/api/ClearSessionCache.d.ts +9 -0
- package/dist/api/ClearSessionCache.d.ts.map +1 -0
- package/dist/api/FirmwareUpdateV4.d.ts +7 -6
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +1 -1
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts +9 -0
- package/dist/api/protocol-v2/DeviceSessionGet.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/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/device/Device.d.ts +2 -2
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceWalletSessionStore.d.ts +15 -0
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
- package/dist/index.d.ts +32 -19
- package/dist/index.js +651 -288
- package/dist/inject.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/walletSession.d.ts +13 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdate.d.ts +4 -1
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +6 -1
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +6 -2
- 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/settings.d.ts +6 -14
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/ClearSessionCache.ts +28 -0
- package/src/api/FileRead.ts +2 -2
- package/src/api/FirmwareUpdateV4.ts +276 -239
- package/src/api/index.ts +3 -0
- package/src/api/protocol-v2/DeviceSessionGet.ts +26 -0
- package/src/api/protocol-v2/DeviceStatusGet.ts +14 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +4 -1
- package/src/api/protocol-v2/helpers.ts +17 -14
- package/src/data/messages/messages-protocol-v2.json +134 -3
- package/src/data/messages/messages.json +8 -0
- package/src/device/Device.ts +64 -56
- package/src/device/DeviceWalletSessionStore.ts +78 -0
- package/src/inject.ts +5 -2
- package/src/protocols/protocol-v2/index.ts +1 -0
- package/src/protocols/protocol-v2/walletSession.ts +83 -0
- package/src/types/api/firmwareUpdate.ts +8 -2
- package/src/types/api/index.ts +10 -3
- package/src/types/api/protocolV2.ts +16 -2
- package/src/types/api/sessionCache.ts +14 -0
- package/src/types/settings.ts +14 -16
- package/src/utils/deviceFeaturesUtils.ts +22 -32
package/src/api/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as getDeviceInfo } from './GetDeviceInfo';
|
|
|
7
7
|
export { default as getOnekeyFeatures } from './GetOnekeyFeatures';
|
|
8
8
|
export { default as getPassphraseState } from './GetPassphraseState';
|
|
9
9
|
export { default as getLogs } from './GetLogs';
|
|
10
|
+
export { default as clearSessionCache } from './ClearSessionCache';
|
|
10
11
|
export { default as checkFirmwareRelease } from './CheckFirmwareRelease';
|
|
11
12
|
export { default as checkBLEFirmwareRelease } from './CheckBLEFirmwareRelease';
|
|
12
13
|
export { default as checkBridgeStatus } from './CheckBridgeStatus';
|
|
@@ -47,6 +48,8 @@ export { default as protocolInfoRequest } from './protocol-v2/ProtocolInfoReques
|
|
|
47
48
|
export { default as ping } from './protocol-v2/Ping';
|
|
48
49
|
export { default as deviceReboot } from './protocol-v2/DeviceReboot';
|
|
49
50
|
export { default as deviceInfoGet } from './protocol-v2/DeviceInfoGet';
|
|
51
|
+
export { default as deviceStatusGet } from './protocol-v2/DeviceStatusGet';
|
|
52
|
+
export { default as deviceSessionGet } from './protocol-v2/DeviceSessionGet';
|
|
50
53
|
export { default as deviceFirmwareUpdate } from './protocol-v2/DeviceFirmwareUpdate';
|
|
51
54
|
export { default as deviceGetFirmwareUpdateStatus } from './protocol-v2/DeviceGetFirmwareUpdateStatus';
|
|
52
55
|
export { default as deviceFactoryInfoSet } from './protocol-v2/DeviceFactoryInfoSet';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseMethod } from '../BaseMethod';
|
|
2
|
+
|
|
3
|
+
export type DeviceSessionGetParams = {
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default class DeviceSessionGet extends BaseMethod<DeviceSessionGetParams> {
|
|
8
|
+
init() {
|
|
9
|
+
this.requireProtocolV2 = true;
|
|
10
|
+
this.useDevicePassphraseState = false;
|
|
11
|
+
this.skipForceUpdateCheck = true;
|
|
12
|
+
this.params = {
|
|
13
|
+
sessionId: this.payload.sessionId,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async run() {
|
|
18
|
+
const payload = this.params.sessionId ? { session_id: this.params.sessionId } : {};
|
|
19
|
+
const { message } = await this.device.commands.typedCall(
|
|
20
|
+
'DeviceSessionGet',
|
|
21
|
+
'DeviceSession',
|
|
22
|
+
payload
|
|
23
|
+
);
|
|
24
|
+
return message;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseMethod } from '../BaseMethod';
|
|
2
|
+
|
|
3
|
+
export default class DeviceStatusGet extends BaseMethod {
|
|
4
|
+
init() {
|
|
5
|
+
this.requireProtocolV2 = true;
|
|
6
|
+
this.useDevicePassphraseState = false;
|
|
7
|
+
this.skipForceUpdateCheck = true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async run() {
|
|
11
|
+
const { message } = await this.device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
|
|
12
|
+
return message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -10,7 +10,10 @@ export default class FilesystemFormat extends BaseMethod {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
async run() {
|
|
13
|
-
const res = await this.device.commands.typedCall('FilesystemFormat', 'Success', {
|
|
13
|
+
const res = await this.device.commands.typedCall('FilesystemFormat', 'Success', {
|
|
14
|
+
data: true,
|
|
15
|
+
user: true,
|
|
16
|
+
});
|
|
14
17
|
return Promise.resolve(res.message);
|
|
15
18
|
}
|
|
16
19
|
}
|
|
@@ -5,8 +5,8 @@ import { ProtocolV2FirmwareTargetType } from '../../protocols/protocol-v2/firmwa
|
|
|
5
5
|
|
|
6
6
|
import type {
|
|
7
7
|
DeviceFirmwareTarget,
|
|
8
|
-
DeviceFirmwareUpdateRecordFields,
|
|
9
8
|
DeviceFirmwareTargetType,
|
|
9
|
+
DeviceFirmwareUpdateRecordFields,
|
|
10
10
|
TransportCallOptions,
|
|
11
11
|
} from '@onekeyfe/hd-transport';
|
|
12
12
|
|
|
@@ -138,16 +138,21 @@ export function normalizeRebootType(value: RebootTypeInput | undefined): DeviceR
|
|
|
138
138
|
return DeviceRebootType.Normal;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
// 与 firmware-pro2 的 proto_target_to_firmware_target 安装白名单保持一致。
|
|
142
|
+
const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set<number>([
|
|
143
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
|
|
144
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
|
|
145
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1,
|
|
146
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2,
|
|
147
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR,
|
|
148
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01,
|
|
149
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02,
|
|
150
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03,
|
|
151
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
|
|
152
|
+
]);
|
|
146
153
|
const FIRMWARE_TARGET_ID_BY_NAME = new Map<string, DeviceFirmwareTargetType>(
|
|
147
154
|
Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) =>
|
|
148
|
-
|
|
149
|
-
? [[key, value as DeviceFirmwareTargetType]]
|
|
150
|
-
: []
|
|
155
|
+
INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value as DeviceFirmwareTargetType]] : []
|
|
151
156
|
)
|
|
152
157
|
);
|
|
153
158
|
|
|
@@ -160,14 +165,12 @@ function normalizeTargetId(
|
|
|
160
165
|
}
|
|
161
166
|
const named = typeof value === 'string' ? FIRMWARE_TARGET_ID_BY_NAME.get(value) : undefined;
|
|
162
167
|
const numeric = named ?? (typeof value === 'number' ? value : Number(value));
|
|
163
|
-
|
|
164
|
-
// 不再放行任意非负整数。
|
|
165
|
-
if (Number.isSafeInteger(numeric) && VALID_FIRMWARE_TARGET_IDS.has(numeric)) {
|
|
168
|
+
if (Number.isSafeInteger(numeric) && INSTALLABLE_FIRMWARE_TARGET_IDS.has(numeric)) {
|
|
166
169
|
return numeric as DeviceFirmwareTargetType;
|
|
167
170
|
}
|
|
168
171
|
throw invalidParameter(
|
|
169
|
-
`Parameter [${name}] must be
|
|
170
|
-
...
|
|
172
|
+
`Parameter [${name}] must be an installable firmware target id (one of ${[
|
|
173
|
+
...INSTALLABLE_FIRMWARE_TARGET_IDS,
|
|
171
174
|
].join(', ')}).`
|
|
172
175
|
);
|
|
173
176
|
}
|
|
@@ -107,8 +107,6 @@
|
|
|
107
107
|
"MessageType_FirmwareHash": 89,
|
|
108
108
|
"MessageType_UnlockPath": 93,
|
|
109
109
|
"MessageType_UnlockedPathRequest": 94,
|
|
110
|
-
"MessageType_UnLockDevice": 10030,
|
|
111
|
-
"MessageType_UnLockDeviceResponse": 10031,
|
|
112
110
|
"MessageType_SetU2FCounter": 63,
|
|
113
111
|
"MessageType_GetNextU2FCounter": 80,
|
|
114
112
|
"MessageType_NextU2FCounter": 81,
|
|
@@ -197,6 +195,7 @@
|
|
|
197
195
|
"MessageType_EthereumGnosisSafeTxAck": 20118,
|
|
198
196
|
"MessageType_EthereumGnosisSafeTxRequest": 20119,
|
|
199
197
|
"MessageType_EthereumSignTxEIP7702OneKey": 20120,
|
|
198
|
+
"MessageType_EthereumSignTypedDataQR": 20121,
|
|
200
199
|
"MessageType_NEMGetAddress": 67,
|
|
201
200
|
"MessageType_NEMAddress": 68,
|
|
202
201
|
"MessageType_NEMSignTx": 69,
|
|
@@ -454,6 +453,8 @@
|
|
|
454
453
|
"MessageType_UiviewConfirmTxRequest": 30202,
|
|
455
454
|
"MessageType_UiviewConfirmSignMessageRequest": 30203,
|
|
456
455
|
"MessageType_UiviewResponse": 30204,
|
|
456
|
+
"MessageType_UnLockDevice": 10030,
|
|
457
|
+
"MessageType_UnLockDeviceResponse": 10031,
|
|
457
458
|
"MessageType_DeviceFactoryInfoSet": 60000,
|
|
458
459
|
"MessageType_DeviceFactoryInfoGet": 60001,
|
|
459
460
|
"MessageType_DeviceFactoryInfo": 60002,
|
|
@@ -478,6 +479,12 @@
|
|
|
478
479
|
"MessageType_Wallpaper": 60432,
|
|
479
480
|
"MessageType_DeviceInfoGet": 60600,
|
|
480
481
|
"MessageType_DeviceInfo": 60601,
|
|
482
|
+
"MessageType_DeviceStatusGet": 60602,
|
|
483
|
+
"MessageType_DeviceStatus": 60603,
|
|
484
|
+
"MessageType_DevGetOnboardingStatus": 60604,
|
|
485
|
+
"MessageType_DevOnboardingStatus": 60605,
|
|
486
|
+
"MessageType_DeviceSessionGet": 60606,
|
|
487
|
+
"MessageType_DeviceSession": 60607,
|
|
481
488
|
"MessageType_FilesystemPermissionFix": 60800,
|
|
482
489
|
"MessageType_FilesystemPathInfo": 60801,
|
|
483
490
|
"MessageType_FilesystemPathInfoQuery": 60802,
|
|
@@ -492,7 +499,8 @@
|
|
|
492
499
|
"MessageType_FilesystemFormat": 60811,
|
|
493
500
|
"MessageType_DeviceFirmwareUpdateRequest": 61000,
|
|
494
501
|
"MessageType_DeviceFirmwareUpdateStatusGet": 61001,
|
|
495
|
-
"MessageType_DeviceFirmwareUpdateStatus": 61002
|
|
502
|
+
"MessageType_DeviceFirmwareUpdateStatus": 61002,
|
|
503
|
+
"MessageType_PortfolioUpdate": 61200
|
|
496
504
|
},
|
|
497
505
|
"reserved": [
|
|
498
506
|
[90, 92],
|
|
@@ -5395,6 +5403,37 @@
|
|
|
5395
5403
|
}
|
|
5396
5404
|
}
|
|
5397
5405
|
},
|
|
5406
|
+
"EthereumSignTypedDataQR": {
|
|
5407
|
+
"fields": {
|
|
5408
|
+
"address_n": {
|
|
5409
|
+
"rule": "repeated",
|
|
5410
|
+
"type": "uint32",
|
|
5411
|
+
"id": 1,
|
|
5412
|
+
"options": {
|
|
5413
|
+
"packed": false
|
|
5414
|
+
}
|
|
5415
|
+
},
|
|
5416
|
+
"json_data": {
|
|
5417
|
+
"type": "bytes",
|
|
5418
|
+
"id": 2
|
|
5419
|
+
},
|
|
5420
|
+
"chain_id": {
|
|
5421
|
+
"type": "uint64",
|
|
5422
|
+
"id": 3
|
|
5423
|
+
},
|
|
5424
|
+
"metamask_v4_compat": {
|
|
5425
|
+
"type": "bool",
|
|
5426
|
+
"id": 4,
|
|
5427
|
+
"options": {
|
|
5428
|
+
"default": true
|
|
5429
|
+
}
|
|
5430
|
+
},
|
|
5431
|
+
"request_id": {
|
|
5432
|
+
"type": "bytes",
|
|
5433
|
+
"id": 5
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
},
|
|
5398
5437
|
"EthereumGetPublicKeyOneKey": {
|
|
5399
5438
|
"fields": {
|
|
5400
5439
|
"address_n": {
|
|
@@ -11120,6 +11159,26 @@
|
|
|
11120
11159
|
}
|
|
11121
11160
|
}
|
|
11122
11161
|
},
|
|
11162
|
+
"ViewRawData": {
|
|
11163
|
+
"fields": {
|
|
11164
|
+
"initial_data": {
|
|
11165
|
+
"rule": "required",
|
|
11166
|
+
"type": "string",
|
|
11167
|
+
"id": 1
|
|
11168
|
+
},
|
|
11169
|
+
"placeholder": {
|
|
11170
|
+
"rule": "required",
|
|
11171
|
+
"type": "uint32",
|
|
11172
|
+
"id": 2
|
|
11173
|
+
}
|
|
11174
|
+
}
|
|
11175
|
+
},
|
|
11176
|
+
"ViewSignLayout": {
|
|
11177
|
+
"values": {
|
|
11178
|
+
"LayoutDefault": 0,
|
|
11179
|
+
"LayoutSafeTxCreate": 1
|
|
11180
|
+
}
|
|
11181
|
+
},
|
|
11123
11182
|
"ViewSignPage": {
|
|
11124
11183
|
"fields": {
|
|
11125
11184
|
"title": {
|
|
@@ -11139,6 +11198,24 @@
|
|
|
11139
11198
|
"tip": {
|
|
11140
11199
|
"type": "ViewTip",
|
|
11141
11200
|
"id": 4
|
|
11201
|
+
},
|
|
11202
|
+
"raw_data": {
|
|
11203
|
+
"type": "ViewRawData",
|
|
11204
|
+
"id": 5
|
|
11205
|
+
},
|
|
11206
|
+
"slide_to_confirm": {
|
|
11207
|
+
"type": "bool",
|
|
11208
|
+
"id": 6,
|
|
11209
|
+
"options": {
|
|
11210
|
+
"default": true
|
|
11211
|
+
}
|
|
11212
|
+
},
|
|
11213
|
+
"layout": {
|
|
11214
|
+
"type": "ViewSignLayout",
|
|
11215
|
+
"id": 7,
|
|
11216
|
+
"options": {
|
|
11217
|
+
"default": "LayoutDefault"
|
|
11218
|
+
}
|
|
11142
11219
|
}
|
|
11143
11220
|
}
|
|
11144
11221
|
},
|
|
@@ -11892,6 +11969,46 @@
|
|
|
11892
11969
|
}
|
|
11893
11970
|
}
|
|
11894
11971
|
},
|
|
11972
|
+
"DeviceStatusGet": {
|
|
11973
|
+
"fields": {}
|
|
11974
|
+
},
|
|
11975
|
+
"DevOnboardingStage": {
|
|
11976
|
+
"values": {
|
|
11977
|
+
"DEV_ONBOARDING_STAGE_UNKNOWN": 0,
|
|
11978
|
+
"DEV_ONBOARDING_STAGE_SAFETY_CHECK": 1,
|
|
11979
|
+
"DEV_ONBOARDING_STAGE_PERSONALIZATION": 2,
|
|
11980
|
+
"DEV_ONBOARDING_STAGE_SELECT_SETUP_METHOD": 3,
|
|
11981
|
+
"DEV_ONBOARDING_STAGE_NEW_DEVICE": 4,
|
|
11982
|
+
"DEV_ONBOARDING_STAGE_SELECT_RESTORE_METHOD": 5,
|
|
11983
|
+
"DEV_ONBOARDING_STAGE_RESTORE_MNEMONIC": 6,
|
|
11984
|
+
"DEV_ONBOARDING_STAGE_RESTORE_SEEDCARD": 7,
|
|
11985
|
+
"DEV_ONBOARDING_STAGE_WALLET_READY": 8,
|
|
11986
|
+
"DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP_PROMPT": 9,
|
|
11987
|
+
"DEV_ONBOARDING_STAGE_SELECT_SEEDCARD_BACKUP_METHOD": 10,
|
|
11988
|
+
"DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP": 11,
|
|
11989
|
+
"DEV_ONBOARDING_STAGE_DONE": 12
|
|
11990
|
+
}
|
|
11991
|
+
},
|
|
11992
|
+
"DevGetOnboardingStatus": {
|
|
11993
|
+
"fields": {}
|
|
11994
|
+
},
|
|
11995
|
+
"DevOnboardingStatus": {
|
|
11996
|
+
"fields": {
|
|
11997
|
+
"stage": {
|
|
11998
|
+
"rule": "required",
|
|
11999
|
+
"type": "DevOnboardingStage",
|
|
12000
|
+
"id": 1
|
|
12001
|
+
},
|
|
12002
|
+
"status_code": {
|
|
12003
|
+
"type": "uint32",
|
|
12004
|
+
"id": 2
|
|
12005
|
+
},
|
|
12006
|
+
"detail_code": {
|
|
12007
|
+
"type": "uint32",
|
|
12008
|
+
"id": 3
|
|
12009
|
+
}
|
|
12010
|
+
}
|
|
12011
|
+
},
|
|
11895
12012
|
"FilesystemPermissionFix": {
|
|
11896
12013
|
"fields": {}
|
|
11897
12014
|
},
|
|
@@ -12105,6 +12222,20 @@
|
|
|
12105
12222
|
}
|
|
12106
12223
|
},
|
|
12107
12224
|
"FilesystemFormat": {
|
|
12225
|
+
"fields": {
|
|
12226
|
+
"data": {
|
|
12227
|
+
"rule": "required",
|
|
12228
|
+
"type": "bool",
|
|
12229
|
+
"id": 1
|
|
12230
|
+
},
|
|
12231
|
+
"user": {
|
|
12232
|
+
"rule": "required",
|
|
12233
|
+
"type": "bool",
|
|
12234
|
+
"id": 2
|
|
12235
|
+
}
|
|
12236
|
+
}
|
|
12237
|
+
},
|
|
12238
|
+
"PortfolioUpdate": {
|
|
12108
12239
|
"fields": {}
|
|
12109
12240
|
},
|
|
12110
12241
|
"google": {
|
package/src/device/Device.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
HardwareError,
|
|
10
10
|
HardwareErrorCode,
|
|
11
11
|
createDeferred,
|
|
12
|
+
createDeviceNotSupportMethodError,
|
|
12
13
|
} from '@onekeyfe/hd-shared';
|
|
13
14
|
|
|
14
15
|
import {
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
import { generateInstanceId } from '../utils/tracing';
|
|
32
33
|
// eslint-disable-next-line import/no-cycle
|
|
33
34
|
import { DeviceCommands } from './DeviceCommands';
|
|
35
|
+
import { deviceWalletSessionStore } from './DeviceWalletSessionStore';
|
|
34
36
|
import {
|
|
35
37
|
type DeviceFirmwareRange,
|
|
36
38
|
DeviceModelToTypes,
|
|
@@ -53,6 +55,7 @@ import {
|
|
|
53
55
|
PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
|
|
54
56
|
requestProtocolV2DeviceInfo,
|
|
55
57
|
} from '../protocols/protocol-v2/features';
|
|
58
|
+
import { refreshProtocolV2DeviceStatus } from '../protocols/protocol-v2/walletSession';
|
|
56
59
|
import { buildProtocolV1FeaturesPayload, buildProtocolV2FeaturesPayload } from '../deviceProfile';
|
|
57
60
|
|
|
58
61
|
import type { PROTO } from '../constants';
|
|
@@ -65,6 +68,7 @@ import type { PassphrasePromptResponse } from './DeviceCommands';
|
|
|
65
68
|
import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
|
|
66
69
|
import type {
|
|
67
70
|
OneKeyDeviceInfo as DeviceDescriptor,
|
|
71
|
+
DeviceStatus,
|
|
68
72
|
ProtocolV2DeviceInfo,
|
|
69
73
|
Success,
|
|
70
74
|
} from '@onekeyfe/hd-transport';
|
|
@@ -119,8 +123,6 @@ export interface Device {
|
|
|
119
123
|
emit<K extends keyof DeviceEvents>(type: K, ...args: DeviceEvents[K]): boolean;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
const deviceSessionCache: Record<string, string> = {};
|
|
123
|
-
|
|
124
126
|
/**
|
|
125
127
|
* Pre-populate the device session cache with a known session ID.
|
|
126
128
|
*
|
|
@@ -138,8 +140,7 @@ export function preloadSessionCache(
|
|
|
138
140
|
passphraseState: string,
|
|
139
141
|
sessionId: string
|
|
140
142
|
): void {
|
|
141
|
-
|
|
142
|
-
deviceSessionCache[key] = sessionId;
|
|
143
|
+
deviceWalletSessionStore.set(deviceId, passphraseState, sessionId);
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
export class Device extends EventEmitter {
|
|
@@ -265,7 +266,7 @@ export class Device extends EventEmitter {
|
|
|
265
266
|
const connectId = this.getConnectId();
|
|
266
267
|
const deviceId = this.getCurrentDeviceId() || null;
|
|
267
268
|
|
|
268
|
-
const features = this
|
|
269
|
+
const { features } = this;
|
|
269
270
|
|
|
270
271
|
return {
|
|
271
272
|
/** Android uses Mac address, iOS uses uuid, USB uses uuid */
|
|
@@ -628,13 +629,6 @@ export class Device extends EventEmitter {
|
|
|
628
629
|
};
|
|
629
630
|
}
|
|
630
631
|
|
|
631
|
-
private generateStateKey(deviceId: string, passphraseState?: string) {
|
|
632
|
-
if (passphraseState) {
|
|
633
|
-
return `${deviceId}@${passphraseState}`;
|
|
634
|
-
}
|
|
635
|
-
return deviceId;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
632
|
private getSessionCacheDeviceKey(_deviceId?: string) {
|
|
639
633
|
const deviceId = _deviceId || this.getCurrentDeviceId();
|
|
640
634
|
if (deviceId) return deviceId;
|
|
@@ -645,7 +639,6 @@ export class Device extends EventEmitter {
|
|
|
645
639
|
}
|
|
646
640
|
|
|
647
641
|
getInternalState(_deviceId?: string) {
|
|
648
|
-
Log.debug('getInternalState session cache: ', deviceSessionCache);
|
|
649
642
|
Log.debug(
|
|
650
643
|
'getInternalState session param: ',
|
|
651
644
|
`device_id: ${_deviceId}`,
|
|
@@ -663,8 +656,7 @@ export class Device extends EventEmitter {
|
|
|
663
656
|
// downstream call carries it and hits the primary lookup below.
|
|
664
657
|
if (!this.passphraseState) return undefined;
|
|
665
658
|
|
|
666
|
-
|
|
667
|
-
return deviceSessionCache[usePassKey];
|
|
659
|
+
return deviceWalletSessionStore.get(deviceId, this.passphraseState);
|
|
668
660
|
}
|
|
669
661
|
|
|
670
662
|
// attach to pin to fix internal state
|
|
@@ -680,36 +672,26 @@ export class Device extends EventEmitter {
|
|
|
680
672
|
`device_id: ${deviceId}`,
|
|
681
673
|
`enablePassphrase: ${enablePassphrase}`,
|
|
682
674
|
`passphraseState: ${passphraseState}`,
|
|
683
|
-
`
|
|
684
|
-
`
|
|
675
|
+
`hasSessionId: ${Boolean(sessionId)}`,
|
|
676
|
+
`hasFeaturesSessionId: ${Boolean(featuresSessionId)}`
|
|
685
677
|
);
|
|
686
678
|
|
|
687
679
|
const cacheDeviceKey = this.getSessionCacheDeviceKey(deviceId);
|
|
688
680
|
if (!cacheDeviceKey) return;
|
|
689
681
|
|
|
690
682
|
if (enablePassphrase) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
} else if (featuresSessionId) {
|
|
695
|
-
deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] =
|
|
696
|
-
featuresSessionId;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// delete the old sessionId
|
|
701
|
-
const oldKey = `${cacheDeviceKey}`;
|
|
702
|
-
if (deviceSessionCache[oldKey]) {
|
|
703
|
-
delete deviceSessionCache[oldKey];
|
|
683
|
+
const walletSessionId =
|
|
684
|
+
sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
|
|
685
|
+
deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
|
|
704
686
|
}
|
|
705
687
|
|
|
706
|
-
|
|
688
|
+
deviceWalletSessionStore.deletePending(cacheDeviceKey);
|
|
707
689
|
}
|
|
708
690
|
|
|
709
691
|
private setInternalState(state: string, initSession?: boolean) {
|
|
710
692
|
Log.debug(
|
|
711
693
|
'setInternalState session param: ',
|
|
712
|
-
`
|
|
694
|
+
`hasState: ${Boolean(state)}`,
|
|
713
695
|
`initSession: ${initSession}`,
|
|
714
696
|
`deviceId: ${this.features?.deviceId}`,
|
|
715
697
|
`passphraseState: ${this.passphraseState}`
|
|
@@ -720,12 +702,11 @@ export class Device extends EventEmitter {
|
|
|
720
702
|
const deviceId = this.getSessionCacheDeviceKey();
|
|
721
703
|
if (!deviceId) return;
|
|
722
704
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
if (
|
|
726
|
-
|
|
705
|
+
if (this.passphraseState) {
|
|
706
|
+
deviceWalletSessionStore.set(deviceId, this.passphraseState, state);
|
|
707
|
+
} else if (initSession) {
|
|
708
|
+
deviceWalletSessionStore.setPending(deviceId, state);
|
|
727
709
|
}
|
|
728
|
-
Log.debug('setInternalState done session cache: ', deviceSessionCache);
|
|
729
710
|
}
|
|
730
711
|
|
|
731
712
|
clearInternalState(_deviceId?: string) {
|
|
@@ -733,12 +714,10 @@ export class Device extends EventEmitter {
|
|
|
733
714
|
|
|
734
715
|
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
735
716
|
if (!deviceId) return;
|
|
736
|
-
|
|
737
|
-
delete deviceSessionCache[key];
|
|
717
|
+
deviceWalletSessionStore.deletePending(deviceId);
|
|
738
718
|
|
|
739
719
|
if (this.passphraseState) {
|
|
740
|
-
|
|
741
|
-
delete deviceSessionCache[usePassKey];
|
|
720
|
+
deviceWalletSessionStore.delete(deviceId, this.passphraseState);
|
|
742
721
|
}
|
|
743
722
|
}
|
|
744
723
|
|
|
@@ -867,6 +846,7 @@ export class Device extends EventEmitter {
|
|
|
867
846
|
}
|
|
868
847
|
|
|
869
848
|
_updateFeatures(protoFeatures: PROTO.Features | Features, initSession?: boolean) {
|
|
849
|
+
const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
|
|
870
850
|
let feat =
|
|
871
851
|
'protocol' in protoFeatures
|
|
872
852
|
? protoFeatures
|
|
@@ -876,28 +856,50 @@ export class Device extends EventEmitter {
|
|
|
876
856
|
if (this.features?.sessionId && !feat.sessionId) {
|
|
877
857
|
feat.sessionId = this.features.sessionId;
|
|
878
858
|
}
|
|
879
|
-
if (this.getCurrentDeviceId() && feat.sessionId) {
|
|
880
|
-
this.setInternalState(feat.sessionId, initSession);
|
|
881
|
-
}
|
|
882
859
|
feat.unlocked = feat.unlocked ?? true;
|
|
883
860
|
|
|
884
861
|
feat = fixFeaturesFirmwareVersion(feat);
|
|
885
862
|
|
|
886
863
|
this.features = feat;
|
|
864
|
+
const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
|
|
865
|
+
if (previousCacheDeviceKey && nextCacheDeviceKey) {
|
|
866
|
+
deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
|
|
867
|
+
}
|
|
868
|
+
if (feat.deviceId && feat.sessionId) {
|
|
869
|
+
this.setInternalState(feat.sessionId, initSession);
|
|
870
|
+
}
|
|
887
871
|
this.featuresNeedsReload = false;
|
|
888
872
|
this.emit(DEVICE.FEATURES, this, feat);
|
|
889
873
|
}
|
|
890
874
|
|
|
891
875
|
updateProtocolV2Features(deviceInfo?: ProtocolV2DeviceInfo) {
|
|
876
|
+
const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
|
|
892
877
|
const features = fixFeaturesFirmwareVersion(
|
|
893
878
|
buildProtocolV2FeaturesPayload(deviceInfo, this.features)
|
|
894
879
|
);
|
|
895
880
|
this.features = features;
|
|
881
|
+
const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
|
|
882
|
+
if (previousCacheDeviceKey && nextCacheDeviceKey) {
|
|
883
|
+
deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
|
|
884
|
+
}
|
|
896
885
|
this.featuresNeedsReload = false;
|
|
897
886
|
this.emit(DEVICE.FEATURES, this, features);
|
|
898
887
|
return features;
|
|
899
888
|
}
|
|
900
889
|
|
|
890
|
+
updateProtocolV2Status(status: DeviceStatus) {
|
|
891
|
+
const previousDeviceInfo = this.features?.raw?.protocolV2DeviceInfo;
|
|
892
|
+
const previousStatus = previousDeviceInfo?.status;
|
|
893
|
+
return this.updateProtocolV2Features({
|
|
894
|
+
...(previousDeviceInfo ?? {}),
|
|
895
|
+
protocol_version: previousDeviceInfo?.protocol_version ?? this.features?.protocolVersion ?? 2,
|
|
896
|
+
status: {
|
|
897
|
+
...previousStatus,
|
|
898
|
+
...status,
|
|
899
|
+
},
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
|
|
901
903
|
/**
|
|
902
904
|
* 暂时只在 acquire 后更新 Session ID
|
|
903
905
|
* 后续看是否有需要依据 listen 返回结果更新
|
|
@@ -1178,8 +1180,7 @@ export class Device extends EventEmitter {
|
|
|
1178
1180
|
}
|
|
1179
1181
|
|
|
1180
1182
|
supportUnlockVersionRange(): DeviceFirmwareRange {
|
|
1181
|
-
// 仅适用于 Protocol V1 的 Pro 系列;Pro2
|
|
1182
|
-
// 且 Protocol V2 固件从首个版本即支持 UnLockDevice(见 unlockDevice 的 isProtocolV2 短路)。
|
|
1183
|
+
// 仅适用于 Protocol V1 的 Pro 系列;Pro2 走独立的 Protocol V2 解锁流程。
|
|
1183
1184
|
return {
|
|
1184
1185
|
pro: {
|
|
1185
1186
|
min: '4.15.0',
|
|
@@ -1188,6 +1189,23 @@ export class Device extends EventEmitter {
|
|
|
1188
1189
|
}
|
|
1189
1190
|
|
|
1190
1191
|
async unlockDevice() {
|
|
1192
|
+
if (this.isProtocolV2()) {
|
|
1193
|
+
try {
|
|
1194
|
+
await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
const errorText =
|
|
1197
|
+
error instanceof Error
|
|
1198
|
+
? `${error.name} ${error.message}`
|
|
1199
|
+
: String((error as { message?: unknown } | null)?.message ?? error ?? '');
|
|
1200
|
+
if (errorText.includes('Failure_UnexpectedMessage')) {
|
|
1201
|
+
throw createDeviceNotSupportMethodError('deviceUnlock', this.getCurrentFirmwareType());
|
|
1202
|
+
}
|
|
1203
|
+
throw error;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
return refreshProtocolV2DeviceStatus(this);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1191
1209
|
const firmwareVersion = this.getCurrentFirmwareVersionString() ?? '0.0.0';
|
|
1192
1210
|
const versionRange = this.getCurrentMethodVersionRange(
|
|
1193
1211
|
type => this.supportUnlockVersionRange()[type]
|
|
@@ -1197,9 +1215,7 @@ export class Device extends EventEmitter {
|
|
|
1197
1215
|
this.features,
|
|
1198
1216
|
Enum_Capability.Capability_AttachToPin
|
|
1199
1217
|
);
|
|
1200
|
-
// Pro2 (Protocol V2) 版本线独立于 Pro 系列,固件从首个版本即支持 UnLockDevice
|
|
1201
1218
|
const supportUnlock =
|
|
1202
|
-
this.isProtocolV2() ||
|
|
1203
1219
|
supportAttachPinCapability ||
|
|
1204
1220
|
(versionRange &&
|
|
1205
1221
|
semver.valid(firmwareVersion) &&
|
|
@@ -1221,14 +1237,6 @@ export class Device extends EventEmitter {
|
|
|
1221
1237
|
return Promise.resolve(features);
|
|
1222
1238
|
}
|
|
1223
1239
|
|
|
1224
|
-
// legacy 解锁探测仅适用于 Protocol V1 老固件;V2 固件必然支持 UnLockDevice
|
|
1225
|
-
if (this.isProtocolV2()) {
|
|
1226
|
-
throw ERRORS.TypedError(
|
|
1227
|
-
HardwareErrorCode.RuntimeError,
|
|
1228
|
-
'unlock device error: device firmware does not support UnLockDevice'
|
|
1229
|
-
);
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
1240
|
const { type } = await this.commands.typedCall('GetAddress', 'Address', {
|
|
1233
1241
|
address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
|
|
1234
1242
|
coin_name: 'Testnet',
|