Initial Commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# Add @suaveplan/currency-provider-coinmarketcap sibling provider
|
||||
|
||||
**Package**: `@suaveplan/currency-provider-coinmarketcap`
|
||||
**Status**: PROPOSED
|
||||
**Type**: new package (sibling of slimmed `@suaveplan/currency-providers`)
|
||||
|
||||
- **Spec delta**: ./specs/currency-provider-coinmarketcap/spec.md
|
||||
|
||||
## Why
|
||||
|
||||
The 2026-05-17 `slim-currency-providers` refactor moved the nine concrete
|
||||
provider classes out of `@suaveplan/currency-providers` and committed each
|
||||
one to its own publishable sibling package. This change lands the
|
||||
`CoinMarketCap` sibling — a crypto rate source backed by the
|
||||
`pro-api.coinmarketcap.com` REST API and authenticated through the
|
||||
`X-CMC_PRO_API_KEY` HTTP header.
|
||||
|
||||
Consumers that already register sibling providers via
|
||||
`CurrencyProviderRegistry` (or instantiate them directly into
|
||||
`CurrencyConverter`) gain a CoinMarketCap option without installing eight
|
||||
other provider packages they do not wire in.
|
||||
|
||||
## What changes
|
||||
|
||||
### ADDED
|
||||
|
||||
- `@suaveplan/currency-provider-coinmarketcap` package at
|
||||
`packages/finance/currency-provider-coinmarketcap/`, version `0.1.0`,
|
||||
universal-tier (`sideEffects: false`).
|
||||
- `CoinMarketCapProvider` class implementing `CurrencyProvider` from
|
||||
`@suaveplan/currency`. Constructed from `ApiKeyConfig`
|
||||
(`apiKey`, optional `baseUrl`, optional injectable `FetchLike` from
|
||||
`@suaveplan/types`).
|
||||
- `supportsCrypto: true`, `supportsFiat: false`, no `supportsVirtual`.
|
||||
CoinMarketCap is a crypto-rates source — fiat rates are out of scope
|
||||
for this sibling (consumers wanting fiat install `currency-provider-ecb`
|
||||
/ `currency-provider-fixer` / `currency-provider-open-exchange-rates`).
|
||||
- `fetchRates(options?)` calls
|
||||
`GET <baseUrl>/cryptocurrency/quotes/latest?symbol=<targets>&convert=<base>`
|
||||
via the shared `httpRequest()` helper from `@suaveplan/currency-providers`.
|
||||
The `X-CMC_PRO_API_KEY` header carries `config.apiKey`; the `Accept`
|
||||
header is `application/json`.
|
||||
- Constructor raises `CurrencyProviderError(MISSING_CONFIG)` when
|
||||
`config.apiKey` is empty or whitespace-only (consistent with the
|
||||
`ApiKeyConfig` contract documented in the slim core).
|
||||
- Response parsing raises `CurrencyProviderError(PARSE_ERROR)` when the
|
||||
payload is not valid JSON or the `data` map is missing / wrong shape.
|
||||
- Response parsing raises `CurrencyProviderError(UPSTREAM_ERROR)` when
|
||||
the upstream payload contains a non-null `status.error_code` field.
|
||||
- `fetchRates()` raises `CurrencyProviderError(UNKNOWN_CURRENCY)` when
|
||||
none of the requested target symbols resolve to a quote in the
|
||||
configured `base` currency.
|
||||
- Non-2xx HTTP responses surface as `CurrencyProviderError(HTTP_ERROR)`
|
||||
(raised by the shared `httpRequest()` helper, with `status` populated).
|
||||
- README, sibling `.md` per implementation file, and subpath exports for
|
||||
`./coinmarketcap/coinmarketcap`.
|
||||
|
||||
### KEPT (from slim core, consumed unchanged)
|
||||
|
||||
- `CurrencyProviderError` + `CURRENCY_PROVIDER_CODES` registry
|
||||
(`HTTP_ERROR`, `PARSE_ERROR`, `UPSTREAM_ERROR`, `MISSING_CONFIG`,
|
||||
`UNKNOWN_CURRENCY`).
|
||||
- `ApiKeyConfig` shared config type.
|
||||
- `httpRequest()` shared HTTP helper.
|
||||
- `FetchLike` from `@suaveplan/types`.
|
||||
|
||||
## Source mapping
|
||||
|
||||
| Module | Source |
|
||||
|---|---|
|
||||
| `CoinMarketCapProvider` | `../suaveplan/packages/finance/currency-providers/src/crypto/coinmarketcap.ts` L1-L61 (upstream class) |
|
||||
| Error mapping (`MISSING_CONFIG` / `PARSE_ERROR` / `UPSTREAM_ERROR` / `UNKNOWN_CURRENCY`) | genesis-original — upstream threw raw `Error`; the slim core's typed `CurrencyProviderError` registry replaces that |
|
||||
| `httpRequest` / `composeAbortSignal` plumbing | `@suaveplan/currency-providers/src/http/http.ts` (slim core, genesis-original) |
|
||||
| Symbol-based crypto query shape | upstream behaviour preserved (`symbol=<csv>&convert=<base>` against `/v1/cryptocurrency/quotes/latest`) |
|
||||
|
||||
## Impact
|
||||
|
||||
### Affected dependents
|
||||
|
||||
Run `bunx turbo ls --filter=...@suaveplan/currency-provider-coinmarketcap`
|
||||
to enumerate.
|
||||
|
||||
- No current dependents (new sibling package; verified by
|
||||
`bunx turbo ls --filter=...@suaveplan/currency-provider-coinmarketcap`).
|
||||
|
||||
The package's only upstream dependencies are
|
||||
`@suaveplan/currency-providers` (slim core, registry / factory / HTTP
|
||||
helper / error registry / configs), `@suaveplan/currency` (the
|
||||
`CurrencyProvider` contract), `@suaveplan/types` (`FetchLike`),
|
||||
`@suaveplan/error` (transitive), and `tslib`. None of those packages
|
||||
need to be touched by this change — the sibling consumes their public
|
||||
surfaces unchanged.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Fiat conversion endpoints. CoinMarketCap exposes
|
||||
`/v1/fiat/map` and `/v2/tools/price-conversion` but this sibling stays
|
||||
scoped to the crypto quotes endpoint (`supportsFiat: false`). A fiat
|
||||
follow-up can land separately if a real consumer needs it.
|
||||
- Historical-rate endpoints, OHLCV, WebSocket streams. Same deferral as
|
||||
every other sibling provider — interface extension lands once
|
||||
`@suaveplan/currency`'s `CurrencyProvider` contract grows the slots.
|
||||
- Rate-limit and retry orchestration. Deferred to `@suaveplan/rate-limiter`
|
||||
and `@suaveplan/retry` integrations once those wrappers land — every
|
||||
sibling provider gains them uniformly through a single composition.
|
||||
- CoinMarketCap-specific helper utilities (rank, market-cap weighting,
|
||||
metadata). Out of scope for a rates provider; a future
|
||||
`@suaveplan/coinmarketcap` package can expose those if needed.
|
||||
Reference in New Issue
Block a user