mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 13:28:11 +00:00
feat: refactor exchange rate handling by integrating new ExchangeService and removing CbeExchangeService
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
|
||||
import { CbeExchangeProvider } from "./cbe.provider";
|
||||
import { EXCHANGE_OPTIONS, ExchangeOptions } from "./exchange.options";
|
||||
import { CurrencyCode } from "./exchange.types";
|
||||
|
||||
/**
|
||||
* Currency exchange service. Resolves the rate between any supported currency
|
||||
* pair and converts amounts, backed by a rate provider (currently CBE).
|
||||
*
|
||||
* Resolution order for `getRate(from, to)`:
|
||||
* 1. `from === to` → `1`.
|
||||
* 2. Provider supplies the pair directly (e.g. CBE → USD→ETB).
|
||||
* 3. Provider supplies the inverse → return `1 / inverse` (e.g. ETB→USD).
|
||||
*
|
||||
* Configure via {@link ExchangeModule.forRoot} / `forRootAsync`.
|
||||
*/
|
||||
@Injectable()
|
||||
export class ExchangeService {
|
||||
private readonly provider: CbeExchangeProvider;
|
||||
|
||||
constructor(@Inject(EXCHANGE_OPTIONS) options: ExchangeOptions) {
|
||||
this.provider = new CbeExchangeProvider(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rate to convert 1 unit of `from` into `to`
|
||||
* (i.e. `amountInTo = amountInFrom * getRate(from, to)`).
|
||||
*/
|
||||
async getRate(from: CurrencyCode, to: CurrencyCode): Promise<number> {
|
||||
if (from === to) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const direct = await this.provider.getBaseRate({ from, to });
|
||||
if (direct !== null) {
|
||||
return direct;
|
||||
}
|
||||
|
||||
const inverse = await this.provider.getBaseRate({ from: to, to: from });
|
||||
if (inverse !== null && inverse > 0) {
|
||||
return 1 / inverse;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`No exchange rate available for ${from}→${to} from provider ${this.provider.name}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** Converts `amount` from one currency to another using {@link getRate}. */
|
||||
async convert(
|
||||
amount: number,
|
||||
from: CurrencyCode,
|
||||
to: CurrencyCode,
|
||||
): Promise<number> {
|
||||
const rate = await this.getRate(from, to);
|
||||
return amount * rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience alias for `getRate('USD', 'ETB')`.
|
||||
* @deprecated Prefer {@link getRate}; kept for existing callers.
|
||||
*/
|
||||
getUsdToEtbRate(): Promise<number> {
|
||||
return this.getRate("USD", "ETB");
|
||||
}
|
||||
|
||||
/** Convenience alias for `getRate('ETB', 'USD')`. */
|
||||
getEtbToUsdRate(): Promise<number> {
|
||||
return this.getRate("ETB", "USD");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user