From ea9d51e427b8e607e612a01629bebf153e516ad9 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 22 Jun 2018 23:52:45 -0700 Subject: Refactor and redesign confirm transaction views --- .../confirm-transaction-base.component.js | 382 +++++++++++++++++++++ .../confirm-transaction-base.container.js | 95 +++++ .../pages/confirm-transaction-base/index.js | 1 + 3 files changed, 478 insertions(+) create mode 100644 ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js create mode 100644 ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js create mode 100644 ui/app/components/pages/confirm-transaction-base/index.js (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js new file mode 100644 index 000000000..3b60a5d5d --- /dev/null +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -0,0 +1,382 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import ConfirmPageContainer, { ConfirmDetailRow } from '../../confirm-page-container' +import { formatCurrency, getHexGasTotal } from '../../../helpers/confirm-transaction/util' +import { isBalanceSufficient } from '../../send_/send.utils' +import { DEFAULT_ROUTE } from '../../../routes' +import { conversionGreaterThan } from '../../../conversion-util' +import { MIN_GAS_LIMIT_DEC } from '../../send_/send.constants' + +export default class ConfirmTransactionBase extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + match: PropTypes.object, + history: PropTypes.object, + // Redux props + txData: PropTypes.object, + tokenData: PropTypes.object, + tokenProps: PropTypes.object, + isTxReprice: PropTypes.bool, + nonce: PropTypes.string, + fromName: PropTypes.string, + fromAddress: PropTypes.string, + toName: PropTypes.string, + toAddress: PropTypes.string, + transactionStatus: PropTypes.string, + ethTransactionAmount: PropTypes.string, + ethTransactionFee: PropTypes.string, + ethTransactionTotal: PropTypes.string, + fiatTransactionAmount: PropTypes.string, + fiatTransactionFee: PropTypes.string, + fiatTransactionTotal: PropTypes.string, + hexGasTotal: PropTypes.string, + balance: PropTypes.string, + currentCurrency: PropTypes.string, + conversionRate: PropTypes.number, + setTransactionToConfirm: PropTypes.func, + clearConfirmTransaction: PropTypes.func, + cancelTransaction: PropTypes.func, + clearSend: PropTypes.func, + sendTransaction: PropTypes.func, + editTransaction: PropTypes.func, + showCustomizeGasModal: PropTypes.func, + updateGasAndCalculate: PropTypes.func, + showTransactionConfirmedModal: PropTypes.func, + // Component props + action: PropTypes.string, + hideDetails: PropTypes.bool, + hideData: PropTypes.bool, + detailsComponent: PropTypes.node, + dataComponent: PropTypes.node, + summaryComponent: PropTypes.node, + contentComponent: PropTypes.node, + title: PropTypes.string, + subtitle: PropTypes.string, + hideSubtitle: PropTypes.bool, + valid: PropTypes.bool, + errorMessage: PropTypes.string, + warning: PropTypes.string, + identiconAddress: PropTypes.string, + onEdit: PropTypes.func, + onEditGas: PropTypes.func, + onCancel: PropTypes.func, + onSubmit: PropTypes.func, + } + + componentDidMount () { + const { match: { params: { id } = {} }, setTransactionToConfirm } = this.props + setTransactionToConfirm(id) + } + + componentDidUpdate (prevProps) { + const { + transactionStatus, + showTransactionConfirmedModal, + history, + clearConfirmTransaction, + match: { params: { id } = {} }, + setTransactionToConfirm, + txData, + } = this.props + + if (transactionStatus === 'dropped') { + showTransactionConfirmedModal({ + onHide: () => { + clearConfirmTransaction() + history.push(DEFAULT_ROUTE) + }, + }) + + return + } + + if (id && id !== txData.id + '') { + setTransactionToConfirm(id) + } + } + + getError () { + const INSUFFICIENT_FUNDS_ERROR = this.context.t('insufficientFunds') + const TRANSACTION_ERROR = this.context.t('transactionError') + const { + balance, + conversionRate, + hexGasTotal, + txData: { + simulationFails, + txParams: { + value: amount, + } = {}, + } = {}, + } = this.props + + const insufficientBalance = balance && !isBalanceSufficient({ + amount, + gasTotal: hexGasTotal || '0x0', + balance, + conversionRate, + }) + + if (insufficientBalance) { + return { + valid: false, + errorMessage: INSUFFICIENT_FUNDS_ERROR, + } + } + + if (simulationFails) { + return { + valid: false, + errorMessage: TRANSACTION_ERROR, + } + } + + return { + valid: true, + } + } + + validateEditGas ({ gasLimit, gasPrice }) { + const { t } = this.context + const { + balance, + conversionRate, + txData: { + txParams: { + value: amount, + } = {}, + } = {}, + } = this.props + + const INSUFFICIENT_FUNDS_ERROR = t('insufficientFunds') + const GAS_LIMIT_TOO_LOW_ERROR = t('gasLimitTooLow') + + const gasTotal = getHexGasTotal({ gasLimit, gasPrice }) + const hasSufficientBalance = isBalanceSufficient({ + amount, + gasTotal, + balance, + conversionRate, + }) + + if (!hasSufficientBalance) { + return { + valid: false, + errorMessage: INSUFFICIENT_FUNDS_ERROR, + } + } + + const gasLimitTooLow = gasLimit && conversionGreaterThan( + { + value: MIN_GAS_LIMIT_DEC, + fromNumericBase: 'dec', + conversionRate, + }, + { + value: gasLimit, + fromNumericBase: 'hex', + }, + ) + + if (gasLimitTooLow) { + return { + valid: false, + errorMessage: GAS_LIMIT_TOO_LOW_ERROR, + } + } + + return { + valid: true, + } + } + + handleEditGas () { + const { onEditGas, showCustomizeGasModal, txData, updateGasAndCalculate } = this.props + + if (onEditGas) { + onEditGas() + } else { + showCustomizeGasModal({ + txData, + onSubmit: txData => updateGasAndCalculate(txData), + validate: ({ gasLimit, gasPrice }) => this.validateEditGas({ gasLimit, gasPrice }), + }) + } + } + + renderDetails () { + const { + detailsComponent, + fiatTransactionFee, + ethTransactionFee, + currentCurrency, + fiatTransactionTotal, + ethTransactionTotal, + hideDetails, + } = this.props + + if (hideDetails) { + return null + } + + return ( + detailsComponent || ( +
+
+ this.handleEditGas()} + /> +
+
+ +
+
+ ) + ) + } + + renderData () { + const { t } = this.context + const { + txData: { + txParams: { + data, + } = {}, + } = {}, + tokenData: { + name, + params, + } = {}, + hideData, + dataComponent, + } = this.props + + if (hideData) { + return null + } + + return dataComponent || ( +
+
+ {`${t('functionType')}:`} + + { name } + +
+
+ { JSON.stringify(params, null, 2) } +
+
+ {`${t('hexData')}:`} +
+
+ { data } +
+
+ ) + } + + handleEdit () { + const { txData, tokenData, tokenProps, onEdit } = this.props + onEdit({ txData, tokenData, tokenProps }) + } + + handleCancel () { + const { onCancel, txData, cancelTransaction, history, clearConfirmTransaction } = this.props + + if (onCancel) { + onCancel(txData) + } else { + cancelTransaction(txData) + .then(() => { + clearConfirmTransaction() + history.push(DEFAULT_ROUTE) + }) + } + } + + handleSubmit () { + const { sendTransaction, clearConfirmTransaction, txData, history, onSubmit } = this.props + + if (onSubmit) { + onSubmit(txData) + } else { + sendTransaction(txData) + .then(() => { + clearConfirmTransaction() + history.push(DEFAULT_ROUTE) + }) + } + } + + render () { + const { + isTxReprice, + fromName, + fromAddress, + toName, + toAddress, + tokenData, + ethTransactionAmount, + fiatTransactionAmount, + valid: propsValid, + errorMessage: propsErrorMessage, + currentCurrency, + action, + title, + subtitle, + hideSubtitle, + identiconAddress, + summaryComponent, + contentComponent, + onEdit, + nonce, + warning, + } = this.props + + const { name } = tokenData + const fiatConvertedAmount = formatCurrency(fiatTransactionAmount, currentCurrency) + const { valid, errorMessage } = this.getError() + + return ( + this.handleEdit()} + onCancel={() => this.handleCancel()} + onSubmit={() => this.handleSubmit()} + /> + ) + } +} diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js new file mode 100644 index 000000000..ea1a1d296 --- /dev/null +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -0,0 +1,95 @@ +import { connect } from 'react-redux' +import { compose } from 'recompose' +import { withRouter } from 'react-router-dom' +import R from 'ramda' +import ConfirmTransactionBase from './confirm-transaction-base.component' +import { + setTransactionToConfirm, + clearConfirmTransaction, + updateGasAndCalculate, +} from '../../../ducks/confirm-transaction.duck' +import { clearSend, cancelTx, updateAndApproveTx, showModal } from '../../../actions' + +const mapStateToProps = (state, props) => { + const { toAddress: propsToAddress } = props + const { confirmTransaction, metamask } = state + const { + ethTransactionAmount, + ethTransactionFee, + ethTransactionTotal, + fiatTransactionAmount, + fiatTransactionFee, + fiatTransactionTotal, + hexGasTotal, + tokenData, + txData, + tokenProps, + nonce, + } = confirmTransaction + const { txParams = {}, lastGasPrice, id: transactionId } = txData + const { from: fromAddress, to: txParamsToAddress } = txParams + const { + conversionRate, + identities, + currentCurrency, + accounts, + selectedAddress, + selectedAddressTxList, + } = metamask + + const { balance } = accounts[selectedAddress] + const { name: fromName } = identities[selectedAddress] + const toAddress = propsToAddress || txParamsToAddress + const toName = identities[toAddress] && identities[toAddress].name + const isTxReprice = Boolean(lastGasPrice) + + const transaction = R.find(({ id }) => id === transactionId)(selectedAddressTxList) + const transactionStatus = transaction ? transaction.status : '' + + return { + balance, + fromAddress, + fromName, + toAddress, + toName, + ethTransactionAmount, + ethTransactionFee, + ethTransactionTotal, + fiatTransactionAmount, + fiatTransactionFee, + fiatTransactionTotal, + hexGasTotal, + txData, + tokenData, + tokenProps, + isTxReprice, + currentCurrency, + conversionRate, + transactionStatus, + nonce, + } +} + +const mapDispatchToProps = dispatch => { + return { + setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)), + clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), + clearSend: () => dispatch(clearSend()), + showTransactionConfirmedModal: ({ onHide }) => { + return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onHide })) + }, + showCustomizeGasModal: ({ txData, onSubmit, validate }) => { + return dispatch(showModal({ name: 'CONFIRM_CUSTOMIZE_GAS', txData, onSubmit, validate })) + }, + updateGasAndCalculate: ({ gasLimit, gasPrice }) => { + return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) + }, + cancelTransaction: ({ id }) => dispatch(cancelTx({ id })), + sendTransaction: txData => dispatch(updateAndApproveTx(txData)), + } +} + +export default compose( + withRouter, + connect(mapStateToProps, mapDispatchToProps) +)(ConfirmTransactionBase) diff --git a/ui/app/components/pages/confirm-transaction-base/index.js b/ui/app/components/pages/confirm-transaction-base/index.js new file mode 100644 index 000000000..9996e9aeb --- /dev/null +++ b/ui/app/components/pages/confirm-transaction-base/index.js @@ -0,0 +1 @@ +export { default } from './confirm-transaction-base.container' -- cgit From e89549846fd3bd520b99740c7845f48f368c3afa Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 25 Jun 2018 12:06:57 -0700 Subject: Refactor data flow, signature request routing --- .../confirm-transaction-base.component.js | 15 +-------------- .../confirm-transaction-base.container.js | 2 -- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index 3b60a5d5d..dfbbd0177 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -36,7 +36,6 @@ export default class ConfirmTransactionBase extends Component { balance: PropTypes.string, currentCurrency: PropTypes.string, conversionRate: PropTypes.number, - setTransactionToConfirm: PropTypes.func, clearConfirmTransaction: PropTypes.func, cancelTransaction: PropTypes.func, clearSend: PropTypes.func, @@ -66,20 +65,12 @@ export default class ConfirmTransactionBase extends Component { onSubmit: PropTypes.func, } - componentDidMount () { - const { match: { params: { id } = {} }, setTransactionToConfirm } = this.props - setTransactionToConfirm(id) - } - - componentDidUpdate (prevProps) { + componentDidUpdate () { const { transactionStatus, showTransactionConfirmedModal, history, clearConfirmTransaction, - match: { params: { id } = {} }, - setTransactionToConfirm, - txData, } = this.props if (transactionStatus === 'dropped') { @@ -92,10 +83,6 @@ export default class ConfirmTransactionBase extends Component { return } - - if (id && id !== txData.id + '') { - setTransactionToConfirm(id) - } } getError () { diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index ea1a1d296..19c39aed9 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -4,7 +4,6 @@ import { withRouter } from 'react-router-dom' import R from 'ramda' import ConfirmTransactionBase from './confirm-transaction-base.component' import { - setTransactionToConfirm, clearConfirmTransaction, updateGasAndCalculate, } from '../../../ducks/confirm-transaction.duck' @@ -72,7 +71,6 @@ const mapStateToProps = (state, props) => { const mapDispatchToProps = dispatch => { return { - setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), clearSend: () => dispatch(clearSend()), showTransactionConfirmedModal: ({ onHide }) => { -- cgit From 9cde5ab11b0670eed7baeb2f31486cb3e253bdcb Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 28 Jun 2018 11:23:31 -0700 Subject: Use eth-method-registry to get method data --- .../confirm-transaction-base.component.js | 14 ++++++++++---- .../confirm-transaction-base.container.js | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index dfbbd0177..1a399a464 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -18,6 +18,7 @@ export default class ConfirmTransactionBase extends Component { // Redux props txData: PropTypes.object, tokenData: PropTypes.object, + methodData: PropTypes.object, tokenProps: PropTypes.object, isTxReprice: PropTypes.bool, nonce: PropTypes.string, @@ -245,7 +246,7 @@ export default class ConfirmTransactionBase extends Component { data, } = {}, } = {}, - tokenData: { + methodData: { name, params, } = {}, @@ -266,7 +267,12 @@ export default class ConfirmTransactionBase extends Component {
- { JSON.stringify(params, null, 2) } +
+ { `${t('parameters')}:` } +
+
+
{ JSON.stringify(params, null, 2) }
+
{`${t('hexData')}:`} @@ -318,7 +324,7 @@ export default class ConfirmTransactionBase extends Component { fromAddress, toName, toAddress, - tokenData, + methodData, ethTransactionAmount, fiatTransactionAmount, valid: propsValid, @@ -336,7 +342,7 @@ export default class ConfirmTransactionBase extends Component { warning, } = this.props - const { name } = tokenData + const { name } = methodData const fiatConvertedAmount = formatCurrency(fiatTransactionAmount, currentCurrency) const { valid, errorMessage } = this.getError() diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index 19c39aed9..4f1fb86c1 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -21,6 +21,7 @@ const mapStateToProps = (state, props) => { fiatTransactionTotal, hexGasTotal, tokenData, + methodData, txData, tokenProps, nonce, @@ -60,6 +61,7 @@ const mapStateToProps = (state, props) => { hexGasTotal, txData, tokenData, + methodData, tokenProps, isTxReprice, currentCurrency, -- cgit From a2d9c43fba49680d7553409a4f5013d3febd80e9 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 6 Jul 2018 11:58:41 -0700 Subject: Various fixes from PR comments --- .../confirm-transaction-base.component.js | 147 +++++++-------------- .../confirm-transaction-base.container.js | 76 ++++++++++- 2 files changed, 121 insertions(+), 102 deletions(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index 1a399a464..842b34d2e 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1,11 +1,13 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import ConfirmPageContainer, { ConfirmDetailRow } from '../../confirm-page-container' -import { formatCurrency, getHexGasTotal } from '../../../helpers/confirm-transaction/util' +import { formatCurrency } from '../../../helpers/confirm-transaction/util' import { isBalanceSufficient } from '../../send_/send.utils' import { DEFAULT_ROUTE } from '../../../routes' -import { conversionGreaterThan } from '../../../conversion-util' -import { MIN_GAS_LIMIT_DEC } from '../../send_/send.constants' +import { + INSUFFICIENT_FUNDS_ERROR_KEY, + TRANSACTION_ERROR_KEY, +} from '../../../constants/error-keys' export default class ConfirmTransactionBase extends Component { static contextTypes = { @@ -13,57 +15,58 @@ export default class ConfirmTransactionBase extends Component { } static propTypes = { + // react-router props match: PropTypes.object, history: PropTypes.object, // Redux props - txData: PropTypes.object, - tokenData: PropTypes.object, - methodData: PropTypes.object, - tokenProps: PropTypes.object, - isTxReprice: PropTypes.bool, - nonce: PropTypes.string, - fromName: PropTypes.string, - fromAddress: PropTypes.string, - toName: PropTypes.string, - toAddress: PropTypes.string, - transactionStatus: PropTypes.string, + balance: PropTypes.string, + cancelTransaction: PropTypes.func, + clearConfirmTransaction: PropTypes.func, + clearSend: PropTypes.func, + conversionRate: PropTypes.number, + currentCurrency: PropTypes.string, + editTransaction: PropTypes.func, ethTransactionAmount: PropTypes.string, ethTransactionFee: PropTypes.string, ethTransactionTotal: PropTypes.string, fiatTransactionAmount: PropTypes.string, fiatTransactionFee: PropTypes.string, fiatTransactionTotal: PropTypes.string, + fromAddress: PropTypes.string, + fromName: PropTypes.string, hexGasTotal: PropTypes.string, - balance: PropTypes.string, - currentCurrency: PropTypes.string, - conversionRate: PropTypes.number, - clearConfirmTransaction: PropTypes.func, - cancelTransaction: PropTypes.func, - clearSend: PropTypes.func, + isTxReprice: PropTypes.bool, + methodData: PropTypes.object, + nonce: PropTypes.string, sendTransaction: PropTypes.func, - editTransaction: PropTypes.func, showCustomizeGasModal: PropTypes.func, - updateGasAndCalculate: PropTypes.func, showTransactionConfirmedModal: PropTypes.func, + toAddress: PropTypes.string, + tokenData: PropTypes.object, + tokenProps: PropTypes.object, + toName: PropTypes.string, + transactionStatus: PropTypes.string, + txData: PropTypes.object, // Component props action: PropTypes.string, - hideDetails: PropTypes.bool, - hideData: PropTypes.bool, - detailsComponent: PropTypes.node, - dataComponent: PropTypes.node, - summaryComponent: PropTypes.node, contentComponent: PropTypes.node, - title: PropTypes.string, - subtitle: PropTypes.string, - hideSubtitle: PropTypes.bool, - valid: PropTypes.bool, + dataComponent: PropTypes.node, + detailsComponent: PropTypes.node, + errorKey: PropTypes.string, errorMessage: PropTypes.string, - warning: PropTypes.string, + hideData: PropTypes.bool, + hideDetails: PropTypes.bool, + hideSubtitle: PropTypes.bool, identiconAddress: PropTypes.string, + onCancel: PropTypes.func, onEdit: PropTypes.func, onEditGas: PropTypes.func, - onCancel: PropTypes.func, onSubmit: PropTypes.func, + subtitle: PropTypes.string, + summaryComponent: PropTypes.node, + title: PropTypes.string, + valid: PropTypes.bool, + warning: PropTypes.string, } componentDidUpdate () { @@ -86,9 +89,7 @@ export default class ConfirmTransactionBase extends Component { } } - getError () { - const INSUFFICIENT_FUNDS_ERROR = this.context.t('insufficientFunds') - const TRANSACTION_ERROR = this.context.t('transactionError') + getErrorKey () { const { balance, conversionRate, @@ -111,68 +112,14 @@ export default class ConfirmTransactionBase extends Component { if (insufficientBalance) { return { valid: false, - errorMessage: INSUFFICIENT_FUNDS_ERROR, + errorKey: INSUFFICIENT_FUNDS_ERROR_KEY, } } if (simulationFails) { return { valid: false, - errorMessage: TRANSACTION_ERROR, - } - } - - return { - valid: true, - } - } - - validateEditGas ({ gasLimit, gasPrice }) { - const { t } = this.context - const { - balance, - conversionRate, - txData: { - txParams: { - value: amount, - } = {}, - } = {}, - } = this.props - - const INSUFFICIENT_FUNDS_ERROR = t('insufficientFunds') - const GAS_LIMIT_TOO_LOW_ERROR = t('gasLimitTooLow') - - const gasTotal = getHexGasTotal({ gasLimit, gasPrice }) - const hasSufficientBalance = isBalanceSufficient({ - amount, - gasTotal, - balance, - conversionRate, - }) - - if (!hasSufficientBalance) { - return { - valid: false, - errorMessage: INSUFFICIENT_FUNDS_ERROR, - } - } - - const gasLimitTooLow = gasLimit && conversionGreaterThan( - { - value: MIN_GAS_LIMIT_DEC, - fromNumericBase: 'dec', - conversionRate, - }, - { - value: gasLimit, - fromNumericBase: 'hex', - }, - ) - - if (gasLimitTooLow) { - return { - valid: false, - errorMessage: GAS_LIMIT_TOO_LOW_ERROR, + errorKey: TRANSACTION_ERROR_KEY, } } @@ -182,16 +129,12 @@ export default class ConfirmTransactionBase extends Component { } handleEditGas () { - const { onEditGas, showCustomizeGasModal, txData, updateGasAndCalculate } = this.props + const { onEditGas, showCustomizeGasModal } = this.props if (onEditGas) { onEditGas() } else { - showCustomizeGasModal({ - txData, - onSubmit: txData => updateGasAndCalculate(txData), - validate: ({ gasLimit, gasPrice }) => this.validateEditGas({ gasLimit, gasPrice }), - }) + showCustomizeGasModal() } } @@ -328,7 +271,8 @@ export default class ConfirmTransactionBase extends Component { ethTransactionAmount, fiatTransactionAmount, valid: propsValid, - errorMessage: propsErrorMessage, + errorMessage, + errorKey: propsErrorKey, currentCurrency, action, title, @@ -344,7 +288,7 @@ export default class ConfirmTransactionBase extends Component { const { name } = methodData const fiatConvertedAmount = formatCurrency(fiatTransactionAmount, currentCurrency) - const { valid, errorMessage } = this.getError() + const { valid, errorKey } = this.getErrorKey() return ( this.handleEdit()} diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index 4f1fb86c1..31108bbd0 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -8,6 +8,14 @@ import { updateGasAndCalculate, } from '../../../ducks/confirm-transaction.duck' import { clearSend, cancelTx, updateAndApproveTx, showModal } from '../../../actions' +import { + INSUFFICIENT_FUNDS_ERROR_KEY, + GAS_LIMIT_TOO_LOW_ERROR_KEY, +} from '../../../constants/error-keys' +import { getHexGasTotal } from '../../../helpers/confirm-transaction/util' +import { isBalanceSufficient } from '../../send_/send.utils' +import { conversionGreaterThan } from '../../../conversion-util' +import { MIN_GAS_LIMIT_DEC } from '../../send_/send.constants' const mapStateToProps = (state, props) => { const { toAddress: propsToAddress } = props @@ -89,7 +97,73 @@ const mapDispatchToProps = dispatch => { } } +const getValidateEditGas = ({ balance, conversionRate, txData }) => { + const { txParams: { value: amount } = {} } = txData + + return ({ gasLimit, gasPrice }) => { + const gasTotal = getHexGasTotal({ gasLimit, gasPrice }) + const hasSufficientBalance = isBalanceSufficient({ + amount, + gasTotal, + balance, + conversionRate, + }) + + if (!hasSufficientBalance) { + return { + valid: false, + errorKey: INSUFFICIENT_FUNDS_ERROR_KEY, + } + } + + const gasLimitTooLow = gasLimit && conversionGreaterThan( + { + value: MIN_GAS_LIMIT_DEC, + fromNumericBase: 'dec', + conversionRate, + }, + { + value: gasLimit, + fromNumericBase: 'hex', + }, + ) + + if (gasLimitTooLow) { + return { + valid: false, + errorKey: GAS_LIMIT_TOO_LOW_ERROR_KEY, + } + } + + return { + valid: true, + } + } +} + +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { balance, conversionRate, txData } = stateProps + const { + showCustomizeGasModal: dispatchShowCustomizeGasModal, + updateGasAndCalculate: dispatchUpdateGasAndCalculate, + ...otherDispatchProps + } = dispatchProps + + const validateEditGas = getValidateEditGas({ balance, conversionRate, txData }) + + return { + ...stateProps, + ...otherDispatchProps, + ...ownProps, + showCustomizeGasModal: () => dispatchShowCustomizeGasModal({ + txData, + onSubmit: txData => dispatchUpdateGasAndCalculate(txData), + validate: validateEditGas, + }), + } +} + export default compose( withRouter, - connect(mapStateToProps, mapDispatchToProps) + connect(mapStateToProps, mapDispatchToProps, mergeProps) )(ConfirmTransactionBase) -- cgit From 5c3efe8bc47a9f8e7a7e0952589c1a2f42ec4eca Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Mon, 16 Jul 2018 13:06:46 -0230 Subject: Fix send import paths in confirm tx components --- .../confirm-transaction-base/confirm-transaction-base.component.js | 2 +- .../confirm-transaction-base/confirm-transaction-base.container.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index 842b34d2e..5327b116f 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import ConfirmPageContainer, { ConfirmDetailRow } from '../../confirm-page-container' import { formatCurrency } from '../../../helpers/confirm-transaction/util' -import { isBalanceSufficient } from '../../send_/send.utils' +import { isBalanceSufficient } from '../../send/send.utils' import { DEFAULT_ROUTE } from '../../../routes' import { INSUFFICIENT_FUNDS_ERROR_KEY, diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index 31108bbd0..7db39adec 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -13,9 +13,9 @@ import { GAS_LIMIT_TOO_LOW_ERROR_KEY, } from '../../../constants/error-keys' import { getHexGasTotal } from '../../../helpers/confirm-transaction/util' -import { isBalanceSufficient } from '../../send_/send.utils' +import { isBalanceSufficient } from '../../send/send.utils' import { conversionGreaterThan } from '../../../conversion-util' -import { MIN_GAS_LIMIT_DEC } from '../../send_/send.constants' +import { MIN_GAS_LIMIT_DEC } from '../../send/send.constants' const mapStateToProps = (state, props) => { const { toAddress: propsToAddress } = props -- cgit From d19c42fcaeea933793ed459ab5248b42811a0498 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Sat, 14 Jul 2018 13:47:07 -0700 Subject: Add fallback when no function found, fix network colors, add fiat values for tokens with contract exchange rates --- .../confirm-transaction-base.component.js | 40 ++++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index 5327b116f..e1bf2210f 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -54,6 +54,8 @@ export default class ConfirmTransactionBase extends Component { detailsComponent: PropTypes.node, errorKey: PropTypes.string, errorMessage: PropTypes.string, + ethTotalTextOverride: PropTypes.string, + fiatTotalTextOverride: PropTypes.string, hideData: PropTypes.bool, hideDetails: PropTypes.bool, hideSubtitle: PropTypes.bool, @@ -146,6 +148,8 @@ export default class ConfirmTransactionBase extends Component { currentCurrency, fiatTransactionTotal, ethTransactionTotal, + fiatTotalTextOverride, + ethTotalTextOverride, hideDetails, } = this.props @@ -153,14 +157,16 @@ export default class ConfirmTransactionBase extends Component { return null } + const formattedCurrency = formatCurrency(fiatTransactionTotal, currentCurrency) + return ( detailsComponent || (
this.handleEditGas()} @@ -169,11 +175,11 @@ export default class ConfirmTransactionBase extends Component {
@@ -206,17 +212,21 @@ export default class ConfirmTransactionBase extends Component {
{`${t('functionType')}:`} - { name } + { name || t('notFound') }
-
-
- { `${t('parameters')}:` } -
-
-
{ JSON.stringify(params, null, 2) }
-
-
+ { + params && ( +
+
+ { `${t('parameters')}:` } +
+
+
{ JSON.stringify(params, null, 2) }
+
+
+ ) + }
{`${t('hexData')}:`}
@@ -297,7 +307,7 @@ export default class ConfirmTransactionBase extends Component { toName={toName} toAddress={toAddress} showEdit={onEdit && !isTxReprice} - action={action || name} + action={action || name || this.context.t('unknownFunction')} title={title || `${fiatConvertedAmount} ${currentCurrency.toUpperCase()}`} subtitle={subtitle || `\u2666 ${ethTransactionAmount}`} hideSubtitle={hideSubtitle} -- cgit From 469a79f97ff887eae5ec99cf6be7b19c20972d02 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Fri, 20 Jul 2018 14:18:50 -0700 Subject: Add fallback options for displaying recipient name in the Confirm screen --- .../confirm-transaction-base.container.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'ui/app/components/pages/confirm-transaction-base') diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index 7db39adec..0c0deff18 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -2,6 +2,7 @@ import { connect } from 'react-redux' import { compose } from 'recompose' import { withRouter } from 'react-router-dom' import R from 'ramda' +import contractMap from 'eth-contract-metadata' import ConfirmTransactionBase from './confirm-transaction-base.component' import { clearConfirmTransaction, @@ -16,6 +17,14 @@ import { getHexGasTotal } from '../../../helpers/confirm-transaction/util' import { isBalanceSufficient } from '../../send/send.utils' import { conversionGreaterThan } from '../../../conversion-util' import { MIN_GAS_LIMIT_DEC } from '../../send/send.constants' +import { addressSlicer } from '../../../util' + +const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { + return { + ...acc, + [base.toLowerCase()]: contractMap[base], + } +}, {}) const mapStateToProps = (state, props) => { const { toAddress: propsToAddress } = props @@ -48,7 +57,10 @@ const mapStateToProps = (state, props) => { const { balance } = accounts[selectedAddress] const { name: fromName } = identities[selectedAddress] const toAddress = propsToAddress || txParamsToAddress - const toName = identities[toAddress] && identities[toAddress].name + const toName = identities[toAddress] + ? identities[toAddress].name + : casedContractMap[toAddress] ? casedContractMap[toAddress].name : addressSlicer(toAddress) + const isTxReprice = Boolean(lastGasPrice) const transaction = R.find(({ id }) => id === transactionId)(selectedAddressTxList) -- cgit