diff --git a/api/currency-utils.js b/api/currency-utils.js index 776a294d0..58e9f86f3 100644 --- a/api/currency-utils.js +++ b/api/currency-utils.js @@ -6,8 +6,10 @@ import { Kintsugi, // On Kusama Kusama, // on Kusama Polkadot // on Polkadot - } from '@interlay/monetary-js'; - +} from '@interlay/monetary-js'; +import { isForeignAsset } from "@interlay/interbtc-api"; + + const COINGECKO_ID_BY_CURRENCY_TICKER = { [Bitcoin.ticker]: 'bitcoin', [Kintsugi.ticker]: 'kintsugi', @@ -33,4 +35,9 @@ const getCoingeckoId = (currency) => { return COINGECKO_ID_BY_CURRENCY_TICKER[currency.ticker]; }; -export { getCoingeckoId }; \ No newline at end of file +const getCoingeckoQueryUrl = (vsId, coingeckoIds) => { + const idsString = coingeckoIds.join(","); + return `https://api.coingecko.com/api/v3/simple/price?vs_currencies=${vsId}&ids=${idsString}`; +}; + +export { getCoingeckoId, getCoingeckoQueryUrl }; \ No newline at end of file diff --git a/api/package-lock.json b/api/package-lock.json index f0d3d3f52..124d156d0 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@interlay/interbtc-api": "2.6.0-rc.0", + "@interlay/monetary-js": "0.7.3", "@polkadot/util-crypto": "12.6.1", "pg": "^8.10.0" }, diff --git a/api/tvl_dex.js b/api/tvl_dex.js index 28b94162b..46289d3c3 100644 --- a/api/tvl_dex.js +++ b/api/tvl_dex.js @@ -1,5 +1,5 @@ import { createInterBtcApi, isForeignAsset } from "@interlay/interbtc-api"; -import { getCoingeckoId } from "./currency-utils"; +import { getCoingeckoId, getCoingeckoQueryUrl } from "./currency-utils"; const tvlDex = async (request, response) => { if (request.method === 'GET') { @@ -11,13 +11,39 @@ const tvlDex = async (request, response) => { ); const pools = await interbtcApi.amm.getLiquidityPools(); + // dedupe ids + const coingeckoIds = new Set( + pools.flatMap((pool) => pool.pooledCurrencies) + .map((monetaryAmount) => getCoingeckoId(monetaryAmount)) + ); + // base: usd, get price for all coingeckoIds + const queryUrl = getCoingeckoQueryUrl("usd", Array.from(coingeckoIds)); + // return format: [ { : { : } }, ... ] + const response = await fetch(queryUrl, { headers: { "accept": "application/json" } }); + const cgData = await response.json(); + const amounts = pools.flatMap((pool) => pool.pooledCurrencies) - .map((monetaryAmount) => ({ - currency: monetaryAmount.currency, - coingeckoId: getCoingeckoId(monetaryAmount.currency), - atomicAmount: monetaryAmount.toString(true), - amount: monetaryAmount.toHuman() - })); + .map((monetaryAmount) => { + const atomicAmount = monetaryAmount.toString(true); + const amount = monetaryAmount.toString(); + + const cgId = getCoingeckoId(monetaryAmount.currency); + const usdPrice = (cgData[cgId] != undefined && cgData[cgId]["usd"] != undefined) + ? cgData[cgId]["usd"] + : undefined; + + const monetaryAmountUsd = usdPrice ? monetaryAmount.mul(usdPrice) : undefined; + const amountUsd = monetaryAmountUsd?.toString(true); + const atomicAmountUsd = monetaryAmountUsd?.toString(); + return { + currency: monetaryAmount.currency, + coingeckoId: getCoingeckoId(monetaryAmount.currency), + atomicAmount, + amount, + atomicAmountUsd, + amountUsd + } + }); return response.status(200) .setHeader("content-type", "application/json")