1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Allow editing of token transactions.

This commit is contained in:
Dan 2017-11-09 11:44:32 -03:30 committed by Chi Kei Chan
parent 0a91671ff6
commit 4671f28476
2 changed files with 91 additions and 11 deletions

View File

@ -2,9 +2,10 @@ const Component = require('react').Component
const { connect } = require('react-redux') const { connect } = require('react-redux')
const h = require('react-hyperscript') const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const abi = require('human-standard-token-abi') const ethAbi = require('ethereumjs-abi')
const tokenAbi = require('human-standard-token-abi')
const abiDecoder = require('abi-decoder') const abiDecoder = require('abi-decoder')
abiDecoder.addABI(abi) abiDecoder.addABI(tokenAbi)
const actions = require('../../actions') const actions = require('../../actions')
const clone = require('clone') const clone = require('clone')
const Identicon = require('../identicon') const Identicon = require('../identicon')
@ -24,6 +25,7 @@ const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
const { const {
getTokenExchangeRate, getTokenExchangeRate,
getSelectedAddress, getSelectedAddress,
getSelectedTokenContract,
} = require('../../selectors') } = require('../../selectors')
module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken) module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
@ -32,6 +34,7 @@ function mapStateToProps (state, ownProps) {
const { token: { symbol }, txData } = ownProps const { token: { symbol }, txData } = ownProps
const { txParams } = txData || {} const { txParams } = txData || {}
const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data) const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { const {
conversionRate, conversionRate,
identities, identities,
@ -47,6 +50,8 @@ function mapStateToProps (state, ownProps) {
tokenExchangeRate, tokenExchangeRate,
tokenData: tokenData || {}, tokenData: tokenData || {},
currentCurrency: currentCurrency.toUpperCase(), currentCurrency: currentCurrency.toUpperCase(),
send: state.metamask.send,
tokenContract: getSelectedTokenContract(state),
} }
} }
@ -57,6 +62,30 @@ function mapDispatchToProps (dispatch, ownProps) {
backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)), backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })), cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
updateTokenExchangeRate: () => dispatch(actions.updateTokenExchangeRate(symbol)), updateTokenExchangeRate: () => dispatch(actions.updateTokenExchangeRate(symbol)),
editTransaction: txMeta => {
const { token: { address } } = ownProps
const { txParams, id } = txMeta
const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { params = [] } = tokenData
const { value } = params[1] || {}
const amount = conversionUtil(value, {
fromNumericBase: 'dec',
toNumericBase: 'hex',
})
const {
gas: gasLimit,
gasPrice,
to,
} = txParams
dispatch(actions.editTx(id))
dispatch(actions.updateGasLimit(gasLimit))
dispatch(actions.updateGasPrice(gasPrice))
dispatch(actions.updateSendTo(to))
dispatch(actions.updateSendAmount(amount))
dispatch(actions.updateSendErrors({ to: null, amount: null }))
dispatch(actions.setSelectedToken(address))
dispatch(actions.showSendTokenPage())
},
} }
} }
@ -68,14 +97,33 @@ function ConfirmSendToken () {
} }
ConfirmSendToken.prototype.componentWillMount = function () { ConfirmSendToken.prototype.componentWillMount = function () {
const { tokenContract, selectedAddress } = this.props
tokenContract && tokenContract
.balanceOf(selectedAddress)
.then(usersToken => {
})
this.props.updateTokenExchangeRate() this.props.updateTokenExchangeRate()
} }
ConfirmSendToken.prototype.getAmount = function () { ConfirmSendToken.prototype.getAmount = function () {
const { conversionRate, tokenExchangeRate, token, tokenData } = this.props const {
conversionRate,
tokenExchangeRate,
token,
tokenData,
send: { amount, editingTransactionId },
} = this.props
const { params = [] } = tokenData const { params = [] } = tokenData
const { value } = params[1] || {} let { value } = params[1] || {}
const { decimals } = token const { decimals } = token
if (editingTransactionId) {
value = conversionUtil(amount, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
})
}
const sendTokenAmount = calcTokenAmount(value, decimals) const sendTokenAmount = calcTokenAmount(value, decimals)
return { return {
@ -242,9 +290,8 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
} }
ConfirmSendToken.prototype.render = function () { ConfirmSendToken.prototype.render = function () {
const { backToAccountDetail, selectedAddress } = this.props const { editTransaction } = this.props
const txMeta = this.gatherTxMeta() const txMeta = this.gatherTxMeta()
const { const {
from: { from: {
address: fromAddress, address: fromAddress,
@ -266,8 +313,8 @@ ConfirmSendToken.prototype.render = function () {
h('div.confirm-screen-wrapper.flex-column.flex-grow', [ h('div.confirm-screen-wrapper.flex-column.flex-grow', [
h('h3.flex-center.confirm-screen-header', [ h('h3.flex-center.confirm-screen-header', [
h('button.confirm-screen-back-button', { h('button.confirm-screen-back-button', {
onClick: () => backToAccountDetail(selectedAddress), onClick: () => editTransaction(txMeta),
}, 'BACK'), }, 'EDIT'),
h('div.confirm-screen-title', 'Confirm Transaction'), h('div.confirm-screen-title', 'Confirm Transaction'),
h('div.confirm-screen-header-tip'), h('div.confirm-screen-header-tip'),
]), ]),
@ -389,6 +436,38 @@ ConfirmSendToken.prototype.gatherTxMeta = function () {
const state = this.state const state = this.state
const txData = clone(state.txData) || clone(props.txData) const txData = clone(state.txData) || clone(props.txData)
if (props.send.editingTransactionId) {
const {
send: {
memo,
amount,
gasLimit: gas,
gasPrice,
},
} = props
const { txParams: { from, to } } = txData
const tokenParams = {
from: ethUtil.addHexPrefix(from),
value: '0',
gas: ethUtil.addHexPrefix(gas),
gasPrice: ethUtil.addHexPrefix(gasPrice),
}
const data = '0xa9059cbb' + Array.prototype.map.call(
ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]),
x => ('00' + x.toString(16)).slice(-2)
).join('')
txData.txParams = {
...tokenParams,
to: ethUtil.addHexPrefix(to),
memo: memo && ethUtil.addHexPrefix(memo),
data,
}
}
// log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`) // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
return txData return txData
} }

View File

@ -76,7 +76,6 @@ SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
updateSendTokenBalance, updateSendTokenBalance,
} = this.props } = this.props
const { decimals } = selectedToken || {} const { decimals } = selectedToken || {}
const tokenBalance = calcTokenAmount(usersToken.balance.toString(), decimals) const tokenBalance = calcTokenAmount(usersToken.balance.toString(), decimals)
updateSendTokenBalance(tokenBalance) updateSendTokenBalance(tokenBalance)
@ -105,13 +104,14 @@ SendTransactionScreen.prototype.componentWillMount = function () {
const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data) const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data)
const tokenBalancePromise = tokenContract && tokenContract.balanceOf(from.address)
let newGasTotal let newGasTotal
if (!editingTransactionId) { if (!editingTransactionId) {
Promise Promise
.all([ .all([
getGasPrice(), getGasPrice(),
estimateGas(estimateGasParams), estimateGas(estimateGasParams),
tokenContract && tokenContract.balanceOf(from.address), tokenBalancePromise,
]) ])
.then(([gasPrice, gas, usersToken]) => { .then(([gasPrice, gas, usersToken]) => {
@ -130,6 +130,8 @@ SendTransactionScreen.prototype.componentWillMount = function () {
multiplierBase: 16, multiplierBase: 16,
}) })
updateGasTotal(newGasTotal) updateGasTotal(newGasTotal)
tokenBalancePromise && tokenBalancePromise.then(
usersToken => this.updateSendTokenBalance(usersToken))
} }
} }
@ -363,7 +365,6 @@ SendTransactionScreen.prototype.validateAmount = function (value) {
const amount = value const amount = value
let amountError = null let amountError = null
const sufficientBalance = isBalanceSufficient({ const sufficientBalance = isBalanceSufficient({
amount: selectedToken ? '0x0' : amount, amount: selectedToken ? '0x0' : amount,
gasTotal, gasTotal,