TypeScript SDK

Official @anaxer/sdk client for Node.js — typed WebSocket streams and REST reads over the public /v1 API. Handles auth, heartbeat, and auto-reconnect so you don't hand-roll the lifecycle.

Install

Requires Node.js ≥ 20. ESM and CommonJS builds ship together.

npm install @anaxer/sdk

A Python SDK is coming soon.

Quickstart

import { connect } from "@anaxer/sdk";

const client = connect({ apiKey: process.env.ANAXER_API_KEY! });

client.stream("creations", { excludeMayhem: true }).on("data", (token) => {
  console.log("new launch:", token.symbol, token.mint);
});

const price = await client.tokens.price(
  "3PFaeFMXiRVYueDCnHHSKndKDDpKZhbhFjQ13JXYpump"
);

connect() returns immediately. The WebSocket opens on the first stream() call (or await client.ready()). Auth is Authorization: Bearer for both WS and REST.

What it handles

  • Auth — attaches your API key for WebSocket and REST.
  • Typed events — channel payloads match the public WebSocket and REST v1 shapes.
  • Heartbeat — client pings; the socket is treated as dead if no inbound traffic arrives within 2× the interval.
  • Reconnection — exponential backoff with jitter; re-sends every active subscription after reconnect.
No gap recovery in v1. After a disconnect the SDK resumes the live feed only — events during the downtime are not replayed. Use REST list endpoints with your own time window or cursor if you need to backfill.

Streaming

Subscribe with client.stream(channel, filters?). Each call returns a subscription you can listen on and close independently.

ChannelPayloadCommon filters
tradesSwapV1sources, mints, wallets, minVolumeUsd, maxVolumeUsd
creationsCreatedV1sources, enriched, excludeMayhem
graduationsGraduatedV1sources, excludeMayhem, minLiquiditySol
pricesPriceUpdateV1sources, mints
const sub = client.stream("trades", {
  sources: ["pump_fun"],
  minVolumeUsd: 10,
});

sub.on("subscribed", (filters) => console.log("live", filters));
sub.on("data", (swap) => console.log(swap.signature, swap.volumeUsd));
sub.on("error", (err) => console.error(err.code, err.message));

// later
sub.close(); // unsubscribe; not resurrected after reconnect

The transfers channel is not exposed on stream() yet (server ingestion pending). The TransferV1 type is still exported for typing.

Connection events

client.on("connected", ({ maxSubscriptions }) => {
  console.log("plan cap", maxSubscriptions);
});
client.on("reconnect", (attempt) => console.log("retry", attempt));
client.on("error", (err) => console.error(err.code, err.message));

await client.ready();  // resolves on first connected frame
await client.close();  // graceful shutdown; disables reconnect
  • Heartbeat default heartbeatMs: 15_000; set 0 to disable.
  • Reconnect is on by default; reconnect: false disables it. unauthorized is terminal (bad key — no retry loop).

REST

All calls are authenticated GETs. Transient 429 / 5xx retry up to restMaxRetries (default 2), honoring Retry-After. Other 4xx throw immediately.

MethodReturns
client.tokens.get(mint)TokenMetadataV1
client.tokens.batch(mints)TokenMetadataV1[] (max 50)
client.tokens.price(mint)PriceUpdateV1
client.tokens.batchPrice(mints)PriceUpdateV1[]
client.tokens.trades(mint, opts?)Page<SwapV1>
client.creations(opts?)Page<CreatedV1>
client.graduations(opts?)Page<GraduatedV1>
client.launchpads.stats(opts?)LaunchpadStatsV1

List endpoints return a Page<T> with .data, .next, and .window. It is also an async iterable that walks next on the same endpoint until null:

const page = await client.creations({ excludeMayhem: true, limit: 50 });
console.log(page.data.length, page.window);

for await (const created of page) {
  console.log(created.mint);
}

Config

connect({
  apiKey: process.env.ANAXER_API_KEY!, // required
  baseUrl: "https://api.anaxer.com",   // optional
  // wsUrl derived from baseUrl → wss://…/v1/stream
  reconnect: true,                     // or false | { baseDelayMs, maxDelayMs, maxRetries }
  heartbeatMs: 15_000,                 // 0 disables
  restMaxRetries: 2,                   // 0 disables REST retries
});

Errors

REST non-2xx throws AnaxerError (code, message, status). WebSocket error frames emit on the matching subscription (when an id is present) or on the client.

import { AnaxerError, connect } from "@anaxer/sdk";

const client = connect({ apiKey: process.env.ANAXER_API_KEY! });

try {
  await client.tokens.get(mint);
} catch (e) {
  if (e instanceof AnaxerError && e.code === "not_found") {
    // mint never observed
  }
}

See the full error codes reference.

Types

Payload and filter types are exported from the package (SwapV1, CreatedV1, TradesFilters, SubscriptionFiltersV1, …). WIRE_VERSION is 1 (envelope v, independent of the npm package version).