@onekeyfe/hd-core 1.1.26-alpha.12 → 1.1.26-alpha.13
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 +99 -0
- package/__tests__/evmLedgerLegacySafety.test.ts +181 -0
- package/dist/api/BaseMethod.d.ts +1 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/index.js +40 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +49 -1
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import { DeviceCommands } from '../src/device/DeviceCommands';
|
|
4
|
+
|
|
5
|
+
jest.mock('../src/data/config', () => ({
|
|
6
|
+
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
7
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
const createCommands = () => {
|
|
11
|
+
const commands = Object.create(DeviceCommands.prototype) as DeviceCommands;
|
|
12
|
+
commands.device = {
|
|
13
|
+
clearCancelableAction: jest.fn(),
|
|
14
|
+
} as any;
|
|
15
|
+
return commands;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe('DeviceCommands failure mapping', () => {
|
|
19
|
+
it.each([
|
|
20
|
+
['ButtonAck', 'Not in Ethereum signing mode'],
|
|
21
|
+
['PinMatrixAck', 'Not in Conflux signing mode'],
|
|
22
|
+
])('keeps %s unexpected message "%s" as firmware runtime error', async (callType, message) => {
|
|
23
|
+
const commands = createCommands();
|
|
24
|
+
|
|
25
|
+
await expect(
|
|
26
|
+
commands._filterCommonTypes(
|
|
27
|
+
{
|
|
28
|
+
type: 'Failure',
|
|
29
|
+
message: {
|
|
30
|
+
code: 'Failure_UnexpectedMessage',
|
|
31
|
+
message,
|
|
32
|
+
},
|
|
33
|
+
} as any,
|
|
34
|
+
callType as any
|
|
35
|
+
)
|
|
36
|
+
).rejects.toMatchObject({
|
|
37
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
38
|
+
message: `Failure_UnexpectedMessage,${message}`,
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('keeps the existing NotInSigningMode mapping', async () => {
|
|
43
|
+
const commands = createCommands();
|
|
44
|
+
|
|
45
|
+
await expect(
|
|
46
|
+
commands._filterCommonTypes(
|
|
47
|
+
{
|
|
48
|
+
type: 'Failure',
|
|
49
|
+
message: {
|
|
50
|
+
code: 'Failure_UnexpectedMessage',
|
|
51
|
+
message: 'Not in Signing mode',
|
|
52
|
+
},
|
|
53
|
+
} as any,
|
|
54
|
+
'ButtonAck'
|
|
55
|
+
)
|
|
56
|
+
).rejects.toMatchObject({
|
|
57
|
+
errorCode: HardwareErrorCode.NotInSigningMode,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('keeps the existing unexpected passphrase mapping', async () => {
|
|
62
|
+
const commands = createCommands();
|
|
63
|
+
|
|
64
|
+
await expect(
|
|
65
|
+
commands._filterCommonTypes(
|
|
66
|
+
{
|
|
67
|
+
type: 'Failure',
|
|
68
|
+
message: {
|
|
69
|
+
code: 'Failure_UnexpectedMessage',
|
|
70
|
+
message: 'Unexpected message',
|
|
71
|
+
},
|
|
72
|
+
} as any,
|
|
73
|
+
'PassphraseAck'
|
|
74
|
+
)
|
|
75
|
+
).rejects.toMatchObject({
|
|
76
|
+
errorCode: HardwareErrorCode.UnexpectPassphrase,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('keeps non signing unexpected messages as runtime errors', async () => {
|
|
81
|
+
const commands = createCommands();
|
|
82
|
+
|
|
83
|
+
await expect(
|
|
84
|
+
commands._filterCommonTypes(
|
|
85
|
+
{
|
|
86
|
+
type: 'Failure',
|
|
87
|
+
message: {
|
|
88
|
+
code: 'Failure_UnexpectedMessage',
|
|
89
|
+
message: 'Not in Reset mode',
|
|
90
|
+
},
|
|
91
|
+
} as any,
|
|
92
|
+
'ButtonAck'
|
|
93
|
+
)
|
|
94
|
+
).rejects.toMatchObject({
|
|
95
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
96
|
+
message: 'Failure_UnexpectedMessage,Not in Reset mode',
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import AllNetworkGetAddressBase from '../src/api/allnetwork/AllNetworkGetAddressBase';
|
|
2
|
+
import EvmGetAddress from '../src/api/evm/EVMGetAddress';
|
|
3
|
+
import EVMGetPublicKey from '../src/api/evm/EVMGetPublicKey';
|
|
4
|
+
import { findMethod } from '../src/api/utils';
|
|
5
|
+
|
|
6
|
+
jest.mock('../src/data/config', () => ({
|
|
7
|
+
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
8
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
jest.mock('../src/api/utils', () => ({
|
|
12
|
+
findMethod: jest.fn(),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
const createDevice = (onekeyDeviceType: string) => {
|
|
16
|
+
const typedCall = jest.fn();
|
|
17
|
+
return {
|
|
18
|
+
typedCall,
|
|
19
|
+
device: {
|
|
20
|
+
features: {
|
|
21
|
+
onekey_device_type: onekeyDeviceType,
|
|
22
|
+
safety_checks: 'Strict',
|
|
23
|
+
},
|
|
24
|
+
commands: {
|
|
25
|
+
typedCall,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class TestAllNetworkMethod extends AllNetworkGetAddressBase {
|
|
32
|
+
async getAllNetworkAddress() {
|
|
33
|
+
return Promise.resolve([]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe('EVM Ledger legacy path safety checks', () => {
|
|
38
|
+
it.each([
|
|
39
|
+
['evmGetAddress', EvmGetAddress],
|
|
40
|
+
['evmGetPublicKey', EVMGetPublicKey],
|
|
41
|
+
])(
|
|
42
|
+
'temporarily relaxes safety checks for Pro %s on ledger legacy path index greater than 1',
|
|
43
|
+
async (methodName, Method) => {
|
|
44
|
+
const { device, typedCall } = createDevice('PRO');
|
|
45
|
+
const method = new Method({
|
|
46
|
+
id: 1,
|
|
47
|
+
payload: {
|
|
48
|
+
method: methodName,
|
|
49
|
+
path: "m/44'/60'/0'/2",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
method.device = device as any;
|
|
53
|
+
|
|
54
|
+
await method.checkSafetyLevelOnTestNet();
|
|
55
|
+
|
|
56
|
+
expect(typedCall).toHaveBeenCalledWith('ApplySettings', 'Success', {
|
|
57
|
+
safety_checks: 'PromptTemporarily',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
it('temporarily relaxes safety checks for Touch get public key on ledger legacy path index greater than 1', async () => {
|
|
63
|
+
const { device, typedCall } = createDevice('TOUCH');
|
|
64
|
+
const method = new EVMGetPublicKey({
|
|
65
|
+
id: 1,
|
|
66
|
+
payload: {
|
|
67
|
+
method: 'evmGetPublicKey',
|
|
68
|
+
path: "m/44'/60'/0'/2",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
method.device = device as any;
|
|
72
|
+
|
|
73
|
+
await method.checkSafetyLevelOnTestNet();
|
|
74
|
+
|
|
75
|
+
expect(typedCall).toHaveBeenCalledWith('ApplySettings', 'Success', {
|
|
76
|
+
safety_checks: 'PromptTemporarily',
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('runs EVM safety checks when allNetwork dispatches to the inner get address method', async () => {
|
|
81
|
+
const { device, typedCall } = createDevice('PRO');
|
|
82
|
+
(findMethod as jest.Mock).mockImplementation(message => new EvmGetAddress(message));
|
|
83
|
+
const runSpy = jest.spyOn(EvmGetAddress.prototype, 'run').mockResolvedValue([
|
|
84
|
+
{
|
|
85
|
+
path: "m/44'/60'/0'/2",
|
|
86
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
const method = new TestAllNetworkMethod({
|
|
90
|
+
id: 1,
|
|
91
|
+
payload: {
|
|
92
|
+
method: 'allNetworkGetAddress',
|
|
93
|
+
connectId: 'connect-id',
|
|
94
|
+
deviceId: 'device-id',
|
|
95
|
+
bundle: [],
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
method.device = {
|
|
99
|
+
...device,
|
|
100
|
+
on: jest.fn(),
|
|
101
|
+
off: jest.fn(),
|
|
102
|
+
} as any;
|
|
103
|
+
|
|
104
|
+
await method.callMethod(
|
|
105
|
+
'evmGetAddress',
|
|
106
|
+
{
|
|
107
|
+
bundle: [
|
|
108
|
+
{
|
|
109
|
+
path: "m/44'/60'/0'/2",
|
|
110
|
+
showOnOneKey: false,
|
|
111
|
+
chainId: 1,
|
|
112
|
+
_originRequestParams: {
|
|
113
|
+
network: 'evm',
|
|
114
|
+
path: "m/44'/60'/0'/2",
|
|
115
|
+
showOnOneKey: false,
|
|
116
|
+
chainName: '1',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
0
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(typedCall).toHaveBeenCalledWith('ApplySettings', 'Success', {
|
|
125
|
+
safety_checks: 'PromptTemporarily',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
runSpy.mockRestore();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it.each(["m/44'/60'/0'/0", "m/44'/60'/0'/1"])(
|
|
132
|
+
'keeps safety checks unchanged for legal ledger legacy path %s',
|
|
133
|
+
async path => {
|
|
134
|
+
const { device, typedCall } = createDevice('PRO');
|
|
135
|
+
const method = new EvmGetAddress({
|
|
136
|
+
id: 1,
|
|
137
|
+
payload: {
|
|
138
|
+
method: 'evmGetAddress',
|
|
139
|
+
path,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
method.device = device as any;
|
|
143
|
+
|
|
144
|
+
await method.checkSafetyLevelOnTestNet();
|
|
145
|
+
|
|
146
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
it('keeps safety checks unchanged for standard 5-segment BIP44 paths', async () => {
|
|
151
|
+
const { device, typedCall } = createDevice('PRO');
|
|
152
|
+
const method = new EvmGetAddress({
|
|
153
|
+
id: 1,
|
|
154
|
+
payload: {
|
|
155
|
+
method: 'evmGetAddress',
|
|
156
|
+
path: "m/44'/60'/0'/0/2",
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
method.device = device as any;
|
|
160
|
+
|
|
161
|
+
await method.checkSafetyLevelOnTestNet();
|
|
162
|
+
|
|
163
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('keeps safety checks unchanged on non Pro/Touch devices', async () => {
|
|
167
|
+
const { device, typedCall } = createDevice('MINI');
|
|
168
|
+
const method = new EvmGetAddress({
|
|
169
|
+
id: 1,
|
|
170
|
+
payload: {
|
|
171
|
+
method: 'evmGetAddress',
|
|
172
|
+
path: "m/44'/60'/0'/2",
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
method.device = device as any;
|
|
176
|
+
|
|
177
|
+
await method.checkSafetyLevelOnTestNet();
|
|
178
|
+
|
|
179
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
180
|
+
});
|
|
181
|
+
});
|
package/dist/api/BaseMethod.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare abstract class BaseMethod<Params = undefined> {
|
|
|
41
41
|
protected checkFeatureVersionLimit(checkCondition: () => boolean, getVersionRange: () => DeviceFirmwareRange, options?: {
|
|
42
42
|
strictCheckDeviceSupport?: boolean;
|
|
43
43
|
}): void;
|
|
44
|
+
private shouldPromptSafetyCheckForEvmLedgerLegacyPath;
|
|
44
45
|
checkSafetyLevelOnTestNet(): Promise<void>;
|
|
45
46
|
dispose(): void;
|
|
46
47
|
postPreviousAddressMessage: (data: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseMethod.d.ts","sourceRoot":"","sources":["../../src/api/BaseMethod.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BaseMethod.d.ts","sourceRoot":"","sources":["../../src/api/BaseMethod.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,eAAe,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA6B3C,8BAAsB,UAAU,CAAC,MAAM,GAAG,SAAS;IACjD,UAAU,EAAE,MAAM,CAAC;IAGnB,MAAM,EAAE,MAAM,CAAC;IAGf,MAAM,EAAE,MAAM,CAAC;IAOf,SAAS,CAAC,EAAE,MAAM,CAAC;IAKnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,IAAI,EAAE,MAAM,CAAC;IAEb,UAAU,EAAG,MAAM,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,cAAc,CAAC,EAAE,cAAc,CAAC;IAKhC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7B,SAAS,CAAC,EAAE,eAAe,CAAC;IAK5B,SAAS,EAAE,OAAO,CAAC;IAMnB,eAAe,EAAE,MAAM,EAAE,CAAC;IAK1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAK5B,qBAAqB,UAAQ;IAK7B,aAAa,UAAS;IAKtB,wBAAwB,UAAQ;IAMhC,oBAAoB,UAAS;IAO7B,wBAAwB,UAAS;IAGjC,WAAW,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAE5C,OAAO,CAAC,EAAE,WAAW,CAAC;gBAEV,OAAO,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE;IAYlD,QAAQ,CAAC,IAAI,IAAI,IAAI;IAErB,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAE5B,eAAe,IAAI,mBAAmB;IAItC,UAAU,CAAC,OAAO,EAAE,WAAW;IAQ/B,SAAS,CAAC,MAAM,EAAE,MAAM;IA2BxB,oBAAoB;IAmBpB,yBAAyB;IAczB,SAAS,CAAC,wBAAwB,CAChC,cAAc,EAAE,MAAM,OAAO,EAC7B,eAAe,EAAE,MAAM,mBAAmB,EAC1C,OAAO,CAAC,EAAE;QACR,wBAAwB,CAAC,EAAE,OAAO,CAAC;KACpC;IA8BH,OAAO,CAAC,6CAA6C;IAqB/C,yBAAyB;IAoB/B,OAAO;IAGP,0BAA0B,SAAU;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,UAOrE;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IA6GzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAuBV"}
|
package/dist/index.js
CHANGED
|
@@ -28121,6 +28121,28 @@ const getBootloaderReleaseInfo = ({ features, willUpdateFirmwareVersion, firmwar
|
|
|
28121
28121
|
};
|
|
28122
28122
|
|
|
28123
28123
|
const Log$9 = getLogger(exports.LoggerNames.Method);
|
|
28124
|
+
const isEvmLedgerLegacyPathWithHighIndex = (path) => {
|
|
28125
|
+
let addressN;
|
|
28126
|
+
if (typeof path === 'string') {
|
|
28127
|
+
try {
|
|
28128
|
+
addressN = getHDPath(path);
|
|
28129
|
+
}
|
|
28130
|
+
catch (_a) {
|
|
28131
|
+
return false;
|
|
28132
|
+
}
|
|
28133
|
+
}
|
|
28134
|
+
else if (Array.isArray(path)) {
|
|
28135
|
+
addressN = path.map((item) => Number(item));
|
|
28136
|
+
}
|
|
28137
|
+
return (Array.isArray(addressN) &&
|
|
28138
|
+
addressN.length === 4 &&
|
|
28139
|
+
addressN[0] === toHardened(44) &&
|
|
28140
|
+
addressN[1] === toHardened(60) &&
|
|
28141
|
+
addressN[2] === toHardened(0) &&
|
|
28142
|
+
addressN[3] > 1 &&
|
|
28143
|
+
addressN[3] < toHardened(0));
|
|
28144
|
+
};
|
|
28145
|
+
const EVM_LEDGER_LEGACY_METHODS = ['evmGetAddress', 'evmGetPublicKey'];
|
|
28124
28146
|
class BaseMethod {
|
|
28125
28147
|
constructor(message) {
|
|
28126
28148
|
this.shouldEnsureConnected = true;
|
|
@@ -28214,6 +28236,20 @@ class BaseMethod {
|
|
|
28214
28236
|
});
|
|
28215
28237
|
}
|
|
28216
28238
|
}
|
|
28239
|
+
shouldPromptSafetyCheckForEvmLedgerLegacyPath() {
|
|
28240
|
+
var _a, _b;
|
|
28241
|
+
if (!EVM_LEDGER_LEGACY_METHODS.includes(this.name)) {
|
|
28242
|
+
return false;
|
|
28243
|
+
}
|
|
28244
|
+
const deviceType = getDeviceType(this.device.features);
|
|
28245
|
+
if (!DeviceModelToTypes.model_touch.includes(deviceType)) {
|
|
28246
|
+
return false;
|
|
28247
|
+
}
|
|
28248
|
+
const paths = Array.isArray((_a = this.payload) === null || _a === void 0 ? void 0 : _a.bundle)
|
|
28249
|
+
? this.payload.bundle.map((item) => item === null || item === void 0 ? void 0 : item.path)
|
|
28250
|
+
: [(_b = this.payload) === null || _b === void 0 ? void 0 : _b.path];
|
|
28251
|
+
return paths.some(isEvmLedgerLegacyPathWithHighIndex);
|
|
28252
|
+
}
|
|
28217
28253
|
checkSafetyLevelOnTestNet() {
|
|
28218
28254
|
var _a, _b, _c;
|
|
28219
28255
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -28222,6 +28258,9 @@ class BaseMethod {
|
|
|
28222
28258
|
[3, 4, 5, 420, 11155111].includes(Number((_b = (_a = this.payload) === null || _a === void 0 ? void 0 : _a.transaction) === null || _b === void 0 ? void 0 : _b.chainId))) {
|
|
28223
28259
|
checkFlag = true;
|
|
28224
28260
|
}
|
|
28261
|
+
if (this.shouldPromptSafetyCheckForEvmLedgerLegacyPath()) {
|
|
28262
|
+
checkFlag = true;
|
|
28263
|
+
}
|
|
28225
28264
|
if (checkFlag && ((_c = this.device.features) === null || _c === void 0 ? void 0 : _c.safety_checks) === 'Strict') {
|
|
28226
28265
|
Log$9.debug('will change safety_checks level');
|
|
28227
28266
|
yield this.device.commands.typedCall('ApplySettings', 'Success', {
|
|
@@ -31444,6 +31483,7 @@ class AllNetworkGetAddressBase extends BaseMethod {
|
|
|
31444
31483
|
this.device.on(DEVICE.PIN, onSignalAbort);
|
|
31445
31484
|
this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
|
|
31446
31485
|
preCheckDeviceSupport(this.device, method);
|
|
31486
|
+
yield method.checkSafetyLevelOnTestNet();
|
|
31447
31487
|
const response = yield method.run();
|
|
31448
31488
|
if (!Array.isArray(response) || response.length === 0) {
|
|
31449
31489
|
throw new Error('No response');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.1.26-alpha.
|
|
3
|
+
"version": "1.1.26-alpha.13",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.1.26-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.1.26-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.1.26-alpha.13",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.1.26-alpha.13",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "9da4d0d2ddaa0f674da6bbdec7f345657d59551a"
|
|
48
48
|
}
|
package/src/api/BaseMethod.ts
CHANGED
|
@@ -8,15 +8,18 @@ import { supportInputPinOnSoftware, supportModifyHomescreen } from '../utils/dev
|
|
|
8
8
|
import { createDeviceMessage } from '../events/device';
|
|
9
9
|
import { UI_REQUEST } from '../constants/ui-request';
|
|
10
10
|
import { DEVICE, FIRMWARE, createFirmwareMessage, createUiMessage } from '../events';
|
|
11
|
+
import { getHDPath, toHardened } from './helpers/pathUtils';
|
|
11
12
|
import { getBleFirmwareReleaseInfo, getFirmwareReleaseInfo } from './firmware/releaseHelper';
|
|
12
13
|
import {
|
|
13
14
|
LoggerNames,
|
|
14
15
|
getDeviceFirmwareVersion,
|
|
16
|
+
getDeviceType,
|
|
15
17
|
getFirmwareType,
|
|
16
18
|
getLogger,
|
|
17
19
|
getMethodVersionRange,
|
|
18
20
|
} from '../utils';
|
|
19
21
|
import { generateInstanceId } from '../utils/tracing';
|
|
22
|
+
import { DeviceModelToTypes } from '../types';
|
|
20
23
|
|
|
21
24
|
import type { Device } from '../device/Device';
|
|
22
25
|
import type DeviceConnector from '../device/DeviceConnector';
|
|
@@ -27,6 +30,31 @@ import type { CoreContext } from '../core';
|
|
|
27
30
|
|
|
28
31
|
const Log = getLogger(LoggerNames.Method);
|
|
29
32
|
|
|
33
|
+
const isEvmLedgerLegacyPathWithHighIndex = (path: unknown) => {
|
|
34
|
+
let addressN: number[] | undefined;
|
|
35
|
+
if (typeof path === 'string') {
|
|
36
|
+
try {
|
|
37
|
+
addressN = getHDPath(path);
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
} else if (Array.isArray(path)) {
|
|
42
|
+
addressN = path.map((item: unknown) => Number(item));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
Array.isArray(addressN) &&
|
|
47
|
+
addressN.length === 4 &&
|
|
48
|
+
addressN[0] === toHardened(44) &&
|
|
49
|
+
addressN[1] === toHardened(60) &&
|
|
50
|
+
addressN[2] === toHardened(0) &&
|
|
51
|
+
addressN[3] > 1 &&
|
|
52
|
+
addressN[3] < toHardened(0)
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const EVM_LEDGER_LEGACY_METHODS = ['evmGetAddress', 'evmGetPublicKey'];
|
|
57
|
+
|
|
30
58
|
export abstract class BaseMethod<Params = undefined> {
|
|
31
59
|
responseID: number;
|
|
32
60
|
|
|
@@ -240,8 +268,25 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
240
268
|
}
|
|
241
269
|
}
|
|
242
270
|
|
|
271
|
+
private shouldPromptSafetyCheckForEvmLedgerLegacyPath() {
|
|
272
|
+
if (!EVM_LEDGER_LEGACY_METHODS.includes(this.name)) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const deviceType = getDeviceType(this.device.features);
|
|
277
|
+
if (!DeviceModelToTypes.model_touch.includes(deviceType)) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const paths = Array.isArray(this.payload?.bundle)
|
|
282
|
+
? this.payload.bundle.map((item: { path?: unknown }) => item?.path)
|
|
283
|
+
: [this.payload?.path];
|
|
284
|
+
|
|
285
|
+
return paths.some(isEvmLedgerLegacyPathWithHighIndex);
|
|
286
|
+
}
|
|
287
|
+
|
|
243
288
|
/**
|
|
244
|
-
* Automatic check safety_check level for
|
|
289
|
+
* Automatic check safety_check level for selected calls that require temporary relaxed checks.
|
|
245
290
|
* @returns {void}
|
|
246
291
|
*/
|
|
247
292
|
async checkSafetyLevelOnTestNet() {
|
|
@@ -253,6 +298,9 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
253
298
|
) {
|
|
254
299
|
checkFlag = true;
|
|
255
300
|
}
|
|
301
|
+
if (this.shouldPromptSafetyCheckForEvmLedgerLegacyPath()) {
|
|
302
|
+
checkFlag = true;
|
|
303
|
+
}
|
|
256
304
|
if (checkFlag && this.device.features?.safety_checks === 'Strict') {
|
|
257
305
|
Log.debug('will change safety_checks level');
|
|
258
306
|
await this.device.commands.typedCall('ApplySettings', 'Success', {
|
|
@@ -371,6 +371,7 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
|
|
|
371
371
|
this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
|
|
372
372
|
|
|
373
373
|
preCheckDeviceSupport(this.device, method);
|
|
374
|
+
await method.checkSafetyLevelOnTestNet();
|
|
374
375
|
|
|
375
376
|
const response = await method.run();
|
|
376
377
|
|