▾ Documentation

WebSocket examples

Copy-paste WebSocket subscription examples for slot, account, and program updates in TypeScript, Rust, and Python.

// updated 2026-06-04

Copy-paste working examples for connecting to Supanode WebSocket.

Prerequisites

  • An active Supanode Bundle subscription or free trial. Don't have one? Contact @supanode_tgs on Telegram.
  • Your server's public IP registered in the Bundle IP allowlist.
  • The WebSocket endpoint URL (default: ws://fra.supanode.xyz:8900).

Authorization is by IP - no tokens to pass during the WebSocket handshake.

Subscribe to slot updates

The lightest possible WebSocket subscription - useful as a smoke test.

import { Connection } from "@solana/web3.js";

const connection = new Connection("http://fra.supanode.xyz:8899", {
  wsEndpoint: "ws://fra.supanode.xyz:8900",
});

const subscriptionId = connection.onSlotChange((slotInfo) => {
  console.log("New slot:", slotInfo.slot);
});

// To unsubscribe later:
// await connection.removeSlotChangeListener(subscriptionId);

Subscribe to an account

Stream updates for a single account.

import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection("http://fra.supanode.xyz:8899", {
  wsEndpoint: "ws://fra.supanode.xyz:8900",
});

const accountAddress = new PublicKey("YOUR_ACCOUNT_PUBKEY");

const subscriptionId = connection.onAccountChange(
  accountAddress,
  (accountInfo) => {
    console.log("Balance:", accountInfo.lamports);
    console.log("Data:", accountInfo.data.toString("base64"));
  },
  "confirmed"
);

Subscribe to a program (with required filter)

programSubscribe requires either a dataSize or memcmp filter on shared plans. Whole-program subscriptions are blocked - see Restrictions.

import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection("http://fra.supanode.xyz:8899", {
  wsEndpoint: "ws://fra.supanode.xyz:8900",
});

const programId = new PublicKey("YOUR_PROGRAM_ID");

const subscriptionId = connection.onProgramAccountChange(
  programId,
  (keyedAccountInfo) => {
    console.log("Account:", keyedAccountInfo.accountId.toBase58());
    console.log("Lamports:", keyedAccountInfo.accountInfo.lamports);
  },
  "confirmed",
  [{ dataSize: 165 }]   // required filter
);

Production tips

  1. Reconnect with exponential backoff. WebSocket connections can drop. Implement retry starting at 1 second, capped at 30 seconds.

  2. Re-establish subscriptions on reconnect. Subscription IDs are connection-scoped. After reconnect, all subscriptions are gone - resubscribe to what you need.

  3. Send a ping every 30-60 seconds. Idle timeout is 10 minutes, but a periodic ping keeps the connection healthy and detects half-open sockets.

  4. Watch your subscription budget. Total subs per plan is a hard cap. See Limits.

  5. Switch to gRPC for high throughput. If you need many account / transaction streams at once, gRPC is the right tool.

Where to go next

Limits
Connection caps and subscription totals.
Restrictions
Blocked subscriptions.
Free Trials
48-hour trial.
Switch to gRPC
For high-throughput streams.