1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Add token exchange rates

This commit is contained in:
Chi Kei Chan 2017-09-13 01:25:39 -07:00
parent 8b5f2a95df
commit 8f31b05ac5
8 changed files with 100 additions and 14 deletions

View File

@ -163,6 +163,8 @@ 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,
@ -1078,6 +1080,28 @@ 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,
},
})
}
})
}
}
// Call Background Then Update // Call Background Then Update
// //
// A function generator for a common pattern wherein: // A function generator for a common pattern wherein:

View File

@ -305,11 +305,7 @@ PendingTx.prototype.render = function () {
// }, 'Reset'), // }, 'Reset'),
// Accept Button // Accept Button
h('input.confirm-screen-confirm-button', { h('button.confirm-screen-confirm-button', ['CONFIRM']),
type: 'submit',
value: 'CONFIRM',
// disabled: insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting,
}),
// Cancel Button // Cancel Button
h('button.cancel.btn-light.confirm-screen-cancel-button', {}, 'CANCEL'), h('button.cancel.btn-light.confirm-screen-cancel-button', {}, 'CANCEL'),

View File

@ -28,9 +28,12 @@ function mapStateToProps (state) {
// const network = state.metamask.network // const network = state.metamask.network
const selectedTokenAddress = state.metamask.selectedTokenAddress const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0] const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
const selectedToken = selectors.getSelectedToken(state)
const tokenExchangeRates = state.metamask.tokenExchangeRates
const pair = `${selectedToken.symbol.toLowerCase()}_eth`
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
// const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress) // const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress)
// const identity = identities[selectedAddress] // const identity = identities[selectedAddress]
return { return {
// sidebarOpen, // sidebarOpen,
selectedAddress, selectedAddress,
@ -39,8 +42,9 @@ function mapStateToProps (state) {
identities, identities,
addressBook, addressBook,
conversionRate, conversionRate,
tokenExchangeRate,
currentBlockGasLimit, currentBlockGasLimit,
selectedToken: selectors.getSelectedToken(state), selectedToken,
// selectedToken: selectors.getSelectedToken(state), // selectedToken: selectors.getSelectedToken(state),
// identity, // identity,
// network, // network,
@ -58,6 +62,7 @@ function mapDispatchToProps (dispatch) {
signTokenTx: (tokenAddress, toAddress, amount, txData) => ( signTokenTx: (tokenAddress, toAddress, amount, txData) => (
dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData)) dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
), ),
updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
// showSidebar: () => { dispatch(actions.showSidebar()) }, // showSidebar: () => { dispatch(actions.showSidebar()) },
// hideSidebar: () => { dispatch(actions.hideSidebar()) }, // hideSidebar: () => { dispatch(actions.hideSidebar()) },
// showModal: (payload) => { dispatch(actions.showModal(payload)) }, // showModal: (payload) => { dispatch(actions.showModal(payload)) },
@ -71,7 +76,7 @@ function SendTokenScreen () {
Component.call(this) Component.call(this)
this.state = { this.state = {
to: '', to: '',
amount: null, amount: '',
selectedCurrency: 'USD', selectedCurrency: 'USD',
isGasTooltipOpen: false, isGasTooltipOpen: false,
gasPrice: '0x5d21dba00', gasPrice: '0x5d21dba00',
@ -80,6 +85,15 @@ function SendTokenScreen () {
} }
} }
SendTokenScreen.prototype.componentWillMount = function () {
const {
updateTokenExchangeRate,
selectedToken: { symbol },
} = this.props
updateTokenExchangeRate(symbol)
}
SendTokenScreen.prototype.validate = function () { SendTokenScreen.prototype.validate = function () {
const { const {
to, to,
@ -206,6 +220,7 @@ SendTokenScreen.prototype.renderAmountInput = function () {
} = this.state } = this.state
const { const {
tokenExchangeRate,
selectedToken: {symbol}, selectedToken: {symbol},
} = this.props } = this.props
@ -217,8 +232,8 @@ SendTokenScreen.prototype.renderAmountInput = function () {
h('div.send-screen-amount-labels', [ h('div.send-screen-amount-labels', [
h('span', ['Amount']), h('span', ['Amount']),
h(CurrencyToggle, { h(CurrencyToggle, {
currentCurrency: selectedCurrency, currentCurrency: tokenExchangeRate ? selectedCurrency : 'USD',
currencies: [ symbol, 'USD' ], currencies: tokenExchangeRate ? [ symbol, 'USD' ] : [],
onClick: currency => this.setState({ selectedCurrency: currency }), onClick: currency => this.setState({ selectedCurrency: currency }),
}), }),
]), ]),
@ -249,6 +264,7 @@ SendTokenScreen.prototype.renderGasInput = function () {
const { const {
conversionRate, conversionRate,
tokenExchangeRate,
currentBlockGasLimit, currentBlockGasLimit,
} = this.props } = this.props
@ -274,6 +290,7 @@ SendTokenScreen.prototype.renderGasInput = function () {
h('div.large-input.send-screen-gas-input', [ h('div.large-input.send-screen-gas-input', [
h(GasFeeDisplay, { h(GasFeeDisplay, {
conversionRate, conversionRate,
tokenExchangeRate,
gasPrice, gasPrice,
currentCurrency: selectedCurrency, currentCurrency: selectedCurrency,
gas: gasLimit, gas: gasLimit,

View File

@ -12,11 +12,11 @@ function CurrencyToggle () {
const defaultCurrencies = [ 'ETH', 'USD' ] const defaultCurrencies = [ 'ETH', 'USD' ]
CurrencyToggle.prototype.render = function () { CurrencyToggle.prototype.renderToggles = function () {
const { onClick, currentCurrency } = this.props const { onClick, currentCurrency } = this.props
const [currencyA, currencyB] = this.props.currencies || defaultCurrencies const [currencyA, currencyB] = this.props.currencies || defaultCurrencies
return h('span.currency-toggle', {}, [ return [
h('span', { h('span', {
className: classnames('currency-toggle__item', { className: classnames('currency-toggle__item', {
'currency-toggle__item--selected': currencyA === currentCurrency, 'currency-toggle__item--selected': currencyA === currentCurrency,
@ -30,6 +30,15 @@ CurrencyToggle.prototype.render = function () {
}), }),
onClick: () => onClick(currencyB), onClick: () => onClick(currencyB),
}, [ currencyB ]), }, [ currencyB ]),
]) // holding on icon from design ]
}
CurrencyToggle.prototype.render = function () {
const currencies = this.props.currencies || defaultCurrencies
return h('span.currency-toggle', currencies.length
? this.renderToggles()
: []
)
} }

View File

@ -3,6 +3,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const USDFeeDisplay = require('./usd-fee-display') const USDFeeDisplay = require('./usd-fee-display')
const EthFeeDisplay = require('./eth-fee-display') const EthFeeDisplay = require('./eth-fee-display')
const { getTxFeeBn, formatBalance, shortenBalance } = require('../../util')
module.exports = GasFeeDisplay module.exports = GasFeeDisplay
@ -11,6 +12,20 @@ function GasFeeDisplay () {
Component.call(this) Component.call(this)
} }
GasFeeDisplay.prototype.getTokenValue = function () {
const {
tokenExchangeRate,
gas,
gasPrice,
blockGasLimit,
} = this.props
const value = formatBalance(getTxFeeBn(gas, gasPrice, blockGasLimit), 6, true)
const [ethNumber] = value.split(' ')
return shortenBalance(Number(ethNumber) / tokenExchangeRate, 6)
}
GasFeeDisplay.prototype.render = function () { GasFeeDisplay.prototype.render = function () {
const { const {
currentCurrency, currentCurrency,
@ -38,7 +53,10 @@ GasFeeDisplay.prototype.render = function () {
blockGasLimit, blockGasLimit,
}) })
default: default:
return h('noscript'); return h('div.token-gas', [
h('div.token-gas__amount', this.getTokenValue()),
h('div.token-gas__symbol', currentCurrency),
])
} }
} }

View File

@ -229,6 +229,17 @@
padding: 1px 4px; padding: 1px 4px;
} }
.token-gas {
&__amount {
display: inline-block;
margin-right: 4px;
}
&__symbol {
display: inline-block;
}
}
.send-token { .send-token {
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;

View File

@ -18,6 +18,7 @@ function reduceMetamask (state, action) {
frequentRpcList: [], frequentRpcList: [],
addressBook: [], addressBook: [],
selectedTokenAddress: null, selectedTokenAddress: null,
tokenExchangeRates: {},
}, state.metamask) }, state.metamask)
switch (action.type) { switch (action.type) {
@ -136,6 +137,15 @@ 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,
},
})
default: default:
return metamaskState return metamaskState

View File

@ -50,6 +50,7 @@ module.exports = {
formatDate, formatDate,
bnMultiplyByFraction, bnMultiplyByFraction,
getTxFeeBn, getTxFeeBn,
shortenBalance,
} }
function valuesFor (obj) { function valuesFor (obj) {