Files
suaveplan/openspec/archive/2026-05-17-add-currency-provider-kraken/proposal.md
2026-05-27 23:29:53 +01:00

5.5 KiB

Add @suaveplan/currency-provider-kraken sibling package

Package: @suaveplan/currency-provider-kraken Status: PROPOSED Type: new package (genesis-original sibling of @suaveplan/currency-providers)

  • Design: ./design.md
  • Spec delta: ./specs/currency-provider-kraken/spec.md

Why

The slim refactor archived at openspec/archive/2026-05-17-slim-currency-providers/ moved every concrete provider out of @suaveplan/currency-providers and committed to landing each one as its own @suaveplan/currency-provider-<name> sibling. Kraken is one of the nine siblings the slim core's proposal.md ## Affected dependents block explicitly enumerates — this change ships it.

Kraken is a free public-ticker provider (no API key) with a regulated-exchange real-time trading price. Wiring it through the slim core's httpRequest + defineCurrencyProvider factory gives consumers a granular install (only pay for Kraken when they want Kraken) and lets the provider iterate on its own version cadence — exactly the foundation-with-sibling-plugins shape established by @suaveplan/network-plugin-* and @suaveplan/drive-plugin-*.

What changes

ADDED

  • New package @suaveplan/currency-provider-kraken at packages/finance/currency-provider-kraken/ (universal-tier, 0.1.0, sideEffects: false).
  • KrakenProvider class implementing the CurrencyProvider contract from @suaveplan/currency. Constructor accepts an optional NoKeyConfig from @suaveplan/currency-providers (baseUrl override + injectable FetchLike).
  • KRAKEN_SYMBOL_MAP — the canonical mapping from Suaveplan symbol (BTC, ETH, SOL, USDT, DOT, ADA, LINK, AVAX, ATOM, LTC, DOGE, XRP) to Kraken pair (XXBTZUSD, XETHZUSD, …) — exported so callers can probe / extend.
  • DEFAULT_KRAKEN_BASE_URL = "https://api.kraken.com/0/public" exported constant.
  • Uses the shared httpRequest() helper from @suaveplan/currency-providers/http/http for the GET — non-2xx responses raise CurrencyProviderError(HTTP_ERROR) with providerName: "kraken" and the HTTP status populated.
  • Maps the Kraken-specific data.error: string[] array to CurrencyProviderError(UPSTREAM_ERROR) with the first message carried on upstreamMessage.
  • Raises CurrencyProviderError(PARSE_ERROR) when the response body fails to JSON-parse, when the result map is missing / not an object, or when a ticker's c[0] price cannot be parsed to a positive finite number.
  • Raises CurrencyProviderError(UNKNOWN_CURRENCY) when every requested options.targets symbol resolves to an unknown / unmapped Kraken pair, so callers don't silently receive an empty rate set.

Source mapping

Upstream reference for parity (the legacy 9-provider bundle):

Capability Upstream source
KrakenProvider class ../suaveplan/packages/finance/currency-providers/src/crypto/kraken.ts L1-L91
Kraken symbol → pair table ../suaveplan/packages/finance/currency-providers/src/crypto/kraken.ts L11-L24
c[0] last-trade-closed price + reciprocal-to-USD rate calc ../suaveplan/packages/finance/currency-providers/src/crypto/kraken.ts L67-L77
Kraken error: string[] upstream-failure detection ../suaveplan/packages/finance/currency-providers/src/crypto/kraken.ts L58-L60
HTTP-error path ../suaveplan/packages/finance/currency-providers/src/crypto/kraken.ts L46-L51 (now delegated to httpRequest)

Genesis-native deltas vs. upstream:

Capability Upstream Migrated Notes
Plain Error HTTP failure ✅ ⬆️ Now CurrencyProviderError(HTTP_ERROR) via shared httpRequest.
Plain Error Kraken-error array ✅ ⬆️ Now CurrencyProviderError(UPSTREAM_ERROR) with upstreamMessage.
Hardcoded globalThis.fetch ✅ ⬆️ Injectable FetchLike via NoKeyConfig.fetch.
Silent empty rate set on unknown target ✅ ⬆️ Now CurrencyProviderError(UNKNOWN_CURRENCY) when every requested target is unmapped.
BTC/ETH/SOL/USDT/DOT/ADA/LINK/AVAX/ATOM/LTC/DOGE/XRP symbol map ✅ ✅ Preserved verbatim.
Reciprocal-of-USD-price rate model ✅ ✅ Preserved verbatim.

No upstream enterprise audit exists for currency-providers (the slim core's design notes were the genesis-native source).

Impact

Affected dependents

Run bunx turbo ls --filter=...@suaveplan/currency-provider-kraken to enumerate. The package is brand-new so there are no current dependents:

  • No current dependents (verified by bunx turbo ls --filter=...@suaveplan/currency-provider-kraken).

This package consumes @suaveplan/currency-providers (the slim core) for the httpRequest helper, the CurrencyProviderError + CURRENCY_PROVIDER_CODES registry, and the NoKeyConfig shape. It consumes @suaveplan/currency for the CurrencyProvider / RateFetchOptions / RateFetchResult contracts and @suaveplan/types for the FetchLike shape. None of those packages need re-testing — they are all unchanged.

Out of scope

  • Authenticated Kraken endpoints (private balance / order endpoints) — this provider wraps only the public ticker, matching the slim core's "free, no API key" classification.
  • WebSocket / streaming ticker — same deferral as the slim core's ## Out of scope.
  • Historical-rate / OHLC endpoints — same deferral.
  • A KrakenProvider built via defineCurrencyProvider (object-literal idiom) — the class form is the canonical surface; the factory remains available for callers who prefer it.