mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #3982 from MetaMask/i3981-contract-rates
Fetch token prices based on contract address
This commit is contained in:
commit
e4eb69dcc2
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
## Current Master
|
## Current Master
|
||||||
|
|
||||||
- Improved performance of 3D fox logo.
|
- Improved performance of 3D fox logo
|
||||||
|
- Fetch token prices based on contract address, not symbol
|
||||||
- Fix bug that prevents setting language locale in settings.
|
- Fix bug that prevents setting language locale in settings.
|
||||||
|
|
||||||
## 4.5.5 Fri Apr 06 2018
|
## 4.5.5 Fri Apr 06 2018
|
||||||
|
@ -199,6 +199,7 @@ function setupController (initState, initLangCode) {
|
|||||||
if (isMetaMaskInternalProcess) {
|
if (isMetaMaskInternalProcess) {
|
||||||
// communication with popup
|
// communication with popup
|
||||||
popupIsOpen = popupIsOpen || (remotePort.name === 'popup')
|
popupIsOpen = popupIsOpen || (remotePort.name === 'popup')
|
||||||
|
controller.isClientOpen = true
|
||||||
controller.setupTrustedCommunication(portStream, 'MetaMask')
|
controller.setupTrustedCommunication(portStream, 'MetaMask')
|
||||||
// record popup as closed
|
// record popup as closed
|
||||||
if (remotePort.sender.url.match(/home.html$/)) {
|
if (remotePort.sender.url.match(/home.html$/)) {
|
||||||
@ -210,6 +211,8 @@ function setupController (initState, initLangCode) {
|
|||||||
if (remotePort.sender.url.match(/home.html$/)) {
|
if (remotePort.sender.url.match(/home.html$/)) {
|
||||||
openMetamaskTabsIDs[remotePort.sender.tab.id] = false
|
openMetamaskTabsIDs[remotePort.sender.tab.id] = false
|
||||||
}
|
}
|
||||||
|
controller.isClientOpen = popupIsOpen ||
|
||||||
|
Object.keys(openMetamaskTabsIDs).some(key => openMetamaskTabsIDs[key])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (remotePort.name === 'notification') {
|
if (remotePort.name === 'notification') {
|
||||||
|
77
app/scripts/controllers/token-rates.js
Normal file
77
app/scripts/controllers/token-rates.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
const ObservableStore = require('obs-store')
|
||||||
|
|
||||||
|
// By default, poll every 3 minutes
|
||||||
|
const DEFAULT_INTERVAL = 180 * 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller that polls for token exchange
|
||||||
|
* rates based on a user's current token list
|
||||||
|
*/
|
||||||
|
class TokenRatesController {
|
||||||
|
/**
|
||||||
|
* Creates a TokenRatesController
|
||||||
|
*
|
||||||
|
* @param {Object} [config] - Options to configure controller
|
||||||
|
*/
|
||||||
|
constructor ({ interval = DEFAULT_INTERVAL, preferences } = {}) {
|
||||||
|
this.store = new ObservableStore()
|
||||||
|
this.preferences = preferences
|
||||||
|
this.interval = interval
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates exchange rates for all tokens
|
||||||
|
*/
|
||||||
|
async updateExchangeRates () {
|
||||||
|
if (!this.isActive) { return }
|
||||||
|
const contractExchangeRates = {}
|
||||||
|
for (const i in this._tokens) {
|
||||||
|
const address = this._tokens[i].address
|
||||||
|
contractExchangeRates[address] = await this.fetchExchangeRate(address)
|
||||||
|
}
|
||||||
|
this.store.putState({ contractExchangeRates })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a token exchange rate by address
|
||||||
|
*
|
||||||
|
* @param {String} address - Token contract address
|
||||||
|
*/
|
||||||
|
async fetchExchangeRate (address) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://exchanges.balanc3.net/prices?from=${address}&to=ETH&autoConversion=false&summaryOnly=true`)
|
||||||
|
const json = await response.json()
|
||||||
|
return json && json.length ? json[0].averagePrice : 0
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Number} - Interval used to poll for exchange rates
|
||||||
|
*/
|
||||||
|
set interval (interval) {
|
||||||
|
this._handle && clearInterval(this._handle)
|
||||||
|
if (!interval) { return }
|
||||||
|
this._handle = setInterval(() => { this.updateExchangeRates() }, interval)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object} - Preferences controller instance
|
||||||
|
*/
|
||||||
|
set preferences (preferences) {
|
||||||
|
this._preferences && this._preferences.unsubscribe()
|
||||||
|
if (!preferences) { return }
|
||||||
|
this._preferences = preferences
|
||||||
|
this.tokens = preferences.getState().tokens
|
||||||
|
preferences.subscribe(({ tokens = [] }) => { this.tokens = tokens })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Array} - Array of token objects with contract addresses
|
||||||
|
*/
|
||||||
|
set tokens (tokens) {
|
||||||
|
this._tokens = tokens
|
||||||
|
this.updateExchangeRates()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TokenRatesController
|
@ -34,6 +34,7 @@ const PersonalMessageManager = require('./lib/personal-message-manager')
|
|||||||
const TypedMessageManager = require('./lib/typed-message-manager')
|
const TypedMessageManager = require('./lib/typed-message-manager')
|
||||||
const TransactionController = require('./controllers/transactions')
|
const TransactionController = require('./controllers/transactions')
|
||||||
const BalancesController = require('./controllers/computed-balances')
|
const BalancesController = require('./controllers/computed-balances')
|
||||||
|
const TokenRatesController = require('./controllers/token-rates')
|
||||||
const ConfigManager = require('./lib/config-manager')
|
const ConfigManager = require('./lib/config-manager')
|
||||||
const nodeify = require('./lib/nodeify')
|
const nodeify = require('./lib/nodeify')
|
||||||
const accountImporter = require('./account-import-strategies')
|
const accountImporter = require('./account-import-strategies')
|
||||||
@ -105,6 +106,11 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
this.provider = this.initializeProvider()
|
this.provider = this.initializeProvider()
|
||||||
this.blockTracker = this.provider._blockTracker
|
this.blockTracker = this.provider._blockTracker
|
||||||
|
|
||||||
|
// token exchange rate tracker
|
||||||
|
this.tokenRatesController = new TokenRatesController({
|
||||||
|
preferences: this.preferencesController.store,
|
||||||
|
})
|
||||||
|
|
||||||
this.recentBlocksController = new RecentBlocksController({
|
this.recentBlocksController = new RecentBlocksController({
|
||||||
blockTracker: this.blockTracker,
|
blockTracker: this.blockTracker,
|
||||||
provider: this.provider,
|
provider: this.provider,
|
||||||
@ -202,6 +208,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
AccountTracker: this.accountTracker.store,
|
AccountTracker: this.accountTracker.store,
|
||||||
TxController: this.txController.memStore,
|
TxController: this.txController.memStore,
|
||||||
BalancesController: this.balancesController.store,
|
BalancesController: this.balancesController.store,
|
||||||
|
TokenRatesController: this.tokenRatesController.store,
|
||||||
MessageManager: this.messageManager.memStore,
|
MessageManager: this.messageManager.memStore,
|
||||||
PersonalMessageManager: this.personalMessageManager.memStore,
|
PersonalMessageManager: this.personalMessageManager.memStore,
|
||||||
TypesMessageManager: this.typedMessageManager.memStore,
|
TypesMessageManager: this.typedMessageManager.memStore,
|
||||||
@ -263,6 +270,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
|
|
||||||
// memStore -> transform -> publicConfigStore
|
// memStore -> transform -> publicConfigStore
|
||||||
this.on('update', (memState) => {
|
this.on('update', (memState) => {
|
||||||
|
this.isClientOpenAndUnlocked = memState.isUnlocked && this._isClientOpen
|
||||||
const publicState = selectPublicState(memState)
|
const publicState = selectPublicState(memState)
|
||||||
publicConfigStore.putState(publicState)
|
publicConfigStore.putState(publicState)
|
||||||
})
|
})
|
||||||
@ -1024,4 +1032,12 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set isClientOpen (open) {
|
||||||
|
this._isClientOpen = open
|
||||||
|
this.isClientOpenAndUnlocked = this.getState().isUnlocked && open
|
||||||
|
}
|
||||||
|
|
||||||
|
set isClientOpenAndUnlocked (active) {
|
||||||
|
this.tokenRatesController.isActive = active
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
29
test/unit/token-rates-controller.js
Normal file
29
test/unit/token-rates-controller.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const assert = require('assert')
|
||||||
|
const sinon = require('sinon')
|
||||||
|
const TokenRatesController = require('../../app/scripts/controllers/token-rates')
|
||||||
|
const ObservableStore = require('obs-store')
|
||||||
|
|
||||||
|
describe('TokenRatesController', () => {
|
||||||
|
it('should listen for preferences store updates', () => {
|
||||||
|
const preferences = new ObservableStore({ tokens: [] })
|
||||||
|
const controller = new TokenRatesController({ preferences })
|
||||||
|
preferences.putState({ tokens: ['foo'] })
|
||||||
|
assert.deepEqual(controller._tokens, ['foo'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should poll on correct interval', async () => {
|
||||||
|
const stub = sinon.stub(global, 'setInterval')
|
||||||
|
new TokenRatesController({ interval: 1337 }) // eslint-disable-line no-new
|
||||||
|
assert.strictEqual(stub.getCall(0).args[1], 1337)
|
||||||
|
stub.restore()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fetch each token rate based on address', async () => {
|
||||||
|
const controller = new TokenRatesController()
|
||||||
|
controller.isActive = true
|
||||||
|
controller.fetchExchangeRate = address => address
|
||||||
|
controller.tokens = [{ address: 'foo' }, { address: 'bar' }]
|
||||||
|
await controller.updateExchangeRates()
|
||||||
|
assert.deepEqual(controller.store.getState().contractExchangeRates, { foo: 'foo', bar: 'bar' })
|
||||||
|
})
|
||||||
|
})
|
@ -221,8 +221,6 @@ 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',
|
|
||||||
updateTokenExchangeRate,
|
|
||||||
PAIR_UPDATE: 'PAIR_UPDATE',
|
PAIR_UPDATE: 'PAIR_UPDATE',
|
||||||
pairUpdate: pairUpdate,
|
pairUpdate: pairUpdate,
|
||||||
coinShiftRquest: coinShiftRquest,
|
coinShiftRquest: coinShiftRquest,
|
||||||
@ -1752,28 +1750,6 @@ function shapeShiftRequest (query, options, cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTokenExchangeRate (token = '') {
|
|
||||||
const pair = `${token.toLowerCase()}_eth`
|
|
||||||
|
|
||||||
return dispatch => {
|
|
||||||
if (!token) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
shapeShiftRequest('marketinfo', { pair }, marketinfo => {
|
|
||||||
if (!marketinfo.error) {
|
|
||||||
dispatch({
|
|
||||||
type: actions.UPDATE_TOKEN_EXCHANGE_RATE,
|
|
||||||
payload: {
|
|
||||||
pair,
|
|
||||||
marketinfo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFeatureFlag (feature, activated, notificationType) {
|
function setFeatureFlag (feature, activated, notificationType) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(actions.showLoadingIndication())
|
dispatch(actions.showLoadingIndication())
|
||||||
|
@ -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,6 @@ 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)),
|
|
||||||
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,15 +177,6 @@ function reduceMetamask (state, action) {
|
|||||||
conversionDate: action.value.conversionDate,
|
conversionDate: action.value.conversionDate,
|
||||||
})
|
})
|
||||||
|
|
||||||
case actions.UPDATE_TOKEN_EXCHANGE_RATE:
|
|
||||||
const { payload: { pair, marketinfo } } = action
|
|
||||||
return extend(metamaskState, {
|
|
||||||
tokenExchangeRates: {
|
|
||||||
...metamaskState.tokenExchangeRates,
|
|
||||||
[pair]: marketinfo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
case actions.UPDATE_TOKENS:
|
case actions.UPDATE_TOKENS:
|
||||||
return extend(metamaskState, {
|
return extend(metamaskState, {
|
||||||
tokens: action.newTokens,
|
tokens: action.newTokens,
|
||||||
|
@ -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) {
|
||||||
|
@ -88,17 +88,6 @@ SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SendTransactionScreen.prototype.componentWillMount = function () {
|
SendTransactionScreen.prototype.componentWillMount = function () {
|
||||||
const {
|
|
||||||
updateTokenExchangeRate,
|
|
||||||
selectedToken = {},
|
|
||||||
} = this.props
|
|
||||||
|
|
||||||
const { symbol } = selectedToken || {}
|
|
||||||
|
|
||||||
if (symbol) {
|
|
||||||
updateTokenExchangeRate(symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateGas()
|
this.updateGas()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user