2021-07-18 15:51:40 +02:00
|
|
|
import untypedFiatUnit from './fiatUnits.json';
|
2021-03-26 16:12:41 +01:00
|
|
|
|
2021-07-18 15:51:40 +02:00
|
|
|
export const FiatUnitSource = {
|
2023-10-22 16:05:35 +02:00
|
|
|
Coinbase: 'Coinbase',
|
2021-03-26 16:12:41 +01:00
|
|
|
CoinDesk: 'CoinDesk',
|
2023-03-31 23:12:49 +02:00
|
|
|
CoinGecko: 'CoinGecko',
|
2021-03-26 16:12:41 +01:00
|
|
|
Yadio: 'Yadio',
|
2022-09-24 22:36:06 +02:00
|
|
|
YadioConvert: 'YadioConvert',
|
2021-07-06 15:07:47 +02:00
|
|
|
Exir: 'Exir',
|
2021-10-14 18:48:16 +02:00
|
|
|
wazirx: 'wazirx',
|
2023-01-28 13:45:35 +01:00
|
|
|
Bitstamp: 'Bitstamp',
|
2023-10-26 14:44:35 +02:00
|
|
|
BNR: 'BNR',
|
2021-07-18 15:51:40 +02:00
|
|
|
} as const;
|
2021-03-26 16:12:41 +01:00
|
|
|
|
2021-07-18 15:51:40 +02:00
|
|
|
const RateExtractors = {
|
2023-10-22 16:05:35 +02:00
|
|
|
Coinbase: async (ticker: string): Promise<number> => {
|
|
|
|
let json;
|
|
|
|
try {
|
|
|
|
const res = await fetch(`https://api.coinbase.com/v2/prices/BTC-${ticker.toUpperCase()}/buy`);
|
|
|
|
json = await res.json();
|
|
|
|
} catch (e: any) {
|
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
|
|
|
let rate = json?.data?.amount;
|
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2021-07-18 15:51:40 +02:00
|
|
|
CoinDesk: async (ticker: string): Promise<number> => {
|
2021-03-26 16:12:41 +01:00
|
|
|
let json;
|
|
|
|
try {
|
2021-09-09 19:02:15 +02:00
|
|
|
const res = await fetch(`https://api.coindesk.com/v1/bpi/currentprice/${ticker}.json`);
|
|
|
|
json = await res.json();
|
2022-01-27 17:20:25 +01:00
|
|
|
} catch (e: any) {
|
2021-03-26 16:12:41 +01:00
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
2023-07-25 15:50:04 +02:00
|
|
|
let rate = json?.bpi?.[ticker]?.rate_float;
|
2021-03-26 16:12:41 +01:00
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2023-03-31 23:12:49 +02:00
|
|
|
CoinGecko: async (ticker: string): Promise<number> => {
|
|
|
|
let json;
|
|
|
|
try {
|
|
|
|
const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=${ticker.toLowerCase()}`);
|
|
|
|
json = await res.json();
|
|
|
|
} catch (e: any) {
|
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
2023-07-25 15:50:04 +02:00
|
|
|
const rate = json?.bitcoin?.[ticker] || json?.bitcoin?.[ticker.toLowerCase()];
|
2023-03-31 23:12:49 +02:00
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2023-01-28 13:45:35 +01:00
|
|
|
Bitstamp: async (ticker: string): Promise<number> => {
|
|
|
|
let json;
|
|
|
|
try {
|
|
|
|
const res = await fetch(`https://www.bitstamp.net/api/v2/ticker/btc${ticker.toLowerCase()}`);
|
|
|
|
json = await res.json();
|
|
|
|
} catch (e: any) {
|
|
|
|
throw new Error(`Could not update rate from Bitstamp for ${ticker}: ${e.message}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(json)) {
|
|
|
|
throw new Error(`Unsupported ticker for Bitstamp: ${ticker}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
let rate = +json?.last;
|
|
|
|
if (!rate) throw new Error(`Could not update rate from Bitstamp for ${ticker}: data is wrong`);
|
|
|
|
|
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate from Bitstamp for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2023-10-26 14:44:35 +02:00
|
|
|
BNR: async (): Promise<number> => {
|
|
|
|
try {
|
|
|
|
const response = await fetch('https://www.bnr.ro/nbrfxrates.xml');
|
|
|
|
const xmlData = await response.text();
|
|
|
|
|
2024-01-20 23:38:17 +01:00
|
|
|
// Fetching USD to RON rate
|
|
|
|
const pattern = /<Rate currency="USD">([\d.]+)<\/Rate>/;
|
2023-10-26 14:44:35 +02:00
|
|
|
const matches = xmlData.match(pattern);
|
2023-01-28 13:45:35 +01:00
|
|
|
|
2023-10-26 14:44:35 +02:00
|
|
|
if (matches && matches[1]) {
|
2024-01-20 23:38:17 +01:00
|
|
|
const usdToRonRate = parseFloat(matches[1]);
|
|
|
|
if (!isNaN(usdToRonRate) && usdToRonRate > 0) {
|
|
|
|
// Fetch BTC to USD rate using CoinGecko extractor
|
|
|
|
const btcToUsdRate = await RateExtractors.CoinGecko('USD');
|
2023-10-26 14:44:35 +02:00
|
|
|
|
2024-01-20 23:38:17 +01:00
|
|
|
// Convert BTC to RON using the USD to RON exchange rate
|
|
|
|
return btcToUsdRate * usdToRonRate;
|
2023-10-26 14:44:35 +02:00
|
|
|
}
|
|
|
|
}
|
2024-01-20 23:38:17 +01:00
|
|
|
throw new Error('Could not find a valid exchange rate for USD to RON');
|
2023-10-26 14:44:35 +02:00
|
|
|
} catch (error: any) {
|
|
|
|
throw new Error(`Could not fetch RON exchange rate: ${error.message}`);
|
|
|
|
}
|
|
|
|
},
|
2021-09-09 19:02:15 +02:00
|
|
|
Yadio: async (ticker: string): Promise<number> => {
|
2021-03-26 16:12:41 +01:00
|
|
|
let json;
|
|
|
|
try {
|
2021-09-09 19:02:15 +02:00
|
|
|
const res = await fetch(`https://api.yadio.io/json/${ticker}`);
|
|
|
|
json = await res.json();
|
2022-01-27 17:20:25 +01:00
|
|
|
} catch (e: any) {
|
2021-03-26 16:12:41 +01:00
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
|
|
|
let rate = json?.[ticker]?.price;
|
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
|
|
|
|
2022-09-24 22:36:06 +02:00
|
|
|
YadioConvert: async (ticker: string): Promise<number> => {
|
2021-03-26 16:12:41 +01:00
|
|
|
let json;
|
|
|
|
try {
|
2022-09-24 22:36:06 +02:00
|
|
|
const res = await fetch(`https://api.yadio.io/convert/1/BTC/${ticker}`);
|
2021-09-09 19:02:15 +02:00
|
|
|
json = await res.json();
|
2022-01-27 17:20:25 +01:00
|
|
|
} catch (e: any) {
|
2021-03-26 16:12:41 +01:00
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
2022-09-24 22:36:06 +02:00
|
|
|
let rate = json?.rate;
|
2021-03-26 16:12:41 +01:00
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
2021-07-06 15:07:47 +02:00
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
|
|
|
|
2021-09-09 19:02:15 +02:00
|
|
|
Exir: async (ticker: string): Promise<number> => {
|
2021-07-06 15:07:47 +02:00
|
|
|
let json;
|
|
|
|
try {
|
2021-09-09 19:02:15 +02:00
|
|
|
const res = await fetch('https://api.exir.io/v1/ticker?symbol=btc-irt');
|
|
|
|
json = await res.json();
|
2022-01-27 17:20:25 +01:00
|
|
|
} catch (e: any) {
|
2021-07-06 15:07:47 +02:00
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
|
|
|
let rate = json?.last;
|
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
2021-03-26 16:12:41 +01:00
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2021-10-14 18:48:16 +02:00
|
|
|
|
|
|
|
wazirx: async (ticker: string): Promise<number> => {
|
|
|
|
let json;
|
|
|
|
try {
|
|
|
|
const res = await fetch(`https://api.wazirx.com/api/v2/tickers/btcinr`);
|
|
|
|
json = await res.json();
|
2022-01-27 17:20:25 +01:00
|
|
|
} catch (e: any) {
|
2021-10-14 18:48:16 +02:00
|
|
|
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
|
|
|
}
|
2023-07-25 15:50:04 +02:00
|
|
|
let rate = json?.ticker?.buy;
|
2021-10-14 18:48:16 +02:00
|
|
|
if (!rate) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
|
|
|
|
rate = Number(rate);
|
|
|
|
if (!(rate >= 0)) throw new Error(`Could not update rate for ${ticker}: data is wrong`);
|
|
|
|
return rate;
|
|
|
|
},
|
2021-07-18 15:51:40 +02:00
|
|
|
} as const;
|
2020-11-22 01:16:20 +01:00
|
|
|
|
2021-07-18 15:51:40 +02:00
|
|
|
type FiatUnit = {
|
|
|
|
[key: string]: {
|
|
|
|
endPointKey: string;
|
|
|
|
symbol: string;
|
|
|
|
locale: string;
|
2023-01-28 13:45:35 +01:00
|
|
|
source: 'CoinDesk' | 'Yadio' | 'Exir' | 'wazirx' | 'Bitstamp';
|
2021-07-18 15:51:40 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
export const FiatUnit = untypedFiatUnit as FiatUnit;
|
2020-11-20 03:27:34 +01:00
|
|
|
|
2024-01-27 14:44:11 +01:00
|
|
|
export type FiatUnitType = {
|
|
|
|
endPointKey: string;
|
|
|
|
symbol: string;
|
|
|
|
locale: string;
|
|
|
|
source: keyof typeof FiatUnitSource;
|
|
|
|
};
|
|
|
|
|
2021-07-18 15:51:40 +02:00
|
|
|
export async function getFiatRate(ticker: string): Promise<number> {
|
2021-03-26 16:12:41 +01:00
|
|
|
return await RateExtractors[FiatUnit[ticker].source](ticker);
|
2020-11-21 03:47:13 +01:00
|
|
|
}
|