<div align="center">
  <h1>Real-Time Currency Converter</h1>
  <p>A powerful TypeScript library supporting dual currency providers for maximum coverage and flexibility</p>
  
  <p>
    <a href="https://www.npmjs.com/package/real-time-currency-converter">
      <img src="https://img.shields.io/npm/v/real-time-currency-converter.svg" alt="npm version">
    </a>
    <a href="https://www.npmjs.com/package/real-time-currency-converter">
      <img src="https://img.shields.io/npm/dt/real-time-currency-converter.svg" alt="npm downloads">
    </a>
    <a href="https://github.com/varadaraj772/real-time-currency-converter/blob/main/LICENSE">
      <img src="https://img.shields.io/npm/l/real-time-currency-converter.svg" alt="license">
    </a>
  </p>

  <p>
    <a href='https://freecurrencyapi.com/'>
      <img src="https://img.shields.io/badge/Powered%20by-FreeCurrencyAPI-blue" alt="Powered by FreeCurrencyAPI">
    </a>
    <a href='https://www.exchangerate-api.com/'>
      <img src="https://img.shields.io/badge/Powered%20by-ExchangeRateAPI-red" alt="Powered by ExchangeRateAPI">
    </a>
  </p>
  
  <p>
    <strong>✨ Dual Provider Support</strong> • 
    <strong>🌍 195+ Currencies</strong> • 
    <strong>⚡ Real-time Rates</strong>
  </p>
</div>

---

## Features

<table>
  <tr>
    <td>✅</td>
    <td><strong>Dual Provider Support</strong></td>
    <td>FreeCurrencyAPI (33 currencies) + ExchangeRate-API (163+ currencies)</td>
  </tr>
  <tr>
    <td>🌍</td>
    <td><strong>Global Coverage</strong></td>
    <td>195+ currencies including exotic ones (KES, AFN, etc.)</td>
  </tr>
  <tr>
    <td>📈</td>
    <td><strong>6,500+ Monthly Requests</strong></td>
    <td>5k from FreeCurrencyAPI + 1.5k from ExchangeRate-API</td>
  </tr>
  <tr>
    <td>⚡</td>
    <td><strong>Real-time + Daily Updates</strong></td>
    <td>Real-time rates + timestamped daily updates</td>
  </tr>
  <tr>
    <td>✅</td>
    <td><strong>TypeScript First</strong></td>
    <td>Full type definitions and IntelliSense</td>
  </tr>
  <tr>
    <td>🛡️</td>
    <td><strong>Smart Fallback</strong></td>
    <td>Choose the best provider for each currency pair</td>
  </tr>
</table>

---

## Installation

**npm**
```npm install real-time-currency-converter```

**yarn**
```yarn add real-time-currency-converter```

**pnpm**
```pnpm add real-time-currency-converter```


---

## 🎯 Choose Your Provider

### FreeCurrencyConverter (High Volume)
- ✅ **5,000 free requests/month**
- ✅ **33 major currencies**
- ✅ **Real-time rates**
- ✅ **Account status tracking**

```
import { FreeCurrencyConverter } from 'real-time-currency-converter';
const converter = new FreeCurrencyConverter('fca_live_xxx');
const result = await converter.convert(100, 'USD', 'EUR');
```

### ExchangeRateConverter (Global Coverage)
- ✅ **163+ currencies worldwide**
- ✅ **Daily updates with timestamps**
- ✅ **Historical data support**
- ✅ **Exotic currency support (KES, AFN, etc.)**

```
import { ExchangeRateConverter } from 'real-time-currency-converter';
const converter = new ExchangeRateConverter('your_exchangerate_key');
const result = await converter.convert(100, 'USD', 'KES');
```

---

## Quick Start

### API Key Setup

<div align="left">
  <p>
    <strong>Choose your provider(s):</strong><br>
    <a href="https://freecurrencyapi.com">
      <img src="https://img.shields.io/badge/FreeCurrencyAPI-5k%20requests%2F33%20currencies-blue?style=for-the-badge" alt="FreeCurrencyAPI">
    </a>
    <a href="https://www.exchangerate-api.com">
      <img src="https://img.shields.io/badge/ExchangeRateAPI-1.5k%20requests%2F163%20currencies-green?style=for-the-badge" alt="ExchangeRate-API">
    </a>
  </p>
  <p><em>Both offer free tiers • No credit card required</em></p>
</div>

### FreeCurrencyAPI (Recommended for Major Currencies)

```
import { FreeCurrencyConverter } from 'real-time-currency-converter';

const converter = new FreeCurrencyConverter('fca_live_xxx');
const result = await converter.convert(100, 'USD', 'EUR');
console.log(${result.convertedAmount} EUR);
```

### ExchangeRate-API (Recommended for Global Coverage)

```
import { ExchangeRateConverter } from 'real-time-currency-converter';

const converter = new ExchangeRateConverter('your_exchangerate_key');
const result = await converter.convert(100, 'USD', 'KES'); // Kenyan Shilling
console.log(${result.convertedAmount} KES);
```

---

## API Reference

### FreeCurrencyConverter

`new FreeCurrencyConverter(apiKey?: string)`

<table>
  <tr>
    <th>Parameter</th>
    <th>Type</th>
    <th>Description</th>
  </tr>
  <tr>
    <td><code>apiKey</code></td>
    <td><code>string</code></td>
    <td>Your FreeCurrencyAPI key (optional, can be set later)</td>
  </tr>
</table>

### ExchangeRateConverter

`new ExchangeRateConverter(apiKey?: string)`

<table>
  <tr>
    <th>Parameter</th>
    <th>Type</th>
    <th>Description</th>
  </tr>
  <tr>
    <td><code>apiKey</code></td>
    <td><code>string</code></td>
    <td>Your ExchangeRate-API key (optional, can be set later)</td>
  </tr>
</table>

### FreeCurrencyConverter Methods

<details>
<summary><strong>init(apiKey: string)</strong></summary>

Initialize or update the API key.
```converter.init('your-freecurrencyapi-key');```

</details>

<details>
<summary><strong>convert(amount, from, to, base?)</strong></summary>

Convert currency with real-time rates.
```
const result = await converter.convert(100, 'USD', 'EUR');
// Returns: ConversionResult
```

**Parameters:**
- `amount` (number): Amount to convert
- `fromCurrency` (string): Source currency code
- `toCurrency` (string): Target currency code
- `baseCurrency` (string, optional): Base currency (default: USD)
</details>

<details>
<summary><strong>getLatestRates(base?, currencies?)</strong></summary>

Get latest exchange rates.
```
const rates = await converter.getLatestRates('USD', ['EUR', 'GBP']);
// Returns: ExchangeRates
```

</details>

<details>
<summary><strong>getCurrencies(currencies?)</strong></summary>

Get ALL supported currencies (33 total)
```
const allCurrencies = await converter.getCurrencies();
// Returns: Record<string, CurrencyInfo> - All 33 currencies

const specificCurrencies = await converter.getCurrencies(['USD', 'EUR', 'GBP']);
// Returns: Record<string, CurrencyInfo> - Only requested currencies

const singleCurrency = await converter.getCurrencies('USD');
// Returns: Record<string, CurrencyInfo> - Only USD
```
</details>

<details>
<summary><strong>getStatus()</strong></summary>

Get account status and quota information.
```
const status = await converter.getStatus();
// Returns: AccountStatus
```

</details>

<details>
<summary><strong>convertMultiple(amount, from, toCurrencies, base?)</strong></summary>

Convert to multiple currencies at once.
```
const results = await converter.convertMultiple(100, 'USD', ['EUR', 'GBP', 'JPY']);
// Returns: ConversionResults[]
```

</details>

### ExchangeRateConverter Methods

<details>
<summary><strong>init(apiKey: string)</strong></summary>

Initialize or update the API key.
```exchangeConverter.init('your-exchangerate-api-key');```

</details>

<details>
<summary><strong>getSupportedCurrencies()</strong></summary>

Get all 163+ supported currencies.
```
const currencies = await exchangeConverter.getSupportedCurrencies();
console.log(Supports ${currencies.length} currencies);
// Returns: string[] - Array of currency codes
```

</details>

<details>
<summary><strong>convert(amount, from, to)</strong></summary>

Convert currency with timestamps.
```
const result = await exchangeConverter.convert(100, 'USD', 'KES');
console.log(Rate updated: ${result.lastUpdated});
// Returns: ConversionResult with lastUpdated timestamp
```

**Parameters:**
- `amount` (number): Amount to convert
- `fromCurrency` (string): Source currency code  
- `toCurrency` (string): Target currency code

</details>

<details>
<summary><strong>getLatestRates(base?, currencies?)</strong></summary>

Get latest exchange rates with timestamps.
```
/ Get all rates for USD base
const allRates = await exchangeConverter.getLatestRates('USD');

// Get specific rates
const rates = await exchangeConverter.getLatestRates('EUR', ['USD', 'GBP', 'KES']);
// Returns: ExchangeRates with lastUpdated
```

</details>

<details>
<summary><strong>convertMultiple(amount, from, toCurrencies)</strong></summary>

Convert to multiple currencies at once.
```
const results = await exchangeConverter.convertMultiple(100, 'USD', ['EUR', 'KES', 'AFN']);
// Returns: ConversionResults[] with timestamps
```

</details>

<details>
<summary><strong>getHistoricalRates(date, base?, currencies?)</strong></summary>

Get historical exchange rates (requires paid plan).
```
const historical = await exchangeConverter.getHistoricalRates('2025-01-01', 'USD', ['EUR', 'GBP']);
// Returns: HistoricalRates
```

</details>

<details>
<summary><strong>isCurrencySupported(currencyCode)</strong></summary>

Check if a currency is supported.
```
const isSupported = await exchangeConverter.isCurrencySupported('KES');
console.log(isSupported); // true
// Returns: boolean
```

</details>

---

## Usage Examples

### FreeCurrencyConverter Examples

#### Basic Currency Conversion
```
import { FreeCurrencyConverter } from "real-time-currency-converter";

const converter = new FreeCurrencyConverter("fca_live_xxx");

try {
  const result = await converter.convert(100, "USD", "EUR");

  console.log({
    amount: result.amount, // 100
    from: result.fromCurrency, // "USD"
    to: result.toCurrency, // "EUR"
    converted: result.convertedAmount, // 84.23
    rate: result.rate, // 0.8423
    provider: result.provider, // "freecurrencyapi"
  });
} catch (error) {
  console.error("Conversion failed:", error.message);
}
```

#### Account Status Monitoring
```
const status = await converter.getStatus();

console.log(`Account ID: ${status.accountId}`);
console.log(`Monthly Usage: ${status.monthlyUsage.used}/${status.monthlyUsage.total}`);
console.log(`Remaining Requests: ${status.monthlyUsage.remaining}`);
console.log(`Usage Percentage: ${status.monthlyUsage.percentage}%`);
```

#### Get Currency Information
```
// Get all supported currencies
const allCurrencies = await converter.getCurrencies();
console.log(`Supports ${Object.keys(allCurrencies).length} currencies`);

// Get specific currency details
const majors = await converter.getCurrencies(["USD", "EUR", "GBP", "JPY"]);
Object.entries(majors).forEach(([code, info]) => {
  console.log(`${code}: ${info.name} (${info.symbol})`);
});
```
#### Multiple Currency Conversion
```
const results = await converter.convertMultiple(1000, "USD", [
  "EUR",
  "GBP",
  "JPY",
  "CAD",
  "AUD",
]);

results.forEach((result) => {
  if ("convertedAmount" in result) {
    console.log(`$1000 USD = ${result.convertedAmount} ${result.toCurrency}`);
  } else {
    console.error(`Failed to convert to ${result.toCurrency}: ${result.error}`);
  }
});
```
### ExchangeRateConverter Examples

#### Basic Currency Conversion with Timestamps
```
import { ExchangeRateConverter } from "real-time-currency-converter";

const converter = new ExchangeRateConverter("your_exchangerate_key");

try {
  const result = await converter.convert(100, "USD", "KES");

  console.log({
    amount: result.amount, // 100
    from: result.fromCurrency, // "USD"
    to: result.toCurrency, // "KES"
    converted: result.convertedAmount, // 12914.44
    rate: result.rate, // 129.1444
    provider: result.provider, // "exchangerateapi"
    lastUpdated: result.lastUpdated, // "Thu, 18 Sep 2025 00:00:01 +0000"
  });
} catch (error) {
  console.error("Conversion failed:", error.message);
}
```

#### Exotic Currency Conversions
```
// African currencies
const kesResult = await converter.convert(1000, "USD", "KES"); // Kenyan Shilling
console.log(`$1000 = ${kesResult.convertedAmount} KES`);

// Asian currencies
const afnResult = await converter.convert(500, "EUR", "AFN"); // Afghan Afghani
console.log(`€500 = ${afnResult.convertedAmount} AFN`);

// European currencies
const allResult = await converter.convert(100, "GBP", "ALL"); // Albanian Lek
console.log(`£100 = ${allResult.convertedAmount} ALL`);
```

#### Get All Supported Currencies
```
const currencies = await converter.getSupportedCurrencies();
console.log(`Total currencies: ${currencies.length}`);
console.log("Sample exotic currencies:",currencies.filter((c) => !["USD", "EUR", "GBP"].includes(c)).slice(0, 10));
```

#### Latest Rates with Filtering
```
// Get rates for specific currencies
const rates = await converter.getLatestRates("USD", [
  "EUR",
  "KES",
  "AFN",
  "ALL",
]);
console.log("Rates from USD:", rates.rates);
console.log("Last updated:", rates.lastUpdated);
```

### Dual Provider Strategy Examples

#### Smart Provider Selection
```
import {
  FreeCurrencyConverter,
  ExchangeRateConverter,
} from "real-time-currency-converter";

const freeConverter = new FreeCurrencyConverter("fca_key");
const exchangeConverter = new ExchangeRateConverter("er_key");

async function smartConvert(amount: number, from: string, to: string) {
  const majorCurrencies = ["USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF"];

  // Use FreeCurrency for major currency pairs (higher quota)
  if (majorCurrencies.includes(from) && majorCurrencies.includes(to)) {
    try {
      console.log("Using FreeCurrencyAPI for major pair...");
      return await freeConverter.convert(amount, from, to);
    } catch (error) {
      console.log("FreeCurrency failed, falling back to ExchangeRate-API...");
    }
  }

  // Use ExchangeRate-API for exotic currencies or fallback
  console.log("Using ExchangeRate-API for broader coverage...");
  return await exchangeConverter.convert(amount, from, to);
}

// Usage
const majorResult = await smartConvert(100, "USD", "EUR"); // Uses FreeCurrency
const exoticResult = await smartConvert(100, "USD", "KES"); // Uses ExchangeRate
```

#### Compare Rates Between Providers
```
async function compareRates(amount: number, from: string, to: string) {
  try {
    const [freeResult, exchangeResult] = await Promise.allSettled([
      freeConverter.convert(amount, from, to),
      exchangeConverter.convert(amount, from, to),
    ]);
    if (
      freeResult.status === "fulfilled" &&
      exchangeResult.status === "fulfilled"
    ) {
      console.log(`FreeCurrency: ${freeResult.value.convertedAmount} ${to}`);
      console.log(
        `ExchangeRate: ${exchangeResult.value.convertedAmount} ${to}`
      );

      const difference = Math.abs(
        freeResult.value.convertedAmount - exchangeResult.value.convertedAmount
      );
      console.log(`Difference: ${difference.toFixed(4)} ${to}`);
    }
  } catch (error) {
    console.error("Comparison failed:", error);
  }
}

await compareRates(1000, "USD", "EUR");
```

---

## Integration Examples

### React Hook for Dual Providers
```
import { useState } from "react";
import {
  FreeCurrencyConverter,
  ExchangeRateConverter,
} from "real-time-currency-converter";

function useDualCurrencyConverter(freeApiKey: string, exchangeApiKey: string) {
  const [freeConverter] = useState(() => new FreeCurrencyConverter(freeApiKey));
  const [exchangeConverter] = useState(
    () => new ExchangeRateConverter(exchangeApiKey)
  );

  const smartConvert = async (
    amount: number,
    from: string,
    to: string,
    preferredProvider?: "free" | "exchange"
  ) => {
    if (preferredProvider === "exchange") {
      return await exchangeConverter.convert(amount, from, to);
    }
    // Try FreeCurrency first for major pairs
    const majorCurrencies = ["USD", "EUR", "GBP", "JPY"];
    if (majorCurrencies.includes(from) && majorCurrencies.includes(to)) {
      try {
        return await freeConverter.convert(amount, from, to);
      } catch (error) {
        console.log("Falling back to ExchangeRate-API...");
      }
    }

    return await exchangeConverter.convert(amount, from, to);
  };

  return { smartConvert, freeConverter, exchangeConverter };
}

export default useDualCurrencyConverter;
```

### Next.js API Route for Both Providers
```
// api/currency/convert.ts
import {
  FreeCurrencyConverter,
  ExchangeRateConverter,
} from "real-time-currency-converter";

const freeConverter = new FreeCurrencyConverter(
  process.env.FREE_CURRENCY_API_KEY
);
const exchangeConverter = new ExchangeRateConverter(
  process.env.EXCHANGE_RATE_API_KEY
);

export default async function handler(req: any, res: any) {
  if (req.method !== "POST") {
    return res.status(405).json({ error: "Method not allowed" });
  }

  const { amount, from, to, provider = "auto" } = req.body;

  try {
    let result;
    if (provider === "exchange") {
      result = await exchangeConverter.convert(amount, from, to);
    } else if (provider === "free") {
      result = await freeConverter.convert(amount, from, to);
    } else {
      // Auto-select provider
      const majorCurrencies = ["USD", "EUR", "GBP", "JPY"];
      if (majorCurrencies.includes(from) && majorCurrencies.includes(to)) {
        try {
          result = await freeConverter.convert(amount, from, to);
        } catch {
          result = await exchangeConverter.convert(amount, from, to);
        }
      } else {
        result = await exchangeConverter.convert(amount, from, to);
      }
    }

    res.status(200).json(result);
  } catch (error) {
    res.status(500).json({ error: error });
  }
}
```

---

## 🌍 Supported Currencies

<div align="center">
  <table>
    <tr>
      <td><strong>Provider</strong></td>
      <td><strong>Currencies</strong></td>
      <td><strong>Best For</strong></td>
    </tr>
    <tr>
      <td><strong>FreeCurrencyAPI</strong></td>
      <td>33 major currencies</td>
      <td>High-volume major currency pairs</td>
    </tr>
    <tr>
      <td><strong>ExchangeRate-API</strong></td>
      <td>163+ global currencies</td>
      <td>Exotic currencies & global coverage</td>
    </tr>
  </table>
</div>

### Major Currencies (Both Providers)
<div align="center">
  <table>
    <tr>
      <td><strong>🇺🇸 USD</strong> - US Dollar</td>
      <td><strong>🇪🇺 EUR</strong> - Euro</td>
      <td><strong>🇬🇧 GBP</strong> - British Pound</td>
    </tr>
    <tr>
      <td><strong>🇯🇵 JPY</strong> - Japanese Yen</td>
      <td><strong>🇨🇦 CAD</strong> - Canadian Dollar</td>
      <td><strong>🇦🇺 AUD</strong> - Australian Dollar</td>
    </tr>
    <tr>
      <td><strong>🇨🇭 CHF</strong> - Swiss Franc</td>
      <td><strong>🇨🇳 CNY</strong> - Chinese Yuan</td>
      <td><strong>🇮🇳 INR</strong> - Indian Rupee</td>
    </tr>
  </table>
</div>

### Exotic Currencies (ExchangeRate-API Only)
<div align="center">
  <table>
    <tr>
      <td><strong>🇰🇪 KES</strong> - Kenyan Shilling</td>
      <td><strong>🇦🇫 AFN</strong> - Afghan Afghani</td>
      <td><strong>🇦🇱 ALL</strong> - Albanian Lek</td>
    </tr>
    <tr>
      <td><strong>🇦🇴 AOA</strong> - Angolan Kwanza</td>
      <td><strong>🇦🇲 AMD</strong> - Armenian Dram</td>
      <td><strong>🇧🇩 BDT</strong> - Bangladeshi Taka</td>
    </tr>
  </table>
</div>

<p align="left">
  <em>...and 150+ more exotic currencies!</em>
</p>

---

## TypeScript Support

Full TypeScript definitions included:
```
interface ConversionResult {
  amount: number;
  fromCurrency: string;
  toCurrency: string;
  convertedAmount: number;
  rate: number;
  baseCurrency?: string;
  provider?: "freecurrencyapi" | "exchangerateapi";
  lastUpdated?: string;
}

interface AccountStatus {
  accountId: number;
  quotas: {
    month: { total: number; used: number; remaining: number };
    grace: { total: number; used: number; remaining: number };
  };
  monthlyUsage: {
    total: number;
    used: number;
    remaining: number;
    percentage: string;
  };
}
```

---

## ⚡ Performance & Limits

<div align="center">
  <table>
    <tr>
      <th>Provider</th>
      <th>Monthly Requests</th>
      <th>Currencies</th>
      <th>Update Frequency</th>
    </tr>
    <tr>
      <td><strong>FreeCurrencyAPI</strong></td>
      <td>5,000 free</td>
      <td>33 major</td>
      <td>Real-time</td>
    </tr>
    <tr>
      <td><strong>ExchangeRate-API</strong></td>
      <td>1,500 free</td>
      <td>163+ global</td>
      <td>Daily with timestamps</td>
    </tr>
    <tr>
      <td><strong>Combined Total</strong></td>
      <td><strong>6,500 requests</strong></td>
      <td><strong>195+ currencies</strong></td>
      <td><strong>Flexible</strong></td>
    </tr>
  </table>
</div>

---

## 💡 Smart Usage Patterns

### Strategy 1: Provider-Specific Usage
```
// For high-volume major currency pairs
const majorConverter = new FreeCurrencyConverter("fca_key");
const majorResult = await majorConverter.convert(100, "USD", "EUR");

// For exotic currencies
const globalConverter = new ExchangeRateConverter("er_key");
const exoticResult = await globalConverter.convert(100, "USD", "KES");
```

### Strategy 2: Fallback Pattern
```
async function smartConvert(amount, from, to) {
  try {
    // Try FreeCurrency first for major pairs
    if (
      ["USD", "EUR", "GBP", "JPY"].includes(from) &&
      ["USD", "EUR", "GBP", "JPY"].includes(to)
    ) {
      return await majorConverter.convert(amount, from, to);
    }
  } catch (error) {
    console.log("Falling back to ExchangeRate-API...");
  }

  // Fallback to ExchangeRate-API for broader coverage
  return await globalConverter.convert(amount, from, to);
}
```

---

## Development

<details>
<summary><strong>Clone and Setup</strong></summary>
```
git clone https://github.com/varadaraj772/real-time-currency-converter.git
cd real-time-currency-converter
npm install
```
</details>

<details>
<summary><strong>Build</strong></summary>
```npm run build```
</details>

<details>
<summary><strong>Test</strong></summary>
```npm test```
</details>

---

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

<div align="left">
  <p>
    <a href="https://github.com/varadaraj772/real-time-currency-converter/issues">Report Bug</a> •
    <a href="https://github.com/varadaraj772/real-time-currency-converter/issues">Request Feature</a> •
    <a href="https://github.com/varadaraj772/real-time-currency-converter/pulls">Submit PR</a>
  </p>
</div>

---

## License

This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.

---

<div align="left">
  <p>
    <strong>Made by <a href="https://github.com/varadaraj772">Varadaraj</a></strong>
  </p>
  
  <p>
    <a href="https://github.com/varadaraj772/real-time-currency-converter">⭐ Star this project</a> if you found it helpful!
  </p>
</div>
