BlueWallet/models/fiatUnit.ts

178 lines
5.6 KiB
TypeScript
Raw Normal View History

2021-07-18 15:51:40 +02:00
import untypedFiatUnit from './fiatUnits.json';
2021-07-18 15:51:40 +02:00
export const FiatUnitSource = {
2023-10-22 10:05:35 -04:00
Coinbase: 'Coinbase',
CoinDesk: 'CoinDesk',
2023-03-31 17:12:49 -04:00
CoinGecko: 'CoinGecko',
Kraken: 'Kraken',
Yadio: 'Yadio',
2022-09-24 16:36:06 -04:00
YadioConvert: 'YadioConvert',
2021-07-06 16:07:47 +03:00
Exir: 'Exir',
2024-08-08 13:24:27 -04:00
coinpaprika: 'coinpaprika',
2023-01-28 12:45:35 +00:00
Bitstamp: 'Bitstamp',
2023-10-26 08:44:35 -04:00
BNR: 'BNR',
2021-07-18 15:51:40 +02:00
} as const;
2024-11-08 00:27:04 -04:00
const handleError = (source: string, ticker: string, error: Error) => {
throw new Error(
`Could not update rate for ${ticker} from ${source}: ${error.message}. ` + `Make sure the network you're on has access to ${source}.`,
);
};
const fetchRate = async (url: string): Promise<any> => {
const response = await fetch(url);
return await response.json();
};
2021-07-18 15:51:40 +02:00
const RateExtractors = {
2023-10-22 10:05:35 -04:00
Coinbase: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.coinbase.com/v2/prices/BTC-${ticker.toUpperCase()}/buy`);
const rate = Number(json?.data?.amount);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('Coinbase', ticker, error);
return undefined as never;
2023-10-22 10:05:35 -04:00
}
},
2024-11-08 00:27:04 -04:00
2021-07-18 15:51:40 +02:00
CoinDesk: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.coindesk.com/v1/bpi/currentprice/${ticker}.json`);
const rate = Number(json?.bpi?.[ticker]?.rate_float);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('CoinDesk', ticker, error);
return undefined as never;
}
},
2024-11-08 00:27:04 -04:00
2023-03-31 17:12:49 -04:00
CoinGecko: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=${ticker.toLowerCase()}`);
const rate = Number(json?.bitcoin?.[ticker.toLowerCase()]);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('CoinGecko', ticker, error);
return undefined as never;
2023-03-31 17:12:49 -04:00
}
},
2024-11-08 00:27:04 -04:00
2023-01-28 12:45:35 +00:00
Bitstamp: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://www.bitstamp.net/api/v2/ticker/btc${ticker.toLowerCase()}`);
const rate = Number(json?.last);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('Bitstamp', ticker, error);
return undefined as never;
2023-01-28 12:45:35 +00:00
}
},
2024-11-08 00:27:04 -04:00
Kraken: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.kraken.com/0/public/Ticker?pair=XXBTZ${ticker.toUpperCase()}`);
const rate = Number(json?.result?.[`XXBTZ${ticker.toUpperCase()}`]?.c?.[0]);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('Kraken', ticker, error);
return undefined as never;
}
},
2024-11-08 00:27:04 -04:00
2023-10-26 08:44:35 -04:00
BNR: async (): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const xmlData = await (await fetch('https://www.bnr.ro/nbrfxrates.xml')).text();
const matches = xmlData.match(/<Rate currency="USD">([\d.]+)<\/Rate>/);
2023-10-26 08:44:35 -04:00
if (matches && matches[1]) {
const usdToRonRate = parseFloat(matches[1]);
2024-11-08 00:27:04 -04:00
const btcToUsdRate = await RateExtractors.CoinGecko('USD');
return btcToUsdRate * usdToRonRate;
2023-10-26 08:44:35 -04:00
}
2024-11-08 00:27:04 -04:00
throw new Error('No valid USD to RON rate found');
2023-10-26 08:44:35 -04:00
} catch (error: any) {
2024-11-08 00:27:04 -04:00
handleError('BNR', 'RON', error);
return undefined as never;
2023-10-26 08:44:35 -04:00
}
},
2024-11-08 00:27:04 -04:00
Yadio: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.yadio.io/json/${ticker}`);
const rate = Number(json?.[ticker]?.price);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('Yadio', ticker, error);
return undefined as never;
}
},
2022-09-24 16:36:06 -04:00
YadioConvert: async (ticker: string): Promise<number> => {
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate(`https://api.yadio.io/convert/1/BTC/${ticker}`);
const rate = Number(json?.rate);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('YadioConvert', ticker, error);
return undefined as never;
}
2021-07-06 16:07:47 +03:00
},
Exir: async (ticker: string): Promise<number> => {
2021-07-06 16:07:47 +03:00
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate('https://api.exir.io/v1/ticker?symbol=btc-irt');
const rate = Number(json?.last);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('Exir', ticker, error);
return undefined as never;
2021-07-06 16:07:47 +03:00
}
},
2021-10-14 12:48:16 -04:00
2024-08-08 13:24:27 -04:00
coinpaprika: async (ticker: string): Promise<number> => {
2021-10-14 12:48:16 -04:00
try {
2024-11-08 00:27:04 -04:00
const json = await fetchRate('https://api.coinpaprika.com/v1/tickers/btc-bitcoin?quotes=INR');
const rate = Number(json?.quotes?.INR?.price);
if (!(rate >= 0)) throw new Error('Invalid data received');
return rate;
} catch (error: any) {
handleError('coinpaprika', ticker, error);
return undefined as never;
2024-08-08 13:24:27 -04:00
}
2021-10-14 12:48:16 -04:00
},
2021-07-18 15:51:40 +02:00
} as const;
2020-11-21 19:16:20 -05:00
2024-03-15 23:05:15 +03:00
export type TFiatUnit = {
endPointKey: string;
symbol: string;
locale: string;
2024-05-25 13:21:31 -04:00
country: string;
2024-08-08 13:24:27 -04:00
source: 'CoinDesk' | 'Yadio' | 'Exir' | 'coinpaprika' | 'Bitstamp' | 'Kraken';
2021-07-18 15:51:40 +02:00
};
2024-03-15 23:05:15 +03:00
export type TFiatUnits = {
[key: string]: TFiatUnit;
};
export const FiatUnit = untypedFiatUnit as TFiatUnits;
2024-01-27 09:44:11 -04:00
export type FiatUnitType = {
endPointKey: string;
symbol: string;
locale: string;
2024-05-25 13:21:31 -04:00
country: string;
2024-01-27 09:44:11 -04:00
source: keyof typeof FiatUnitSource;
};
2021-07-18 15:51:40 +02:00
export async function getFiatRate(ticker: string): Promise<number> {
return await RateExtractors[FiatUnit[ticker].source](ticker);
2020-11-20 21:47:13 -05:00
}