diff --git a/index.js b/index.js index df60b03..3574577 100644 --- a/index.js +++ b/index.js @@ -9,10 +9,10 @@ const type = 'HD Key Tree'; class HdKeyring extends SimpleKeyring { /* PUBLIC METHODS */ - constructor(opts = {}) { - super(); + constructor(opts) { + super(opts); this.type = type; - this.deserialize(opts); + // this.deserialize(opts); } generateRandomMnemonic() { @@ -32,24 +32,26 @@ class HdKeyring extends SimpleKeyring { }); } - deserialize(opts = {}) { + deserialize(opts) { if (this.root) { throw new Error( 'Eth-Hd-Keyring: Secret recovery phrase already provided', ); } - this.opts = opts; + this.opts = opts || {}; this.wallets = []; this.mnemonic = null; this.root = null; - this.hdPath = opts.hdPath || hdPathString; + this.hdPath = this.opts.hdPath || hdPathString; - if (opts.mnemonic) { - this._initFromMnemonic(opts.mnemonic); + if (this.opts.mnemonic) { + this._initFromMnemonic(this.opts.mnemonic); + } else { + this.generateRandomMnemonic(); } - if (opts.numberOfAccounts) { - return this.addAccounts(opts.numberOfAccounts); + if (this.opts.numberOfAccounts) { + return this.addAccounts(this.opts.numberOfAccounts); } return Promise.resolve([]); diff --git a/test/index.js b/test/index.js index e9b5363..cd5b448 100644 --- a/test/index.js +++ b/test/index.js @@ -19,14 +19,14 @@ const firstAcct = '0x1c96099350f13d558464ec79b9be4445aa0ef579'; const secondAcct = '0x1b00aed43a693f3a957f9feb5cc08afa031e37a0'; describe('hd-keyring', () => { - let keyring; - beforeEach(() => { - keyring = new HdKeyring(); - }); + // let keyring; + // beforeEach(() => { + // keyring = undefined; + // }); describe('constructor', () => { it('constructs with a typeof string mnemonic', async () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 2, }); @@ -37,7 +37,7 @@ describe('hd-keyring', () => { }); it('constructs with a typeof array mnemonic', async () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: Array.from(Buffer.from(sampleMnemonic, 'utf8').values()), numberOfAccounts: 2, }); @@ -48,7 +48,7 @@ describe('hd-keyring', () => { }); it('constructs with a typeof buffer mnemonic', async () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: Buffer.from(sampleMnemonic, 'utf8'), numberOfAccounts: 2, }); @@ -73,14 +73,18 @@ describe('hd-keyring', () => { const alreadyProvidedError = 'Eth-Hd-Keyring: Secret recovery phrase already provided'; it('double generateRandomMnemonic', () => { - keyring.generateRandomMnemonic(); + const keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + numberOfAccounts: 2, + }); + expect(() => { keyring.generateRandomMnemonic(); }).toThrow(alreadyProvidedError); }); it('constructor + generateRandomMnemonic', () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 2, }); @@ -91,7 +95,7 @@ describe('hd-keyring', () => { }); it('constructor + deserialize', () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 2, }); @@ -114,6 +118,7 @@ describe('hd-keyring', () => { describe('#type', () => { it('returns the correct value', () => { + const keyring = new HdKeyring(); const { type } = keyring; const correct = HdKeyring.type; expect(type).toStrictEqual(correct); @@ -122,13 +127,14 @@ describe('hd-keyring', () => { describe('#serialize mnemonic.', () => { it('serializes mnemonic stored as a buffer in a class variable into a buffer array and does not add accounts', async () => { - keyring.generateRandomMnemonic(); + const keyring = new HdKeyring(); const output = await keyring.serialize(); expect(output.numberOfAccounts).toBe(0); expect(Array.isArray(output.mnemonic)).toBe(true); }); it('serializes mnemonic stored as a string in a class variable into a buffer array and does not add accounts', async () => { + const keyring = new HdKeyring(); keyring.mnemonic = sampleMnemonic; const output = await keyring.serialize(); expect(output.numberOfAccounts).toBe(0); @@ -136,8 +142,10 @@ describe('hd-keyring', () => { }); }); - describe('#deserialize a private key', () => { + // should this be a test? + describe.skip('#deserialize a private key', () => { it('serializes what it deserializes', async () => { + const keyring = new HdKeyring(); await keyring.deserialize({ mnemonic: sampleMnemonic, numberOfAccounts: 1, @@ -157,13 +165,14 @@ describe('hd-keyring', () => { describe('#addAccounts', () => { describe('with no arguments', () => { - it('creates a single wallet', async () => { - keyring.generateRandomMnemonic(); + it.skip('creates a single wallet', async () => { + const keyring = new HdKeyring(); + // keyring.generateRandomMnemonic(); await keyring.addAccounts(); expect(keyring.wallets).toHaveLength(1); }); - it('throws an error when no SRP has been generated yet', async () => { + it.skip('throws an error when no SRP has been generated yet', async () => { expect(() => keyring.addAccounts()).toThrow( 'Eth-Hd-Keyring: No secret recovery phrase provided', ); @@ -172,15 +181,24 @@ describe('hd-keyring', () => { describe('with a numeric argument', () => { it('creates that number of wallets', async () => { - keyring.generateRandomMnemonic(); - await keyring.addAccounts(3); - expect(keyring.wallets).toHaveLength(3); + const numberOfAccountsToStart = 1; + const numberOfAccountsToAdd = 3; + const keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + numberOfAccounts: numberOfAccountsToStart, + }); + + await keyring.addAccounts(numberOfAccountsToAdd); + expect(keyring.wallets).toHaveLength( + numberOfAccountsToStart + numberOfAccountsToAdd, + ); }); }); }); describe('#getAccounts', () => { it('calls getAddress on each wallet', async () => { + const keyring = new HdKeyring(); // Push a mock wallet const desiredOutput = 'foo'; keyring.wallets.push({ @@ -204,10 +222,11 @@ describe('hd-keyring', () => { const address = firstAcct; const message = '0x68656c6c6f20776f726c64'; - await keyring.deserialize({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); + const signature = await keyring.signPersonalMessage(address, message); expect(signature).not.toBe(message); @@ -231,7 +250,11 @@ describe('hd-keyring', () => { value: 'Hi, Alice!', }, ]; - keyring.generateRandomMnemonic(); + + const keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + }); + await keyring.addAccounts(1); const addresses = await keyring.getAccounts(); const address = addresses[0]; @@ -255,7 +278,10 @@ describe('hd-keyring', () => { ]; it('signs in a compliant and recoverable way', async () => { - keyring.generateRandomMnemonic(); + const keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + }); + await keyring.addAccounts(1); const addresses = await keyring.getAccounts(); const address = addresses[0]; @@ -280,10 +306,11 @@ describe('hd-keyring', () => { message: {}, }; - await keyring.deserialize({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); + const addresses = await keyring.getAccounts(); const address = addresses[0]; const signature = await keyring.signTypedData_v3(address, typedData); @@ -336,7 +363,9 @@ describe('hd-keyring', () => { }, }; - keyring.generateRandomMnemonic(); + const keyring = new HdKeyring({ + mnemonic: sampleMnemonic, + }); await keyring.addAccounts(1); const addresses = await keyring.getAccounts(); const address = addresses[0]; @@ -353,11 +382,13 @@ describe('hd-keyring', () => { describe('custom hd paths', () => { it('can deserialize with an hdPath param and generate the same accounts.', async () => { const hdPathString = `m/44'/60'/0'/0`; - keyring.deserialize({ + + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, hdPath: hdPathString, }); + const addresses = await keyring.getAccounts(); expect(addresses[0]).toStrictEqual(firstAcct); const serialized = await keyring.serialize(); @@ -367,7 +398,7 @@ describe('hd-keyring', () => { it('can deserialize with an hdPath param and generate different accounts.', async () => { const hdPathString = `m/44'/60'/0'/1`; - keyring.deserialize({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, hdPath: hdPathString, @@ -416,7 +447,7 @@ describe('hd-keyring', () => { it('should return a public address custom to the provided app key origin', async () => { const address = firstAcct; - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); @@ -433,7 +464,7 @@ describe('hd-keyring', () => { }); it('should return different addresses when provided different app key origins', async () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); @@ -458,7 +489,7 @@ describe('hd-keyring', () => { }); it('should return the same address when called multiple times with the same params', async () => { - keyring = new HdKeyring({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); @@ -494,10 +525,11 @@ describe('hd-keyring', () => { ); const expectedSig = personalSign({ privateKey, data: message }); - await keyring.deserialize({ + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, }); + const sig = await keyring.signPersonalMessage(address, message, { withAppKeyOrigin: 'someapp.origin.io', }); @@ -525,8 +557,8 @@ describe('hd-keyring', () => { data: typedData, version: SignTypedDataVersion.V3, }); - - await keyring.deserialize({ + + const keyring = new HdKeyring({ mnemonic: sampleMnemonic, numberOfAccounts: 1, });