1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Add Import With Seed Phrase

This commit is contained in:
Chi Kei Chan 2017-10-20 22:31:59 -07:00
parent 2b26496826
commit f503120b82
6 changed files with 156 additions and 19 deletions

View File

@ -8,6 +8,7 @@ class CreatePasswordScreen extends Component {
static propTypes = { static propTypes = {
isLoading: PropTypes.bool.isRequired, isLoading: PropTypes.bool.isRequired,
createAccount: PropTypes.func.isRequired, createAccount: PropTypes.func.isRequired,
goToImportWithSeedPhrase: PropTypes.func.isRequired,
goToImportAccount: PropTypes.func.isRequired, goToImportAccount: PropTypes.func.isRequired,
next: PropTypes.func.isRequired next: PropTypes.func.isRequired
} }
@ -44,7 +45,7 @@ class CreatePasswordScreen extends Component {
} }
render() { render() {
const { isLoading, goToImportAccount } = this.props const { isLoading, goToImportAccount, goToImportWithSeedPhrase } = this.props
return isLoading return isLoading
? <LoadingScreen loadingMessage="Creating your new account" /> ? <LoadingScreen loadingMessage="Creating your new account" />
@ -72,6 +73,16 @@ class CreatePasswordScreen extends Component {
> >
Create Create
</button> </button>
<a
href=""
className="first-time-flow__link create-password__import-link"
onClick={e => {
e.preventDefault()
goToImportWithSeedPhrase()
}}
>
Import with seed phrase
</a>
{ /* } { /* }
<a <a
href="" href=""

View File

@ -0,0 +1,103 @@
import React, {Component, PropTypes} from 'react'
import {connect} from 'react-redux'
import LoadingScreen from './loading-screen'
import {createNewVaultAndRestore, hideWarning} from '../../../../ui/app/actions'
class ImportSeedPhraseScreen extends Component {
static propTypes = {
warning: PropTypes.string,
back: PropTypes.func.isRequired,
next: PropTypes.func.isRequired,
createNewVaultAndRestore: PropTypes.func.isRequired,
hideWarning: PropTypes.func.isRequired,
isLoading: PropTypes.bool.isRequired,
};
state = {
seedPhrase: '',
password: '',
confirmPassword: '',
}
onClick = () => {
const { password, seedPhrase } = this.state
const { createNewVaultAndRestore, next } = this.props
createNewVaultAndRestore(password, seedPhrase)
.then(next)
}
isValid () {
const { seedPhrase, password, confirmPassword } = this.state
if (seedPhrase.split(' ').length !== 12) {
return false
}
if (password.length < 8) {
return false
}
if (password !== confirmPassword) {
return false
}
return true
}
render () {
return this.props.isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
: (
<div className="import-account">
<a
className="import-account__back-button"
onClick={e => {
e.preventDefault()
this.props.back()
}}
href="#"
>
{`< Back`}
</a>
<div className="import-account__title">
Import an Account with Seed Phrase
</div>
<div className="import-account__selector-label">
Enter your secret twelve word phrase here to restore your vault.
</div>
<textarea
className="import-account__secret-phrase"
onChange={e => this.setState({seedPhrase: e.target.value})}
/>
<input
className="first-time-flow__input"
type="password"
placeholder="New Password (min 8 characters)"
onChange={e => this.setState({password: e.target.value})}
/>
<input
className="first-time-flow__input create-password__confirm-input"
type="password"
placeholder="Confirm Password"
onChange={e => this.setState({confirmPassword: e.target.value})}
/>
<button
className="first-time-flow__button"
onClick={this.onClick}
disabled={!this.isValid()}
>
Import
</button>
</div>
)
}
}
export default connect(
({ appState: { isLoading, warning } }) => ({ isLoading, warning }),
dispatch => ({
createNewVaultAndRestore: (pw, seed) => dispatch(createNewVaultAndRestore(pw, seed)),
hideWarning: () => dispatch(hideWarning()),
})
)(ImportSeedPhraseScreen)

View File

@ -78,7 +78,8 @@
width: initial !important; width: initial !important;
} }
.backup-phrase__confirm-secret { .backup-phrase__confirm-secret,
.import-account__secret-phrase {
width: initial !important; width: initial !important;
height: initial !important; height: initial !important;
min-height: 190px; min-height: 190px;
@ -266,7 +267,8 @@ button.backup-phrase__reveal-button:hover {
transform: scale(1); transform: scale(1);
} }
.backup-phrase__confirm-secret { .backup-phrase__confirm-secret,
.import-account__secret-phrase {
height: 190px; height: 190px;
width: 495px; width: 495px;
border: 1px solid #CDCDCD; border: 1px solid #CDCDCD;
@ -276,6 +278,10 @@ button.backup-phrase__reveal-button:hover {
padding: 17px; padding: 17px;
} }
.import-account__secret-phrase {
font-size: 16px;
}
.backup-phrase__confirm-seed-options { .backup-phrase__confirm-seed-options {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;

View File

@ -5,7 +5,7 @@ import UniqueImageScreen from './unique-image-screen'
import NoticeScreen from './notice-screen' import NoticeScreen from './notice-screen'
import BackupPhraseScreen from './backup-phrase-screen' import BackupPhraseScreen from './backup-phrase-screen'
import ImportAccountScreen from './import-account-screen' import ImportAccountScreen from './import-account-screen'
import BuyEtherScreen from './buy-ether-screen' import ImportSeedPhraseScreen from './import-seed-phrase-screen'
import {onboardingBuyEthView} from '../../../../ui/app/actions' import {onboardingBuyEthView} from '../../../../ui/app/actions'
class FirstTimeFlow extends Component { class FirstTimeFlow extends Component {
@ -27,6 +27,7 @@ class FirstTimeFlow extends Component {
static SCREEN_TYPE = { static SCREEN_TYPE = {
CREATE_PASSWORD: 'create_password', CREATE_PASSWORD: 'create_password',
IMPORT_ACCOUNT: 'import_account', IMPORT_ACCOUNT: 'import_account',
IMPORT_SEED_PHRASE: 'import_seed_phrase',
UNIQUE_IMAGE: 'unique_image', UNIQUE_IMAGE: 'unique_image',
NOTICE: 'notice', NOTICE: 'notice',
BACK_UP_PHRASE: 'back_up_phrase', BACK_UP_PHRASE: 'back_up_phrase',
@ -77,6 +78,7 @@ class FirstTimeFlow extends Component {
<CreatePasswordScreen <CreatePasswordScreen
next={() => this.setScreenType(SCREEN_TYPE.UNIQUE_IMAGE)} next={() => this.setScreenType(SCREEN_TYPE.UNIQUE_IMAGE)}
goToImportAccount={() => this.setScreenType(SCREEN_TYPE.IMPORT_ACCOUNT)} goToImportAccount={() => this.setScreenType(SCREEN_TYPE.IMPORT_ACCOUNT)}
goToImportWithSeedPhrase={() => this.setScreenType(SCREEN_TYPE.IMPORT_SEED_PHRASE)}
/> />
) )
case SCREEN_TYPE.IMPORT_ACCOUNT: case SCREEN_TYPE.IMPORT_ACCOUNT:
@ -86,6 +88,13 @@ class FirstTimeFlow extends Component {
next={() => this.setScreenType(SCREEN_TYPE.NOTICE)} next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
/> />
) )
case SCREEN_TYPE.IMPORT_SEED_PHRASE:
return (
<ImportSeedPhraseScreen
back={() => this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)}
next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
/>
)
case SCREEN_TYPE.UNIQUE_IMAGE: case SCREEN_TYPE.UNIQUE_IMAGE:
return ( return (
<UniqueImageScreen <UniqueImageScreen

View File

@ -238,10 +238,20 @@ function createNewVaultAndRestore (password, seed) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
log.debug(`background.createNewVaultAndRestore`) log.debug(`background.createNewVaultAndRestore`)
background.createNewVaultAndRestore(password, seed, (err) => {
dispatch(actions.hideLoadingIndication()) return new Promise((resolve, reject) => {
if (err) return dispatch(actions.displayWarning(err.message)) background.createNewVaultAndRestore(password, seed, (err) => {
dispatch(actions.showAccountsPage())
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.displayWarning(err.message))
return reject(err)
}
dispatch(actions.showAccountsPage())
resolve()
})
}) })
} }
} }

View File

@ -3237,9 +3237,9 @@ eth-hd-keyring@^1.2.1:
ethereumjs-wallet "^0.6.0" ethereumjs-wallet "^0.6.0"
events "^1.1.1" events "^1.1.1"
eth-json-rpc-filters@^1.2.2: eth-json-rpc-filters@^1.2.4:
version "1.2.3" version "1.2.4"
resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.3.tgz#6ad6db134d1fc84c4d0b60f9faf19b70d300ae1e" resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.4.tgz#716109b1cf4d0ec01f30f848d65c60c34400e975"
dependencies: dependencies:
await-semaphore "^0.1.1" await-semaphore "^0.1.1"
eth-json-rpc-middleware "^1.0.0" eth-json-rpc-middleware "^1.0.0"
@ -3261,9 +3261,9 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7:
promise-to-callback "^1.0.0" promise-to-callback "^1.0.0"
tape "^4.6.3" tape "^4.6.3"
eth-keyring-controller@^2.1.0: eth-keyring-controller@^2.1.2:
version "2.1.1" version "2.1.2"
resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.1.tgz#08129c8300f0ac6de9110e0b8d51292b5c6327e3" resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.2.tgz#1af179d8fd7ff470eb91e113a0fd3a440bd66bcc"
dependencies: dependencies:
bip39 "^2.4.0" bip39 "^2.4.0"
bluebird "^3.5.0" bluebird "^3.5.0"
@ -7845,14 +7845,12 @@ samsam@1.x, samsam@^1.1.3:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67"
sandwich-expando@^1.0.5: sandwich-expando@^1.1.3:
version "1.1.1" version "1.1.3"
resolved "https://registry.yarnpkg.com/sandwich-expando/-/sandwich-expando-1.1.1.tgz#83806fcca2375af8b6c30e6f52ed4f989debb165" resolved "https://registry.yarnpkg.com/sandwich-expando/-/sandwich-expando-1.1.3.tgz#6ba78d034c32f8bf5ab5934c214f8384614a88a5"
dependencies: dependencies:
babel-preset-es2015 "^6.6.0" babel-preset-es2015 "^6.6.0"
babelify "^7.3.0" babelify "^7.3.0"
brfs "^1.4.3"
raphael "^2.2.0"
react "^15.0.2" react "^15.0.2"
react-dom "^15.0.2" react-dom "^15.0.2"
react-hyperscript "^2.4.0" react-hyperscript "^2.4.0"