Trade stream
Subscribe once and receive every trade your wallet participates in across all tokens—a single chronological feed suited to portfolio-wide alerts, journaling, or mirroring activity into your own infra. Billing and wallet eligibility match REST (see Authentication).
When this mode fits
- You want one connection that covers the whole wallet, without maintaining per-mint channels.
- Downstream logic deduplicates tokens itself or persists everything into a datastore.
- You intentionally avoid client-side filtering so you cannot miss ancillary fills on related assets.
If you only care about swaps on one mint, use Token stream instead—less traffic and simpler consumers.
Official TypeScript SDK
Highest-level API: omit tokenMint so handshake auth is only apiKey + walletAddress.
import { SendyClient, type WalletTradeStreamReady } from '@mvritz/sendy-sdk';
const client = new SendyClient({ apiKey: process.env.SENDY_API_KEY! });
const socket = client.connectWalletTradeStream('YOUR_WALLET');
socket.on('ready', (p: WalletTradeStreamReady) => {
console.assert(p.filter === 'all' && p.tokenMint === null);
});
socket.on('trade', () => {});
socket.on('disconnect', () => socket.close());Socket.IO handshake (all mints)
- URL:
https://api.sendy.lol - Namespace:
/sdk/wallet - Socket.IO HTTP path:
/socket.io
Auth JSON
{
"apiKey": "sendy_…",
"walletAddress": "<eligible solana pubkey>"
}Signals
ready— includesfilter: "all",tokenMint: nulltrade— full fill payload for any SPL involvederror— API key / wallet / quota issues
Implementations
Same behavior across languages: websocket transport, authenticated namespace handshake, then listen for trade. Rust snippet expects rust_socketio with the async feature plus tokio + serde_json.
import { io } from 'socket.io-client';
const socket = io('https://api.sendy.lol/sdk/wallet', {
path: '/socket.io',
transports: ['websocket'],
auth: {
apiKey: process.env.SENDY_API_KEY!,
walletAddress: 'YOUR_WALLET',
},
});
socket.on('ready', (p) => {
console.log('filter', p.filter);
});
socket.on('trade', (trade) => {
console.log(trade.tokenAddress, trade.side);
});
socket.on('error', (err) => console.error(err));
socket.io.on('close', () => socket.close());Reading wscat output
Socket.IO rides on Engine.IO framing; raw lines mix engine metadata with JSON payloads. The wscat flow is primarily for inspecting live bytes or proving connectivity—in production rely on socket.io-client, python-socketio, or rust_socketio which negotiate auth and namespaces for you.