zurri / src /services /exchangeRateService.ts
nexusbert's picture
push
ef85da9
import axios from 'axios';
export class ExchangeRateService {
private cachedRate: number | null = null;
private cacheExpiry: Date | null = null;
private readonly CACHE_DURATION_MS = 60 * 60 * 1000;
private readonly FALLBACK_RATE: number;
constructor() {
this.FALLBACK_RATE = parseFloat(process.env.NGN_PER_USD || '750');
}
async getNGNToUSDRate(): Promise<number> {
if (this.cachedRate && this.cacheExpiry && new Date() < this.cacheExpiry) {
console.log('Using cached exchange rate:', this.cachedRate);
return this.cachedRate;
}
try {
const rate = await this.fetchExchangeRate();
this.cachedRate = rate;
this.cacheExpiry = new Date(Date.now() + this.CACHE_DURATION_MS);
console.log('Fetched new exchange rate:', rate);
return rate;
} catch (error) {
console.error('Failed to fetch exchange rate, using fallback:', error);
return this.FALLBACK_RATE;
}
}
private async fetchExchangeRate(): Promise<number> {
try {
const response = await axios.get('https://api.exchangerate-api.com/v4/latest/USD', {
timeout: 5000,
});
const rate = response.data.rates?.NGN;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('ExchangeRate-API failed, trying alternative...');
}
// Option 2: CurrencyAPI (requires free API key, but more reliable)
const currencyApiKey = process.env.CURRENCY_API_KEY;
if (currencyApiKey) {
try {
const response = await axios.get(
`https://api.currencyapi.com/v3/latest?apikey=${currencyApiKey}&currencies=NGN&base_currency=USD`,
{ timeout: 5000 }
);
const rate = response.data.data?.NGN?.value;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('CurrencyAPI failed, trying alternative...');
}
}
// Option 3: Fixer.io (requires API key)
const fixerApiKey = process.env.FIXER_API_KEY;
if (fixerApiKey) {
try {
const response = await axios.get(
`https://api.fixer.io/latest?access_key=${fixerApiKey}&base=USD&symbols=NGN`,
{ timeout: 5000 }
);
const rate = response.data.rates?.NGN;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('Fixer.io failed, using fallback...');
}
}
// If all APIs fail, throw error to use fallback
throw new Error('All exchange rate APIs failed');
}
/**
* Get the fallback rate (from env or default)
*/
getFallbackRate(): number {
return this.FALLBACK_RATE;
}
/**
* Clear the cache (useful for testing or manual refresh)
*/
clearCache(): void {
this.cachedRate = null;
this.cacheExpiry = null;
}
}