mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add support for RPC endpoints with custom chain IDs (#5134)
This commit is contained in:
parent
eaca9a0e8a
commit
54a8ade266
@ -692,9 +692,27 @@
|
|||||||
"newRecipient": {
|
"newRecipient": {
|
||||||
"message": "New Recipient"
|
"message": "New Recipient"
|
||||||
},
|
},
|
||||||
"newRPC": {
|
"newNetwork": {
|
||||||
|
"message": "New Network"
|
||||||
|
},
|
||||||
|
"rpcURL": {
|
||||||
"message": "New RPC URL"
|
"message": "New RPC URL"
|
||||||
},
|
},
|
||||||
|
"showAdvancedOptions": {
|
||||||
|
"message": "Show Advanced Options"
|
||||||
|
},
|
||||||
|
"hideAdvancedOptions": {
|
||||||
|
"message": "Hide Advanced Options"
|
||||||
|
},
|
||||||
|
"optionalChainId": {
|
||||||
|
"message": "ChainID (optional)"
|
||||||
|
},
|
||||||
|
"optionalSymbol": {
|
||||||
|
"message": "Symbol (optional)"
|
||||||
|
},
|
||||||
|
"optionalNickname": {
|
||||||
|
"message": "Nickname (optional)"
|
||||||
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"message": "Next"
|
"message": "Next"
|
||||||
},
|
},
|
||||||
@ -803,7 +821,7 @@
|
|||||||
"message": "Primary Currency"
|
"message": "Primary Currency"
|
||||||
},
|
},
|
||||||
"primaryCurrencySettingDescription": {
|
"primaryCurrencySettingDescription": {
|
||||||
"message": "Select ETH to prioritize displaying values in ETH. Select Fiat to prioritize displaying values in your selected currency."
|
"message": "Select native to prioritize displaying values in the native currency of the chain (e.g. ETH). Select Fiat to prioritize displaying values in your selected fiat currency."
|
||||||
},
|
},
|
||||||
"privacyMsg": {
|
"privacyMsg": {
|
||||||
"message": "Privacy Policy"
|
"message": "Privacy Policy"
|
||||||
|
@ -21,6 +21,7 @@ class CurrencyController {
|
|||||||
* since midnight of January 1, 1970
|
* since midnight of January 1, 1970
|
||||||
* @property {number} conversionInterval The id of the interval created by the scheduleConversionInterval method.
|
* @property {number} conversionInterval The id of the interval created by the scheduleConversionInterval method.
|
||||||
* Used to clear an existing interval on subsequent calls of that method.
|
* Used to clear an existing interval on subsequent calls of that method.
|
||||||
|
* @property {string} nativeCurrency The ticker/symbol of the native chain currency
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
@ -28,6 +29,7 @@ class CurrencyController {
|
|||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 0,
|
conversionRate: 0,
|
||||||
conversionDate: 'N/A',
|
conversionDate: 'N/A',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
}, opts.initState)
|
}, opts.initState)
|
||||||
this.store = new ObservableStore(initState)
|
this.store = new ObservableStore(initState)
|
||||||
}
|
}
|
||||||
@ -36,6 +38,29 @@ class CurrencyController {
|
|||||||
// PUBLIC METHODS
|
// PUBLIC METHODS
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A getter for the nativeCurrency property
|
||||||
|
*
|
||||||
|
* @returns {string} A 2-4 character shorthand that describes the specific currency
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getNativeCurrency () {
|
||||||
|
return this.store.getState().nativeCurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A setter for the nativeCurrency property
|
||||||
|
*
|
||||||
|
* @param {string} nativeCurrency The new currency to set as the nativeCurrency in the store
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setNativeCurrency (nativeCurrency) {
|
||||||
|
this.store.updateState({
|
||||||
|
nativeCurrency,
|
||||||
|
ticker: nativeCurrency,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A getter for the currentCurrency property
|
* A getter for the currentCurrency property
|
||||||
*
|
*
|
||||||
@ -104,15 +129,32 @@ class CurrencyController {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async updateConversionRate () {
|
async updateConversionRate () {
|
||||||
let currentCurrency
|
let currentCurrency, nativeCurrency
|
||||||
try {
|
try {
|
||||||
currentCurrency = this.getCurrentCurrency()
|
currentCurrency = this.getCurrentCurrency()
|
||||||
const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`)
|
nativeCurrency = this.getNativeCurrency()
|
||||||
|
let apiUrl
|
||||||
|
if (nativeCurrency === 'ETH') {
|
||||||
|
apiUrl = `https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`
|
||||||
|
} else {
|
||||||
|
apiUrl = `https://min-api.cryptocompare.com/data/price?fsym=${nativeCurrency.toUpperCase()}&tsyms=${currentCurrency.toUpperCase()}`
|
||||||
|
}
|
||||||
|
const response = await fetch(apiUrl)
|
||||||
const parsedResponse = await response.json()
|
const parsedResponse = await response.json()
|
||||||
this.setConversionRate(Number(parsedResponse.bid))
|
if (nativeCurrency === 'ETH') {
|
||||||
this.setConversionDate(Number(parsedResponse.timestamp))
|
this.setConversionRate(Number(parsedResponse.bid))
|
||||||
|
this.setConversionDate(Number(parsedResponse.timestamp))
|
||||||
|
} else {
|
||||||
|
if (parsedResponse[currentCurrency.toUpperCase()]) {
|
||||||
|
this.setConversionRate(Number(parsedResponse[currentCurrency.toUpperCase()]))
|
||||||
|
this.setConversionDate(parseInt((new Date()).getTime() / 1000))
|
||||||
|
} else {
|
||||||
|
this.setConversionRate(0)
|
||||||
|
this.setConversionDate('N/A')
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err)
|
log.warn(`MetaMask - Failed to query currency conversion:`, nativeCurrency, currentCurrency, err)
|
||||||
this.setConversionRate(0)
|
this.setConversionRate(0)
|
||||||
this.setConversionDate('N/A')
|
this.setConversionDate('N/A')
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ const createInfuraClient = require('./createInfuraClient')
|
|||||||
const createJsonRpcClient = require('./createJsonRpcClient')
|
const createJsonRpcClient = require('./createJsonRpcClient')
|
||||||
const createLocalhostClient = require('./createLocalhostClient')
|
const createLocalhostClient = require('./createLocalhostClient')
|
||||||
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
|
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
|
||||||
|
const extend = require('extend')
|
||||||
|
const networks = { networkList: {} }
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ROPSTEN,
|
ROPSTEN,
|
||||||
@ -29,6 +31,10 @@ const defaultProviderConfig = {
|
|||||||
type: testMode ? RINKEBY : MAINNET,
|
type: testMode ? RINKEBY : MAINNET,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultNetworkConfig = {
|
||||||
|
ticker: 'ETH',
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = class NetworkController extends EventEmitter {
|
module.exports = class NetworkController extends EventEmitter {
|
||||||
|
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
@ -39,7 +45,8 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
// create stores
|
// create stores
|
||||||
this.providerStore = new ObservableStore(providerConfig)
|
this.providerStore = new ObservableStore(providerConfig)
|
||||||
this.networkStore = new ObservableStore('loading')
|
this.networkStore = new ObservableStore('loading')
|
||||||
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore })
|
this.networkConfig = new ObservableStore(defaultNetworkConfig)
|
||||||
|
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore, settings: this.networkConfig })
|
||||||
this.on('networkDidChange', this.lookupNetwork)
|
this.on('networkDidChange', this.lookupNetwork)
|
||||||
// provider and block tracker
|
// provider and block tracker
|
||||||
this._provider = null
|
this._provider = null
|
||||||
@ -51,8 +58,8 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
|
|
||||||
initializeProvider (providerParams) {
|
initializeProvider (providerParams) {
|
||||||
this._baseProviderParams = providerParams
|
this._baseProviderParams = providerParams
|
||||||
const { type, rpcTarget } = this.providerStore.getState()
|
const { type, rpcTarget, chainId, ticker, nickname } = this.providerStore.getState()
|
||||||
this._configureProvider({ type, rpcTarget })
|
this._configureProvider({ type, rpcTarget, chainId, ticker, nickname })
|
||||||
this.lookupNetwork()
|
this.lookupNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +79,20 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
return this.networkStore.getState()
|
return this.networkStore.getState()
|
||||||
}
|
}
|
||||||
|
|
||||||
setNetworkState (network) {
|
getNetworkConfig () {
|
||||||
|
return this.networkConfig.getState()
|
||||||
|
}
|
||||||
|
|
||||||
|
setNetworkState (network, type) {
|
||||||
|
if (network === 'loading') {
|
||||||
|
return this.networkStore.putState(network)
|
||||||
|
}
|
||||||
|
|
||||||
|
// type must be defined
|
||||||
|
if (!type) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
network = networks.networkList[type] && networks.networkList[type].chainId ? networks.networkList[type].chainId : network
|
||||||
return this.networkStore.putState(network)
|
return this.networkStore.putState(network)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,18 +105,22 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
if (!this._provider) {
|
if (!this._provider) {
|
||||||
return log.warn('NetworkController - lookupNetwork aborted due to missing provider')
|
return log.warn('NetworkController - lookupNetwork aborted due to missing provider')
|
||||||
}
|
}
|
||||||
|
var { type } = this.providerStore.getState()
|
||||||
const ethQuery = new EthQuery(this._provider)
|
const ethQuery = new EthQuery(this._provider)
|
||||||
ethQuery.sendAsync({ method: 'net_version' }, (err, network) => {
|
ethQuery.sendAsync({ method: 'net_version' }, (err, network) => {
|
||||||
if (err) return this.setNetworkState('loading')
|
if (err) return this.setNetworkState('loading')
|
||||||
log.info('web3.getNetwork returned ' + network)
|
log.info('web3.getNetwork returned ' + network)
|
||||||
this.setNetworkState(network)
|
this.setNetworkState(network, type)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setRpcTarget (rpcTarget) {
|
setRpcTarget (rpcTarget, chainId, ticker = 'ETH', nickname = '') {
|
||||||
const providerConfig = {
|
const providerConfig = {
|
||||||
type: 'rpc',
|
type: 'rpc',
|
||||||
rpcTarget,
|
rpcTarget,
|
||||||
|
chainId,
|
||||||
|
ticker,
|
||||||
|
nickname,
|
||||||
}
|
}
|
||||||
this.providerConfig = providerConfig
|
this.providerConfig = providerConfig
|
||||||
}
|
}
|
||||||
@ -132,7 +156,7 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_configureProvider (opts) {
|
_configureProvider (opts) {
|
||||||
const { type, rpcTarget } = opts
|
const { type, rpcTarget, chainId, ticker, nickname } = opts
|
||||||
// infura type-based endpoints
|
// infura type-based endpoints
|
||||||
const isInfura = INFURA_PROVIDER_TYPES.includes(type)
|
const isInfura = INFURA_PROVIDER_TYPES.includes(type)
|
||||||
if (isInfura) {
|
if (isInfura) {
|
||||||
@ -142,7 +166,7 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
this._configureLocalhostProvider()
|
this._configureLocalhostProvider()
|
||||||
// url-based rpc endpoints
|
// url-based rpc endpoints
|
||||||
} else if (type === 'rpc') {
|
} else if (type === 'rpc') {
|
||||||
this._configureStandardProvider({ rpcUrl: rpcTarget })
|
this._configureStandardProvider({ rpcUrl: rpcTarget, chainId, ticker, nickname })
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)
|
throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)
|
||||||
}
|
}
|
||||||
@ -152,6 +176,11 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
log.info('NetworkController - configureInfuraProvider', type)
|
log.info('NetworkController - configureInfuraProvider', type)
|
||||||
const networkClient = createInfuraClient({ network: type })
|
const networkClient = createInfuraClient({ network: type })
|
||||||
this._setNetworkClient(networkClient)
|
this._setNetworkClient(networkClient)
|
||||||
|
// setup networkConfig
|
||||||
|
var settings = {
|
||||||
|
ticker: 'ETH',
|
||||||
|
}
|
||||||
|
this.networkConfig.putState(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
_configureLocalhostProvider () {
|
_configureLocalhostProvider () {
|
||||||
@ -160,9 +189,22 @@ module.exports = class NetworkController extends EventEmitter {
|
|||||||
this._setNetworkClient(networkClient)
|
this._setNetworkClient(networkClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
_configureStandardProvider ({ rpcUrl }) {
|
_configureStandardProvider ({ rpcUrl, chainId, ticker, nickname }) {
|
||||||
log.info('NetworkController - configureStandardProvider', rpcUrl)
|
log.info('NetworkController - configureStandardProvider', rpcUrl)
|
||||||
const networkClient = createJsonRpcClient({ rpcUrl })
|
const networkClient = createJsonRpcClient({ rpcUrl })
|
||||||
|
// hack to add a 'rpc' network with chainId
|
||||||
|
networks.networkList['rpc'] = {
|
||||||
|
chainId: chainId,
|
||||||
|
rpcUrl,
|
||||||
|
ticker: ticker || 'ETH',
|
||||||
|
nickname,
|
||||||
|
}
|
||||||
|
// setup networkConfig
|
||||||
|
var settings = {
|
||||||
|
network: chainId,
|
||||||
|
}
|
||||||
|
settings = extend(settings, networks.networkList['rpc'])
|
||||||
|
this.networkConfig.putState(settings)
|
||||||
this._setNetworkClient(networkClient)
|
this._setNetworkClient(networkClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class PreferencesController {
|
|||||||
*/
|
*/
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
const initState = extend({
|
const initState = extend({
|
||||||
frequentRpcList: [],
|
frequentRpcListDetail: [],
|
||||||
currentAccountTab: 'history',
|
currentAccountTab: 'history',
|
||||||
accountTokens: {},
|
accountTokens: {},
|
||||||
assetImages: {},
|
assetImages: {},
|
||||||
@ -39,7 +39,7 @@ class PreferencesController {
|
|||||||
seedWords: null,
|
seedWords: null,
|
||||||
forgottenPassword: false,
|
forgottenPassword: false,
|
||||||
preferences: {
|
preferences: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
},
|
},
|
||||||
}, opts.initState)
|
}, opts.initState)
|
||||||
|
|
||||||
@ -392,19 +392,22 @@ class PreferencesController {
|
|||||||
* Adds custom RPC url to state.
|
* Adds custom RPC url to state.
|
||||||
*
|
*
|
||||||
* @param {string} url The RPC url to add to frequentRpcList.
|
* @param {string} url The RPC url to add to frequentRpcList.
|
||||||
|
* @param {number} chainId Optional chainId of the selected network.
|
||||||
|
* @param {string} ticker Optional ticker symbol of the selected network.
|
||||||
|
* @param {string} nickname Optional nickname of the selected network.
|
||||||
* @returns {Promise<array>} Promise resolving to updated frequentRpcList.
|
* @returns {Promise<array>} Promise resolving to updated frequentRpcList.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
addToFrequentRpcList (url) {
|
addToFrequentRpcList (url, chainId, ticker = 'ETH', nickname = '') {
|
||||||
const rpcList = this.getFrequentRpcList()
|
const rpcList = this.getFrequentRpcListDetail()
|
||||||
const index = rpcList.findIndex((element) => { return element === url })
|
const index = rpcList.findIndex((element) => { return element.rpcUrl === url })
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
rpcList.splice(index, 1)
|
rpcList.splice(index, 1)
|
||||||
}
|
}
|
||||||
if (url !== 'http://localhost:8545') {
|
if (url !== 'http://localhost:8545') {
|
||||||
rpcList.push(url)
|
rpcList.push({ rpcUrl: url, chainId, ticker, nickname })
|
||||||
}
|
}
|
||||||
this.store.updateState({ frequentRpcList: rpcList })
|
this.store.updateState({ frequentRpcListiDetail: rpcList })
|
||||||
return Promise.resolve(rpcList)
|
return Promise.resolve(rpcList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,23 +419,23 @@ class PreferencesController {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
removeFromFrequentRpcList (url) {
|
removeFromFrequentRpcList (url) {
|
||||||
const rpcList = this.getFrequentRpcList()
|
const rpcList = this.getFrequentRpcListDetail()
|
||||||
const index = rpcList.findIndex((element) => { return element === url })
|
const index = rpcList.findIndex((element) => { return element.rpcUrl === url })
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
rpcList.splice(index, 1)
|
rpcList.splice(index, 1)
|
||||||
}
|
}
|
||||||
this.store.updateState({ frequentRpcList: rpcList })
|
this.store.updateState({ frequentRpcListDetail: rpcList })
|
||||||
return Promise.resolve(rpcList)
|
return Promise.resolve(rpcList)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for the `frequentRpcList` property.
|
* Getter for the `frequentRpcListDetail` property.
|
||||||
*
|
*
|
||||||
* @returns {array<string>} An array of one or two rpc urls.
|
* @returns {array<array>} An array of rpc urls.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
getFrequentRpcList () {
|
getFrequentRpcListDetail () {
|
||||||
return this.store.getState().frequentRpcList
|
return this.store.getState().frequentRpcListDetail
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,12 +138,12 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
this.accountTracker.stop()
|
this.accountTracker.stop()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// ensure accountTracker updates balances after network change
|
// ensure accountTracker updates balances after network change
|
||||||
this.networkController.on('networkDidChange', () => {
|
this.networkController.on('networkDidChange', () => {
|
||||||
this.accountTracker._updateAccounts()
|
this.accountTracker._updateAccounts()
|
||||||
})
|
})
|
||||||
|
|
||||||
// key mgmt
|
// key mgmt
|
||||||
const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring]
|
const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring]
|
||||||
this.keyringController = new KeyringController({
|
this.keyringController = new KeyringController({
|
||||||
@ -197,6 +197,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
this.networkController.on('networkDidChange', () => {
|
this.networkController.on('networkDidChange', () => {
|
||||||
this.balancesController.updateAllBalances()
|
this.balancesController.updateAllBalances()
|
||||||
|
var currentCurrency = this.currencyController.getCurrentCurrency()
|
||||||
|
this.setCurrentCurrency(currentCurrency, function() {})
|
||||||
})
|
})
|
||||||
this.balancesController.updateAllBalances()
|
this.balancesController.updateAllBalances()
|
||||||
|
|
||||||
@ -1412,10 +1414,13 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
* @param {Function} cb - A callback function returning currency info.
|
* @param {Function} cb - A callback function returning currency info.
|
||||||
*/
|
*/
|
||||||
setCurrentCurrency (currencyCode, cb) {
|
setCurrentCurrency (currencyCode, cb) {
|
||||||
|
const { ticker } = this.networkController.getNetworkConfig()
|
||||||
try {
|
try {
|
||||||
|
this.currencyController.setNativeCurrency(ticker)
|
||||||
this.currencyController.setCurrentCurrency(currencyCode)
|
this.currencyController.setCurrentCurrency(currencyCode)
|
||||||
this.currencyController.updateConversionRate()
|
this.currencyController.updateConversionRate()
|
||||||
const data = {
|
const data = {
|
||||||
|
nativeCurrency: ticker || 'ETH',
|
||||||
conversionRate: this.currencyController.getConversionRate(),
|
conversionRate: this.currencyController.getConversionRate(),
|
||||||
currentCurrency: this.currencyController.getCurrentCurrency(),
|
currentCurrency: this.currencyController.getCurrentCurrency(),
|
||||||
conversionDate: this.currencyController.getConversionDate(),
|
conversionDate: this.currencyController.getConversionDate(),
|
||||||
@ -1454,11 +1459,14 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* A method for selecting a custom URL for an ethereum RPC provider.
|
* A method for selecting a custom URL for an ethereum RPC provider.
|
||||||
* @param {string} rpcTarget - A URL for a valid Ethereum RPC API.
|
* @param {string} rpcTarget - A URL for a valid Ethereum RPC API.
|
||||||
|
* @param {number} chainId - The chainId of the selected network.
|
||||||
|
* @param {string} ticker - The ticker symbol of the selected network.
|
||||||
|
* @param {string} nickname - Optional nickname of the selected network.
|
||||||
* @returns {Promise<String>} - The RPC Target URL confirmed.
|
* @returns {Promise<String>} - The RPC Target URL confirmed.
|
||||||
*/
|
*/
|
||||||
async setCustomRpc (rpcTarget) {
|
async setCustomRpc (rpcTarget, chainId, ticker = 'ETH', nickname = '') {
|
||||||
this.networkController.setRpcTarget(rpcTarget)
|
this.networkController.setRpcTarget(rpcTarget, chainId, ticker, nickname)
|
||||||
await this.preferencesController.addToFrequentRpcList(rpcTarget)
|
await this.preferencesController.addToFrequentRpcList(rpcTarget, chainId, ticker, nickname)
|
||||||
return rpcTarget
|
return rpcTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@
|
|||||||
},
|
},
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -152,7 +152,7 @@
|
|||||||
},
|
},
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
},
|
},
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
"tokens": [],
|
"tokens": [],
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
},
|
},
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
"send": {},
|
"send": {},
|
||||||
"currentLocale": "en",
|
"currentLocale": "en",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"useETHAsPrimaryCurrency": true
|
"useNativeCurrencyAsPrimaryCurrency": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"appState": {
|
"appState": {
|
||||||
|
@ -73,7 +73,7 @@ function mapStateToProps (state) {
|
|||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
nextUnreadNotice: state.metamask.nextUnreadNotice,
|
nextUnreadNotice: state.metamask.nextUnreadNotice,
|
||||||
lostAccounts: state.metamask.lostAccounts,
|
lostAccounts: state.metamask.lostAccounts,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
|
||||||
featureFlags,
|
featureFlags,
|
||||||
suggestedTokens: state.metamask.suggestedTokens,
|
suggestedTokens: state.metamask.suggestedTokens,
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ module.exports = class AppBar extends Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
frequentRpcList: PropTypes.array.isRequired,
|
frequentRpcListDetail: PropTypes.array.isRequired,
|
||||||
isMascara: PropTypes.bool.isRequired,
|
isMascara: PropTypes.bool.isRequired,
|
||||||
isOnboarding: PropTypes.bool.isRequired,
|
isOnboarding: PropTypes.bool.isRequired,
|
||||||
identities: PropTypes.any.isRequired,
|
identities: PropTypes.any.isRequired,
|
||||||
@ -196,7 +196,7 @@ module.exports = class AppBar extends Component {
|
|||||||
renderNetworkDropdown () {
|
renderNetworkDropdown () {
|
||||||
const {
|
const {
|
||||||
dispatch,
|
dispatch,
|
||||||
frequentRpcList: rpcList,
|
frequentRpcListDetail: rpcList,
|
||||||
provider,
|
provider,
|
||||||
} = this.props
|
} = this.props
|
||||||
const {
|
const {
|
||||||
@ -321,8 +321,8 @@ module.exports = class AppBar extends Component {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCustomOption ({ rpcTarget, type }) {
|
renderCustomOption ({ rpcTarget, type, ticker }) {
|
||||||
const {dispatch} = this.props
|
const {dispatch, network} = this.props
|
||||||
|
|
||||||
if (type !== 'rpc') {
|
if (type !== 'rpc') {
|
||||||
return null
|
return null
|
||||||
@ -340,7 +340,7 @@ module.exports = class AppBar extends Component {
|
|||||||
default:
|
default:
|
||||||
return h(DropdownMenuItem, {
|
return h(DropdownMenuItem, {
|
||||||
key: rpcTarget,
|
key: rpcTarget,
|
||||||
onClick: () => dispatch(actions.setRpcTarget(rpcTarget)),
|
onClick: () => dispatch(actions.setRpcTarget(rpcTarget, network, ticker)),
|
||||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||||
}, [
|
}, [
|
||||||
h('i.fa.fa-question-circle.fa-lg.menu-icon'),
|
h('i.fa.fa-question-circle.fa-lg.menu-icon'),
|
||||||
@ -354,7 +354,8 @@ module.exports = class AppBar extends Component {
|
|||||||
const {dispatch} = this.props
|
const {dispatch} = this.props
|
||||||
const reversedRpcList = rpcList.slice().reverse()
|
const reversedRpcList = rpcList.slice().reverse()
|
||||||
|
|
||||||
return reversedRpcList.map((rpc) => {
|
return reversedRpcList.map((entry) => {
|
||||||
|
const rpc = entry.rpcUrl
|
||||||
const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget
|
const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget
|
||||||
|
|
||||||
if ((rpc === LOCALHOST_RPC_URL) || currentRpcTarget) {
|
if ((rpc === LOCALHOST_RPC_URL) || currentRpcTarget) {
|
||||||
@ -363,7 +364,7 @@ module.exports = class AppBar extends Component {
|
|||||||
return h(DropdownMenuItem, {
|
return h(DropdownMenuItem, {
|
||||||
key: `common${rpc}`,
|
key: `common${rpc}`,
|
||||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||||
onClick: () => dispatch(actions.setRpcTarget(rpc)),
|
onClick: () => dispatch(actions.setRpcTarget(rpc, entry.chainId, entry.ticker)),
|
||||||
}, [
|
}, [
|
||||||
h('i.fa.fa-question-circle.fa-lg.menu-icon'),
|
h('i.fa.fa-question-circle.fa-lg.menu-icon'),
|
||||||
rpc,
|
rpc,
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
const Component = require('react').Component
|
const Component = require('react').Component
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
|
const connect = require('react-redux').connect
|
||||||
const inherits = require('util').inherits
|
const inherits = require('util').inherits
|
||||||
const formatBalance = require('../util').formatBalance
|
const formatBalance = require('../util').formatBalance
|
||||||
const generateBalanceObject = require('../util').generateBalanceObject
|
const generateBalanceObject = require('../util').generateBalanceObject
|
||||||
const Tooltip = require('./tooltip.js')
|
const Tooltip = require('./tooltip.js')
|
||||||
const FiatValue = require('./fiat-value.js')
|
const FiatValue = require('./fiat-value.js')
|
||||||
|
|
||||||
module.exports = EthBalanceComponent
|
module.exports = connect(mapStateToProps)(EthBalanceComponent)
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
return {
|
||||||
|
ticker: state.metamask.ticker,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inherits(EthBalanceComponent, Component)
|
inherits(EthBalanceComponent, Component)
|
||||||
function EthBalanceComponent () {
|
function EthBalanceComponent () {
|
||||||
@ -16,9 +22,10 @@ function EthBalanceComponent () {
|
|||||||
EthBalanceComponent.prototype.render = function () {
|
EthBalanceComponent.prototype.render = function () {
|
||||||
var props = this.props
|
var props = this.props
|
||||||
let { value } = props
|
let { value } = props
|
||||||
|
const { ticker } = props
|
||||||
var style = props.style
|
var style = props.style
|
||||||
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
|
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
|
||||||
value = value ? formatBalance(value, 6, needsParse) : '...'
|
value = value ? formatBalance(value, 6, needsParse, ticker) : '...'
|
||||||
var width = props.width
|
var width = props.width
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
const Component = require('react').Component
|
const Component = require('react').Component
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
|
const connect = require('react-redux').connect
|
||||||
const inherits = require('util').inherits
|
const inherits = require('util').inherits
|
||||||
const formatBalance = require('../util').formatBalance
|
const formatBalance = require('../util').formatBalance
|
||||||
const generateBalanceObject = require('../util').generateBalanceObject
|
const generateBalanceObject = require('../util').generateBalanceObject
|
||||||
const Tooltip = require('./tooltip.js')
|
const Tooltip = require('./tooltip.js')
|
||||||
const FiatValue = require('./fiat-value.js')
|
const FiatValue = require('./fiat-value.js')
|
||||||
|
|
||||||
module.exports = EthBalanceComponent
|
module.exports = connect(mapStateToProps)(EthBalanceComponent)
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
return {
|
||||||
|
ticker: state.metamask.ticker,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inherits(EthBalanceComponent, Component)
|
inherits(EthBalanceComponent, Component)
|
||||||
function EthBalanceComponent () {
|
function EthBalanceComponent () {
|
||||||
@ -16,9 +22,9 @@ function EthBalanceComponent () {
|
|||||||
EthBalanceComponent.prototype.render = function () {
|
EthBalanceComponent.prototype.render = function () {
|
||||||
var props = this.props
|
var props = this.props
|
||||||
let { value } = props
|
let { value } = props
|
||||||
const { style, width } = props
|
const { ticker, style, width } = props
|
||||||
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
|
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
|
||||||
value = value ? formatBalance(value, 6, needsParse) : '...'
|
value = value ? formatBalance(value, 6, needsParse, ticker) : '...'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ ConfigScreen.prototype.render = function () {
|
|||||||
|
|
||||||
currentProviderDisplay(metamaskState),
|
currentProviderDisplay(metamaskState),
|
||||||
|
|
||||||
h('div', { style: {display: 'flex'} }, [
|
h('div', { style: {display: 'block'} }, [
|
||||||
h('input#new_rpc', {
|
h('input#new_rpc', {
|
||||||
placeholder: 'New RPC URL',
|
placeholder: 'New RPC URL',
|
||||||
style: {
|
style: {
|
||||||
@ -81,7 +81,70 @@ ConfigScreen.prototype.render = function () {
|
|||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
var element = event.target
|
var element = event.target
|
||||||
var newRpc = element.value
|
var newRpc = element.value
|
||||||
rpcValidation(newRpc, state)
|
var chainid = document.querySelector('input#chainid')
|
||||||
|
var ticker = document.querySelector('input#ticker')
|
||||||
|
var nickname = document.querySelector('input#nickname')
|
||||||
|
rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
h('br'),
|
||||||
|
h('input#chainid', {
|
||||||
|
placeholder: 'ChainId (optional)',
|
||||||
|
style: {
|
||||||
|
width: 'inherit',
|
||||||
|
flex: '1 0 auto',
|
||||||
|
height: '30px',
|
||||||
|
margin: '8px',
|
||||||
|
},
|
||||||
|
onKeyPress (event) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
var element = document.querySelector('input#new_rpc')
|
||||||
|
var newRpc = element.value
|
||||||
|
var chainid = document.querySelector('input#chainid')
|
||||||
|
var ticker = document.querySelector('input#ticker')
|
||||||
|
var nickname = document.querySelector('input#nickname')
|
||||||
|
rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
h('br'),
|
||||||
|
h('input#ticker', {
|
||||||
|
placeholder: 'Symbol (optional)',
|
||||||
|
style: {
|
||||||
|
width: 'inherit',
|
||||||
|
flex: '1 0 auto',
|
||||||
|
height: '30px',
|
||||||
|
margin: '8px',
|
||||||
|
},
|
||||||
|
onKeyPress (event) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
var element = document.querySelector('input#new_rpc')
|
||||||
|
var newRpc = element.value
|
||||||
|
var chainid = document.querySelector('input#chainid')
|
||||||
|
var ticker = document.querySelector('input#ticker')
|
||||||
|
var nickname = document.querySelector('input#nickname')
|
||||||
|
rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
h('br'),
|
||||||
|
h('input#nickname', {
|
||||||
|
placeholder: 'Nickname (optional)',
|
||||||
|
style: {
|
||||||
|
width: 'inherit',
|
||||||
|
flex: '1 0 auto',
|
||||||
|
height: '30px',
|
||||||
|
margin: '8px',
|
||||||
|
},
|
||||||
|
onKeyPress (event) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
var element = document.querySelector('input#new_rpc')
|
||||||
|
var newRpc = element.value
|
||||||
|
var chainid = document.querySelector('input#chainid')
|
||||||
|
var ticker = document.querySelector('input#ticker')
|
||||||
|
var nickname = document.querySelector('input#nickname')
|
||||||
|
rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -93,7 +156,10 @@ ConfigScreen.prototype.render = function () {
|
|||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
var element = document.querySelector('input#new_rpc')
|
var element = document.querySelector('input#new_rpc')
|
||||||
var newRpc = element.value
|
var newRpc = element.value
|
||||||
rpcValidation(newRpc, state)
|
var chainid = document.querySelector('input#chainid')
|
||||||
|
var ticker = document.querySelector('input#ticker')
|
||||||
|
var nickname = document.querySelector('input#nickname')
|
||||||
|
rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state)
|
||||||
},
|
},
|
||||||
}, 'Save'),
|
}, 'Save'),
|
||||||
]),
|
]),
|
||||||
@ -189,9 +255,9 @@ ConfigScreen.prototype.render = function () {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function rpcValidation (newRpc, state) {
|
function rpcValidation (newRpc, chainid, ticker = 'ETH', nickname = '', state) {
|
||||||
if (validUrl.isWebUri(newRpc)) {
|
if (validUrl.isWebUri(newRpc)) {
|
||||||
state.dispatch(actions.setRpcTarget(newRpc))
|
state.dispatch(actions.setRpcTarget(newRpc, chainid, ticker, nickname))
|
||||||
} else {
|
} else {
|
||||||
var appendedRpc = `http://${newRpc}`
|
var appendedRpc = `http://${newRpc}`
|
||||||
if (validUrl.isWebUri(appendedRpc)) {
|
if (validUrl.isWebUri(appendedRpc)) {
|
||||||
|
@ -102,7 +102,7 @@ function parseBalance (balance) {
|
|||||||
|
|
||||||
// Takes wei hex, returns an object with three properties.
|
// Takes wei hex, returns an object with three properties.
|
||||||
// Its "formatted" property is what we generally use to render values.
|
// Its "formatted" property is what we generally use to render values.
|
||||||
function formatBalance (balance, decimalsToKeep, needsParse = true) {
|
function formatBalance (balance, decimalsToKeep, needsParse = true, ticker = 'ETH') {
|
||||||
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
|
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
|
||||||
var beforeDecimal = parsed[0]
|
var beforeDecimal = parsed[0]
|
||||||
var afterDecimal = parsed[1]
|
var afterDecimal = parsed[1]
|
||||||
@ -112,14 +112,14 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) {
|
|||||||
if (afterDecimal !== '0') {
|
if (afterDecimal !== '0') {
|
||||||
var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
|
var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
|
||||||
if (sigFigs) { afterDecimal = sigFigs[0] }
|
if (sigFigs) { afterDecimal = sigFigs[0] }
|
||||||
formatted = '0.' + afterDecimal + ' ETH'
|
formatted = '0.' + afterDecimal + ` ${ticker}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
|
formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ` ${ticker}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
afterDecimal += Array(decimalsToKeep).join('0')
|
afterDecimal += Array(decimalsToKeep).join('0')
|
||||||
formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
|
formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ` ${ticker}`
|
||||||
}
|
}
|
||||||
return formatted
|
return formatted
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,9 @@
|
|||||||
"0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d": 0.00039345803819379796,
|
"0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d": 0.00039345803819379796,
|
||||||
"0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5": 0.00008189274407698049
|
"0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5": 0.00008189274407698049
|
||||||
},
|
},
|
||||||
|
"ticker": "ETH",
|
||||||
"currentCurrency": "usd",
|
"currentCurrency": "usd",
|
||||||
|
"nativeCurrency": "ETH",
|
||||||
"conversionRate": 556.12,
|
"conversionRate": 556.12,
|
||||||
"addressBook": [
|
"addressBook": [
|
||||||
{
|
{
|
||||||
@ -1248,4 +1250,4 @@
|
|||||||
"context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
|
"context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ describe('# Network Controller', function () {
|
|||||||
|
|
||||||
describe('#setNetworkState', function () {
|
describe('#setNetworkState', function () {
|
||||||
it('should update the network', function () {
|
it('should update the network', function () {
|
||||||
networkController.setNetworkState(1)
|
networkController.setNetworkState(1, 'rpc')
|
||||||
const networkState = networkController.getNetworkState()
|
const networkState = networkController.getNetworkState()
|
||||||
assert.equal(networkState, 1, 'network is 1')
|
assert.equal(networkState, 1, 'network is 1')
|
||||||
})
|
})
|
||||||
|
@ -487,20 +487,20 @@ describe('preferences controller', function () {
|
|||||||
|
|
||||||
describe('on updateFrequentRpcList', function () {
|
describe('on updateFrequentRpcList', function () {
|
||||||
it('should add custom RPC url to state', function () {
|
it('should add custom RPC url to state', function () {
|
||||||
preferencesController.addToFrequentRpcList('rpc_url')
|
preferencesController.addToFrequentRpcList('rpc_url', 1)
|
||||||
preferencesController.addToFrequentRpcList('http://localhost:8545')
|
preferencesController.addToFrequentRpcList('http://localhost:8545', 1)
|
||||||
assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url'])
|
assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] )
|
||||||
preferencesController.addToFrequentRpcList('rpc_url')
|
preferencesController.addToFrequentRpcList('rpc_url', 1)
|
||||||
assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url'])
|
assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] )
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should remove custom RPC url from state', function () {
|
it('should remove custom RPC url from state', function () {
|
||||||
preferencesController.addToFrequentRpcList('rpc_url')
|
preferencesController.addToFrequentRpcList('rpc_url', 1)
|
||||||
assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url'])
|
assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] )
|
||||||
preferencesController.removeFromFrequentRpcList('other_rpc_url')
|
preferencesController.removeFromFrequentRpcList('other_rpc_url')
|
||||||
preferencesController.removeFromFrequentRpcList('http://localhost:8545')
|
preferencesController.removeFromFrequentRpcList('http://localhost:8545')
|
||||||
preferencesController.removeFromFrequentRpcList('rpc_url')
|
preferencesController.removeFromFrequentRpcList('rpc_url')
|
||||||
assert.deepEqual(preferencesController.store.getState().frequentRpcList, [])
|
assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1133,7 +1133,7 @@ describe('Actions', () => {
|
|||||||
{ type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' },
|
{ type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' },
|
||||||
]
|
]
|
||||||
|
|
||||||
setRpcTargetSpy.callsFake((newRpc, callback) => {
|
setRpcTargetSpy.callsFake((newRpc, chainId, ticker, nickname, callback) => {
|
||||||
callback(new Error('error'))
|
callback(new Error('error'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ var actions = {
|
|||||||
setPreference,
|
setPreference,
|
||||||
updatePreferences,
|
updatePreferences,
|
||||||
UPDATE_PREFERENCES: 'UPDATE_PREFERENCES',
|
UPDATE_PREFERENCES: 'UPDATE_PREFERENCES',
|
||||||
setUseETHAsPrimaryCurrencyPreference,
|
setUseNativeCurrencyAsPrimaryCurrencyPreference,
|
||||||
|
|
||||||
setMouseUserState,
|
setMouseUserState,
|
||||||
SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
|
SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
|
||||||
@ -1874,10 +1874,10 @@ function updateProviderType (type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setRpcTarget (newRpc) {
|
function setRpcTarget (newRpc, chainId, ticker = 'ETH', nickname = '') {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
log.debug(`background.setRpcTarget: ${newRpc}`)
|
log.debug(`background.setRpcTarget: ${newRpc} ${chainId} ${ticker} ${nickname}`)
|
||||||
background.setCustomRpc(newRpc, (err, result) => {
|
background.setCustomRpc(newRpc, chainId, ticker, nickname, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.error(err)
|
log.error(err)
|
||||||
return dispatch(actions.displayWarning('Had a problem changing networks!'))
|
return dispatch(actions.displayWarning('Had a problem changing networks!'))
|
||||||
@ -2330,8 +2330,8 @@ function updatePreferences (value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUseETHAsPrimaryCurrencyPreference (value) {
|
function setUseNativeCurrencyAsPrimaryCurrencyPreference (value) {
|
||||||
return setPreference('useETHAsPrimaryCurrency', value)
|
return setPreference('useNativeCurrencyAsPrimaryCurrency', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNetworkNonce (networkNonce) {
|
function setNetworkNonce (networkNonce) {
|
||||||
|
@ -101,7 +101,7 @@ class App extends Component {
|
|||||||
network,
|
network,
|
||||||
isMouseUser,
|
isMouseUser,
|
||||||
provider,
|
provider,
|
||||||
frequentRpcList,
|
frequentRpcListDetail,
|
||||||
currentView,
|
currentView,
|
||||||
setMouseUserState,
|
setMouseUserState,
|
||||||
sidebar,
|
sidebar,
|
||||||
@ -147,7 +147,7 @@ class App extends Component {
|
|||||||
// network dropdown
|
// network dropdown
|
||||||
h(NetworkDropdown, {
|
h(NetworkDropdown, {
|
||||||
provider,
|
provider,
|
||||||
frequentRpcList,
|
frequentRpcListDetail,
|
||||||
}, []),
|
}, []),
|
||||||
|
|
||||||
h(AccountMenu),
|
h(AccountMenu),
|
||||||
@ -230,7 +230,7 @@ App.propTypes = {
|
|||||||
alertMessage: PropTypes.string,
|
alertMessage: PropTypes.string,
|
||||||
network: PropTypes.string,
|
network: PropTypes.string,
|
||||||
provider: PropTypes.object,
|
provider: PropTypes.object,
|
||||||
frequentRpcList: PropTypes.array,
|
frequentRpcListDetail: PropTypes.array,
|
||||||
currentView: PropTypes.object,
|
currentView: PropTypes.object,
|
||||||
sidebar: PropTypes.object,
|
sidebar: PropTypes.object,
|
||||||
alertOpen: PropTypes.bool,
|
alertOpen: PropTypes.bool,
|
||||||
@ -322,7 +322,7 @@ function mapStateToProps (state) {
|
|||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
nextUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
|
||||||
currentCurrency: state.metamask.currentCurrency,
|
currentCurrency: state.metamask.currentCurrency,
|
||||||
isMouseUser: state.appState.isMouseUser,
|
isMouseUser: state.appState.isMouseUser,
|
||||||
betaUI: state.metamask.featureFlags.betaUI,
|
betaUI: state.metamask.featureFlags.betaUI,
|
||||||
|
@ -6,7 +6,7 @@ import TokenBalance from './token-balance'
|
|||||||
import Identicon from './identicon'
|
import Identicon from './identicon'
|
||||||
import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display'
|
import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display'
|
||||||
import { PRIMARY, SECONDARY } from '../constants/common'
|
import { PRIMARY, SECONDARY } from '../constants/common'
|
||||||
const { getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors')
|
const { getNativeCurrency, getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors')
|
||||||
|
|
||||||
const { formatBalance } = require('../util')
|
const { formatBalance } = require('../util')
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ function mapStateToProps (state) {
|
|||||||
return {
|
return {
|
||||||
account,
|
account,
|
||||||
network,
|
network,
|
||||||
|
nativeCurrency: getNativeCurrency(state),
|
||||||
conversionRate: conversionRateSelector(state),
|
conversionRate: conversionRateSelector(state),
|
||||||
currentCurrency: getCurrentCurrency(state),
|
currentCurrency: getCurrentCurrency(state),
|
||||||
assetImages: getAssetImages(state),
|
assetImages: getAssetImages(state),
|
||||||
@ -66,10 +67,10 @@ BalanceComponent.prototype.renderTokenBalance = function () {
|
|||||||
|
|
||||||
BalanceComponent.prototype.renderBalance = function () {
|
BalanceComponent.prototype.renderBalance = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { account } = props
|
const { account, nativeCurrency } = props
|
||||||
const balanceValue = account && account.balance
|
const balanceValue = account && account.balance
|
||||||
const needsParse = 'needsParse' in props ? props.needsParse : true
|
const needsParse = 'needsParse' in props ? props.needsParse : true
|
||||||
const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse) : '...'
|
const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse, nativeCurrency) : '...'
|
||||||
const showFiat = 'showFiat' in props ? props.showFiat : true
|
const showFiat = 'showFiat' in props ? props.showFiat : true
|
||||||
|
|
||||||
if (formattedBalance === 'None' || formattedBalance === '...') {
|
if (formattedBalance === 'None' || formattedBalance === '...') {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { ETH, GWEI } from '../../constants/common'
|
import { GWEI } from '../../constants/common'
|
||||||
|
|
||||||
export default class CurrencyDisplay extends PureComponent {
|
export default class CurrencyDisplay extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -12,7 +12,7 @@ export default class CurrencyDisplay extends PureComponent {
|
|||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
suffix: PropTypes.string,
|
suffix: PropTypes.string,
|
||||||
// Used in container
|
// Used in container
|
||||||
currency: PropTypes.oneOf([ETH]),
|
currency: PropTypes.string,
|
||||||
denomination: PropTypes.oneOf([GWEI]),
|
denomination: PropTypes.oneOf([GWEI]),
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
|
@ -14,6 +14,7 @@ export default class CurrencyInput extends PureComponent {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
conversionRate: PropTypes.number,
|
conversionRate: PropTypes.number,
|
||||||
currentCurrency: PropTypes.string,
|
currentCurrency: PropTypes.string,
|
||||||
|
nativeCurrency: PropTypes.string,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
onBlur: PropTypes.func,
|
onBlur: PropTypes.func,
|
||||||
suffix: PropTypes.string,
|
suffix: PropTypes.string,
|
||||||
@ -77,13 +78,13 @@ export default class CurrencyInput extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderConversionComponent () {
|
renderConversionComponent () {
|
||||||
const { useFiat, currentCurrency } = this.props
|
const { useFiat, currentCurrency, nativeCurrency } = this.props
|
||||||
const { hexValue } = this.state
|
const { hexValue } = this.state
|
||||||
let currency, numberOfDecimals
|
let currency, numberOfDecimals
|
||||||
|
|
||||||
if (useFiat) {
|
if (useFiat) {
|
||||||
// Display ETH
|
// Display ETH
|
||||||
currency = ETH
|
currency = nativeCurrency || ETH
|
||||||
numberOfDecimals = 6
|
numberOfDecimals = 6
|
||||||
} else {
|
} else {
|
||||||
// Display Fiat
|
// Display Fiat
|
||||||
|
@ -3,18 +3,19 @@ import CurrencyInput from './currency-input.component'
|
|||||||
import { ETH } from '../../constants/common'
|
import { ETH } from '../../constants/common'
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const { metamask: { currentCurrency, conversionRate } } = state
|
const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
nativeCurrency,
|
||||||
currentCurrency,
|
currentCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||||
const { currentCurrency } = stateProps
|
const { nativeCurrency, currentCurrency } = stateProps
|
||||||
const { useFiat } = ownProps
|
const { useFiat } = ownProps
|
||||||
const suffix = useFiat ? currentCurrency.toUpperCase() : ETH
|
const suffix = useFiat ? currentCurrency.toUpperCase() : nativeCurrency || ETH
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...stateProps,
|
...stateProps,
|
||||||
|
@ -22,6 +22,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should render properly with a suffix', () => {
|
it('should render properly with a suffix', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -32,6 +33,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<CurrencyInput
|
<CurrencyInput
|
||||||
suffix="ETH"
|
suffix="ETH"
|
||||||
|
nativeCurrency="ETH"
|
||||||
/>
|
/>
|
||||||
</Provider>
|
</Provider>
|
||||||
)
|
)
|
||||||
@ -45,6 +47,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should render properly with an ETH value', () => {
|
it('should render properly with an ETH value', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -56,6 +59,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
<CurrencyInput
|
<CurrencyInput
|
||||||
value="de0b6b3a7640000"
|
value="de0b6b3a7640000"
|
||||||
suffix="ETH"
|
suffix="ETH"
|
||||||
|
nativeCurrency="ETH"
|
||||||
currentCurrency="usd"
|
currentCurrency="usd"
|
||||||
conversionRate={231.06}
|
conversionRate={231.06}
|
||||||
/>
|
/>
|
||||||
@ -75,6 +79,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should render properly with a fiat value', () => {
|
it('should render properly with a fiat value', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -87,6 +92,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
value="f602f2234d0ea"
|
value="f602f2234d0ea"
|
||||||
suffix="USD"
|
suffix="USD"
|
||||||
useFiat
|
useFiat
|
||||||
|
nativeCurrency="ETH"
|
||||||
currentCurrency="usd"
|
currentCurrency="usd"
|
||||||
conversionRate={231.06}
|
conversionRate={231.06}
|
||||||
/>
|
/>
|
||||||
@ -116,6 +122,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should call onChange and onBlur on input changes with the hex value for ETH', () => {
|
it('should call onChange and onBlur on input changes with the hex value for ETH', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -127,6 +134,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
onChange={handleChangeSpy}
|
onChange={handleChangeSpy}
|
||||||
onBlur={handleBlurSpy}
|
onBlur={handleBlurSpy}
|
||||||
suffix="ETH"
|
suffix="ETH"
|
||||||
|
nativeCurrency="ETH"
|
||||||
currentCurrency="usd"
|
currentCurrency="usd"
|
||||||
conversionRate={231.06}
|
conversionRate={231.06}
|
||||||
/>
|
/>
|
||||||
@ -160,6 +168,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should call onChange and onBlur on input changes with the hex value for fiat', () => {
|
it('should call onChange and onBlur on input changes with the hex value for fiat', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -171,6 +180,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
onChange={handleChangeSpy}
|
onChange={handleChangeSpy}
|
||||||
onBlur={handleBlurSpy}
|
onBlur={handleBlurSpy}
|
||||||
suffix="USD"
|
suffix="USD"
|
||||||
|
nativeCurrency="ETH"
|
||||||
currentCurrency="usd"
|
currentCurrency="usd"
|
||||||
conversionRate={231.06}
|
conversionRate={231.06}
|
||||||
useFiat
|
useFiat
|
||||||
@ -205,6 +215,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
it('should change the state and pass in a new decimalValue when props.value changes', () => {
|
it('should change the state and pass in a new decimalValue when props.value changes', () => {
|
||||||
const mockStore = {
|
const mockStore = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
conversionRate: 231.06,
|
conversionRate: 231.06,
|
||||||
},
|
},
|
||||||
@ -216,6 +227,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
onChange={handleChangeSpy}
|
onChange={handleChangeSpy}
|
||||||
onBlur={handleBlurSpy}
|
onBlur={handleBlurSpy}
|
||||||
suffix="USD"
|
suffix="USD"
|
||||||
|
nativeCurrency="ETH"
|
||||||
currentCurrency="usd"
|
currentCurrency="usd"
|
||||||
conversionRate={231.06}
|
conversionRate={231.06}
|
||||||
useFiat
|
useFiat
|
||||||
|
@ -20,12 +20,14 @@ describe('CurrencyInput container', () => {
|
|||||||
metamask: {
|
metamask: {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(mapStateToProps(mockState), {
|
assert.deepEqual(mapStateToProps(mockState), {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -35,12 +37,14 @@ describe('CurrencyInput container', () => {
|
|||||||
const mockStateProps = {
|
const mockStateProps = {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
}
|
}
|
||||||
const mockDispatchProps = {}
|
const mockDispatchProps = {}
|
||||||
|
|
||||||
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, { useFiat: true }), {
|
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, { useFiat: true }), {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
useFiat: true,
|
useFiat: true,
|
||||||
suffix: 'USD',
|
suffix: 'USD',
|
||||||
})
|
})
|
||||||
@ -48,6 +52,7 @@ describe('CurrencyInput container', () => {
|
|||||||
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, {}), {
|
assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, {}), {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
currentCurrency: 'usd',
|
currentCurrency: 'usd',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
suffix: 'ETH',
|
suffix: 'ETH',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -26,14 +26,14 @@ class AccountDropdowns extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderAccounts () {
|
renderAccounts () {
|
||||||
const { identities, accounts, selected, menuItemStyles, actions, keyrings } = this.props
|
const { identities, accounts, selected, menuItemStyles, actions, keyrings, ticker } = this.props
|
||||||
|
|
||||||
return Object.keys(identities).map((key, index) => {
|
return Object.keys(identities).map((key, index) => {
|
||||||
const identity = identities[key]
|
const identity = identities[key]
|
||||||
const isSelected = identity.address === selected
|
const isSelected = identity.address === selected
|
||||||
|
|
||||||
const balanceValue = accounts[key].balance
|
const balanceValue = accounts[key].balance
|
||||||
const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...'
|
const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, true, ticker) : '...'
|
||||||
const simpleAddress = identity.address.substring(2).toLowerCase()
|
const simpleAddress = identity.address.substring(2).toLowerCase()
|
||||||
|
|
||||||
const keyring = keyrings.find((kr) => {
|
const keyring = keyrings.find((kr) => {
|
||||||
@ -421,6 +421,7 @@ AccountDropdowns.propTypes = {
|
|||||||
network: PropTypes.number,
|
network: PropTypes.number,
|
||||||
// actions.showExportPrivateKeyModal: ,
|
// actions.showExportPrivateKeyModal: ,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
|
ticker: PropTypes.string,
|
||||||
enableAccountsSelector: PropTypes.bool,
|
enableAccountsSelector: PropTypes.bool,
|
||||||
enableAccountOption: PropTypes.bool,
|
enableAccountOption: PropTypes.bool,
|
||||||
enableAccountOptions: PropTypes.bool,
|
enableAccountOptions: PropTypes.bool,
|
||||||
@ -458,6 +459,7 @@ const mapDispatchToProps = (dispatch) => {
|
|||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
return {
|
return {
|
||||||
|
ticker: state.metamask.ticker,
|
||||||
keyrings: state.metamask.keyrings,
|
keyrings: state.metamask.keyrings,
|
||||||
sidebarOpen: state.appState.sidebar.isOpen,
|
sidebarOpen: state.appState.sidebar.isOpen,
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,9 @@ const notToggleElementClassnames = [
|
|||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
return {
|
return {
|
||||||
provider: state.metamask.provider,
|
provider: state.metamask.provider,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
|
||||||
networkDropdownOpen: state.appState.networkDropdownOpen,
|
networkDropdownOpen: state.appState.networkDropdownOpen,
|
||||||
|
network: state.metamask.network,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,8 +41,8 @@ function mapDispatchToProps (dispatch) {
|
|||||||
setDefaultRpcTarget: type => {
|
setDefaultRpcTarget: type => {
|
||||||
dispatch(actions.setDefaultRpcTarget(type))
|
dispatch(actions.setDefaultRpcTarget(type))
|
||||||
},
|
},
|
||||||
setRpcTarget: (target) => {
|
setRpcTarget: (target, network, ticker, nickname) => {
|
||||||
dispatch(actions.setRpcTarget(target))
|
dispatch(actions.setRpcTarget(target, network, ticker, nickname))
|
||||||
},
|
},
|
||||||
delRpcTarget: (target) => {
|
delRpcTarget: (target) => {
|
||||||
dispatch(actions.delRpcTarget(target))
|
dispatch(actions.delRpcTarget(target))
|
||||||
@ -71,7 +72,7 @@ module.exports = compose(
|
|||||||
NetworkDropdown.prototype.render = function () {
|
NetworkDropdown.prototype.render = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
|
const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
|
||||||
const rpcList = props.frequentRpcList
|
const rpcListDetail = props.frequentRpcListDetail
|
||||||
const isOpen = this.props.networkDropdownOpen
|
const isOpen = this.props.networkDropdownOpen
|
||||||
const dropdownMenuItemStyle = {
|
const dropdownMenuItemStyle = {
|
||||||
fontSize: '16px',
|
fontSize: '16px',
|
||||||
@ -225,7 +226,7 @@ NetworkDropdown.prototype.render = function () {
|
|||||||
),
|
),
|
||||||
|
|
||||||
this.renderCustomOption(props.provider),
|
this.renderCustomOption(props.provider),
|
||||||
this.renderCommonRpc(rpcList, props.provider),
|
this.renderCommonRpc(rpcListDetail, props.provider),
|
||||||
|
|
||||||
h(
|
h(
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
@ -267,28 +268,33 @@ NetworkDropdown.prototype.getNetworkName = function () {
|
|||||||
} else if (providerName === 'rinkeby') {
|
} else if (providerName === 'rinkeby') {
|
||||||
name = this.context.t('rinkeby')
|
name = this.context.t('rinkeby')
|
||||||
} else {
|
} else {
|
||||||
name = this.context.t('unknownNetwork')
|
name = provider.nickname || this.context.t('unknownNetwork')
|
||||||
}
|
}
|
||||||
|
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
|
NetworkDropdown.prototype.renderCommonRpc = function (rpcListDetail, provider) {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const reversedRpcList = rpcList.slice().reverse()
|
const reversedRpcListDetail = rpcListDetail.slice().reverse()
|
||||||
|
const network = props.network
|
||||||
|
|
||||||
return reversedRpcList.map((rpc) => {
|
return reversedRpcListDetail.map((entry) => {
|
||||||
|
const rpc = entry.rpcUrl
|
||||||
|
const ticker = entry.ticker || 'ETH'
|
||||||
|
const nickname = entry.nickname || ''
|
||||||
const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget
|
const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget
|
||||||
|
|
||||||
if ((rpc === 'http://localhost:8545') || currentRpcTarget) {
|
if ((rpc === 'http://localhost:8545') || currentRpcTarget) {
|
||||||
return null
|
return null
|
||||||
} else {
|
} else {
|
||||||
|
const chainId = entry.chainId || network
|
||||||
return h(
|
return h(
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
{
|
{
|
||||||
key: `common${rpc}`,
|
key: `common${rpc}`,
|
||||||
closeMenu: () => this.props.hideNetworkDropdown(),
|
closeMenu: () => this.props.hideNetworkDropdown(),
|
||||||
onClick: () => props.setRpcTarget(rpc),
|
onClick: () => props.setRpcTarget(rpc, chainId, ticker, nickname),
|
||||||
style: {
|
style: {
|
||||||
fontSize: '16px',
|
fontSize: '16px',
|
||||||
lineHeight: '20px',
|
lineHeight: '20px',
|
||||||
@ -302,7 +308,7 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
|
|||||||
style: {
|
style: {
|
||||||
color: currentRpcTarget ? '#ffffff' : '#9b9b9b',
|
color: currentRpcTarget ? '#ffffff' : '#9b9b9b',
|
||||||
},
|
},
|
||||||
}, rpc),
|
}, nickname || rpc),
|
||||||
h('i.fa.fa-times.delete',
|
h('i.fa.fa-times.delete',
|
||||||
{
|
{
|
||||||
onClick: (e) => {
|
onClick: (e) => {
|
||||||
@ -317,8 +323,9 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkDropdown.prototype.renderCustomOption = function (provider) {
|
NetworkDropdown.prototype.renderCustomOption = function (provider) {
|
||||||
const { rpcTarget, type } = provider
|
const { rpcTarget, type, ticker, nickname } = provider
|
||||||
const props = this.props
|
const props = this.props
|
||||||
|
const network = props.network
|
||||||
|
|
||||||
if (type !== 'rpc') return null
|
if (type !== 'rpc') return null
|
||||||
|
|
||||||
@ -332,7 +339,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
{
|
{
|
||||||
key: rpcTarget,
|
key: rpcTarget,
|
||||||
onClick: () => props.setRpcTarget(rpcTarget),
|
onClick: () => props.setRpcTarget(rpcTarget, network, ticker, nickname),
|
||||||
closeMenu: () => this.props.hideNetworkDropdown(),
|
closeMenu: () => this.props.hideNetworkDropdown(),
|
||||||
style: {
|
style: {
|
||||||
fontSize: '16px',
|
fontSize: '16px',
|
||||||
@ -347,7 +354,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) {
|
|||||||
style: {
|
style: {
|
||||||
color: '#ffffff',
|
color: '#ffffff',
|
||||||
},
|
},
|
||||||
}, rpcTarget),
|
}, nickname || rpcTarget),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ describe('Network Dropdown', () => {
|
|||||||
provider: {
|
provider: {
|
||||||
'type': 'test',
|
'type': 'test',
|
||||||
},
|
},
|
||||||
frequentRpcList: [
|
frequentRpcListDetail: [
|
||||||
'http://localhost:7545',
|
{ rpcUrl: 'http://localhost:7545' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
appState: {
|
appState: {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const { Component } = require('react')
|
const { Component } = require('react')
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
|
const connect = require('react-redux').connect
|
||||||
const { inherits } = require('util')
|
const { inherits } = require('util')
|
||||||
const {
|
const {
|
||||||
formatBalance,
|
formatBalance,
|
||||||
@ -8,7 +9,12 @@ const {
|
|||||||
const Tooltip = require('./tooltip.js')
|
const Tooltip = require('./tooltip.js')
|
||||||
const FiatValue = require('./fiat-value.js')
|
const FiatValue = require('./fiat-value.js')
|
||||||
|
|
||||||
module.exports = EthBalanceComponent
|
module.exports = connect(mapStateToProps)(EthBalanceComponent)
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
return {
|
||||||
|
ticker: state.metamask.ticker,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inherits(EthBalanceComponent, Component)
|
inherits(EthBalanceComponent, Component)
|
||||||
function EthBalanceComponent () {
|
function EthBalanceComponent () {
|
||||||
@ -17,9 +23,9 @@ function EthBalanceComponent () {
|
|||||||
|
|
||||||
EthBalanceComponent.prototype.render = function () {
|
EthBalanceComponent.prototype.render = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { value, style, width, needsParse = true } = props
|
const { ticker, value, style, width, needsParse = true } = props
|
||||||
|
|
||||||
const formattedValue = value ? formatBalance(value, 6, needsParse) : '...'
|
const formattedValue = value ? formatBalance(value, 6, needsParse, ticker) : '...'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ export default class NetworkDisplay extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { network, provider: { type } } = this.props
|
const { network, provider: { type, nickname } } = this.props
|
||||||
const networkClass = networkToClassHash[network]
|
const networkClass = networkToClassHash[network]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -61,7 +61,7 @@ export default class NetworkDisplay extends Component {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
<div className="network-display__name">
|
<div className="network-display__name">
|
||||||
{ this.context.t(type) }
|
{ type === 'rpc' && nickname ? nickname : this.context.t(type) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -23,9 +23,10 @@ Network.prototype.render = function () {
|
|||||||
const props = this.props
|
const props = this.props
|
||||||
const context = this.context
|
const context = this.context
|
||||||
const networkNumber = props.network
|
const networkNumber = props.network
|
||||||
let providerName
|
let providerName, providerNick
|
||||||
try {
|
try {
|
||||||
providerName = props.provider.type
|
providerName = props.provider.type
|
||||||
|
providerNick = props.provider.nickname || ''
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
providerName = null
|
providerName = null
|
||||||
}
|
}
|
||||||
@ -131,7 +132,7 @@ Network.prototype.render = function () {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
h('.network-name', context.t('privateNetwork')),
|
h('.network-name', providerNick || context.t('privateNetwork')),
|
||||||
h('i.fa.fa-chevron-down.fa-lg.network-caret'),
|
h('i.fa.fa-chevron-down.fa-lg.network-caret'),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,9 @@
|
|||||||
color: $crimson;
|
color: $crimson;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__rpc-save-button {
|
&__advanced-link {
|
||||||
align-self: flex-end;
|
color: $curious-blue;
|
||||||
padding: 5px;
|
padding-left: 5px;
|
||||||
text-transform: uppercase;
|
|
||||||
color: $dusty-gray;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__rpc-save-button {
|
&__rpc-save-button {
|
||||||
@ -19,6 +16,9 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: $dusty-gray;
|
color: $dusty-gray;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 25%;
|
||||||
|
min-width: 80px;
|
||||||
|
height: 33px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__button--red {
|
&__button--red {
|
||||||
|
@ -55,12 +55,17 @@ export default class SettingsTab extends PureComponent {
|
|||||||
sendHexData: PropTypes.bool,
|
sendHexData: PropTypes.bool,
|
||||||
currentCurrency: PropTypes.string,
|
currentCurrency: PropTypes.string,
|
||||||
conversionDate: PropTypes.number,
|
conversionDate: PropTypes.number,
|
||||||
useETHAsPrimaryCurrency: PropTypes.bool,
|
nativeCurrency: PropTypes.string,
|
||||||
setUseETHAsPrimaryCurrencyPreference: PropTypes.func,
|
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
|
||||||
|
setUseNativeCurrencyAsPrimaryCurrencyPreference: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
newRpc: '',
|
newRpc: '',
|
||||||
|
chainId: '',
|
||||||
|
showOptions: false,
|
||||||
|
ticker: '',
|
||||||
|
nickname: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCurrentConversion () {
|
renderCurrentConversion () {
|
||||||
@ -121,37 +126,98 @@ export default class SettingsTab extends PureComponent {
|
|||||||
|
|
||||||
renderNewRpcUrl () {
|
renderNewRpcUrl () {
|
||||||
const { t } = this.context
|
const { t } = this.context
|
||||||
const { newRpc } = this.state
|
const { newRpc, chainId, ticker, nickname } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-page__content-row">
|
<div className="settings-page__content-row">
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<span>{ t('newRPC') }</span>
|
<span>{ t('newNetwork') }</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<div className="settings-page__content-item-col">
|
<div className="settings-page__content-item-col">
|
||||||
<TextField
|
<TextField
|
||||||
type="text"
|
type="text"
|
||||||
id="new-rpc"
|
id="new-rpc"
|
||||||
placeholder={t('newRPC')}
|
placeholder={t('rpcURL')}
|
||||||
value={newRpc}
|
value={newRpc}
|
||||||
onChange={e => this.setState({ newRpc: e.target.value })}
|
onChange={e => this.setState({ newRpc: e.target.value })}
|
||||||
onKeyPress={e => {
|
onKeyPress={e => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
this.validateRpc(newRpc)
|
this.validateRpc(newRpc, chainId, ticker, nickname)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="none"
|
margin="dense"
|
||||||
/>
|
/>
|
||||||
<div
|
<TextField
|
||||||
className="settings-tab__rpc-save-button"
|
type="text"
|
||||||
onClick={e => {
|
id="chainid"
|
||||||
e.preventDefault()
|
placeholder={t('optionalChainId')}
|
||||||
this.validateRpc(newRpc)
|
value={chainId}
|
||||||
|
onChange={e => this.setState({ chainId: e.target.value })}
|
||||||
|
onKeyPress={e => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
this.validateRpc(newRpc, chainId, ticker, nickname)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
style={{
|
||||||
{ t('save') }
|
display: this.state.showOptions ? null : 'none',
|
||||||
|
}}
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
type="text"
|
||||||
|
id="ticker"
|
||||||
|
placeholder={t('optionalSymbol')}
|
||||||
|
value={ticker}
|
||||||
|
onChange={e => this.setState({ ticker: e.target.value })}
|
||||||
|
onKeyPress={e => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
this.validateRpc(newRpc, chainId, ticker, nickname)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
display: this.state.showOptions ? null : 'none',
|
||||||
|
}}
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
type="text"
|
||||||
|
id="nickname"
|
||||||
|
placeholder={t('optionalNickname')}
|
||||||
|
value={nickname}
|
||||||
|
onChange={e => this.setState({ nickname: e.target.value })}
|
||||||
|
onKeyPress={e => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
this.validateRpc(newRpc, chainId, ticker, nickname)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
display: this.state.showOptions ? null : 'none',
|
||||||
|
}}
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
/>
|
||||||
|
<div className="flex-row flex-align-center space-between">
|
||||||
|
<span className="settings-tab__advanced-link"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
this.setState({ showOptions: !this.state.showOptions })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ t(this.state.showOptions ? 'hideAdvancedOptions' : 'showAdvancedOptions') }
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
className="button btn-primary settings-tab__rpc-save-button"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
this.validateRpc(newRpc, chainId, ticker, nickname)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ t('save') }
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -159,11 +225,11 @@ export default class SettingsTab extends PureComponent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
validateRpc (newRpc) {
|
validateRpc (newRpc, chainId, ticker = 'ETH', nickname) {
|
||||||
const { setRpcTarget, displayWarning } = this.props
|
const { setRpcTarget, displayWarning } = this.props
|
||||||
|
|
||||||
if (validUrl.isWebUri(newRpc)) {
|
if (validUrl.isWebUri(newRpc)) {
|
||||||
setRpcTarget(newRpc)
|
setRpcTarget(newRpc, chainId, ticker, nickname)
|
||||||
} else {
|
} else {
|
||||||
const appendedRpc = `http://${newRpc}`
|
const appendedRpc = `http://${newRpc}`
|
||||||
|
|
||||||
@ -341,9 +407,13 @@ export default class SettingsTab extends PureComponent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUseEthAsPrimaryCurrency () {
|
renderUsePrimaryCurrencyOptions () {
|
||||||
const { t } = this.context
|
const { t } = this.context
|
||||||
const { useETHAsPrimaryCurrency, setUseETHAsPrimaryCurrencyPreference } = this.props
|
const {
|
||||||
|
nativeCurrency,
|
||||||
|
setUseNativeCurrencyAsPrimaryCurrencyPreference,
|
||||||
|
useNativeCurrencyAsPrimaryCurrency,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-page__content-row">
|
<div className="settings-page__content-row">
|
||||||
@ -359,23 +429,23 @@ export default class SettingsTab extends PureComponent {
|
|||||||
<div className="settings-tab__radio-button">
|
<div className="settings-tab__radio-button">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
id="eth-primary-currency"
|
id="native-primary-currency"
|
||||||
onChange={() => setUseETHAsPrimaryCurrencyPreference(true)}
|
onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(true)}
|
||||||
checked={Boolean(useETHAsPrimaryCurrency)}
|
checked={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
htmlFor="eth-primary-currency"
|
htmlFor="native-primary-currency"
|
||||||
className="settings-tab__radio-label"
|
className="settings-tab__radio-label"
|
||||||
>
|
>
|
||||||
{ t('eth') }
|
{ nativeCurrency }
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="settings-tab__radio-button">
|
<div className="settings-tab__radio-button">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
id="fiat-primary-currency"
|
id="fiat-primary-currency"
|
||||||
onChange={() => setUseETHAsPrimaryCurrencyPreference(false)}
|
onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(false)}
|
||||||
checked={!useETHAsPrimaryCurrency}
|
checked={!useNativeCurrencyAsPrimaryCurrency}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
htmlFor="fiat-primary-currency"
|
htmlFor="fiat-primary-currency"
|
||||||
@ -398,7 +468,7 @@ export default class SettingsTab extends PureComponent {
|
|||||||
<div className="settings-page__content">
|
<div className="settings-page__content">
|
||||||
{ warning && <div className="settings-tab__error">{ warning }</div> }
|
{ warning && <div className="settings-tab__error">{ warning }</div> }
|
||||||
{ this.renderCurrentConversion() }
|
{ this.renderCurrentConversion() }
|
||||||
{ this.renderUseEthAsPrimaryCurrency() }
|
{ this.renderUsePrimaryCurrencyOptions() }
|
||||||
{ this.renderCurrentLocale() }
|
{ this.renderCurrentLocale() }
|
||||||
{ this.renderNewRpcUrl() }
|
{ this.renderNewRpcUrl() }
|
||||||
{ this.renderStateLogs() }
|
{ this.renderStateLogs() }
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
updateCurrentLocale,
|
updateCurrentLocale,
|
||||||
setFeatureFlag,
|
setFeatureFlag,
|
||||||
showModal,
|
showModal,
|
||||||
setUseETHAsPrimaryCurrencyPreference,
|
setUseNativeCurrencyAsPrimaryCurrencyPreference,
|
||||||
} from '../../../../actions'
|
} from '../../../../actions'
|
||||||
import { preferencesSelector } from '../../../../selectors'
|
import { preferencesSelector } from '../../../../selectors'
|
||||||
|
|
||||||
@ -20,13 +20,14 @@ const mapStateToProps = state => {
|
|||||||
const {
|
const {
|
||||||
currentCurrency,
|
currentCurrency,
|
||||||
conversionDate,
|
conversionDate,
|
||||||
|
nativeCurrency,
|
||||||
useBlockie,
|
useBlockie,
|
||||||
featureFlags: { sendHexData } = {},
|
featureFlags: { sendHexData } = {},
|
||||||
provider = {},
|
provider = {},
|
||||||
isMascara,
|
isMascara,
|
||||||
currentLocale,
|
currentLocale,
|
||||||
} = metamask
|
} = metamask
|
||||||
const { useETHAsPrimaryCurrency } = preferencesSelector(state)
|
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
warning,
|
warning,
|
||||||
@ -34,17 +35,18 @@ const mapStateToProps = state => {
|
|||||||
currentLocale,
|
currentLocale,
|
||||||
currentCurrency,
|
currentCurrency,
|
||||||
conversionDate,
|
conversionDate,
|
||||||
|
nativeCurrency,
|
||||||
useBlockie,
|
useBlockie,
|
||||||
sendHexData,
|
sendHexData,
|
||||||
provider,
|
provider,
|
||||||
useETHAsPrimaryCurrency,
|
useNativeCurrencyAsPrimaryCurrency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => {
|
||||||
return {
|
return {
|
||||||
setCurrentCurrency: currency => dispatch(setCurrentCurrency(currency)),
|
setCurrentCurrency: currency => dispatch(setCurrentCurrency(currency)),
|
||||||
setRpcTarget: newRpc => dispatch(setRpcTarget(newRpc)),
|
setRpcTarget: (newRpc, chainId, ticker, nickname) => dispatch(setRpcTarget(newRpc, chainId, ticker, nickname)),
|
||||||
displayWarning: warning => dispatch(displayWarning(warning)),
|
displayWarning: warning => dispatch(displayWarning(warning)),
|
||||||
revealSeedConfirmation: () => dispatch(revealSeedConfirmation()),
|
revealSeedConfirmation: () => dispatch(revealSeedConfirmation()),
|
||||||
setUseBlockie: value => dispatch(setUseBlockie(value)),
|
setUseBlockie: value => dispatch(setUseBlockie(value)),
|
||||||
@ -54,8 +56,8 @@ const mapDispatchToProps = dispatch => {
|
|||||||
},
|
},
|
||||||
setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)),
|
setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)),
|
||||||
showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })),
|
showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })),
|
||||||
setUseETHAsPrimaryCurrencyPreference: value => {
|
setUseNativeCurrencyAsPrimaryCurrencyPreference: value => {
|
||||||
return dispatch(setUseETHAsPrimaryCurrencyPreference(value))
|
return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { connect } from 'react-redux'
|
|||||||
import {
|
import {
|
||||||
getConversionRate,
|
getConversionRate,
|
||||||
getCurrentCurrency,
|
getCurrentCurrency,
|
||||||
|
getNativeCurrency,
|
||||||
} from '../send.selectors.js'
|
} from '../send.selectors.js'
|
||||||
import AccountListItem from './account-list-item.component'
|
import AccountListItem from './account-list-item.component'
|
||||||
|
|
||||||
@ -11,5 +12,6 @@ function mapStateToProps (state) {
|
|||||||
return {
|
return {
|
||||||
conversionRate: getConversionRate(state),
|
conversionRate: getConversionRate(state),
|
||||||
currentCurrency: getCurrentCurrency(state),
|
currentCurrency: getCurrentCurrency(state),
|
||||||
|
nativeCurrency: getNativeCurrency(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ describe('AccountListItem Component', function () {
|
|||||||
className={'mockClassName'}
|
className={'mockClassName'}
|
||||||
conversionRate={4}
|
conversionRate={4}
|
||||||
currentCurrency={'mockCurrentyCurrency'}
|
currentCurrency={'mockCurrentyCurrency'}
|
||||||
|
nativeCurrency={'ETH'}
|
||||||
displayAddress={false}
|
displayAddress={false}
|
||||||
displayBalance={false}
|
displayBalance={false}
|
||||||
handleClick={propsMethodSpies.handleClick}
|
handleClick={propsMethodSpies.handleClick}
|
||||||
|
@ -13,6 +13,7 @@ proxyquire('../account-list-item.container.js', {
|
|||||||
'../send.selectors.js': {
|
'../send.selectors.js': {
|
||||||
getConversionRate: (s) => `mockConversionRate:${s}`,
|
getConversionRate: (s) => `mockConversionRate:${s}`,
|
||||||
getCurrentCurrency: (s) => `mockCurrentCurrency:${s}`,
|
getCurrentCurrency: (s) => `mockCurrentCurrency:${s}`,
|
||||||
|
getNativeCurrency: (s) => `mockNativeCurrency:${s}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ describe('account-list-item container', () => {
|
|||||||
assert.deepEqual(mapStateToProps('mockState'), {
|
assert.deepEqual(mapStateToProps('mockState'), {
|
||||||
conversionRate: 'mockConversionRate:mockState',
|
conversionRate: 'mockConversionRate:mockState',
|
||||||
currentCurrency: 'mockCurrentCurrency:mockState',
|
currentCurrency: 'mockCurrentCurrency:mockState',
|
||||||
|
nativeCurrency: 'mockNativeCurrency:mockState',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const selectors = {
|
|||||||
getCurrentNetwork,
|
getCurrentNetwork,
|
||||||
getCurrentViewContext,
|
getCurrentViewContext,
|
||||||
getForceGasMin,
|
getForceGasMin,
|
||||||
|
getNativeCurrency,
|
||||||
getGasLimit,
|
getGasLimit,
|
||||||
getGasPrice,
|
getGasPrice,
|
||||||
getGasPriceFromRecentBlocks,
|
getGasPriceFromRecentBlocks,
|
||||||
@ -111,6 +112,10 @@ function getCurrentCurrency (state) {
|
|||||||
return state.metamask.currentCurrency
|
return state.metamask.currentCurrency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNativeCurrency (state) {
|
||||||
|
return state.metamask.nativeCurrency
|
||||||
|
}
|
||||||
|
|
||||||
function getCurrentNetwork (state) {
|
function getCurrentNetwork (state) {
|
||||||
return state.metamask.network
|
return state.metamask.network
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ module.exports = {
|
|||||||
'currentCurrency': 'USD',
|
'currentCurrency': 'USD',
|
||||||
'conversionRate': 1200.88200327,
|
'conversionRate': 1200.88200327,
|
||||||
'conversionDate': 1489013762,
|
'conversionDate': 1489013762,
|
||||||
|
'nativeCurrency': 'ETH',
|
||||||
'noActiveNotices': true,
|
'noActiveNotices': true,
|
||||||
'frequentRpcList': [],
|
'frequentRpcList': [],
|
||||||
'network': '3',
|
'network': '3',
|
||||||
|
@ -12,6 +12,7 @@ const {
|
|||||||
getCurrentCurrency,
|
getCurrentCurrency,
|
||||||
getCurrentNetwork,
|
getCurrentNetwork,
|
||||||
getCurrentViewContext,
|
getCurrentViewContext,
|
||||||
|
getNativeCurrency,
|
||||||
getForceGasMin,
|
getForceGasMin,
|
||||||
getGasLimit,
|
getGasLimit,
|
||||||
getGasPrice,
|
getGasPrice,
|
||||||
@ -178,6 +179,15 @@ describe('send selectors', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('getNativeCurrency()', () => {
|
||||||
|
it('should return the ticker symbol of the selected network', () => {
|
||||||
|
assert.equal(
|
||||||
|
getNativeCurrency(mockState),
|
||||||
|
'ETH'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('getCurrentNetwork()', () => {
|
describe('getCurrentNetwork()', () => {
|
||||||
it('should return the id of the currently selected network', () => {
|
it('should return the id of the currently selected network', () => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
@ -18,10 +18,11 @@ describe('TransactionActivityLog container', () => {
|
|||||||
const mockState = {
|
const mockState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
conversionRate: 280.45,
|
conversionRate: 280.45,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45 })
|
assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,6 @@ import classnames from 'classnames'
|
|||||||
import { getActivities } from './transaction-activity-log.util'
|
import { getActivities } from './transaction-activity-log.util'
|
||||||
import Card from '../card'
|
import Card from '../card'
|
||||||
import { getEthConversionFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util'
|
import { getEthConversionFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util'
|
||||||
import { ETH } from '../../constants/common'
|
|
||||||
import { formatDate } from '../../util'
|
import { formatDate } from '../../util'
|
||||||
|
|
||||||
export default class TransactionActivityLog extends PureComponent {
|
export default class TransactionActivityLog extends PureComponent {
|
||||||
@ -16,6 +15,7 @@ export default class TransactionActivityLog extends PureComponent {
|
|||||||
transaction: PropTypes.object,
|
transaction: PropTypes.object,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
conversionRate: PropTypes.number,
|
conversionRate: PropTypes.number,
|
||||||
|
nativeCurrency: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -45,16 +45,17 @@ export default class TransactionActivityLog extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderActivity (activity, index) {
|
renderActivity (activity, index) {
|
||||||
const { conversionRate } = this.props
|
const { conversionRate, nativeCurrency } = this.props
|
||||||
const { eventKey, value, timestamp } = activity
|
const { eventKey, value, timestamp } = activity
|
||||||
const ethValue = index === 0
|
const ethValue = index === 0
|
||||||
? `${getValueFromWeiHex({
|
? `${getValueFromWeiHex({
|
||||||
value,
|
value,
|
||||||
toCurrency: ETH,
|
fromCurrency: nativeCurrency,
|
||||||
|
toCurrency: nativeCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
numberOfDecimals: 6,
|
numberOfDecimals: 6,
|
||||||
})} ${ETH}`
|
})} ${nativeCurrency}`
|
||||||
: getEthConversionFromWeiHex({ value, toCurrency: ETH, conversionRate })
|
: getEthConversionFromWeiHex({ value, fromCurrency: nativeCurrency, conversionRate })
|
||||||
const formattedTimestamp = formatDate(timestamp)
|
const formattedTimestamp = formatDate(timestamp)
|
||||||
const activityText = this.context.t(eventKey, [ethValue, formattedTimestamp])
|
const activityText = this.context.t(eventKey, [ethValue, formattedTimestamp])
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import TransactionActivityLog from './transaction-activity-log.component'
|
import TransactionActivityLog from './transaction-activity-log.component'
|
||||||
import { conversionRateSelector } from '../../selectors'
|
import { conversionRateSelector, getNativeCurrency } from '../../selectors'
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
conversionRate: conversionRateSelector(state),
|
conversionRate: conversionRateSelector(state),
|
||||||
|
nativeCurrency: getNativeCurrency(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
export { default } from './transaction-breakdown.component'
|
export { default } from './transaction-breakdown.container'
|
||||||
|
@ -6,7 +6,7 @@ import Card from '../card'
|
|||||||
import CurrencyDisplay from '../currency-display'
|
import CurrencyDisplay from '../currency-display'
|
||||||
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
|
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
|
||||||
import HexToDecimal from '../hex-to-decimal'
|
import HexToDecimal from '../hex-to-decimal'
|
||||||
import { ETH, GWEI, PRIMARY, SECONDARY } from '../../constants/common'
|
import { GWEI, PRIMARY, SECONDARY } from '../../constants/common'
|
||||||
import { getHexGasTotal } from '../../helpers/confirm-transaction/util'
|
import { getHexGasTotal } from '../../helpers/confirm-transaction/util'
|
||||||
import { sumHexes } from '../../helpers/transactions.util'
|
import { sumHexes } from '../../helpers/transactions.util'
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ export default class TransactionBreakdown extends PureComponent {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
transaction: PropTypes.object,
|
transaction: PropTypes.object,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
|
nativeCurrency: PropTypes.string.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -26,7 +27,7 @@ export default class TransactionBreakdown extends PureComponent {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { t } = this.context
|
const { t } = this.context
|
||||||
const { transaction, className } = this.props
|
const { transaction, className, nativeCurrency } = 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
|
||||||
@ -72,7 +73,7 @@ export default class TransactionBreakdown extends PureComponent {
|
|||||||
<TransactionBreakdownRow title={t('gasPrice')}>
|
<TransactionBreakdownRow title={t('gasPrice')}>
|
||||||
<CurrencyDisplay
|
<CurrencyDisplay
|
||||||
className="transaction-breakdown__value"
|
className="transaction-breakdown__value"
|
||||||
currency={ETH}
|
currency={nativeCurrency}
|
||||||
denomination={GWEI}
|
denomination={GWEI}
|
||||||
value={gasPrice}
|
value={gasPrice}
|
||||||
hideLabel
|
hideLabel
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
import { connect } from 'react-redux'
|
||||||
|
import TransactionBreakdown from './transaction-breakdown.component'
|
||||||
|
import { getNativeCurrency } from '../../selectors'
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return {
|
||||||
|
nativeCurrency: getNativeCurrency(state),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(TransactionBreakdown)
|
@ -2,7 +2,7 @@ import { connect } from 'react-redux'
|
|||||||
import { withRouter } from 'react-router-dom'
|
import { withRouter } from 'react-router-dom'
|
||||||
import { compose } from 'recompose'
|
import { compose } from 'recompose'
|
||||||
import TransactionViewBalance from './transaction-view-balance.component'
|
import TransactionViewBalance from './transaction-view-balance.component'
|
||||||
import { getSelectedToken, getSelectedAddress, getSelectedTokenAssetImage } from '../../selectors'
|
import { getSelectedToken, getSelectedAddress, getNativeCurrency, getSelectedTokenAssetImage } from '../../selectors'
|
||||||
import { showModal } from '../../actions'
|
import { showModal } from '../../actions'
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
@ -15,6 +15,7 @@ const mapStateToProps = state => {
|
|||||||
selectedToken: getSelectedToken(state),
|
selectedToken: getSelectedToken(state),
|
||||||
network,
|
network,
|
||||||
balance,
|
balance,
|
||||||
|
nativeCurrency: getNativeCurrency(state),
|
||||||
assetImage: getSelectedTokenAssetImage(state),
|
assetImage: getSelectedTokenAssetImage(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,16 @@ describe('UserPreferencedCurrencyDisplay container', () => {
|
|||||||
it('should return the correct props', () => {
|
it('should return the correct props', () => {
|
||||||
const mockState = {
|
const mockState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
preferences: {
|
preferences: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(mapStateToProps(mockState), {
|
assert.deepEqual(mapStateToProps(mockState), {
|
||||||
useETHAsPrimaryCurrency: true,
|
nativeCurrency: 'ETH',
|
||||||
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -37,33 +39,38 @@ describe('UserPreferencedCurrencyDisplay container', () => {
|
|||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
stateProps: {
|
stateProps: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
ownProps: {
|
ownProps: {
|
||||||
type: 'PRIMARY',
|
type: 'PRIMARY',
|
||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
currency: 'ETH',
|
currency: 'ETH',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
numberOfDecimals: 6,
|
numberOfDecimals: 6,
|
||||||
prefix: undefined,
|
prefix: undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stateProps: {
|
stateProps: {
|
||||||
useETHAsPrimaryCurrency: false,
|
useNativeCurrencyAsPrimaryCurrency: false,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
ownProps: {
|
ownProps: {
|
||||||
type: 'PRIMARY',
|
type: 'PRIMARY',
|
||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
currency: undefined,
|
currency: undefined,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
numberOfDecimals: 2,
|
numberOfDecimals: 2,
|
||||||
prefix: undefined,
|
prefix: undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
stateProps: {
|
stateProps: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
ownProps: {
|
ownProps: {
|
||||||
type: 'SECONDARY',
|
type: 'SECONDARY',
|
||||||
@ -71,6 +78,7 @@ describe('UserPreferencedCurrencyDisplay container', () => {
|
|||||||
fiatPrefix: '-',
|
fiatPrefix: '-',
|
||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
currency: undefined,
|
currency: undefined,
|
||||||
numberOfDecimals: 4,
|
numberOfDecimals: 4,
|
||||||
prefix: '-',
|
prefix: '-',
|
||||||
@ -78,7 +86,8 @@ describe('UserPreferencedCurrencyDisplay container', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
stateProps: {
|
stateProps: {
|
||||||
useETHAsPrimaryCurrency: false,
|
useNativeCurrencyAsPrimaryCurrency: false,
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
},
|
},
|
||||||
ownProps: {
|
ownProps: {
|
||||||
type: 'SECONDARY',
|
type: 'SECONDARY',
|
||||||
@ -89,6 +98,7 @@ describe('UserPreferencedCurrencyDisplay container', () => {
|
|||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
currency: 'ETH',
|
currency: 'ETH',
|
||||||
|
nativeCurrency: 'ETH',
|
||||||
numberOfDecimals: 3,
|
numberOfDecimals: 3,
|
||||||
prefix: 'b',
|
prefix: 'b',
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@ export default class UserPreferencedCurrencyDisplay extends PureComponent {
|
|||||||
fiatPrefix: PropTypes.string,
|
fiatPrefix: PropTypes.string,
|
||||||
// From container
|
// From container
|
||||||
currency: PropTypes.string,
|
currency: PropTypes.string,
|
||||||
|
nativeCurrency: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEthLogo () {
|
renderEthLogo () {
|
||||||
|
@ -4,15 +4,16 @@ import { preferencesSelector } 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 { useETHAsPrimaryCurrency } = preferencesSelector(state)
|
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
useETHAsPrimaryCurrency,
|
useNativeCurrencyAsPrimaryCurrency,
|
||||||
|
nativeCurrency: state.metamask.nativeCurrency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||||
const { useETHAsPrimaryCurrency, ...restStateProps } = stateProps
|
const { useNativeCurrencyAsPrimaryCurrency, nativeCurrency, ...restStateProps } = stateProps
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
numberOfDecimals: propsNumberOfDecimals,
|
numberOfDecimals: propsNumberOfDecimals,
|
||||||
@ -26,14 +27,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
|
|
||||||
let currency, numberOfDecimals, prefix
|
let currency, numberOfDecimals, prefix
|
||||||
|
|
||||||
if (type === PRIMARY && useETHAsPrimaryCurrency ||
|
if (type === PRIMARY && useNativeCurrencyAsPrimaryCurrency ||
|
||||||
type === SECONDARY && !useETHAsPrimaryCurrency) {
|
type === SECONDARY && !useNativeCurrencyAsPrimaryCurrency) {
|
||||||
// Display ETH
|
// Display ETH
|
||||||
currency = ETH
|
currency = nativeCurrency || ETH
|
||||||
numberOfDecimals = propsNumberOfDecimals || ethNumberOfDecimals || 6
|
numberOfDecimals = propsNumberOfDecimals || ethNumberOfDecimals || 6
|
||||||
prefix = propsPrefix || ethPrefix
|
prefix = propsPrefix || ethPrefix
|
||||||
} else if (type === SECONDARY && useETHAsPrimaryCurrency ||
|
} else if (type === SECONDARY && useNativeCurrencyAsPrimaryCurrency ||
|
||||||
type === PRIMARY && !useETHAsPrimaryCurrency) {
|
type === PRIMARY && !useNativeCurrencyAsPrimaryCurrency) {
|
||||||
// Display Fiat
|
// Display Fiat
|
||||||
numberOfDecimals = propsNumberOfDecimals || fiatNumberOfDecimals || 2
|
numberOfDecimals = propsNumberOfDecimals || fiatNumberOfDecimals || 2
|
||||||
prefix = propsPrefix || fiatPrefix
|
prefix = propsPrefix || fiatPrefix
|
||||||
@ -43,6 +44,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
...restStateProps,
|
...restStateProps,
|
||||||
...dispatchProps,
|
...dispatchProps,
|
||||||
...restOwnProps,
|
...restOwnProps,
|
||||||
|
nativeCurrency,
|
||||||
currency,
|
currency,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
prefix,
|
prefix,
|
||||||
|
@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => {
|
|||||||
assert.equal(wrapper.find(CurrencyInput).length, 1)
|
assert.equal(wrapper.find(CurrencyInput).length, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render useFiat for CurrencyInput based on preferences.useETHAsPrimaryCurrency', () => {
|
it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<UserPreferencedCurrencyInput
|
<UserPreferencedCurrencyInput
|
||||||
useETHAsPrimaryCurrency
|
useNativeCurrencyAsPrimaryCurrency
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.ok(wrapper)
|
assert.ok(wrapper)
|
||||||
assert.equal(wrapper.find(CurrencyInput).length, 1)
|
assert.equal(wrapper.find(CurrencyInput).length, 1)
|
||||||
assert.equal(wrapper.find(CurrencyInput).props().useFiat, false)
|
assert.equal(wrapper.find(CurrencyInput).props().useFiat, false)
|
||||||
wrapper.setProps({ useETHAsPrimaryCurrency: false })
|
wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false })
|
||||||
assert.equal(wrapper.find(CurrencyInput).props().useFiat, true)
|
assert.equal(wrapper.find(CurrencyInput).props().useFiat, true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -18,13 +18,13 @@ describe('UserPreferencedCurrencyInput container', () => {
|
|||||||
const mockState = {
|
const mockState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
preferences: {
|
preferences: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(mapStateToProps(mockState), {
|
assert.deepEqual(mapStateToProps(mockState), {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -4,16 +4,16 @@ import CurrencyInput from '../currency-input'
|
|||||||
|
|
||||||
export default class UserPreferencedCurrencyInput extends PureComponent {
|
export default class UserPreferencedCurrencyInput extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
useETHAsPrimaryCurrency: PropTypes.bool,
|
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { useETHAsPrimaryCurrency, ...restProps } = this.props
|
const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CurrencyInput
|
<CurrencyInput
|
||||||
{...restProps}
|
{...restProps}
|
||||||
useFiat={!useETHAsPrimaryCurrency}
|
useFiat={!useNativeCurrencyAsPrimaryCurrency}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ import UserPreferencedCurrencyInput from './user-preferenced-currency-input.comp
|
|||||||
import { preferencesSelector } from '../../selectors'
|
import { preferencesSelector } from '../../selectors'
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const { useETHAsPrimaryCurrency } = preferencesSelector(state)
|
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
useETHAsPrimaryCurrency,
|
useNativeCurrencyAsPrimaryCurrency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => {
|
|||||||
assert.equal(wrapper.find(TokenInput).length, 1)
|
assert.equal(wrapper.find(TokenInput).length, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render showFiat for TokenInput based on preferences.useETHAsPrimaryCurrency', () => {
|
it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<UserPreferencedTokenInput
|
<UserPreferencedTokenInput
|
||||||
useETHAsPrimaryCurrency
|
useNativeCurrencyAsPrimaryCurrency
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.ok(wrapper)
|
assert.ok(wrapper)
|
||||||
assert.equal(wrapper.find(TokenInput).length, 1)
|
assert.equal(wrapper.find(TokenInput).length, 1)
|
||||||
assert.equal(wrapper.find(TokenInput).props().showFiat, false)
|
assert.equal(wrapper.find(TokenInput).props().showFiat, false)
|
||||||
wrapper.setProps({ useETHAsPrimaryCurrency: false })
|
wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false })
|
||||||
assert.equal(wrapper.find(TokenInput).props().showFiat, true)
|
assert.equal(wrapper.find(TokenInput).props().showFiat, true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -18,13 +18,13 @@ describe('UserPreferencedTokenInput container', () => {
|
|||||||
const mockState = {
|
const mockState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
preferences: {
|
preferences: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(mapStateToProps(mockState), {
|
assert.deepEqual(mapStateToProps(mockState), {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -4,16 +4,16 @@ import TokenInput from '../token-input'
|
|||||||
|
|
||||||
export default class UserPreferencedTokenInput extends PureComponent {
|
export default class UserPreferencedTokenInput extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
useETHAsPrimaryCurrency: PropTypes.bool,
|
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { useETHAsPrimaryCurrency, ...restProps } = this.props
|
const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TokenInput
|
<TokenInput
|
||||||
{...restProps}
|
{...restProps}
|
||||||
showFiat={!useETHAsPrimaryCurrency}
|
showFiat={!useNativeCurrencyAsPrimaryCurrency}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ import UserPreferencedTokenInput from './user-preferenced-token-input.component'
|
|||||||
import { preferencesSelector } from '../../selectors'
|
import { preferencesSelector } from '../../selectors'
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const { useETHAsPrimaryCurrency } = preferencesSelector(state)
|
const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
useETHAsPrimaryCurrency,
|
useNativeCurrencyAsPrimaryCurrency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
conversionRateSelector,
|
conversionRateSelector,
|
||||||
currentCurrencySelector,
|
currentCurrencySelector,
|
||||||
unconfirmedTransactionsHashSelector,
|
unconfirmedTransactionsHashSelector,
|
||||||
|
getNativeCurrency,
|
||||||
} from '../selectors/confirm-transaction'
|
} from '../selectors/confirm-transaction'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -292,16 +293,17 @@ export function updateTxDataAndCalculate (txData) {
|
|||||||
const state = getState()
|
const state = getState()
|
||||||
const currentCurrency = currentCurrencySelector(state)
|
const currentCurrency = currentCurrencySelector(state)
|
||||||
const conversionRate = conversionRateSelector(state)
|
const conversionRate = conversionRateSelector(state)
|
||||||
|
const nativeCurrency = getNativeCurrency(state)
|
||||||
|
|
||||||
dispatch(updateTxData(txData))
|
dispatch(updateTxData(txData))
|
||||||
|
|
||||||
const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData
|
const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData
|
||||||
|
|
||||||
const fiatTransactionAmount = getValueFromWeiHex({
|
const fiatTransactionAmount = getValueFromWeiHex({
|
||||||
value, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
|
value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
|
||||||
})
|
})
|
||||||
const ethTransactionAmount = getValueFromWeiHex({
|
const ethTransactionAmount = getValueFromWeiHex({
|
||||||
value, toCurrency: 'ETH', conversionRate, numberOfDecimals: 6,
|
value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6,
|
||||||
})
|
})
|
||||||
|
|
||||||
dispatch(updateTransactionAmounts({
|
dispatch(updateTransactionAmounts({
|
||||||
@ -314,13 +316,15 @@ export function updateTxDataAndCalculate (txData) {
|
|||||||
|
|
||||||
const fiatTransactionFee = getTransactionFee({
|
const fiatTransactionFee = getTransactionFee({
|
||||||
value: hexTransactionFee,
|
value: hexTransactionFee,
|
||||||
|
fromCurrency: nativeCurrency,
|
||||||
toCurrency: currentCurrency,
|
toCurrency: currentCurrency,
|
||||||
numberOfDecimals: 2,
|
numberOfDecimals: 2,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
})
|
})
|
||||||
const ethTransactionFee = getTransactionFee({
|
const ethTransactionFee = getTransactionFee({
|
||||||
value: hexTransactionFee,
|
value: hexTransactionFee,
|
||||||
toCurrency: 'ETH',
|
fromCurrency: nativeCurrency,
|
||||||
|
toCurrency: nativeCurrency,
|
||||||
numberOfDecimals: 6,
|
numberOfDecimals: 6,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
})
|
})
|
||||||
|
@ -55,6 +55,7 @@ export function addFiat (...args) {
|
|||||||
|
|
||||||
export function getValueFromWeiHex ({
|
export function getValueFromWeiHex ({
|
||||||
value,
|
value,
|
||||||
|
fromCurrency = 'ETH',
|
||||||
toCurrency,
|
toCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
@ -63,7 +64,7 @@ export function getValueFromWeiHex ({
|
|||||||
return conversionUtil(value, {
|
return conversionUtil(value, {
|
||||||
fromNumericBase: 'hex',
|
fromNumericBase: 'hex',
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
fromCurrency: 'ETH',
|
fromCurrency,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
fromDenomination: 'WEI',
|
fromDenomination: 'WEI',
|
||||||
@ -74,6 +75,7 @@ export function getValueFromWeiHex ({
|
|||||||
|
|
||||||
export function getTransactionFee ({
|
export function getTransactionFee ({
|
||||||
value,
|
value,
|
||||||
|
fromCurrency = 'ETH',
|
||||||
toCurrency,
|
toCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
@ -82,7 +84,7 @@ export function getTransactionFee ({
|
|||||||
fromNumericBase: 'BN',
|
fromNumericBase: 'BN',
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
fromDenomination: 'WEI',
|
fromDenomination: 'WEI',
|
||||||
fromCurrency: 'ETH',
|
fromCurrency,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
@ -99,6 +101,7 @@ export function formatCurrency (value, currencyCode) {
|
|||||||
|
|
||||||
export function convertTokenToFiat ({
|
export function convertTokenToFiat ({
|
||||||
value,
|
value,
|
||||||
|
fromCurrency = 'ETH',
|
||||||
toCurrency,
|
toCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
contractExchangeRate,
|
contractExchangeRate,
|
||||||
@ -108,6 +111,7 @@ export function convertTokenToFiat ({
|
|||||||
return conversionUtil(value, {
|
return conversionUtil(value, {
|
||||||
fromNumericBase: 'dec',
|
fromNumericBase: 'dec',
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
|
fromCurrency,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
numberOfDecimals: 2,
|
numberOfDecimals: 2,
|
||||||
conversionRate: totalExchangeRate,
|
conversionRate: totalExchangeRate,
|
||||||
|
@ -20,8 +20,8 @@ export function decimalToHex (decimal) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDecimals = 6 }) {
|
export function getEthConversionFromWeiHex ({ value, fromCurrency = ETH, conversionRate, numberOfDecimals = 6 }) {
|
||||||
const denominations = [ETH, GWEI, WEI]
|
const denominations = [fromCurrency, GWEI, WEI]
|
||||||
|
|
||||||
let nonZeroDenomination
|
let nonZeroDenomination
|
||||||
|
|
||||||
@ -29,7 +29,8 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec
|
|||||||
const convertedValue = getValueFromWeiHex({
|
const convertedValue = getValueFromWeiHex({
|
||||||
value,
|
value,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
toCurrency: ETH,
|
fromCurrency,
|
||||||
|
toCurrency: fromCurrency,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
toDenomination: denominations[i],
|
toDenomination: denominations[i],
|
||||||
})
|
})
|
||||||
@ -45,6 +46,7 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec
|
|||||||
|
|
||||||
export function getValueFromWeiHex ({
|
export function getValueFromWeiHex ({
|
||||||
value,
|
value,
|
||||||
|
fromCurrency = ETH,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
@ -53,7 +55,7 @@ export function getValueFromWeiHex ({
|
|||||||
return conversionUtil(value, {
|
return conversionUtil(value, {
|
||||||
fromNumericBase: 'hex',
|
fromNumericBase: 'hex',
|
||||||
toNumericBase: 'dec',
|
toNumericBase: 'dec',
|
||||||
fromCurrency: ETH,
|
fromCurrency,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
numberOfDecimals,
|
numberOfDecimals,
|
||||||
fromDenomination: WEI,
|
fromDenomination: WEI,
|
||||||
|
@ -52,7 +52,7 @@ function reduceMetamask (state, action) {
|
|||||||
welcomeScreenSeen: false,
|
welcomeScreenSeen: false,
|
||||||
currentLocale: '',
|
currentLocale: '',
|
||||||
preferences: {
|
preferences: {
|
||||||
useETHAsPrimaryCurrency: true,
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
},
|
},
|
||||||
}, state.metamask)
|
}, state.metamask)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ const selectors = {
|
|||||||
getAddressBook,
|
getAddressBook,
|
||||||
getSendFrom,
|
getSendFrom,
|
||||||
getCurrentCurrency,
|
getCurrentCurrency,
|
||||||
|
getNativeCurrency,
|
||||||
getSendAmount,
|
getSendAmount,
|
||||||
getSelectedTokenToFiatRate,
|
getSelectedTokenToFiatRate,
|
||||||
getSelectedTokenContract,
|
getSelectedTokenContract,
|
||||||
@ -143,6 +144,10 @@ function getCurrentCurrency (state) {
|
|||||||
return state.metamask.currentCurrency
|
return state.metamask.currentCurrency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNativeCurrency (state) {
|
||||||
|
return state.metamask.nativeCurrency
|
||||||
|
}
|
||||||
|
|
||||||
function getSelectedTokenToFiatRate (state) {
|
function getSelectedTokenToFiatRate (state) {
|
||||||
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
|
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
|
||||||
const conversionRate = conversionRateSelector(state)
|
const conversionRate = conversionRateSelector(state)
|
||||||
|
@ -93,6 +93,7 @@ export const unconfirmedTransactionsCountSelector = createSelector(
|
|||||||
|
|
||||||
export const currentCurrencySelector = state => state.metamask.currentCurrency
|
export const currentCurrencySelector = state => state.metamask.currentCurrency
|
||||||
export const conversionRateSelector = state => state.metamask.conversionRate
|
export const conversionRateSelector = state => state.metamask.conversionRate
|
||||||
|
export const getNativeCurrency = state => state.metamask.nativeCurrency
|
||||||
|
|
||||||
const txDataSelector = state => state.confirmTransaction.txData
|
const txDataSelector = state => state.confirmTransaction.txData
|
||||||
const tokenDataSelector = state => state.confirmTransaction.tokenData
|
const tokenDataSelector = state => state.confirmTransaction.tokenData
|
||||||
|
@ -128,7 +128,7 @@ function parseBalance (balance) {
|
|||||||
|
|
||||||
// Takes wei hex, returns an object with three properties.
|
// Takes wei hex, returns an object with three properties.
|
||||||
// Its "formatted" property is what we generally use to render values.
|
// Its "formatted" property is what we generally use to render values.
|
||||||
function formatBalance (balance, decimalsToKeep, needsParse = true) {
|
function formatBalance (balance, decimalsToKeep, needsParse = true, ticker = 'ETH') {
|
||||||
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
|
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
|
||||||
var beforeDecimal = parsed[0]
|
var beforeDecimal = parsed[0]
|
||||||
var afterDecimal = parsed[1]
|
var afterDecimal = parsed[1]
|
||||||
@ -138,14 +138,14 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) {
|
|||||||
if (afterDecimal !== '0') {
|
if (afterDecimal !== '0') {
|
||||||
var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
|
var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
|
||||||
if (sigFigs) { afterDecimal = sigFigs[0] }
|
if (sigFigs) { afterDecimal = sigFigs[0] }
|
||||||
formatted = '0.' + afterDecimal + ' ETH'
|
formatted = '0.' + afterDecimal + ` ${ticker}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
|
formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ` ${ticker}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
afterDecimal += Array(decimalsToKeep).join('0')
|
afterDecimal += Array(decimalsToKeep).join('0')
|
||||||
formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
|
formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ` ${ticker}`
|
||||||
}
|
}
|
||||||
return formatted
|
return formatted
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user