From 4f31e8e1a1f16f36d28e76ab7ecceb4e5ab17df3 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Fri, 21 Jun 2019 13:06:05 -0700 Subject: [PATCH 1/4] Trim whitespce on seed verify words. --- src/action/wallet.js | 2 +- test/unit/action/wallet.spec.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/action/wallet.js b/src/action/wallet.js index 9a3adf61f..ae20e7fa7 100644 --- a/src/action/wallet.js +++ b/src/action/wallet.js @@ -43,7 +43,7 @@ class WalletAction { * @param {number} options.index The seed index */ setSeedVerify({ word = '', index }) { - this._store.wallet.seedVerify[index] = word.toLowerCase(); + this._store.wallet.seedVerify[index] = word.toLowerCase().trim(); } /** diff --git a/test/unit/action/wallet.spec.js b/test/unit/action/wallet.spec.js index 235e27d89..ecbb19098 100644 --- a/test/unit/action/wallet.spec.js +++ b/test/unit/action/wallet.spec.js @@ -58,6 +58,11 @@ describe('Action Wallet Unit Tests', () => { wallet.setSeedVerify({ word: 'FOO', index: 1 }); expect(store.wallet.seedVerify[1], 'to equal', 'foo'); }); + + it('should trim whitespace', () => { + wallet.setSeedVerify({ word: ' foo ', index: 1 }); + expect(store.wallet.seedVerify[1], 'to equal', 'foo'); + }); }); describe('initSetPassword()', () => { From d611a5a9668ef9e70472cc1da51de4abd69523c3 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Fri, 21 Jun 2019 13:07:57 -0700 Subject: [PATCH 2/4] Fix blank seed error: don't reuse seed store prop for restore seed --- src/action/index-mobile.js | 1 + src/action/wallet.js | 8 +++++--- src/store.js | 1 + src/view/restore-seed-mobile.js | 2 +- src/view/restore-seed.js | 2 +- test/unit/action/wallet.spec.js | 12 +++++++----- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/action/index-mobile.js b/src/action/index-mobile.js index 5f55559ae..751ee26a0 100644 --- a/src/action/index-mobile.js +++ b/src/action/index-mobile.js @@ -242,6 +242,7 @@ store.seedMnemonic = [ 'quit', 'cashew', ]; +store.restoreSeedMnemonic = Array(24).fill(''); store.logs = [ '[14:00:24.995] [info] Using lnd in path lnd', 'Checking for update', diff --git a/src/action/wallet.js b/src/action/wallet.js index ae20e7fa7..0530e6ccd 100644 --- a/src/action/wallet.js +++ b/src/action/wallet.js @@ -53,7 +53,7 @@ class WalletAction { * @param {number} options.index The seed index */ setRestoreSeed({ word, index }) { - this._store.seedMnemonic[index] = word.trim(); + this._store.restoreSeedMnemonic[index] = word.trim(); } /** @@ -221,7 +221,9 @@ class WalletAction { await this.initWallet({ walletPassword: newPassword, recoveryWindow: this._store.settings.restoring ? RECOVERY_WINDOW : 0, - seedMnemonic: this._store.seedMnemonic.toJSON(), + seedMnemonic: this._store.settings.restoring + ? this._store.restoreSeedMnemonic.toJSON() + : this._store.seedMnemonic.toJSON(), }); } @@ -320,7 +322,7 @@ class WalletAction { * @return {undefined} */ initRestoreWallet() { - this._store.seedMnemonic = Array(24).fill(''); + this._store.restoreSeedMnemonic = Array(24).fill(''); this._store.wallet.restoreIndex = 0; this._nav.goRestoreSeed(); } diff --git a/src/store.js b/src/store.js index 9d413844b..dbcae7840 100644 --- a/src/store.js +++ b/src/store.js @@ -82,6 +82,7 @@ export class Store { }, paymentRequest: null, seedMnemonic: [], + restoreSeedMnemonic: [], notifications: [], unseenNtfnCount: 0, logs: '', diff --git a/src/view/restore-seed-mobile.js b/src/view/restore-seed-mobile.js index 4ec0d6e61..410ce23b7 100644 --- a/src/view/restore-seed-mobile.js +++ b/src/view/restore-seed-mobile.js @@ -57,7 +57,7 @@ const RestoreSeedView = ({ store, wallet }) => ( {store.restoreVerifyIndexes.map((seedIndex, i) => ( wallet.setRestoreSeed({ word, index: seedIndex - 1 }) } diff --git a/src/view/restore-seed.js b/src/view/restore-seed.js index 944e49c85..43725123a 100644 --- a/src/view/restore-seed.js +++ b/src/view/restore-seed.js @@ -47,7 +47,7 @@ const RestoreSeedView = ({ store, wallet }) => ( {store.restoreVerifyIndexes.map((seedIndex, i) => ( wallet.setRestoreSeed({ word, index: seedIndex - 1 }) } diff --git a/test/unit/action/wallet.spec.js b/test/unit/action/wallet.spec.js index ecbb19098..7a3b222a4 100644 --- a/test/unit/action/wallet.spec.js +++ b/test/unit/action/wallet.spec.js @@ -242,13 +242,15 @@ describe('Action Wallet Unit Tests', () => { }); it('init wallet correctly during restore', async () => { + const restoreSeed = ['hi', 'hello', 'hola']; + store.restoreSeedMnemonic = restoreSeed; store.settings.restoring = true; wallet.setNewPassword({ password: 'secret123' }); wallet.setPasswordVerify({ password: 'secret123' }); await wallet.checkNewPassword(); expect(wallet.initWallet, 'was called with', { walletPassword: 'secret123', - seedMnemonic: ['foo', 'bar', 'baz'], + seedMnemonic: restoreSeed, recoveryWindow: RECOVERY_WINDOW, }); }); @@ -372,7 +374,7 @@ describe('Action Wallet Unit Tests', () => { it('should clear attributes and navigate to view', () => { store.wallet.restoreIndex = 42; wallet.initRestoreWallet(); - expect(store.seedMnemonic.length, 'to equal', 24); + expect(store.restoreSeedMnemonic.length, 'to equal', 24); expect(store.wallet.restoreIndex, 'to equal', 0); expect(nav.goRestoreSeed, 'was called once'); }); @@ -380,17 +382,17 @@ describe('Action Wallet Unit Tests', () => { describe('setRestoreSeed()', () => { beforeEach(() => { - store.seedMnemonic = Array(24).fill(''); + store.restoreSeedMnemonic = Array(24).fill(''); }); it('should clear attributes', () => { wallet.setRestoreSeed({ word: 'foo', index: 1 }); - expect(store.seedMnemonic[1], 'to equal', 'foo'); + expect(store.restoreSeedMnemonic[1], 'to equal', 'foo'); }); it('should trim whitespace', () => { wallet.setRestoreSeed({ word: ' foo ', index: 1 }); - expect(store.seedMnemonic[1], 'to equal', 'foo'); + expect(store.restoreSeedMnemonic[1], 'to equal', 'foo'); }); }); From 0e2ff9265f7671f3e345d26b436a36f950b6ddad Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Mon, 1 Jul 2019 14:49:36 -0700 Subject: [PATCH 3/4] Revert "Fix blank seed error: don't reuse seed store prop for restore seed" This reverts commit d611a5a9668ef9e70472cc1da51de4abd69523c3. --- src/action/index-mobile.js | 1 - src/action/wallet.js | 8 +++----- src/store.js | 1 - src/view/restore-seed-mobile.js | 2 +- src/view/restore-seed.js | 2 +- test/unit/action/wallet.spec.js | 12 +++++------- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/action/index-mobile.js b/src/action/index-mobile.js index 751ee26a0..5f55559ae 100644 --- a/src/action/index-mobile.js +++ b/src/action/index-mobile.js @@ -242,7 +242,6 @@ store.seedMnemonic = [ 'quit', 'cashew', ]; -store.restoreSeedMnemonic = Array(24).fill(''); store.logs = [ '[14:00:24.995] [info] Using lnd in path lnd', 'Checking for update', diff --git a/src/action/wallet.js b/src/action/wallet.js index 0530e6ccd..ae20e7fa7 100644 --- a/src/action/wallet.js +++ b/src/action/wallet.js @@ -53,7 +53,7 @@ class WalletAction { * @param {number} options.index The seed index */ setRestoreSeed({ word, index }) { - this._store.restoreSeedMnemonic[index] = word.trim(); + this._store.seedMnemonic[index] = word.trim(); } /** @@ -221,9 +221,7 @@ class WalletAction { await this.initWallet({ walletPassword: newPassword, recoveryWindow: this._store.settings.restoring ? RECOVERY_WINDOW : 0, - seedMnemonic: this._store.settings.restoring - ? this._store.restoreSeedMnemonic.toJSON() - : this._store.seedMnemonic.toJSON(), + seedMnemonic: this._store.seedMnemonic.toJSON(), }); } @@ -322,7 +320,7 @@ class WalletAction { * @return {undefined} */ initRestoreWallet() { - this._store.restoreSeedMnemonic = Array(24).fill(''); + this._store.seedMnemonic = Array(24).fill(''); this._store.wallet.restoreIndex = 0; this._nav.goRestoreSeed(); } diff --git a/src/store.js b/src/store.js index dbcae7840..9d413844b 100644 --- a/src/store.js +++ b/src/store.js @@ -82,7 +82,6 @@ export class Store { }, paymentRequest: null, seedMnemonic: [], - restoreSeedMnemonic: [], notifications: [], unseenNtfnCount: 0, logs: '', diff --git a/src/view/restore-seed-mobile.js b/src/view/restore-seed-mobile.js index 410ce23b7..4ec0d6e61 100644 --- a/src/view/restore-seed-mobile.js +++ b/src/view/restore-seed-mobile.js @@ -57,7 +57,7 @@ const RestoreSeedView = ({ store, wallet }) => ( {store.restoreVerifyIndexes.map((seedIndex, i) => ( wallet.setRestoreSeed({ word, index: seedIndex - 1 }) } diff --git a/src/view/restore-seed.js b/src/view/restore-seed.js index 43725123a..944e49c85 100644 --- a/src/view/restore-seed.js +++ b/src/view/restore-seed.js @@ -47,7 +47,7 @@ const RestoreSeedView = ({ store, wallet }) => ( {store.restoreVerifyIndexes.map((seedIndex, i) => ( wallet.setRestoreSeed({ word, index: seedIndex - 1 }) } diff --git a/test/unit/action/wallet.spec.js b/test/unit/action/wallet.spec.js index 7a3b222a4..ecbb19098 100644 --- a/test/unit/action/wallet.spec.js +++ b/test/unit/action/wallet.spec.js @@ -242,15 +242,13 @@ describe('Action Wallet Unit Tests', () => { }); it('init wallet correctly during restore', async () => { - const restoreSeed = ['hi', 'hello', 'hola']; - store.restoreSeedMnemonic = restoreSeed; store.settings.restoring = true; wallet.setNewPassword({ password: 'secret123' }); wallet.setPasswordVerify({ password: 'secret123' }); await wallet.checkNewPassword(); expect(wallet.initWallet, 'was called with', { walletPassword: 'secret123', - seedMnemonic: restoreSeed, + seedMnemonic: ['foo', 'bar', 'baz'], recoveryWindow: RECOVERY_WINDOW, }); }); @@ -374,7 +372,7 @@ describe('Action Wallet Unit Tests', () => { it('should clear attributes and navigate to view', () => { store.wallet.restoreIndex = 42; wallet.initRestoreWallet(); - expect(store.restoreSeedMnemonic.length, 'to equal', 24); + expect(store.seedMnemonic.length, 'to equal', 24); expect(store.wallet.restoreIndex, 'to equal', 0); expect(nav.goRestoreSeed, 'was called once'); }); @@ -382,17 +380,17 @@ describe('Action Wallet Unit Tests', () => { describe('setRestoreSeed()', () => { beforeEach(() => { - store.restoreSeedMnemonic = Array(24).fill(''); + store.seedMnemonic = Array(24).fill(''); }); it('should clear attributes', () => { wallet.setRestoreSeed({ word: 'foo', index: 1 }); - expect(store.restoreSeedMnemonic[1], 'to equal', 'foo'); + expect(store.seedMnemonic[1], 'to equal', 'foo'); }); it('should trim whitespace', () => { wallet.setRestoreSeed({ word: ' foo ', index: 1 }); - expect(store.restoreSeedMnemonic[1], 'to equal', 'foo'); + expect(store.seedMnemonic[1], 'to equal', 'foo'); }); }); From a6ea615c5c4ac20f2b059b923862436ac56a24cc Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Mon, 1 Jul 2019 16:03:24 -0700 Subject: [PATCH 4/4] Generate seed when initializing seed view in case seed was cleared previously. --- src/action/index-mobile.js | 56 ++++++++++++++++++--------------- src/action/wallet.js | 3 +- src/view/select-seed.js | 4 +-- test/unit/action/wallet.spec.js | 15 ++++++--- 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/action/index-mobile.js b/src/action/index-mobile.js index 5f55559ae..8b73669ea 100644 --- a/src/action/index-mobile.js +++ b/src/action/index-mobile.js @@ -139,6 +139,36 @@ sinon.stub(channel, 'connectAndOpen'); sinon.stub(channel, 'closeSelectedChannel'); sinon.stub(autopilot, 'toggle'); +// Stub gRPC seed generation during development. +grpc.sendUnlockerCommand.withArgs('GenSeed').resolves({ + cipherSeedMnemonic: [ + 'empower', + 'neglect', + 'experience', + 'elevator', + 'entropy', + 'future', + 'trust', + 'swift', + 'pluck', + 'easy', + 'kite', + 'measure', + 'engage', + 'settle', + 'dog', + 'manager', + 'tool', + 'fan', + 'neglect', + 'conduct', + 'blouse', + 'stone', + 'quit', + 'cashew', + ], +}); + // SET SOME DUMMY DATA DURING DEVELOPMENT setTimeout( () => (store.walletAddress = 'ra2XT898gWTp9q2DwMgtwMJsUEh3oMeS4K'), @@ -216,32 +246,6 @@ store.selectedTransaction = (store.computedTransactions || []).find( tx => tx.type === 'bitcoin' ); store.selectedChannel = store.computedChannels && store.computedChannels[0]; -store.seedMnemonic = [ - 'empower', - 'neglect', - 'experience', - 'elevator', - 'entropy', - 'future', - 'trust', - 'swift', - 'pluck', - 'easy', - 'kite', - 'measure', - 'engage', - 'settle', - 'dog', - 'manager', - 'tool', - 'fan', - 'neglect', - 'conduct', - 'blouse', - 'stone', - 'quit', - 'cashew', -]; store.logs = [ '[14:00:24.995] [info] Using lnd in path lnd', 'Checking for update', diff --git a/src/action/wallet.js b/src/action/wallet.js index ae20e7fa7..902e5b8e9 100644 --- a/src/action/wallet.js +++ b/src/action/wallet.js @@ -283,8 +283,9 @@ class WalletAction { * resetting the current seed index. * @return {undefined} */ - initSeed() { + async initSeed() { this._store.wallet.seedIndex = 0; + await this.generateSeed(); this._nav.goSeedIntro ? this._nav.goSeedIntro() : this._nav.goSeed(); } diff --git a/src/view/select-seed.js b/src/view/select-seed.js index 22c82f695..86c7717e3 100644 --- a/src/view/select-seed.js +++ b/src/view/select-seed.js @@ -72,10 +72,10 @@ const SelectSeedView = ({ store, wallet, setting }) => ( + onPress={async () => store.settings.restoring ? wallet.initRestoreWallet() - : wallet.initSeed() + : await wallet.initSeed() } > Next diff --git a/test/unit/action/wallet.spec.js b/test/unit/action/wallet.spec.js index ecbb19098..591e33b62 100644 --- a/test/unit/action/wallet.spec.js +++ b/test/unit/action/wallet.spec.js @@ -321,17 +321,24 @@ describe('Action Wallet Unit Tests', () => { }); describe('initSeed()', () => { - it('should clear attributes and navigate to view', () => { + beforeEach(() => { + grpc.sendUnlockerCommand.withArgs('GenSeed').resolves({ + cipherSeedMnemonic: 'foo bar', + }); + }); + + it('should clear attributes and navigate to view', async () => { store.wallet.seedIndex = 42; - wallet.initSeed(); + await wallet.initSeed(); expect(store.wallet.seedIndex, 'to equal', 0); + expect(store.seedMnemonic, 'to equal', 'foo bar'); expect(nav.goSeed, 'was called once'); }); - it('should navigate to seed intro on mobile', () => { + it('should navigate to seed intro on mobile', async () => { nav = sinon.createStubInstance(NavActionMobile); wallet = new WalletAction(store, grpc, db, nav, notification); - wallet.initSeed(); + await wallet.initSeed(); expect(nav.goSeedIntro, 'was called once'); }); });