feat: coincap forex api fallback
This commit is contained in:
parent
ff474ee507
commit
3af6d3a773
2 changed files with 63 additions and 15 deletions
59
lib/forex.js
59
lib/forex.js
|
|
@ -1,5 +1,62 @@
|
||||||
|
const _ = require('lodash/fp')
|
||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
|
const BN = require('./bn')
|
||||||
|
|
||||||
|
const MAX_ROTATIONS = 5
|
||||||
|
|
||||||
const getFiatRates = () => axios.get('https://bitpay.com/api/rates').then(response => response.data)
|
const getFiatRates = () => axios.get('https://bitpay.com/api/rates').then(response => response.data)
|
||||||
|
|
||||||
module.exports = { getFiatRates }
|
const API_QUEUE = [
|
||||||
|
{ api: getBitPayFxRate, name: 'bitpay', fiatCodeProperty: 'code', rateProperty: 'rate' },
|
||||||
|
{ api: getCoinCapFxRate, name: 'coincap', fiatCodeProperty: 'symbol', rateProperty: 'rateUsd' }
|
||||||
|
]
|
||||||
|
|
||||||
|
function getBitPayFxRate (fiatCode, fiatCodeProperty, rateProperty) {
|
||||||
|
return axios.get('https://bitpay.com/rates')
|
||||||
|
.then(response => {
|
||||||
|
const fxRates = response.data.data
|
||||||
|
const usdRate = findCurrencyRates(fxRates, 'USD', fiatCodeProperty, rateProperty)
|
||||||
|
const fxRate = findCurrencyRates(fxRates, fiatCode, fiatCodeProperty, rateProperty).div(usdRate)
|
||||||
|
return {
|
||||||
|
fxRate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCoinCapFxRate (fiatCode, fiatCodeProperty, rateProperty) {
|
||||||
|
return axios.get('https://api.coincap.io/v2/rates')
|
||||||
|
.then(response => {
|
||||||
|
const fxRates = response.data.data
|
||||||
|
const fxRate = findCurrencyRates(fxRates, fiatCode, fiatCodeProperty, rateProperty)
|
||||||
|
return {
|
||||||
|
fxRate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function findCurrencyRates (fxRates, fiatCode, fiatCodeProperty, rateProperty) {
|
||||||
|
const rates = _.find(_.matchesProperty(fiatCodeProperty, fiatCode), fxRates)
|
||||||
|
if (!rates || !rates[rateProperty]) throw new Error(`Unsupported currency: ${fiatCode}`)
|
||||||
|
return new BN(rates[rateProperty].toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRate = (retries = 1, fiatCode) => {
|
||||||
|
const selected = _.first(API_QUEUE).name
|
||||||
|
const activeAPI = _.first(API_QUEUE).api
|
||||||
|
const fiatCodeProperty = _.first(API_QUEUE).fiatCodeProperty
|
||||||
|
const rateProperty = _.first(API_QUEUE).rateProperty
|
||||||
|
|
||||||
|
if (!activeAPI) throw new Error(`FOREX api ${selected} does not exist.`)
|
||||||
|
|
||||||
|
return activeAPI(fiatCode, fiatCodeProperty, rateProperty).then(res => res)
|
||||||
|
.catch(() => {
|
||||||
|
// Switch service
|
||||||
|
const erroredService = API_QUEUE.shift()
|
||||||
|
API_QUEUE.push(erroredService)
|
||||||
|
if (retries >= MAX_ROTATIONS) throw new Error(`FOREX API error from ${erroredService.name}`)
|
||||||
|
|
||||||
|
return getRate(++retries, fiatCode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getFiatRates, getRate }
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
const _ = require('lodash/fp')
|
|
||||||
const axios = require('axios')
|
|
||||||
const ccxt = require('ccxt')
|
const ccxt = require('ccxt')
|
||||||
|
|
||||||
const BN = require('../../bn')
|
const BN = require('../../bn')
|
||||||
const { buildMarket, verifyFiatSupport } = require('../common/ccxt')
|
const { buildMarket, verifyFiatSupport } = require('../common/ccxt')
|
||||||
|
const { getRate } = require('../../../lib/forex')
|
||||||
|
|
||||||
|
const RETRIES = 2
|
||||||
|
|
||||||
function ticker (fiatCode, cryptoCode, tickerName) {
|
function ticker (fiatCode, cryptoCode, tickerName) {
|
||||||
const ticker = new ccxt[tickerName]({ timeout: 3000 })
|
const ticker = new ccxt[tickerName]({ timeout: 3000 })
|
||||||
|
|
@ -11,13 +12,9 @@ function ticker (fiatCode, cryptoCode, tickerName) {
|
||||||
return getCurrencyRates(ticker, fiatCode, cryptoCode)
|
return getCurrencyRates(ticker, fiatCode, cryptoCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return axios.get('https://bitpay.com/rates')
|
return getRate(RETRIES, fiatCode)
|
||||||
.then(response => {
|
.then(({ fxRate }) => {
|
||||||
try {
|
try {
|
||||||
const fxRates = response.data.data
|
|
||||||
const usdRate = findCurrencyRates(fxRates, 'USD')
|
|
||||||
const fxRate = findCurrencyRates(fxRates, fiatCode).div(usdRate)
|
|
||||||
|
|
||||||
return getCurrencyRates(ticker, 'USD', cryptoCode)
|
return getCurrencyRates(ticker, 'USD', cryptoCode)
|
||||||
.then(res => ({
|
.then(res => ({
|
||||||
rates: {
|
rates: {
|
||||||
|
|
@ -49,10 +46,4 @@ function getCurrencyRates (ticker, fiatCode, cryptoCode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findCurrencyRates (fxRates, fiatCode) {
|
|
||||||
const rates = _.find(_.matchesProperty('code', fiatCode), fxRates)
|
|
||||||
if (!rates || !rates.rate) throw new Error(`Unsupported currency: ${fiatCode}`)
|
|
||||||
return new BN(rates.rate.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { ticker }
|
module.exports = { ticker }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue