aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/app/components/app/modals/account-details-modal.js107
-rw-r--r--ui/app/components/app/modals/account-details-modal/account-details-modal.component.js87
-rw-r--r--ui/app/components/app/modals/account-details-modal/account-details-modal.container.js27
-rw-r--r--ui/app/components/app/modals/account-details-modal/index.js1
-rw-r--r--ui/app/components/app/modals/modal.js2
-rw-r--r--ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js19
-rw-r--r--ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js78
-rw-r--r--ui/app/pages/keychains/restore-vault.js1
8 files changed, 210 insertions, 112 deletions
diff --git a/ui/app/components/app/modals/account-details-modal.js b/ui/app/components/app/modals/account-details-modal.js
deleted file mode 100644
index 6cffc918b..000000000
--- a/ui/app/components/app/modals/account-details-modal.js
+++ /dev/null
@@ -1,107 +0,0 @@
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../../../store/actions')
-const AccountModalContainer = require('./account-modal-container')
-const { getSelectedIdentity, getRpcPrefsForCurrentProvider } = require('../../../selectors/selectors')
-const genAccountLink = require('../../../../lib/account-link.js')
-const QrView = require('../../ui/qr-code')
-const EditableLabel = require('../../ui/editable-label')
-
-import Button from '../../ui/button'
-
-function mapStateToProps (state) {
- return {
- network: state.metamask.network,
- selectedIdentity: getSelectedIdentity(state),
- keyrings: state.metamask.keyrings,
- rpcPrefs: getRpcPrefsForCurrentProvider(state),
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- // Is this supposed to be used somewhere?
- showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
- showExportPrivateKeyModal: () => {
- dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
- },
- hideModal: () => dispatch(actions.hideModal()),
- setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
- }
-}
-
-inherits(AccountDetailsModal, Component)
-function AccountDetailsModal () {
- Component.call(this)
-}
-
-AccountDetailsModal.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
-
-
-// Not yet pixel perfect todos:
- // fonts of qr-header
-
-AccountDetailsModal.prototype.render = function () {
- const {
- selectedIdentity,
- network,
- showExportPrivateKeyModal,
- setAccountLabel,
- keyrings,
- rpcPrefs,
- } = this.props
- const { name, address } = selectedIdentity
-
- const keyring = keyrings.find((kr) => {
- return kr.accounts.includes(address)
- })
-
- let exportPrivateKeyFeatureEnabled = true
- // This feature is disabled for hardware wallets
- if (keyring && keyring.type.search('Hardware') !== -1) {
- exportPrivateKeyFeatureEnabled = false
- }
-
- return h(AccountModalContainer, {}, [
- h(EditableLabel, {
- className: 'account-modal__name',
- defaultValue: name,
- onSubmit: label => setAccountLabel(address, label),
- }),
-
- h(QrView, {
- Qr: {
- data: address,
- network: network,
- },
- }),
-
- h('div.account-modal-divider'),
-
- h(Button, {
- type: 'secondary',
- className: 'account-modal__button',
- onClick: () => {
- global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) })
- },
- }, (rpcPrefs.blockExplorerUrl
- ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]])
- : this.context.t('viewOnEtherscan'))),
-
- // Holding on redesign for Export Private Key functionality
-
- exportPrivateKeyFeatureEnabled ? h(Button, {
- type: 'secondary',
- className: 'account-modal__button',
- onClick: () => showExportPrivateKeyModal(),
- }, this.context.t('exportPrivateKey')) : null,
-
- ])
-}
diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js
new file mode 100644
index 000000000..e3919edcf
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js
@@ -0,0 +1,87 @@
+import React, { Component} from 'react'
+import PropTypes from 'prop-types'
+import AccountModalContainer from '../account-modal-container'
+import genAccountLink from '../../../../../lib/account-link.js'
+import QrView from '../../../ui/qr-code'
+import EditableLabel from '../../../ui/editable-label'
+import Button from '../../../ui/button'
+
+export default class AccountDetailsModal extends Component {
+ static propTypes = {
+ selectedIdentity: PropTypes.object,
+ network: PropTypes.string,
+ showExportPrivateKeyModal: PropTypes.func,
+ setAccountLabel: PropTypes.func,
+ keyrings: PropTypes.array,
+ rpcPrefs: PropTypes.object,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ render () {
+ const {
+ selectedIdentity,
+ network,
+ showExportPrivateKeyModal,
+ setAccountLabel,
+ keyrings,
+ rpcPrefs,
+ } = this.props
+ const { name, address } = selectedIdentity
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(address)
+ })
+
+ let exportPrivateKeyFeatureEnabled = true
+ // This feature is disabled for hardware wallets
+ if (keyring && keyring.type.search('Hardware') !== -1) {
+ exportPrivateKeyFeatureEnabled = false
+ }
+
+ return (
+ <AccountModalContainer>
+ <EditableLabel
+ className="account-modal__name"
+ defaultValue={name}
+ onSubmit={label => setAccountLabel(address, label)}
+ />
+
+ <QrView
+ Qr={{
+ data: address,
+ network: network,
+ }}
+ />
+
+ <div className="account-modal-divider"/>
+
+ <Button
+ type="secondary"
+ className="account-modal__button"
+ onClick={() => {
+ global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) })
+ }}
+ >
+ {rpcPrefs.blockExplorerUrl
+ ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]])
+ : this.context.t('viewOnEtherscan')
+ }
+ </Button>
+
+ {exportPrivateKeyFeatureEnabled
+ ? <Button
+ type="secondary"
+ className="account-modal__button"
+ onClick={() => showExportPrivateKeyModal()}
+ >
+ {this.context.t('exportPrivateKey')}
+ </Button>
+ : null
+ }
+ </AccountModalContainer>
+ )
+ }
+}
diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js
new file mode 100644
index 000000000..4b2283ced
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js
@@ -0,0 +1,27 @@
+import { connect } from 'react-redux'
+import actions from '../../../../store/actions'
+import { getSelectedIdentity, getRpcPrefsForCurrentProvider } from '../../../../selectors/selectors'
+import AccountDetailsModal from './account-details-modal.component'
+
+const mapStateToProps = (state) => {
+ return {
+ network: state.metamask.network,
+ selectedIdentity: getSelectedIdentity(state),
+ keyrings: state.metamask.keyrings,
+ rpcPrefs: getRpcPrefsForCurrentProvider(state),
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ // Is this supposed to be used somewhere?
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
diff --git a/ui/app/components/app/modals/account-details-modal/index.js b/ui/app/components/app/modals/account-details-modal/index.js
new file mode 100644
index 000000000..433f4d170
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/index.js
@@ -0,0 +1 @@
+export { default } from './account-details-modal.container'
diff --git a/ui/app/components/app/modals/modal.js b/ui/app/components/app/modals/modal.js
index 90432da96..394367c46 100644
--- a/ui/app/components/app/modals/modal.js
+++ b/ui/app/components/app/modals/modal.js
@@ -12,7 +12,7 @@ const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums
// Modal Components
const BuyOptions = require('./buy-options-modal')
const DepositEtherModal = require('./deposit-ether-modal')
-const AccountDetailsModal = require('./account-details-modal')
+import AccountDetailsModal from './account-details-modal'
const EditAccountNameModal = require('./edit-account-name-modal')
const ExportPrivateKeyModal = require('./export-private-key-modal')
const NewAccountModal = require('./new-account-modal')
diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
index 5092d277e..a2fb5a3bf 100644
--- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
+++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
@@ -30,10 +30,21 @@ export default class ImportWithSeedPhrase extends PureComponent {
}
parseSeedPhrase = (seedPhrase) => {
- return seedPhrase
- .trim()
- .match(/\w+/g)
- .join(' ')
+ if (!seedPhrase) {
+ return ''
+ }
+
+ const trimmed = seedPhrase.trim()
+ if (!trimmed) {
+ return ''
+ }
+
+ const words = trimmed.match(/\w+/g)
+ if (!words) {
+ return ''
+ }
+
+ return words.join(' ')
}
componentWillMount () {
diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js
new file mode 100644
index 000000000..7960d17b2
--- /dev/null
+++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js
@@ -0,0 +1,78 @@
+import React from 'react'
+import assert from 'assert'
+import { shallow } from 'enzyme'
+import sinon from 'sinon'
+import ImportWithSeedPhrase from '../import-with-seed-phrase.component'
+
+function shallowRender (props = {}, context = {}) {
+ return shallow(<ImportWithSeedPhrase {...props} />, {
+ context: {
+ t: str => str + '_t',
+ metricsEvent: sinon.spy(),
+ ...context,
+ },
+ })
+}
+
+describe('ImportWithSeedPhrase Component', () => {
+ it('should render without error', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+ const textareaCount = root.find('.first-time-flow__textarea').length
+ assert.equal(textareaCount, 1, 'should render 12 seed phrases')
+ })
+
+ describe('parseSeedPhrase', () => {
+ it('should handle a regular seed phrase', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz')
+ })
+
+ it('should trim extraneous whitespace from the given seed phrase', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(' foo bar baz '), 'foo bar baz')
+ })
+
+ it('should return an empty string when given a whitespace-only string', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(' '), '')
+ })
+
+ it('should return an empty string when given a string with only symbols', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase('$'), '')
+ })
+
+ it('should return an empty string for both null and undefined', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(undefined), '')
+ assert.deepEqual(parseSeedPhrase(null), '')
+ })
+ })
+})
diff --git a/ui/app/pages/keychains/restore-vault.js b/ui/app/pages/keychains/restore-vault.js
index 574949258..08164fd9f 100644
--- a/ui/app/pages/keychains/restore-vault.js
+++ b/ui/app/pages/keychains/restore-vault.js
@@ -123,6 +123,7 @@ class RestoreVaultPage extends Component {
className="import-account__back-button"
onClick={e => {
e.preventDefault()
+ this.props.leaveImportSeedScreenState()
this.props.history.goBack()
}}
href="#"