From 8c4d58aa4508e3d54c3f69847347e78d09c63b97 Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 10 Jun 2018 03:52:32 -0400 Subject: initial trezor support --- .../pages/create-account/connect-hardware.js | 234 +++++++++++++++++++++ ui/app/components/pages/create-account/index.js | 25 ++- .../components/pages/create-account/new-account.js | 2 + 3 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 ui/app/components/pages/create-account/connect-hardware.js (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js new file mode 100644 index 000000000..37b7414b3 --- /dev/null +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -0,0 +1,234 @@ +const { Component } = require('react') +const PropTypes = require('prop-types') +const h = require('react-hyperscript') +const connect = require('react-redux').connect +const actions = require('../../../actions') +const genAccountLink = require('../../../../lib/account-link.js') +const log = require('loglevel') +const { DEFAULT_ROUTE } = require('../../../routes') + +class ConnectHardwareForm extends Component { + constructor (props, context) { + super(props) + this.state = { + error: null, + response: null, + btnText: 'Connect to Trezor', // Test + selectedAccount: '', + accounts: [], + } + } + + connectToTrezor () { + if (this.state.accounts.length) { + return null + } + this.setState({ btnText: 'Connecting...' }) + this.getPage() + } + + getPage (page = 1) { + this.props + .connectHardware('trezor', page) + .then(accounts => { + if (accounts.length) { + this.setState({ accounts: accounts }) + } + }) + .catch(e => { + this.setState({ btnText: 'Connect to Trezor' }) + }) + } + + unlockAccount () { + if (this.state.selectedAccount === '') { + return Promise.reject({ error: 'You need to select an account!' }) + } + log.debug('should unlock account ', this.state.selectedAccount) + return this.props.unlockTrezorAccount(this.state.selectedAccount) + } + + handleRadioChange = e => { + log.debug('Selected account with index ', e.target.value) + + this.setState({ + selectedAccount: e.target.value, + error: null, + }) + } + + renderAccounts () { + if (!this.state.accounts.length) { + return null + } + log.debug('ACCOUNTS : ', this.state.accounts) + log.debug('SELECTED?', this.state.selectedAccount) + + return h('div.hw-account-list', [ + h('div.hw-account-list__title_wrapper', [ + h('div.hw-account-list__title', {}, ['Select an Address']), + h('div.hw-account-list__device', {}, ['Trezor - ETH']), + ]), + this.state.accounts.map((a, i) => { + return h('div.hw-account-list__item', { key: a.address }, [ + h('span.hw-account-list__item__index', a.index + 1), + h('div.hw-account-list__item__radio', [ + h('input', { + type: 'radio', + name: 'selectedAccount', + id: `address-${i}`, + value: a.index, + onChange: this.handleRadioChange, + }), + h( + 'label.hw-account-list__item__label', + { + htmlFor: `address-${i}`, + }, + `${a.address.slice(0, 4)}...${a.address.slice(-4)}` + ), + ]), + h('span.hw-account-list__item__balance', `${a.balance} ETH`), + h( + 'a.hw-account-list__item__link', + { + href: genAccountLink(a.address, this.props.network), + target: '_blank', + title: this.context.t('etherscanView'), + }, + h('img', { src: 'images/popout.svg' }) + ), + ]) + }), + ]) + } + + renderPagination () { + if (!this.state.accounts.length) { + return null + } + return h('div.hw-list-pagination', [ + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.getPage(-1), + }, + '< Prev' + ), + + h( + 'button.btn-primary.hw-list-pagination__button', + { + onClick: () => this.getPage(), + }, + 'Next >' + ), + ]) + } + + renderButtons () { + if (!this.state.accounts.length) { + return null + } + const { history } = this.props + + return h('div.new-account-create-form__buttons', {}, [ + h( + 'button.btn-default.btn--large.new-account-create-form__button', + { + onClick: () => history.push(DEFAULT_ROUTE), + }, + [this.context.t('cancel')] + ), + + h( + 'button.btn-primary.btn--large.new-account-create-form__button', + { + onClick: () => { + this.unlockAccount(this.state.selectedAccount) + .then(() => history.push(DEFAULT_ROUTE)) + .catch(e => { + this.setState({ error: e.error }) + }) + }, + }, + [this.context.t('unlock')] + ), + ]) + } + + renderError () { + return this.state.error + ? h('span.error', { style: { marginBottom: 40 } }, this.state.error) + : null + } + + renderConnectButton () { + return !this.state.accounts.length + ? h( + 'button.btn-primary.btn--large', + { onClick: () => this.connectToTrezor(), style: { margin: 12 } }, + this.state.btnText + ) + : null + } + + render () { + return h('div.new-account-create-form', [ + this.renderError(), + this.renderConnectButton(), + this.renderAccounts(), + this.renderPagination(), + this.renderButtons(), + ]) + } +} + +ConnectHardwareForm.propTypes = { + hideModal: PropTypes.func, + showImportPage: PropTypes.func, + showConnectPage: PropTypes.func, + connectHardware: PropTypes.func, + unlockTrezorAccount: PropTypes.func, + numberOfExistingAccounts: PropTypes.number, + history: PropTypes.object, + t: PropTypes.func, + network: PropTypes.string, +} + +const mapStateToProps = state => { + const { + metamask: { network, selectedAddress, identities = {} }, + } = state + const numberOfExistingAccounts = Object.keys(identities).length + + return { + network, + address: selectedAddress, + numberOfExistingAccounts, + } +} + +const mapDispatchToProps = dispatch => { + return { + toCoinbase: address => + dispatch(actions.buyEth({ network: '1', address, amount: 0 })), + hideModal: () => dispatch(actions.hideModal()), + connectHardware: (deviceName, page) => { + return dispatch(actions.connectHardware(deviceName, page)) + }, + unlockTrezorAccount: index => { + return dispatch(actions.unlockTrezorAccount(index)) + }, + showImportPage: () => dispatch(actions.showImportPage()), + showConnectPage: () => dispatch(actions.showConnectPage()), + } +} + +ConnectHardwareForm.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)( + ConnectHardwareForm +) diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index 6e3b93742..69a4db80a 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -8,7 +8,12 @@ const { getCurrentViewContext } = require('../../../selectors') const classnames = require('classnames') const NewAccountCreateForm = require('./new-account') const NewAccountImportForm = require('./import-account') -const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE } = require('../../../routes') +const ConnectHardwareForm = require('./connect-hardware') +const { + NEW_ACCOUNT_ROUTE, + IMPORT_ACCOUNT_ROUTE, + CONNECT_HARDWARE_ROUTE, +} = require('../../../routes') class CreateAccountPage extends Component { renderTabs () { @@ -36,6 +41,19 @@ class CreateAccountPage extends Component { }, [ this.context.t('import'), ]), + h( + 'div.new-account__tabs__tab', + { + className: classnames('new-account__tabs__tab', { + 'new-account__tabs__selected': matchPath(location.pathname, { + path: CONNECT_HARDWARE_ROUTE, + exact: true, + }), + }), + onClick: () => history.push(CONNECT_HARDWARE_ROUTE), + }, + this.context.t('connect') + ), ]) } @@ -57,6 +75,11 @@ class CreateAccountPage extends Component { path: IMPORT_ACCOUNT_ROUTE, component: NewAccountImportForm, }), + h(Route, { + exact: true, + path: CONNECT_HARDWARE_ROUTE, + component: ConnectHardwareForm, + }), ]), ]), ]) diff --git a/ui/app/components/pages/create-account/new-account.js b/ui/app/components/pages/create-account/new-account.js index 9c94990e0..402b8f03b 100644 --- a/ui/app/components/pages/create-account/new-account.js +++ b/ui/app/components/pages/create-account/new-account.js @@ -62,6 +62,7 @@ class NewAccountCreateForm extends Component { NewAccountCreateForm.propTypes = { hideModal: PropTypes.func, showImportPage: PropTypes.func, + showConnectPage: PropTypes.func, createAccount: PropTypes.func, numberOfExistingAccounts: PropTypes.number, history: PropTypes.object, @@ -92,6 +93,7 @@ const mapDispatchToProps = dispatch => { }) }, showImportPage: () => dispatch(actions.showImportPage()), + showConnectPage: () => dispatch(actions.showConnectPage()), } } -- cgit From d1880073f678dbdc52e07e62ec66c39eea5062a6 Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 10 Jun 2018 21:10:22 -0400 Subject: balances working --- .../pages/create-account/connect-hardware.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 37b7414b3..6f1e03550 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -6,6 +6,7 @@ const actions = require('../../../actions') const genAccountLink = require('../../../../lib/account-link.js') const log = require('loglevel') const { DEFAULT_ROUTE } = require('../../../routes') +const { formatBalance } = require('../../../util') class ConnectHardwareForm extends Component { constructor (props, context) { @@ -57,10 +58,22 @@ class ConnectHardwareForm extends Component { }) } + getBalance (address) { + // Get the balance + log.debug('getBalance : ', address) + const { accounts } = this.props + const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' + log.debug('balanceValue : ', balanceValue) + const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' + log.debug('formattedBalance : ', formattedBalance) + return formattedBalance + } + renderAccounts () { if (!this.state.accounts.length) { return null } + log.debug('ACCOUNTS : ', this.state.accounts) log.debug('SELECTED?', this.state.selectedAccount) @@ -70,6 +83,7 @@ class ConnectHardwareForm extends Component { h('div.hw-account-list__device', {}, ['Trezor - ETH']), ]), this.state.accounts.map((a, i) => { + return h('div.hw-account-list__item', { key: a.address }, [ h('span.hw-account-list__item__index', a.index + 1), h('div.hw-account-list__item__radio', [ @@ -88,7 +102,7 @@ class ConnectHardwareForm extends Component { `${a.address.slice(0, 4)}...${a.address.slice(-4)}` ), ]), - h('span.hw-account-list__item__balance', `${a.balance} ETH`), + h('span.hw-account-list__item__balance', `${this.getBalance(a.address)}`), h( 'a.hw-account-list__item__link', { @@ -194,16 +208,18 @@ ConnectHardwareForm.propTypes = { history: PropTypes.object, t: PropTypes.func, network: PropTypes.string, + accounts: PropTypes.object, } const mapStateToProps = state => { const { - metamask: { network, selectedAddress, identities = {} }, + metamask: { network, selectedAddress, identities = {}, accounts = [] }, } = state const numberOfExistingAccounts = Object.keys(identities).length return { network, + accounts, address: selectedAddress, numberOfExistingAccounts, } -- cgit From 8763ea898e7838d08315063b0e2181405a2ae3d5 Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 13 Jun 2018 01:32:13 -0400 Subject: move TrezorKeyring to its own package --- ui/app/components/pages/create-account/connect-hardware.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 6f1e03550..152a4f275 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -25,10 +25,10 @@ class ConnectHardwareForm extends Component { return null } this.setState({ btnText: 'Connecting...' }) - this.getPage() + this.getPage(1) } - getPage (page = 1) { + getPage (page) { this.props .connectHardware('trezor', page) .then(accounts => { @@ -133,7 +133,7 @@ class ConnectHardwareForm extends Component { h( 'button.btn-primary.hw-list-pagination__button', { - onClick: () => this.getPage(), + onClick: () => this.getPage(1), }, 'Next >' ), -- cgit From 75581ceebe719e102b177dc20f3b9e232c48e8a4 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 21 Jun 2018 14:57:45 -0230 Subject: Show all errors on account creation screen. --- ui/app/components/pages/create-account/import-account/json.js | 2 +- ui/app/components/pages/create-account/import-account/private-key.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 1dc2ba534..955b45d74 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -114,7 +114,7 @@ class JsonImportSubview extends Component { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err)) + .catch(err => displayWarning(err.message || err)) } } diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 5df3777da..0d8ff0db6 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -104,5 +104,5 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err)) + .catch(err => displayWarning(err.message || err)) } -- cgit From 03f17d910a17abe3fe8c8dae2ef38a66bb86f222 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 21 Jun 2018 15:53:26 -0230 Subject: Check that error is defined in import-account error catch. --- ui/app/components/pages/create-account/import-account/json.js | 2 +- ui/app/components/pages/create-account/import-account/private-key.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 955b45d74..c9d14be5f 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -114,7 +114,7 @@ class JsonImportSubview extends Component { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err.message || err)) + .catch(err => err && displayWarning(err.message || err)) } } diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 0d8ff0db6..c38c39206 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -104,5 +104,5 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { setSelectedAddress(firstAddress) } }) - .catch(err => displayWarning(err.message || err)) + .catch(err => err && displayWarning(err.message || err)) } -- cgit From f19ffaf08d49f33c395a25faf3eeb6b08d5285a4 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 2 Jul 2018 15:16:05 -0400 Subject: move hardcoded strings to localization file --- .../pages/create-account/connect-hardware.js | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/connect-hardware.js b/ui/app/components/pages/create-account/connect-hardware.js index 152a4f275..d022d7487 100644 --- a/ui/app/components/pages/create-account/connect-hardware.js +++ b/ui/app/components/pages/create-account/connect-hardware.js @@ -4,7 +4,6 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('../../../actions') const genAccountLink = require('../../../../lib/account-link.js') -const log = require('loglevel') const { DEFAULT_ROUTE } = require('../../../routes') const { formatBalance } = require('../../../util') @@ -14,7 +13,7 @@ class ConnectHardwareForm extends Component { this.state = { error: null, response: null, - btnText: 'Connect to Trezor', // Test + btnText: context.t('connectToTrezor'), selectedAccount: '', accounts: [], } @@ -24,7 +23,7 @@ class ConnectHardwareForm extends Component { if (this.state.accounts.length) { return null } - this.setState({ btnText: 'Connecting...' }) + this.setState({ btnText: this.context.t('connecting')}) this.getPage(1) } @@ -37,21 +36,18 @@ class ConnectHardwareForm extends Component { } }) .catch(e => { - this.setState({ btnText: 'Connect to Trezor' }) + this.setState({ btnText: this.context.t('connectToTrezor') }) }) } unlockAccount () { if (this.state.selectedAccount === '') { - return Promise.reject({ error: 'You need to select an account!' }) + return Promise.reject({ error: this.context.t('accountSelectionRequired') }) } - log.debug('should unlock account ', this.state.selectedAccount) return this.props.unlockTrezorAccount(this.state.selectedAccount) } handleRadioChange = e => { - log.debug('Selected account with index ', e.target.value) - this.setState({ selectedAccount: e.target.value, error: null, @@ -60,12 +56,9 @@ class ConnectHardwareForm extends Component { getBalance (address) { // Get the balance - log.debug('getBalance : ', address) const { accounts } = this.props const balanceValue = accounts && accounts[address] ? accounts[address].balance : '' - log.debug('balanceValue : ', balanceValue) const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' - log.debug('formattedBalance : ', formattedBalance) return formattedBalance } @@ -74,12 +67,9 @@ class ConnectHardwareForm extends Component { return null } - log.debug('ACCOUNTS : ', this.state.accounts) - log.debug('SELECTED?', this.state.selectedAccount) - return h('div.hw-account-list', [ h('div.hw-account-list__title_wrapper', [ - h('div.hw-account-list__title', {}, ['Select an Address']), + h('div.hw-account-list__title', {}, [this.context.t('selectAnAddress')]), h('div.hw-account-list__device', {}, ['Trezor - ETH']), ]), this.state.accounts.map((a, i) => { @@ -127,7 +117,7 @@ class ConnectHardwareForm extends Component { { onClick: () => this.getPage(-1), }, - '< Prev' + `< ${this.context.t('prev')}` ), h( @@ -135,7 +125,7 @@ class ConnectHardwareForm extends Component { { onClick: () => this.getPage(1), }, - 'Next >' + `${this.context.t('next')} >` ), ]) } -- cgit From a8f745f9fe74751b87f500af3857b66d4c80f45e Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 2 Jul 2018 18:49:33 -0400 Subject: eslint --fix . --- ui/app/components/pages/create-account/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index 6e3b93742..5681e43a9 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -42,7 +42,7 @@ class CreateAccountPage extends Component { render () { return h('div.new-account', {}, [ h('div.new-account__header', [ - h('div.new-account__title', this.context.t('newAccount') ), + h('div.new-account__title', this.context.t('newAccount')), this.renderTabs(), ]), h('div.new-account__form', [ -- cgit From d126887bc3a795d27f54a4ca5178503e522d41d9 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Tue, 3 Jul 2018 09:47:30 -0700 Subject: fixes 4663 --- ui/app/components/pages/create-account/import-account/json.js | 1 + ui/app/components/pages/create-account/import-account/private-key.js | 1 + 2 files changed, 2 insertions(+) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/import-account/json.js b/ui/app/components/pages/create-account/import-account/json.js index 1dc2ba534..453fceb83 100644 --- a/ui/app/components/pages/create-account/import-account/json.js +++ b/ui/app/components/pages/create-account/import-account/json.js @@ -109,6 +109,7 @@ class JsonImportSubview extends Component { .then(({ selectedAddress }) => { if (selectedAddress) { history.push(DEFAULT_ROUTE) + displayWarning(null) } else { displayWarning('Error importing account.') setSelectedAddress(firstAddress) diff --git a/ui/app/components/pages/create-account/import-account/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js index 5df3777da..7a470c2ad 100644 --- a/ui/app/components/pages/create-account/import-account/private-key.js +++ b/ui/app/components/pages/create-account/import-account/private-key.js @@ -99,6 +99,7 @@ PrivateKeyImportView.prototype.createNewKeychain = function () { .then(({ selectedAddress }) => { if (selectedAddress) { history.push(DEFAULT_ROUTE) + displayWarning(null) } else { displayWarning('Error importing account.') setSelectedAddress(firstAddress) -- cgit From 9d3f2435e58e2454506ea1a5f7b85452a10edffa Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 3 Jul 2018 15:46:15 -0400 Subject: lint fix --- ui/app/components/pages/create-account/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js index ad2081315..d3de1ea01 100644 --- a/ui/app/components/pages/create-account/index.js +++ b/ui/app/components/pages/create-account/index.js @@ -12,7 +12,7 @@ const ConnectHardwareForm = require('./connect-hardware') const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE, - CONNECT_HARDWARE_ROUTE, + CONNECT_HARDWARE_ROUTE, } = require('../../../routes') class CreateAccountPage extends Component { -- cgit From f262f0ea64e1e803d8dcd9a31f92cffe81d27b3d Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 22 Jun 2018 14:41:18 -0230 Subject: Update import from seed screen on new ui. --- .../pages/keychains/restore-vault-new.js | 189 +++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 ui/app/components/pages/keychains/restore-vault-new.js (limited to 'ui/app/components/pages') diff --git a/ui/app/components/pages/keychains/restore-vault-new.js b/ui/app/components/pages/keychains/restore-vault-new.js new file mode 100644 index 000000000..ef38faf1e --- /dev/null +++ b/ui/app/components/pages/keychains/restore-vault-new.js @@ -0,0 +1,189 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import {connect} from 'react-redux' +import { + createNewVaultAndRestore, + unMarkPasswordForgotten, +} from '../../../actions' +import { DEFAULT_ROUTE } from '../../../routes' +import TextField from '../../text-field' + +class RestoreVaultPageNew extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + warning: PropTypes.string, + createNewVaultAndRestore: PropTypes.func.isRequired, + leaveImportSeedScreenState: PropTypes.func, + history: PropTypes.object, + isLoading: PropTypes.bool, + }; + + state = { + seedPhrase: '', + password: '', + confirmPassword: '', + seedPhraseError: null, + passwordError: null, + confirmPasswordError: null, + } + + parseSeedPhrase = (seedPhrase) => { + return seedPhrase + .match(/\w+/g) + .join(' ') + } + + handleSeedPhraseChange (seedPhrase) { + let seedPhraseError = null + + if (seedPhrase && this.parseSeedPhrase(seedPhrase).split(' ').length !== 12) { + seedPhraseError = this.context.t('seedPhraseReq') + } + + this.setState({ seedPhrase, seedPhraseError }) + } + + handlePasswordChange (password) { + const { confirmPassword } = this.state + let confirmPasswordError = null + let passwordError = null + + if (password && password.length < 8) { + passwordError = this.context.t('passwordNotLongEnough') + } + + if (confirmPassword && password !== confirmPassword) { + confirmPasswordError = this.context.t('passwordsDontMatch') + } + + this.setState({ password, passwordError, confirmPasswordError }) + } + + handleConfirmPasswordChange (confirmPassword) { + const { password } = this.state + let confirmPasswordError = null + + if (password !== confirmPassword) { + confirmPasswordError = this.context.t('passwordsDontMatch') + } + + this.setState({ confirmPassword, confirmPasswordError }) + } + + onClick = () => { + const { password, seedPhrase } = this.state + const { + createNewVaultAndRestore, + leaveImportSeedScreenState, + history, + } = this.props + + leaveImportSeedScreenState() + createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase)) + .then(() => history.push(DEFAULT_ROUTE)) + } + + hasError () { + const { passwordError, confirmPasswordError, seedPhraseError } = this.state + return passwordError || confirmPasswordError || seedPhraseError + } + + render () { + const { + seedPhrase, + password, + confirmPassword, + seedPhraseError, + passwordError, + confirmPasswordError, + } = this.state + const { t } = this.context + const { isLoading } = this.props + const disabled = !seedPhrase || !password || !confirmPassword || isLoading || this.hasError() + + return ( +
+
+
+ { + e.preventDefault() + this.props.history.goBack() + }} + href="#" + > + {`< Back`} + +
+ { this.context.t('restoreAccountWithSeed') } +
+
+ { this.context.t('secretPhrase') } +
+
+ +