Fetch token prices based on contract address

feature/default_network_editable
bitpshr 7 years ago
parent 3afe76bcba
commit a350e80fee
  1. 68
      ui/app/actions.js
  2. 8
      ui/app/components/pending-tx/confirm-send-token.js
  3. 2
      ui/app/components/send/send-v2-container.js
  4. 20
      ui/app/components/token-cell.js
  5. 18
      ui/app/components/tx-list-item.js
  6. 23
      ui/app/reducers/metamask.js
  7. 19
      ui/app/selectors.js
  8. 8
      ui/app/send-v2.js

@ -220,8 +220,10 @@ var actions = {
coinBaseSubview: coinBaseSubview, coinBaseSubview: coinBaseSubview,
SHAPESHIFT_SUBVIEW: 'SHAPESHIFT_SUBVIEW', SHAPESHIFT_SUBVIEW: 'SHAPESHIFT_SUBVIEW',
shapeShiftSubview: shapeShiftSubview, shapeShiftSubview: shapeShiftSubview,
UPDATE_TOKEN_EXCHANGE_RATE: 'UPDATE_TOKEN_EXCHANGE_RATE', UPDATE_CONTRACT_EXCHANGE_RATES: 'UPDATE_CONTRACT_EXCHANGE_RATES',
updateTokenExchangeRate, UPDATE_CONTRACT_EXCHANGE_RATE: 'UPDATE_CONTRACT_EXCHANGE_RATE',
updateContractExchangeRates,
updateContractExchangeRate,
PAIR_UPDATE: 'PAIR_UPDATE', PAIR_UPDATE: 'PAIR_UPDATE',
pairUpdate: pairUpdate, pairUpdate: pairUpdate,
coinShiftRquest: coinShiftRquest, coinShiftRquest: coinShiftRquest,
@ -1080,9 +1082,12 @@ function unlockMetamask (account) {
} }
function updateMetamaskState (newState) { function updateMetamaskState (newState) {
return { return async dispatch => {
type: actions.UPDATE_METAMASK_STATE, await dispatch({
value: newState, type: actions.UPDATE_METAMASK_STATE,
value: newState,
})
dispatch(updateContractExchangeRates())
} }
} }
@ -1295,9 +1300,12 @@ function addTokens (tokens) {
} }
function updateTokens (newTokens) { function updateTokens (newTokens) {
return { return async dispatch => {
type: actions.UPDATE_TOKENS, await dispatch({
newTokens, type: actions.UPDATE_TOKENS,
newTokens,
})
dispatch(updateContractExchangeRates())
} }
} }
@ -1751,24 +1759,38 @@ function shapeShiftRequest (query, options, cb) {
} }
} }
function updateTokenExchangeRate (token = '') { async function fetchContractRate (address) {
const pair = `${token.toLowerCase()}_eth` try {
const response = await fetch(`https://exchanges.balanc3.net/prices?from=${address}&to=ETH&autoConversion=false&summaryOnly=true`)
const json = await response.json()
const rate = json && json.length ? json[0].averagePrice : 0
return { address, rate }
} catch (error) { }
}
return dispatch => { function updateContractExchangeRates () {
if (!token) { return async (dispatch, getState) => {
return const { metamask: { tokens = [] } } = getState()
const newExchangeRates = {}
for (const i in tokens) {
const address = tokens[i].address
newExchangeRates[address] = (await fetchContractRate(address)).rate
} }
shapeShiftRequest('marketinfo', { pair }, marketinfo => { dispatch({
if (!marketinfo.error) { type: actions.UPDATE_CONTRACT_EXCHANGE_RATES,
dispatch({ payload: { newExchangeRates },
type: actions.UPDATE_TOKEN_EXCHANGE_RATE, })
payload: { }
pair, }
marketinfo,
}, function updateContractExchangeRate (address) {
}) return async dispatch => {
} const { address, rate } = await fetchContractRate(address)
dispatch({
type: actions.UPDATE_CONTRACT_EXCHANGE_RATE,
payload: { address, rate },
}) })
} }
} }

@ -48,7 +48,7 @@ module.exports = compose(
function mapStateToProps (state, ownProps) { function mapStateToProps (state, ownProps) {
const { token: { symbol }, txData } = ownProps const { token: { address }, txData } = ownProps
const { txParams } = txData || {} const { txParams } = txData || {}
const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data) const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
@ -59,7 +59,7 @@ function mapStateToProps (state, ownProps) {
} = state.metamask } = state.metamask
const accounts = state.metamask.accounts const accounts = state.metamask.accounts
const selectedAddress = getSelectedAddress(state) const selectedAddress = getSelectedAddress(state)
const tokenExchangeRate = getTokenExchangeRate(state, symbol) const tokenExchangeRate = getTokenExchangeRate(state, address)
const { balance } = accounts[selectedAddress] const { balance } = accounts[selectedAddress]
return { return {
conversionRate, conversionRate,
@ -75,12 +75,9 @@ function mapStateToProps (state, ownProps) {
} }
function mapDispatchToProps (dispatch, ownProps) { function mapDispatchToProps (dispatch, ownProps) {
const { token: { symbol } } = ownProps
return { return {
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)),
editTransaction: txMeta => { editTransaction: txMeta => {
const { token: { address } } = ownProps const { token: { address } } = ownProps
const { txParams = {}, id } = txMeta const { txParams = {}, id } = txMeta
@ -203,7 +200,6 @@ ConfirmSendToken.prototype.componentWillMount = function () {
.balanceOf(selectedAddress) .balanceOf(selectedAddress)
.then(usersToken => { .then(usersToken => {
}) })
this.props.updateTokenExchangeRate()
this.updateComponentSendErrors({}) this.updateComponentSendErrors({})
} }

@ -66,7 +66,7 @@ function mapDispatchToProps (dispatch) {
showCustomizeGasModal: () => dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })), showCustomizeGasModal: () => dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })),
estimateGas: params => dispatch(actions.estimateGas(params)), estimateGas: params => dispatch(actions.estimateGas(params)),
getGasPrice: () => dispatch(actions.getGasPrice()), getGasPrice: () => dispatch(actions.getGasPrice()),
updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)), updateContractExchangeRate: address => dispatch(actions.updateContractExchangeRate(address)),
signTokenTx: (tokenAddress, toAddress, amount, txData) => ( signTokenTx: (tokenAddress, toAddress, amount, txData) => (
dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData)) dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
), ),

@ -16,7 +16,7 @@ function mapStateToProps (state) {
currentCurrency: state.metamask.currentCurrency, currentCurrency: state.metamask.currentCurrency,
selectedTokenAddress: state.metamask.selectedTokenAddress, selectedTokenAddress: state.metamask.selectedTokenAddress,
userAddress: selectors.getSelectedAddress(state), userAddress: selectors.getSelectedAddress(state),
tokenExchangeRates: state.metamask.tokenExchangeRates, contractExchangeRates: state.metamask.contractExchangeRates,
conversionRate: state.metamask.conversionRate, conversionRate: state.metamask.conversionRate,
sidebarOpen: state.appState.sidebarOpen, sidebarOpen: state.appState.sidebarOpen,
} }
@ -25,7 +25,6 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) { function mapDispatchToProps (dispatch) {
return { return {
setSelectedToken: address => dispatch(actions.setSelectedToken(address)), setSelectedToken: address => dispatch(actions.setSelectedToken(address)),
updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
hideSidebar: () => dispatch(actions.hideSidebar()), hideSidebar: () => dispatch(actions.hideSidebar()),
} }
} }
@ -41,15 +40,6 @@ function TokenCell () {
} }
} }
TokenCell.prototype.componentWillMount = function () {
const {
updateTokenExchangeRate,
symbol,
} = this.props
updateTokenExchangeRate(symbol)
}
TokenCell.prototype.render = function () { TokenCell.prototype.render = function () {
const { tokenMenuOpen } = this.state const { tokenMenuOpen } = this.state
const props = this.props const props = this.props
@ -60,7 +50,7 @@ TokenCell.prototype.render = function () {
network, network,
setSelectedToken, setSelectedToken,
selectedTokenAddress, selectedTokenAddress,
tokenExchangeRates, contractExchangeRates,
conversionRate, conversionRate,
hideSidebar, hideSidebar,
sidebarOpen, sidebarOpen,
@ -68,15 +58,13 @@ TokenCell.prototype.render = function () {
// userAddress, // userAddress,
} = props } = props
const pair = `${symbol.toLowerCase()}_eth`
let currentTokenToFiatRate let currentTokenToFiatRate
let currentTokenInFiat let currentTokenInFiat
let formattedFiat = '' let formattedFiat = ''
if (tokenExchangeRates[pair]) { if (contractExchangeRates[address]) {
currentTokenToFiatRate = multiplyCurrencies( currentTokenToFiatRate = multiplyCurrencies(
tokenExchangeRates[pair].rate, contractExchangeRates[address],
conversionRate conversionRate
) )
currentTokenInFiat = conversionUtil(string, { currentTokenInFiat = conversionUtil(string, {

@ -27,7 +27,7 @@ function mapStateToProps (state) {
return { return {
tokens: state.metamask.tokens, tokens: state.metamask.tokens,
currentCurrency: getCurrentCurrency(state), currentCurrency: getCurrentCurrency(state),
tokenExchangeRates: state.metamask.tokenExchangeRates, contractExchangeRates: state.metamask.contractExchangeRates,
selectedAddressTxList: state.metamask.selectedAddressTxList, selectedAddressTxList: state.metamask.selectedAddressTxList,
} }
} }
@ -142,31 +142,29 @@ TxListItem.prototype.getTokenInfo = async function () {
({ decimals, symbol } = await tokenInfoGetter(toAddress)) ({ decimals, symbol } = await tokenInfoGetter(toAddress))
} }
return { decimals, symbol } return { decimals, symbol, address: toAddress }
} }
TxListItem.prototype.getSendTokenTotal = async function () { TxListItem.prototype.getSendTokenTotal = async function () {
const { const {
txParams = {}, txParams = {},
conversionRate, conversionRate,
tokenExchangeRates, contractExchangeRates,
currentCurrency, currentCurrency,
} = this.props } = this.props
const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data) const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { params = [] } = decodedData || {} const { params = [] } = decodedData || {}
const { value } = params[1] || {} const { value } = params[1] || {}
const { decimals, symbol } = await this.getTokenInfo() const { decimals, symbol, address } = await this.getTokenInfo()
const total = calcTokenAmount(value, decimals) const total = calcTokenAmount(value, decimals)
const pair = symbol && `${symbol.toLowerCase()}_eth`
let tokenToFiatRate let tokenToFiatRate
let totalInFiat let totalInFiat
if (tokenExchangeRates[pair]) { if (contractExchangeRates[address]) {
tokenToFiatRate = multiplyCurrencies( tokenToFiatRate = multiplyCurrencies(
tokenExchangeRates[pair].rate, contractExchangeRates[address],
conversionRate conversionRate
) )
@ -220,7 +218,6 @@ TxListItem.prototype.resubmit = function () {
TxListItem.prototype.render = function () { TxListItem.prototype.render = function () {
const { const {
transactionStatus, transactionStatus,
transactionAmount,
onClick, onClick,
transactionId, transactionId,
dateString, dateString,
@ -229,7 +226,6 @@ TxListItem.prototype.render = function () {
txParams, txParams,
} = this.props } = this.props
const { total, fiatTotal, isTokenTx } = this.state const { total, fiatTotal, isTokenTx } = this.state
const showFiatTotal = transactionAmount !== '0x0' && fiatTotal
return h(`div${className || ''}`, { return h(`div${className || ''}`, {
key: transactionId, key: transactionId,
@ -288,7 +284,7 @@ TxListItem.prototype.render = function () {
h('span.tx-list-value', total), h('span.tx-list-value', total),
showFiatTotal && h('span.tx-list-fiat-value', fiatTotal), fiatTotal && h('span.tx-list-fiat-value', fiatTotal),
]), ]),
]), ]),

@ -24,6 +24,7 @@ function reduceMetamask (state, action) {
frequentRpcList: [], frequentRpcList: [],
addressBook: [], addressBook: [],
selectedTokenAddress: null, selectedTokenAddress: null,
contractExchangeRates: {},
tokenExchangeRates: {}, tokenExchangeRates: {},
tokens: [], tokens: [],
send: { send: {
@ -176,14 +177,22 @@ function reduceMetamask (state, action) {
conversionDate: action.value.conversionDate, conversionDate: action.value.conversionDate,
}) })
case actions.UPDATE_TOKEN_EXCHANGE_RATE: case actions.UPDATE_CONTRACT_EXCHANGE_RATES:
const { payload: { pair, marketinfo } } = action const { payload: { newExchangeRates } } = action
return extend(metamaskState, { return {
tokenExchangeRates: { ...metamaskState,
...metamaskState.tokenExchangeRates, contractExchangeRates: newExchangeRates,
[pair]: marketinfo, }
case actions.UPDATE_CONTRACT_EXCHANGE_RATE:
const { payload: { address, rate } } = action
return {
...metamaskState,
contractExchangeRates: {
...metamaskState.contractExchangeRates,
[address]: rate,
}, },
}) }
case actions.UPDATE_TOKENS: case actions.UPDATE_TOKENS:
return extend(metamaskState, { return extend(metamaskState, {

@ -62,22 +62,15 @@ function getSelectedToken (state) {
} }
function getSelectedTokenExchangeRate (state) { function getSelectedTokenExchangeRate (state) {
const tokenExchangeRates = state.metamask.tokenExchangeRates const contractExchangeRates = state.metamask.contractExchangeRates
const selectedToken = getSelectedToken(state) || {} const selectedToken = getSelectedToken(state) || {}
const { symbol = '' } = selectedToken const { address } = selectedToken
return contractExchangeRates[address] || 0
const pair = `${symbol.toLowerCase()}_eth`
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
} }
function getTokenExchangeRate (state, tokenSymbol) { function getTokenExchangeRate (state, address) {
const pair = `${tokenSymbol.toLowerCase()}_eth` const contractExchangeRates = state.metamask.contractExchangeRates
const tokenExchangeRates = state.metamask.tokenExchangeRates return contractExchangeRates[address] || 0
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
} }
function conversionRateSelector (state) { function conversionRateSelector (state) {

@ -89,14 +89,14 @@ SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
SendTransactionScreen.prototype.componentWillMount = function () { SendTransactionScreen.prototype.componentWillMount = function () {
const { const {
updateTokenExchangeRate, updateContractExchangeRate,
selectedToken = {}, selectedToken = {},
} = this.props } = this.props
const { symbol } = selectedToken || {} const { address } = selectedToken || {}
if (symbol) { if (address) {
updateTokenExchangeRate(symbol) updateContractExchangeRate(address)
} }
this.updateGas() this.updateGas()

Loading…
Cancel
Save