diff --git a/ui/app/components/app/modals/export-private-key-modal.js b/ui/app/components/app/modals/export-private-key-modal.js deleted file mode 100644 index 215052015..000000000 --- a/ui/app/components/app/modals/export-private-key-modal.js +++ /dev/null @@ -1,178 +0,0 @@ -const log = require('loglevel') -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 { stripHexPrefix } = require('ethereumjs-util') -const actions = require('../../../store/actions') -const { getSelectedIdentity } = require('../../../selectors/selectors') -const ReadOnlyInput = require('../../ui/readonly-input') -const copyToClipboard = require('copy-to-clipboard') -const { checksumAddress } = require('../../../helpers/utils/util') -import AccountModalContainer from './account-modal-container' -import Button from '../../ui/button' - -function mapStateToPropsFactory () { - let selectedIdentity = null - return function mapStateToProps (state) { - // We should **not** change the identity displayed here even if it changes from underneath us. - // If we do, we will be showing the user one private key and a **different** address and name. - // Note that the selected identity **will** change from underneath us when we unlock the keyring - // which is the expected behavior that we are side-stepping. - selectedIdentity = selectedIdentity || getSelectedIdentity(state) - return { - warning: state.appState.warning, - privateKey: state.appState.accountDetail.privateKey, - network: state.metamask.network, - selectedIdentity, - previousModalState: state.appState.modal.previousModalState.name, - } - } -} - -function mapDispatchToProps (dispatch) { - return { - exportAccount: (password, address) => { - return dispatch(actions.exportAccount(password, address)) - .then((res) => { - dispatch(actions.hideWarning()) - return res - }) - }, - showAccountDetailModal: () => dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })), - hideModal: () => dispatch(actions.hideModal()), - } -} - -inherits(ExportPrivateKeyModal, Component) -function ExportPrivateKeyModal () { - Component.call(this) - - this.state = { - password: '', - privateKey: null, - showWarning: true, - } -} - -ExportPrivateKeyModal.contextTypes = { - t: PropTypes.func, -} - -module.exports = connect(mapStateToPropsFactory, mapDispatchToProps)(ExportPrivateKeyModal) - - -ExportPrivateKeyModal.prototype.exportAccountAndGetPrivateKey = function (password, address) { - const { exportAccount } = this.props - - exportAccount(password, address) - .then(privateKey => this.setState({ - privateKey, - showWarning: false, - })) - .catch((e) => log.error(e)) -} - -ExportPrivateKeyModal.prototype.renderPasswordLabel = function (privateKey) { - return h('span.private-key-password-label', privateKey - ? this.context.t('copyPrivateKey') - : this.context.t('typePassword') - ) -} - -ExportPrivateKeyModal.prototype.renderPasswordInput = function (privateKey) { - const plainKey = privateKey && stripHexPrefix(privateKey) - - return privateKey - ? h(ReadOnlyInput, { - wrapperClass: 'private-key-password-display-wrapper', - inputClass: 'private-key-password-display-textarea', - textarea: true, - value: plainKey, - onClick: () => copyToClipboard(plainKey), - }) - : h('input.private-key-password-input', { - type: 'password', - onChange: event => this.setState({ password: event.target.value }), - }) -} - -ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, address, hideModal) { - return h('div.export-private-key-buttons', {}, [ - !privateKey && h(Button, { - type: 'default', - large: true, - className: 'export-private-key__button export-private-key__button--cancel', - onClick: () => hideModal(), - }, this.context.t('cancel')), - - (privateKey - ? ( - h(Button, { - type: 'secondary', - large: true, - className: 'export-private-key__button', - onClick: () => hideModal(), - }, this.context.t('done')) - ) : ( - h(Button, { - type: 'secondary', - large: true, - className: 'export-private-key__button', - disabled: !this.state.password, - onClick: () => this.exportAccountAndGetPrivateKey(this.state.password, address), - }, this.context.t('confirm')) - ) - ), - - ]) -} - -ExportPrivateKeyModal.prototype.render = function () { - const { - selectedIdentity, - warning, - showAccountDetailModal, - hideModal, - previousModalState, - } = this.props - const { name, address } = selectedIdentity - - const { - privateKey, - showWarning, - } = this.state - - return h(AccountModalContainer, { - selectedIdentity, - showBackButton: previousModalState === 'ACCOUNT_DETAILS', - backButtonAction: () => showAccountDetailModal(), - }, [ - - h('span.account-name', name), - - h(ReadOnlyInput, { - wrapperClass: 'ellip-address-wrapper', - inputClass: 'qr-ellip-address ellip-address', - value: checksumAddress(address), - }), - - h('div.account-modal-divider'), - - h('span.modal-body-title', this.context.t('showPrivateKeys')), - - h('div.private-key-password', {}, [ - this.renderPasswordLabel(privateKey), - - this.renderPasswordInput(privateKey), - - showWarning && warning ? h('span.private-key-password-error', warning) : null, - ]), - - h('div.private-key-password-warning', this.context.t('privateKeyWarning')), - - this.renderButtons(privateKey, address, hideModal), - - ]) -} diff --git a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js new file mode 100644 index 000000000..264bcc041 --- /dev/null +++ b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js @@ -0,0 +1,168 @@ +import log from 'loglevel' +import PropTypes from 'prop-types' +import React, { Component } from 'react' + +const { stripHexPrefix } = require('ethereumjs-util') +const copyToClipboard = require('copy-to-clipboard') +const { checksumAddress } = require('../../../../helpers/utils/util') +const ReadOnlyInput = require('../../../ui/readonly-input') +import Button from '../../../ui/button' +import AccountModalContainer from '../account-modal-container' + +export default class ExportPrivateKeyModal extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static defaultProps = { + warning: null, + previousModalState: null, + } + + static propTypes = { + exportAccount: PropTypes.func.isRequired, + selectedIdentity: PropTypes.object.isRequired, + warning: PropTypes.node, + showAccountDetailModal: PropTypes.func.isRequired, + hideModal: PropTypes.func.isRequired, + previousModalState: PropTypes.string, + } + + state = { + password: '', + privateKey: null, + showWarning: true, + } + + exportAccountAndGetPrivateKey = (password, address) => { + const { exportAccount } = this.props + + exportAccount(password, address) + .then(privateKey => this.setState({ + privateKey, + showWarning: false, + })) + .catch((e) => log.error(e)) + } + + renderPasswordLabel (privateKey) { + return ( + + { + privateKey + ? this.context.t('copyPrivateKey') + : this.context.t('typePassword') + } + + ) + } + + renderPasswordInput (privateKey) { + const plainKey = privateKey && stripHexPrefix(privateKey) + + if (!privateKey) { + return ( + this.setState({ password: event.target.value })} + /> + ) + } + + return ( + copyToClipboard(plainKey)} + /> + ) + } + + renderButtons (privateKey, address, hideModal) { + return ( +
+ {!privateKey && ( + + )} + { + privateKey + ? ( + + ) + : ( + + ) + } +
+ ) + } + + render () { + const { + selectedIdentity, + warning, + showAccountDetailModal, + hideModal, + previousModalState, + } = this.props + const { name, address } = selectedIdentity + + const { + privateKey, + showWarning, + } = this.state + + return ( + showAccountDetailModal()} + > + {name} + +
+ {this.context.t('showPrivateKeys')} +
+ {this.renderPasswordLabel(privateKey)} + {this.renderPasswordInput(privateKey)} + { + (showWarning && warning) + ? {warning} + : null + } +
+
{this.context.t('privateKeyWarning')}
+ {this.renderButtons(privateKey, address, hideModal)} + + ) + } +} diff --git a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js new file mode 100644 index 000000000..1b8f63c94 --- /dev/null +++ b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js @@ -0,0 +1,38 @@ +import { connect } from 'react-redux' +import { exportAccount, hideWarning, showModal, hideModal } from '../../../../store/actions' +import { getSelectedIdentity } from '../../../../selectors/selectors' +import ExportPrivateKeyModal from './export-private-key-modal.component' + +function mapStateToPropsFactory () { + let selectedIdentity = null + return function mapStateToProps (state) { + // We should **not** change the identity displayed here even if it changes from underneath us. + // If we do, we will be showing the user one private key and a **different** address and name. + // Note that the selected identity **will** change from underneath us when we unlock the keyring + // which is the expected behavior that we are side-stepping. + selectedIdentity = selectedIdentity || getSelectedIdentity(state) + return { + warning: state.appState.warning, + privateKey: state.appState.accountDetail.privateKey, + network: state.metamask.network, + selectedIdentity, + previousModalState: state.appState.modal.previousModalState.name, + } + } +} + +function mapDispatchToProps (dispatch) { + return { + exportAccount: (password, address) => { + return dispatch(exportAccount(password, address)) + .then((res) => { + dispatch(hideWarning()) + return res + }) + }, + showAccountDetailModal: () => dispatch(showModal({ name: 'ACCOUNT_DETAILS' })), + hideModal: () => dispatch(hideModal()), + } +} + +export default connect(mapStateToPropsFactory, mapDispatchToProps)(ExportPrivateKeyModal) diff --git a/ui/app/components/app/modals/export-private-key-modal/index.js b/ui/app/components/app/modals/export-private-key-modal/index.js new file mode 100644 index 000000000..996c995ca --- /dev/null +++ b/ui/app/components/app/modals/export-private-key-modal/index.js @@ -0,0 +1 @@ +export { default } from './export-private-key-modal.container' diff --git a/ui/app/components/app/modals/modal.js b/ui/app/components/app/modals/modal.js index ada758b99..27162bdd5 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 DepositEtherModal = require('./deposit-ether-modal') import AccountDetailsModal from './account-details-modal' -const ExportPrivateKeyModal = require('./export-private-key-modal') +const ExportPrivateKeyModal = require('./export-private-key-modal').default const HideTokenConfirmationModal = require('./hide-token-confirmation-modal') const NotifcationModal = require('./notification-modal') const QRScanner = require('./qr-scanner')