// Currency exchange rate API // Uses free exchangerate.host API import axios from 'axios' interface ExchangeRates { USD: number CNY: number IRR: number } interface CachedRates { rates: ExchangeRates timestamp: number } const CACHE_DURATION = 60 * 60 * 1000 // 1 hour in milliseconds // Fallback rates if API fails (approximate) const FALLBACK_RATES: ExchangeRates = { USD: 100, // 1 USD = 100 RUB CNY: 14, // 1 CNY = 14 RUB IRR: 0.0024, // 1 IRR = 0.0024 RUB (or 1 RUB = ~420 IRR) } let cachedRates: CachedRates | null = null export const currencyApi = { // Get all exchange rates (RUB to other currencies) getExchangeRates: async (): Promise => { // Check cache first if (cachedRates && Date.now() - cachedRates.timestamp < CACHE_DURATION) { return cachedRates.rates } try { // Try primary API (exchangerate.host) - get RUB based rates const response = await axios.get<{ success?: boolean rates?: { USD?: number; CNY?: number; IRR?: number } }>('https://api.exchangerate.host/latest', { params: { base: 'RUB', symbols: 'USD,CNY,IRR' }, }) if (response.data.success && response.data.rates) { // API returns how much of each currency equals 1 RUB // We need the inverse: how many RUB equals 1 of each currency const rates: ExchangeRates = { USD: response.data.rates.USD ? 1 / response.data.rates.USD : FALLBACK_RATES.USD, CNY: response.data.rates.CNY ? 1 / response.data.rates.CNY : FALLBACK_RATES.CNY, IRR: response.data.rates.IRR ? 1 / response.data.rates.IRR : FALLBACK_RATES.IRR, } cachedRates = { rates, timestamp: Date.now() } return rates } // Try backup API (open.er-api.com) const backupResponse = await axios.get<{ rates?: { USD?: number; CNY?: number; IRR?: number } }>('https://open.er-api.com/v6/latest/RUB') if (backupResponse.data.rates) { const rates: ExchangeRates = { USD: backupResponse.data.rates.USD ? 1 / backupResponse.data.rates.USD : FALLBACK_RATES.USD, CNY: backupResponse.data.rates.CNY ? 1 / backupResponse.data.rates.CNY : FALLBACK_RATES.CNY, IRR: backupResponse.data.rates.IRR ? 1 / backupResponse.data.rates.IRR : FALLBACK_RATES.IRR, } cachedRates = { rates, timestamp: Date.now() } return rates } // Return fallback rates if both APIs fail return FALLBACK_RATES } catch (error) { console.warn('Failed to fetch exchange rates, using fallback:', error) return FALLBACK_RATES } }, // Convert RUB to target currency convertFromRub: (rubAmount: number, targetCurrency: keyof ExchangeRates, rates: ExchangeRates): number => { const rate = rates[targetCurrency] if (!rate || rate <= 0) { return rubAmount / FALLBACK_RATES[targetCurrency] } return rubAmount / rate }, // Convert from target currency to RUB convertToRub: (amount: number, sourceCurrency: keyof ExchangeRates, rates: ExchangeRates): number => { const rate = rates[sourceCurrency] if (!rate || rate <= 0) { return amount * FALLBACK_RATES[sourceCurrency] } return amount * rate }, } export type { ExchangeRates }