Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/action/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class NavAction {
this._store.route = 'Loader';
}

goSelectSeed() {
this._store.route = 'SelectSeed';
}

goSeed() {
this._store.route = 'Seed';
}
Expand All @@ -21,8 +25,12 @@ class NavAction {
this._store.route = 'SeedVerify';
}

goRestoreWallet() {
// this._store.route = 'RestoreWallet';
goRestoreSeed() {
this._store.route = 'RestoreSeed';
}

goRestorePassword() {
this._store.route = 'RestorePassword';
}

goSeedSuccess() {
Expand Down
87 changes: 83 additions & 4 deletions src/action/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@

import { observe, when } from 'mobx';
import { toBuffer, parseSat, checkHttpStatus, nap, poll } from '../helper';
import { MIN_PASSWORD_LENGTH, NOTIFICATION_DELAY, RATE_DELAY } from '../config';
import {
MIN_PASSWORD_LENGTH,
NOTIFICATION_DELAY,
RATE_DELAY,
RECOVERY_WINDOW,
} from '../config';
import * as log from './log';

class WalletAction {
Expand Down Expand Up @@ -41,6 +46,16 @@ class WalletAction {
this._store.wallet.seedVerify[index] = word;
}

/**
* Set the restore seed input by the seed word and
* seed index.
* @param {string} options.word The seed word
* @param {number} options.index The seed index
*/
setRestoreSeed({ word, index }) {
this._store.wallet.restoreSeed[index] = word;
}

//
// Wallet Password actions
//
Expand Down Expand Up @@ -82,6 +97,14 @@ class WalletAction {
this._store.wallet.passwordVerify = password;
}

/**
* Set whether or not we're restoring the wallet.
* @param {boolean} options.restoring Whether or not we're restoring.
*/
setRestoringWallet({ restoring }) {
this._store.wallet.restoring = restoring;
}

//
// Wallet actions
//
Expand All @@ -98,7 +121,7 @@ class WalletAction {
this._store.firstStart = true;
this._nav.goLoader();
await nap(NOTIFICATION_DELAY);
this._nav.goSeed();
this._nav.goSelectSeed();
} catch (err) {
this.initPassword();
}
Expand Down Expand Up @@ -181,18 +204,60 @@ class WalletAction {
* screen.
* @param {string} options.walletPassword The user chosen password
* @param {Array} options.seedMnemonic The seed words to generate the wallet
* @param {number} options.recoveryWindow The number of addresses to recover
* @return {Promise<undefined>}
*/
async initWallet({ walletPassword, seedMnemonic }) {
async initWallet({ walletPassword, seedMnemonic, recoveryWindow = 0 }) {
try {
await this._grpc.sendUnlockerCommand('InitWallet', {
wallet_password: toBuffer(walletPassword),
cipher_seed_mnemonic: seedMnemonic,
recovery_window: recoveryWindow,
});
this._store.walletUnlocked = true;
this._nav.goSeedSuccess();
} catch (err) {
this._notification.display({ msg: 'Initializing wallet failed', err });
this._notification.display({
type: 'error',
msg: `Initializing wallet failed: ${err.details}`,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above does the same in one line. Why the change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, did you see this comment? #612 (comment) This is the reason I changed it, you may not be getting the same issue?

}
}

/**
* Initialize the restore wallet view by resetting input values and then
* navigating to the view.
* @return {undefined}
*/
initRestoreWallet() {
this._store.wallet.restoreIndex = 0;
this._nav.goRestoreSeed();
}

/**
* Initialize the next restore wallet view by setting a new restoreIndex or,
* if all seed words have been entered, navigating to the password entry
* view.
* @return {undefined}
*/
initNextRestorePage() {
if (this._store.wallet.restoreIndex < 21) {
this._store.wallet.restoreIndex += 3;
} else {
this._nav.goRestorePassword();
}
}

/**
* Initialize the previous restore wallet view by setting a new restoreIndex
* or, if on the first seed entry page, navigating to the select seed view.
* @return {undefined}
*/
initPrevRestorePage() {
if (this._store.wallet.restoreIndex >= 3) {
this._store.wallet.restoreIndex -= 3;
} else {
this._nav.goSelectSeed();
}
}

Expand All @@ -205,6 +270,20 @@ class WalletAction {
await this.unlockWallet({ walletPassword: password });
}

/**
* Initialize the wallet with the password input the seed that was already
* inputted, and the default recovery window.
* @return {Promise<undefined>}
*/
async restoreWallet() {
const { password, restoreSeed } = this._store.wallet;
await this.initWallet({
walletPassword: password,
seedMnemonic: restoreSeed.toJSON(),
recoveryWindow: RECOVERY_WINDOW,
});
}

/**
* Unlock the wallet by calling the grpc api with the user chosen password.
* @param {string} options.walletPassword The password used to encrypt the wallet
Expand Down
13 changes: 13 additions & 0 deletions src/computed/seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ const ComputedSeed = store => {
const c2 = formatOrdinal(seedVerifyIndexes[2]);
return `Type the ${c0}, ${c1}, and ${c2} words of your recovery phrase.`;
}),
restoreIndexes: computed(() => [...Array(24).keys()].map(x => ++x)),
restoreVerifyIndexes: computed(() => {
const { restoreIndexes } = store;
const { restoreIndex } = store.wallet;
return restoreIndexes.slice(restoreIndex, restoreIndex + 3);
}),
restoreVerifyCopy: computed(() => {
const { restoreVerifyIndexes } = store;
const c0 = formatOrdinal(restoreVerifyIndexes[0]);
const c1 = formatOrdinal(restoreVerifyIndexes[1]);
const c2 = formatOrdinal(restoreVerifyIndexes[2]);
return `Type the ${c0}, ${c1}, and ${c2} words of your recovery phrase.`;
}),
});
};

Expand Down
1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports.PREFIX_URI = `${prefixName}:`;
module.exports.DEFAULT_ROUTE = 'Welcome';
module.exports.MIN_PASSWORD_LENGTH = 8;
module.exports.MAX_LOG_LENGTH = 10000;
module.exports.RECOVERY_WINDOW = 250;

module.exports.UNITS = {
sat: { display: 'SAT', displayLong: 'Satoshi', denominator: 1 },
Expand Down
3 changes: 3 additions & 0 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export class Store {
password: '',
passwordVerify: '',
seedVerify: ['', '', ''],
restoring: false,
restoreIndex: 0,
restoreSeed: Array(24).fill(''),
},
transactions: [],
selectedTransaction: null,
Expand Down
12 changes: 12 additions & 0 deletions src/view/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import Container from '../component/container';
import { NotificationBar } from '../component/notification';
import Welcome from './welcome';
import Loader from './loader';
import SelectSeed from './select-seed';
import Seed from './seed';
import SeedVerify from './seed-verify';
import SeedSuccess from './seed-success';
import SetPassword from './set-password';
import RestoreSeed from './restore-seed';
import RestorePassword from './restore-password';
import Password from './password';
import NewAddress from './new-address';
import LoaderSyncing from './loader-syncing';
Expand Down Expand Up @@ -56,6 +59,9 @@ class MainView extends Component {
/>
{route === 'Welcome' && <Welcome />}
{route === 'Loader' && <Loader />}
{route === 'SelectSeed' && (
<SelectSeed store={store} wallet={wallet} nav={nav} />
)}
{route === 'Seed' && <Seed store={store} wallet={wallet} />}
{route === 'SeedVerify' && (
<SeedVerify store={store} nav={nav} wallet={wallet} />
Expand All @@ -64,6 +70,12 @@ class MainView extends Component {
{route === 'SetPassword' && (
<SetPassword store={store} wallet={wallet} />
)}
{route === 'RestoreSeed' && (
<RestoreSeed store={store} wallet={wallet} />
)}
{route === 'RestorePassword' && (
<RestorePassword store={store} wallet={wallet} nav={nav} />
)}
{route === 'Password' && <Password store={store} wallet={wallet} />}
{route === 'NewAddress' && (
<NewAddress store={store} invoice={invoice} info={info} />
Expand Down
70 changes: 70 additions & 0 deletions src/view/restore-password.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { observer } from 'mobx-react';
import PropTypes from 'prop-types';
import Background from '../component/background';
import MainContent from '../component/main-content';
import { H1Text } from '../component/text';
import { Header } from '../component/header';
import { Button, BackButton, GlasButton } from '../component/button';
import { InputField } from '../component/field';
import Card from '../component/card';
import { FormSubText, FormStretcher } from '../component/form';

//
// Restore Wallet Password View
//

const styles = StyleSheet.create({
content: {
justifyContent: 'flex-end',
},
title: {
textAlign: 'center',
marginBottom: 20,
},
card: {
maxHeight: 350,
maxWidth: 680,
paddingLeft: 45,
paddingRight: 45,
paddingBottom: 50,
},
});

const RestorePasswordView = ({ store, wallet, nav }) => (
<Background image="purple-gradient-bg">
<Header>
<BackButton onPress={() => nav.goSelectSeed()} />
<Button disabled onPress={() => {}} />
</Header>
<MainContent style={styles.content}>
<View>
<H1Text style={styles.title}>Restore wallet</H1Text>
</View>
<Card style={styles.card}>
<FormSubText>Please enter your password.</FormSubText>
<FormStretcher>
<InputField
style={styles.input}
placeholder="Password"
secureTextEntry={true}
autoFocus={true}
value={store.wallet.password}
onChangeText={password => wallet.setPassword({ password })}
onSubmitEditing={() => wallet.restoreWallet()}
/>
</FormStretcher>
</Card>
<GlasButton onPress={() => wallet.restoreWallet()}>Restore</GlasButton>
</MainContent>
</Background>
);

RestorePasswordView.propTypes = {
store: PropTypes.object.isRequired,
wallet: PropTypes.object.isRequired,
nav: PropTypes.object.isRequired,
};

export default observer(RestorePasswordView);
25 changes: 13 additions & 12 deletions src/view/restore-wallet.js → src/view/restore-seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Header } from '../component/header';
import Card from '../component/card';

//
// Restore Wallet View
// Restore Wallet Seed View
//

const styles = StyleSheet.create({
Expand All @@ -32,38 +32,39 @@ const styles = StyleSheet.create({
},
});

const RestoreWalletView = ({ store, nav, wallet }) => (
const RestoreSeedView = ({ store, wallet }) => (
<Background image="purple-gradient-bg">
<Header>
<BackButton onPress={() => nav.goSeed()} />
<BackButton onPress={() => wallet.initPrevRestorePage()} />
<Button disabled onPress={() => {}} />
</Header>
<MainContent style={styles.content}>
<View>
<H1Text style={styles.title}>Restore your wallet</H1Text>
</View>
<Card style={styles.card}>
<FormSubText>{store.seedVerifyCopy}</FormSubText>
{store.seedVerifyIndexes.map((seedIndex, i) => (
<FormSubText>{store.restoreVerifyCopy}</FormSubText>
{store.restoreVerifyIndexes.map((seedIndex, i) => (
<SeedEntry
seedIndex={seedIndex}
value={store.wallet.seedVerify[i]}
onChangeText={word => wallet.setSeedVerify({ word, index: i })}
value={store.wallet.restoreSeed[seedIndex - 1]}
onChangeText={word =>
wallet.setRestoreSeed({ word, index: seedIndex - 1 })
}
key={i}
autoFocus={i === 0}
onSubmitEditing={() => wallet.checkSeed()}
onSubmitEditing={() => wallet.initNextRestorePage()}
/>
))}
</Card>
<GlasButton onPress={() => wallet.checkSeed()}>Next</GlasButton>
<GlasButton onPress={() => wallet.initNextRestorePage()}>Next</GlasButton>
</MainContent>
</Background>
);

RestoreWalletView.propTypes = {
RestoreSeedView.propTypes = {
store: PropTypes.object.isRequired,
nav: PropTypes.object.isRequired,
wallet: PropTypes.object.isRequired,
};

export default observer(RestoreWalletView);
export default observer(RestoreSeedView);
Loading