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
-
Reconnect with exponential backoff. WebSocket connections can drop. Implement retry starting at 1 second, capped at 30 seconds.
-
Re-establish subscriptions on reconnect. Subscription IDs are connection-scoped. After reconnect, all subscriptions are gone - resubscribe to what you need.
-
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.
-
Watch your subscription budget. Total subs per plan is a hard cap. See Limits.
-
Switch to gRPC for high throughput. If you need many account / transaction streams at once, gRPC is the right tool.