Files
2026-05-27 23:29:53 +01:00

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.