@onekeyfe/hd-core 1.1.9-alpha.0 → 1.1.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.
@@ -1,13 +1,12 @@
1
1
  import {
2
2
  EthereumSignTx,
3
3
  EthereumSignTxEIP1559,
4
- EthereumSignTxEIP7702OneKey,
5
4
  EthereumTxRequestOneKey,
6
5
  MessageResponse,
7
6
  TypedCall,
8
7
  } from '@onekeyfe/hd-transport';
9
8
  import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
10
- import { EVMSignedTx, EVMTransaction, EVMTransactionEIP1559, EVMTransactionEIP7702 } from '../../../types';
9
+ import { EVMSignedTx, EVMTransaction, EVMTransactionEIP1559 } from '../../../types';
11
10
  import { cutString } from '../../helpers/stringUtils';
12
11
  import { stripHexStartZeroes } from '../../helpers/hexUtils';
13
12
 
@@ -181,91 +180,17 @@ export const evmSignTxEip1559 = async ({
181
180
 
182
181
  return processTxRequest({ typedCall, request: response.message, data: rest, supportTrezor });
183
182
  };
184
-
185
- export const evmSignTxEip7702 = async ({
186
- typedCall,
187
- addressN,
188
- tx,
189
- supportTrezor,
190
- }: {
191
- typedCall: TypedCall;
192
- addressN: number[];
193
- tx: EVMTransactionEIP7702;
194
- supportTrezor?: boolean;
195
- }) => {
196
- const {
197
- to,
198
- value,
199
- gasLimit,
200
- nonce,
201
- data,
202
- chainId,
203
- maxFeePerGas,
204
- maxPriorityFeePerGas,
205
- accessList,
206
- authorizationList,
207
- } = tx;
208
-
209
- const length = data == null ? 0 : data.length / 2;
210
-
211
- const [first, rest] = cutString(data, 1024 * 2);
212
-
213
- const message: EthereumSignTxEIP7702OneKey = {
214
- address_n: addressN,
215
- nonce: stripHexStartZeroes(nonce),
216
- max_gas_fee: stripHexStartZeroes(maxFeePerGas),
217
- max_priority_fee: stripHexStartZeroes(maxPriorityFeePerGas),
218
- gas_limit: stripHexStartZeroes(gasLimit),
219
- to,
220
- value: stripHexStartZeroes(value),
221
- data_length: length,
222
- data_initial_chunk: first,
223
- chain_id: chainId,
224
- access_list: (accessList || []).map(a => ({
225
- address: a.address,
226
- storage_keys: a.storageKeys,
227
- })),
228
- authorization_list: authorizationList.map(auth => ({
229
- address_n: auth.addressN || [],
230
- chain_id: auth.chainId,
231
- address: auth.address,
232
- nonce: stripHexStartZeroes(auth.nonce),
233
- signature: auth.signature ? {
234
- y_parity: auth.signature.yParity,
235
- r: auth.signature.r,
236
- s: auth.signature.s,
237
- } : undefined,
238
- })),
239
- };
240
-
241
- let response;
242
- if (supportTrezor) {
243
- // Note: Trezor doesn't support EIP7702 yet, this is for future compatibility
244
- throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'EIP7702 not supported by Trezor');
245
- } else {
246
- response = await typedCall('EthereumSignTxEIP7702OneKey', 'EthereumTxRequestOneKey', message);
247
- }
248
-
249
- return processTxRequest({ typedCall, request: response.message, data: rest, supportTrezor });
250
- };
251
-
252
183
  export const signTransaction = async ({
253
184
  typedCall,
254
185
  isEIP1559,
255
- isEIP7702,
256
186
  addressN,
257
187
  tx,
258
188
  }: {
259
189
  addressN: number[];
260
- tx: EVMTransaction | EVMTransactionEIP1559 | EVMTransactionEIP7702;
190
+ tx: EVMTransaction | EVMTransactionEIP1559;
261
191
  isEIP1559: boolean;
262
- isEIP7702?: boolean;
263
192
  typedCall: TypedCall;
264
- }) => {
265
- if (isEIP7702) {
266
- return evmSignTxEip7702({ typedCall, addressN, tx: tx as EVMTransactionEIP7702 });
267
- }
268
- return isEIP1559
193
+ }) =>
194
+ isEIP1559
269
195
  ? evmSignTxEip1559({ typedCall, addressN, tx: tx as EVMTransactionEIP1559 })
270
196
  : evmSignTx({ typedCall, addressN, tx: tx as EVMTransaction });
271
- };
@@ -5323,125 +5323,6 @@
5323
5323
  }
5324
5324
  }
5325
5325
  },
5326
- "EthereumAuthorizationSignature": {
5327
- "fields": {
5328
- "y_parity": {
5329
- "rule": "required",
5330
- "type": "uint32",
5331
- "id": 1
5332
- },
5333
- "r": {
5334
- "rule": "required",
5335
- "type": "bytes",
5336
- "id": 2
5337
- },
5338
- "s": {
5339
- "rule": "required",
5340
- "type": "bytes",
5341
- "id": 3
5342
- }
5343
- }
5344
- },
5345
- "EthereumAuthorizationOneKey": {
5346
- "fields": {
5347
- "address_n": {
5348
- "rule": "repeated",
5349
- "type": "uint32",
5350
- "id": 1,
5351
- "options": {
5352
- "packed": false
5353
- }
5354
- },
5355
- "chain_id": {
5356
- "rule": "required",
5357
- "type": "uint64",
5358
- "id": 2
5359
- },
5360
- "address": {
5361
- "rule": "required",
5362
- "type": "string",
5363
- "id": 3
5364
- },
5365
- "nonce": {
5366
- "rule": "required",
5367
- "type": "bytes",
5368
- "id": 4
5369
- },
5370
- "signature": {
5371
- "type": "EthereumAuthorizationSignature",
5372
- "id": 5
5373
- }
5374
- }
5375
- },
5376
- "EthereumSignTxEIP7702OneKey": {
5377
- "fields": {
5378
- "address_n": {
5379
- "rule": "repeated",
5380
- "type": "uint32",
5381
- "id": 1,
5382
- "options": {
5383
- "packed": false
5384
- }
5385
- },
5386
- "nonce": {
5387
- "rule": "required",
5388
- "type": "bytes",
5389
- "id": 2
5390
- },
5391
- "max_gas_fee": {
5392
- "rule": "required",
5393
- "type": "bytes",
5394
- "id": 3
5395
- },
5396
- "max_priority_fee": {
5397
- "rule": "required",
5398
- "type": "bytes",
5399
- "id": 4
5400
- },
5401
- "gas_limit": {
5402
- "rule": "required",
5403
- "type": "bytes",
5404
- "id": 5
5405
- },
5406
- "to": {
5407
- "rule": "required",
5408
- "type": "string",
5409
- "id": 6
5410
- },
5411
- "value": {
5412
- "rule": "required",
5413
- "type": "bytes",
5414
- "id": 7
5415
- },
5416
- "data_initial_chunk": {
5417
- "type": "bytes",
5418
- "id": 8,
5419
- "options": {
5420
- "default": ""
5421
- }
5422
- },
5423
- "data_length": {
5424
- "rule": "required",
5425
- "type": "uint32",
5426
- "id": 9
5427
- },
5428
- "chain_id": {
5429
- "rule": "required",
5430
- "type": "uint64",
5431
- "id": 10
5432
- },
5433
- "access_list": {
5434
- "rule": "repeated",
5435
- "type": "EthereumAccessListOneKey",
5436
- "id": 11
5437
- },
5438
- "authorization_list": {
5439
- "rule": "repeated",
5440
- "type": "EthereumAuthorizationOneKey",
5441
- "id": 12
5442
- }
5443
- }
5444
- },
5445
5326
  "EthereumTxRequestOneKey": {
5446
5327
  "fields": {
5447
5328
  "data_length": {
@@ -5459,11 +5340,6 @@
5459
5340
  "signature_s": {
5460
5341
  "type": "bytes",
5461
5342
  "id": 4
5462
- },
5463
- "authorization_signatures": {
5464
- "rule": "repeated",
5465
- "type": "EthereumAuthorizationSignature",
5466
- "id": 10
5467
5343
  }
5468
5344
  }
5469
5345
  },
@@ -12024,7 +11900,6 @@
12024
11900
  "MessageType_EthereumAddressOneKey": 20103,
12025
11901
  "MessageType_EthereumSignTxOneKey": 20104,
12026
11902
  "MessageType_EthereumSignTxEIP1559OneKey": 20105,
12027
- "MessageType_EthereumSignTxEIP7702OneKey": 20120,
12028
11903
  "MessageType_EthereumTxRequestOneKey": 20106,
12029
11904
  "MessageType_EthereumTxAckOneKey": 20107,
12030
11905
  "MessageType_EthereumSignMessageOneKey": 20108,
@@ -25,7 +25,7 @@ import type {
25
25
  import { DeviceModelToTypes } from '../types';
26
26
  import { findLatestRelease, getReleaseChangelog, getReleaseStatus } from '../utils/release';
27
27
 
28
- export type IFirmwareField = 'firmware' | 'firmware-v2' | 'firmware-v6';
28
+ export type IFirmwareField = 'firmware' | 'firmware-v2' | 'firmware-v7';
29
29
 
30
30
  export type MessageVersion = 'latest' | 'v1';
31
31
 
package/src/inject.ts CHANGED
@@ -2,8 +2,9 @@ import { EventEmitter } from 'events';
2
2
  import { CallMethod } from './events';
3
3
  import { CoreApi } from './types/api';
4
4
  import type { AllNetworkAddress } from './types/api/allNetworkGetAddress';
5
+ import { Unsuccessful } from './types';
5
6
 
6
- type CallbackFunction = (data?: any, error?: { message: string; code?: number }) => void;
7
+ type CallbackFunction = (data?: any, error?: Unsuccessful) => void;
7
8
 
8
9
  const callbackManager = new Map<string, CallbackFunction>();
9
10
 
@@ -179,8 +180,8 @@ export const createCoreApi = (
179
180
  registerCallback(callbackId, onLoopItemResponse);
180
181
 
181
182
  const callbackIdFinish = generateCallbackId();
182
- registerCallback(callbackIdFinish, (data?: AllNetworkAddress[]) => {
183
- onAllItemsResponse?.(data);
183
+ registerCallback(callbackIdFinish, (data?: AllNetworkAddress[], error?: Unsuccessful) => {
184
+ onAllItemsResponse?.(data, error);
184
185
  cleanupCallback(callbackIdFinish);
185
186
  cleanupCallback(callbackId);
186
187
  });
@@ -37,37 +37,9 @@ export type EVMTransactionEIP1559 = {
37
37
  accessList?: EVMAccessList[];
38
38
  };
39
39
 
40
- export type EVMAuthorizationSignature = {
41
- yParity: number;
42
- r: string;
43
- s: string;
44
- };
45
-
46
- export type EVMAuthorization = {
47
- addressN?: number[];
48
- chainId: number;
49
- address: string;
50
- nonce: string;
51
- signature?: EVMAuthorizationSignature;
52
- };
53
-
54
- export type EVMTransactionEIP7702 = {
55
- to: string;
56
- value: string;
57
- gasLimit: string;
58
- gasPrice?: typeof undefined;
59
- nonce: string;
60
- data?: string;
61
- chainId: number;
62
- maxFeePerGas: string;
63
- maxPriorityFeePerGas: string;
64
- accessList?: EVMAccessList[];
65
- authorizationList: EVMAuthorization[];
66
- };
67
-
68
40
  export type EVMSignTransactionParams = {
69
41
  path: string | number[];
70
- transaction: EVMTransaction | EVMTransactionEIP1559 | EVMTransactionEIP7702;
42
+ transaction: EVMTransaction | EVMTransactionEIP1559;
71
43
  };
72
44
 
73
45
  export declare function evmSignTransaction(
@@ -78,7 +78,7 @@ export type DeviceTypeMap = {
78
78
  [k in IKnownDevice]: {
79
79
  firmware: IFirmwareReleaseInfo[];
80
80
  'firmware-v2'?: IFirmwareReleaseInfo[];
81
- 'firmware-v6'?: IFirmwareReleaseInfo[];
81
+ 'firmware-v7'?: IFirmwareReleaseInfo[];
82
82
  ble: IBLEFirmwareReleaseInfo[];
83
83
  };
84
84
  };
@@ -240,21 +240,21 @@ export const getFirmwareUpdateField = ({
240
240
  }
241
241
 
242
242
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
243
- return 'firmware-v6';
243
+ return 'firmware-v7';
244
244
  }
245
245
 
246
246
  if (deviceType === EDeviceType.Touch) {
247
247
  if (targetVersion) {
248
248
  if (semver.eq(targetVersion, '4.0.0')) return 'firmware-v2';
249
- if (semver.gt(targetVersion, '4.0.0')) return 'firmware-v6';
249
+ if (semver.gt(targetVersion, '4.0.0')) return 'firmware-v7';
250
250
  }
251
251
 
252
252
  if (semver.lt(deviceFirmwareVersion.join('.'), '3.4.0')) return 'firmware';
253
253
 
254
- return 'firmware-v6';
254
+ return 'firmware-v7';
255
255
  }
256
256
  if (deviceType === EDeviceType.Pro) {
257
- return 'firmware-v6';
257
+ return 'firmware-v7';
258
258
  }
259
259
  return 'firmware';
260
260
  };
@@ -266,7 +266,7 @@ export const getFirmwareUpdateField = ({
266
266
  export const getFirmwareUpdateFieldArray = (
267
267
  features: Features,
268
268
  updateType: 'firmware' | 'ble' | 'bootloader'
269
- ): ('firmware' | 'ble' | 'firmware-v2' | 'firmware-v6')[] => {
269
+ ): ('firmware' | 'ble' | 'firmware-v2' | 'firmware-v7')[] => {
270
270
  const deviceType = getDeviceType(features);
271
271
  if (updateType === 'ble') {
272
272
  return ['ble'];
@@ -278,25 +278,25 @@ export const getFirmwareUpdateFieldArray = (
278
278
  deviceType === 'mini' ||
279
279
  deviceType === 'classicpure'
280
280
  ) {
281
- return ['firmware-v6'];
281
+ return ['firmware-v7'];
282
282
  }
283
283
 
284
284
  if (deviceType === 'touch') {
285
285
  const currentVersion = getDeviceFirmwareVersion(features).join('.');
286
286
  if (semver.gt(currentVersion, '4.0.0')) {
287
- return ['firmware-v6', 'firmware'];
287
+ return ['firmware-v7', 'firmware'];
288
288
  }
289
289
  if (semver.gte(currentVersion, '4.0.0')) {
290
290
  return ['firmware-v2', 'firmware'];
291
291
  }
292
292
  if (!currentVersion || semver.lt(currentVersion, '3.0.0')) {
293
- return ['firmware-v6', 'firmware-v2', 'firmware'];
293
+ return ['firmware-v7', 'firmware-v2', 'firmware'];
294
294
  }
295
295
  return ['firmware'];
296
296
  }
297
297
 
298
298
  if (deviceType === 'pro') {
299
- return ['firmware-v6'];
299
+ return ['firmware-v7'];
300
300
  }
301
301
 
302
302
  return ['firmware'];
@@ -1,216 +0,0 @@
1
- import { EVMTransactionEIP7702, EVMAuthorization, EVMAuthorizationSignature } from '../src/types';
2
-
3
- describe('EVM EIP-7702 Transaction Types', () => {
4
- test('should create valid EIP7702 transaction type', () => {
5
- const authSignature: EVMAuthorizationSignature = {
6
- yParity: 0,
7
- r: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
8
- s: '0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321',
9
- };
10
-
11
- const authorization: EVMAuthorization = {
12
- chainId: 1,
13
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
14
- nonce: '0x0',
15
- signature: authSignature,
16
- };
17
-
18
- const transaction: EVMTransactionEIP7702 = {
19
- to: '0x7314e0f1c0e28474bdb6be3e2c3e0453255188f8',
20
- value: '0xf4240',
21
- gasLimit: '0x5208',
22
- nonce: '0x0',
23
- data: '0x',
24
- chainId: 1,
25
- maxFeePerGas: '0xbebc200',
26
- maxPriorityFeePerGas: '0x9502f900',
27
- accessList: [],
28
- authorizationList: [authorization],
29
- };
30
-
31
- expect(transaction.authorizationList).toHaveLength(1);
32
- expect(transaction.authorizationList[0].chainId).toBe(1);
33
- expect(transaction.authorizationList[0].address).toBe('0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb');
34
- expect(transaction.authorizationList[0].signature?.yParity).toBe(0);
35
- });
36
-
37
- test('should create EIP7702 transaction with multiple authorizations', () => {
38
- const auth1: EVMAuthorization = {
39
- chainId: 1,
40
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
41
- nonce: '0x0',
42
- signature: {
43
- yParity: 0,
44
- r: '0x1111111111111111111111111111111111111111111111111111111111111111',
45
- s: '0x2222222222222222222222222222222222222222222222222222222222222222',
46
- },
47
- };
48
-
49
- const auth2: EVMAuthorization = {
50
- chainId: 1,
51
- address: '0x7DAF91DFe55FcAb363416A6E3bceb3Da34ff1d30',
52
- nonce: '0x1',
53
- signature: {
54
- yParity: 1,
55
- r: '0x3333333333333333333333333333333333333333333333333333333333333333',
56
- s: '0x4444444444444444444444444444444444444444444444444444444444444444',
57
- },
58
- };
59
-
60
- const transaction: EVMTransactionEIP7702 = {
61
- to: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
62
- value: '0x0',
63
- gasLimit: '0x7530',
64
- nonce: '0x1',
65
- data: '0x8129fc1c', // initialize() function selector
66
- chainId: 1,
67
- maxFeePerGas: '0xbebc200',
68
- maxPriorityFeePerGas: '0x9502f900',
69
- accessList: [
70
- {
71
- address: '0xA0b86a33E6417c8f2c8B758B2d7D2E0C0C2E8E8E',
72
- storageKeys: ['0x0000000000000000000000000000000000000000000000000000000000000001'],
73
- },
74
- ],
75
- authorizationList: [auth1, auth2],
76
- };
77
-
78
- expect(transaction.authorizationList).toHaveLength(2);
79
- expect(transaction.authorizationList[0].address).toBe('0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb');
80
- expect(transaction.authorizationList[1].address).toBe('0x7DAF91DFe55FcAb363416A6E3bceb3Da34ff1d30');
81
- expect(transaction.accessList).toHaveLength(1);
82
- });
83
-
84
- test('should create EIP7702 transaction without signature (for delegation setup)', () => {
85
- const authorization: EVMAuthorization = {
86
- addressN: [44, 60, 0, 0, 0], // m/44'/60'/0'/0/0
87
- chainId: 1,
88
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
89
- nonce: '0x0',
90
- // No signature - will be provided by hardware wallet
91
- };
92
-
93
- const transaction: EVMTransactionEIP7702 = {
94
- to: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
95
- value: '0x0',
96
- gasLimit: '0x5208',
97
- nonce: '0x0',
98
- data: '0x8129fc1c',
99
- chainId: 1,
100
- maxFeePerGas: '0xbebc200',
101
- maxPriorityFeePerGas: '0x9502f900',
102
- accessList: [],
103
- authorizationList: [authorization],
104
- };
105
-
106
- expect(transaction.authorizationList[0].addressN).toEqual([44, 60, 0, 0, 0]);
107
- expect(transaction.authorizationList[0].signature).toBeUndefined();
108
- });
109
-
110
- test('should validate required EIP7702 fields', () => {
111
- const transaction: EVMTransactionEIP7702 = {
112
- to: '0x7314e0f1c0e28474bdb6be3e2c3e0453255188f8',
113
- value: '0xf4240',
114
- gasLimit: '0x5208',
115
- nonce: '0x0',
116
- chainId: 1,
117
- maxFeePerGas: '0xbebc200',
118
- maxPriorityFeePerGas: '0x9502f900',
119
- authorizationList: [
120
- {
121
- chainId: 1,
122
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
123
- nonce: '0x0',
124
- },
125
- ],
126
- };
127
-
128
- // Verify required fields are present
129
- expect(transaction.to).toBeDefined();
130
- expect(transaction.value).toBeDefined();
131
- expect(transaction.gasLimit).toBeDefined();
132
- expect(transaction.nonce).toBeDefined();
133
- expect(transaction.chainId).toBeDefined();
134
- expect(transaction.maxFeePerGas).toBeDefined();
135
- expect(transaction.maxPriorityFeePerGas).toBeDefined();
136
- expect(transaction.authorizationList).toBeDefined();
137
- expect(transaction.authorizationList).toHaveLength(1);
138
-
139
- // Verify EIP-1559 fields are used (not gasPrice)
140
- expect(transaction.gasPrice).toBeUndefined();
141
- });
142
-
143
- test('should handle empty authorization list validation', () => {
144
- // This should be caught by validation in the actual implementation
145
- const createInvalidTransaction = () => {
146
- const transaction: EVMTransactionEIP7702 = {
147
- to: '0x7314e0f1c0e28474bdb6be3e2c3e0453255188f8',
148
- value: '0xf4240',
149
- gasLimit: '0x5208',
150
- nonce: '0x0',
151
- chainId: 1,
152
- maxFeePerGas: '0xbebc200',
153
- maxPriorityFeePerGas: '0x9502f900',
154
- authorizationList: [], // Empty authorization list
155
- };
156
- return transaction;
157
- };
158
-
159
- const invalidTx = createInvalidTransaction();
160
- expect(invalidTx.authorizationList).toHaveLength(0);
161
- // In actual implementation, this should be validated and throw an error
162
- });
163
- });
164
-
165
- describe('EVM EIP-7702 Authorization Types', () => {
166
- test('should create authorization with all fields', () => {
167
- const authorization: EVMAuthorization = {
168
- addressN: [44, 60, 0, 0, 0],
169
- chainId: 1,
170
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
171
- nonce: '0x0',
172
- signature: {
173
- yParity: 0,
174
- r: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
175
- s: '0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321',
176
- },
177
- };
178
-
179
- expect(authorization.addressN).toEqual([44, 60, 0, 0, 0]);
180
- expect(authorization.chainId).toBe(1);
181
- expect(authorization.address).toBe('0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb');
182
- expect(authorization.nonce).toBe('0x0');
183
- expect(authorization.signature?.yParity).toBe(0);
184
- expect(authorization.signature?.r).toMatch(/^0x[0-9a-f]{64}$/i);
185
- expect(authorization.signature?.s).toMatch(/^0x[0-9a-f]{64}$/i);
186
- });
187
-
188
- test('should create authorization without addressN (external signature)', () => {
189
- const authorization: EVMAuthorization = {
190
- chainId: 1,
191
- address: '0x80296FF8D1ED46f8e3C7992664D13B833504c2Bb',
192
- nonce: '0x0',
193
- signature: {
194
- yParity: 1,
195
- r: '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
196
- s: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
197
- },
198
- };
199
-
200
- expect(authorization.addressN).toBeUndefined();
201
- expect(authorization.signature).toBeDefined();
202
- });
203
-
204
- test('should validate authorization signature format', () => {
205
- const signature: EVMAuthorizationSignature = {
206
- yParity: 0,
207
- r: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
208
- s: '0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321',
209
- };
210
-
211
- expect(signature.yParity).toBeGreaterThanOrEqual(0);
212
- expect(signature.yParity).toBeLessThanOrEqual(1);
213
- expect(signature.r).toMatch(/^0x[0-9a-f]{64}$/i);
214
- expect(signature.s).toMatch(/^0x[0-9a-f]{64}$/i);
215
- });
216
- });