aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app
diff options
context:
space:
mode:
authorDan <danjm.com@gmail.com>2017-11-09 23:14:32 +0800
committerChi Kei Chan <chikeichan@gmail.com>2017-11-15 08:18:00 +0800
commit4671f28476165fec43785ae23352c1e9a0776abc (patch)
tree58b6f4a1b46d70f279ed2120d23cc0acbcf04372 /ui/app
parent0a91671ff69957596abbcffb7d20c89f144d7a69 (diff)
downloadtangerine-wallet-browser-4671f28476165fec43785ae23352c1e9a0776abc.tar.gz
tangerine-wallet-browser-4671f28476165fec43785ae23352c1e9a0776abc.tar.zst
tangerine-wallet-browser-4671f28476165fec43785ae23352c1e9a0776abc.zip
Allow editing of token transactions.
Diffstat (limited to 'ui/app')
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js95
-rw-r--r--ui/app/send-v2.js7
2 files changed, 91 insertions, 11 deletions
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index f14da38ef..aab45f2a4 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -2,9 +2,10 @@ const Component = require('react').Component
const { connect } = require('react-redux')
const h = require('react-hyperscript')
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')
-abiDecoder.addABI(abi)
+abiDecoder.addABI(tokenAbi)
const actions = require('../../actions')
const clone = require('clone')
const Identicon = require('../identicon')
@@ -24,6 +25,7 @@ const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
const {
getTokenExchangeRate,
getSelectedAddress,
+ getSelectedTokenContract,
} = require('../../selectors')
module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
@@ -32,6 +34,7 @@ function mapStateToProps (state, ownProps) {
const { token: { symbol }, txData } = ownProps
const { txParams } = txData || {}
const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+
const {
conversionRate,
identities,
@@ -47,6 +50,8 @@ function mapStateToProps (state, ownProps) {
tokenExchangeRate,
tokenData: tokenData || {},
currentCurrency: currentCurrency.toUpperCase(),
+ send: state.metamask.send,
+ tokenContract: getSelectedTokenContract(state),
}
}
@@ -57,6 +62,30 @@ function mapDispatchToProps (dispatch, ownProps) {
backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
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 () {
+ const { tokenContract, selectedAddress } = this.props
+ tokenContract && tokenContract
+ .balanceOf(selectedAddress)
+ .then(usersToken => {
+ })
this.props.updateTokenExchangeRate()
}
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 { value } = params[1] || {}
+ let { value } = params[1] || {}
const { decimals } = token
+
+ if (editingTransactionId) {
+ value = conversionUtil(amount, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ })
+ }
+
const sendTokenAmount = calcTokenAmount(value, decimals)
return {
@@ -242,9 +290,8 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
}
ConfirmSendToken.prototype.render = function () {
- const { backToAccountDetail, selectedAddress } = this.props
+ const { editTransaction } = this.props
const txMeta = this.gatherTxMeta()
-
const {
from: {
address: fromAddress,
@@ -266,8 +313,8 @@ ConfirmSendToken.prototype.render = function () {
h('div.confirm-screen-wrapper.flex-column.flex-grow', [
h('h3.flex-center.confirm-screen-header', [
h('button.confirm-screen-back-button', {
- onClick: () => backToAccountDetail(selectedAddress),
- }, 'BACK'),
+ onClick: () => editTransaction(txMeta),
+ }, 'EDIT'),
h('div.confirm-screen-title', 'Confirm Transaction'),
h('div.confirm-screen-header-tip'),
]),
@@ -389,6 +436,38 @@ ConfirmSendToken.prototype.gatherTxMeta = function () {
const state = this.state
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)}`)
return txData
}
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index 0d745c66e..788ae87b4 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -76,7 +76,6 @@ SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
updateSendTokenBalance,
} = this.props
const { decimals } = selectedToken || {}
-
const tokenBalance = calcTokenAmount(usersToken.balance.toString(), decimals)
updateSendTokenBalance(tokenBalance)
@@ -105,13 +104,14 @@ SendTransactionScreen.prototype.componentWillMount = function () {
const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data)
+ const tokenBalancePromise = tokenContract && tokenContract.balanceOf(from.address)
let newGasTotal
if (!editingTransactionId) {
Promise
.all([
getGasPrice(),
estimateGas(estimateGasParams),
- tokenContract && tokenContract.balanceOf(from.address),
+ tokenBalancePromise,
])
.then(([gasPrice, gas, usersToken]) => {
@@ -130,6 +130,8 @@ SendTransactionScreen.prototype.componentWillMount = function () {
multiplierBase: 16,
})
updateGasTotal(newGasTotal)
+ tokenBalancePromise && tokenBalancePromise.then(
+ usersToken => this.updateSendTokenBalance(usersToken))
}
}
@@ -363,7 +365,6 @@ SendTransactionScreen.prototype.validateAmount = function (value) {
const amount = value
let amountError = null
-
const sufficientBalance = isBalanceSufficient({
amount: selectedToken ? '0x0' : amount,
gasTotal,