mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Split ExportPrivateKeyModal into container and component files (#7561)
This commit is contained in:
parent
00060d787a
commit
f0e5ab6c12
@ -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),
|
|
||||||
|
|
||||||
])
|
|
||||||
}
|
|
@ -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 (
|
||||||
|
<span className="private-key-password-label">
|
||||||
|
{
|
||||||
|
privateKey
|
||||||
|
? this.context.t('copyPrivateKey')
|
||||||
|
: this.context.t('typePassword')
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPasswordInput (privateKey) {
|
||||||
|
const plainKey = privateKey && stripHexPrefix(privateKey)
|
||||||
|
|
||||||
|
if (!privateKey) {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
className="private-key-password-input"
|
||||||
|
onChange={event => this.setState({ password: event.target.value })}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReadOnlyInput
|
||||||
|
wrapperClass="private-key-password-display-wrapper"
|
||||||
|
inputClass="private-key-password-display-textarea"
|
||||||
|
textarea
|
||||||
|
value={plainKey}
|
||||||
|
onClick={() => copyToClipboard(plainKey)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons (privateKey, address, hideModal) {
|
||||||
|
return (
|
||||||
|
<div className="export-private-key-buttons">
|
||||||
|
{!privateKey && (
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
large
|
||||||
|
className="export-private-key__button export-private-key__button--cancel"
|
||||||
|
onClick={() => hideModal()}
|
||||||
|
>
|
||||||
|
{this.context.t('cancel')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{
|
||||||
|
privateKey
|
||||||
|
? (
|
||||||
|
<Button
|
||||||
|
onClick={() => hideModal()}
|
||||||
|
type="secondary"
|
||||||
|
large
|
||||||
|
className="export-private-key__button"
|
||||||
|
>
|
||||||
|
{this.context.t('done')}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<Button
|
||||||
|
onClick={() => this.exportAccountAndGetPrivateKey(this.state.password, address)}
|
||||||
|
type="secondary"
|
||||||
|
large
|
||||||
|
className="export-private-key__button"
|
||||||
|
disabled={!this.state.password}
|
||||||
|
>
|
||||||
|
{this.context.t('confirm')}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {
|
||||||
|
selectedIdentity,
|
||||||
|
warning,
|
||||||
|
showAccountDetailModal,
|
||||||
|
hideModal,
|
||||||
|
previousModalState,
|
||||||
|
} = this.props
|
||||||
|
const { name, address } = selectedIdentity
|
||||||
|
|
||||||
|
const {
|
||||||
|
privateKey,
|
||||||
|
showWarning,
|
||||||
|
} = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccountModalContainer
|
||||||
|
selectedIdentity={selectedIdentity}
|
||||||
|
showBackButton={previousModalState === 'ACCOUNT_DETAILS'}
|
||||||
|
backButtonAction={() => showAccountDetailModal()}
|
||||||
|
>
|
||||||
|
<span className="account-name">{name}</span>
|
||||||
|
<ReadOnlyInput
|
||||||
|
wrapperClass="ellip-address-wrapper"
|
||||||
|
inputClass="qr-ellip-address ellip-address"
|
||||||
|
value={checksumAddress(address)}
|
||||||
|
/>
|
||||||
|
<div className="account-modal-divider"/>
|
||||||
|
<span className="modal-body-title">{this.context.t('showPrivateKeys')}</span>
|
||||||
|
<div className="private-key-password">
|
||||||
|
{this.renderPasswordLabel(privateKey)}
|
||||||
|
{this.renderPasswordInput(privateKey)}
|
||||||
|
{
|
||||||
|
(showWarning && warning)
|
||||||
|
? <span className="private-key-password-error">{warning}</span>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="private-key-password-warning">{this.context.t('privateKeyWarning')}</div>
|
||||||
|
{this.renderButtons(privateKey, address, hideModal)}
|
||||||
|
</AccountModalContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
@ -0,0 +1 @@
|
|||||||
|
export { default } from './export-private-key-modal.container'
|
@ -12,7 +12,7 @@ const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums
|
|||||||
// Modal Components
|
// Modal Components
|
||||||
const DepositEtherModal = require('./deposit-ether-modal')
|
const DepositEtherModal = require('./deposit-ether-modal')
|
||||||
import AccountDetailsModal from './account-details-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 HideTokenConfirmationModal = require('./hide-token-confirmation-modal')
|
||||||
const NotifcationModal = require('./notification-modal')
|
const NotifcationModal = require('./notification-modal')
|
||||||
const QRScanner = require('./qr-scanner')
|
const QRScanner = require('./qr-scanner')
|
||||||
|
Loading…
Reference in New Issue
Block a user