aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/pages/create-account/import-account
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/pages/create-account/import-account')
-rw-r--r--ui/app/pages/create-account/import-account/index.js96
-rw-r--r--ui/app/pages/create-account/import-account/json.js170
-rw-r--r--ui/app/pages/create-account/import-account/private-key.js128
-rw-r--r--ui/app/pages/create-account/import-account/seed.js35
4 files changed, 429 insertions, 0 deletions
diff --git a/ui/app/pages/create-account/import-account/index.js b/ui/app/pages/create-account/import-account/index.js
new file mode 100644
index 000000000..48d8f8838
--- /dev/null
+++ b/ui/app/pages/create-account/import-account/index.js
@@ -0,0 +1,96 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
+const connect = require('react-redux').connect
+import Select from 'react-select'
+
+// Subviews
+const JsonImportView = require('./json.js')
+const PrivateKeyImportView = require('./private-key.js')
+
+
+AccountImportSubview.contextTypes = {
+ t: PropTypes.func,
+}
+
+module.exports = connect()(AccountImportSubview)
+
+
+inherits(AccountImportSubview, Component)
+function AccountImportSubview () {
+ Component.call(this)
+}
+
+AccountImportSubview.prototype.getMenuItemTexts = function () {
+ return [
+ this.context.t('privateKey'),
+ this.context.t('jsonFile'),
+ ]
+}
+
+AccountImportSubview.prototype.render = function () {
+ const state = this.state || {}
+ const menuItems = this.getMenuItemTexts()
+ const { type } = state
+
+ return (
+ h('div.new-account-import-form', [
+
+ h('.new-account-import-disclaimer', [
+ h('span', this.context.t('importAccountMsg')),
+ h('span', {
+ style: {
+ cursor: 'pointer',
+ textDecoration: 'underline',
+ },
+ onClick: () => {
+ global.platform.openWindow({
+ url: 'https://metamask.zendesk.com/hc/en-us/articles/360015289932',
+ })
+ },
+ }, this.context.t('here')),
+ ]),
+
+ h('div.new-account-import-form__select-section', [
+
+ h('div.new-account-import-form__select-label', this.context.t('selectType')),
+
+ h(Select, {
+ className: 'new-account-import-form__select',
+ name: 'import-type-select',
+ clearable: false,
+ value: type || menuItems[0],
+ options: menuItems.map((type) => {
+ return {
+ value: type,
+ label: type,
+ }
+ }),
+ onChange: (opt) => {
+ this.setState({ type: opt.value })
+ },
+ }),
+
+ ]),
+
+ this.renderImportView(),
+ ])
+ )
+}
+
+AccountImportSubview.prototype.renderImportView = function () {
+ const state = this.state || {}
+ const { type } = state
+ const menuItems = this.getMenuItemTexts()
+ const current = type || menuItems[0]
+
+ switch (current) {
+ case this.context.t('privateKey'):
+ return h(PrivateKeyImportView)
+ case this.context.t('jsonFile'):
+ return h(JsonImportView)
+ default:
+ return h(JsonImportView)
+ }
+}
diff --git a/ui/app/pages/create-account/import-account/json.js b/ui/app/pages/create-account/import-account/json.js
new file mode 100644
index 000000000..17bef763c
--- /dev/null
+++ b/ui/app/pages/create-account/import-account/json.js
@@ -0,0 +1,170 @@
+const Component = require('react').Component
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const connect = require('react-redux').connect
+const actions = require('../../../store/actions')
+const FileInput = require('react-simple-file-input').default
+const { DEFAULT_ROUTE } = require('../../../helpers/constants/routes')
+const { getMetaMaskAccounts } = require('../../../selectors/selectors')
+const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
+import Button from '../../../components/ui/button'
+
+class JsonImportSubview extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ file: null,
+ fileContents: '',
+ }
+ }
+
+ render () {
+ const { error } = this.props
+
+ return (
+ h('div.new-account-import-form__json', [
+
+ h('p', this.context.t('usedByClients')),
+ h('a.warning', {
+ href: HELP_LINK,
+ target: '_blank',
+ }, this.context.t('fileImportFail')),
+
+ h(FileInput, {
+ readAs: 'text',
+ onLoad: this.onLoad.bind(this),
+ style: {
+ margin: '20px 0px 12px 34%',
+ fontSize: '15px',
+ display: 'flex',
+ justifyContent: 'center',
+ },
+ }),
+
+ h('input.new-account-import-form__input-password', {
+ type: 'password',
+ placeholder: this.context.t('enterPassword'),
+ id: 'json-password-box',
+ onKeyPress: this.createKeyringOnEnter.bind(this),
+ }),
+
+ h('div.new-account-create-form__buttons', {}, [
+
+ h(Button, {
+ type: 'default',
+ large: true,
+ className: 'new-account-create-form__button',
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
+ }, [this.context.t('cancel')]),
+
+ h(Button, {
+ type: 'primary',
+ large: true,
+ className: 'new-account-create-form__button',
+ onClick: () => this.createNewKeychain(),
+ }, [this.context.t('import')]),
+
+ ]),
+
+ error ? h('span.error', error) : null,
+ ])
+ )
+ }
+
+ onLoad (event, file) {
+ this.setState({file: file, fileContents: event.target.result})
+ }
+
+ createKeyringOnEnter (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+ }
+
+ createNewKeychain () {
+ const { firstAddress, displayWarning, importNewJsonAccount, setSelectedAddress, history } = this.props
+ const state = this.state
+
+ if (!state) {
+ const message = this.context.t('validFileImport')
+ return displayWarning(message)
+ }
+
+ const { fileContents } = state
+
+ if (!fileContents) {
+ const message = this.context.t('needImportFile')
+ return displayWarning(message)
+ }
+
+ const passwordInput = document.getElementById('json-password-box')
+ const password = passwordInput.value
+
+ importNewJsonAccount([ fileContents, password ])
+ .then(({ selectedAddress }) => {
+ if (selectedAddress) {
+ history.push(DEFAULT_ROUTE)
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Accounts',
+ action: 'Import Account',
+ name: 'Imported Account with JSON',
+ },
+ })
+ displayWarning(null)
+ } else {
+ displayWarning('Error importing account.')
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Accounts',
+ action: 'Import Account',
+ name: 'Error importing JSON',
+ },
+ })
+ setSelectedAddress(firstAddress)
+ }
+ })
+ .catch(err => err && displayWarning(err.message || err))
+ }
+}
+
+JsonImportSubview.propTypes = {
+ error: PropTypes.string,
+ goHome: PropTypes.func,
+ displayWarning: PropTypes.func,
+ firstAddress: PropTypes.string,
+ importNewJsonAccount: PropTypes.func,
+ history: PropTypes.object,
+ setSelectedAddress: PropTypes.func,
+ t: PropTypes.func,
+}
+
+const mapStateToProps = state => {
+ return {
+ error: state.appState.warning,
+ firstAddress: Object.keys(getMetaMaskAccounts(state))[0],
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ displayWarning: warning => dispatch(actions.displayWarning(warning)),
+ importNewJsonAccount: options => dispatch(actions.importNewAccount('JSON File', options)),
+ setSelectedAddress: (address) => dispatch(actions.setSelectedAddress(address)),
+ }
+}
+
+JsonImportSubview.contextTypes = {
+ t: PropTypes.func,
+ metricsEvent: PropTypes.func,
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(JsonImportSubview)
diff --git a/ui/app/pages/create-account/import-account/private-key.js b/ui/app/pages/create-account/import-account/private-key.js
new file mode 100644
index 000000000..450614e87
--- /dev/null
+++ b/ui/app/pages/create-account/import-account/private-key.js
@@ -0,0 +1,128 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const PropTypes = require('prop-types')
+const connect = require('react-redux').connect
+const actions = require('../../../store/actions')
+const { DEFAULT_ROUTE } = require('../../../helpers/constants/routes')
+const { getMetaMaskAccounts } = require('../../../selectors/selectors')
+import Button from '../../../components/ui/button'
+
+PrivateKeyImportView.contextTypes = {
+ t: PropTypes.func,
+ metricsEvent: PropTypes.func,
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(PrivateKeyImportView)
+
+
+function mapStateToProps (state) {
+ return {
+ error: state.appState.warning,
+ firstAddress: Object.keys(getMetaMaskAccounts(state))[0],
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ importNewAccount: (strategy, [ privateKey ]) => {
+ return dispatch(actions.importNewAccount(strategy, [ privateKey ]))
+ },
+ displayWarning: (message) => dispatch(actions.displayWarning(message || null)),
+ setSelectedAddress: (address) => dispatch(actions.setSelectedAddress(address)),
+ }
+}
+
+inherits(PrivateKeyImportView, Component)
+function PrivateKeyImportView () {
+ this.createKeyringOnEnter = this.createKeyringOnEnter.bind(this)
+ Component.call(this)
+}
+
+PrivateKeyImportView.prototype.render = function () {
+ const { error, displayWarning } = this.props
+
+ return (
+ h('div.new-account-import-form__private-key', [
+
+ h('span.new-account-create-form__instruction', this.context.t('pastePrivateKey')),
+
+ h('div.new-account-import-form__private-key-password-container', [
+
+ h('input.new-account-import-form__input-password', {
+ type: 'password',
+ id: 'private-key-box',
+ onKeyPress: e => this.createKeyringOnEnter(e),
+ }),
+
+ ]),
+
+ h('div.new-account-import-form__buttons', {}, [
+
+ h(Button, {
+ type: 'default',
+ large: true,
+ className: 'new-account-create-form__button',
+ onClick: () => {
+ displayWarning(null)
+ this.props.history.push(DEFAULT_ROUTE)
+ },
+ }, [this.context.t('cancel')]),
+
+ h(Button, {
+ type: 'primary',
+ large: true,
+ className: 'new-account-create-form__button',
+ onClick: () => this.createNewKeychain(),
+ }, [this.context.t('import')]),
+
+ ]),
+
+ error ? h('span.error', error) : null,
+ ])
+ )
+}
+
+PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+}
+
+PrivateKeyImportView.prototype.createNewKeychain = function () {
+ const input = document.getElementById('private-key-box')
+ const privateKey = input.value
+ const { importNewAccount, history, displayWarning, setSelectedAddress, firstAddress } = this.props
+
+ importNewAccount('Private Key', [ privateKey ])
+ .then(({ selectedAddress }) => {
+ if (selectedAddress) {
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Accounts',
+ action: 'Import Account',
+ name: 'Imported Account with Private Key',
+ },
+ })
+ history.push(DEFAULT_ROUTE)
+ displayWarning(null)
+ } else {
+ displayWarning('Error importing account.')
+ this.context.metricsEvent({
+ eventOpts: {
+ category: 'Accounts',
+ action: 'Import Account',
+ name: 'Error importing with Private Key',
+ },
+ })
+ setSelectedAddress(firstAddress)
+ }
+ })
+ .catch(err => err && displayWarning(err.message || err))
+}
diff --git a/ui/app/pages/create-account/import-account/seed.js b/ui/app/pages/create-account/import-account/seed.js
new file mode 100644
index 000000000..d98909baa
--- /dev/null
+++ b/ui/app/pages/create-account/import-account/seed.js
@@ -0,0 +1,35 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
+const connect = require('react-redux').connect
+
+SeedImportSubview.contextTypes = {
+ t: PropTypes.func,
+}
+
+module.exports = connect(mapStateToProps)(SeedImportSubview)
+
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(SeedImportSubview, Component)
+function SeedImportSubview () {
+ Component.call(this)
+}
+
+SeedImportSubview.prototype.render = function () {
+ return (
+ h('div', {
+ style: {
+ },
+ }, [
+ this.context.t('pasteSeed'),
+ h('textarea'),
+ h('br'),
+ h('button', this.context.t('submit')),
+ ])
+ )
+}