mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Fixes display of confirm screen token decimals by not relying on confirmTransaction state.
This commit is contained in:
parent
0e108db3cc
commit
789fc8b8ad
@ -68,6 +68,22 @@ async function getDecimals (tokenAddress) {
|
|||||||
return decimals
|
return decimals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchSymbolAndDecimals (tokenAddress) {
|
||||||
|
let symbol, decimals
|
||||||
|
|
||||||
|
try {
|
||||||
|
symbol = await getSymbol(tokenAddress)
|
||||||
|
decimals = await getDecimals(tokenAddress)
|
||||||
|
} catch (error) {
|
||||||
|
log.warn(`symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
symbol: symbol || DEFAULT_SYMBOL,
|
||||||
|
decimals: decimals || DEFAULT_DECIMALS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getSymbolAndDecimals (tokenAddress, existingTokens = []) {
|
export async function getSymbolAndDecimals (tokenAddress, existingTokens = []) {
|
||||||
const existingToken = existingTokens.find(({ address }) => tokenAddress === address)
|
const existingToken = existingTokens.find(({ address }) => tokenAddress === address)
|
||||||
|
|
||||||
@ -116,3 +132,8 @@ export function getTokenValue (tokenParams = []) {
|
|||||||
const valueData = tokenParams.find(param => param.name === '_value')
|
const valueData = tokenParams.find(param => param.name === '_value')
|
||||||
return valueData && valueData.value
|
return valueData && valueData.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTokenToAddress (tokenParams = []) {
|
||||||
|
const toAddressData = tokenParams.find(param => param.name === '_to')
|
||||||
|
return toAddressData && toAddressData.value
|
||||||
|
}
|
||||||
|
@ -102,6 +102,20 @@ export function getFourBytePrefix (data = '') {
|
|||||||
return fourBytePrefix
|
return fourBytePrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an transaction category, returns a boolean which indicates whether the transaction is calling an erc20 token method
|
||||||
|
*
|
||||||
|
* @param {string} transactionCategory - The category of transaction being evaluated
|
||||||
|
* @returns {boolean} - whether the transaction is calling an erc20 token method
|
||||||
|
*/
|
||||||
|
export function isTokenMethodAction (transactionCategory) {
|
||||||
|
return [
|
||||||
|
TOKEN_METHOD_TRANSFER,
|
||||||
|
TOKEN_METHOD_APPROVE,
|
||||||
|
TOKEN_METHOD_TRANSFER_FROM,
|
||||||
|
].includes(transactionCategory)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the action of a transaction as a key to be passed into the translator.
|
* Returns the action of a transaction as a key to be passed into the translator.
|
||||||
* @param {Object} transaction - txData object
|
* @param {Object} transaction - txData object
|
||||||
@ -122,11 +136,7 @@ export function getTransactionActionKey (transaction) {
|
|||||||
return DEPLOY_CONTRACT_ACTION_KEY
|
return DEPLOY_CONTRACT_ACTION_KEY
|
||||||
}
|
}
|
||||||
|
|
||||||
const isTokenAction = [
|
const isTokenAction = isTokenMethodAction(transactionCategory)
|
||||||
TOKEN_METHOD_TRANSFER,
|
|
||||||
TOKEN_METHOD_APPROVE,
|
|
||||||
TOKEN_METHOD_TRANSFER_FROM,
|
|
||||||
].find(actionName => actionName === transactionCategory)
|
|
||||||
const isNonTokenSmartContract = transactionCategory === CONTRACT_INTERACTION_KEY
|
const isNonTokenSmartContract = transactionCategory === CONTRACT_INTERACTION_KEY
|
||||||
|
|
||||||
if (isTokenAction || isNonTokenSmartContract) {
|
if (isTokenAction || isNonTokenSmartContract) {
|
||||||
|
@ -1,27 +1,42 @@
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component'
|
import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component'
|
||||||
import {
|
import {
|
||||||
tokenAmountAndToAddressSelector,
|
|
||||||
contractExchangeRateSelector,
|
contractExchangeRateSelector,
|
||||||
} from '../../selectors/confirm-transaction'
|
} from '../../selectors/confirm-transaction'
|
||||||
|
import { tokenSelector } from '../../selectors/tokens'
|
||||||
|
import {
|
||||||
|
getTokenData,
|
||||||
|
} from '../../helpers/utils/transactions.util'
|
||||||
|
import {
|
||||||
|
calcTokenAmount,
|
||||||
|
getTokenToAddress,
|
||||||
|
getTokenValue,
|
||||||
|
} from '../../helpers/utils/token-util'
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
|
||||||
const { tokenAmount: ownTokenAmount } = ownProps
|
const mapStateToProps = (state) => {
|
||||||
const { confirmTransaction, metamask: { currentCurrency, conversionRate } } = state
|
const { confirmTransaction, metamask: { currentCurrency, conversionRate } } = state
|
||||||
const {
|
const {
|
||||||
txData: { txParams: { to: tokenAddress } = {} } = {},
|
txData: { txParams: { to: tokenAddress, data } = {} } = {},
|
||||||
tokenProps: { tokenSymbol } = {},
|
|
||||||
fiatTransactionTotal,
|
fiatTransactionTotal,
|
||||||
ethTransactionTotal,
|
ethTransactionTotal,
|
||||||
} = confirmTransaction
|
} = confirmTransaction
|
||||||
|
|
||||||
const { tokenAmount, toAddress } = tokenAmountAndToAddressSelector(state)
|
|
||||||
|
const tokens = tokenSelector(state)
|
||||||
|
const currentToken = tokens && tokens.find(({ address }) => tokenAddress === address)
|
||||||
|
const { decimals, symbol: tokenSymbol } = currentToken || {}
|
||||||
|
|
||||||
|
const tokenData = getTokenData(data)
|
||||||
|
const tokenValue = tokenData && getTokenValue(tokenData.params)
|
||||||
|
const toAddress = tokenData && getTokenToAddress(tokenData.params)
|
||||||
|
const tokenAmount = tokenData && calcTokenAmount(tokenValue, decimals).toString()
|
||||||
const contractExchangeRate = contractExchangeRateSelector(state)
|
const contractExchangeRate = contractExchangeRateSelector(state)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
toAddress,
|
toAddress,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
tokenAmount: typeof ownTokenAmount !== 'undefined' ? ownTokenAmount : tokenAmount,
|
tokenAmount,
|
||||||
tokenSymbol,
|
tokenSymbol,
|
||||||
currentCurrency,
|
currentCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
|
@ -37,6 +37,8 @@ export default class ConfirmTransaction extends Component {
|
|||||||
getContractMethodData: PropTypes.func,
|
getContractMethodData: PropTypes.func,
|
||||||
transactionId: PropTypes.string,
|
transactionId: PropTypes.string,
|
||||||
paramsTransactionId: PropTypes.string,
|
paramsTransactionId: PropTypes.string,
|
||||||
|
getTokenParams: PropTypes.func,
|
||||||
|
isTokenMethodAction: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
getParamsTransactionId () {
|
getParamsTransactionId () {
|
||||||
@ -49,11 +51,13 @@ export default class ConfirmTransaction extends Component {
|
|||||||
totalUnapprovedCount = 0,
|
totalUnapprovedCount = 0,
|
||||||
send = {},
|
send = {},
|
||||||
history,
|
history,
|
||||||
transaction: { txParams: { data } = {} } = {},
|
transaction: { txParams: { data, to } = {} } = {},
|
||||||
fetchBasicGasAndTimeEstimates,
|
fetchBasicGasAndTimeEstimates,
|
||||||
getContractMethodData,
|
getContractMethodData,
|
||||||
transactionId,
|
transactionId,
|
||||||
paramsTransactionId,
|
paramsTransactionId,
|
||||||
|
getTokenParams,
|
||||||
|
isTokenMethodAction,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!totalUnapprovedCount && !send.to) {
|
if (!totalUnapprovedCount && !send.to) {
|
||||||
@ -63,6 +67,9 @@ export default class ConfirmTransaction extends Component {
|
|||||||
|
|
||||||
fetchBasicGasAndTimeEstimates()
|
fetchBasicGasAndTimeEstimates()
|
||||||
getContractMethodData(data)
|
getContractMethodData(data)
|
||||||
|
if (isTokenMethodAction) {
|
||||||
|
getTokenParams(to)
|
||||||
|
}
|
||||||
this.props.setTransactionToConfirm(transactionId || paramsTransactionId)
|
this.props.setTransactionToConfirm(transactionId || paramsTransactionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,16 @@ import {
|
|||||||
setTransactionToConfirm,
|
setTransactionToConfirm,
|
||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
} from '../../ducks/confirm-transaction/confirm-transaction.duck'
|
} from '../../ducks/confirm-transaction/confirm-transaction.duck'
|
||||||
|
import {
|
||||||
|
isTokenMethodAction,
|
||||||
|
} from '../../helpers/utils/transactions.util'
|
||||||
import {
|
import {
|
||||||
fetchBasicGasAndTimeEstimates,
|
fetchBasicGasAndTimeEstimates,
|
||||||
} from '../../ducks/gas/gas.duck'
|
} from '../../ducks/gas/gas.duck'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getContractMethodData,
|
getContractMethodData,
|
||||||
|
getTokenParams,
|
||||||
} from '../../store/actions'
|
} from '../../store/actions'
|
||||||
import ConfirmTransaction from './confirm-transaction.component'
|
import ConfirmTransaction from './confirm-transaction.component'
|
||||||
import { unconfirmedTransactionsListSelector } from '../../selectors/confirm-transaction'
|
import { unconfirmedTransactionsListSelector } from '../../selectors/confirm-transaction'
|
||||||
@ -25,6 +29,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
const transaction = totalUnconfirmed
|
const transaction = totalUnconfirmed
|
||||||
? unapprovedTxs[id] || unconfirmedTransactions[totalUnconfirmed - 1]
|
? unapprovedTxs[id] || unconfirmedTransactions[totalUnconfirmed - 1]
|
||||||
: {}
|
: {}
|
||||||
|
const { id: transactionId, transactionCategory } = transaction
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalUnapprovedCount: totalUnconfirmed,
|
totalUnapprovedCount: totalUnconfirmed,
|
||||||
@ -33,9 +38,10 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
unapprovedTxs,
|
unapprovedTxs,
|
||||||
id,
|
id,
|
||||||
paramsTransactionId: id && String(id),
|
paramsTransactionId: id && String(id),
|
||||||
transactionId: transaction.id && String(transaction.id),
|
transactionId: transactionId && String(transactionId),
|
||||||
unconfirmedTransactions,
|
unconfirmedTransactions,
|
||||||
transaction,
|
transaction,
|
||||||
|
isTokenMethodAction: isTokenMethodAction(transactionCategory),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +53,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||||
fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()),
|
fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()),
|
||||||
getContractMethodData: (data) => dispatch(getContractMethodData(data)),
|
getContractMethodData: (data) => dispatch(getContractMethodData(data)),
|
||||||
|
getTokenParams: (tokenAddress) => dispatch(getTokenParams(tokenAddress)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ const {
|
|||||||
const ethUtil = require('ethereumjs-util')
|
const ethUtil = require('ethereumjs-util')
|
||||||
const { fetchLocale } = require('../helpers/utils/i18n-helper')
|
const { fetchLocale } = require('../helpers/utils/i18n-helper')
|
||||||
const { getMethodDataAsync } = require('../helpers/utils/transactions.util')
|
const { getMethodDataAsync } = require('../helpers/utils/transactions.util')
|
||||||
|
const { fetchSymbolAndDecimals } = require('../helpers/utils/token-util')
|
||||||
const log = require('loglevel')
|
const log = require('loglevel')
|
||||||
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../../app/scripts/lib/enums')
|
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../../app/scripts/lib/enums')
|
||||||
const { hasUnconfirmedTransactions } = require('../helpers/utils/confirm-tx.util')
|
const { hasUnconfirmedTransactions } = require('../helpers/utils/confirm-tx.util')
|
||||||
@ -367,6 +368,12 @@ var actions = {
|
|||||||
loadingMethoDataFinished,
|
loadingMethoDataFinished,
|
||||||
LOADING_METHOD_DATA_STARTED: 'LOADING_METHOD_DATA_STARTED',
|
LOADING_METHOD_DATA_STARTED: 'LOADING_METHOD_DATA_STARTED',
|
||||||
LOADING_METHOD_DATA_FINISHED: 'LOADING_METHOD_DATA_FINISHED',
|
LOADING_METHOD_DATA_FINISHED: 'LOADING_METHOD_DATA_FINISHED',
|
||||||
|
|
||||||
|
getTokenParams,
|
||||||
|
loadingTokenParamsStarted,
|
||||||
|
LOADING_TOKEN_PARAMS_STARTED: 'LOADING_TOKEN_PARAMS_STARTED',
|
||||||
|
loadingTokenParamsFinished,
|
||||||
|
LOADING_TOKEN_PARAMS_FINISHED: 'LOADING_TOKEN_PARAMS_FINISHED',
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = actions
|
module.exports = actions
|
||||||
@ -2816,3 +2823,39 @@ function getContractMethodData (data = '') {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadingTokenParamsStarted () {
|
||||||
|
return {
|
||||||
|
type: actions.LOADING_TOKEN_PARAMS_STARTED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadingTokenParamsFinished () {
|
||||||
|
return {
|
||||||
|
type: actions.LOADING_TOKEN_PARAMS_FINISHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTokenParams (tokenAddress) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const existingTokens = getState().metamask.tokens
|
||||||
|
const existingToken = existingTokens.find(({ address }) => tokenAddress === address)
|
||||||
|
|
||||||
|
if (existingToken) {
|
||||||
|
return Promise.resolve({
|
||||||
|
symbol: existingToken.symbol,
|
||||||
|
decimals: existingToken.decimals,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(actions.loadingTokenParamsStarted())
|
||||||
|
log.debug(`loadingTokenParams`)
|
||||||
|
|
||||||
|
|
||||||
|
return fetchSymbolAndDecimals(tokenAddress, existingTokens)
|
||||||
|
.then(({ symbol, decimals }) => {
|
||||||
|
dispatch(actions.addToken(tokenAddress, symbol, decimals))
|
||||||
|
dispatch(actions.loadingTokenParamsFinished())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user