Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse and construct function together #328

Merged
merged 8 commits into from
Aug 26, 2019
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
13 changes: 10 additions & 3 deletions src/components/AccountIconChooser.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { NetworkProtocols } from '../constants';
import fonts from "../fonts";
import { debounce } from '../util/debounce';
import { brainWalletAddress, substrateAddress, words } from '../util/native';
import {constructSURI} from '../util/suri'

export default class AccountIconChooser extends React.PureComponent {
constructor(props) {
Expand All @@ -48,7 +49,6 @@ export default class AccountIconChooser extends React.PureComponent {

// clean previous selection
onSelect({ newAddress: '', isBip39: false, newSeed: ''});

try {
const icons = await Promise.all(
Array(4)
Expand All @@ -65,12 +65,19 @@ export default class AccountIconChooser extends React.PureComponent {
if (protocol === NetworkProtocols.ETHEREUM) {
Object.assign(result, await brainWalletAddress(result.seed));
} else {
// Substrate
try {
result.address = await substrateAddress(`${result.seed}${derivationPath}///${derivationPassword}`, prefix);
const suri = constructSURI({
derivePath: derivationPath,
password: derivationPassword,
phrase: result.seed
});

result.address = await substrateAddress(suri, prefix);
result.bip39 = true;
} catch (e){
// invalid seed or derivation path
// console.error(e);
console.error(e);
}
}
return result;
Expand Down
26 changes: 19 additions & 7 deletions src/components/DerivationPathField.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';

import keyExtract from '../util/keyExtract'
import {parseDerivationPath} from '../util/suri'
import TextInput from './TextInput';

export default function DerivationPathField(props) {
Expand Down Expand Up @@ -58,12 +58,24 @@ export default function DerivationPathField(props) {
{showAdvancedField &&
<TextInput
onChangeText={(text) => {
const derivationPath = keyExtract(text);
onChange({
derivationPassword: derivationPath.password || '',
derivationPath: derivationPath.derivePath || ''
});
setIsValidPath(!!derivationPath.password || !!derivationPath.derivePath);
try {
const derivationPath = parseDerivationPath(text);

onChange({
derivationPassword: derivationPath.password || '',
derivationPath: derivationPath.derivePath || '',
isDerivationPathValid: true
});
setIsValidPath(true);
} catch (e) {
// wrong derivationPath
onChange({
derivationPassword: '',
derivationPath: '',
isDerivationPathValid: false
});
setIsValidPath(false);
}
}}
placeholder="optional derivation path"
style={isValidPath ? ownStyles.validInput: ownStyles.invalidInput}
Expand Down
58 changes: 38 additions & 20 deletions src/screens/AccountNew.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
'use strict';

import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { StyleSheet, Text, View } from 'react-native';
import { Subscribe } from 'unstated';

import colors from '../colors';
Expand All @@ -32,6 +32,7 @@ import { NETWORK_LIST, NetworkProtocols } from '../constants';
import fonts from '../fonts';
import AccountsStore from '../stores/AccountsStore';
import { empty, validateSeed } from '../util/account';
import {constructSURI} from '../util/suri';

export default class AccountNew extends React.Component {
static navigationOptions = {
Expand All @@ -55,6 +56,7 @@ class AccountNewView extends React.Component {
this.state = {
derivationPassword: '',
derivationPath: '',
isDerivationPathValid: true,
selectedAccount: undefined,
selectedNetwork: undefined,
};
Expand All @@ -79,7 +81,7 @@ class AccountNewView extends React.Component {

render() {
const { accounts, navigation } = this.props;
const { derivationPassword, derivationPath, selectedAccount, selectedNetwork } = this.state;
const { derivationPassword, derivationPath, isDerivationPathValid, selectedAccount, selectedNetwork } = this.state;
const {address, name, seed, validBip39Seed} = selectedAccount;
const isSubstrate = selectedNetwork.protocol === NetworkProtocols.SUBSTRATE;

Expand All @@ -100,22 +102,38 @@ class AccountNewView extends React.Component {
derivationPassword={derivationPassword}
derivationPath={derivationPath}
onSelect={({ newAddress, isBip39, newSeed }) => {
if (isSubstrate) {
accounts.updateNew({
address: newAddress,
derivationPassword,
derivationPath,
seed: `${newSeed}${derivationPath}///${derivationPassword}`,
seedPhrase: newSeed,
validBip39Seed: isBip39
});
if (newAddress && isBip39 && newSeed){
if (isSubstrate) {
try {
const suri = constructSURI({
derivePath: derivationPath,
password: derivationPassword,
phrase: newSeed
});

accounts.updateNew({
address: newAddress,
derivationPassword,
derivationPath,
seed: suri,
seedPhrase: newSeed,
validBip39Seed: isBip39
});
} catch (e) {
console.error(e);
}
} else {
// Ethereum account
accounts.updateNew({
address: newAddress,
seed: newSeed,
validBip39Seed: isBip39
});
}
} else {
accounts.updateNew({
address: newAddress,
seed: newSeed,
validBip39Seed: isBip39
});
}}}
accounts.updateNew({ address: '', seed: '', validBip39Seed: false})
}
}}
network={selectedNetwork}
value={address && address}
/>
Expand All @@ -126,8 +144,8 @@ class AccountNewView extends React.Component {
placeholder="Enter a new account name"
/>
{isSubstrate && <DerivationPathField
onChange = { ({derivationPassword, derivationPath}) => {
this.setState({ derivationPath, derivationPassword });
onChange = { ({derivationPassword, derivationPath, isDerivationPathValid}) => {
this.setState({ derivationPath, derivationPassword, isDerivationPathValid });
}}
styles={styles}
/>}
Expand All @@ -139,7 +157,7 @@ class AccountNewView extends React.Component {
<Button
buttonStyles={styles.nextStep}
title="Next Step"
disabled={!validateSeed(seed, validBip39Seed).valid}
disabled={!validateSeed(seed, validBip39Seed).valid || !isDerivationPathValid}
onPress={() => {
validateSeed(seed, validBip39Seed).valid &&
navigation.navigate('AccountBackup', {
Expand Down
52 changes: 39 additions & 13 deletions src/screens/AccountRecover.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import AccountsStore from '../stores/AccountsStore';
import { empty, validateSeed } from '../util/account';
import { debounce } from '../util/debounce';
import { brainWalletAddress, substrateAddress } from '../util/native';
import {constructSURI} from '../util/suri';

export default class AccountRecover extends React.Component {
static navigationOptions = {
Expand All @@ -66,6 +67,7 @@ class AccountRecoverView extends React.Component {
this.state = {
derivationPassword: '',
derivationPath: '',
isDerivationPathValid: true,
seedPhrase: '',
selectedAccount: undefined,
selectedNetwork: undefined,
Expand All @@ -85,26 +87,50 @@ class AccountRecoverView extends React.Component {
}
}

clearNewAccount = function () {
const { accounts } = this.props;

accounts.updateNew({ address:'', derivationPath:'', derivationPassword:'', seed:'', seedPhrase:'', validBip39Seed: false })
}

addressGeneration = (seedPhrase, derivationPath = '', derivationPassword = '') => {
const { accounts } = this.props;
const { selectedNetwork:{protocol, prefix} } = this.state;

if (!seedPhrase){
this.clearNewAccount();

return;
}

if (protocol === NetworkProtocols.ETHEREUM){
brainWalletAddress(seedPhrase)
.then(({ address, bip39 }) =>
accounts.updateNew({ address, seed: seedPhrase, seedPhrase, validBip39Seed: bip39 })
)
.catch(console.error);
} else {
const suri = `${seedPhrase}${derivationPath}///${derivationPassword}`
substrateAddress(suri, prefix)
.then((address) => {
accounts.updateNew({ address, derivationPath, derivationPassword, seed: suri, seedPhrase, validBip39Seed: true })
})
.catch(
//invalid phrase
accounts.updateNew({ address:'', derivationPath:'', derivationPassword:'', seed:'', seedPhrase:'', validBip39Seed: false })
);
// Substrate
try {
const suri = constructSURI({
derivePath: derivationPath,
password: derivationPassword,
phrase: seedPhrase
});

substrateAddress(suri, prefix)
.then((address) => {
accounts.updateNew({ address, derivationPath, derivationPassword, seed: suri, seedPhrase, validBip39Seed: true })
})
.catch(() => {
//invalid phrase
Copy link
Contributor

Choose a reason for hiding this comment

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

This one error catch may be redundant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so since the catch is specific to substrateAddress whereas the other is for constructSURI

this.clearNewAccount();
});
} catch (e) {
// invalid phrase or derivation path
this.clearNewAccount();
}

}
};

Expand All @@ -129,7 +155,7 @@ class AccountRecoverView extends React.Component {

render() {
const { accounts, navigation } = this.props;
const { derivationPassword, derivationPath, selectedAccount, selectedNetwork} = this.state;
const { derivationPassword, derivationPath, isDerivationPathValid, selectedAccount, selectedNetwork} = this.state;
const {address, name, networkKey, seedPhrase, validBip39Seed} = selectedAccount;
const isSubstrate = selectedNetwork.protocol === NetworkProtocols.SUBSTRATE;

Expand Down Expand Up @@ -171,9 +197,9 @@ class AccountRecoverView extends React.Component {
value={this.state.seedPhrase}
/>
{isSubstrate && <DerivationPathField
onChange = { ({derivationPassword, derivationPath}) => {
onChange = { ({derivationPassword, derivationPath, isDerivationPathValid}) => {
this.debouncedAddressGeneration(seedPhrase, derivationPath, derivationPassword);
this.setState({ derivationPath, derivationPassword });
this.setState({ derivationPath, derivationPassword, isDerivationPathValid });
}}
styles={styles}
/>}
Expand All @@ -186,7 +212,7 @@ class AccountRecoverView extends React.Component {
/>
<Button
buttonStyles={{ marginBottom: 40 }}
disabled={isSubstrate && !address}
disabled={isSubstrate && (!address || !isDerivationPathValid)}
title="Next Step"
onPress={() => {
const validation = validateSeed(
Expand Down
4 changes: 2 additions & 2 deletions src/stores/AccountsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Container } from 'unstated';

import { accountId, empty } from '../util/account';
import { loadAccounts, saveAccount } from '../util/db';
import keyExtract from '../util/keyExtract'
import {parseSURI} from '../util/suri'
import { decryptData, encryptData } from '../util/native';


Expand Down Expand Up @@ -144,7 +144,7 @@ export default class AccountsStore extends Container {
try {
account.seed = await decryptData(account.encryptedSeed, pin);

const {phrase, derivePath, password} = keyExtract(account.seed)
const {phrase, derivePath, password} = parseSURI(account.seed)

account.seedPhrase = phrase || '';
account.derivationPath = derivePath || '';
Expand Down
23 changes: 0 additions & 23 deletions src/util/keyExtract.js

This file was deleted.

Loading