diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index 8fda9e836..810c8d518 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -25,6 +25,7 @@ class CurrencyController { */ constructor (opts = {}) { const initState = extend({ + currentCoin: 'poa', currentCurrency: 'usd', conversionRate: 0, conversionDate: 'N/A', @@ -36,6 +37,26 @@ class CurrencyController { // PUBLIC METHODS // + /** + * A getter for the currentCoin property + * + * @returns {string} A 2-4 character shorthand that describes a specific coin, related to the network + * + */ + getCurrentCoin () { + return this.store.getState().currentCoin + } + + /** + * A setter for the currentCoin property + * + * @param {string} currentCoin The new coin to set as the currentCoin in the store + * + */ + setCurrentCoin (currentCoin) { + this.store.updateState({ currentCoin }) + } + /** * A getter for the currentCurrency property * @@ -59,7 +80,7 @@ class CurrencyController { /** * A getter for the conversionRate property * - * @returns {string} The conversion rate from ETH to the selected currency. + * @returns {string} The conversion rate from current coin to the selected currency. * */ getConversionRate () { @@ -104,15 +125,27 @@ class CurrencyController { * */ async updateConversionRate () { - let currentCurrency + let currentCurrency, currentCoin try { currentCurrency = this.getCurrentCurrency() - const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) - const parsedResponse = await response.json() - this.setConversionRate(Number(parsedResponse.bid)) - this.setConversionDate(Number(parsedResponse.timestamp)) + currentCoin = this.getCurrentCoin() + let conversionRate, conversionDate + if (currentCoin === 'poa') { + const coinId = await this.getCoinMarketCapId(currentCoin) + const response = await fetch(`https://api.coinmarketcap.com/v2/ticker/${coinId}/?convert=${currentCurrency.toLowerCase()}`) + const parsedResponse = await response.json() + conversionRate = Number(parsedResponse.data.quotes[currentCurrency.toUpperCase()].price) + conversionDate = Number(parsedResponse.metadata.timestamp) + } else { + const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) + const parsedResponse = await response.json() + conversionRate = Number(parsedResponse.bid) + conversionDate = Number(parsedResponse.timestamp) + } + this.setConversionRate(conversionRate) + this.setConversionDate(conversionDate) } catch (err) { - log.warn(`Nifty Wallet - Failed to query currency conversion:`, currentCurrency, err) + log.warn(`Nifty Wallet - Failed to query currency conversion:`, currentCoin, currentCurrency, err) this.setConversionRate(0) this.setConversionDate('N/A') } @@ -132,6 +165,17 @@ class CurrencyController { this.updateConversionRate() }, POLLING_INTERVAL) } + + async getCoinMarketCapId (symbol) { + const response = await fetch(`https://api.coinmarketcap.com/v2/listings/`) + const parsedResponse = await response.json() + const results = parsedResponse.data.filter(coin => coin.symbol === symbol.toUpperCase()) + if (!results.length) { + throw new Error(`Nifty Wallet - Failed to fetch ${symbol} from coinmarketcap listings`) + } + return results[0].id + } + } module.exports = CurrencyController diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 97e18aa2e..6e8b7c56b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -333,6 +333,7 @@ module.exports = class MetamaskController extends EventEmitter { // etc getState: (cb) => cb(null, this.getState()), setCurrentCurrency: this.setCurrentCurrency.bind(this), + setCurrentCoin: this.setCurrentCoin.bind(this), setUseBlockie: this.setUseBlockie.bind(this), setCurrentLocale: this.setCurrentLocale.bind(this), markAccountsFound: this.markAccountsFound.bind(this), @@ -1184,6 +1185,27 @@ module.exports = class MetamaskController extends EventEmitter { } } + /** + * A method for setting the network coin. + * @param {string} coinCode - The code of the coin. + * @param {Function} cb - A callback function returning currency info. + */ + async setCurrentCoin (coinCode, cb) { + try { + this.currencyController.setCurrentCoin(coinCode) + await this.currencyController.updateConversionRate() + const data = { + conversionRate: this.currencyController.getConversionRate(), + currentCoin: this.currencyController.getCurrentCoin(), + currentCurrency: this.currencyController.getCurrentCurrency(), + conversionDate: this.currencyController.getConversionDate(), + } + cb(null, data) + } catch (err) { + cb(err) + } + } + /** * A method for forwarding the user to the easiest way to obtain ether, * or the network "gas" currency, for the current selected network. diff --git a/ui/app/actions.js b/ui/app/actions.js index d8b3ed69d..6f6a4db84 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1543,6 +1543,22 @@ function setProviderType (type) { dispatch(actions.setSelectedToken()) }) + const newCoin = type === 'poa' || type === 'sokol' ? 'poa' : 'eth' + background.setCurrentCoin(newCoin, (err, data) => { + if (err) { + log.error(err.stack) + return dispatch(actions.displayWarning(err.message)) + } + dispatch({ + type: actions.SET_CURRENT_FIAT, + value: { + currentCurrency: data.currentCurrency, + conversionRate: data.conversionRate, + conversionDate: data.conversionDate, + }, + }) + }) + } }