Solana Tracker LogoSolana Tracker
Swap
Developers
⌘K
Affiliate

Products

  • Data API
  • Pump.fun API
  • Solana RPC
  • Dedicated Nodes
  • Yellowstone gRPC
  • Raptor Swap API
  • Enterprise

Trading

  • Swap
  • Latest Tokens
  • Trending
  • Top Gainers
  • Memescope
  • Whale Watch
  • KOL Tracker

Tools

  • Wallet Tracker
  • Rugcheck
  • PnL Leaderboard
  • KOLScan
  • Axiom Leaderboard
  • Photon Leaderboard
  • Bloom Leaderboard
  • FOMO Leaderboard
  • GMGN Leaderboard
  • Pump.fun App Leaderboard
  • Terminal Leaderboard
  • Platform Compare
  • My Positions
  • Teams

Resources

  • Developer Guides
  • Blog
  • Documentation
  • API Reference
  • Status
  • Affiliate Program — 25% recurring, uncapped
Solana TrackerSolana Tracker© 2026
Terms of ServicePrivacy PolicyContact
←Back to blog
typescript api clientsolana trackersolanatracker apicrypto sdk typescriptsolana websocket

TypeScript API Client for Solana Tracker

Build a TypeScript API client for Solana Tracker with install, auth, key endpoints, WebSocket streams, and crypto trading code examples.

September 1, 2026/17 min read

Table of contents

  • Why a Typed Solana Client Changes Your Build
  • Installing and Authenticating the TypeScript SDK
  • Choosing the Right RPC Plan for Your Crypto Volume
  • Fetching Token Data and Recent Trades
  • Querying Wallets, PnL, and Leaderboards
  • Adding Rugcheck and Risk Scores to Your Client
  • Subscribing to Real-Time Datastream Rooms
  • Designing for Type Safety at the Network Boundary
  • Handling Rate Limits, Retries, and Timeouts
  • Common Integration Bugs and Quick Fixes
  • Quick Reference Card for Your Solana Client
TypeScript API Client for Solana Tracker

You're halfway through a Solana trading interface when the problems start multiplying. The price endpoint returns one shape, the wallet history returns another, and a manual cast makes the compiler quiet without making the data safe. Then a token launches, the response includes a missing field, and your swap flow fails at the exact moment users expect it to work.

A practical TypeScript API client should do more than autocomplete method names. It should keep crypto data typed from the request boundary to the trading decision, validate untrusted JSON at runtime, respect RPC limits, and make failures visible. The examples below connect those patterns to token discovery, swaps, wallet PnL, rug checks, and real-time Solana activity.

Why a Typed Solana Client Changes Your Build

A token page often needs price data, recent trades, holder information, and wallet context before it can show a useful buy decision. With raw fetch, developers commonly write a request, cast the result, and duplicate interfaces across portfolio components, bot handlers, and swap routers. Those declarations drift as the upstream schema changes.

A typed client gives each feature the same contract. The token card, pre-swap guard, and trade monitor can consume named methods and inferred responses instead of passing any through the application.

Practical rule: Type the boundary once, then keep trading logic unaware of HTTP details.

TypeScript has moved from an optional preference to a mainstream ecosystem standard. A 2026 summary reported TypeScript support across 95% of the top 100 npm packages, compared with 25% in 2016, and across 89% of the top 1,000 packages, compared with 15% in 2016. The same source estimated that 82% of new package creation used TypeScript in 2026. These figures support a practical conclusion for SDK authors, typed request and response models are now expected across serious JavaScript libraries. (TypeScript adoption and ecosystem growth)

The maintenance difference becomes obvious in a crypto codebase:

  • Raw REST: manual paths, casts, duplicated response interfaces, and scattered error handling.
  • Typed client: autocomplete, constrained parameters, reusable response models, and narrower failure branches.
  • Validated client: runtime parsing before a price, balance, or risk result reaches execution code.

The compiler catches incorrect property names. It can't prove that a server returned the promised JSON. That second problem needs runtime validation, which is why a good client combines static types with a defensive network boundary.

Installing and Authenticating the TypeScript SDK

Start by installing the official Data API package in the application that owns the API key:

npm install @solana-tracker/data-api

With pnpm, use:

pnpm add @solana-tracker/data-api

Keep the key server-side. A .env file can contain:

SOLANA_TRACKER_API_KEY=replace_with_your_key

Load it through process.env in a backend, worker, or server route. Don't embed the key in a browser bundle, because a dApp user's browser can inspect bundled configuration.

The exact constructor and method names can vary with the installed SDK release, so keep the integration aligned with the package's current API reference. A typical first-call shape looks like this:

import "dotenv/config";
import { createClient } from "@solana-tracker/data-api";

const apiKey = process.env.SOLANA_TRACKER_API_KEY;

if (!apiKey) {
  throw new Error("SOLANA_TRACKER_API_KEY is missing");
}

const client = createClient({
  apiKey,
});

const tokenAddress = "TOKEN_MINT_ADDRESS";

const token = await client.tokens.get(tokenAddress);

console.log({
  price: token.price,
  firstTrade: token.trades?.[0],
});

Treat that snippet as the integration shape to verify against your installed version, not as permission to guess response fields. The IDE should expose the actual token model, optional fields, pagination properties, and trade structure supplied by the SDK.

The first authenticated request needs an active paid tier for gateway access. Choose the tier according to request volume, then keep authentication centralized so token endpoints, wallet queries, and risk checks all use the same configured client.

TypeScript's ecosystem scale is one reason typed SDKs fit this workflow. A separate 2026 dataset reported about 201.5 million weekly downloads for the typescript package, up from 83.2 million in the same week a year earlier, a 142% increase. (TypeScript usage dataset)

Choosing the Right RPC Plan for Your Crypto Volume

Plan selection should follow the call path, not the number of developers on the project. A portfolio dashboard may request holdings occasionally, while a launch monitor can combine token lookups, risk checks, and trade updates during a fast market.

Published Solana Tracker plan limits are:

Plan Token / Trade Holder / PnL Rugcheck RPS Limit Recommended For
Free Not specified in the published plan table Not specified in the published plan table Not specified in the published plan table 5 general RPS Development and light testing
Developer Not specified in the published plan table Not specified in the published plan table Not specified in the published plan table 60 general RPS Active wallets and trading tools
Business Not specified in the published plan table Not specified in the published plan table Not specified in the published plan table 225 general RPS Higher-volume production systems

The published monthly allowances are 500,000 credits for Free, 15,000,000 for Developer, and 100,000,000 for Business. The same plan documentation states that exceeding limits returns 429 Too Many Requests. (Solana Tracker RPC credits and rate limits)

The requested per-call credit prices for token information, holder lookups, PnL, and Rugcheck aren't provided in the verified plan data, so don't hardcode a made-up cost table into your SDK. Read the current endpoint pricing from the account documentation and record it beside each method in your internal usage model.

Use this formula once the endpoint prices are known:

monthly credits = Σ(endpoint calls × current credits per call)

A sniper bot that repeatedly checks new tokens and risk reports will consume credits far faster than a dashboard that refreshes a wallet snapshot. Start with Developer for active wallet and trading workflows, then move to Business when sustained throughput and Datastream room usage exceed the smaller operating envelope.

Fetching Token Data and Recent Trades

A token page should request only the data it needs for the current view. Use token/:tokenAddress for metadata and price, tokens/multi/:tokens for a watchlist or swap selector, and the trades endpoint for activity that changes continuously. The current Solana Tracker Data API documentation should remain the source of truth for exact method signatures and endpoint parameters.

Define local domain types only when they add application meaning:

interface TokenInfo {
  address: string;
  name?: string;
  symbol?: string;
  price?: number;
}

interface TokenTrade {
  signature: string;
  pool?: string;
  side?: "buy" | "sell";
  amount?: number;
  price?: number;
}

If the SDK already exports these models, import them instead of redeclaring them. The goal isn't to create a second contract. It's to stop any from entering your components.

const token = await client.tokens.get(tokenAddress);

const watchlist = await client.tokens.getMany([
  firstMint,
  secondMint,
  thirdMint,
]);

const trades = await client.trades.list({
  token: tokenAddress,
  cursor: previousCursor,
  pool: poolAddress,
});

A single token call powers a price header and metadata card. A multi-token call is useful before rendering a swap interface because the UI can resolve several mint addresses in one request. Cursor pagination lets a recent-trades table continue from its last position instead of downloading the same history repeatedly.

Pool filtering deserves a separate adapter. A trade response filtered by pool can expose a different useful shape from an unfiltered token activity response, so don't assume every trade object has identical fields.

Credit accounting also belongs beside the method wrapper. The verified plan material confirms that endpoint usage consumes credits, but it doesn't publish the per-call prices for these specific routes. Keep those values configurable and update them from the current account documentation rather than baking assumptions into a bot.

Querying Wallets, PnL, and Leaderboards

Wallet features need more than a balance snapshot. A useful Solana portfolio screen combines current holdings from wallet/:address, trade history from wallet/:address/trades, open positions from wallet/:address/positions, and broader context from leaderboard.

type WalletAddress = string;

const holdings = await client.wallets.get(walletAddress);

const history = await client.wallets.trades(walletAddress, {
  page: 1,
  limit: 50,
});

const positions = await client.wallets.positions(walletAddress);

const leaders = await client.leaderboard.list({
  sort: "pnl",
  page: 1,
  limit: 25,
});

The exact SDK namespaces should follow the installed package version. Keep page and limit in the query adapter, not inside React components, so pagination remains consistent across wallet history and leaderboard views.

Raw trade history usually isn't the same thing as realized PnL. A dashboard can derive a simplified FIFO result by matching sells against earlier buys:

type Trade = {
  side: "buy" | "sell";
  quantity: number;
  unitPrice: number;
};

function realizedPnl(trades: Trade[]): number {
  const lots: Trade[] = [];
  let pnl = 0;

  for (const trade of trades) {
    if (trade.side === "buy") {
      lots.push({ ...trade });
      continue;
    }

    let remaining = trade.quantity;

    while (remaining > 0 && lots.length > 0) {
      const lot = lots[0];
      const matched = Math.min(remaining, lot.quantity);

      pnl += matched * (trade.unitPrice - lot.unitPrice);
      lot.quantity -= matched;
      remaining -= matched;

      if (lot.quantity === 0) lots.shift();
    }
  }

  return pnl;
}

This is an application calculation, not a replacement for the API's own wallet analytics. Cache holdings and positions by wallet and observed slot, while treating trade history as a paginated source that needs explicit refresh rules. Snapshot calls and full history calls have different credit implications, so measure them separately in your client telemetry.

Adding Rugcheck and Risk Scores to Your Client

Risk checks belong before transaction construction, not after a user signs. A new memecoin buy can call the full token/:tokenAddress/rugcheck report for an inspection screen, while a lighter risk endpoint can support a fast confirmation modal.

A professional woman in a suit reviewing risk scores and rug compliance reports in a sketch style.

Authority flags matter because an active mint or freeze authority changes the user's risk decision. Keep the guard explicit and return reasons that the UI can render:

type RiskReport = {
  score: number;
  mintAuthority?: string | null;
  freezeAuthority?: string | null;
  reasons?: string[];
};

async function preSwapGuard(
  client: typeof apiClient,
  tokenAddress: string,
): Promise<RiskReport> {
  const report = await client.tokens.rugcheck(tokenAddress);

  if (report.mintAuthority) {
    throw new Error("Swap blocked: mint authority is still active");
  }

  if (report.freezeAuthority) {
    throw new Error("Swap blocked: freeze authority is still active");
  }

  return report;
}

Replace typeof apiClient with the concrete client type exported by your installed package. Also define the score threshold in configuration, rather than hiding it inside the function, so a trading interface and an automated strategy can apply different policies.

Scores update per slot, so a cached result needs a freshness policy. The verified product information describes Rugcheck as a 1 to 10 score across 20 or more risk factors, including authority signals and wallet behavior indicators. Treat that score as decision support, not a guarantee that a trade is safe.

The full report, lighter score call, and any bulk risk workflow can have different credit costs. Keep the endpoint cost in one configuration object and show the user why a transaction was blocked.

Subscribing to Real-Time Datastream Rooms

Polling is a poor fit for token launches, pool trades, and wallet activity. Datastream provides WebSocket rooms for live crypto events, including token launches, wallet activity, price updates, and volume. Its documentation states that Datastream starts on the Premium plan and above, offers 20 or more room types, and Premium+ supports unlimited messages without usage-based fees. (Solana Tracker pricing and Datastream details)

A small wrapper should own connection state and event parsing:

type DatastreamEvent =
  | { type: "token_launch"; mint: string; symbol?: string }
  | { type: "trade"; pool: string; price: number; side: "buy" | "sell" }
  | { type: "wallet_activity"; wallet: string; signature: string };

const ws = new WebSocket(process.env.DATASTREAM_URL!);

ws.addEventListener("open", () => {
  ws.send(JSON.stringify({
    action: "subscribe",
    room: "token_launches",
  }));
});

ws.addEventListener("message", (message) => {
  const event = JSON.parse(message.data) as DatastreamEvent;
  eventQueue.push(event);
});

function unsubscribe() {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({
      action: "unsubscribe",
      room: "token_launches",
    }));
  }
  ws.close();
}

The payload names above are an adapter shape. Confirm the current room subscription contract before shipping. Room categories can map cleanly to workflows:

Room Type Event Payload Use Case Credits / Hour
Token launches New mint and launch metadata Discovery and pre-swap Rugcheck Not specified
Pool trades Pool, side, price, and trade data Live execution signals Not specified
Wallet activity Wallet and transaction activity Whale or portfolio monitoring Not specified
Price and volume Market updates Charts and alerts Not specified

Don't render every event directly. Push events into a bounded queue, coalesce updates by mint or pool, and let the UI consume the latest state. Reconnect after close codes 1006 and 1011 with backoff, but avoid a reconnect storm by allowing only one pending timer and closing old listeners.

Solana's own WebSocket RPC also exposes accountSubscribe, logsSubscribe, programSubscribe, signatureSubscribe, blockSubscribe, and rootSubscribe, which can support lower-level monitoring such as wallet changes, program logs, or trade confirmation. (Solana WebSocket subscription methods)

Designing for Type Safety at the Network Boundary

A generated interface describes what the server is expected to return. It doesn't transform hostile JSON into valid trading data. Solana RPC responses can contain null values, optional fields, program-specific variations, and values that shouldn't pass through JavaScript number handling without deliberate treatment.

Keep the response as unknown until a runtime schema accepts it. With Zod, the parser can both validate and infer the application type:

import { z } from "zod";

const SolAmount = z
  .string()
  .regex(/^\d+(\.\d+)?$/)
  .brand<"SolAmount">();

const TokenSchema = z.object({
  address: z.string().min(1),
  symbol: z.string().optional(),
  price: z.number().finite().optional(),
  amount: SolAmount.optional(),
}).strip();

type SafeToken = z.infer<typeof TokenSchema>;

function parseToken(payload: unknown): SafeToken {
  return TokenSchema.parse(payload);
}

The branded amount prevents a raw string from being confused with an arbitrary identifier. For large token quantities, keep the original decimal representation or convert through a decimal library. Don't use Number just because the generated interface says a field is numeric.

The practical pattern is:

  1. Receive unknown.
  2. Parse and strip fields you don't use.
  3. Narrow success and error envelopes.
  4. Pass only the inferred safe type to swap and portfolio logic.

The same principle applies when an OpenAPI document exists. Generation is useful for maintainability, especially when types regenerate in CI and contract checks detect drift, but generated output still needs runtime validation at the network edge. A thin handwritten wrapper plus schemas is often easier to maintain for a focused API, while code generation fits large specifications a team doesn't own. (Type-safe API client boundary patterns)

Handling Rate Limits, Retries, and Timeouts

A retry wrapper must distinguish a delayed read from an execution decision. Retrying a token price lookup can be reasonable. Blindly retrying a submitted swap can duplicate side effects unless the operation has an idempotency design.

Public Solana RPC endpoints enforce 100 requests per 10 seconds per IP, 40 requests per 10 seconds per single RPC, 40 concurrent connections per IP, 40 connection attempts per 10 seconds per IP, and 100 MB of data per 30 seconds. These limits make batching, bounded concurrency, and cancellation part of client correctness, not optional tuning. (Solana cluster rate limits)

A hand-drawn illustration depicting common bugs in a TypeScript API client and HTTP request failure scenarios.

A reusable read wrapper can classify failures before callers handle them:

type ClientError =
  | { kind: "RateLimitError"; resetAt?: number }
  | { kind: "TimeoutError" }
  | { kind: "ValidationError"; message: string }
  | { kind: "ServerError"; status: number };

async function withTimeout<T>(
  operation: (signal: AbortSignal) => Promise<T>,
  milliseconds: number,
): Promise<T> {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), milliseconds);

  try {
    return await operation(controller.signal);
  } catch (error) {
    if (controller.signal.aborted) {
      throw { kind: "TimeoutError" } satisfies ClientError;
    }
    throw error;
  } finally {
    clearTimeout(timer);
  }
}

Use a short timeout for a price read and a longer one for wallet PnL, but keep both configurable. On 429, read X-RateLimit-Reset when available, add jitter to exponential backoff, and cap attempts. A circuit breaker should stop sending traffic after repeated server failures and recover only after a cooldown.

For a clear explanation of retry windows, reset headers, and backoff behavior, the CloudCops GmbH guide to rate limiting is a useful companion. Align retry budgets with the selected plan rather than allowing every component to retry independently.

Common Integration Bugs and Quick Fixes

Production failures usually come from the boundary between an apparently typed method and the messy behavior around it.

Symptom in a Solana workflow Cause Quick fix
Token page shows stale metadata after a program change Generated or handwritten models weren't refreshed Regenerate types in CI and validate the live payload
Launch monitor stops after a 429 The client ignores reset information Classify 429, honor reset headers, and back off with jitter
Datastream opens repeated sockets after a drop Reconnect handlers schedule themselves more than once Track one socket and one reconnect timer per room
Supply read fails during logging BigInt reaches JSON.stringify Serialize large values explicitly as strings
Browser dApp gets blocked by CORS A secret-bearing server client was moved into the browser Proxy authenticated calls through a server route
Bulk holder lookup uses more credits than expected Each mint became a separate request Batch addresses where the endpoint supports it and meter calls

The most dangerous bug is a silent cast. as TokenInfo can make a missing price look valid to the compiler while the swap modal receives undefined. Parse first, then render a loading or unavailable state.

A WebSocket room also needs an explicit lifecycle. Unsubscribe on component disposal, clear timers on close, and discard messages from an old socket after a reconnect. For supply and balances, preserve integer precision until the display layer formats the value.

Finally, log credit usage by endpoint and workflow. A holder screen, rug check, wallet refresh, and trade table shouldn't all report under one generic api.request event. Per-route accounting shows which feature is consuming capacity before the trading service reaches its ceiling.

Quick Reference Card for Your Solana Client

Keep this table beside the editor. It maps a trading requirement to a boundary pattern without hiding the operational cost questions.

Capability Client Pattern Endpoint / Method Crypto Use Case
Token data Typed response plus runtime parser token/:tokenAddress Price and metadata before a swap
Recent trades Cursor pagination and pool-aware model trades Live pool activity table
Wallet PnL Paginated history plus FIFO calculation wallet/:address/trades Portfolio performance
Leaderboards Typed sorting and pagination leaderboard Compare wallet activity
Rugcheck scoring Pre-swap guard and authority checks token/:tokenAddress/rugcheck and risk Block risky token entries
Datastream rooms Typed events, queue, and reconnect ownership WebSocket room subscription Launch, trade, and wallet alerts

A production TypeScript API client should therefore combine generated or handwritten types, runtime schemas, centralized authentication, bounded retries, and explicit credit telemetry. Solana Tracker offers a Data API, Datastream feeds, RPC infrastructure, swap tooling, and risk analysis for these Solana workflows. Visit Solana Tracker to review the available developer interfaces, then wire one typed token lookup and one pre-swap risk guard before expanding into wallet PnL or streaming rooms.

More articles

Best DEX Aggregator: 7 Crypto Options Compared
best dex aggregatorDEX aggregatorsSolana trading

Best DEX Aggregator: 7 Crypto Options Compared

August 31, 2026·14 min read
The Imperative for Privacy in Crypto in 2026
privacy in cryptocrypto privacy toolsSolana privacy

The Imperative for Privacy in Crypto in 2026

August 30, 2026·15 min read
Agave 4.2 Update: Everything You Need to Know
Agave 4.2Solana upgradeAlpenglow

Agave 4.2 Update: Everything You Need to Know

August 29, 2026·17 min read