@metamask/eth-hd-keyring 5.0.1 → 6.0.0
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/CHANGELOG.md +8 -3
- package/index.js +6 -1
- package/package.json +1 -1
- package/test/index.js +64 -37
package/CHANGELOG.md
CHANGED
|
@@ -6,11 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
## [
|
|
9
|
+
## [6.0.0]
|
|
10
|
+
### Changed
|
|
11
|
+
- Revert mnemonic serialization format from `Record<number, number>` (i.e. a stringified `Uint8Array`) which was introduced in v5.0.0 back to an untyped array of utf8 encoded bytes, which was the format prior to v5.0.0 ([#81](https://github.com/MetaMask/eth-hd-keyring/pull/81))
|
|
12
|
+
|
|
13
|
+
## [5.0.1] [DEPRECATED]
|
|
10
14
|
### Removed
|
|
11
15
|
- Remove prepack script and references in order to fix publish release flow ([#77](https://github.com/MetaMask/eth-hd-keyring/pull/77))
|
|
12
16
|
|
|
13
|
-
## [5.0.0]
|
|
17
|
+
## [5.0.0] [DEPRECATED]
|
|
14
18
|
### Changed
|
|
15
19
|
- **BREAKING**: Update minimum Node.js version from v12 to v14 ([#67](https://github.com/MetaMask/eth-hd-keyring/pull/67))
|
|
16
20
|
- **BREAKING:** Makes version-specific `signTypedData` methods private ([#71](https://github.com/MetaMask/eth-hd-keyring/pull/71))
|
|
@@ -54,7 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
54
58
|
- Deserialize method (and `HdKeyring` constructor by extension) can no longer be passed an options object containing a value for `numberOfAccounts` if it is not also containing a value for `mnemonic`.
|
|
55
59
|
- Package name changed from `eth-hd-keyring` to `@metamask/eth-hd-keyring`.
|
|
56
60
|
|
|
57
|
-
[Unreleased]: https://github.com/MetaMask/eth-hd-keyring/compare/
|
|
61
|
+
[Unreleased]: https://github.com/MetaMask/eth-hd-keyring/compare/v6.0.0...HEAD
|
|
62
|
+
[6.0.0]: https://github.com/MetaMask/eth-hd-keyring/compare/v5.0.1...v6.0.0
|
|
58
63
|
[5.0.1]: https://github.com/MetaMask/eth-hd-keyring/compare/v5.0.0...v5.0.1
|
|
59
64
|
[5.0.0]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.2...v5.0.0
|
|
60
65
|
[4.0.2]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.1...v4.0.2
|
package/index.js
CHANGED
|
@@ -80,8 +80,13 @@ class HdKeyring {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
serialize() {
|
|
83
|
+
const mnemonicAsString = this._uint8ArrayToString(this.mnemonic);
|
|
84
|
+
const uint8ArrayMnemonic = new TextEncoder('utf-8').encode(
|
|
85
|
+
mnemonicAsString,
|
|
86
|
+
);
|
|
87
|
+
|
|
83
88
|
return Promise.resolve({
|
|
84
|
-
mnemonic:
|
|
89
|
+
mnemonic: Array.from(uint8ArrayMnemonic),
|
|
85
90
|
numberOfAccounts: this._wallets.length,
|
|
86
91
|
hdPath: this.hdPath,
|
|
87
92
|
});
|
package/package.json
CHANGED
package/test/index.js
CHANGED
|
@@ -37,11 +37,6 @@ const secondAcct = '0x1b00aed43a693f3a957f9feb5cc08afa031e37a0';
|
|
|
37
37
|
const notKeyringAddress = '0xbD20F6F5F1616947a39E11926E78ec94817B3931';
|
|
38
38
|
|
|
39
39
|
describe('hd-keyring', () => {
|
|
40
|
-
let keyring;
|
|
41
|
-
beforeEach(() => {
|
|
42
|
-
keyring = new HdKeyring();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
40
|
describe('compare old bip39 implementation with new', () => {
|
|
46
41
|
it('should derive the same accounts from the same mnemonics', async () => {
|
|
47
42
|
const mnemonics = [];
|
|
@@ -70,7 +65,7 @@ describe('hd-keyring', () => {
|
|
|
70
65
|
|
|
71
66
|
describe('constructor', () => {
|
|
72
67
|
it('constructs with a typeof string mnemonic', async () => {
|
|
73
|
-
keyring = new HdKeyring({
|
|
68
|
+
const keyring = new HdKeyring({
|
|
74
69
|
mnemonic: sampleMnemonic,
|
|
75
70
|
numberOfAccounts: 2,
|
|
76
71
|
});
|
|
@@ -81,7 +76,7 @@ describe('hd-keyring', () => {
|
|
|
81
76
|
});
|
|
82
77
|
|
|
83
78
|
it('constructs with a typeof buffer mnemonic', async () => {
|
|
84
|
-
keyring = new HdKeyring({
|
|
79
|
+
const keyring = new HdKeyring({
|
|
85
80
|
mnemonic: Buffer.from(sampleMnemonic, 'utf8'),
|
|
86
81
|
numberOfAccounts: 2,
|
|
87
82
|
});
|
|
@@ -98,7 +93,7 @@ describe('hd-keyring', () => {
|
|
|
98
93
|
const uInt8ArrayOfMnemonic = new Uint8Array(
|
|
99
94
|
new Uint16Array(indices).buffer,
|
|
100
95
|
);
|
|
101
|
-
keyring = new HdKeyring({
|
|
96
|
+
const keyring = new HdKeyring({
|
|
102
97
|
mnemonic: uInt8ArrayOfMnemonic,
|
|
103
98
|
numberOfAccounts: 2,
|
|
104
99
|
});
|
|
@@ -134,6 +129,7 @@ describe('hd-keyring', () => {
|
|
|
134
129
|
const alreadyProvidedError =
|
|
135
130
|
'Eth-Hd-Keyring: Secret recovery phrase already provided';
|
|
136
131
|
it('double generateRandomMnemonic', () => {
|
|
132
|
+
const keyring = new HdKeyring();
|
|
137
133
|
keyring.generateRandomMnemonic();
|
|
138
134
|
expect(() => {
|
|
139
135
|
keyring.generateRandomMnemonic();
|
|
@@ -141,7 +137,7 @@ describe('hd-keyring', () => {
|
|
|
141
137
|
});
|
|
142
138
|
|
|
143
139
|
it('constructor + generateRandomMnemonic', () => {
|
|
144
|
-
keyring = new HdKeyring({
|
|
140
|
+
const keyring = new HdKeyring({
|
|
145
141
|
mnemonic: sampleMnemonic,
|
|
146
142
|
numberOfAccounts: 2,
|
|
147
143
|
});
|
|
@@ -152,7 +148,7 @@ describe('hd-keyring', () => {
|
|
|
152
148
|
});
|
|
153
149
|
|
|
154
150
|
it('constructor + deserialize', () => {
|
|
155
|
-
keyring = new HdKeyring({
|
|
151
|
+
const keyring = new HdKeyring({
|
|
156
152
|
mnemonic: sampleMnemonic,
|
|
157
153
|
numberOfAccounts: 2,
|
|
158
154
|
});
|
|
@@ -175,6 +171,8 @@ describe('hd-keyring', () => {
|
|
|
175
171
|
|
|
176
172
|
describe('#type', () => {
|
|
177
173
|
it('returns the correct value', () => {
|
|
174
|
+
const keyring = new HdKeyring();
|
|
175
|
+
|
|
178
176
|
const { type } = keyring;
|
|
179
177
|
const correct = HdKeyring.type;
|
|
180
178
|
expect(type).toStrictEqual(correct);
|
|
@@ -182,39 +180,46 @@ describe('hd-keyring', () => {
|
|
|
182
180
|
});
|
|
183
181
|
|
|
184
182
|
describe('#serialize mnemonic.', () => {
|
|
185
|
-
it('serializes mnemonic
|
|
186
|
-
keyring
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
it('serializes the mnemonic in the same format as previous version (an array of utf8 encoded bytes)', async () => {
|
|
184
|
+
const keyring = new HdKeyring({
|
|
185
|
+
mnemonic: sampleMnemonic,
|
|
186
|
+
});
|
|
187
|
+
// uses previous version of eth-hd-keyring to ensure backwards compatibility
|
|
188
|
+
const oldHDKeyring = new OldHdKeyring({ mnemonic: sampleMnemonic });
|
|
189
|
+
const { mnemonic: oldKeyringSerializedMnemonic } =
|
|
190
|
+
await oldHDKeyring.serialize();
|
|
191
|
+
|
|
190
192
|
const output = await keyring.serialize();
|
|
191
|
-
expect(output.
|
|
192
|
-
expect(output.mnemonic).toStrictEqual(mnemonicAsUint8Array);
|
|
193
|
+
expect(output.mnemonic).toStrictEqual(oldKeyringSerializedMnemonic);
|
|
193
194
|
});
|
|
194
195
|
|
|
195
|
-
it('serializes
|
|
196
|
-
keyring
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
keyring.addAccounts(1);
|
|
196
|
+
it('serializes mnemonic passed in as a string to an array of utf8 encoded bytes', async () => {
|
|
197
|
+
const keyring = new HdKeyring({
|
|
198
|
+
mnemonic: sampleMnemonic,
|
|
199
|
+
});
|
|
200
200
|
const output = await keyring.serialize();
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
expect(
|
|
201
|
+
// this Buffer.from(...).toString() is the method of converting from an array of utf8 encoded bytes back to a string
|
|
202
|
+
const mnemonicAsString = Buffer.from(output.mnemonic).toString();
|
|
203
|
+
expect(mnemonicAsString).toStrictEqual(sampleMnemonic);
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
it('serializes mnemonic
|
|
207
|
-
|
|
206
|
+
it('serializes mnemonic passed in as a an array of utf8 encoded bytes in the same format', async () => {
|
|
207
|
+
const uint8Array = new TextEncoder('utf-8').encode(sampleMnemonic);
|
|
208
|
+
const mnemonicAsArrayOfUtf8EncodedBytes = Array.from(uint8Array);
|
|
209
|
+
const keyring = new HdKeyring({
|
|
210
|
+
mnemonic: mnemonicAsArrayOfUtf8EncodedBytes,
|
|
211
|
+
});
|
|
212
|
+
|
|
208
213
|
const output = await keyring.serialize();
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
);
|
|
214
|
+
// this Buffer.from(...).toString() is the method of converting from an array of utf8 encoded bytes back to a string
|
|
215
|
+
const mnemonicAsString = Buffer.from(output.mnemonic).toString();
|
|
216
|
+
expect(mnemonicAsString).toStrictEqual(sampleMnemonic);
|
|
213
217
|
});
|
|
214
218
|
});
|
|
215
219
|
|
|
216
220
|
describe('#deserialize a private key', () => {
|
|
217
221
|
it('serializes what it deserializes', async () => {
|
|
222
|
+
const keyring = new HdKeyring();
|
|
218
223
|
await keyring.deserialize({
|
|
219
224
|
mnemonic: sampleMnemonic,
|
|
220
225
|
numberOfAccounts: 1,
|
|
@@ -228,7 +233,7 @@ describe('hd-keyring', () => {
|
|
|
228
233
|
expect(accountsSecondCheck[1]).toStrictEqual(secondAcct);
|
|
229
234
|
expect(accountsSecondCheck).toHaveLength(2);
|
|
230
235
|
const serialized = await keyring.serialize();
|
|
231
|
-
expect(
|
|
236
|
+
expect(Buffer.from(serialized.mnemonic).toString()).toStrictEqual(
|
|
232
237
|
sampleMnemonic,
|
|
233
238
|
);
|
|
234
239
|
});
|
|
@@ -237,6 +242,7 @@ describe('hd-keyring', () => {
|
|
|
237
242
|
describe('#addAccounts', () => {
|
|
238
243
|
describe('with no arguments', () => {
|
|
239
244
|
it('creates a single wallet', async () => {
|
|
245
|
+
const keyring = new HdKeyring();
|
|
240
246
|
keyring.generateRandomMnemonic();
|
|
241
247
|
await keyring.addAccounts();
|
|
242
248
|
const accounts = await keyring.getAccounts();
|
|
@@ -244,6 +250,7 @@ describe('hd-keyring', () => {
|
|
|
244
250
|
});
|
|
245
251
|
|
|
246
252
|
it('throws an error when no SRP has been generated yet', async () => {
|
|
253
|
+
const keyring = new HdKeyring();
|
|
247
254
|
expect(() => keyring.addAccounts()).toThrow(
|
|
248
255
|
'Eth-Hd-Keyring: No secret recovery phrase provided',
|
|
249
256
|
);
|
|
@@ -252,6 +259,7 @@ describe('hd-keyring', () => {
|
|
|
252
259
|
|
|
253
260
|
describe('with a numeric argument', () => {
|
|
254
261
|
it('creates that number of wallets', async () => {
|
|
262
|
+
const keyring = new HdKeyring();
|
|
255
263
|
keyring.generateRandomMnemonic();
|
|
256
264
|
await keyring.addAccounts(3);
|
|
257
265
|
const accounts = await keyring.getAccounts();
|
|
@@ -262,6 +270,8 @@ describe('hd-keyring', () => {
|
|
|
262
270
|
|
|
263
271
|
describe('#signPersonalMessage', () => {
|
|
264
272
|
it('returns the expected value', async () => {
|
|
273
|
+
const keyring = new HdKeyring();
|
|
274
|
+
|
|
265
275
|
const address = firstAcct;
|
|
266
276
|
const message = '0x68656c6c6f20776f726c64';
|
|
267
277
|
|
|
@@ -283,8 +293,8 @@ describe('hd-keyring', () => {
|
|
|
283
293
|
|
|
284
294
|
describe('#signTypedData', () => {
|
|
285
295
|
it('can recover a basic signature', async () => {
|
|
296
|
+
const keyring = new HdKeyring();
|
|
286
297
|
Buffer.from(privKeyHex, 'hex');
|
|
287
|
-
|
|
288
298
|
const typedData = [
|
|
289
299
|
{
|
|
290
300
|
type: 'string',
|
|
@@ -316,6 +326,7 @@ describe('hd-keyring', () => {
|
|
|
316
326
|
];
|
|
317
327
|
|
|
318
328
|
it('signs in a compliant and recoverable way', async () => {
|
|
329
|
+
const keyring = new HdKeyring();
|
|
319
330
|
keyring.generateRandomMnemonic();
|
|
320
331
|
await keyring.addAccounts(1);
|
|
321
332
|
const addresses = await keyring.getAccounts();
|
|
@@ -334,6 +345,7 @@ describe('hd-keyring', () => {
|
|
|
334
345
|
|
|
335
346
|
describe('#signTypedData_v3', () => {
|
|
336
347
|
it('signs in a compliant and recoverable way', async () => {
|
|
348
|
+
const keyring = new HdKeyring();
|
|
337
349
|
const typedData = {
|
|
338
350
|
types: {
|
|
339
351
|
EIP712Domain: [],
|
|
@@ -363,6 +375,7 @@ describe('hd-keyring', () => {
|
|
|
363
375
|
|
|
364
376
|
describe('#signTypedData_v3 signature verification', () => {
|
|
365
377
|
it('signs in a recoverable way.', async () => {
|
|
378
|
+
const keyring = new HdKeyring();
|
|
366
379
|
const typedData = {
|
|
367
380
|
types: {
|
|
368
381
|
EIP712Domain: [
|
|
@@ -419,6 +432,7 @@ describe('hd-keyring', () => {
|
|
|
419
432
|
|
|
420
433
|
describe('custom hd paths', () => {
|
|
421
434
|
it('can deserialize with an hdPath param and generate the same accounts.', async () => {
|
|
435
|
+
const keyring = new HdKeyring();
|
|
422
436
|
const hdPathString = `m/44'/60'/0'/0`;
|
|
423
437
|
keyring.deserialize({
|
|
424
438
|
mnemonic: sampleMnemonic,
|
|
@@ -432,8 +446,8 @@ describe('hd-keyring', () => {
|
|
|
432
446
|
});
|
|
433
447
|
|
|
434
448
|
it('can deserialize with an hdPath param and generate different accounts.', async () => {
|
|
449
|
+
const keyring = new HdKeyring();
|
|
435
450
|
const hdPathString = `m/44'/60'/0'/1`;
|
|
436
|
-
|
|
437
451
|
keyring.deserialize({
|
|
438
452
|
mnemonic: sampleMnemonic,
|
|
439
453
|
numberOfAccounts: 1,
|
|
@@ -454,14 +468,14 @@ describe('hd-keyring', () => {
|
|
|
454
468
|
|
|
455
469
|
for (let i = 0; i < 1e3; i++) {
|
|
456
470
|
|
|
457
|
-
keyring = new HdKeyring({
|
|
471
|
+
const keyring = new HdKeyring({
|
|
458
472
|
numberOfAccounts: 1,
|
|
459
473
|
})
|
|
460
474
|
const originalAccounts = await keyring.getAccounts()
|
|
461
475
|
const serialized = await keyring.serialize()
|
|
462
476
|
const mnemonic = serialized.mnemonic
|
|
463
477
|
|
|
464
|
-
keyring = new HdKeyring({
|
|
478
|
+
const keyring = new HdKeyring({
|
|
465
479
|
numberOfAccounts: 1,
|
|
466
480
|
mnemonic,
|
|
467
481
|
})
|
|
@@ -481,6 +495,7 @@ describe('hd-keyring', () => {
|
|
|
481
495
|
|
|
482
496
|
describe('signing methods withAppKeyOrigin option', () => {
|
|
483
497
|
it('should signPersonalMessage with the expected key when passed a withAppKeyOrigin', async () => {
|
|
498
|
+
const keyring = new HdKeyring();
|
|
484
499
|
const address = firstAcct;
|
|
485
500
|
const message = '0x68656c6c6f20776f726c64';
|
|
486
501
|
|
|
@@ -502,6 +517,7 @@ describe('hd-keyring', () => {
|
|
|
502
517
|
});
|
|
503
518
|
|
|
504
519
|
it('should signTypedData with the expected key when passed a withAppKeyOrigin', async () => {
|
|
520
|
+
const keyring = new HdKeyring();
|
|
505
521
|
const address = firstAcct;
|
|
506
522
|
const typedData = {
|
|
507
523
|
types: {
|
|
@@ -546,6 +562,7 @@ describe('hd-keyring', () => {
|
|
|
546
562
|
'0xb21867b2221db0172e970b7370825b71c57823ff8714168ce9748f32f450e2c43d0fe396eb5b5f59284b7fd108c8cf61a6180a6756bdd3d4b7b9ccc4ac6d51611b';
|
|
547
563
|
|
|
548
564
|
it('passes the dennis test', async function () {
|
|
565
|
+
const keyring = new HdKeyring();
|
|
549
566
|
await keyring.deserialize({
|
|
550
567
|
mnemonic: sampleMnemonic,
|
|
551
568
|
numberOfAccounts: 1,
|
|
@@ -555,6 +572,7 @@ describe('hd-keyring', () => {
|
|
|
555
572
|
});
|
|
556
573
|
|
|
557
574
|
it('reliably can decode messages it signs', async function () {
|
|
575
|
+
const keyring = new HdKeyring();
|
|
558
576
|
await keyring.deserialize({
|
|
559
577
|
mnemonic: sampleMnemonic,
|
|
560
578
|
numberOfAccounts: 1,
|
|
@@ -583,6 +601,7 @@ describe('hd-keyring', () => {
|
|
|
583
601
|
});
|
|
584
602
|
|
|
585
603
|
it('throw error for invalid message', async function () {
|
|
604
|
+
const keyring = new HdKeyring();
|
|
586
605
|
await keyring.deserialize({
|
|
587
606
|
mnemonic: sampleMnemonic,
|
|
588
607
|
numberOfAccounts: 1,
|
|
@@ -594,6 +613,7 @@ describe('hd-keyring', () => {
|
|
|
594
613
|
});
|
|
595
614
|
|
|
596
615
|
it('throw error if empty address is passed', async function () {
|
|
616
|
+
const keyring = new HdKeyring();
|
|
597
617
|
await keyring.deserialize({
|
|
598
618
|
mnemonic: sampleMnemonic,
|
|
599
619
|
numberOfAccounts: 1,
|
|
@@ -605,6 +625,7 @@ describe('hd-keyring', () => {
|
|
|
605
625
|
});
|
|
606
626
|
|
|
607
627
|
it('throw error if address not associated with the current keyring is passed', async function () {
|
|
628
|
+
const keyring = new HdKeyring();
|
|
608
629
|
await keyring.deserialize({
|
|
609
630
|
mnemonic: sampleMnemonic,
|
|
610
631
|
numberOfAccounts: 1,
|
|
@@ -617,6 +638,7 @@ describe('hd-keyring', () => {
|
|
|
617
638
|
});
|
|
618
639
|
|
|
619
640
|
describe('#removeAccount', function () {
|
|
641
|
+
let keyring;
|
|
620
642
|
beforeEach(() => {
|
|
621
643
|
keyring = new HdKeyring({
|
|
622
644
|
mnemonic: sampleMnemonic,
|
|
@@ -645,6 +667,7 @@ describe('hd-keyring', () => {
|
|
|
645
667
|
});
|
|
646
668
|
|
|
647
669
|
describe('getAppKeyAddress', function () {
|
|
670
|
+
let keyring;
|
|
648
671
|
beforeEach(() => {
|
|
649
672
|
keyring = new HdKeyring({
|
|
650
673
|
mnemonic: sampleMnemonic,
|
|
@@ -710,6 +733,7 @@ describe('hd-keyring', () => {
|
|
|
710
733
|
});
|
|
711
734
|
|
|
712
735
|
describe('exportAccount', function () {
|
|
736
|
+
let keyring;
|
|
713
737
|
beforeEach(() => {
|
|
714
738
|
keyring = new HdKeyring({
|
|
715
739
|
mnemonic: sampleMnemonic,
|
|
@@ -734,6 +758,7 @@ describe('hd-keyring', () => {
|
|
|
734
758
|
|
|
735
759
|
describe('#encryptionPublicKey', function () {
|
|
736
760
|
const publicKey = 'LV7lWhd0mUDcvxkMU2o6uKXftu25zq4bMYdmMqppXic=';
|
|
761
|
+
let keyring;
|
|
737
762
|
beforeEach(() => {
|
|
738
763
|
keyring = new HdKeyring({
|
|
739
764
|
mnemonic: sampleMnemonic,
|
|
@@ -762,6 +787,7 @@ describe('hd-keyring', () => {
|
|
|
762
787
|
});
|
|
763
788
|
|
|
764
789
|
describe('#signTypedData V4 signature verification', function () {
|
|
790
|
+
let keyring;
|
|
765
791
|
beforeEach(() => {
|
|
766
792
|
keyring = new HdKeyring({
|
|
767
793
|
mnemonic: sampleMnemonic,
|
|
@@ -842,7 +868,7 @@ describe('hd-keyring', () => {
|
|
|
842
868
|
|
|
843
869
|
describe('#decryptMessage', function () {
|
|
844
870
|
const message = 'Hello world!';
|
|
845
|
-
let encryptedMessage;
|
|
871
|
+
let encryptedMessage, keyring;
|
|
846
872
|
|
|
847
873
|
beforeEach(async () => {
|
|
848
874
|
keyring = new HdKeyring({
|
|
@@ -882,6 +908,7 @@ describe('hd-keyring', () => {
|
|
|
882
908
|
});
|
|
883
909
|
|
|
884
910
|
describe('#signTransaction', function () {
|
|
911
|
+
let keyring;
|
|
885
912
|
beforeEach(() => {
|
|
886
913
|
keyring = new HdKeyring({
|
|
887
914
|
mnemonic: sampleMnemonic,
|