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

6.1 KiB

provider — KrakenProvider class

(no submodules)

Purpose

KrakenProvider is the universal CurrencyProvider implementation for Kraken's free /0/public/Ticker endpoint. It fetches real-time last-trade-closed prices for a fixed set of high-volume crypto pairs and returns them as reciprocal-of-USD rates, so a downstream CurrencyConverter can translate USD → BTC (and friends) without callers ever seeing Kraken's non-standard pair names.

The class is the canonical sibling-package surface defined by the slim @suaveplan/currency-providers core: it wraps a single upstream endpoint, maps every documented failure mode to a typed CurrencyProviderError, and exposes nothing that consumers can't already obtain from the shared core helpers.

Features

  • No API key required — Kraken's public endpoint is free and rate-limited per IP
  • 12 high-volume symbols out of the box (BTC, ETH, SOL, USDT, DOT, ADA, LINK, AVAX, ATOM, LTC, DOGE, XRP); extensible via constructor extraSymbols
  • Reciprocal-of-USD rate model — 1 USD = (1 / krakenLastTradePrice) of the target crypto, matching the shape every CurrencyConverter consumer expects
  • Uses the slim core's httpRequest() helper so HTTP failures, timeouts, and caller abort-signal propagation are handled uniformly
  • Maps the four wire-level failure modes to typed CurrencyProviderError: HTTP_ERROR (non-2xx), UPSTREAM_ERROR (Kraken error[] array), PARSE_ERROR (malformed JSON / shape mismatch), UNKNOWN_CURRENCY (all requested targets unmapped)
  • Universal — no node:/bun:/DOM imports; runs unchanged under Node ≥ 18, Bun, modern browsers (subject to Kraken's CORS), Web Workers
  • Optional injectable FetchLike (defaults to globalThis.fetch) for recording tests, proxying, or staging URLs

Usage: Basic

import { KrakenProvider } from "@suaveplan/currency-provider-kraken/provider/provider";

const provider = new KrakenProvider();
const result = await provider.fetchRates({ base: "USD" });

console.log(result.rates.BTC); // e.g. 0.0000149 (≈ 1 / 67000)
console.log(result.rates.ETH); // e.g. 0.0002857 (≈ 1 / 3500)

Usage: Advanced

import { CurrencyConverter } from "@suaveplan/currency";
import { CurrencyProviderRegistry } from "@suaveplan/currency-providers";
import { KrakenProvider } from "@suaveplan/currency-provider-kraken/provider/provider";

// Use the slim core's registry — wire Kraken plus any other sibling
// providers your app supports. The Kraken instance extends coverage with
// a newly-listed pair via `extraSymbols`, and reuses a custom fetch
// closure that adds a proxy header.
const registry = new CurrencyProviderRegistry();
registry.register(
 new KrakenProvider({
  baseUrl: "https://kraken.proxy.example.com/0/public",
  fetch: async (url, init) =>
   fetch(url, {
    ...init,
    headers: {
     ...(init?.headers ?? {}),
     "x-proxy-token": process.env.PROXY_TOKEN ?? "",
    },
   }),
  extraSymbols: { MATIC: "MATICUSD" },
 }),
);

const converter = new CurrencyConverter({
 provider: registry.get("kraken"),
});
const btcRate = await converter.getRate("USD", "BTC");
const maticRate = await converter.getRate("USD", "MATIC");

API Reference

Export Kind Description
DEFAULT_KRAKEN_BASE_URL string "https://api.kraken.com/0/public" — overridable via config.baseUrl.
KrakenProviderConfig interface extends NoKeyConfig Optional baseUrl, optional fetch (FetchLike), optional extraSymbols (Record<string, string>).
KrakenProvider class implements CurrencyProvider Fixed name = "kraken", supportsCrypto = true, supportsFiat = false. Constructor takes an optional KrakenProviderConfig.
KrakenProvider.fetchRates(options?) (RateFetchOptions?) => Promise<RateFetchResult> Issues one GET /Ticker?pair=<csv> via the injected fetch. Returns { base, rates, timestamp }. Throws CurrencyProviderError on every documented failure path.

Error codes raised

Code When
CURRENCY_PROVIDER.HTTP_ERROR Non-2xx response (raised by the shared httpRequest). Carries status.
CURRENCY_PROVIDER.UPSTREAM_ERROR Kraken response carries a non-empty error[] array. Carries upstreamMessage.
CURRENCY_PROVIDER.PARSE_ERROR Body fails JSON-parse, OR the parsed body does not match the { error: string[], result: object } shape. Carries cause for the JSON-parse case.
CURRENCY_PROVIDER.UNKNOWN_CURRENCY Caller supplied options.targets but none of the requested symbols resolved to a mapped Kraken pair.

Implementation Notes

  • The pair list sent in the pair= query is the value list of the merged symbol map — Kraken supports a comma-separated batch so the whole supported set is fetched in a single round trip. This is more efficient than one request per symbol AND matches what Kraken's documentation recommends.
  • The rate model is 1 / Number.parseFloat(ticker.c[0]) where c[0] is Kraken's "last trade closed" price. Entries whose price does not parse to a positive finite number are skipped (not raised) — Kraken occasionally returns "0.00" for freshly-listed pairs. If the entire mapped set drops, options.targets filtering will subsequently raise UNKNOWN_CURRENCY on the caller's behalf.
  • options.signal is forwarded into httpRequest() so the caller's AbortController composes with any future timeout the helper applies.
  • The provider does not retry, cache, or rate-limit. Those concerns belong in wrapper providers (the slim core's ## Out of scope defers them) — keeping this class focused on Kraken's wire protocol keeps the failure surface auditable.
  • All HTTP error mapping flows through the shared httpRequest() helper exported from @suaveplan/currency-providers/http/http, so the response is never read on a non-2xx path — Kraken's body on a 5xx is typically HTML and would otherwise raise a confusing PARSE_ERROR.
  • Tier purity: no node: imports, no DOM imports, no setTimeout. The helper uses AbortSignal.timeout for timeouts (universal in Node 17.3+, Bun, modern browsers).