@onekeyfe/hd-core 1.1.27-alpha.31 → 1.1.27-alpha.33
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__/evmSignTransaction.test.ts +1 -1
- package/__tests__/evmSignTypedData.test.ts +1 -1
- package/__tests__/protocol-v2.test.ts +319 -9
- package/dist/api/DirList.d.ts.map +1 -1
- package/dist/api/DirMake.d.ts.map +1 -1
- package/dist/api/DirRemove.d.ts.map +1 -1
- package/dist/api/FileDelete.d.ts.map +1 -1
- package/dist/api/FileRead.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/PathInfo.d.ts.map +1 -1
- package/dist/api/helpers/filesystemValidation.d.ts +7 -0
- package/dist/api/helpers/filesystemValidation.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +2 -2
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +185 -83
- package/dist/protocols/protocol-v2/features.d.ts +1 -1
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/types/api/getPassphraseState.d.ts +4 -1
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +1 -1
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +2 -0
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/package.json +4 -4
- package/src/api/DirList.ts +6 -2
- package/src/api/DirMake.ts +2 -1
- package/src/api/DirRemove.ts +2 -1
- package/src/api/FileDelete.ts +2 -1
- package/src/api/FileRead.ts +12 -5
- package/src/api/FileWrite.ts +19 -7
- package/src/api/GetPassphraseState.ts +5 -1
- package/src/api/PathInfo.ts +2 -1
- package/src/api/evm/EVMGetAddress.ts +1 -1
- package/src/api/evm/EVMGetPublicKey.ts +1 -1
- package/src/api/evm/EVMSignMessage.ts +1 -1
- package/src/api/evm/EVMSignTransaction.ts +1 -1
- package/src/api/evm/EVMSignTypedData.ts +4 -4
- package/src/api/evm/EVMVerifyMessage.ts +1 -1
- package/src/api/helpers/filesystemValidation.ts +51 -0
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +2 -1
- package/src/api/protocol-v2/helpers.ts +34 -11
- package/src/core/index.ts +12 -4
- package/src/data-manager/DataManager.ts +7 -7
- package/src/data-manager/MessagesConfig.ts +6 -6
- package/src/data-manager/TransportManager.ts +4 -4
- package/src/device/Device.ts +2 -2
- package/src/protocols/protocol-v2/features.ts +37 -40
- package/src/protocols/protocol-v2/firmware.ts +1 -1
- package/src/types/api/getPassphraseState.ts +5 -1
- package/src/types/api/index.ts +1 -1
- package/src/utils/deviceFeaturesUtils.ts +26 -10
- /package/src/data/messages/{messages-pro2.json → messages-protocol-v2.json} +0 -0
|
@@ -16,7 +16,11 @@ export default class GetPassphraseState extends BaseMethod {
|
|
|
16
16
|
return Promise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
|
|
17
17
|
|
|
18
18
|
const { passphraseState, newSession, unlockedAttachPin } =
|
|
19
|
-
await getPassphraseStateWithRefreshDeviceInfo(this.device
|
|
19
|
+
await getPassphraseStateWithRefreshDeviceInfo(this.device, {
|
|
20
|
+
expectPassphraseState: this.payload.passphraseState,
|
|
21
|
+
onlyMainPin: this.payload.useEmptyPassphrase,
|
|
22
|
+
allowCreateAttachPin: this.payload.allowCreateAttachPin,
|
|
23
|
+
});
|
|
20
24
|
|
|
21
25
|
const { features } = this.device;
|
|
22
26
|
const isPro2 = getDeviceType(features) === EDeviceType.Pro2;
|
package/src/api/PathInfo.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import { validateNonEmptyString } from './helpers/filesystemValidation';
|
|
2
3
|
|
|
3
4
|
export type PathInfoParams = {
|
|
4
5
|
path: string;
|
|
@@ -8,7 +9,7 @@ export default class PathInfo extends BaseMethod<PathInfoParams> {
|
|
|
8
9
|
init() {
|
|
9
10
|
this.skipForceUpdateCheck = true;
|
|
10
11
|
this.useDevicePassphraseState = false;
|
|
11
|
-
this.params = { path: this.payload.path };
|
|
12
|
+
this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async run() {
|
|
@@ -44,7 +44,7 @@ export default class EvmGetAddress extends BaseMethod<EthereumGetAddressOneKey[]
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
async getEvmAddress(param: EthereumGetAddressOneKey) {
|
|
47
|
-
if (TransportManager.getProtocolV1MessageSchema() === '
|
|
47
|
+
if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
|
|
48
48
|
return getAddressLegacyV1({
|
|
49
49
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
50
50
|
param,
|
|
@@ -57,7 +57,7 @@ export default class EVMGetPublicKey extends BaseMethod<EthereumGetPublicKeyOneK
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
getEvmPublicKey(param: EthereumGetPublicKey) {
|
|
60
|
-
if (TransportManager.getProtocolV1MessageSchema() === '
|
|
60
|
+
if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
|
|
61
61
|
return getPublicKeyLegacyV1({
|
|
62
62
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
63
63
|
param,
|
|
@@ -34,7 +34,7 @@ export default class EVMSignMessage extends BaseMethod<EthereumSignMessageOneKey
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
async run() {
|
|
37
|
-
if (TransportManager.getProtocolV1MessageSchema() === '
|
|
37
|
+
if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
|
|
38
38
|
return signMessageLegacyV1({
|
|
39
39
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
40
40
|
params: this.params,
|
|
@@ -120,7 +120,7 @@ export default class EVMSignTransaction extends BaseMethod {
|
|
|
120
120
|
|
|
121
121
|
if (formattedTx == null) throw ERRORS.TypedError('Runtime', 'formattedTx is not set');
|
|
122
122
|
|
|
123
|
-
if (TransportManager.getProtocolV1MessageSchema() === '
|
|
123
|
+
if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
|
|
124
124
|
return signTransactionLegacyV1({
|
|
125
125
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
126
126
|
addressN,
|
|
@@ -261,7 +261,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
|
|
|
261
261
|
let supportTrezor = false;
|
|
262
262
|
let response: MessageResponse<MessageKey>;
|
|
263
263
|
switch (TransportManager.getProtocolV1MessageSchema()) {
|
|
264
|
-
case '
|
|
264
|
+
case 'v1LegacySchema':
|
|
265
265
|
supportTrezor = true;
|
|
266
266
|
response = await signTypedDataLegacyV1({
|
|
267
267
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
@@ -272,7 +272,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
|
|
|
272
272
|
});
|
|
273
273
|
break;
|
|
274
274
|
|
|
275
|
-
case '
|
|
275
|
+
case 'v1CurrentSchema':
|
|
276
276
|
default:
|
|
277
277
|
supportTrezor = false;
|
|
278
278
|
response = await signTypedData({
|
|
@@ -309,7 +309,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
|
|
|
309
309
|
if (!domainHash) throw ERRORS.TypedError('Runtime', 'domainHash is required');
|
|
310
310
|
|
|
311
311
|
switch (TransportManager.getProtocolV1MessageSchema()) {
|
|
312
|
-
case '
|
|
312
|
+
case 'v1LegacySchema':
|
|
313
313
|
return signTypedHashLegacyV1({
|
|
314
314
|
typedCall,
|
|
315
315
|
addressN,
|
|
@@ -319,7 +319,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
|
|
|
319
319
|
device: this.device,
|
|
320
320
|
});
|
|
321
321
|
|
|
322
|
-
case '
|
|
322
|
+
case 'v1CurrentSchema':
|
|
323
323
|
default:
|
|
324
324
|
return signTypedHash({
|
|
325
325
|
typedCall,
|
|
@@ -31,7 +31,7 @@ export default class EVMSignMessage extends BaseMethod<EthereumVerifyMessageOneK
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
async run() {
|
|
34
|
-
if (TransportManager.getProtocolV1MessageSchema() === '
|
|
34
|
+
if (TransportManager.getProtocolV1MessageSchema() === 'v1LegacySchema') {
|
|
35
35
|
return verifyMessageLegacyV1({
|
|
36
36
|
typedCall: this.device.commands.typedCall.bind(this.device.commands),
|
|
37
37
|
params: this.params,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
export const invalidParameter = (message: string) =>
|
|
4
|
+
ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter, message);
|
|
5
|
+
|
|
6
|
+
export function validateNonEmptyString(value: unknown, name: string): string {
|
|
7
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
8
|
+
throw invalidParameter(`Parameter [${name}] is required and must be a non-empty string.`);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function validateNonNegativeInteger(
|
|
14
|
+
value: unknown,
|
|
15
|
+
name: string,
|
|
16
|
+
defaultValue?: number
|
|
17
|
+
): number {
|
|
18
|
+
if (value === undefined || value === null) {
|
|
19
|
+
if (defaultValue !== undefined) return defaultValue;
|
|
20
|
+
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const numeric = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
|
|
24
|
+
if (typeof numeric !== 'number' || !Number.isSafeInteger(numeric) || numeric < 0) {
|
|
25
|
+
throw invalidParameter(`Parameter [${name}] must be a non-negative integer.`);
|
|
26
|
+
}
|
|
27
|
+
return numeric;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function validateOptionalNonNegativeInteger(
|
|
31
|
+
value: unknown,
|
|
32
|
+
name: string
|
|
33
|
+
): number | undefined {
|
|
34
|
+
if (value === undefined || value === null) return undefined;
|
|
35
|
+
return validateNonNegativeInteger(value, name);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function validateOptionalPercentage(value: unknown, name: string): number | undefined {
|
|
39
|
+
const numeric = validateOptionalNonNegativeInteger(value, name);
|
|
40
|
+
if (numeric === undefined) return undefined;
|
|
41
|
+
if (numeric > 100) {
|
|
42
|
+
throw invalidParameter(`Parameter [${name}] must be between 0 and 100.`);
|
|
43
|
+
}
|
|
44
|
+
return numeric;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function validateRequiredData(value: unknown, name: string): void {
|
|
48
|
+
if (value === undefined || value === null) {
|
|
49
|
+
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -20,11 +20,12 @@ export default class DeviceFirmwareUpdate extends BaseMethod<DeviceFirmwareUpdat
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
async run() {
|
|
23
|
+
const targets = normalizeFirmwareTargets(this.params);
|
|
23
24
|
const res = await this.device.commands.typedCall(
|
|
24
25
|
'DeviceFirmwareUpdate',
|
|
25
26
|
PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES,
|
|
26
27
|
{
|
|
27
|
-
targets
|
|
28
|
+
targets,
|
|
28
29
|
},
|
|
29
30
|
PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS
|
|
30
31
|
);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { DeviceRebootType } from '@onekeyfe/hd-transport';
|
|
2
2
|
|
|
3
|
+
import { invalidParameter, validateNonEmptyString } from '../helpers/filesystemValidation';
|
|
4
|
+
|
|
3
5
|
import type {
|
|
4
6
|
DeviceFirmwareTarget,
|
|
5
7
|
DeviceFirmwareTargetType,
|
|
@@ -69,8 +71,10 @@ export const PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS: TransportCallOptions = {
|
|
|
69
71
|
intermediateTypes: ['DeviceFirmwareInstallProgress'],
|
|
70
72
|
};
|
|
71
73
|
|
|
72
|
-
export const PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES: (
|
|
73
|
-
|
|
74
|
+
export const PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES: (
|
|
75
|
+
| 'Success'
|
|
76
|
+
| 'DeviceFirmwareUpdateStatus'
|
|
77
|
+
)[] = ['Success', 'DeviceFirmwareUpdateStatus'];
|
|
74
78
|
|
|
75
79
|
export function normalizeRebootType(value: RebootTypeInput | undefined): DeviceRebootType {
|
|
76
80
|
if (typeof value === 'number') return value;
|
|
@@ -83,15 +87,24 @@ export function normalizeRebootType(value: RebootTypeInput | undefined): DeviceR
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
function normalizeTargetId(
|
|
86
|
-
value: DeviceFirmwareTargetType | string | number | undefined
|
|
90
|
+
value: DeviceFirmwareTargetType | string | number | undefined,
|
|
91
|
+
name: string
|
|
87
92
|
): DeviceFirmwareTargetType {
|
|
88
|
-
if (
|
|
93
|
+
if (value === undefined || value === null) {
|
|
94
|
+
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
95
|
+
}
|
|
96
|
+
if (typeof value === 'number') {
|
|
97
|
+
if (Number.isSafeInteger(value) && value > 0) return value;
|
|
98
|
+
throw invalidParameter(`Parameter [${name}] must be a valid firmware target id.`);
|
|
99
|
+
}
|
|
89
100
|
const numeric = Number(value);
|
|
90
|
-
if (Number.
|
|
91
|
-
|
|
101
|
+
if (Number.isSafeInteger(numeric) && numeric > 0) return numeric;
|
|
102
|
+
throw invalidParameter(`Parameter [${name}] must be a valid firmware target id.`);
|
|
92
103
|
}
|
|
93
104
|
|
|
94
|
-
export function normalizeFirmwareTargets(
|
|
105
|
+
export function normalizeFirmwareTargets(
|
|
106
|
+
params: DeviceFirmwareUpdateParams
|
|
107
|
+
): DeviceFirmwareTarget[] {
|
|
95
108
|
const targets =
|
|
96
109
|
params.targets ??
|
|
97
110
|
(params.path
|
|
@@ -103,10 +116,20 @@ export function normalizeFirmwareTargets(params: DeviceFirmwareUpdateParams): De
|
|
|
103
116
|
]
|
|
104
117
|
: []);
|
|
105
118
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
119
|
+
if (!Array.isArray(targets) || targets.length === 0) {
|
|
120
|
+
throw invalidParameter('Parameter [targets] must contain at least one firmware target.');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return targets.map((target, index) => {
|
|
124
|
+
if (!target || typeof target !== 'object') {
|
|
125
|
+
throw invalidParameter(`Parameter [targets.${index}] must be an object.`);
|
|
126
|
+
}
|
|
127
|
+
const targetId = target.target_id ?? target.targetId;
|
|
128
|
+
return {
|
|
129
|
+
target_id: normalizeTargetId(targetId, `targets.${index}.target_id`),
|
|
130
|
+
path: validateNonEmptyString(target.path, `targets.${index}.path`),
|
|
131
|
+
};
|
|
132
|
+
});
|
|
110
133
|
}
|
|
111
134
|
|
|
112
135
|
export function buildTargets(params: DeviceGetDeviceInfoParams): DeviceInfoTargets | undefined {
|
package/src/core/index.ts
CHANGED
|
@@ -479,7 +479,7 @@ const onCallDevice = async (
|
|
|
479
479
|
// Check to see if it is safe to use Passphrase
|
|
480
480
|
checkPassphraseEnableState(method, device.features);
|
|
481
481
|
|
|
482
|
-
if (
|
|
482
|
+
if (shouldCheckPassphraseState(method, device)) {
|
|
483
483
|
// check version
|
|
484
484
|
const support = supportNewPassphrase(device.features);
|
|
485
485
|
if (!support.support) {
|
|
@@ -994,8 +994,6 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
994
994
|
const checkPassphraseEnableState = (method: BaseMethod, features?: Features) => {
|
|
995
995
|
if (!method.useDevicePassphraseState) return;
|
|
996
996
|
|
|
997
|
-
const isPro2 = getDeviceType(features) === EDeviceType.Pro2;
|
|
998
|
-
|
|
999
997
|
if (features?.passphrase_protection === true) {
|
|
1000
998
|
const hasNoPassphraseState =
|
|
1001
999
|
method.payload.passphraseState == null || method.payload.passphraseState === '';
|
|
@@ -1008,12 +1006,22 @@ const checkPassphraseEnableState = (method: BaseMethod, features?: Features) =>
|
|
|
1008
1006
|
}
|
|
1009
1007
|
}
|
|
1010
1008
|
|
|
1011
|
-
if (features?.passphrase_protection === false && method.payload.passphraseState
|
|
1009
|
+
if (features?.passphrase_protection === false && method.payload.passphraseState) {
|
|
1012
1010
|
DevicePool.clearDeviceCache(method.payload.connectId);
|
|
1013
1011
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase);
|
|
1014
1012
|
}
|
|
1015
1013
|
};
|
|
1016
1014
|
|
|
1015
|
+
const shouldCheckPassphraseState = (method: BaseMethod, device: Device) => {
|
|
1016
|
+
if (!method.useDevicePassphraseState) return false;
|
|
1017
|
+
|
|
1018
|
+
const isPro2 = getDeviceType(device.features) === EDeviceType.Pro2;
|
|
1019
|
+
const pro2ExplicitWalletSelection =
|
|
1020
|
+
isPro2 && (!!method.payload?.passphraseState || !!method.payload?.useEmptyPassphrase);
|
|
1021
|
+
|
|
1022
|
+
return device.hasUsePassphrase() || pro2ExplicitWalletSelection;
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1017
1025
|
const cleanup = () => {
|
|
1018
1026
|
_uiPromises = [];
|
|
1019
1027
|
Log.debug('Cleanup...');
|
|
@@ -4,7 +4,7 @@ import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
|
4
4
|
|
|
5
5
|
import MessagesJSON from '../data/messages/messages.json';
|
|
6
6
|
import MessagesLegacyV1JSON from '../data/messages/messages_legacy_v1.json';
|
|
7
|
-
import
|
|
7
|
+
import MessagesProtocolV2JSON from '../data/messages/messages-protocol-v2.json';
|
|
8
8
|
import {
|
|
9
9
|
LoggerNames,
|
|
10
10
|
getDeviceBLEFirmwareVersion,
|
|
@@ -41,8 +41,8 @@ export const FIRMWARE_FIELDS = [
|
|
|
41
41
|
|
|
42
42
|
export type IFirmwareField = (typeof FIRMWARE_FIELDS)[number];
|
|
43
43
|
|
|
44
|
-
export type ProtocolV1MessageSchema = '
|
|
45
|
-
export type ProtobufMessageSchema = ProtocolV1MessageSchema | '
|
|
44
|
+
export type ProtocolV1MessageSchema = 'v1CurrentSchema' | 'v1LegacySchema';
|
|
45
|
+
export type ProtobufMessageSchema = ProtocolV1MessageSchema | 'v2Schema';
|
|
46
46
|
|
|
47
47
|
const FIRMWARE_FIELD_TYPE_MAP: Readonly<Record<IFirmwareField, EFirmwareType>> = {
|
|
48
48
|
firmware: EFirmwareType.Universal,
|
|
@@ -98,9 +98,9 @@ export default class DataManager {
|
|
|
98
98
|
static settings: ConnectSettings;
|
|
99
99
|
|
|
100
100
|
static messages: { [schema in ProtobufMessageSchema]: JSON } = {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
v1CurrentSchema: MessagesJSON as unknown as JSON,
|
|
102
|
+
v1LegacySchema: MessagesLegacyV1JSON as unknown as JSON,
|
|
103
|
+
v2Schema: MessagesProtocolV2JSON as unknown as JSON,
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
static lastCheckTimestamp = 0;
|
|
@@ -477,7 +477,7 @@ export default class DataManager {
|
|
|
477
477
|
}
|
|
478
478
|
}
|
|
479
479
|
|
|
480
|
-
static getProtobufMessages(schema: ProtobufMessageSchema = '
|
|
480
|
+
static getProtobufMessages(schema: ProtobufMessageSchema = 'v1CurrentSchema'): JSON {
|
|
481
481
|
return this.messages[schema];
|
|
482
482
|
}
|
|
483
483
|
|
|
@@ -12,17 +12,17 @@ export const PROTOBUF_MESSAGE_CONFIG: DeviceVersionConfig = {
|
|
|
12
12
|
model_mini: [
|
|
13
13
|
// Classic1s starts from 3.5.0, so use the current Protocol V1 schema by default.
|
|
14
14
|
// Only use the legacy Protocol V1 schema for specific old versions (< 3.3.0).
|
|
15
|
-
{ minVersion: '3.3.0', protocolV1MessageSchema: '
|
|
16
|
-
{ minVersion: '0.0.1', protocolV1MessageSchema: '
|
|
15
|
+
{ minVersion: '3.3.0', protocolV1MessageSchema: 'v1CurrentSchema' },
|
|
16
|
+
{ minVersion: '0.0.1', protocolV1MessageSchema: 'v1LegacySchema' },
|
|
17
17
|
// Fallback to current Protocol V1 schema for unknown versions (0.0.0).
|
|
18
|
-
{ minVersion: '0.0.0', protocolV1MessageSchema: '
|
|
18
|
+
{ minVersion: '0.0.0', protocolV1MessageSchema: 'v1CurrentSchema' },
|
|
19
19
|
],
|
|
20
20
|
model_touch: [
|
|
21
21
|
// Use the current Protocol V1 schema by default for Touch/Pro.
|
|
22
22
|
// Only use the legacy Protocol V1 schema for specific old versions (< 4.5.0).
|
|
23
|
-
{ minVersion: '4.5.0', protocolV1MessageSchema: '
|
|
24
|
-
{ minVersion: '0.0.1', protocolV1MessageSchema: '
|
|
23
|
+
{ minVersion: '4.5.0', protocolV1MessageSchema: 'v1CurrentSchema' },
|
|
24
|
+
{ minVersion: '0.0.1', protocolV1MessageSchema: 'v1LegacySchema' },
|
|
25
25
|
// Fallback to current Protocol V1 schema for unknown versions (0.0.0).
|
|
26
|
-
{ minVersion: '0.0.0', protocolV1MessageSchema: '
|
|
26
|
+
{ minVersion: '0.0.0', protocolV1MessageSchema: 'v1CurrentSchema' },
|
|
27
27
|
],
|
|
28
28
|
};
|
|
@@ -33,7 +33,7 @@ export default class TransportManager {
|
|
|
33
33
|
|
|
34
34
|
static reactNativeInit = false;
|
|
35
35
|
|
|
36
|
-
static protocolV1MessageSchema: ProtocolV1MessageSchema = '
|
|
36
|
+
static protocolV1MessageSchema: ProtocolV1MessageSchema = 'v1CurrentSchema';
|
|
37
37
|
|
|
38
38
|
static plugin: LowlevelTransportSharedPlugin | null = null;
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ export default class TransportManager {
|
|
|
41
41
|
Log.debug('transport manager load');
|
|
42
42
|
this.defaultMessages = DataManager.getProtobufMessages();
|
|
43
43
|
this.currentMessages = this.defaultMessages;
|
|
44
|
-
this.protocolV1MessageSchema = '
|
|
44
|
+
this.protocolV1MessageSchema = 'v1CurrentSchema';
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
static async configure() {
|
|
@@ -76,7 +76,7 @@ export default class TransportManager {
|
|
|
76
76
|
Log.debug('Configuring transports');
|
|
77
77
|
await this.transport.configure(JSON.stringify(this.defaultMessages));
|
|
78
78
|
this.currentMessages = this.defaultMessages;
|
|
79
|
-
this.protocolV1MessageSchema = '
|
|
79
|
+
this.protocolV1MessageSchema = 'v1CurrentSchema';
|
|
80
80
|
await this.configureProtocolV2Messages();
|
|
81
81
|
Log.debug('Configuring transports done');
|
|
82
82
|
} catch (error) {
|
|
@@ -148,7 +148,7 @@ export default class TransportManager {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
private static async configureProtocolV2Messages() {
|
|
151
|
-
const protocolV2Messages = DataManager.getProtobufMessages('
|
|
151
|
+
const protocolV2Messages = DataManager.getProtobufMessages('v2Schema');
|
|
152
152
|
const { configureProtocolV2 } = this.transport;
|
|
153
153
|
if (protocolV2Messages && typeof configureProtocolV2 === 'function') {
|
|
154
154
|
await configureProtocolV2.call(this.transport, JSON.stringify(protocolV2Messages));
|
package/src/device/Device.ts
CHANGED
|
@@ -543,8 +543,8 @@ export class Device extends EventEmitter {
|
|
|
543
543
|
/**
|
|
544
544
|
* Device initialization over Protocol V2.
|
|
545
545
|
*
|
|
546
|
-
* Protocol V2 不走传统 Initialize/GetFeatures
|
|
547
|
-
*
|
|
546
|
+
* Protocol V2 不走传统 Initialize/GetFeatures,当前通过 Ping 验证链路,
|
|
547
|
+
* 再用 DeviceGetDeviceInfo 归一成 legacy-style Features 视图。
|
|
548
548
|
*/
|
|
549
549
|
private async _initializeProtocolV2() {
|
|
550
550
|
Log.debug('Initialize device via Protocol V2 feature adapter');
|
|
@@ -53,24 +53,24 @@ type ProtocolV2DeviceInfo = {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
56
|
+
const PROTOCOL_V2_DEVICE_INFO_REQUEST = {
|
|
57
|
+
targets: {
|
|
58
|
+
hw: true,
|
|
59
|
+
fw: true,
|
|
60
|
+
bt: true,
|
|
61
|
+
se1: true,
|
|
62
|
+
se2: true,
|
|
63
|
+
se3: true,
|
|
64
|
+
se4: true,
|
|
65
|
+
status: true,
|
|
66
|
+
},
|
|
67
|
+
types: {
|
|
68
|
+
version: true,
|
|
69
|
+
build_id: true,
|
|
70
|
+
hash: true,
|
|
71
|
+
specific: true,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
74
|
|
|
75
75
|
function parseVersion(version?: string | null): [number, number, number] {
|
|
76
76
|
if (!version) return [0, 0, 0];
|
|
@@ -228,7 +228,7 @@ export function normalizeProtocolV2Features(
|
|
|
228
228
|
export async function getProtocolV2Features({
|
|
229
229
|
commands,
|
|
230
230
|
descriptor,
|
|
231
|
-
|
|
231
|
+
onDeviceInfoError,
|
|
232
232
|
timeoutMs,
|
|
233
233
|
}: {
|
|
234
234
|
commands: DeviceCommands;
|
|
@@ -243,25 +243,22 @@ export async function getProtocolV2Features({
|
|
|
243
243
|
await commands.typedCall('Ping', 'Success', { message: 'init' });
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
// }
|
|
265
|
-
|
|
266
|
-
return normalizeProtocolV2Features(descriptor);
|
|
246
|
+
try {
|
|
247
|
+
const { message } = callOptions
|
|
248
|
+
? await commands.typedCall(
|
|
249
|
+
'DeviceGetDeviceInfo',
|
|
250
|
+
'DeviceInfo',
|
|
251
|
+
PROTOCOL_V2_DEVICE_INFO_REQUEST,
|
|
252
|
+
callOptions
|
|
253
|
+
)
|
|
254
|
+
: await commands.typedCall(
|
|
255
|
+
'DeviceGetDeviceInfo',
|
|
256
|
+
'DeviceInfo',
|
|
257
|
+
PROTOCOL_V2_DEVICE_INFO_REQUEST
|
|
258
|
+
);
|
|
259
|
+
return normalizeProtocolV2Features(descriptor, message as unknown as ProtocolV2DeviceInfo);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
onDeviceInfoError?.(error);
|
|
262
|
+
return normalizeProtocolV2Features(descriptor);
|
|
263
|
+
}
|
|
267
264
|
}
|
|
@@ -9,7 +9,11 @@ export type GetPassphraseStatePayload =
|
|
|
9
9
|
passphrase_protection?: boolean | null;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
export type GetPassphraseStateParams = CommonParams & {
|
|
13
|
+
allowCreateAttachPin?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
12
16
|
export declare function getPassphraseState(
|
|
13
17
|
connectId?: string,
|
|
14
|
-
params?:
|
|
18
|
+
params?: GetPassphraseStateParams
|
|
15
19
|
): Response<GetPassphraseStatePayload>;
|
package/src/types/api/index.ts
CHANGED
|
@@ -162,7 +162,7 @@ import type { neoSignTransaction } from './neoSignTransaction';
|
|
|
162
162
|
import type { ConnectSettings } from '../settings';
|
|
163
163
|
|
|
164
164
|
export * from './export';
|
|
165
|
-
export type { GetPassphraseStatePayload } from './getPassphraseState';
|
|
165
|
+
export type { GetPassphraseStateParams, GetPassphraseStatePayload } from './getPassphraseState';
|
|
166
166
|
|
|
167
167
|
export type CoreApi = {
|
|
168
168
|
/**
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import semver from 'semver';
|
|
2
2
|
import { isNaN } from 'lodash';
|
|
3
3
|
import { EDeviceType, type EFirmwareType, ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Enum_Capability,
|
|
6
|
+
type GetPassphraseState as GetPassphraseStateMessage,
|
|
7
|
+
} from '@onekeyfe/hd-transport';
|
|
5
8
|
|
|
6
9
|
import { toHardened } from '../api/helpers/pathUtils';
|
|
7
10
|
import { DeviceModelToTypes, DeviceTypeToModels } from '../types';
|
|
@@ -23,8 +26,8 @@ export const getSupportProtocolV1MessageSchema = (
|
|
|
23
26
|
): { messages: JSON; protocolV1MessageSchema: ProtocolV1MessageSchema } => {
|
|
24
27
|
if (!features)
|
|
25
28
|
return {
|
|
26
|
-
messages: DataManager.messages.
|
|
27
|
-
protocolV1MessageSchema: '
|
|
29
|
+
messages: DataManager.messages.v1CurrentSchema,
|
|
30
|
+
protocolV1MessageSchema: 'v1CurrentSchema',
|
|
28
31
|
};
|
|
29
32
|
|
|
30
33
|
const currentDeviceVersion = getDeviceFirmwareVersion(features).join('.');
|
|
@@ -50,8 +53,8 @@ export const getSupportProtocolV1MessageSchema = (
|
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
return {
|
|
53
|
-
messages: DataManager.messages.
|
|
54
|
-
protocolV1MessageSchema: '
|
|
56
|
+
messages: DataManager.messages.v1CurrentSchema,
|
|
57
|
+
protocolV1MessageSchema: 'v1CurrentSchema',
|
|
55
58
|
};
|
|
56
59
|
};
|
|
57
60
|
|
|
@@ -89,6 +92,7 @@ export const getPassphraseStateWithRefreshDeviceInfo = async (
|
|
|
89
92
|
options?: {
|
|
90
93
|
expectPassphraseState?: string;
|
|
91
94
|
onlyMainPin?: boolean;
|
|
95
|
+
allowCreateAttachPin?: boolean;
|
|
92
96
|
}
|
|
93
97
|
) => {
|
|
94
98
|
const { features, commands } = device;
|
|
@@ -119,8 +123,10 @@ export const getPassphraseStateWithRefreshDeviceInfo = async (
|
|
|
119
123
|
await device.getFeatures();
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
if (isPro2 && device.features
|
|
123
|
-
|
|
126
|
+
if (isPro2 && device.features) {
|
|
127
|
+
if (passphraseState) {
|
|
128
|
+
device.features.passphrase_protection = true;
|
|
129
|
+
}
|
|
124
130
|
if (newSession) {
|
|
125
131
|
device.features.session_id = newSession;
|
|
126
132
|
}
|
|
@@ -146,6 +152,7 @@ export const getPassphraseState = async (
|
|
|
146
152
|
options?: {
|
|
147
153
|
expectPassphraseState?: string;
|
|
148
154
|
onlyMainPin?: boolean;
|
|
155
|
+
allowCreateAttachPin?: boolean;
|
|
149
156
|
}
|
|
150
157
|
): Promise<{
|
|
151
158
|
passphraseState: string | undefined;
|
|
@@ -169,9 +176,18 @@ export const getPassphraseState = async (
|
|
|
169
176
|
(deviceType === EDeviceType.Pro && semver.gte(firmwareVersion.join('.'), '4.15.0'));
|
|
170
177
|
|
|
171
178
|
if (supportGetPassphraseState) {
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
179
|
+
const payload: GetPassphraseStateMessage = options?.onlyMainPin
|
|
180
|
+
? { _only_main_pin: true }
|
|
181
|
+
: { passphrase_state: options?.expectPassphraseState };
|
|
182
|
+
if (options?.allowCreateAttachPin) {
|
|
183
|
+
payload.allow_create_attach_pin = true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const { message, type } = await commands.typedCall(
|
|
187
|
+
'GetPassphraseState',
|
|
188
|
+
'PassphraseState',
|
|
189
|
+
payload
|
|
190
|
+
);
|
|
175
191
|
|
|
176
192
|
// @ts-expect-error
|
|
177
193
|
if (type === 'CallMethodError') {
|
|
File without changes
|