1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 19:26:13 +02:00

Show token amounts in TransactionListItem for token transfers

This commit is contained in:
Alexander Tseung 2018-08-05 22:25:58 -07:00
parent 13c4ecd610
commit 33a94332e4
10 changed files with 75 additions and 79 deletions

View File

@ -69,7 +69,7 @@ export default class TransactionListItem extends PureComponent {
const nonceAndDateText = `#${nonce} - ${formatDate(transaction.time)}` const nonceAndDateText = `#${nonce} - ${formatDate(transaction.time)}`
const fiatDisplayText = `-${fiatDisplayValue}` const fiatDisplayText = `-${fiatDisplayValue}`
const ethDisplayText = `-${ethTransactionAmount} ETH` const ethDisplayText = ethTransactionAmount && `-${ethTransactionAmount} ETH`
return ( return (
<div <div

View File

@ -5,18 +5,39 @@ import withMethodData from '../../higher-order-components/with-method-data'
import TransactionListItem from './transaction-list-item.component' import TransactionListItem from './transaction-list-item.component'
import { setSelectedToken, retryTransaction } from '../../actions' import { setSelectedToken, retryTransaction } from '../../actions'
import { getEthFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util' import { getEthFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util'
import { getTokenData } from '../../helpers/transactions.util'
import { formatCurrency } from '../../helpers/confirm-transaction/util' import { formatCurrency } from '../../helpers/confirm-transaction/util'
import { calcTokenAmount } from '../../token-util'
import { TOKEN_METHOD_TRANSFER } from '../../constants/transactions'
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const { metamask } = state const { metamask } = state
const { currentCurrency, conversionRate } = metamask const { currentCurrency, conversionRate } = metamask
const { transaction: { txParams: { value } = {} } = {} } = ownProps const { transaction: { txParams: { value, data } = {} } = {}, token } = ownProps
const ethTransactionAmount = getEthFromWeiHex({ value, conversionRate })
const fiatTransactionAmount = getValueFromWeiHex({ let ethTransactionAmount, fiatDisplayValue
value, conversionRate, toCurrency: currentCurrency, numberOfDecimals: 2,
}) if (token) {
const fiatFormattedAmount = formatCurrency(fiatTransactionAmount, currentCurrency) const { decimals = '', symbol = '' } = token
const fiatDisplayValue = `${fiatFormattedAmount} ${currentCurrency.toUpperCase()}` const tokenData = getTokenData(data)
if (tokenData.params && tokenData.params.length === 2) {
const tokenDataName = tokenData.name || ''
const tokenValue = tokenData.params[1].value
const tokenAmount = tokenDataName.toLowerCase() === TOKEN_METHOD_TRANSFER
? calcTokenAmount(tokenValue, decimals)
: tokenValue
fiatDisplayValue = `${tokenAmount} ${symbol}`
}
} else {
ethTransactionAmount = getEthFromWeiHex({ value, conversionRate })
const fiatTransactionAmount = getValueFromWeiHex({
value, conversionRate, toCurrency: currentCurrency, numberOfDecimals: 2,
})
const fiatFormattedAmount = formatCurrency(fiatTransactionAmount, currentCurrency)
fiatDisplayValue = `${fiatFormattedAmount} ${currentCurrency.toUpperCase()}`
}
return { return {
ethTransactionAmount, ethTransactionAmount,

View File

@ -17,6 +17,7 @@ export default class TransactionList extends PureComponent {
pendingTransactions: PropTypes.array, pendingTransactions: PropTypes.array,
completedTransactions: PropTypes.array, completedTransactions: PropTypes.array,
transactionToRetry: PropTypes.object, transactionToRetry: PropTypes.object,
selectedToken: PropTypes.object,
} }
shouldShowRetry = transaction => { shouldShowRetry = transaction => {
@ -27,7 +28,11 @@ export default class TransactionList extends PureComponent {
renderTransactions () { renderTransactions () {
const { t } = this.context const { t } = this.context
const { pendingTransactions = [], completedTransactions = [] } = this.props const {
pendingTransactions = [],
completedTransactions = [],
selectedToken,
} = this.props
return ( return (
<div className="transaction-list__transactions"> <div className="transaction-list__transactions">
@ -43,6 +48,7 @@ export default class TransactionList extends PureComponent {
transaction={transaction} transaction={transaction}
key={transaction.id} key={transaction.id}
showRetry={this.shouldShowRetry(transaction)} showRetry={this.shouldShowRetry(transaction)}
token={selectedToken}
/> />
)) ))
} }
@ -59,6 +65,7 @@ export default class TransactionList extends PureComponent {
<TransactionListItem <TransactionListItem
transaction={transaction} transaction={transaction}
key={transaction.id} key={transaction.id}
token={selectedToken}
/> />
)) ))
: this.renderEmpty() : this.renderEmpty()

View File

@ -6,6 +6,7 @@ import {
pendingTransactionsSelector, pendingTransactionsSelector,
completedTransactionsSelector, completedTransactionsSelector,
} from '../../selectors/transactions' } from '../../selectors/transactions'
import { selectedTokenSelector } from '../../selectors/tokens'
import { getLatestSubmittedTxWithEarliestNonce } from '../../helpers/transactions.util' import { getLatestSubmittedTxWithEarliestNonce } from '../../helpers/transactions.util'
const mapStateToProps = state => { const mapStateToProps = state => {
@ -15,6 +16,7 @@ const mapStateToProps = state => {
completedTransactions: completedTransactionsSelector(state), completedTransactions: completedTransactionsSelector(state),
pendingTransactions, pendingTransactions,
transactionToRetry: getLatestSubmittedTxWithEarliestNonce(pendingTransactions), transactionToRetry: getLatestSubmittedTxWithEarliestNonce(pendingTransactions),
selectedToken: selectedTokenSelector(state),
} }
} }

View File

@ -5,7 +5,6 @@ import {
} from '../selectors/confirm-transaction' } from '../selectors/confirm-transaction'
import { import {
getTokenData,
getValueFromWeiHex, getValueFromWeiHex,
getTransactionFee, getTransactionFee,
getHexGasTotal, getHexGasTotal,
@ -16,7 +15,7 @@ import {
isSmartContractAddress, isSmartContractAddress,
} from '../helpers/confirm-transaction/util' } from '../helpers/confirm-transaction/util'
import { getMethodData } from '../helpers/transactions.util' import { getTokenData, getMethodData } from '../helpers/transactions.util'
import { getSymbolAndDecimals } from '../token-util' import { getSymbolAndDecimals } from '../token-util'
import { conversionUtil } from '../conversion-util' import { conversionUtil } from '../conversion-util'

View File

@ -1,12 +1,8 @@
import currencyFormatter from 'currency-formatter' import currencyFormatter from 'currency-formatter'
import currencies from 'currency-formatter/currencies' import currencies from 'currency-formatter/currencies'
import abi from 'human-standard-token-abi'
import abiDecoder from 'abi-decoder'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
abiDecoder.addABI(abi)
import { import {
conversionUtil, conversionUtil,
addCurrencies, addCurrencies,
@ -16,10 +12,6 @@ import {
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction' import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
export function getTokenData (data = {}) {
return abiDecoder.decodeMethod(data)
}
export function increaseLastGasPrice (lastGasPrice) { export function increaseLastGasPrice (lastGasPrice) {
return ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, { return ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
multiplicandBase: 16, multiplicandBase: 16,

View File

@ -1,7 +1,7 @@
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import MethodRegistry from 'eth-method-registry' import MethodRegistry from 'eth-method-registry'
const registry = new MethodRegistry({ provider: global.ethereumProvider }) import abi from 'human-standard-token-abi'
import abiDecoder from 'abi-decoder'
import { hexToDecimal } from './conversions.util' import { hexToDecimal } from './conversions.util'
import { import {
@ -15,6 +15,26 @@ import {
TRANSFER_FROM_ACTION_KEY, TRANSFER_FROM_ACTION_KEY,
} from '../constants/transactions' } from '../constants/transactions'
abiDecoder.addABI(abi)
export function getTokenData (data = {}) {
return abiDecoder.decodeMethod(data)
}
const registry = new MethodRegistry({ provider: global.ethereumProvider })
export async function getMethodData (data = {}) {
const prefixedData = ethUtil.addHexPrefix(data)
const fourBytePrefix = prefixedData.slice(0, 10)
const sig = await registry.lookup(fourBytePrefix)
const parsedResult = registry.parse(sig)
return {
name: parsedResult.name,
params: parsedResult.args,
}
}
export function isConfirmDeployContract (txData = {}) { export function isConfirmDeployContract (txData = {}) {
const { txParams = {} } = txData const { txParams = {} } = txData
return !txParams.to return !txParams.to
@ -46,18 +66,6 @@ export function getTransactionActionKey (transaction, methodData) {
} }
} }
export async function getMethodData (data = {}) {
const prefixedData = ethUtil.addHexPrefix(data)
const fourBytePrefix = prefixedData.slice(0, 10)
const sig = await registry.lookup(fourBytePrefix)
const parsedResult = registry.parse(sig)
return {
name: parsedResult.name,
params: parsedResult.args,
}
}
export function getLatestSubmittedTxWithEarliestNonce (transactions = []) { export function getLatestSubmittedTxWithEarliestNonce (transactions = []) {
if (!transactions.length) { if (!transactions.length) {
return {} return {}

View File

@ -1,5 +1,4 @@
const abi = require('human-standard-token-abi') const abi = require('human-standard-token-abi')
import { createSelector } from 'reselect'
import { import {
transactionsSelector, transactionsSelector,
@ -105,50 +104,6 @@ function getCurrentAccountWithSendEtherInfo (state) {
return accounts.find(({ address }) => address === currentAddress) return accounts.find(({ address }) => address === currentAddress)
} }
// // function shapeShiftTxListSelector (state) {
// // return state.metamask.shapeShiftTxList || []
// // }
// const transactionsSelector = createSelector(
// selectedTokenAddressSelector,
// unapprovedMsgsSelector,
// shapeShiftTxListSelector,
// selectedAddressTxListSelector,
// (selectedTokenAddress, unapprovedMsgs = {}, shapeShiftTxList = [], transactions = []) => {
// const unapprovedMsgsList = valuesFor(unapprovedMsgs)
// const txsToRender = transactions.concat(unapprovedMsgsList, shapeShiftTxList)
// return selectedTokenAddress
// ? txsToRender
// .filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)
// .sort((a, b) => b.time - a.time)
// : txsToRender
// .sort((a, b) => b.time - a.time)
// }
// )
// // function transactionsSelector (state) {
// // const { selectedTokenAddress } = state.metamask
// // const unapprovedMsgs = valuesFor(state.metamask.unapprovedMsgs)
// // const shapeShiftTxList = shapeShiftTxListSelector(state)
// // const transactions = state.metamask.selectedAddressTxList || []
// // const txsToRender = transactions.concat(unapprovedMsgs, shapeShiftTxList)
// // return selectedTokenAddress
// // ? txsToRender
// // .filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)
// // .sort((a, b) => b.time - a.time)
// // : txsToRender
// // .sort((a, b) => b.time - a.time)
// // }
export const pendingTransactionsSelector = createSelector(
transactionsSelector,
transactions => {
}
)
function getGasIsLoading (state) { function getGasIsLoading (state) {
return state.appState.gasIsLoading return state.appState.gasIsLoading
} }

View File

@ -0,0 +1,11 @@
import { createSelector } from 'reselect'
export const selectedTokenAddressSelector = state => state.metamask.selectedTokenAddress
export const tokenSelector = state => state.metamask.tokens
export const selectedTokenSelector = createSelector(
tokenSelector,
selectedTokenAddressSelector,
(tokens = [], selectedTokenAddress = '') => {
return tokens.find(({ address }) => address === selectedTokenAddress)
}
)

View File

@ -6,8 +6,9 @@ import {
SUBMITTED_STATUS, SUBMITTED_STATUS,
} from '../constants/transactions' } from '../constants/transactions'
import { selectedTokenAddressSelector } from './tokens'
export const shapeShiftTxListSelector = state => state.metamask.shapeShiftTxList export const shapeShiftTxListSelector = state => state.metamask.shapeShiftTxList
export const selectedTokenAddressSelector = state => state.metamask.selectedTokenAddress
export const unapprovedMsgsSelector = state => state.metamask.unapprovedMsgs export const unapprovedMsgsSelector = state => state.metamask.unapprovedMsgs
export const selectedAddressTxListSelector = state => state.metamask.selectedAddressTxList export const selectedAddressTxListSelector = state => state.metamask.selectedAddressTxList