diff --git a/CHANGELOG.md b/CHANGELOG.md index 72bf4a23..992efc81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - changed: Simplify our React Native integration. +- removed: Delete all rate plugins. ## 0.22.0 (2023-10-24) diff --git a/src/index.ts b/src/index.ts index 71887d19..4f1b9202 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,17 +2,6 @@ import 'regenerator-runtime/runtime' import type { EdgeCorePlugins } from 'edge-core-js/types' -import { makeBitMaxPlugin } from './rate/bitmax' -import { makeCoinbasePlugin } from './rate/coinbase' -import { makeCoincapPlugin } from './rate/coincap' -import { makeCoinGeckoPlugin } from './rate/coingecko' -import { makeCoinmonitorPlugin } from './rate/coinmonitor' -import { makeCompoundPlugin } from './rate/compound' -import { makeConstantRatePlugin } from './rate/constantRate' -import { makeCurrencyconverterapiPlugin } from './rate/currencyconverterapi' -import { makeEdgeRatesPlugin } from './rate/edgeRates' -import { makeNomicsPlugin } from './rate/nomics' -import { makeWazirxPlugin } from './rate/wazirx' import { makeChangeHeroPlugin } from './swap/changehero' import { makeChangeNowPlugin } from './swap/changenow' import { makeLifiPlugin } from './swap/defi/lifi' @@ -30,19 +19,6 @@ import { makeSwapuzPlugin } from './swap/swapuz' import { makeTransferPlugin } from './swap/transfer' const plugins = { - // Rate plugins: - bitmax: makeBitMaxPlugin, - coinbase: makeCoinbasePlugin, - coincap: makeCoincapPlugin, - coingecko: makeCoinGeckoPlugin, - coinmonitor: makeCoinmonitorPlugin, - compound: makeCompoundPlugin, - constantRate: makeConstantRatePlugin, - currencyconverterapi: makeCurrencyconverterapiPlugin, - edgeRates: makeEdgeRatesPlugin, - nomics: makeNomicsPlugin, - wazirx: makeWazirxPlugin, - // Swap plugins: changehero: makeChangeHeroPlugin, changenow: makeChangeNowPlugin, diff --git a/src/rate/bitmax.ts b/src/rate/bitmax.ts deleted file mode 100644 index aa587040..00000000 --- a/src/rate/bitmax.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asBitMaxTickerResponse = asObject({ data: asObject({ close: asString }) }) - -export function makeBitMaxPlugin(opts: EdgeCorePluginOptions): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'bitmax', - displayName: 'BitMax' - }, - - async fetchRates(pairsHint) { - for (const pair of pairsHint) { - // BitMax is only used to query FIO price - if (pair.fromCurrency !== 'FIO') continue - try { - const response = await fetchCors( - 'https://ascendex.com/api/pro/v1/ticker?symbol=FIO/USDT' - ) - const json = await response.json() - if (!response.ok || json.reason === 'DATA_NOT_AVAILABLE') { - // Return fixed rate if data is unavailable - break - } - const rate = Number(asBitMaxTickerResponse(json).data.close) - return [ - { - fromCurrency: 'FIO', - toCurrency: 'USDT', - rate - } - ] - } catch (e) { - log.warn(`Issue with Bitmax rate data structure ${String(e)}`) - break - } - } - return [] - } - } -} diff --git a/src/rate/coinbase.ts b/src/rate/coinbase.ts deleted file mode 100644 index fe38e8af..00000000 --- a/src/rate/coinbase.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { asMap, asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asCoinbaseResponse = asObject({ - data: asObject({ - rates: asMap(asString) - }) -}) - -export function makeCoinbasePlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'coinbase', - displayName: 'Coinbase' - }, - - async fetchRates(pairsHint) { - const pairs = [] - try { - const reply = await fetchCors( - 'https://api.coinbase.com/v2/exchange-rates' - ) - const json = await reply.json() - const cleanJson = asCoinbaseResponse(json) - for (const pair of pairsHint) { - const cc = pair.fromCurrency - if ( - cleanJson.data.rates[cc] == null || - cleanJson.data.rates[cc] === '' - ) - continue - const rate = Number(cleanJson.data.rates[cc]) - pairs.push({ - fromCurrency: 'iso:USD', - toCurrency: cc, - rate - }) - } - } catch (e) { - log.warn(`Issue with Coinbase rate data structure ${String(e)}`) - } - return pairs - } - } -} diff --git a/src/rate/coincap.ts b/src/rate/coincap.ts deleted file mode 100644 index a5a26588..00000000 --- a/src/rate/coincap.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { asArray, asNumber, asObject, asOptional, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asCoincapResponse = asObject({ - data: asArray( - asObject({ - symbol: asString, - priceUsd: asString - }) - ) -}) - -const asCoincapError = asObject({ - error: asOptional(asString), - timestamp: asNumber -}) - -const asCoincapAssets = asArray( - asObject({ - id: asString, - symbol: asString - }) -) - -interface RatePair { - fromCurrency: string - toCurrency: string - rate: number -} - -const currencyMap: { [symbol: string]: string } = {} - -export function makeCoincapPlugin(opts: EdgeCorePluginOptions): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'coincap', - displayName: 'Coincap' - }, - - async fetchRates(pairsHint): Promise { - const pairs: RatePair[] = [] - // Create unique ID map - if (Object.keys(currencyMap).length === 0) { - const assets = await fetchCors(`https://api.coincap.io/v2/assets/`) - const assetsJson = await assets.json() - const assetIds = asCoincapAssets(assetsJson.data) - assetIds.forEach(code => (currencyMap[code.symbol] = code.id)) - } - - // Create query strings - const queryStrings = [] - let filteredPairs: string[] = [] - for (let i = 0; i < pairsHint.length; i++) { - if ( - currencyMap[pairsHint[i].fromCurrency] === '' || - currencyMap[pairsHint[i].fromCurrency] == null - ) - continue - if (pairsHint[i].fromCurrency.includes('iso:')) continue - if ( - filteredPairs.some( - cc => cc === currencyMap[pairsHint[i].fromCurrency] - ) - ) - continue - filteredPairs.push(currencyMap[pairsHint[i].fromCurrency]) - if (filteredPairs.length === 100 || i === pairsHint.length - 1) { - queryStrings.push(filteredPairs.join(',')) - filteredPairs = [] - } - } - - for (const query of queryStrings) { - // Coincap only provides prices in USD - try { - const reply = await fetch( - `https://api.coincap.io/v2/assets?ids=${query}` - ) - const json = await reply.json() - const { error } = asCoincapError(json) - if ((error != null && error !== '') || !reply.ok) { - throw new Error( - `CoincapHistorical returned code ${JSON.stringify( - error ?? reply.status - )}` - ) - } - asCoincapResponse(json).data.forEach(rate => - pairs.push({ - fromCurrency: rate.symbol, - toCurrency: 'iso:USD', - rate: Number(rate.priceUsd) - }) - ) - } catch (e) { - log.warn(`Issue with Coincap rate data structure ${String(e)}`) - } - } - return pairs - } - } -} diff --git a/src/rate/coingecko.ts b/src/rate/coingecko.ts deleted file mode 100644 index acac07c2..00000000 --- a/src/rate/coingecko.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { asMap, asNumber, asObject } from 'cleaners' -import { - EdgeCorePluginOptions, - EdgeRateHint, - EdgeRatePair, - EdgeRatePlugin -} from 'edge-core-js/types' - -const asGeckoBulkUsdReply = asMap(asObject({ usd: asNumber })) - -const coinGeckoMap: { [ccode: string]: string } = { - TLOS: 'telos', - FIRO: 'zcoin', - ANT: 'aragon', - TBTC: 'tbtc', - FIO: 'fio-protocol', - VTC: 'vertcoin', - SMART: 'smartcash', - GRS: 'groestlcoin', - FUN: 'funfair', - BADGER: 'badger-dao', - CREAM: 'cream-2', - CVP: 'concentrated-voting-power', - DOUGH: 'piedao-dough-v2', - ETHBNT: 'ethbnt', - SUSD: 'nusd', - USDS: 'stableusd', - TUSD: 'true-usd', - GUSD: 'gemini-dollar', - YETI: 'yearn-ecosystem-token-index', - PAX: 'paxos-standard', - RBTC: 'rootstock', - RIF: 'rif-token', - FTC: 'feathercoin', - GLM: 'golem', - GNO: 'gnosis', - STORJ: 'storj', - BTC: 'bitcoin', - ETH: 'ethereum', - BCH: 'bitcoin-cash', - BNB: 'binancecoin', - EOS: 'eos', - ETC: 'ethereum-classic', - XLM: 'stellar', - XTZ: 'tezos', - XRP: 'ripple', - BTG: 'bitcoin-gold', - BSV: 'bitcoin-cash-sv', - DASH: 'dash', - DGB: 'digibyte', - DOGE: 'dogecoin', - EBST: 'eboost', - LTC: 'litecoin', - QTUM: 'qtum', - RVN: 'ravencoin', - UFO: 'ufocoin', - XMR: 'monero', - REP: 'augur', - DAI: 'dai', - SAI: 'sai', - WINGS: 'wings', - USDT: 'tether', - IND: 'indorse', - HUR: 'hurify', - BAT: 'basic-attention-token', - BNT: 'bancor', - KNC: 'kyber-network', - POLY: 'polymath-network', - USDC: 'usd-coin', - ZRX: '0x', - OMG: 'omisego', - NMR: 'numeraire', - MKR: 'maker', - SALT: 'salt', - MANA: 'decentraland', - NEXO: 'nexo', - KIN: 'kin', - LINK: 'chainlink', - BRZ: 'brz', - CREP: 'compound-augur', - CUSDC: 'compound-usd-coin', - CETH: 'compound-ether', - CBAT: 'compound-basic-attention-token', - CZRX: 'compound-0x', - CWBTC: 'compound-wrapped-btc', - CSAI: 'compound-sai', - CDAI: 'cdai', - OXT: 'orchid-protocol', - COMP: 'compound-governance-token', - MET: 'metronome', - SNX: 'havven', - SBTC: 'sbtc', - AAVE: 'aave', - WBTC: 'wrapped-bitcoin', - YFI: 'yearn-finance', - CRV: 'curve-dao-token', - BAL: 'balancer', - SUSHI: 'sushi', - UMA: 'uma', - IDLE: 'idle', - NXM: 'nxm', - PICKLE: 'pickle-finance', - ROOK: 'rook', - INDEX: 'index-cooperative', - WETH: 'weth', - RENBTC: 'renbtc', - RENBCH: 'renbch', - RENZEC: 'renzec', - DPI: 'defipulse-index', - BAND: 'band-protocol', - REN: 'republic-protocol', - AMPL: 'ampleforth', - HBAR: 'hedera-hashgraph', - OCEAN: 'ocean-protocol', - AVAX: 'avalanche-2', - MATIC: 'matic-network', - PNG: 'pangolin', - PEFI: 'penguin-finance', - XAVA: 'avalaunch', - BIFI: 'beefy-finance', - YAK: 'yield-yak', - JOE: 'joe', - TIME: 'wonderland', - SPELL: 'spell-token', - FXS: 'frax-share', - MIM: 'magic-internet-money', - BUSD: 'binance-usd', - UNI: 'uniswap', - BOO: 'spookyswap', - FTM: 'fantom', - TSHARE: 'tomb-shares', - TOMB: 'tomb', - MAI: 'mimatic', - CELO: 'celo', - CUSD: 'celo-dollar', - CEUR: 'celo-euro', - AYFI: 'aave-yfi', - ALINK: 'aave-link', - ADAI: 'aave-dai', - ABAT: 'aave-bat', - AWETH: 'aave-weth', - AWBTC: 'aave-wbtc', - ASNX: 'aave-snx', - AREN: 'aave-ren', - AUSDT: 'aave-usdt', - AMKR: 'aave-mkr', - AMANA: 'aave-mana', - AZRX: 'aave-zrx', - AKNC: 'aave-knc', - AUSDC: 'aave-usdc', - ASUSD: 'aave-susd', - AUNI: 'aave-uni' -} - -export function makeCoinGeckoPlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - displayName: 'Coingecko', - pluginId: 'coingecko' - }, - - async fetchRates(pairsHint: EdgeRateHint[]): Promise { - const pairs: EdgeRatePair[] = [] - const query = [] - for (const pair of pairsHint) { - // Coingecko is only used to query specific currencies - if (coinGeckoMap[pair.fromCurrency] != null) - query.push(coinGeckoMap[pair.fromCurrency]) - } - try { - const reply = await fetchCors( - `https://api.coingecko.com/api/v3/simple/price?ids=${query.join( - ',' - )}&vs_currencies=usd` - ) - const json = await reply.json() - const rates = asGeckoBulkUsdReply(json) - Object.keys(rates).forEach(rate => { - const fromCurrency = Object.keys(coinGeckoMap).find( - key => typeof key === 'string' && coinGeckoMap[key] === rate - ) - if (fromCurrency != null) - pairs.push({ - fromCurrency, - toCurrency: 'iso:USD', - rate: rates[rate].usd - }) - }) - } catch (e) { - log.warn(`Issue with Coingecko rate data structure ${String(e)}`) - } - return pairs - } - } -} diff --git a/src/rate/coinmonitor.ts b/src/rate/coinmonitor.ts deleted file mode 100644 index 86ba2f2f..00000000 --- a/src/rate/coinmonitor.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asCoinmonitorTickerResponse = asObject({ mediana_prom: asString }) - -export function makeCoinmonitorPlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'coinmonitor', - displayName: 'coinmonitor' - }, - - async fetchRates(pairsHint) { - const pairs = [] - for (const pair of pairsHint) { - if (pair.fromCurrency === 'BTC' && pair.toCurrency === 'iso:ARS') { - try { - const response = await fetchCors( - 'https://ar.coinmonitor.info/api/v3/btc_ars' - ) - const json = await response.json() - const rate = Number(asCoinmonitorTickerResponse(json).mediana_prom) - pairs.push({ - fromCurrency: 'BTC', - toCurrency: 'iso:ARS', - rate - }) - } catch (e) { - log.warn(`Issue with Coinmonitor rate data structure ${String(e)}`) - } - break - } - } - return pairs - } - } -} diff --git a/src/rate/compound.ts b/src/rate/compound.ts deleted file mode 100644 index 2e17f59b..00000000 --- a/src/rate/compound.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { asArray, asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asCToken = asObject({ - cToken: asArray( - asObject({ - exchange_rate: asObject({ - value: asString - }), - underlying_symbol: asString, - symbol: asString - }) - ) -}) - -function fixCurrency(currencyCode: string): string { - return currencyCode.toUpperCase() -} - -export function makeCompoundPlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'compound', - displayName: 'Compound' - }, - - async fetchRates() { - const reply = await fetchCors( - 'https://api.compound.finance/api/v2/ctoken' - ) - const json = asCToken(await reply.json()) - - const pairs = [] - for (const rateInfo of json.cToken) { - const rate = Number(rateInfo.exchange_rate.value) - const toCurrency = fixCurrency(rateInfo.underlying_symbol) - const fromCurrency = fixCurrency(rateInfo.symbol) - pairs.push({ - fromCurrency, - toCurrency, - rate - }) - } - - return pairs - } - } -} diff --git a/src/rate/constantRate.ts b/src/rate/constantRate.ts deleted file mode 100644 index f0ec22e1..00000000 --- a/src/rate/constantRate.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { EdgeRatePlugin } from 'edge-core-js/types' - -export function makeConstantRatePlugin(): EdgeRatePlugin { - return { - rateInfo: { - pluginId: 'constantRate', - displayName: 'ConstantRate' - }, - - async fetchRates() { - // Grab all the pairs which are in USD: - const pairs = [ - { - fromCurrency: 'TESTBTC', - toCurrency: 'iso:USD', - rate: 0.01 - }, - { - fromCurrency: 'WETH', - toCurrency: 'ETH', - rate: 1 - }, - { - fromCurrency: 'iso:BRL', - toCurrency: 'BRZ', - rate: 1 - }, - { - fromCurrency: 'WBTC', - toCurrency: 'BTC', - rate: 1 - }, - // AAVE tokens - { - fromCurrency: 'AYFI', - toCurrency: 'YFI', - rate: 1 - }, - { - fromCurrency: 'ALINK', - toCurrency: 'LINK', - rate: 1 - }, - { - fromCurrency: 'ADAI', - toCurrency: 'DAI', - rate: 1 - }, - { - fromCurrency: 'ABAT', - toCurrency: 'BAT', - rate: 1 - }, - { - fromCurrency: 'AWETH', - toCurrency: 'WETH', - rate: 1 - }, - { - fromCurrency: 'AWBTC', - toCurrency: 'WBTC', - rate: 1 - }, - { - fromCurrency: 'ASNX', - toCurrency: 'SNX', - rate: 1 - }, - { - fromCurrency: 'AREN', - toCurrency: 'REN', - rate: 1 - }, - { - fromCurrency: 'AUSDT', - toCurrency: 'USDT', - rate: 1 - }, - { - fromCurrency: 'AMKR', - toCurrency: 'MKR', - rate: 1 - }, - { - fromCurrency: 'AMANA', - toCurrency: 'MANA', - rate: 1 - }, - { - fromCurrency: 'AZRX', - toCurrency: 'ZRX', - rate: 1 - }, - { - fromCurrency: 'AKNC', - toCurrency: 'KNC', - rate: 1 - }, - { - fromCurrency: 'AUSDC', - toCurrency: 'USDC', - rate: 1 - }, - { - fromCurrency: 'ASUSD', - toCurrency: 'SUSD', - rate: 1 - }, - { - fromCurrency: 'AUNI', - toCurrency: 'UNI', - rate: 1 - }, - // Deprecated tokens - { - fromCurrency: 'ANT', - toCurrency: 'ANTV1', - rate: 1 - }, - { - fromCurrency: 'REPV2', - toCurrency: 'REP', - rate: 1 - }, - // FTM Frapped tokens - { - fromCurrency: 'FUSDT', - toCurrency: 'USDT', - rate: 1 - }, - { - fromCurrency: 'FBTC', - toCurrency: 'BTC', - rate: 1 - }, - { - fromCurrency: 'FETH', - toCurrency: 'ETH', - rate: 1 - }, - // MAI Finance - { - fromCurrency: 'MAI', - toCurrency: 'iso:USD', - rate: 1 - }, - // AVAX wrapped tokens: - { - fromCurrency: 'BUSD.e', - toCurrency: 'BUSD', - rate: 1 - }, - { - fromCurrency: 'DAI.e', - toCurrency: 'DAI', - rate: 1 - }, - { - fromCurrency: 'LINK.e', - toCurrency: 'LINK', - rate: 1 - }, - { - fromCurrency: 'UNI.e', - toCurrency: 'UNI', - rate: 1 - }, - { - fromCurrency: 'USDC.e', - toCurrency: 'USDC', - rate: 1 - }, - { - fromCurrency: 'USDT.e', - toCurrency: 'USDT', - rate: 1 - }, - { - fromCurrency: 'WBTC.e', - toCurrency: 'WBTC', - rate: 1 - } - ] - return pairs - } - } -} diff --git a/src/rate/currencyconverterapi.ts b/src/rate/currencyconverterapi.ts deleted file mode 100644 index 7ea1a72a..00000000 --- a/src/rate/currencyconverterapi.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { asNumber, asObject, asOptional, asString } from 'cleaners' -import { - EdgeCorePluginOptions, - EdgeRatePair, - EdgeRatePlugin -} from 'edge-core-js/types' - -const asInitOptions = asObject({ - apiKey: asString -}) - -const asRates = asObject(asNumber) - -const asCurrencyConverterResponse = asObject({ - status: asOptional(asNumber), - error: asOptional(asString) -}).withRest - -const checkAndPush = (isoCc: string, ccArray: string[]): void => { - if (isoCc !== 'iso:USD' && isoCc.slice(0, 4) === 'iso:') { - const cc = isoCc.slice(4).toUpperCase() - if (!ccArray.includes(`USD_${cc}`)) { - ccArray.push(`USD_${cc}`) - } - } -} - -export function makeCurrencyconverterapiPlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - const { apiKey } = asInitOptions(opts.initOptions) - - return { - rateInfo: { - pluginId: 'currencyconverterapi', - displayName: 'CurrencyConverterAPI' - }, - - async fetchRates(pairsHint): Promise { - pairsHint = pairsHint.concat([ - { fromCurrency: 'iso:USD', toCurrency: 'iso:IMP' }, - { fromCurrency: 'iso:USD', toCurrency: 'iso:IRR' } - ]) - const isoCodesWanted: string[] = [] - for (const pair of pairsHint) { - checkAndPush(pair.fromCurrency, isoCodesWanted) - checkAndPush(pair.toCurrency, isoCodesWanted) - } - - const pairs = [] - const query = isoCodesWanted.join(',') - try { - const response = await fetchCors( - `https://api.currconv.com/api/v7/convert?q=${query}&compact=ultra&apiKey=${apiKey}` - ) - const { status, error, ...rest } = asCurrencyConverterResponse( - await response.json() - ) - const rates: { [cc: string]: number } = rest as {} - if ( - (status != null && status !== 200) || - (error != null && error !== '') || - !response.ok - ) { - throw new Error( - `CurrencyConvertor returned with status: ${JSON.stringify( - status ?? response.status - )} and error: ${JSON.stringify(error)}` - ) - } - for (const rate of Object.keys(asRates(rates))) { - pairs.push({ - fromCurrency: 'iso:USD', - toCurrency: `iso:${rate.split('_')[1]}`, - rate: rates[rate] - }) - } - } catch (e: any) { - log.warn( - `Failed to get ${query} from currencyconverterapi.com`, - e.message - ) - } - return pairs - } - } -} diff --git a/src/rate/edgeRates.ts b/src/rate/edgeRates.ts deleted file mode 100644 index 765675a3..00000000 --- a/src/rate/edgeRates.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asEdgeRatesResponse = asObject({ - exchangeRate: asString -}) - -function checkIfFiat(code: string): boolean { - if (code.includes('iso:')) return true - return false -} - -export function makeEdgeRatesPlugin( - opts: EdgeCorePluginOptions -): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'edgeRates', - displayName: 'EdgeRates' - }, - - async fetchRates(pairsHint) { - const pairs = [] - for (const pair of pairsHint) { - // Skip if neither code is a fiat code - if (!checkIfFiat(pair.fromCurrency) || !checkIfFiat(pair.toCurrency)) - continue - - const fiatFrom = pair.fromCurrency.split(':') - const fiatTo = pair.toCurrency.split(':') - try { - const reply = await fetchCors( - `https://rates1.edge.app/v1/exchangeRate?currency_pair=${fiatFrom[1]}_${fiatTo[1]}` - ) - const jsonData = await reply.json() - const rate = Number(asEdgeRatesResponse(jsonData).exchangeRate) - pairs.push({ - fromCurrency: pair.fromCurrency, - toCurrency: pair.toCurrency, - rate - }) - } catch (e) { - log.warn( - `Issue with EdgeRates rate data structure for ${ - pair.fromCurrency - }/${pair.toCurrency} pair. Error: ${String(e)}` - ) - } - } - return pairs - } - } -} diff --git a/src/rate/nomics.ts b/src/rate/nomics.ts deleted file mode 100644 index ad21152a..00000000 --- a/src/rate/nomics.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { asArray, asObject, asOptional, asString } from 'cleaners' -import { - EdgeCorePluginOptions, - EdgeRatePair, - EdgeRatePlugin -} from 'edge-core-js/types' - -const asInitOptions = asObject({ - apiKey: asString -}) - -const asNomicsResponse = asArray( - asObject({ - price: asOptional(asString), - symbol: asString - }) -) - -const UNIQUE_ID_MAP: { [cc: string]: string } = { - BOO: 'BOO4' -} - -export function makeNomicsPlugin(opts: EdgeCorePluginOptions): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - const { apiKey } = asInitOptions(opts.initOptions) - - if (apiKey == null) { - throw new Error('No Nomics exchange rates API key provided') - } - return { - rateInfo: { - pluginId: 'nomics', - displayName: 'Nomics' - }, - - async fetchRates(pairsHint) { - const pairs: EdgeRatePair[] = [] - - // Create query strings - const queryStrings = [] - let filteredPairs: string[] = [] - for (let i = 0; i < pairsHint.length; i++) { - if (pairsHint[i].fromCurrency.includes('iso:')) continue - if (filteredPairs.some(cc => cc === pairsHint[i].fromCurrency)) continue - filteredPairs.push( - UNIQUE_ID_MAP[pairsHint[i].fromCurrency] ?? pairsHint[i].fromCurrency - ) - if (filteredPairs.length === 100 || i === pairsHint.length - 1) { - queryStrings.push(filteredPairs.join(',')) - filteredPairs = [] - } - } - - for (const query of queryStrings) { - try { - const reply = await fetchCors( - `https://api.nomics.com/v1/currencies/ticker?key=${apiKey}&ids=${query}&convert=USD` - ) - if (reply.status === 429 || reply.status === 401 || !reply.ok) - throw new Error(`Nomics returned with status: ${reply.status}`) - asNomicsResponse(await reply.json()).forEach(rate => { - // When Nomics considers a coin "dead" they don't return a price - if (rate.price != null) - pairs.push({ - fromCurrency: rate.symbol, - toCurrency: 'iso:USD', - rate: Number(rate.price) - }) - }) - } catch (e: any) { - log.warn( - `Issue with Nomics rate data structure. ${String(e.message)}` - ) - } - } - return pairs - } - } -} diff --git a/src/rate/wazirx.ts b/src/rate/wazirx.ts deleted file mode 100644 index a744765a..00000000 --- a/src/rate/wazirx.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { asMap, asObject, asString } from 'cleaners' -import { EdgeCorePluginOptions, EdgeRatePlugin } from 'edge-core-js/types' - -const asWazirxResponse = asMap( - asObject({ - last: asString - }) -) - -type WazirxResponse = ReturnType - -function fixCurrency(currencyCode: string): string { - currencyCode = currencyCode.toUpperCase() - - if (currencyCode === 'BCHABC') currencyCode = 'BCH' - - return currencyCode -} - -export function makeWazirxPlugin(opts: EdgeCorePluginOptions): EdgeRatePlugin { - const { io, log } = opts - const { fetchCors = io.fetch } = io - - return { - rateInfo: { - pluginId: 'wazirx', - displayName: 'WazirX' - }, - - async fetchRates(pairsHint) { - const pairs = [] - let rates: WazirxResponse | undefined - for (const pair of pairsHint) { - // Wazirx is only used to query INR exchange rates - if (pair.toCurrency !== 'iso:INR') continue - - try { - if (rates === undefined) { - const reply = await fetchCors( - 'https://api.wazirx.com/api/v2/tickers' - ) - const json = await reply.json() - rates = asWazirxResponse(json) - } - - const cc = fixCurrency(pair.fromCurrency).toLowerCase() - const currencyPair = `${cc}inr` - if (rates[currencyPair] != null) { - pairs.push({ - fromCurrency: pair.fromCurrency, - toCurrency: 'iso:INR', - rate: Number(rates[currencyPair].last) - }) - } - } catch (e) { - log.warn(`Issue with Wazirx rate data structure ${String(e)}`) - } - } - return pairs - } - } -} diff --git a/test/demo.ts b/test/demo.ts deleted file mode 100644 index 61a06ff0..00000000 --- a/test/demo.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable no-console */ - -import { EdgeCorePluginOptions, EdgeRatePlugin, makeNodeIo } from 'edge-core-js' - -import edgeCorePlugins from '../src/index' - -type EdgeRatePluginFactory = (env: EdgeCorePluginOptions) => EdgeRatePlugin - -const io = makeNodeIo(__dirname) -const log = Object.assign(() => {}, { - error() {}, - warn() {}, - crash() {}, - breadcrumb() {} -}) - -async function showRate( - plugin: EdgeRatePluginFactory, - fromCurrency: string, - toCurrency: string, - initOptions: Object = {} -): Promise { - const instance: EdgeRatePlugin = plugin({ - initOptions, - io, - log, - nativeIo: {}, - pluginDisklet: io.disklet - }) - const pairs = await instance.fetchRates([]) - - const name = instance.rateInfo.displayName - for (const pair of pairs) { - if (pair.fromCurrency === fromCurrency && pair.toCurrency === toCurrency) { - const fromPretty = fromCurrency.replace(/iso:/, '') - const toPretty = toCurrency.replace(/iso:/, '') - console.log(`${name} ${fromPretty} to ${toPretty}: ${pair.rate}`) - } - } -} - -showRate(edgeCorePlugins.coinbase, 'iso:USD', 'BTC').catch(e => console.log(e)) - -// Uncomment and insert key to test: -// showRate(edgeCorePlugins['currencyconverterapi'], 'iso:USD', 'iso:IRR', { -// apiKey: 'xxxx' -// })