diff --git a/ui/app/components/app/signature-request-original.js b/ui/app/components/app/signature-request-original.js deleted file mode 100644 index e23d724cb..000000000 --- a/ui/app/components/app/signature-request-original.js +++ /dev/null @@ -1,357 +0,0 @@ -const Component = require('react').Component -const PropTypes = require('prop-types') -const h = require('react-hyperscript') -const inherits = require('util').inherits -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import Identicon from '../ui/identicon' -const connect = require('react-redux').connect -const ethUtil = require('ethereumjs-util') -const classnames = require('classnames') -const { compose } = require('recompose') -const { withRouter } = require('react-router-dom') -const { ObjectInspector } = require('react-inspector') - -import AccountListItem from '../../pages/send/account-list-item/account-list-item.component' - -const actions = require('../../store/actions') -const { conversionUtil } = require('../../helpers/utils/conversion-util') - -const { - getSelectedAccount, - getCurrentAccountWithSendEtherInfo, - getSelectedAddress, - conversionRateSelector, -} = require('../../selectors/selectors.js') - -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import Button from '../ui/button' - -const { DEFAULT_ROUTE } = require('../../helpers/constants/routes') - -function mapStateToProps (state) { - return { - balance: getSelectedAccount(state).balance, - selectedAccount: getCurrentAccountWithSendEtherInfo(state), - selectedAddress: getSelectedAddress(state), - requester: null, - requesterAddress: null, - conversionRate: conversionRateSelector(state), - } -} - -function mapDispatchToProps (dispatch) { - return { - goHome: () => dispatch(actions.goHome()), - clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - } -} - -function mergeProps (stateProps, dispatchProps, ownProps) { - const { - signPersonalMessage, - signTypedMessage, - cancelPersonalMessage, - cancelTypedMessage, - signMessage, - cancelMessage, - txData, - } = ownProps - - const { type } = txData - - let cancel - let sign - if (type === 'personal_sign') { - cancel = cancelPersonalMessage - sign = signPersonalMessage - } else if (type === 'eth_signTypedData') { - cancel = cancelTypedMessage - sign = signTypedMessage - } else if (type === 'eth_sign') { - cancel = cancelMessage - sign = signMessage - } - - return { - ...ownProps, - ...stateProps, - ...dispatchProps, - txData, - cancel, - sign, - } -} - -SignatureRequest.contextTypes = { - t: PropTypes.func, - metricsEvent: PropTypes.func, -} - -module.exports = compose( - withRouter, - connect(mapStateToProps, mapDispatchToProps, mergeProps) -)(SignatureRequest) - - -inherits(SignatureRequest, Component) -function SignatureRequest (props) { - Component.call(this) - - this.state = { - selectedAccount: props.selectedAccount, - } - this._beforeUnload = this._beforeUnload.bind(this) -} - -SignatureRequest.prototype._beforeUnload = function (event) { - const { clearConfirmTransaction, cancel } = this.props - const { metricsEvent } = this.context - metricsEvent({ - eventOpts: { - category: 'Transactions', - action: 'Sign Request', - name: 'Cancel Sig Request Via Notification Close', - }, - }) - clearConfirmTransaction() - cancel(event) -} - -SignatureRequest.prototype._removeBeforeUnload = function () { - if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION) { - window.removeEventListener('beforeunload', this._beforeUnload) - } -} - -SignatureRequest.prototype.componentDidMount = function () { - if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION) { - window.addEventListener('beforeunload', this._beforeUnload) - } -} - -SignatureRequest.prototype.componentWillUnmount = function () { - this._removeBeforeUnload() -} - -SignatureRequest.prototype.renderHeader = function () { - return h('div.request-signature__header', [ - - h('div.request-signature__header-background'), - - h('div.request-signature__header__text', this.context.t('sigRequest')), - - h('div.request-signature__header__tip-container', [ - h('div.request-signature__header__tip'), - ]), - - ]) -} - -SignatureRequest.prototype.renderAccount = function () { - const { selectedAccount } = this.state - - return h('div.request-signature__account', [ - - h('div.request-signature__account-text', [this.context.t('account') + ':']), - - h('div.request-signature__account-item', [ - h(AccountListItem, { - account: selectedAccount, - displayBalance: false, - }), - ]), - ]) -} - -SignatureRequest.prototype.renderBalance = function () { - const { balance, conversionRate } = this.props - - const balanceInEther = conversionUtil(balance, { - fromNumericBase: 'hex', - toNumericBase: 'dec', - fromDenomination: 'WEI', - numberOfDecimals: 6, - conversionRate, - }) - - return h('div.request-signature__balance', [ - - h('div.request-signature__balance-text', `${this.context.t('balance')}:`), - - h('div.request-signature__balance-value', `${balanceInEther} ETH`), - - ]) -} - -SignatureRequest.prototype.renderAccountInfo = function () { - return h('div.request-signature__account-info', [ - - this.renderAccount(), - - this.renderRequestIcon(), - - this.renderBalance(), - - ]) -} - -SignatureRequest.prototype.renderRequestIcon = function () { - const { requesterAddress } = this.props - - return h('div.request-signature__request-icon', [ - h(Identicon, { - diameter: 40, - address: requesterAddress, - }), - ]) -} - -SignatureRequest.prototype.renderRequestInfo = function () { - return h('div.request-signature__request-info', [ - - h('div.request-signature__headline', [ - this.context.t('yourSigRequested'), - ]), - - ]) -} - -SignatureRequest.prototype.msgHexToText = function (hex) { - try { - const stripped = ethUtil.stripHexPrefix(hex) - const buff = Buffer.from(stripped, 'hex') - return buff.length === 32 ? hex : buff.toString('utf8') - } catch (e) { - return hex - } -} - -// eslint-disable-next-line react/display-name -SignatureRequest.prototype.renderTypedData = function (data) { - const { domain, message } = JSON.parse(data) - return [ - h('div.request-signature__typed-container', [ - domain ? h('div', [ - h('h1', 'Domain'), - h(ObjectInspector, { data: domain, expandLevel: 1, name: 'domain' }), - ]) : '', - message ? h('div', [ - h('h1', 'Message'), - h(ObjectInspector, { data: message, expandLevel: 1, name: 'message' }), - ]) : '', - ]), - ] -} - -SignatureRequest.prototype.renderBody = function () { - let rows - let notice = this.context.t('youSign') + ':' - - const { txData } = this.props - const { type, msgParams: { data } } = txData - - if (type === 'personal_sign') { - rows = [{ name: this.context.t('message'), value: this.msgHexToText(data) }] - } else if (type === 'eth_signTypedData') { - rows = data - } else if (type === 'eth_sign') { - rows = [{ name: this.context.t('message'), value: data }] - notice = [this.context.t('signNotice'), - h('span.request-signature__help-link', { - onClick: () => { - global.platform.openWindow({ - url: 'https://metamask.zendesk.com/hc/en-us/articles/360015488751', - }) - }, - }, this.context.t('learnMore'))] - } - - return h('div.request-signature__body', {}, [ - - this.renderAccountInfo(), - - this.renderRequestInfo(), - - h('div.request-signature__notice', { - className: classnames({ - 'request-signature__notice': type === 'personal_sign' || type === 'eth_signTypedData', - 'request-signature__warning': type === 'eth_sign', - }), - }, [notice]), - - h('div.request-signature__rows', - rows.map(({ name, value }, index) => { - if (typeof value === 'boolean') { - value = value.toString() - } - return h('div.request-signature__row', { key: `request-signature-row-${index}` }, [ - h('div.request-signature__row-title', [`${name}:`]), - h('div.request-signature__row-value', value), - ]) - }) - ), - ]) -} - -SignatureRequest.prototype.renderFooter = function () { - const { cancel, sign } = this.props - - return h('div.request-signature__footer', [ - h(Button, { - type: 'default', - large: true, - className: 'request-signature__footer__cancel-button', - onClick: event => { - this._removeBeforeUnload() - cancel(event).then(() => { - this.context.metricsEvent({ - eventOpts: { - category: 'Transactions', - action: 'Sign Request', - name: 'Cancel', - }, - }) - this.props.clearConfirmTransaction() - this.props.history.push(DEFAULT_ROUTE) - }) - }, - }, this.context.t('cancel')), - h(Button, { - type: 'secondary', - large: true, - className: 'request-signature__footer__sign-button', - onClick: event => { - this._removeBeforeUnload() - sign(event).then(() => { - this.context.metricsEvent({ - eventOpts: { - category: 'Transactions', - action: 'Sign Request', - name: 'Confirm', - }, - }) - this.props.clearConfirmTransaction() - this.props.history.push(DEFAULT_ROUTE) - }) - }, - }, this.context.t('sign')), - ]) -} - -SignatureRequest.prototype.render = function () { - return ( - - h('div.request-signature__container', [ - - this.renderHeader(), - - this.renderBody(), - - this.renderFooter(), - - ]) - - ) - -} diff --git a/ui/app/components/app/signature-request-original/index.js b/ui/app/components/app/signature-request-original/index.js new file mode 100644 index 000000000..00a906785 --- /dev/null +++ b/ui/app/components/app/signature-request-original/index.js @@ -0,0 +1 @@ +export { default } from './signature-request-original.container' diff --git a/ui/app/components/app/signature-request-original/signature-request-original.component.js b/ui/app/components/app/signature-request-original/signature-request-original.component.js new file mode 100644 index 000000000..2485ae506 --- /dev/null +++ b/ui/app/components/app/signature-request-original/signature-request-original.component.js @@ -0,0 +1,318 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import ethUtil from 'ethereumjs-util' +import classnames from 'classnames' +import { ObjectInspector } from 'react-inspector' + +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../app/scripts/lib/enums' +import { getEnvironmentType } from '../../../../../app/scripts/lib/util' +import Identicon from '../../ui/identicon' +import AccountListItem from '../../../pages/send/account-list-item/account-list-item.component' +import { conversionUtil } from '../../../helpers/utils/conversion-util' +import Button from '../../ui/button' +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' + +export default class SignatureRequestOriginal extends Component { + static contextTypes = { + t: PropTypes.func.isRequired, + metricsEvent: PropTypes.func.isRequired, + } + + static propTypes = { + balance: PropTypes.string, + cancel: PropTypes.func.isRequired, + clearConfirmTransaction: PropTypes.func.isRequired, + conversionRate: PropTypes.number, + history: PropTypes.object.isRequired, + requesterAddress: PropTypes.string, + selectedAccount: PropTypes.string, + sign: PropTypes.func.isRequired, + txData: PropTypes.object.isRequired, + } + + state = { + selectedAccount: this.props.selectedAccount, + } + + componentDidMount = () => { + if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION) { + window.addEventListener('beforeunload', this._beforeUnload) + } + } + + componentWillUnmount = () => { + this._removeBeforeUnload() + } + + _beforeUnload = (event) => { + const { clearConfirmTransaction, cancel } = this.props + const { metricsEvent } = this.context + metricsEvent({ + eventOpts: { + category: 'Transactions', + action: 'Sign Request', + name: 'Cancel Sig Request Via Notification Close', + }, + }) + clearConfirmTransaction() + cancel(event) + } + + _removeBeforeUnload = () => { + if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION) { + window.removeEventListener('beforeunload', this._beforeUnload) + } + } + + renderHeader = () => { + return ( +
+
+ +
+ { this.context.t('sigRequest') } +
+ +
+
+
+
+ ) + } + + renderAccount = () => { + const { selectedAccount } = this.state + + return ( +
+
+ { `${this.context.t('account')}:` } +
+ +
+ +
+
+ ) + } + + renderBalance = () => { + const { balance, conversionRate } = this.props + + const balanceInEther = conversionUtil(balance, { + fromNumericBase: 'hex', + toNumericBase: 'dec', + fromDenomination: 'WEI', + numberOfDecimals: 6, + conversionRate, + }) + + return ( +
+
+ { `${this.context.t('balance')}:` } +
+
+ { `${balanceInEther} ETH` } +
+
+ ) + } + + renderRequestIcon = () => { + const { requesterAddress } = this.props + + return ( +
+ +
+ ) + } + + renderAccountInfo = () => { + return ( +
+ { this.renderAccount() } + { this.renderRequestIcon() } + { this.renderBalance() } +
+ ) + } + + renderRequestInfo = () => { + return ( +
+
+ { this.context.t('yourSigRequested') } +
+
+ ) + } + + msgHexToText = (hex) => { + try { + const stripped = ethUtil.stripHexPrefix(hex) + const buff = Buffer.from(stripped, 'hex') + return buff.length === 32 ? hex : buff.toString('utf8') + } catch (e) { + return hex + } + } + + renderTypedData = (data) => { + const { domain, message } = JSON.parse(data) + return ( +
+ { + domain + ?
+

+ Domain +

+ +
+ : '' + } + { + message + ?
+

+ Message +

+ +
+ : '' + } +
+ ) + } + + renderBody = () => { + let rows + let notice = `${this.context.t('youSign')}:` + + const { txData } = this.props + const { type, msgParams: { data } } = txData + + if (type === 'personal_sign') { + rows = [{ name: this.context.t('message'), value: this.msgHexToText(data) }] + } else if (type === 'eth_signTypedData') { + rows = data + } else if (type === 'eth_sign') { + rows = [{ name: this.context.t('message'), value: data }] + notice = this.context.t('signNotice') + } + + return ( +
+ { this.renderAccountInfo() } + { this.renderRequestInfo() } +
+ { notice } + { + type === 'eth_sign' + ? { + global.platform.openWindow({ + url: 'https://metamask.zendesk.com/hc/en-us/articles/360015488751', + }) + }} + > + { this.context.t('learnMore') } + + : null + } +
+
+ { + rows.map(({ name, value }, index) => { + if (typeof value === 'boolean') { + value = value.toString() + } + return ( +
+
+ { `${name}:` } +
+
+ { value } +
+
+ ) + }) + } +
+
+ ) + } + + renderFooter = () => { + const { cancel, sign } = this.props + + return ( +
+ , + +
+ ) + } + + render = () => { + return ( +
+ { this.renderHeader() } + { this.renderBody() } + { this.renderFooter() } +
+ ) + } +} diff --git a/ui/app/components/app/signature-request-original/signature-request-original.container.js b/ui/app/components/app/signature-request-original/signature-request-original.container.js new file mode 100644 index 000000000..be891b4db --- /dev/null +++ b/ui/app/components/app/signature-request-original/signature-request-original.container.js @@ -0,0 +1,72 @@ +import { connect } from 'react-redux' +import { compose } from 'recompose' +import { withRouter } from 'react-router-dom' + +import actions from '../../../store/actions' +import { + getSelectedAccount, + getCurrentAccountWithSendEtherInfo, + getSelectedAddress, + conversionRateSelector, +} from '../../../selectors/selectors.js' +import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck' +import SignatureRequestOriginal from './signature-request-original.component' + +function mapStateToProps (state) { + return { + balance: getSelectedAccount(state).balance, + selectedAccount: getCurrentAccountWithSendEtherInfo(state), + selectedAddress: getSelectedAddress(state), + requester: null, + requesterAddress: null, + conversionRate: conversionRateSelector(state), + } +} + +function mapDispatchToProps (dispatch) { + return { + goHome: () => dispatch(actions.goHome()), + clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), + } +} + +function mergeProps (stateProps, dispatchProps, ownProps) { + const { + signPersonalMessage, + signTypedMessage, + cancelPersonalMessage, + cancelTypedMessage, + signMessage, + cancelMessage, + txData, + } = ownProps + + const { type } = txData + + let cancel + let sign + if (type === 'personal_sign') { + cancel = cancelPersonalMessage + sign = signPersonalMessage + } else if (type === 'eth_signTypedData') { + cancel = cancelTypedMessage + sign = signTypedMessage + } else if (type === 'eth_sign') { + cancel = cancelMessage + sign = signMessage + } + + return { + ...ownProps, + ...stateProps, + ...dispatchProps, + txData, + cancel, + sign, + } +} + +export default compose( + withRouter, + connect(mapStateToProps, mapDispatchToProps, mergeProps) +)(SignatureRequestOriginal) diff --git a/ui/app/pages/confirm-transaction/conf-tx.js b/ui/app/pages/confirm-transaction/conf-tx.js index ce1edde5c..79d7f5e4f 100644 --- a/ui/app/pages/confirm-transaction/conf-tx.js +++ b/ui/app/pages/confirm-transaction/conf-tx.js @@ -10,7 +10,7 @@ const log = require('loglevel') const R = require('ramda') const SignatureRequest = require('../../components/app/signature-request').default -const SignatureRequestOriginal = require('../../components/app/signature-request-original') +const SignatureRequestOriginal = require('../../components/app/signature-request-original').default const Loading = require('../../components/ui/loading-screen') const { DEFAULT_ROUTE } = require('../../helpers/constants/routes')