JavaScript / Node.js
Track all pending settlements
Copy
const WebSocket = require("ws");
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.on("open", () => {
ws.send(JSON.stringify({
action: "subscribe",
type: "settlements",
filters: { status: "pending" }
}));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
switch (msg.type) {
case "snapshot":
console.log(`Loaded ${msg.count} recent settlements`);
break;
case "settlement":
const d = msg.data;
console.log(
`${d.status.toUpperCase()} | ${d.taker_side} ${d.taker_size} shares @ ${d.taker_price}`,
`| "${d.market_title}" (${d.outcome})`
);
break;
case "status_update":
console.log(`Confirmed: ${msg.data.tx_hash} in ${msg.data.latency_ms}ms`);
break;
case "heartbeat":
break; // ignore
}
});
// Reconnect on close
ws.on("close", () => setTimeout(() => process.exit(1), 1000));
Whale alerts ($5K+)
Copy
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.on("open", () => {
ws.send(JSON.stringify({
action: "subscribe",
type: "large_trades",
filters: { min_size: 5000 }
}));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
if (msg.type === "settlement") {
const d = msg.data;
console.log(`WHALE ALERT: ${d.taker_side} $${d.taker_size.toFixed(0)} @ ${d.taker_price}`);
console.log(` Market: ${d.market_title} (${d.outcome})`);
console.log(` Wallet: ${d.taker_wallet}`);
console.log(` TX: ${d.tx_hash}`);
}
});
Monitor a specific market by slug
Copy
ws.send(JSON.stringify({
action: "subscribe",
type: "markets",
filters: {
slugs: ["will-pete-hegseth-win-the-2028-us-presidential-election"],
snapshot_count: 100 // Get last 100 events
}
}));
Track a wallet
Copy
ws.send(JSON.stringify({
action: "subscribe",
type: "wallets",
filters: {
wallets: ["0xabcdef1234567890abcdef1234567890abcdef12"]
}
}));
// Receives: settlements, trades, position changes, deposits, status updates
Chainlink price feed
Copy
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.on("open", () => {
ws.send(JSON.stringify({
action: "subscribe",
type: "chainlink",
filters: { feeds: ["BTC/USD"] }
}));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
if (msg.type === "price_feed") {
const d = msg.data;
console.log(`BTC/USD: $${d.price.toFixed(2)} (bid: $${d.bid.toFixed(2)}, ask: $${d.ask.toFixed(2)})`);
}
});
Settlements + price feeds on same connection
Copy
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.on("open", () => {
// Subscribe to both — they're independent streams
ws.send(JSON.stringify({ action: "subscribe", type: "settlements" }));
ws.send(JSON.stringify({ action: "subscribe", type: "chainlink" }));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
switch (msg.type) {
case "settlement":
console.log(`TRADE: ${msg.data.taker_side} ${msg.data.taker_size} @ ${msg.data.taker_price}`);
break;
case "price_feed":
console.log(`BTC: $${msg.data.price.toFixed(2)}`);
break;
}
});
Python
asyncio client with reconnection
Copy
import asyncio
import json
import websockets
API_KEY = "pn_live_YOUR_KEY"
URL = f"wss://ws.polynode.dev/ws?key={API_KEY}"
async def connect():
while True:
try:
async with websockets.connect(URL) as ws:
# Subscribe to pending settlements
await ws.send(json.dumps({
"action": "subscribe",
"type": "settlements",
"filters": {"status": "pending", "min_size": 100}
}))
async for message in ws:
msg = json.loads(message)
if msg["type"] == "snapshot":
print(f"Loaded {msg['count']} recent events")
elif msg["type"] == "settlement":
d = msg["data"]
print(f"{d['taker_side']} {d['taker_size']:.0f} @ {d['taker_price']:.2f}"
f" | {d.get('market_title', 'unknown')}")
elif msg["type"] == "status_update":
print(f"Confirmed: {msg['data']['tx_hash'][:16]}..."
f" ({msg['data']['latency_ms']}ms)")
except (websockets.ConnectionClosed, ConnectionError) as e:
print(f"Disconnected: {e}. Reconnecting in 3s...")
await asyncio.sleep(3)
asyncio.run(connect())
Multiple wallet subscriptions
Copy
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
const subscriptionIds = [];
ws.on("open", () => {
// Subscribe to multiple wallet groups — each creates an independent subscription
ws.send(JSON.stringify({
action: "subscribe",
type: "wallets",
filters: { wallets: ["0xWallet1...", "0xWallet2..."] }
}));
ws.send(JSON.stringify({
action: "subscribe",
type: "wallets",
filters: { wallets: ["0xWallet3...", "0xWallet4..."] }
}));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
if (msg.type === "subscribed") {
// Save subscription_id for targeted unsubscribe later
subscriptionIds.push(msg.subscription_id);
console.log(`Subscribed: ${msg.subscription_id}`);
}
if (msg.type === "settlement") {
console.log(`${msg.data.taker_side} ${msg.data.taker_size} @ ${msg.data.taker_price}`);
}
});
// Later: remove just one subscription
// ws.send(JSON.stringify({ action: "unsubscribe", subscription_id: subscriptionIds[0] }));
// Or remove all
// ws.send(JSON.stringify({ action: "unsubscribe" }));
wscat (CLI)
Quick testing from the command line:Copy
# Install
npm install -g wscat
# Connect
wscat -c "wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY"
# Once connected, paste:
{"action": "subscribe", "type": "settlements", "filters": {"status": "pending"}}
Copy
# Subscribe to Chainlink BTC/USD prices
{"action": "subscribe", "type": "chainlink"}
# Subscribe to whale trades (stacks with previous subscriptions)
{"action": "subscribe", "type": "large_trades", "filters": {"min_size": 10000}}
# Subscribe by market slug
{"action": "subscribe", "type": "markets", "filters": {"slugs": ["bitcoin-100k-2026"]}}
# Ping
{"action": "ping"}
# Unsubscribe a specific subscription (use the subscription_id from the ack)
{"action": "unsubscribe", "subscription_id": "abc123:1"}
# Unsubscribe all
{"action": "unsubscribe"}
curl (WebSocket upgrade)
Copy
# Using websocat (Rust CLI tool)
websocat "wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY"
# Then type:
{"action":"subscribe","type":"settlements"}
Common patterns
Reconnection with exponential backoff
Copy
function createConnection() {
let delay = 1000;
function connect() {
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.onopen = () => {
delay = 1000; // Reset backoff
ws.send(JSON.stringify({
action: "subscribe",
type: "settlements"
}));
};
ws.onclose = () => {
console.log(`Reconnecting in ${delay}ms...`);
setTimeout(connect, delay);
delay = Math.min(delay * 2, 30000); // Max 30s
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type !== "heartbeat") {
handleEvent(msg);
}
};
}
connect();
}
Pending-to-confirmed tracking
Copy
const pending = new Map();
function handleEvent(msg) {
if (msg.type === "settlement" && msg.data.status === "pending") {
pending.set(msg.data.tx_hash, {
...msg.data,
received_at: Date.now()
});
console.log(`PENDING: ${msg.data.taker_side} ${msg.data.taker_size} @ ${msg.data.taker_price}`);
}
if (msg.type === "status_update") {
const original = pending.get(msg.data.tx_hash);
if (original) {
console.log(`CONFIRMED: ${msg.data.latency_ms}ms latency, block ${msg.data.block_number}`);
pending.delete(msg.data.tx_hash);
}
}
}

