diff --git a/lib/exchange.js b/lib/exchange.js index f9811bb8..ee325b2f 100644 --- a/lib/exchange.js +++ b/lib/exchange.js @@ -50,19 +50,26 @@ function active (settings, cryptoCode) { } function getMarkets () { - const filterExchanges = _.filter(it => it.class === 'exchange') + const filterExchanges = _.filter(it => it.class === 'exchange' && !it.dev && it.code !== 'no-exchange') const availableExchanges = _.map(it => it.code, filterExchanges(accounts.ACCOUNT_LIST)) - return _.reduce( - (acc, value) => - Promise.all([acc, ccxt.getMarkets(value, ALL_CRYPTOS)]) - .then(([a, markets]) => Promise.resolve({ - ...a, - [value]: markets - })), - Promise.resolve({}), - availableExchanges - ) + const fetchMarketForExchange = exchange => + ccxt.getMarkets(exchange, ALL_CRYPTOS) + .then(markets => ({ exchange, markets })) + .catch(error => ({ + exchange, + markets: [], + error: error.message + })) + + const transformToObject = _.reduce((acc, { exchange, markets }) => ({ + ...acc, + [exchange]: markets + }), {}) + + const promises = _.map(fetchMarketForExchange, availableExchanges) + return Promise.all(promises) + .then(transformToObject) } module.exports = { diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index 3b13daf8..24ac2424 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -14,6 +14,7 @@ const { ApolloServer } = require('apollo-server-express') require('../environment-helper') const { asyncLocalStorage, defaultStore } = require('../async-storage') const logger = require('../logger') +const exchange = require('../exchange') const { AuthDirective } = require('./graphql/directives') const { typeDefs, resolvers } = require('./graphql/schema') @@ -98,6 +99,9 @@ function run () { const serverLog = `lamassu-admin-server listening on port ${serverPort}` + // cache markets on startup + exchange.getMarkets().catch(console.error) + const webServer = https.createServer(certOptions, app) webServer.listen(serverPort, () => logger.info(serverLog)) }) diff --git a/lib/plugins/exchange/ccxt.js b/lib/plugins/exchange/ccxt.js index 63b57fa9..a69021ba 100644 --- a/lib/plugins/exchange/ccxt.js +++ b/lib/plugins/exchange/ccxt.js @@ -56,6 +56,8 @@ function calculatePrice (side, amount, orderBook) { } function _getMarkets (exchangeName, availableCryptos) { + const prunedCryptos = _.compose(_.uniq, _.map(coinUtils.getEquivalentCode))(availableCryptos) + try { const exchange = new ccxt[exchangeName]() const cryptosToQuoteAgainst = ['USDT'] @@ -65,13 +67,13 @@ function _getMarkets (exchangeName, availableCryptos) { .then(_.filter(it => (it.type === 'spot' || it.spot))) .then(res => _.reduce((acc, value) => { - if (_.includes(value.base, availableCryptos) && _.includes(value.quote, currencyCodes)) { + if (_.includes(value.base, prunedCryptos) && _.includes(value.quote, currencyCodes)) { if (value.quote === value.base) return acc if (_.isNil(acc[value.quote])) { return { ...acc, [value.quote]: [value.base] } } - + acc[value.quote].push(value.base) } return acc diff --git a/new-lamassu-admin/src/pages/Services/schemas/helper.js b/new-lamassu-admin/src/pages/Services/schemas/helper.js index c1c97870..58d97339 100644 --- a/new-lamassu-admin/src/pages/Services/schemas/helper.js +++ b/new-lamassu-admin/src/pages/Services/schemas/helper.js @@ -1,4 +1,4 @@ -import { ALL_CRYPTOS } from '@lamassu/coins' +import { ALL_CRYPTOS, utils as coinUtils } from '@lamassu/coins' import * as R from 'ramda' const WARNING_LEVELS = { @@ -29,8 +29,12 @@ const leadingZerosTest = (value, context) => { } const buildCurrencyOptions = markets => { + const prunedCoins = R.compose( + R.uniq, + R.map(coinUtils.getEquivalentCode) + )(ALL_CRYPTOS) return R.map(it => { - const unavailableCryptos = R.difference(ALL_CRYPTOS, markets[it]) + const unavailableCryptos = R.difference(prunedCoins, markets[it]) const unavailableCryptosFiltered = R.difference(unavailableCryptos, [it]) // As the markets can have stablecoins to trade against other crypto, filter them out, as there can't be pairs such as USDT/USDT const unavailableMarketsStr = @@ -44,7 +48,7 @@ const buildCurrencyOptions = markets => { const warningLevel = R.isEmpty(unavailableCryptosFiltered) ? WARNING_LEVELS.CLEAN : !R.isEmpty(unavailableCryptosFiltered) && - R.length(unavailableCryptosFiltered) < R.length(ALL_CRYPTOS) + R.length(unavailableCryptosFiltered) < R.length(prunedCoins) ? WARNING_LEVELS.PARTIAL : WARNING_LEVELS.IMPORTANT