Show/Hide Fiat on Testnets based on User Preference (#6153)

feature/default_network_editable
Chi Kei Chan 6 years ago committed by Whymarrh Whitby
parent fc1655eecb
commit a2320c76fe
  1. 6
      app/_locales/en/messages.json
  2. 3
      development/states/confirm-new-ui.json
  3. 3
      development/states/currency-localization.json
  4. 3
      development/states/send-edit.json
  5. 3
      development/states/send-new-ui.json
  6. 38
      test/e2e/beta/metamask-beta-ui.spec.js
  7. 5
      ui/app/actions.js
  8. 5
      ui/app/components/balance/balance.container.js
  9. 22
      ui/app/components/currency-input/currency-input.component.js
  10. 4
      ui/app/components/currency-input/currency-input.container.js
  11. 40
      ui/app/components/currency-input/tests/currency-input.component.test.js
  12. 170
      ui/app/components/currency-input/tests/currency-input.container.test.js
  13. 7
      ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
  14. 63
      ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
  15. 5
      ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js
  16. 6
      ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js
  17. 32
      ui/app/components/pages/settings/settings-tab/settings-tab.component.js
  18. 7
      ui/app/components/pages/settings/settings-tab/settings-tab.container.js
  19. 20
      ui/app/components/send/account-list-item/account-list-item.component.js
  20. 6
      ui/app/components/send/account-list-item/account-list-item.container.js
  21. 14
      ui/app/components/send/account-list-item/tests/account-list-item-component.test.js
  22. 53
      ui/app/components/send/account-list-item/tests/account-list-item-container.test.js
  23. 42
      ui/app/components/token-input/tests/token-input.component.test.js
  24. 126
      ui/app/components/token-input/tests/token-input.container.test.js
  25. 11
      ui/app/components/token-input/token-input.component.js
  26. 5
      ui/app/components/token-input/token-input.container.js
  27. 18
      ui/app/components/transaction-breakdown/transaction-breakdown.component.js
  28. 6
      ui/app/components/transaction-breakdown/transaction-breakdown.container.js
  29. 9
      ui/app/components/transaction-list-item/transaction-list-item.component.js
  30. 5
      ui/app/components/transaction-list-item/transaction-list-item.container.js
  31. 31
      ui/app/components/transaction-view-balance/transaction-view-balance.component.js
  32. 5
      ui/app/components/transaction-view-balance/transaction-view-balance.container.js
  33. 87
      ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js
  34. 19
      ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js
  35. 4
      ui/app/constants/common.js
  36. 6
      ui/app/reducers/metamask.js
  37. 8
      ui/app/selectors.js
  38. 40
      ui/app/selectors/custom-gas.js
  39. 345
      ui/app/selectors/tests/custom-gas.test.js

@ -1237,6 +1237,12 @@
"showAdvancedGasInlineDescription": { "showAdvancedGasInlineDescription": {
"message": "Select this to show gas price and limit controls directly on the send and confirm screens." "message": "Select this to show gas price and limit controls directly on the send and confirm screens."
}, },
"showFiatConversionInTestnets": {
"message": "Show Conversion in Testnets"
},
"showFiatConversionInTestnetsDescription": {
"message": "Select this to show fiat conversion in when you are on Testnets"
},
"showPrivateKeys": { "showPrivateKeys": {
"message": "Show Private Keys" "message": "Show Private Keys"
}, },

@ -131,7 +131,8 @@
}, },
"currentLocale": "en", "currentLocale": "en",
"preferences": { "preferences": {
"useNativeCurrencyAsPrimaryCurrency": true "useNativeCurrencyAsPrimaryCurrency": true,
"showFiatInTestnets": true
} }
}, },
"appState": { "appState": {

@ -113,7 +113,8 @@
}, },
"currentLocale": "en", "currentLocale": "en",
"preferences": { "preferences": {
"useNativeCurrencyAsPrimaryCurrency": true "useNativeCurrencyAsPrimaryCurrency": true,
"showFiatInTestnets": true
} }
}, },
"appState": { "appState": {

@ -135,7 +135,8 @@
}, },
"currentLocale": "en", "currentLocale": "en",
"preferences": { "preferences": {
"useNativeCurrencyAsPrimaryCurrency": true "useNativeCurrencyAsPrimaryCurrency": true,
"showFiatInTestnets": true
} }
}, },
"appState": { "appState": {

@ -114,7 +114,8 @@
}, },
"currentLocale": "en", "currentLocale": "en",
"preferences": { "preferences": {
"useNativeCurrencyAsPrimaryCurrency": true "useNativeCurrencyAsPrimaryCurrency": true,
"showFiatInTestnets": true
} }
}, },
"appState": { "appState": {

@ -495,10 +495,13 @@ describe('MetaMask', function () {
await findElement(driver, By.css('.tab-bar')) await findElement(driver, By.css('.tab-bar'))
const showConversionToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(3) .settings-page__content-item-col > div'))
await showConversionToggle.click()
const advancedGasTitle = await findElement(driver, By.xpath(`//span[contains(text(), 'Advanced gas controls')]`)) const advancedGasTitle = await findElement(driver, By.xpath(`//span[contains(text(), 'Advanced gas controls')]`))
await driver.executeScript('arguments[0].scrollIntoView(true)', advancedGasTitle) await driver.executeScript('arguments[0].scrollIntoView(true)', advancedGasTitle)
const advancedGasToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(11) .settings-page__content-item-col > div')) const advancedGasToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(12) .settings-page__content-item-col > div'))
await advancedGasToggle.click() await advancedGasToggle.click()
windowHandles = await driver.getAllWindowHandles() windowHandles = await driver.getAllWindowHandles()
extension = windowHandles[0] extension = windowHandles[0]
@ -560,23 +563,37 @@ describe('MetaMask', function () {
await delay(regularDelayMs) await delay(regularDelayMs)
}) })
let txValues
it('finds the transaction in the transactions list', async function () { it('finds the transaction in the transactions list', async function () {
const transactions = await findElements(driver, By.css('.transaction-list-item')) const transactions = await findElements(driver, By.css('.transaction-list-item'))
assert.equal(transactions.length, 4) assert.equal(transactions.length, 4)
const txValues = await findElement(driver, By.css('.transaction-list-item__amount--primary')) txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
await driver.wait(until.elementTextMatches(txValues, /-3\s*ETH/), 10000) await driver.wait(until.elementTextMatches(txValues[0], /-3\s*ETH/), 10000)
}) })
it('the transaction has the expected gas price', async function () { it('the transaction has the expected gas price', async function () {
const txValues = await findElement(driver, By.css('.transaction-list-item__amount--primary')) await delay(largeDelayMs)
await txValues.click() let txGasPriceLabels
await delay(tinyDelayMs) let txGasPrices
await findElement(driver, By.xpath(`//div[contains(text(), 'Gas Price (GWEI)')]`)) try {
await txValues[0].click()
await findElement(driver, By.xpath(`//span[contains(text(), '7')]`)) txGasPrices = await findElements(driver, By.css('.transaction-breakdown__value'))
txGasPriceLabels = await findElements(driver, By.css('.transaction-breakdown-row__title'))
txGasPrices = await findElements(driver, By.css('.transaction-breakdown__value'))
await driver.wait(until.elementTextMatches(txGasPrices[3], /^10$/), 10000)
} catch (e) {
console.log(e.message)
txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
await txValues[0].click()
txGasPriceLabels = await findElements(driver, By.css('.transaction-breakdown-row__title'))
txGasPrices = await findElements(driver, By.css('.transaction-breakdown__value'))
await driver.wait(until.elementTextMatches(txGasPrices[3], /^10$/), 10000)
}
assert(txGasPriceLabels[2])
txValues.click() await txValues[0].click()
}) })
}) })
@ -1125,6 +1142,7 @@ describe('MetaMask', function () {
return confirmedTxes.length === 2 return confirmedTxes.length === 2
}, 10000) }, 10000)
await delay(regularDelayMs)
const txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary')) const txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
await driver.wait(until.elementTextMatches(txValues[0], /-7\s*TST/)) await driver.wait(until.elementTextMatches(txValues[0], /-7\s*TST/))
const txStatuses = await findElements(driver, By.css('.transaction-list-item__action')) const txStatuses = await findElements(driver, By.css('.transaction-list-item__action'))

@ -317,6 +317,7 @@ var actions = {
updatePreferences, updatePreferences,
UPDATE_PREFERENCES: 'UPDATE_PREFERENCES', UPDATE_PREFERENCES: 'UPDATE_PREFERENCES',
setUseNativeCurrencyAsPrimaryCurrencyPreference, setUseNativeCurrencyAsPrimaryCurrencyPreference,
setShowFiatConversionOnTestnetsPreference,
// Migration of users to new UI // Migration of users to new UI
setCompletedUiMigration, setCompletedUiMigration,
@ -2470,6 +2471,10 @@ function setUseNativeCurrencyAsPrimaryCurrencyPreference (value) {
return setPreference('useNativeCurrencyAsPrimaryCurrency', value) return setPreference('useNativeCurrencyAsPrimaryCurrency', value)
} }
function setShowFiatConversionOnTestnetsPreference (value) {
return setPreference('showFiatInTestnets', value)
}
function setCompletedOnboarding () { function setCompletedOnboarding () {
return dispatch => { return dispatch => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())

@ -6,9 +6,13 @@ import {
conversionRateSelector, conversionRateSelector,
getCurrentCurrency, getCurrentCurrency,
getMetaMaskAccounts, getMetaMaskAccounts,
getIsMainnet,
preferencesSelector,
} from '../../selectors' } from '../../selectors'
const mapStateToProps = state => { const mapStateToProps = state => {
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const accounts = getMetaMaskAccounts(state) const accounts = getMetaMaskAccounts(state)
const network = state.metamask.network const network = state.metamask.network
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0] const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
@ -21,6 +25,7 @@ const mapStateToProps = state => {
conversionRate: conversionRateSelector(state), conversionRate: conversionRateSelector(state),
currentCurrency: getCurrentCurrency(state), currentCurrency: getCurrentCurrency(state),
assetImages: getAssetImages(state), assetImages: getAssetImages(state),
showFiat: (isMainnet || !!showFiatInTestnets),
} }
} }

@ -11,6 +11,10 @@ import { ETH } from '../../constants/common'
* gets converted into a decimal value depending on the currency (ETH or Fiat). * gets converted into a decimal value depending on the currency (ETH or Fiat).
*/ */
export default class CurrencyInput extends PureComponent { export default class CurrencyInput extends PureComponent {
static contextTypes = {
t: PropTypes.func,
}
static propTypes = { static propTypes = {
conversionRate: PropTypes.number, conversionRate: PropTypes.number,
currentCurrency: PropTypes.string, currentCurrency: PropTypes.string,
@ -18,6 +22,7 @@ export default class CurrencyInput extends PureComponent {
onChange: PropTypes.func, onChange: PropTypes.func,
onBlur: PropTypes.func, onBlur: PropTypes.func,
useFiat: PropTypes.bool, useFiat: PropTypes.bool,
hideFiat: PropTypes.bool,
value: PropTypes.string, value: PropTypes.string,
fiatSuffix: PropTypes.string, fiatSuffix: PropTypes.string,
nativeSuffix: PropTypes.string, nativeSuffix: PropTypes.string,
@ -61,8 +66,13 @@ export default class CurrencyInput extends PureComponent {
} }
shouldUseFiat = () => { shouldUseFiat = () => {
const { useFiat } = this.props const { useFiat, hideFiat } = this.props
const { isSwapped } = this.state || {} const { isSwapped } = this.state || {}
if (hideFiat) {
return false
}
return isSwapped ? !useFiat : useFiat return isSwapped ? !useFiat : useFiat
} }
@ -93,10 +103,18 @@ export default class CurrencyInput extends PureComponent {
} }
renderConversionComponent () { renderConversionComponent () {
const { currentCurrency, nativeCurrency } = this.props const { currentCurrency, nativeCurrency, hideFiat } = this.props
const { hexValue } = this.state const { hexValue } = this.state
let currency, numberOfDecimals let currency, numberOfDecimals
if (hideFiat) {
return (
<div className="currency-input__conversion-component">
{ this.context.t('noConversionRateAvailable') }
</div>
)
}
if (this.shouldUseFiat()) { if (this.shouldUseFiat()) {
// Display ETH // Display ETH
currency = nativeCurrency || ETH currency = nativeCurrency || ETH

@ -1,14 +1,18 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import CurrencyInput from './currency-input.component' import CurrencyInput from './currency-input.component'
import { ETH } from '../../constants/common' import { ETH } from '../../constants/common'
import {getIsMainnet, preferencesSelector} from '../../selectors'
const mapStateToProps = state => { const mapStateToProps = state => {
const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
nativeCurrency, nativeCurrency,
currentCurrency, currentCurrency,
conversionRate, conversionRate,
hideFiat: (!isMainnet && !showFiatInTestnets),
} }
} }

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import assert from 'assert' import assert from 'assert'
import { shallow, mount } from 'enzyme' import { shallow, mount } from 'enzyme'
import sinon from 'sinon' import sinon from 'sinon'
@ -111,6 +112,45 @@ describe('CurrencyInput Component', () => {
assert.equal(wrapper.find('.unit-input__input').props().value, '1') assert.equal(wrapper.find('.unit-input__input').props().value, '1')
assert.equal(wrapper.find('.currency-display-component').text(), '0.004328ETH') assert.equal(wrapper.find('.currency-display-component').text(), '0.004328ETH')
}) })
it('should render properly with a native value when hideFiat is true', () => {
const mockStore = {
metamask: {
nativeCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 231.06,
},
}
const store = configureMockStore()(mockStore)
const wrapper = mount(
<Provider store={store}>
<CurrencyInput
value="f602f2234d0ea"
fiatSuffix="USD"
nativeSuffix="ETH"
useFiat
hideFiat={true}
nativeCurrency="ETH"
currentCurrency="usd"
conversionRate={231.06}
/>
</Provider>,
{
context: { t: str => str + '_t' },
childContextTypes: { t: PropTypes.func },
}
)
assert.ok(wrapper)
const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance()
assert.equal(currencyInputInstance.state.decimalValue, 0.004328)
assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea')
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH')
assert.equal(wrapper.find('.unit-input__input').props().value, '0.004328')
assert.equal(wrapper.find('.currency-input__conversion-component').text(), 'noConversionRateAvailable_t')
})
}) })
describe('handling actions', () => { describe('handling actions', () => {

@ -15,47 +15,155 @@ proxyquire('../currency-input.container.js', {
describe('CurrencyInput container', () => { describe('CurrencyInput container', () => {
describe('mapStateToProps()', () => { describe('mapStateToProps()', () => {
it('should return the correct props', () => { const tests = [
const mockState = { // Test # 1
metamask: { {
comment: 'should return correct props in mainnet',
mockState: {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
},
},
expected: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
hideFiat: false,
},
},
// Test # 2
{
comment: 'should return correct props when not in mainnet and showFiatInTestnets is false',
mockState: {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'rinkeby',
},
},
},
expected: {
conversionRate: 280.45, conversionRate: 280.45,
currentCurrency: 'usd', currentCurrency: 'usd',
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
hideFiat: true,
}, },
} },
// Test # 3
{
comment: 'should return correct props when not in mainnet and showFiatInTestnets is true',
mockState: {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'rinkeby',
},
},
},
expected: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
hideFiat: false,
},
},
// Test # 4
{
comment: 'should return correct props when in mainnet and showFiatInTestnets is true',
mockState: {
metamask: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'mainnet',
},
},
},
expected: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
hideFiat: false,
},
},
]
assert.deepEqual(mapStateToProps(mockState), { tests.forEach(({ mockState, expected, comment }) => {
conversionRate: 280.45, it(comment, () => assert.deepEqual(mapStateToProps(mockState), expected))
currentCurrency: 'usd',
nativeCurrency: 'ETH',
})
}) })
}) })
describe('mergeProps()', () => { describe('mergeProps()', () => {
it('should return the correct props', () => { const tests = [
const mockStateProps = { // Test # 1
conversionRate: 280.45, {
currentCurrency: 'usd', comment: 'should return the correct props',
nativeCurrency: 'ETH', mock: {
} stateProps: {
const mockDispatchProps = {} conversionRate: 280.45,
currentCurrency: 'usd',
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, { useFiat: true }), { nativeCurrency: 'ETH',
conversionRate: 280.45, },
currentCurrency: 'usd', dispatchProps: {},
nativeCurrency: 'ETH', ownProps: {},
useFiat: true, },
nativeSuffix: 'ETH', expected: {
fiatSuffix: 'USD', conversionRate: 280.45,
}) currentCurrency: 'usd',
nativeCurrency: 'ETH',
// useFiat: true,
nativeSuffix: 'ETH',
fiatSuffix: 'USD',
},
},
// Test # 1
{
comment: 'should return the correct props when useFiat is true',
mock: {
stateProps: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
},
dispatchProps: {},
ownProps: { useFiat: true },
},
expected: {
conversionRate: 280.45,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
useFiat: true,
nativeSuffix: 'ETH',
fiatSuffix: 'USD',
},
},
]
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, {}), { tests.forEach(({ mock: { stateProps, dispatchProps, ownProps }, expected, comment }) => {
conversionRate: 280.45, it(comment, () => {
currentCurrency: 'usd', assert.deepEqual(mergeProps(stateProps, dispatchProps, ownProps), expected)
nativeCurrency: 'ETH',
nativeSuffix: 'ETH',
fiatSuffix: 'USD',
}) })
}) })
}) })

@ -63,6 +63,7 @@ import {
} from '../../send/send.utils' } from '../../send/send.utils'
import { addHexPrefix } from 'ethereumjs-util' import { addHexPrefix } from 'ethereumjs-util'
import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price-chart.utils' import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price-chart.utils'
import {getIsMainnet, preferencesSelector} from '../../../selectors'
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const { transaction = {} } = ownProps const { transaction = {} } = ownProps
@ -91,6 +92,10 @@ const mapStateToProps = (state, ownProps) => {
const estimatedTimes = getEstimatedGasTimes(state) const estimatedTimes = getEstimatedGasTimes(state)
const balance = getCurrentEthBalance(state) const balance = getCurrentEthBalance(state)
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const showFiat = Boolean(isMainnet || showFiatInTestnets)
const insufficientBalance = !isBalanceSufficient({ const insufficientBalance = !isBalanceSufficient({
amount: value, amount: value,
gasTotal, gasTotal,
@ -124,7 +129,7 @@ const mapStateToProps = (state, ownProps) => {
infoRowProps: { infoRowProps: {
originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate),
originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal),
newTotalFiat, newTotalFiat: showFiat ? newTotalFiat : '',
newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal),
transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal),
sendAmount: addHexWEIsToRenderableEth(value, '0x0'), sendAmount: addHexWEIsToRenderableEth(value, '0x0'),

@ -71,6 +71,12 @@ describe('gas-modal-page-container container', () => {
}, },
currentCurrency: 'abc', currentCurrency: 'abc',
conversionRate: 50, conversionRate: 50,
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
gas: { gas: {
basicEstimates: { basicEstimates: {
@ -152,6 +158,63 @@ describe('gas-modal-page-container container', () => {
}), }),
expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true }), expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true }),
}, },
{
mockState: Object.assign({}, baseMockState, {
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: false,
},
provider: {
...baseMockState.metamask.provider,
type: 'rinkeby',
},
},
}),
mockOwnProps: baseMockOwnProps,
expectedResult: {
...baseExpectedResult,
infoRowProps: {
...baseExpectedResult.infoRowProps,
newTotalFiat: '',
},
},
},
{
mockState: Object.assign({}, baseMockState, {
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: true,
},
provider: {
...baseMockState.metamask.provider,
type: 'rinkeby',
},
},
}),
mockOwnProps: baseMockOwnProps,
expectedResult: baseExpectedResult,
},
{
mockState: Object.assign({}, baseMockState, {
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: true,
},
provider: {
...baseMockState.metamask.provider,
type: 'mainnet',
},
},
}),
mockOwnProps: baseMockOwnProps,
expectedResult: baseExpectedResult,
},
] ]
let result let result

@ -86,6 +86,7 @@ export default class ConfirmTransactionBase extends Component {
warning: PropTypes.string, warning: PropTypes.string,
advancedInlineGasShown: PropTypes.bool, advancedInlineGasShown: PropTypes.bool,
insufficientBalance: PropTypes.bool, insufficientBalance: PropTypes.bool,
hideFiatConversion: PropTypes.bool,
} }
state = { state = {
@ -174,6 +175,7 @@ export default class ConfirmTransactionBase extends Component {
customGas, customGas,
insufficientBalance, insufficientBalance,
updateGasAndCalculate, updateGasAndCalculate,
hideFiatConversion,
} = this.props } = this.props
if (hideDetails) { if (hideDetails) {
@ -190,6 +192,7 @@ export default class ConfirmTransactionBase extends Component {
headerText="Edit" headerText="Edit"
headerTextClassName="confirm-detail-row__header-text--edit" headerTextClassName="confirm-detail-row__header-text--edit"
onHeaderClick={() => this.handleEditGas()} onHeaderClick={() => this.handleEditGas()}
secondaryText={hideFiatConversion ? this.context.t('noConversionRateAvailable') : ''}
/> />
{advancedInlineGasShown {advancedInlineGasShown
? <AdvancedGasInputs ? <AdvancedGasInputs
@ -209,7 +212,7 @@ export default class ConfirmTransactionBase extends Component {
label="Total" label="Total"
value={hexTransactionTotal} value={hexTransactionTotal}
primaryText={primaryTotalTextOverride} primaryText={primaryTotalTextOverride}
secondaryText={secondaryTotalTextOverride} secondaryText={hideFiatConversion ? this.context.t('noConversionRateAvailable') : secondaryTotalTextOverride}
headerText="Amount + Gas Fee" headerText="Amount + Gas Fee"
headerTextClassName="confirm-detail-row__header-text--total" headerTextClassName="confirm-detail-row__header-text--total"
primaryValueTextColor="#2f9ae0" primaryValueTextColor="#2f9ae0"

@ -18,7 +18,7 @@ import { isBalanceSufficient, calcGasTotal } from '../../send/send.utils'
import { conversionGreaterThan } from '../../../conversion-util' import { conversionGreaterThan } from '../../../conversion-util'
import { MIN_GAS_LIMIT_DEC } from '../../send/send.constants' import { MIN_GAS_LIMIT_DEC } from '../../send/send.constants'
import { checksumAddress, addressSlicer, valuesFor } from '../../../util' import { checksumAddress, addressSlicer, valuesFor } from '../../../util'
import { getMetaMaskAccounts, getAdvancedInlineGasShown } from '../../../selectors' import {getMetaMaskAccounts, getAdvancedInlineGasShown, preferencesSelector, getIsMainnet} from '../../../selectors'
const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
return { return {
@ -29,6 +29,8 @@ const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const { toAddress: propsToAddress } = props const { toAddress: propsToAddress } = props
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const { confirmTransaction, metamask, gas } = state const { confirmTransaction, metamask, gas } = state
const { const {
ethTransactionAmount, ethTransactionAmount,
@ -135,6 +137,8 @@ const mapStateToProps = (state, props) => {
}, },
advancedInlineGasShown: getAdvancedInlineGasShown(state), advancedInlineGasShown: getAdvancedInlineGasShown(state),
insufficientBalance, insufficientBalance,
hideSubtitle: (!isMainnet && !showFiatInTestnets),
hideFiatConversion: (!isMainnet && !showFiatInTestnets),
} }
} }

@ -63,6 +63,8 @@ export default class SettingsTab extends PureComponent {
setAdvancedInlineGasFeatureFlag: PropTypes.func, setAdvancedInlineGasFeatureFlag: PropTypes.func,
advancedInlineGas: PropTypes.bool, advancedInlineGas: PropTypes.bool,
mobileSync: PropTypes.bool, mobileSync: PropTypes.bool,
showFiatInTestnets: PropTypes.bool,
setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired,
} }
state = { state = {
@ -529,6 +531,35 @@ export default class SettingsTab extends PureComponent {
) )
} }
renderShowConversionInTestnets () {
const { t } = this.context
const {
showFiatInTestnets,
setShowFiatConversionOnTestnetsPreference,
} = this.props
return (
<div className="settings-page__content-row">
<div className="settings-page__content-item">
<span>{ t('showFiatConversionInTestnets') }</span>
<div className="settings-page__content-description">
{ t('showFiatConversionInTestnetsDescription') }
</div>
</div>
<div className="settings-page__content-item">
<div className="settings-page__content-item-col">
<ToggleButton
value={showFiatInTestnets}
onToggle={value => setShowFiatConversionOnTestnetsPreference(!value)}
activeLabel=""
inactiveLabel=""
/>
</div>
</div>
</div>
)
}
renderPrivacyOptIn () { renderPrivacyOptIn () {
const { t } = this.context const { t } = this.context
const { privacyMode, setPrivacyMode } = this.props const { privacyMode, setPrivacyMode } = this.props
@ -563,6 +594,7 @@ export default class SettingsTab extends PureComponent {
{ warning && <div className="settings-tab__error">{ warning }</div> } { warning && <div className="settings-tab__error">{ warning }</div> }
{ this.renderCurrentConversion() } { this.renderCurrentConversion() }
{ this.renderUsePrimaryCurrencyOptions() } { this.renderUsePrimaryCurrencyOptions() }
{ this.renderShowConversionInTestnets() }
{ this.renderCurrentLocale() } { this.renderCurrentLocale() }
{ this.renderNewRpcUrl() } { this.renderNewRpcUrl() }
{ this.renderStateLogs() } { this.renderStateLogs() }

@ -12,6 +12,7 @@ import {
setFeatureFlag, setFeatureFlag,
showModal, showModal,
setUseNativeCurrencyAsPrimaryCurrencyPreference, setUseNativeCurrencyAsPrimaryCurrencyPreference,
setShowFiatConversionOnTestnetsPreference,
} from '../../../../actions' } from '../../../../actions'
import { preferencesSelector } from '../../../../selectors' import { preferencesSelector } from '../../../../selectors'
@ -31,7 +32,7 @@ const mapStateToProps = state => {
provider = {}, provider = {},
currentLocale, currentLocale,
} = metamask } = metamask
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) const { useNativeCurrencyAsPrimaryCurrency, showFiatInTestnets } = preferencesSelector(state)
return { return {
warning, warning,
@ -46,6 +47,7 @@ const mapStateToProps = state => {
provider, provider,
useNativeCurrencyAsPrimaryCurrency, useNativeCurrencyAsPrimaryCurrency,
mobileSync, mobileSync,
showFiatInTestnets,
} }
} }
@ -64,6 +66,9 @@ const mapDispatchToProps = dispatch => {
setUseNativeCurrencyAsPrimaryCurrencyPreference: value => { setUseNativeCurrencyAsPrimaryCurrencyPreference: value => {
return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value)) return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value))
}, },
setShowFiatConversionOnTestnetsPreference: value => {
return dispatch(setShowFiatConversionOnTestnetsPreference(value))
},
showClearApprovalModal: () => dispatch(showModal({ name: 'CLEAR_APPROVED_ORIGINS' })), showClearApprovalModal: () => dispatch(showModal({ name: 'CLEAR_APPROVED_ORIGINS' })),
} }
} }

@ -19,8 +19,13 @@ export default class AccountListItem extends Component {
handleClick: PropTypes.func, handleClick: PropTypes.func,
icon: PropTypes.node, icon: PropTypes.node,
balanceIsCached: PropTypes.bool, balanceIsCached: PropTypes.bool,
showFiat: PropTypes.bool,
}; };
static defaultProps = {
showFiat: true,
}
static contextTypes = { static contextTypes = {
t: PropTypes.func, t: PropTypes.func,
}; };
@ -34,6 +39,7 @@ export default class AccountListItem extends Component {
handleClick, handleClick,
icon = null, icon = null,
balanceIsCached, balanceIsCached,
showFiat,
} = this.props } = this.props
const { name, address, balance } = account || {} const { name, address, balance } = account || {}
@ -83,11 +89,15 @@ export default class AccountListItem extends Component {
balanceIsCached ? <span className="account-list-item__cached-star">*</span> : null balanceIsCached ? <span className="account-list-item__cached-star">*</span> : null
} }
</div> </div>
<UserPreferencedCurrencyDisplay {
type={SECONDARY} showFiat && (
value={balance} <UserPreferencedCurrencyDisplay
hideTitle={true} type={SECONDARY}
/> value={balance}
hideTitle={true}
/>
)
}
</div> </div>
</Tooltip> </Tooltip>
) )

@ -5,17 +5,23 @@ import {
getNativeCurrency, getNativeCurrency,
} from '../send.selectors.js' } from '../send.selectors.js'
import { import {
getIsMainnet,
isBalanceCached, isBalanceCached,
preferencesSelector,
} from '../../../selectors' } from '../../../selectors'
import AccountListItem from './account-list-item.component' import AccountListItem from './account-list-item.component'
export default connect(mapStateToProps)(AccountListItem) export default connect(mapStateToProps)(AccountListItem)
function mapStateToProps (state) { function mapStateToProps (state) {
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
conversionRate: getConversionRate(state), conversionRate: getConversionRate(state),
currentCurrency: getCurrentCurrency(state), currentCurrency: getCurrentCurrency(state),
nativeCurrency: getNativeCurrency(state), nativeCurrency: getNativeCurrency(state),
balanceIsCached: isBalanceCached(state), balanceIsCached: isBalanceCached(state),
showFiat: (isMainnet || !!showFiatInTestnets),
} }
} }

@ -126,9 +126,23 @@ describe('AccountListItem Component', function () {
) )
}) })
it('should only render one CurrencyDisplay if showFiat is false', () => {
wrapper.setProps({ showFiat: false, displayBalance: true })
assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 1)
assert.deepEqual(
wrapper.find(UserPreferencedCurrencyDisplay).at(0).props(),
{
type: 'PRIMARY',
value: 'mockBalance',
hideTitle: true,
}
)
})
it('should not render a CurrencyDisplay if displayBalance is false', () => { it('should not render a CurrencyDisplay if displayBalance is false', () => {
wrapper.setProps({ displayBalance: false }) wrapper.setProps({ displayBalance: false })
assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 0) assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 0)
}) })
}) })
}) })

@ -11,12 +11,16 @@ proxyquire('../account-list-item.container.js', {
}, },
}, },
'../send.selectors.js': { '../send.selectors.js': {
getConversionRate: (s) => `mockConversionRate:${s}`, getConversionRate: () => `mockConversionRate`,
getCurrentCurrency: (s) => `mockCurrentCurrency:${s}`, getCurrentCurrency: () => `mockCurrentCurrency`,
getNativeCurrency: (s) => `mockNativeCurrency:${s}`, getNativeCurrency: () => `mockNativeCurrency`,
}, },
'../../../selectors.js': { '../../../selectors.js': {
isBalanceCached: (s) => `mockBalanceIsCached:${s}`, isBalanceCached: () => `mockBalanceIsCached`,
preferencesSelector: ({ showFiatInTestnets }) => ({
showFiatInTestnets,
}),
getIsMainnet: ({ isMainnet }) => isMainnet,
}, },
}) })
@ -25,11 +29,42 @@ describe('account-list-item container', () => {
describe('mapStateToProps()', () => { describe('mapStateToProps()', () => {
it('should map the correct properties to props', () => { it('should map the correct properties to props', () => {
assert.deepEqual(mapStateToProps('mockState'), { assert.deepEqual(mapStateToProps({ isMainnet: true, showFiatInTestnets: false }), {
conversionRate: 'mockConversionRate:mockState', conversionRate: 'mockConversionRate',
currentCurrency: 'mockCurrentCurrency:mockState', currentCurrency: 'mockCurrentCurrency',
nativeCurrency: 'mockNativeCurrency:mockState', nativeCurrency: 'mockNativeCurrency',
balanceIsCached: 'mockBalanceIsCached:mockState', balanceIsCached: 'mockBalanceIsCached',
showFiat: true,
})
})
it('should map the correct properties to props when in mainnet and showFiatInTestnet is true', () => {
assert.deepEqual(mapStateToProps({ isMainnet: true, showFiatInTestnets: true }), {
conversionRate: 'mockConversionRate',
currentCurrency: 'mockCurrentCurrency',
nativeCurrency: 'mockNativeCurrency',
balanceIsCached: 'mockBalanceIsCached',
showFiat: true,
})
})
it('should map the correct properties to props when not in mainnet and showFiatInTestnet is true', () => {
assert.deepEqual(mapStateToProps({ isMainnet: false, showFiatInTestnets: true }), {
conversionRate: 'mockConversionRate',
currentCurrency: 'mockCurrentCurrency',
nativeCurrency: 'mockNativeCurrency',
balanceIsCached: 'mockBalanceIsCached',
showFiat: true,
})
})
it('should map the correct properties to props when not in mainnet and showFiatInTestnet is false', () => {
assert.deepEqual(mapStateToProps({ isMainnet: false, showFiatInTestnets: false }), {
conversionRate: 'mockConversionRate',
currentCurrency: 'mockCurrentCurrency',
nativeCurrency: 'mockNativeCurrency',
balanceIsCached: 'mockBalanceIsCached',
showFiat: false,
}) })
}) })

@ -159,6 +159,48 @@ describe('TokenInput Component', () => {
assert.equal(wrapper.find('.unit-input__input').props().value, '1') assert.equal(wrapper.find('.unit-input__input').props().value, '1')
assert.equal(wrapper.find('.currency-display-component').text(), '$462.12USD') assert.equal(wrapper.find('.currency-display-component').text(), '$462.12USD')
}) })
it('should render properly with a token value for fiat, but hideConversion is true', () => {
const mockStore = {
metamask: {
currentCurrency: 'usd',
conversionRate: 231.06,
},
}
const store = configureMockStore()(mockStore)
const wrapper = mount(
<Provider store={store}>
<TokenInput
value="2710"
selectedToken={{
address: '0x1',
decimals: '4',
symbol: 'ABC',
}}
suffix="ABC"
selectedTokenExchangeRate={2}
showFiat
hideConversion
/>
</Provider>,
{
context: { t },
childContextTypes: {
t: PropTypes.func,
},
},
)
assert.ok(wrapper)
const tokenInputInstance = wrapper.find(TokenInput).at(0).instance()
assert.equal(tokenInputInstance.state.decimalValue, 1)
assert.equal(tokenInputInstance.state.hexValue, '2710')
assert.equal(wrapper.find('.unit-input__suffix').length, 1)
assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC')
assert.equal(wrapper.find('.unit-input__input').props().value, '1')
assert.equal(wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable')
})
}) })
describe('handling actions', () => { describe('handling actions', () => {

@ -29,6 +29,12 @@ describe('TokenInput container', () => {
selectedTokenAddress: '0x1', selectedTokenAddress: '0x1',
contractExchangeRates: {}, contractExchangeRates: {},
send: {}, send: {},
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
} }
@ -40,6 +46,7 @@ describe('TokenInput container', () => {
symbol: 'ABC', symbol: 'ABC',
}, },
selectedTokenExchangeRate: 0, selectedTokenExchangeRate: 0,
hideConversion: false,
}) })
}) })
@ -59,6 +66,12 @@ describe('TokenInput container', () => {
send: { send: {
token: { address: 'test' }, token: { address: 'test' },
}, },
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
} }
@ -68,6 +81,7 @@ describe('TokenInput container', () => {
address: 'test', address: 'test',
}, },
selectedTokenExchangeRate: 0, selectedTokenExchangeRate: 0,
hideConversion: false,
}) })
}) })
@ -87,6 +101,12 @@ describe('TokenInput container', () => {
'0x1': 5, '0x1': 5,
}, },
send: {}, send: {},
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
} }
@ -98,6 +118,112 @@ describe('TokenInput container', () => {
symbol: 'ABC', symbol: 'ABC',
}, },
selectedTokenExchangeRate: 5, selectedTokenExchangeRate: 5,
hideConversion: false,
})
})
it('should return the correct props when not in mainnet and showFiatInTestnets is false', () => {
const mockState = {
metamask: {
currentCurrency: 'usd',
tokens: [
{
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
],
selectedTokenAddress: '0x1',
contractExchangeRates: {},
send: {},
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'rinkeby',
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
currentCurrency: 'usd',
selectedToken: {
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
selectedTokenExchangeRate: 0,
hideConversion: true,
})
})
it('should return the correct props when not in mainnet and showFiatInTestnets is true', () => {
const mockState = {
metamask: {
currentCurrency: 'usd',
tokens: [
{
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
],
selectedTokenAddress: '0x1',
contractExchangeRates: {},
send: {},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'rinkeby',
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
currentCurrency: 'usd',
selectedToken: {
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
selectedTokenExchangeRate: 0,
hideConversion: false,
})
})
it('should return the correct props when in mainnet and showFiatInTestnets is true', () => {
const mockState = {
metamask: {
currentCurrency: 'usd',
tokens: [
{
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
],
selectedTokenAddress: '0x1',
contractExchangeRates: {},
send: {},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'mainnet',
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
currentCurrency: 'usd',
selectedToken: {
address: '0x1',
decimals: '4',
symbol: 'ABC',
},
selectedTokenExchangeRate: 0,
hideConversion: false,
}) })
}) })
}) })

@ -24,6 +24,7 @@ export default class TokenInput extends PureComponent {
value: PropTypes.string, value: PropTypes.string,
suffix: PropTypes.string, suffix: PropTypes.string,
showFiat: PropTypes.bool, showFiat: PropTypes.bool,
hideConversion: PropTypes.bool,
selectedToken: PropTypes.object, selectedToken: PropTypes.object,
selectedTokenExchangeRate: PropTypes.number, selectedTokenExchangeRate: PropTypes.number,
} }
@ -81,10 +82,18 @@ export default class TokenInput extends PureComponent {
} }
renderConversionComponent () { renderConversionComponent () {
const { selectedTokenExchangeRate, showFiat, currentCurrency } = this.props const { selectedTokenExchangeRate, showFiat, currentCurrency, hideConversion } = this.props
const { decimalValue } = this.state const { decimalValue } = this.state
let currency, numberOfDecimals let currency, numberOfDecimals
if (hideConversion) {
return (
<div className="currency-input__conversion-component">
{ this.context.t('noConversionRateAvailable') }
</div>
)
}
if (showFiat) { if (showFiat) {
// Display Fiat // Display Fiat
currency = currentCurrency currency = currentCurrency

@ -1,14 +1,17 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import TokenInput from './token-input.component' import TokenInput from './token-input.component'
import { getSelectedToken, getSelectedTokenExchangeRate } from '../../selectors' import {getIsMainnet, getSelectedToken, getSelectedTokenExchangeRate, preferencesSelector} from '../../selectors'
const mapStateToProps = state => { const mapStateToProps = state => {
const { metamask: { currentCurrency } } = state const { metamask: { currentCurrency } } = state
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
currentCurrency, currentCurrency,
selectedToken: getSelectedToken(state), selectedToken: getSelectedToken(state),
selectedTokenExchangeRate: getSelectedTokenExchangeRate(state), selectedTokenExchangeRate: getSelectedTokenExchangeRate(state),
hideConversion: (!isMainnet && !showFiatInTestnets),
} }
} }

@ -18,15 +18,17 @@ export default class TransactionBreakdown extends PureComponent {
transaction: PropTypes.object, transaction: PropTypes.object,
className: PropTypes.string, className: PropTypes.string,
nativeCurrency: PropTypes.string.isRequired, nativeCurrency: PropTypes.string.isRequired,
showFiat: PropTypes.bool,
} }
static defaultProps = { static defaultProps = {
transaction: {}, transaction: {},
showFiat: true,
} }
render () { render () {
const { t } = this.context const { t } = this.context
const { transaction, className, nativeCurrency } = this.props const { transaction, className, nativeCurrency, showFiat } = this.props
const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {} } = transaction const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {} } = transaction
const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas
@ -84,11 +86,15 @@ export default class TransactionBreakdown extends PureComponent {
type={PRIMARY} type={PRIMARY}
value={totalInHex} value={totalInHex}
/> />
<UserPreferencedCurrencyDisplay {
className="transaction-breakdown__value" showFiat && (
type={SECONDARY} <UserPreferencedCurrencyDisplay
value={totalInHex} className="transaction-breakdown__value"
/> type={SECONDARY}
value={totalInHex}
/>
)
}
</div> </div>
</TransactionBreakdownRow> </TransactionBreakdownRow>
</div> </div>

@ -1,10 +1,14 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import TransactionBreakdown from './transaction-breakdown.component' import TransactionBreakdown from './transaction-breakdown.component'
import { getNativeCurrency } from '../../selectors' import {getIsMainnet, getNativeCurrency, preferencesSelector} from '../../selectors'
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
nativeCurrency: getNativeCurrency(state), nativeCurrency: getNativeCurrency(state),
showFiat: (isMainnet || !!showFiatInTestnets),
} }
} }

@ -24,6 +24,7 @@ export default class TransactionListItem extends PureComponent {
showCancelModal: PropTypes.func, showCancelModal: PropTypes.func,
showCancel: PropTypes.bool, showCancel: PropTypes.bool,
showRetry: PropTypes.bool, showRetry: PropTypes.bool,
showFiat: PropTypes.bool,
token: PropTypes.object, token: PropTypes.object,
tokenData: PropTypes.object, tokenData: PropTypes.object,
transaction: PropTypes.object, transaction: PropTypes.object,
@ -33,6 +34,10 @@ export default class TransactionListItem extends PureComponent {
fetchGasEstimates: PropTypes.func, fetchGasEstimates: PropTypes.func,
} }
static defaultProps = {
showFiat: true,
}
state = { state = {
showTransactionDetails: false, showTransactionDetails: false,
} }
@ -115,9 +120,9 @@ export default class TransactionListItem extends PureComponent {
} }
renderSecondaryCurrency () { renderSecondaryCurrency () {
const { token, value } = this.props const { token, value, showFiat } = this.props
return token return token || !showFiat
? null ? null
: ( : (
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay

@ -14,11 +14,16 @@ import {
setCustomGasPriceForRetry, setCustomGasPriceForRetry,
setCustomGasLimit, setCustomGasLimit,
} from '../../ducks/gas.duck' } from '../../ducks/gas.duck'
import {getIsMainnet, preferencesSelector} from '../../selectors'
const mapStateToProps = state => { const mapStateToProps = state => {
const { metamask: { knownMethodData } } = state const { metamask: { knownMethodData } } = state
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
knownMethodData, knownMethodData,
showFiat: (isMainnet || !!showFiatInTestnets),
} }
} }

@ -22,10 +22,15 @@ export default class TransactionViewBalance extends PureComponent {
balance: PropTypes.string, balance: PropTypes.string,
assetImage: PropTypes.string, assetImage: PropTypes.string,
balanceIsCached: PropTypes.bool, balanceIsCached: PropTypes.bool,
showFiat: PropTypes.bool,
}
static defaultProps = {
showFiat: true,
} }
renderBalance () { renderBalance () {
const { selectedToken, balance, balanceIsCached } = this.props const { selectedToken, balance, balanceIsCached, showFiat } = this.props
return selectedToken return selectedToken
? ( ? (
@ -53,16 +58,20 @@ export default class TransactionViewBalance extends PureComponent {
balanceIsCached ? <span className="transaction-view-balance__cached-star">*</span> : null balanceIsCached ? <span className="transaction-view-balance__cached-star">*</span> : null
} }
</div> </div>
<UserPreferencedCurrencyDisplay {
className={classnames({ showFiat && (
'transaction-view-balance__cached-secondary-balance': balanceIsCached, <UserPreferencedCurrencyDisplay
'transaction-view-balance__secondary-balance': !balanceIsCached, className={classnames({
})} 'transaction-view-balance__cached-secondary-balance': balanceIsCached,
value={balance} 'transaction-view-balance__secondary-balance': !balanceIsCached,
type={SECONDARY} })}
ethNumberOfDecimals={4} value={balance}
hideTitle={true} type={SECONDARY}
/> ethNumberOfDecimals={4}
hideTitle={true}
/>
)
}
</div> </div>
</Tooltip> </Tooltip>
) )

@ -9,10 +9,14 @@ import {
getSelectedTokenAssetImage, getSelectedTokenAssetImage,
getMetaMaskAccounts, getMetaMaskAccounts,
isBalanceCached, isBalanceCached,
preferencesSelector,
getIsMainnet,
} from '../../selectors' } from '../../selectors'
import { showModal } from '../../actions' import { showModal } from '../../actions'
const mapStateToProps = state => { const mapStateToProps = state => {
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const selectedAddress = getSelectedAddress(state) const selectedAddress = getSelectedAddress(state)
const { metamask: { network } } = state const { metamask: { network } } = state
const accounts = getMetaMaskAccounts(state) const accounts = getMetaMaskAccounts(state)
@ -26,6 +30,7 @@ const mapStateToProps = state => {
nativeCurrency: getNativeCurrency(state), nativeCurrency: getNativeCurrency(state),
assetImage: getSelectedTokenAssetImage(state), assetImage: getSelectedTokenAssetImage(state),
balanceIsCached: isBalanceCached(state), balanceIsCached: isBalanceCached(state),
showFiat: (isMainnet || !!showFiatInTestnets),
} }
} }

@ -21,6 +21,10 @@ describe('UserPreferencedCurrencyDisplay container', () => {
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
preferences: { preferences: {
useNativeCurrencyAsPrimaryCurrency: true, useNativeCurrencyAsPrimaryCurrency: true,
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
}, },
}, },
} }
@ -28,6 +32,30 @@ describe('UserPreferencedCurrencyDisplay container', () => {
assert.deepEqual(mapStateToProps(mockState), { assert.deepEqual(mapStateToProps(mockState), {
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
useNativeCurrencyAsPrimaryCurrency: true, useNativeCurrencyAsPrimaryCurrency: true,
isMainnet: true,
showFiatInTestnets: false,
})
})
it('should return the correct props when not in mainnet and showFiatInTestnets is true', () => {
const mockState = {
metamask: {
nativeCurrency: 'ETH',
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
showFiatInTestnets: true,
},
provider: {
type: 'rinkeby',
},
},
}
assert.deepEqual(mapStateToProps(mockState), {
nativeCurrency: 'ETH',
useNativeCurrencyAsPrimaryCurrency: true,
isMainnet: false,
showFiatInTestnets: true,
}) })
}) })
}) })
@ -41,6 +69,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
stateProps: { stateProps: {
useNativeCurrencyAsPrimaryCurrency: true, useNativeCurrencyAsPrimaryCurrency: true,
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
isMainnet: true,
showFiatInTestnets: false,
}, },
ownProps: { ownProps: {
type: 'PRIMARY', type: 'PRIMARY',
@ -56,6 +86,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
stateProps: { stateProps: {
useNativeCurrencyAsPrimaryCurrency: false, useNativeCurrencyAsPrimaryCurrency: false,
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
isMainnet: true,
showFiatInTestnets: false,
}, },
ownProps: { ownProps: {
type: 'PRIMARY', type: 'PRIMARY',
@ -71,6 +103,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
stateProps: { stateProps: {
useNativeCurrencyAsPrimaryCurrency: true, useNativeCurrencyAsPrimaryCurrency: true,
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
isMainnet: true,
showFiatInTestnets: false,
}, },
ownProps: { ownProps: {
type: 'SECONDARY', type: 'SECONDARY',
@ -88,6 +122,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
stateProps: { stateProps: {
useNativeCurrencyAsPrimaryCurrency: false, useNativeCurrencyAsPrimaryCurrency: false,
nativeCurrency: 'ETH', nativeCurrency: 'ETH',
isMainnet: true,
showFiatInTestnets: false,
}, },
ownProps: { ownProps: {
type: 'SECONDARY', type: 'SECONDARY',
@ -103,6 +139,57 @@ describe('UserPreferencedCurrencyDisplay container', () => {
prefix: 'b', prefix: 'b',
}, },
}, },
{
stateProps: {
useNativeCurrencyAsPrimaryCurrency: false,
nativeCurrency: 'ETH',
isMainnet: false,
showFiatInTestnets: false,
},
ownProps: {
type: 'PRIMARY',
},
result: {
currency: 'ETH',
nativeCurrency: 'ETH',
numberOfDecimals: 6,
prefix: undefined,
},
},
{
stateProps: {
useNativeCurrencyAsPrimaryCurrency: false,
nativeCurrency: 'ETH',
isMainnet: false,
showFiatInTestnets: true,
},
ownProps: {
type: 'PRIMARY',
},
result: {
currency: undefined,
nativeCurrency: 'ETH',
numberOfDecimals: 2,
prefix: undefined,
},
},
{
stateProps: {
useNativeCurrencyAsPrimaryCurrency: false,
nativeCurrency: 'ETH',
isMainnet: true,
showFiatInTestnets: true,
},
ownProps: {
type: 'PRIMARY',
},
result: {
currency: undefined,
nativeCurrency: 'ETH',
numberOfDecimals: 2,
prefix: undefined,
},
},
] ]
tests.forEach(({ stateProps, ownProps, result }) => { tests.forEach(({ stateProps, ownProps, result }) => {

@ -1,19 +1,26 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display.component' import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display.component'
import { preferencesSelector } from '../../selectors' import { preferencesSelector, getIsMainnet } from '../../selectors'
import { ETH, PRIMARY, SECONDARY } from '../../constants/common' import { ETH, PRIMARY, SECONDARY } from '../../constants/common'
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) const {
useNativeCurrencyAsPrimaryCurrency,
showFiatInTestnets,
} = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
return { return {
useNativeCurrencyAsPrimaryCurrency, useNativeCurrencyAsPrimaryCurrency,
showFiatInTestnets,
isMainnet,
nativeCurrency: state.metamask.nativeCurrency, nativeCurrency: state.metamask.nativeCurrency,
} }
} }
const mergeProps = (stateProps, dispatchProps, ownProps) => { const mergeProps = (stateProps, dispatchProps, ownProps) => {
const { useNativeCurrencyAsPrimaryCurrency, nativeCurrency, ...restStateProps } = stateProps const { useNativeCurrencyAsPrimaryCurrency, showFiatInTestnets, isMainnet, nativeCurrency, ...restStateProps } = stateProps
const { const {
type, type,
numberOfDecimals: propsNumberOfDecimals, numberOfDecimals: propsNumberOfDecimals,
@ -40,6 +47,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
prefix = propsPrefix || fiatPrefix prefix = propsPrefix || fiatPrefix
} }
if (!isMainnet && !showFiatInTestnets) {
currency = nativeCurrency || ETH
numberOfDecimals = propsNumberOfDecimals || ethNumberOfDecimals || 6
prefix = propsPrefix || ethPrefix
}
return { return {
...restStateProps, ...restStateProps,
...dispatchProps, ...dispatchProps,

@ -4,3 +4,7 @@ export const WEI = 'WEI'
export const PRIMARY = 'PRIMARY' export const PRIMARY = 'PRIMARY'
export const SECONDARY = 'SECONDARY' export const SECONDARY = 'SECONDARY'
export const NETWORK_TYPES = {
MAINNET: 'mainnet',
}

@ -53,6 +53,7 @@ function reduceMetamask (state, action) {
currentLocale: '', currentLocale: '',
preferences: { preferences: {
useNativeCurrencyAsPrimaryCurrency: true, useNativeCurrencyAsPrimaryCurrency: true,
showFiatInTestnets: false,
}, },
completedOnboarding: false, completedOnboarding: false,
knownMethodData: {}, knownMethodData: {},
@ -375,7 +376,10 @@ function reduceMetamask (state, action) {
case actions.UPDATE_PREFERENCES: { case actions.UPDATE_PREFERENCES: {
return extend(metamaskState, { return extend(metamaskState, {
preferences: { ...action.payload }, preferences: {
...metamaskState.preferences,
...action.payload,
},
}) })
} }

@ -1,3 +1,5 @@
import {NETWORK_TYPES} from './constants/common'
const abi = require('human-standard-token-abi') const abi = require('human-standard-token-abi')
import { import {
transactionsSelector, transactionsSelector,
@ -37,6 +39,7 @@ const selectors = {
getNetworkIdentifier, getNetworkIdentifier,
isBalanceCached, isBalanceCached,
getAdvancedInlineGasShown, getAdvancedInlineGasShown,
getIsMainnet,
} }
module.exports = selectors module.exports = selectors
@ -228,6 +231,11 @@ function getTotalUnapprovedCount ({ metamask }) {
unapprovedTypedMessagesCount unapprovedTypedMessagesCount
} }
function getIsMainnet (state) {
const networkType = getNetworkIdentifier(state)
return networkType === NETWORK_TYPES.MAINNET
}
function preferencesSelector ({ metamask }) { function preferencesSelector ({ metamask }) {
return metamask.preferences return metamask.preferences
} }

@ -5,7 +5,7 @@ import {
conversionGreaterThan, conversionGreaterThan,
} from '../conversion-util' } from '../conversion-util'
import { import {
getCurrentCurrency, getCurrentCurrency, getIsMainnet, preferencesSelector,
} from '../selectors' } from '../selectors'
import { import {
formatCurrency, formatCurrency,
@ -225,6 +225,10 @@ function getRenderableBasicEstimateData (state, gasLimit) {
if (getBasicGasEstimateLoadingStatus(state)) { if (getBasicGasEstimateLoadingStatus(state)) {
return [] return []
} }
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const showFiat = (isMainnet || !!showFiatInTestnets)
const conversionRate = state.metamask.conversionRate const conversionRate = state.metamask.conversionRate
const currentCurrency = getCurrentCurrency(state) const currentCurrency = getCurrentCurrency(state)
const { const {
@ -243,22 +247,28 @@ function getRenderableBasicEstimateData (state, gasLimit) {
return [ return [
{ {
labelKey: 'slow', labelKey: 'slow',
feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit),
feeInSecondaryCurrency: getRenderableEthFee(safeLow, gasLimit), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate)
: '',
timeEstimate: safeLowWait && getRenderableTimeEstimate(safeLowWait), timeEstimate: safeLowWait && getRenderableTimeEstimate(safeLowWait),
priceInHexWei: getGasPriceInHexWei(safeLow), priceInHexWei: getGasPriceInHexWei(safeLow),
}, },
{ {
labelKey: 'average', labelKey: 'average',
feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit),
feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate)
: '',
timeEstimate: fastWait && getRenderableTimeEstimate(fastWait), timeEstimate: fastWait && getRenderableTimeEstimate(fastWait),
priceInHexWei: getGasPriceInHexWei(fast), priceInHexWei: getGasPriceInHexWei(fast),
}, },
{ {
labelKey: 'fast', labelKey: 'fast',
feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit),
feeInSecondaryCurrency: getRenderableEthFee(fastest, gasLimit), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate)
: '',
timeEstimate: fastestWait && getRenderableTimeEstimate(fastestWait), timeEstimate: fastestWait && getRenderableTimeEstimate(fastestWait),
priceInHexWei: getGasPriceInHexWei(fastest), priceInHexWei: getGasPriceInHexWei(fastest),
}, },
@ -269,6 +279,10 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) {
if (getBasicGasEstimateLoadingStatus(state)) { if (getBasicGasEstimateLoadingStatus(state)) {
return [] return []
} }
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const showFiat = (isMainnet || !!showFiatInTestnets)
const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state) || '0x5208' const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state) || '0x5208'
const conversionRate = state.metamask.conversionRate const conversionRate = state.metamask.conversionRate
const currentCurrency = getCurrentCurrency(state) const currentCurrency = getCurrentCurrency(state)
@ -285,19 +299,25 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) {
return [ return [
{ {
labelKey: 'slow', labelKey: 'slow',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate)
: '',
feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(safeLow, true), priceInHexWei: getGasPriceInHexWei(safeLow, true),
}, },
{ {
labelKey: 'average', labelKey: 'average',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate)
: '',
feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(fast, true), priceInHexWei: getGasPriceInHexWei(fast, true),
}, },
{ {
labelKey: 'fast', labelKey: 'fast',
feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: showFiat
? getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate)
: '',
feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true),
priceInHexWei: getGasPriceInHexWei(fastest, true), priceInHexWei: getGasPriceInHexWei(fastest, true),
}, },

@ -78,22 +78,22 @@ describe('custom-gas selectors', () => {
expectedResult: [ expectedResult: [
{ {
labelKey: 'slow', labelKey: 'slow',
feeInPrimaryCurrency: '$0.01', feeInSecondaryCurrency: '$0.01',
feeInSecondaryCurrency: '0.0000525 ETH', feeInPrimaryCurrency: '0.0000525 ETH',
timeEstimate: '~6 min 36 sec', timeEstimate: '~6 min 36 sec',
priceInHexWei: '0x9502f900', priceInHexWei: '0x9502f900',
}, },
{ {
labelKey: 'average', labelKey: 'average',
feeInPrimaryCurrency: '$0.03', feeInSecondaryCurrency: '$0.03',
feeInSecondaryCurrency: '0.000105 ETH', feeInPrimaryCurrency: '0.000105 ETH',
timeEstimate: '~3 min 18 sec', timeEstimate: '~3 min 18 sec',
priceInHexWei: '0x12a05f200', priceInHexWei: '0x12a05f200',
}, },
{ {
labelKey: 'fast', labelKey: 'fast',
feeInPrimaryCurrency: '$0.05', feeInSecondaryCurrency: '$0.05',
feeInSecondaryCurrency: '0.00021 ETH', feeInPrimaryCurrency: '0.00021 ETH',
timeEstimate: '~30 sec', timeEstimate: '~30 sec',
priceInHexWei: '0x2540be400', priceInHexWei: '0x2540be400',
}, },
@ -102,6 +102,12 @@ describe('custom-gas selectors', () => {
metamask: { metamask: {
conversionRate: 255.71, conversionRate: 255.71,
currentCurrency: 'usd', currentCurrency: 'usd',
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
gas: { gas: {
basicEstimates: { basicEstimates: {
@ -120,22 +126,22 @@ describe('custom-gas selectors', () => {
expectedResult: [ expectedResult: [
{ {
labelKey: 'slow', labelKey: 'slow',
feeInPrimaryCurrency: '$0.27', feeInSecondaryCurrency: '$0.27',
feeInSecondaryCurrency: '0.000105 ETH', feeInPrimaryCurrency: '0.000105 ETH',
timeEstimate: '~13 min 12 sec', timeEstimate: '~13 min 12 sec',
priceInHexWei: '0x12a05f200', priceInHexWei: '0x12a05f200',
}, },
{ {
labelKey: 'average', labelKey: 'average',
feeInPrimaryCurrency: '$0.54', feeInSecondaryCurrency: '$0.54',
feeInSecondaryCurrency: '0.00021 ETH', feeInPrimaryCurrency: '0.00021 ETH',
timeEstimate: '~6 min 36 sec', timeEstimate: '~6 min 36 sec',
priceInHexWei: '0x2540be400', priceInHexWei: '0x2540be400',
}, },
{ {
labelKey: 'fast', labelKey: 'fast',
feeInPrimaryCurrency: '$1.07', feeInSecondaryCurrency: '$1.07',
feeInSecondaryCurrency: '0.00042 ETH', feeInPrimaryCurrency: '0.00042 ETH',
timeEstimate: '~1 min', timeEstimate: '~1 min',
priceInHexWei: '0x4a817c800', priceInHexWei: '0x4a817c800',
}, },
@ -147,6 +153,165 @@ describe('custom-gas selectors', () => {
send: { send: {
gasLimit: '0x5208', gasLimit: '0x5208',
}, },
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 5,
safeLowWait: 13.2,
fast: 10,
fastWait: 6.6,
fastest: 20,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
labelKey: 'slow',
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.000105 ETH',
timeEstimate: '~13 min 12 sec',
priceInHexWei: '0x12a05f200',
},
{
labelKey: 'average',
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.00021 ETH',
timeEstimate: '~6 min 36 sec',
priceInHexWei: '0x2540be400',
},
{
labelKey: 'fast',
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.00042 ETH',
timeEstimate: '~1 min',
priceInHexWei: '0x4a817c800',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'rinkeby',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 5,
safeLowWait: 13.2,
fast: 10,
fastWait: 6.6,
fastest: 20,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
labelKey: 'slow',
feeInSecondaryCurrency: '$0.27',
feeInPrimaryCurrency: '0.000105 ETH',
timeEstimate: '~13 min 12 sec',
priceInHexWei: '0x12a05f200',
},
{
labelKey: 'average',
feeInSecondaryCurrency: '$0.54',
feeInPrimaryCurrency: '0.00021 ETH',
timeEstimate: '~6 min 36 sec',
priceInHexWei: '0x2540be400',
},
{
labelKey: 'fast',
feeInSecondaryCurrency: '$1.07',
feeInPrimaryCurrency: '0.00042 ETH',
timeEstimate: '~1 min',
priceInHexWei: '0x4a817c800',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'rinkeby',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 5,
safeLowWait: 13.2,
fast: 10,
fastWait: 6.6,
fastest: 20,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
labelKey: 'slow',
feeInSecondaryCurrency: '$0.27',
feeInPrimaryCurrency: '0.000105 ETH',
timeEstimate: '~13 min 12 sec',
priceInHexWei: '0x12a05f200',
},
{
labelKey: 'average',
feeInSecondaryCurrency: '$0.54',
feeInPrimaryCurrency: '0.00021 ETH',
timeEstimate: '~6 min 36 sec',
priceInHexWei: '0x2540be400',
},
{
labelKey: 'fast',
feeInSecondaryCurrency: '$1.07',
feeInPrimaryCurrency: '0.00042 ETH',
timeEstimate: '~1 min',
priceInHexWei: '0x4a817c800',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'mainnet',
},
}, },
gas: { gas: {
basicEstimates: { basicEstimates: {
@ -203,6 +368,12 @@ describe('custom-gas selectors', () => {
send: { send: {
gasLimit: '0x5208', gasLimit: '0x5208',
}, },
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
}, },
gas: { gas: {
basicEstimates: { basicEstimates: {
@ -245,6 +416,156 @@ describe('custom-gas selectors', () => {
send: { send: {
gasLimit: '0x5208', gasLimit: '0x5208',
}, },
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 50,
safeLowWait: 13.2,
fast: 100,
fastWait: 6.6,
fastest: 200,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.00105 ETH',
labelKey: 'slow',
priceInHexWei: '0xba43b7400',
},
{
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.0021 ETH',
labelKey: 'average',
priceInHexWei: '0x174876e800',
},
{
feeInSecondaryCurrency: '',
feeInPrimaryCurrency: '0.0042 ETH',
labelKey: 'fast',
priceInHexWei: '0x2e90edd000',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'rinkeby',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 50,
safeLowWait: 13.2,
fast: 100,
fastWait: 6.6,
fastest: 200,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
feeInSecondaryCurrency: '$2.68',
feeInPrimaryCurrency: '0.00105 ETH',
labelKey: 'slow',
priceInHexWei: '0xba43b7400',
},
{
feeInSecondaryCurrency: '$5.37',
feeInPrimaryCurrency: '0.0021 ETH',
labelKey: 'average',
priceInHexWei: '0x174876e800',
},
{
feeInSecondaryCurrency: '$10.74',
feeInPrimaryCurrency: '0.0042 ETH',
labelKey: 'fast',
priceInHexWei: '0x2e90edd000',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'rinkeby',
},
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
safeLow: 50,
safeLowWait: 13.2,
fast: 100,
fastWait: 6.6,
fastest: 200,
fastestWait: 1.0,
},
},
},
},
{
expectedResult: [
{
feeInSecondaryCurrency: '$2.68',
feeInPrimaryCurrency: '0.00105 ETH',
labelKey: 'slow',
priceInHexWei: '0xba43b7400',
},
{
feeInSecondaryCurrency: '$5.37',
feeInPrimaryCurrency: '0.0021 ETH',
labelKey: 'average',
priceInHexWei: '0x174876e800',
},
{
feeInSecondaryCurrency: '$10.74',
feeInPrimaryCurrency: '0.0042 ETH',
labelKey: 'fast',
priceInHexWei: '0x2e90edd000',
},
],
mockState: {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: '0x5208',
},
preferences: {
showFiatInTestnets: true,
},
provider: {
type: 'mainnet',
},
}, },
gas: { gas: {
basicEstimates: { basicEstimates: {

Loading…
Cancel
Save