REF: currency rates loader, add LPB new rate source

This commit is contained in:
Ivan Vershigora 2021-03-26 18:12:41 +03:00
parent ed18f475ba
commit c0c4d7c411
3 changed files with 89 additions and 72 deletions

View file

@ -1,11 +1,12 @@
import Frisbee from 'frisbee';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AppStorage } from '../class';
import { FiatServerResponse, FiatUnit } from '../models/fiatUnit';
import DefaultPreference from 'react-native-default-preference';
import RNWidgetCenter from 'react-native-widget-center';
import * as RNLocalize from 'react-native-localize';
const BigNumber = require('bignumber.js');
import BigNumber from 'bignumber.js';
import { AppStorage } from '../class';
import { FiatUnit, getFiatRate } from '../models/fiatUnit';
let preferredFiatCurrency = FiatUnit.USD;
const exchangeRates = {};
@ -56,14 +57,9 @@ async function updateExchangeRate() {
}
}
let response;
const fiatServerResponse = new FiatServerResponse(preferredFiatCurrency);
let rate;
try {
const api = new Frisbee({
baseURI: fiatServerResponse.baseURI(),
});
response = await api.get(fiatServerResponse.endPoint());
fiatServerResponse.isErrorFound(response);
rate = await getFiatRate(preferredFiatCurrency.endPointKey);
} catch (Err) {
console.warn(Err);
const lastSavedExchangeRate = JSON.parse(await AsyncStorage.getItem(AppStorage.EXCHANGE_RATES));
@ -72,7 +68,7 @@ async function updateExchangeRate() {
}
exchangeRates[STRUCT.LAST_UPDATED] = +new Date();
exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = fiatServerResponse.rate(response);
exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = rate;
await AsyncStorage.setItem(AppStorage.EXCHANGE_RATES, JSON.stringify(exchangeRates));
await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(preferredFiatCurrency));
await setPrefferedCurrency(preferredFiatCurrency);

View file

@ -1,15 +1,71 @@
export const FiatUnitSource = Object.freeze({ CoinDesk: 'CoinDesk', Yadio: 'Yadio' });
import Frisbee from 'frisbee';
export const FiatUnitSource = Object.freeze({
CoinDesk: 'CoinDesk',
Yadio: 'Yadio',
BitcoinduLiban: 'BitcoinduLiban',
});
const RateExtractors = Object.freeze({
CoinDesk: async ticker => {
const api = new Frisbee({ baseURI: 'https://api.coindesk.com' });
const res = await api.get(`/v1/bpi/currentprice/${ticker}.json`);
if (res.err) throw new Error(`Could not update rate for ${ticker}: ${res.err}`);
let json;
try {
json = typeof res.body === 'string' ? JSON.parse(res.body) : res.body;
} catch (e) {
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
}
let rate = json?.bpi?.[ticker]?.rate_float; // eslint-disable-line
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;
},
Yadio: async ticker => {
const api = new Frisbee({ baseURI: 'https://api.yadio.io/json' });
const res = await api.get(`/${ticker}`);
if (res.err) throw new Error(`Could not update rate for ${ticker}: ${res.err}`);
let json;
try {
json = typeof res.body === 'string' ? JSON.parse(res.body) : res.body;
} catch (e) {
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;
},
BitcoinduLiban: async ticker => {
const api = new Frisbee({ baseURI: 'https://bitcoinduliban.org' });
const res = await api.get('/api.php?key=lbpusd');
if (res.err) throw new Error(`Could not update rate for ${ticker}: ${res.err}`);
let json;
try {
json = typeof res.body === 'string' ? JSON.parse(res.body) : res.body;
} catch (e) {
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
}
let rate = json?.[`BTC/${ticker}`];
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;
},
});
export const FiatUnit = Object.freeze({
USD: { endPointKey: 'USD', symbol: '$', locale: 'en-US', source: FiatUnitSource.CoinDesk },
ARS: {
endPointKey: 'ARS',
symbol: '$',
locale: 'es-AR',
dataSource: 'https://api.yadio.io/json',
rateKey: 'ARS',
source: FiatUnitSource.Yadio,
},
ARS: { endPointKey: 'ARS', symbol: '$', locale: 'es-AR', source: FiatUnitSource.Yadio },
AUD: { endPointKey: 'AUD', symbol: '$', locale: 'en-AU', source: FiatUnitSource.CoinDesk },
BRL: { endPointKey: 'BRL', symbol: 'R$', locale: 'pt-BR', source: FiatUnitSource.CoinDesk },
CAD: { endPointKey: 'CAD', symbol: '$', locale: 'en-CA', source: FiatUnitSource.CoinDesk },
@ -27,7 +83,7 @@ export const FiatUnit = Object.freeze({
JPY: { endPointKey: 'JPY', symbol: '¥', locale: 'ja-JP', source: FiatUnitSource.CoinDesk },
KES: { endPointKey: 'KES', symbol: 'Ksh', locale: 'en-KE', source: FiatUnitSource.CoinDesk },
KRW: { endPointKey: 'KRW', symbol: '₩', locale: 'ko-KR', source: FiatUnitSource.CoinDesk },
LBP: { endPointKey: 'LBP', symbol: 'ل.ل.', locale: 'ar-LB', source: FiatUnitSource.CoinDesk },
LBP: { endPointKey: 'LBP', symbol: 'ل.ل.', locale: 'ar-LB', source: FiatUnitSource.BitcoinduLiban },
MXN: { endPointKey: 'MXN', symbol: '$', locale: 'es-MX', source: FiatUnitSource.CoinDesk },
MYR: { endPointKey: 'MYR', symbol: 'RM', locale: 'ms-MY', source: FiatUnitSource.CoinDesk },
NGN: { endPointKey: 'NGN', symbol: '₦', locale: 'en-NG', source: FiatUnitSource.CoinDesk },
@ -45,57 +101,10 @@ export const FiatUnit = Object.freeze({
UAH: { endPointKey: 'UAH', symbol: '₴', locale: 'uk-UA', source: FiatUnitSource.CoinDesk },
UYU: { endPointKey: 'UYU', symbol: '$', locale: 'es-UY', source: FiatUnitSource.CoinDesk },
VEF: { endPointKey: 'VEF', symbol: 'Bs.', locale: 'es-VE', source: FiatUnitSource.CoinDesk },
VES: {
endPointKey: 'VES',
symbol: 'Bs.',
locale: 'es-VE',
dataSource: 'https://api.yadio.io/json',
rateKey: 'VES',
source: FiatUnitSource.Yadio,
},
VES: { endPointKey: 'VES', symbol: 'Bs.', locale: 'es-VE', source: FiatUnitSource.Yadio },
ZAR: { endPointKey: 'ZAR', symbol: 'R', locale: 'en-ZA', source: FiatUnitSource.CoinDesk },
});
export class FiatServerResponse {
constructor(fiatUnit) {
this.fiatUnit = fiatUnit;
}
baseURI = () => {
if (this.fiatUnit.dataSource) {
return this.fiatUnit.dataSource;
} else {
return 'https://api.coindesk.com';
}
};
endPoint = () => {
if (this.fiatUnit.dataSource) {
return `/${this.fiatUnit.endPointKey}`;
} else {
return '/v1/bpi/currentprice/' + this.fiatUnit.endPointKey + '.json';
}
};
rate = response => {
const json = typeof response.body === 'string' ? JSON.parse(response.body) : response.body;
if (this.fiatUnit.dataSource) {
return json[this.fiatUnit.rateKey].price * 1;
} else {
return json.bpi[this.fiatUnit.endPointKey].rate_float * 1;
}
};
isErrorFound = response => {
const json = typeof response.body === 'string' ? JSON.parse(response.body) : response.body;
if (this.fiatUnit.dataSource) {
if (!json || !json[this.fiatUnit.rateKey]) {
throw new Error('Could not update currency rate: ' + response.err);
}
} else {
if (!json || !json.bpi || !json.bpi[this.fiatUnit.endPointKey] || !json.bpi[this.fiatUnit.endPointKey].rate_float) {
throw new Error('Could not update currency rate: ' + response.err);
}
}
};
export async function getFiatRate(ticker) {
return await RateExtractors[FiatUnit[ticker].source](ticker);
}

View file

@ -28,5 +28,17 @@ describe('currency', () => {
assert.strictEqual(preferred.endPointKey, 'EUR');
cur = JSON.parse(await AsyncStorage.getItem(AppStorage.EXCHANGE_RATES));
assert.ok(cur.BTC_EUR > 0);
// test Yadio rate source
await currency.setPrefferedCurrency(FiatUnit.ARS);
await currency.startUpdater();
cur = JSON.parse(await AsyncStorage.getItem(AppStorage.EXCHANGE_RATES));
assert.ok(cur.BTC_ARS > 0);
// test BitcoinduLiban rate source
await currency.setPrefferedCurrency(FiatUnit.LBP);
await currency.startUpdater();
cur = JSON.parse(await AsyncStorage.getItem(AppStorage.EXCHANGE_RATES));
assert.ok(cur.BTC_LBP > 0);
});
});