@onekeyfe/hd-core 1.1.11-alpha.1 → 1.1.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__/evmSignTransaction.test.ts +418 -0
- package/dist/api/evm/EVMSignTransaction.d.ts +2 -2
- package/dist/api/evm/latest/signTransaction.d.ts +2 -2
- package/dist/api/evm/latest/signTransaction.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +17 -8
- package/dist/types/api/evmSignTransaction.d.ts +4 -2
- package/dist/types/api/evmSignTransaction.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/api/evm/EVMSignTransaction.ts +1 -1
- package/src/api/evm/latest/signTransaction.ts +42 -16
- package/src/types/api/evmSignTransaction.ts +4 -2
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import EVMSignTransaction from '../src/api/evm/EVMSignTransaction';
|
|
2
|
+
import { EVMTransactionEIP7702 } from '../src/types';
|
|
3
|
+
|
|
4
|
+
// Mock the config module to avoid package.json resolution issues
|
|
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
|
+
// Mock the device and transport manager
|
|
11
|
+
jest.mock('../src/data-manager/TransportManager', () => ({
|
|
12
|
+
getMessageVersion: jest.fn(() => 'v2'),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('../src/device/Device', () => ({
|
|
16
|
+
Device: jest.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe('EVMSignTransaction EIP-7702', () => {
|
|
20
|
+
let mockDevice: any;
|
|
21
|
+
let mockTypedCall: jest.Mock;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
mockTypedCall = jest.fn();
|
|
25
|
+
mockDevice = {
|
|
26
|
+
commands: {
|
|
27
|
+
typedCall: {
|
|
28
|
+
bind: jest.fn(() => mockTypedCall),
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('EIP-7702 Transaction Detection', () => {
|
|
35
|
+
it('should detect EIP-7702 transaction with authorization list', () => {
|
|
36
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
37
|
+
to: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
38
|
+
value: '0x0',
|
|
39
|
+
gasLimit: '0x5208',
|
|
40
|
+
nonce: '0x0',
|
|
41
|
+
chainId: 1,
|
|
42
|
+
maxFeePerGas: '0xbebc200',
|
|
43
|
+
maxPriorityFeePerGas: '0x9502f900',
|
|
44
|
+
authorizationList: [
|
|
45
|
+
{
|
|
46
|
+
chainId: 1,
|
|
47
|
+
address: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
48
|
+
nonce: '0x1',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const method = new EVMSignTransaction({
|
|
54
|
+
id: 1,
|
|
55
|
+
payload: {
|
|
56
|
+
method: 'evmSignTransaction',
|
|
57
|
+
path: "m/44'/60'/0'/0/0",
|
|
58
|
+
transaction,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
method.device = mockDevice;
|
|
62
|
+
method.init();
|
|
63
|
+
|
|
64
|
+
expect(method.isEIP7702).toBe(true);
|
|
65
|
+
expect(method.isEIP1559).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should not detect EIP-7702 when authorization list is empty', () => {
|
|
69
|
+
const transaction = {
|
|
70
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
71
|
+
value: '0x0',
|
|
72
|
+
gasLimit: '0x5208',
|
|
73
|
+
nonce: '0x0',
|
|
74
|
+
chainId: 1,
|
|
75
|
+
maxFeePerGas: '0x77359400',
|
|
76
|
+
maxPriorityFeePerGas: '0x77359400',
|
|
77
|
+
authorizationList: [],
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const method = new EVMSignTransaction({
|
|
81
|
+
id: 1,
|
|
82
|
+
payload: {
|
|
83
|
+
method: 'evmSignTransaction',
|
|
84
|
+
path: "m/44'/60'/0'/0/0",
|
|
85
|
+
transaction,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
method.device = mockDevice;
|
|
89
|
+
method.init();
|
|
90
|
+
|
|
91
|
+
expect(method.isEIP7702).toBe(false);
|
|
92
|
+
expect(method.isEIP1559).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('EIP-7702 Signature Processing', () => {
|
|
97
|
+
it('should return flattened r,s,v structure for authorization signatures', async () => {
|
|
98
|
+
const mockAuthSignatures = [
|
|
99
|
+
{
|
|
100
|
+
y_parity: 0,
|
|
101
|
+
r: 'abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd',
|
|
102
|
+
s: 'efab5678901234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
y_parity: 1,
|
|
106
|
+
r: '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
107
|
+
s: '567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234',
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
mockTypedCall.mockResolvedValue({
|
|
112
|
+
message: {
|
|
113
|
+
signature_v: 27,
|
|
114
|
+
signature_r: 'deadbeef1234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
115
|
+
signature_s: 'cafebabe567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
116
|
+
authorization_signatures: mockAuthSignatures,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
121
|
+
to: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
122
|
+
value: '0x0',
|
|
123
|
+
gasLimit: '0x5208',
|
|
124
|
+
nonce: '0x0',
|
|
125
|
+
chainId: 1,
|
|
126
|
+
maxFeePerGas: '0xbebc200',
|
|
127
|
+
maxPriorityFeePerGas: '0x9502f900',
|
|
128
|
+
authorizationList: [
|
|
129
|
+
{
|
|
130
|
+
chainId: 1,
|
|
131
|
+
address: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
132
|
+
nonce: '0x1',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const method = new EVMSignTransaction({
|
|
138
|
+
id: 1,
|
|
139
|
+
payload: {
|
|
140
|
+
method: 'evmSignTransaction',
|
|
141
|
+
path: "m/44'/60'/0'/0/0",
|
|
142
|
+
transaction,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
method.device = mockDevice;
|
|
146
|
+
method.init();
|
|
147
|
+
|
|
148
|
+
const result = await method.run();
|
|
149
|
+
|
|
150
|
+
expect(result).toEqual({
|
|
151
|
+
v: '0x1b',
|
|
152
|
+
r: '0xdeadbeef1234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
153
|
+
s: '0xcafebabe567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
154
|
+
authorizationSignatures: [
|
|
155
|
+
{
|
|
156
|
+
yParity: 0,
|
|
157
|
+
r: 'abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd',
|
|
158
|
+
s: 'efab5678901234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
yParity: 1,
|
|
162
|
+
r: '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
163
|
+
s: '567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234',
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should handle transaction without authorization signatures', async () => {
|
|
170
|
+
mockTypedCall.mockResolvedValue({
|
|
171
|
+
message: {
|
|
172
|
+
signature_v: 28,
|
|
173
|
+
signature_r: 'deadbeef1234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
174
|
+
signature_s: 'cafebabe567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
175
|
+
authorization_signatures: [],
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
180
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
181
|
+
value: '0x0',
|
|
182
|
+
gasLimit: '0x5208',
|
|
183
|
+
nonce: '0x0',
|
|
184
|
+
chainId: 1,
|
|
185
|
+
maxFeePerGas: '0x77359400',
|
|
186
|
+
maxPriorityFeePerGas: '0x77359400',
|
|
187
|
+
authorizationList: [
|
|
188
|
+
{
|
|
189
|
+
chainId: 1,
|
|
190
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
191
|
+
nonce: '0x0',
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const method = new EVMSignTransaction({
|
|
197
|
+
id: 1,
|
|
198
|
+
payload: {
|
|
199
|
+
method: 'evmSignTransaction',
|
|
200
|
+
path: "m/44'/60'/0'/0/0",
|
|
201
|
+
transaction,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
method.device = mockDevice;
|
|
205
|
+
method.init();
|
|
206
|
+
|
|
207
|
+
const result = await method.run();
|
|
208
|
+
|
|
209
|
+
expect(result).toEqual({
|
|
210
|
+
v: '0x1c',
|
|
211
|
+
r: '0xdeadbeef1234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
212
|
+
s: '0xcafebabe567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('EIP-7702 Validation', () => {
|
|
218
|
+
it('should require authorization list for EIP-7702 transactions', () => {
|
|
219
|
+
const transaction = {
|
|
220
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
221
|
+
value: '0x0',
|
|
222
|
+
gasLimit: '0x5208',
|
|
223
|
+
nonce: '0x0',
|
|
224
|
+
chainId: 1,
|
|
225
|
+
maxFeePerGas: '0x77359400',
|
|
226
|
+
maxPriorityFeePerGas: '0x77359400',
|
|
227
|
+
authorizationList: [], // Empty authorization list should trigger EIP1559 detection, not EIP7702
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// This should not throw because empty authorizationList means it's EIP1559, not EIP7702
|
|
231
|
+
expect(() => {
|
|
232
|
+
const method = new EVMSignTransaction({
|
|
233
|
+
id: 1,
|
|
234
|
+
payload: {
|
|
235
|
+
method: 'evmSignTransaction',
|
|
236
|
+
path: "m/44'/60'/0'/0/0",
|
|
237
|
+
transaction,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
method.device = mockDevice;
|
|
241
|
+
method.init();
|
|
242
|
+
}).not.toThrow();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should require maxFeePerGas and maxPriorityFeePerGas for EIP-7702', () => {
|
|
246
|
+
const transaction = {
|
|
247
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
248
|
+
value: '0x0',
|
|
249
|
+
gasLimit: '0x5208',
|
|
250
|
+
nonce: '0x0',
|
|
251
|
+
chainId: 1,
|
|
252
|
+
authorizationList: [
|
|
253
|
+
{
|
|
254
|
+
chainId: 1,
|
|
255
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
256
|
+
nonce: '0x0',
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
// Missing maxFeePerGas and maxPriorityFeePerGas
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
expect(() => {
|
|
263
|
+
const method = new EVMSignTransaction({
|
|
264
|
+
id: 1,
|
|
265
|
+
payload: {
|
|
266
|
+
method: 'evmSignTransaction',
|
|
267
|
+
path: "m/44'/60'/0'/0/0",
|
|
268
|
+
transaction,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
method.device = mockDevice;
|
|
272
|
+
method.init();
|
|
273
|
+
}).toThrow();
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
describe('Version Range', () => {
|
|
278
|
+
it('should return correct version range for EIP-7702', () => {
|
|
279
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
280
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
281
|
+
value: '0x0',
|
|
282
|
+
gasLimit: '0x5208',
|
|
283
|
+
nonce: '0x0',
|
|
284
|
+
chainId: 1,
|
|
285
|
+
maxFeePerGas: '0x77359400',
|
|
286
|
+
maxPriorityFeePerGas: '0x77359400',
|
|
287
|
+
authorizationList: [
|
|
288
|
+
{
|
|
289
|
+
chainId: 1,
|
|
290
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
291
|
+
nonce: '0x0',
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const method = new EVMSignTransaction({
|
|
297
|
+
id: 1,
|
|
298
|
+
payload: {
|
|
299
|
+
method: 'evmSignTransaction',
|
|
300
|
+
path: "m/44'/60'/0'/0/0",
|
|
301
|
+
transaction,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
method.device = mockDevice;
|
|
305
|
+
method.init();
|
|
306
|
+
|
|
307
|
+
const versionRange = method.getVersionRange();
|
|
308
|
+
|
|
309
|
+
expect(versionRange).toEqual({
|
|
310
|
+
model_classic1s: {
|
|
311
|
+
min: '3.13.0',
|
|
312
|
+
},
|
|
313
|
+
pro: {
|
|
314
|
+
min: '4.16.0',
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe('Edge Cases', () => {
|
|
321
|
+
it('should handle authorization with existing signature', async () => {
|
|
322
|
+
const mockAuthSignatures = [
|
|
323
|
+
{
|
|
324
|
+
y_parity: 1,
|
|
325
|
+
r: 'abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd',
|
|
326
|
+
s: 'efab5678901234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
327
|
+
},
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
mockTypedCall.mockResolvedValue({
|
|
331
|
+
message: {
|
|
332
|
+
signature_v: 27,
|
|
333
|
+
signature_r: 'deadbeef1234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
334
|
+
signature_s: 'cafebabe567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
335
|
+
authorization_signatures: mockAuthSignatures,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
340
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
341
|
+
value: '0x0',
|
|
342
|
+
gasLimit: '0x5208',
|
|
343
|
+
nonce: '0x0',
|
|
344
|
+
chainId: 1,
|
|
345
|
+
maxFeePerGas: '0x77359400',
|
|
346
|
+
maxPriorityFeePerGas: '0x77359400',
|
|
347
|
+
authorizationList: [
|
|
348
|
+
{
|
|
349
|
+
chainId: 1,
|
|
350
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
351
|
+
nonce: '0x0',
|
|
352
|
+
yParity: 0,
|
|
353
|
+
r: 'existing_r_value_1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
354
|
+
s: 'existing_s_value_567890abcdef1234567890abcdef1234567890abcdef1234',
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const method = new EVMSignTransaction({
|
|
360
|
+
id: 1,
|
|
361
|
+
payload: {
|
|
362
|
+
method: 'evmSignTransaction',
|
|
363
|
+
path: "m/44'/60'/0'/0/0",
|
|
364
|
+
transaction,
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
method.device = mockDevice;
|
|
368
|
+
method.init();
|
|
369
|
+
|
|
370
|
+
const result = await method.run();
|
|
371
|
+
|
|
372
|
+
expect(result.authorizationSignatures).toHaveLength(1);
|
|
373
|
+
expect(result.authorizationSignatures?.[0]).toEqual({
|
|
374
|
+
yParity: 1,
|
|
375
|
+
r: 'abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd',
|
|
376
|
+
s: 'efab5678901234567890abcdef1234567890abcdef1234567890abcdef123456',
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('should throw error for non-self-sponsoring transactions', async () => {
|
|
381
|
+
const transaction: EVMTransactionEIP7702 = {
|
|
382
|
+
to: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
383
|
+
value: '0x0',
|
|
384
|
+
gasLimit: '0x5208',
|
|
385
|
+
nonce: '0x0',
|
|
386
|
+
chainId: 1,
|
|
387
|
+
maxFeePerGas: '0xbebc200',
|
|
388
|
+
maxPriorityFeePerGas: '0x9502f900',
|
|
389
|
+
authorizationList: [
|
|
390
|
+
{
|
|
391
|
+
chainId: 1,
|
|
392
|
+
address: '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9',
|
|
393
|
+
nonce: '0x1',
|
|
394
|
+
addressN: [44, 60, 0, 0, 1], // Different from transaction signer
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const method = new EVMSignTransaction({
|
|
400
|
+
id: 1,
|
|
401
|
+
payload: {
|
|
402
|
+
method: 'evmSignTransaction',
|
|
403
|
+
path: "m/44'/60'/0'/0/0", // Different from authorization addressN
|
|
404
|
+
transaction,
|
|
405
|
+
},
|
|
406
|
+
});
|
|
407
|
+
method.device = mockDevice;
|
|
408
|
+
method.init();
|
|
409
|
+
|
|
410
|
+
await expect(method.run()).rejects.toMatchObject({
|
|
411
|
+
errorCode: 400,
|
|
412
|
+
message: expect.stringContaining(
|
|
413
|
+
'Hardware currently only supports self-sponsoring EIP-7702 transactions'
|
|
414
|
+
),
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
});
|
|
@@ -12,7 +12,7 @@ export default class EVMSignTransaction extends BaseMethod {
|
|
|
12
12
|
model_classic1s: {
|
|
13
13
|
min: string;
|
|
14
14
|
};
|
|
15
|
-
|
|
15
|
+
pro: {
|
|
16
16
|
min: string;
|
|
17
17
|
};
|
|
18
18
|
model_mini?: undefined;
|
|
@@ -21,7 +21,7 @@ export default class EVMSignTransaction extends BaseMethod {
|
|
|
21
21
|
min: string;
|
|
22
22
|
};
|
|
23
23
|
model_classic1s?: undefined;
|
|
24
|
-
|
|
24
|
+
pro?: undefined;
|
|
25
25
|
};
|
|
26
26
|
run(): Promise<import("../../types").EVMSignedTx>;
|
|
27
27
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EthereumTxRequestOneKey, TypedCall } from '@onekeyfe/hd-transport';
|
|
1
|
+
import { EthereumTxRequest, EthereumTxRequestOneKey, TypedCall } from '@onekeyfe/hd-transport';
|
|
2
2
|
import { EVMSignedTx, EVMTransaction, EVMTransactionEIP1559, EVMTransactionEIP7702 } from '../../../types';
|
|
3
3
|
export declare const processTxRequest: ({ typedCall, request, data, chainId, supportTrezor, }: {
|
|
4
4
|
typedCall: TypedCall;
|
|
5
|
-
request: EthereumTxRequestOneKey;
|
|
5
|
+
request: EthereumTxRequestOneKey | EthereumTxRequest;
|
|
6
6
|
data: string;
|
|
7
7
|
chainId?: number | undefined;
|
|
8
8
|
supportTrezor?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signTransaction.d.ts","sourceRoot":"","sources":["../../../../src/api/evm/latest/signTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"signTransaction.d.ts","sourceRoot":"","sources":["../../../../src/api/evm/latest/signTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,iBAAiB,EACjB,uBAAuB,EAEvB,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAIxB,eAAO,MAAM,gBAAgB;eAOhB,SAAS;aACX,uBAAuB,GAAG,iBAAiB;UAC9C,MAAM;cACF,MAAM,GAAG,SAAS;;MAE1B,QAAQ,WAAW,CA4DtB,CAAC;AAEF,eAAO,MAAM,SAAS;eAMT,SAAS;cACV,MAAM,EAAE;QACd,cAAc;;0BAgDnB,CAAC;AAEF,eAAO,MAAM,gBAAgB;eAMhB,SAAS;cACV,MAAM,EAAE;QACd,qBAAqB;;0BA4C1B,CAAC;AAEF,eAAO,MAAM,gBAAgB;eAMhB,SAAS;cACV,MAAM,EAAE;QACd,qBAAqB;;0BAgF1B,CAAC;AAEF,eAAO,MAAM,eAAe;cAOhB,MAAM,EAAE;QACd,cAAc,GAAG,qBAAqB,GAAG,qBAAqB;eACvD,OAAO;;eAEP,SAAS;0BAQrB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -798,11 +798,13 @@ type EVMAuthorizationSignature = {
|
|
|
798
798
|
s: string;
|
|
799
799
|
};
|
|
800
800
|
type EVMAuthorization = {
|
|
801
|
-
addressN?: number[];
|
|
802
801
|
chainId: number;
|
|
803
802
|
address: string;
|
|
804
803
|
nonce: string;
|
|
805
|
-
|
|
804
|
+
addressN?: number[];
|
|
805
|
+
yParity?: number;
|
|
806
|
+
r?: string;
|
|
807
|
+
s?: string;
|
|
806
808
|
};
|
|
807
809
|
type EVMTransactionEIP7702 = {
|
|
808
810
|
to: string;
|
package/dist/index.js
CHANGED
|
@@ -32169,7 +32169,7 @@ const processTxRequest = ({ typedCall, request, data, chainId, supportTrezor, })
|
|
|
32169
32169
|
let v = request.signature_v;
|
|
32170
32170
|
const r = request.signature_r;
|
|
32171
32171
|
const s = request.signature_s;
|
|
32172
|
-
const authorizationSignatures = request.authorization_signatures;
|
|
32172
|
+
const authorizationSignatures = 'authorization_signatures' in request ? request.authorization_signatures : undefined;
|
|
32173
32173
|
if (v == null || r == null || s == null) {
|
|
32174
32174
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'processTxRequest: Unexpected request');
|
|
32175
32175
|
}
|
|
@@ -32182,7 +32182,7 @@ const processTxRequest = ({ typedCall, request, data, chainId, supportTrezor, })
|
|
|
32182
32182
|
s: `0x${s}`,
|
|
32183
32183
|
};
|
|
32184
32184
|
if (authorizationSignatures && authorizationSignatures.length > 0) {
|
|
32185
|
-
result.authorizationSignatures = authorizationSignatures.map(sig => ({
|
|
32185
|
+
result.authorizationSignatures = authorizationSignatures.map((sig) => ({
|
|
32186
32186
|
yParity: sig.y_parity,
|
|
32187
32187
|
r: sig.r,
|
|
32188
32188
|
s: sig.s,
|
|
@@ -32275,6 +32275,10 @@ const evmSignTxEip1559 = ({ typedCall, addressN, tx, supportTrezor, }) => __awai
|
|
|
32275
32275
|
});
|
|
32276
32276
|
const evmSignTxEip7702 = ({ typedCall, addressN, tx, supportTrezor, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32277
32277
|
const { to, value, gasLimit, nonce, data, chainId, maxFeePerGas, maxPriorityFeePerGas, accessList, authorizationList, } = tx;
|
|
32278
|
+
const hasNonSelfSponsoring = authorizationList.some(auth => auth.addressN && auth.addressN.join('/') !== addressN.join('/'));
|
|
32279
|
+
if (hasNonSelfSponsoring) {
|
|
32280
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodError, 'Hardware currently only supports self-sponsoring EIP-7702 transactions. All authorization entries must be signed by the same account as the transaction.');
|
|
32281
|
+
}
|
|
32278
32282
|
const length = data == null ? 0 : data.length / 2;
|
|
32279
32283
|
const [first, rest] = cutString(data, 1024 * 2);
|
|
32280
32284
|
const message = {
|
|
@@ -32297,11 +32301,11 @@ const evmSignTxEip7702 = ({ typedCall, addressN, tx, supportTrezor, }) => __awai
|
|
|
32297
32301
|
chain_id: auth.chainId,
|
|
32298
32302
|
address: addHexPrefix(auth.address),
|
|
32299
32303
|
nonce: stripHexStartZeroes(auth.nonce),
|
|
32300
|
-
signature: auth.
|
|
32304
|
+
signature: auth.yParity !== undefined && auth.r && auth.s
|
|
32301
32305
|
? {
|
|
32302
|
-
y_parity: auth.
|
|
32303
|
-
r: auth.
|
|
32304
|
-
s: auth.
|
|
32306
|
+
y_parity: auth.yParity,
|
|
32307
|
+
r: auth.r,
|
|
32308
|
+
s: auth.s,
|
|
32305
32309
|
}
|
|
32306
32310
|
: undefined,
|
|
32307
32311
|
})),
|
|
@@ -32313,7 +32317,12 @@ const evmSignTxEip7702 = ({ typedCall, addressN, tx, supportTrezor, }) => __awai
|
|
|
32313
32317
|
else {
|
|
32314
32318
|
response = yield typedCall('EthereumSignTxEIP7702OneKey', 'EthereumTxRequestOneKey', message);
|
|
32315
32319
|
}
|
|
32316
|
-
return processTxRequest({
|
|
32320
|
+
return processTxRequest({
|
|
32321
|
+
typedCall,
|
|
32322
|
+
request: response.message,
|
|
32323
|
+
data: rest,
|
|
32324
|
+
supportTrezor,
|
|
32325
|
+
});
|
|
32317
32326
|
});
|
|
32318
32327
|
const signTransaction$1 = ({ typedCall, isEIP1559, isEIP7702, addressN, tx, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32319
32328
|
if (isEIP7702) {
|
|
@@ -32400,7 +32409,7 @@ class EVMSignTransaction extends BaseMethod {
|
|
|
32400
32409
|
model_classic1s: {
|
|
32401
32410
|
min: '3.13.0',
|
|
32402
32411
|
},
|
|
32403
|
-
|
|
32412
|
+
pro: {
|
|
32404
32413
|
min: '4.16.0',
|
|
32405
32414
|
},
|
|
32406
32415
|
};
|
|
@@ -39,11 +39,13 @@ export type EVMAuthorizationSignature = {
|
|
|
39
39
|
s: string;
|
|
40
40
|
};
|
|
41
41
|
export type EVMAuthorization = {
|
|
42
|
-
addressN?: number[];
|
|
43
42
|
chainId: number;
|
|
44
43
|
address: string;
|
|
45
44
|
nonce: string;
|
|
46
|
-
|
|
45
|
+
addressN?: number[];
|
|
46
|
+
yParity?: number;
|
|
47
|
+
r?: string;
|
|
48
|
+
s?: string;
|
|
47
49
|
};
|
|
48
50
|
export type EVMTransactionEIP7702 = {
|
|
49
51
|
to: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evmSignTransaction.d.ts","sourceRoot":"","sources":["../../../src/types/api/evmSignTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,uBAAuB,CAAC,EAAE,yBAAyB,EAAE,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,SAAS,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,SAAS,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,
|
|
1
|
+
{"version":3,"file":"evmSignTransaction.d.ts","sourceRoot":"","sources":["../../../src/types/api/evmSignTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,uBAAuB,CAAC,EAAE,yBAAyB,EAAE,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,SAAS,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,SAAS,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,cAAc,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;CAC7E,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GAAG,wBAAwB,GAC9C,QAAQ,CAAC,WAAW,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.1.11
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.11",
|
|
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",
|
|
7
7
|
"license": "ISC",
|
|
@@ -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.11
|
|
29
|
-
"@onekeyfe/hd-transport": "1.1.11
|
|
28
|
+
"@onekeyfe/hd-shared": "1.1.11",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.1.11",
|
|
30
30
|
"axios": "^0.27.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/web-bluetooth": "^0.0.21",
|
|
47
47
|
"ripple-keypairs": "^1.3.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "6f34846189d7e74c84a7c25cf2db12ce9abf338f"
|
|
50
50
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
EthereumAuthorizationSignature,
|
|
2
3
|
EthereumSignTx,
|
|
3
4
|
EthereumSignTxEIP1559,
|
|
4
5
|
EthereumSignTxEIP7702OneKey,
|
|
6
|
+
EthereumTxRequest,
|
|
5
7
|
EthereumTxRequestOneKey,
|
|
6
8
|
MessageResponse,
|
|
7
9
|
TypedCall,
|
|
@@ -24,7 +26,7 @@ export const processTxRequest = async ({
|
|
|
24
26
|
supportTrezor,
|
|
25
27
|
}: {
|
|
26
28
|
typedCall: TypedCall;
|
|
27
|
-
request: EthereumTxRequestOneKey;
|
|
29
|
+
request: EthereumTxRequestOneKey | EthereumTxRequest;
|
|
28
30
|
data: string;
|
|
29
31
|
chainId?: number | undefined;
|
|
30
32
|
supportTrezor?: boolean;
|
|
@@ -33,7 +35,8 @@ export const processTxRequest = async ({
|
|
|
33
35
|
let v = request.signature_v;
|
|
34
36
|
const r = request.signature_r;
|
|
35
37
|
const s = request.signature_s;
|
|
36
|
-
const authorizationSignatures =
|
|
38
|
+
const authorizationSignatures =
|
|
39
|
+
'authorization_signatures' in request ? request.authorization_signatures : undefined;
|
|
37
40
|
|
|
38
41
|
if (v == null || r == null || s == null) {
|
|
39
42
|
throw ERRORS.TypedError(
|
|
@@ -53,13 +56,15 @@ export const processTxRequest = async ({
|
|
|
53
56
|
s: `0x${s}`,
|
|
54
57
|
};
|
|
55
58
|
|
|
56
|
-
// Add authorization signatures for EIP7702 transactions
|
|
59
|
+
// Add authorization signatures for EIP7702 transactions with flattened yParity,r,s structure
|
|
57
60
|
if (authorizationSignatures && authorizationSignatures.length > 0) {
|
|
58
|
-
result.authorizationSignatures = authorizationSignatures.map(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
result.authorizationSignatures = authorizationSignatures.map(
|
|
62
|
+
(sig: EthereumAuthorizationSignature) => ({
|
|
63
|
+
yParity: sig.y_parity,
|
|
64
|
+
r: sig.r,
|
|
65
|
+
s: sig.s,
|
|
66
|
+
})
|
|
67
|
+
);
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
return Promise.resolve(result);
|
|
@@ -223,6 +228,21 @@ export const evmSignTxEip7702 = async ({
|
|
|
223
228
|
authorizationList,
|
|
224
229
|
} = tx;
|
|
225
230
|
|
|
231
|
+
// Hardware currently only supports self-sponsoring transactions
|
|
232
|
+
// Check if all authorization entries are for self-sponsoring
|
|
233
|
+
const hasNonSelfSponsoring = authorizationList.some(
|
|
234
|
+
auth =>
|
|
235
|
+
// If addressN is provided for this authorization, it should match the transaction signer
|
|
236
|
+
auth.addressN && auth.addressN.join('/') !== addressN.join('/')
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
if (hasNonSelfSponsoring) {
|
|
240
|
+
throw ERRORS.TypedError(
|
|
241
|
+
HardwareErrorCode.CallMethodError,
|
|
242
|
+
'Hardware currently only supports self-sponsoring EIP-7702 transactions. All authorization entries must be signed by the same account as the transaction.'
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
226
246
|
const length = data == null ? 0 : data.length / 2;
|
|
227
247
|
|
|
228
248
|
const [first, rest] = cutString(data, 1024 * 2);
|
|
@@ -247,13 +267,14 @@ export const evmSignTxEip7702 = async ({
|
|
|
247
267
|
chain_id: auth.chainId,
|
|
248
268
|
address: addHexPrefix(auth.address),
|
|
249
269
|
nonce: stripHexStartZeroes(auth.nonce),
|
|
250
|
-
signature:
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
270
|
+
signature:
|
|
271
|
+
auth.yParity !== undefined && auth.r && auth.s
|
|
272
|
+
? {
|
|
273
|
+
y_parity: auth.yParity,
|
|
274
|
+
r: auth.r,
|
|
275
|
+
s: auth.s,
|
|
276
|
+
}
|
|
277
|
+
: undefined,
|
|
257
278
|
})),
|
|
258
279
|
};
|
|
259
280
|
|
|
@@ -265,7 +286,12 @@ export const evmSignTxEip7702 = async ({
|
|
|
265
286
|
response = await typedCall('EthereumSignTxEIP7702OneKey', 'EthereumTxRequestOneKey', message);
|
|
266
287
|
}
|
|
267
288
|
|
|
268
|
-
return processTxRequest({
|
|
289
|
+
return processTxRequest({
|
|
290
|
+
typedCall,
|
|
291
|
+
request: response.message,
|
|
292
|
+
data: rest,
|
|
293
|
+
supportTrezor,
|
|
294
|
+
});
|
|
269
295
|
};
|
|
270
296
|
|
|
271
297
|
export const signTransaction = async ({
|
|
@@ -45,11 +45,13 @@ export type EVMAuthorizationSignature = {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
export type EVMAuthorization = {
|
|
48
|
-
addressN?: number[];
|
|
49
48
|
chainId: number;
|
|
50
49
|
address: string;
|
|
51
50
|
nonce: string;
|
|
52
|
-
|
|
51
|
+
addressN?: number[];
|
|
52
|
+
yParity?: number;
|
|
53
|
+
r?: string;
|
|
54
|
+
s?: string;
|
|
53
55
|
};
|
|
54
56
|
|
|
55
57
|
export type EVMTransactionEIP7702 = {
|