diff --git a/lib/plugins.js b/lib/plugins.js index a119e7dd..ef001f7d 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -225,12 +225,16 @@ function plugins (settings, deviceId) { } } + function getTickerRates (fiatCode, cryptoCode) { + return ticker.getRates(settings, fiatCode, cryptoCode) + } + function pollQueries () { const localeConfig = configManager.getLocale(deviceId, settings.config) const fiatCode = localeConfig.fiatCurrency const cryptoCodes = localeConfig.cryptoCurrencies - const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c)) + const tickerPromises = cryptoCodes.map(c => getTickerRates(fiatCode, c)) const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c)) const networkPromises = cryptoCodes.map(c => wallet.cryptoNetwork(settings, c)) const supportsBatchingPromise = cryptoCodes.map(c => wallet.supportsBatching(settings, c)) @@ -342,7 +346,7 @@ function plugins (settings, deviceId) { function fiatBalance (fiatCode, cryptoCode) { const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config) return Promise.all([ - ticker.getRates(settings, fiatCode, cryptoCode), + getTickerRates(fiatCode, cryptoCode), wallet.balance(settings, cryptoCode) ]) .then(([rates, balanceRec]) => { @@ -832,7 +836,7 @@ function plugins (settings, deviceId) { const fiatCode = localeConfig.fiatCurrency const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config) - const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c)) + const tickerPromises = cryptoCodes.map(c => getTickerRates(fiatCode, c)) return Promise.all(tickerPromises) } diff --git a/lib/ticker.js b/lib/ticker.js index afef8a72..221235e3 100644 --- a/lib/ticker.js +++ b/lib/ticker.js @@ -14,33 +14,40 @@ const FETCH_INTERVAL = 58000 const PEGGED_FIAT_CURRENCIES = { NAD: 'ZAR' } -function _getRates (settings, fiatCode, cryptoCode) { - return Promise.resolve() - .then(() => { - const config = settings.config - const tickerName = configManager.getWalletSettings(cryptoCode, config).ticker - const market = [cryptoCode, fiatCode].join('-') +const getFallbackTicker = ticker => + _.difference(['bitpay', 'kraken', 'bitstamp'], [ticker])[0] - return buildTicker(fiatCode, cryptoCode, tickerName) - .then(r => ({ - rates: r.rates, - timestamp: Date.now() - })) - .then(r => { - lastRate[market] = r - return r - }) - .catch(err => { - logger.error(err) - return lastRate[market] - }) +const hasRatesOrReject = emsg => r => _.get(['rates'], r) ? + r : + Promise.reject(new Error(emsg)) + +const get1 = (market, fiatCode, cryptoCode, ticker, emsg) => + buildTicker(fiatCode, cryptoCode, ticker) + .then(hasRatesOrReject(emsg)) + .then(({ rates }) => { + return lastRate[market] = { rates, timestamp: Date.now() } }) -} + +const _getRates = (settings, fiatCode, cryptoCode) => Promise.resolve() + .then(() => { + const ticker = configManager.getWalletSettings(cryptoCode, settings.config).ticker + const market = [cryptoCode, fiatCode].join('-') + const fallbackTicker = getFallbackTicker(ticker) + const emsg = fallbackTicker ? + "Failed to get rates with configured ticker, trying fallback" : + "Failed to get ticker rates" + return get1(market, fiatCode, cryptoCode, ticker, emsg) + .catch(err => { + logger.error(err) + return fallbackTicker ? + get1(market, fiatCode, cryptoCode, fallbackTicker, "Failed to get rates with fallback ticker") : + lastRate[market] + }) + .then(hasRatesOrReject("Failed to get ticker rates")) + }) function buildTicker (fiatCode, cryptoCode, tickerName) { - fiatCode = _.includes(fiatCode, _.keys(PEGGED_FIAT_CURRENCIES)) - ? PEGGED_FIAT_CURRENCIES[fiatCode] - : fiatCode + fiatCode = _.defaultTo(fiatCode, _.get([fiatCode], PEGGED_FIAT_CURRENCIES)) cryptoCode = coinUtils.getEquivalentCode(cryptoCode) if (tickerName === 'bitpay') return bitpay.ticker(fiatCode, cryptoCode)