2021-02-04 19:15:23 +01:00
|
|
|
import log from 'loglevel';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React, { Component } from 'react';
|
2019-11-27 16:06:31 +01:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
import copyToClipboard from 'copy-to-clipboard';
|
|
|
|
import Button from '../../../ui/button';
|
|
|
|
import AccountModalContainer from '../account-modal-container';
|
2022-09-22 17:04:24 +02:00
|
|
|
import {
|
|
|
|
toChecksumHexAddress,
|
|
|
|
stripHexPrefix,
|
|
|
|
} from '../../../../../shared/modules/hexstring-utils';
|
2022-08-16 18:39:23 +02:00
|
|
|
import {
|
|
|
|
EVENT,
|
|
|
|
EVENT_NAMES,
|
|
|
|
} from '../../../../../shared/constants/metametrics';
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
export default class ExportPrivateKeyModal extends Component {
|
|
|
|
static contextTypes = {
|
|
|
|
t: PropTypes.func,
|
2022-08-16 18:39:23 +02:00
|
|
|
trackEvent: PropTypes.func,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
warning: null,
|
|
|
|
previousModalState: null,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
exportAccount: PropTypes.func.isRequired,
|
|
|
|
selectedIdentity: PropTypes.object.isRequired,
|
|
|
|
warning: PropTypes.node,
|
|
|
|
showAccountDetailModal: PropTypes.func.isRequired,
|
|
|
|
hideModal: PropTypes.func.isRequired,
|
2020-08-27 01:19:41 +02:00
|
|
|
hideWarning: PropTypes.func.isRequired,
|
2020-08-15 01:08:26 +02:00
|
|
|
clearAccountDetails: PropTypes.func.isRequired,
|
2019-11-27 16:06:31 +01:00
|
|
|
previousModalState: PropTypes.string,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
state = {
|
|
|
|
password: '',
|
|
|
|
privateKey: null,
|
|
|
|
showWarning: true,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2019-11-27 16:06:31 +01:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
componentWillUnmount() {
|
2021-02-04 19:15:23 +01:00
|
|
|
this.props.clearAccountDetails();
|
|
|
|
this.props.hideWarning();
|
2020-08-15 01:08:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-27 16:06:31 +01:00
|
|
|
exportAccountAndGetPrivateKey = (password, address) => {
|
2021-02-04 19:15:23 +01:00
|
|
|
const { exportAccount } = this.props;
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
exportAccount(password, address)
|
2022-08-16 18:39:23 +02:00
|
|
|
.then((privateKey) => {
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: EVENT.CATEGORIES.KEYS,
|
|
|
|
event: EVENT_NAMES.KEY_EXPORT_REVEALED,
|
|
|
|
properties: {
|
|
|
|
key_type: EVENT.KEY_TYPES.PKEY,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
this.setState({
|
|
|
|
privateKey,
|
|
|
|
showWarning: false,
|
2022-08-16 18:39:23 +02:00
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch((e) => {
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: EVENT.CATEGORIES.KEYS,
|
|
|
|
event: EVENT_NAMES.KEY_EXPORT_FAILED,
|
|
|
|
properties: {
|
|
|
|
key_type: EVENT.KEY_TYPES.PKEY,
|
|
|
|
reason: 'incorrect_password',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
log.error(e);
|
|
|
|
});
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2019-11-27 16:06:31 +01:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderPasswordLabel(privateKey) {
|
2019-11-27 16:06:31 +01:00
|
|
|
return (
|
2020-08-11 18:07:47 +02:00
|
|
|
<span className="export-private-key-modal__password-label">
|
2020-11-03 00:41:28 +01:00
|
|
|
{privateKey
|
|
|
|
? this.context.t('copyPrivateKey')
|
|
|
|
: this.context.t('typePassword')}
|
2019-11-27 16:06:31 +01:00
|
|
|
</span>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-11-27 16:06:31 +01:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderPasswordInput(privateKey) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const plainKey = privateKey && stripHexPrefix(privateKey);
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
if (!privateKey) {
|
|
|
|
return (
|
|
|
|
<input
|
|
|
|
type="password"
|
2020-08-11 18:07:47 +02:00
|
|
|
className="export-private-key-modal__password-input"
|
2020-02-15 21:34:12 +01:00
|
|
|
onChange={(event) => this.setState({ password: event.target.value })}
|
2019-11-27 16:06:31 +01:00
|
|
|
/>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-11-27 16:06:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-04-04 17:07:01 +02:00
|
|
|
<div
|
|
|
|
className="export-private-key-modal__private-key-display"
|
2022-08-16 18:39:23 +02:00
|
|
|
onClick={() => {
|
|
|
|
copyToClipboard(plainKey);
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: EVENT.CATEGORIES.KEYS,
|
|
|
|
event: EVENT_NAMES.KEY_EXPORT_COPIED,
|
|
|
|
properties: {
|
|
|
|
key_type: EVENT.KEY_TYPES.PKEY,
|
|
|
|
copy_method: 'clipboard',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}}
|
2022-04-04 17:07:01 +02:00
|
|
|
>
|
|
|
|
{plainKey}
|
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-11-27 16:06:31 +01:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderButtons(privateKey, address, hideModal) {
|
2019-11-27 16:06:31 +01:00
|
|
|
return (
|
2020-08-11 18:07:47 +02:00
|
|
|
<div className="export-private-key-modal__buttons">
|
2019-11-27 16:06:31 +01:00
|
|
|
{!privateKey && (
|
|
|
|
<Button
|
2021-10-05 21:20:42 +02:00
|
|
|
type="secondary"
|
2019-11-27 16:06:31 +01:00
|
|
|
large
|
2020-08-11 18:07:47 +02:00
|
|
|
className="export-private-key-modal__button export-private-key-modal__button--cancel"
|
2022-08-16 18:39:23 +02:00
|
|
|
onClick={() => {
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: EVENT.CATEGORIES.KEYS,
|
|
|
|
event: EVENT_NAMES.KEY_EXPORT_CANCELED,
|
|
|
|
properties: {
|
|
|
|
key_type: EVENT.KEY_TYPES.PKEY,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
hideModal();
|
|
|
|
}}
|
2019-11-27 16:06:31 +01:00
|
|
|
>
|
|
|
|
{this.context.t('cancel')}
|
|
|
|
</Button>
|
|
|
|
)}
|
2020-11-03 00:41:28 +01:00
|
|
|
{privateKey ? (
|
|
|
|
<Button
|
2022-08-16 18:39:23 +02:00
|
|
|
onClick={() => {
|
|
|
|
hideModal();
|
|
|
|
}}
|
2021-10-05 21:20:42 +02:00
|
|
|
type="primary"
|
2020-11-03 00:41:28 +01:00
|
|
|
large
|
|
|
|
className="export-private-key-modal__button"
|
|
|
|
>
|
|
|
|
{this.context.t('done')}
|
|
|
|
</Button>
|
|
|
|
) : (
|
|
|
|
<Button
|
2022-08-16 18:39:23 +02:00
|
|
|
onClick={() => {
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: EVENT.CATEGORIES.KEYS,
|
|
|
|
event: EVENT_NAMES.KEY_EXPORT_REQUESTED,
|
|
|
|
properties: {
|
|
|
|
key_type: EVENT.KEY_TYPES.PKEY,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
this.exportAccountAndGetPrivateKey(this.state.password, address);
|
|
|
|
}}
|
2021-10-05 21:20:42 +02:00
|
|
|
type="primary"
|
2020-11-03 00:41:28 +01:00
|
|
|
large
|
|
|
|
className="export-private-key-modal__button"
|
|
|
|
disabled={!this.state.password}
|
|
|
|
>
|
|
|
|
{this.context.t('confirm')}
|
|
|
|
</Button>
|
|
|
|
)}
|
2019-11-27 16:06:31 +01:00
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-11-27 16:06:31 +01:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
render() {
|
2019-11-27 16:06:31 +01:00
|
|
|
const {
|
|
|
|
selectedIdentity,
|
|
|
|
warning,
|
|
|
|
showAccountDetailModal,
|
|
|
|
hideModal,
|
|
|
|
previousModalState,
|
2021-02-04 19:15:23 +01:00
|
|
|
} = this.props;
|
|
|
|
const { name, address } = selectedIdentity;
|
2019-11-27 16:06:31 +01:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
const { privateKey, showWarning } = this.state;
|
2019-11-27 16:06:31 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<AccountModalContainer
|
2020-08-11 18:07:47 +02:00
|
|
|
className="export-private-key-modal"
|
2019-11-27 16:06:31 +01:00
|
|
|
selectedIdentity={selectedIdentity}
|
|
|
|
showBackButton={previousModalState === 'ACCOUNT_DETAILS'}
|
|
|
|
backButtonAction={() => showAccountDetailModal()}
|
|
|
|
>
|
2020-08-11 18:07:47 +02:00
|
|
|
<span className="export-private-key-modal__account-name">{name}</span>
|
2022-04-04 17:07:01 +02:00
|
|
|
<div className="ellip-address-wrapper">
|
|
|
|
{toChecksumHexAddress(address)}
|
|
|
|
</div>
|
2020-08-11 18:07:47 +02:00
|
|
|
<div className="export-private-key-modal__divider" />
|
2020-11-03 00:41:28 +01:00
|
|
|
<span className="export-private-key-modal__body-title">
|
|
|
|
{this.context.t('showPrivateKeys')}
|
|
|
|
</span>
|
2020-08-11 18:07:47 +02:00
|
|
|
<div className="export-private-key-modal__password">
|
2019-11-27 16:06:31 +01:00
|
|
|
{this.renderPasswordLabel(privateKey)}
|
|
|
|
{this.renderPasswordInput(privateKey)}
|
2020-11-03 00:41:28 +01:00
|
|
|
{showWarning && warning ? (
|
|
|
|
<span className="export-private-key-modal__password--error">
|
|
|
|
{warning}
|
|
|
|
</span>
|
|
|
|
) : null}
|
|
|
|
</div>
|
|
|
|
<div className="export-private-key-modal__password--warning">
|
|
|
|
{this.context.t('privateKeyWarning')}
|
2019-11-27 16:06:31 +01:00
|
|
|
</div>
|
|
|
|
{this.renderButtons(privateKey, address, hideModal)}
|
|
|
|
</AccountModalContainer>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-11-27 16:06:31 +01:00
|
|
|
}
|
|
|
|
}
|