4.3 KiB
OpenSpec Change: enterprise-currency-providers
- Change ID: enterprise-currency-providers
- Package:
@suaveplan/currency-providers - Category: finance
- Target path:
finance/currency/currency-providers - Status: PROPOSED
- Date: 2026-04-24
- Reference spec:
/mnt/s/web/suaveplan/enterprise/currency-providers.md
Summary
Deliver @suaveplan/currency-providers on the genesis branch from scratch at enterprise quality. The package implements concrete CurrencyProvider implementations (from @suaveplan/currency) for eight real exchange-rate APIs: three fiat providers (ECB XML feed, Open Exchange Rates, Fixer) and five crypto providers (CoinGecko, CoinMarketCap, Binance, Kraken, CryptoCompare), plus a VirtualCurrencyProvider. All HTTP calls go through a shared fetch wrapper with timeout, retry via @suaveplan/retry, rate-limit header parsing, and in-flight request coalescing. Typed error hierarchy (AuthError, RateLimitError, NetworkError, ParseError). Optional RateLimitedProvider decorator.
Current-state audit (genesis)
Does not exist on genesis — fresh build.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
Typed CURRENCY_PROVIDER.* error codes |
@suaveplan/types (workspace:^) |
LoggerLike |
@suaveplan/currency (workspace:^) |
CurrencyProvider interface |
@suaveplan/retry (workspace:^) |
HTTP retry + backoff |
@suaveplan/logger (workspace:^) |
Structured logs |
zod (catalog:forms) |
Response parsing schemas |
@opentelemetry/api (catalog:observability) |
Spans + counters + histograms |
tslib (catalog:build) |
Runtime helpers |
Public API surface
// Fiat providers
class EcbProvider implements CurrencyProvider { ... }
class FixerProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
class OpenExchangeRatesProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
// Crypto providers
class BinanceProvider implements CurrencyProvider { ... }
class CoinGeckoProvider implements CurrencyProvider { ... }
class CoinMarketCapProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
class CryptoCompareProvider implements CurrencyProvider { ... }
class KrakenProvider implements CurrencyProvider { ... }
// Virtual
class VirtualCurrencyProvider implements CurrencyProvider { ... }
// Wrapper
class RateLimitedProvider implements CurrencyProvider {
constructor(provider: CurrencyProvider, options: RateLimitOptions)
}
// Errors
class ProviderError extends SuaveplanError { ... }
class AuthError extends ProviderError { ... }
class RateLimitError extends ProviderError { retryAfterMs?: number }
class NetworkError extends ProviderError { ... }
class ParseError extends ProviderError { ... }
// HTTP utilities
function createFetchWrapper(options: FetchWrapperOptions): FetchWrapper
function coalesce<T>(key: string, fn: () => Promise<T>): Promise<T>
File layout
finance/currency/currency-providers/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
types/
provider.types.ts
provider.types.md
http/
fetch-wrapper/
fetch-wrapper.ts
fetch-wrapper.md
fetch-wrapper.test.ts
index.ts
coalesce/
coalesce.ts
coalesce.md
coalesce.test.ts
index.ts
fiat/
ecb-provider/
ecb-provider.ts / .md / .test.ts / index.ts
fixer-provider/
fixer-provider.ts / .md / .test.ts / index.ts
open-exchange-rates-provider/
open-exchange-rates-provider.ts / .md / .test.ts / index.ts
crypto/
binance-provider/ ...
coingecko-provider/ ...
coinmarketcap-provider/ ...
cryptocompare-provider/ ...
kraken-provider/ ...
virtual/
virtual-currency-provider/ ...
wrappers/
rate-limited-provider/ ...
tests/
integration.test.ts
Impact
Requires @suaveplan/currency to be published first (implements its CurrencyProvider interface). Downstream: @suaveplan/currency consumers via the fallback chain.
Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/currency, @suaveplan/retry, @suaveplan/logger.