Real-time event server for the SIR protocol. Broadcasts auction events to frontends and computes leaderboard rankings in the background.
- Real-time Events - Watches SIR contracts for auctions, bids, and dividends, then broadcasts to connected frontends via Socket.IO
- Leaderboard Worker - Computes position PnL every 10 minutes and stores rankings in Redis
# From monorepo root (SIR/)
pnpm installcd websocket-server
cp .env.example .envEdit .env with your values. At minimum you need:
CHAIN_IDS=1,999,6343
WSS_URLS=wss://eth-mainnet.g.alchemy.com/v2/KEY,...
SIR_CONTRACT_ADDRESSES=0x4Da4...,0xA06D...,0x2149...
FRONTEND_URLS=https://app.sir.trading,http://localhost:3000For the leaderboard worker, also add:
LEADERBOARD_WORKER_ENABLED=true
REDIS_URL=redis://...
RPC_URLS=https://eth-mainnet.g.alchemy.com/v2/KEY,...
SUBGRAPH_URLS=https://api.goldsky.com/...,...# Development (hot reload)
pnpm dev
# Production
pnpm build && pnpm startcurl http://localhost:8080/healthThe server broadcasts these Socket.IO events:
| Event | Description |
|---|---|
auctionStarted |
New auction began |
bidReceived |
Someone placed a bid |
auctionSettled |
Auction ended, tokens sent to winner |
dividendsPaid |
Dividends distributed to stakers |
All events include chainId so frontends can filter by chain.
-
Create service - New → GitHub Repo → select
SIRmonorepo -
Build settings:
- Root Directory:
websocket-server - Build Command:
npm install && npm run build - Start Command:
npm start
- Root Directory:
-
Environment variables - Add all variables from
.env.example -
Generate domain - Settings → Networking → Generate Domain
-
Health check - Point to
/healthendpoint
In the Next.js App's .env:
NEXT_PUBLIC_WEBSOCKET_URL=https://your-railway-domain.up.railway.appThe App's useRealtimeAuctions hook connects automatically. Falls back to polling if not set.
When enabled, the worker:
- Runs every 10 minutes
- Fetches positions from subgraph
- Computes PnL using on-chain data
- Writes rankings to Redis ZSETs
The App's /api/leaderboard/active endpoint reads directly from Redis for instant responses.
Check worker status in /health response under leaderboardWorker.
| Variable | Required | Description |
|---|---|---|
CHAIN_IDS |
✓ | Chain IDs (e.g., 1,999,6343) |
WSS_URLS |
✓ | WebSocket RPCs for events |
SIR_CONTRACT_ADDRESSES |
✓ | SIR contract per chain |
FRONTEND_URLS |
✓ | CORS origins |
PORT |
Default: 8080 |
|
LEADERBOARD_WORKER_ENABLED |
Set true to enable |
|
REDIS_URL |
Worker | Redis connection |
RPC_URLS |
Worker | HTTP RPCs for multicalls |
SUBGRAPH_URLS |
Worker | Goldsky endpoints |
SUBGRAPH_API_KEY |
Subgraph auth | |
COINGECKO_API_KEY |
Price fetching | |
MAX_POSITIONS_PER_RUN |
Default: 500 |
Vector variables (CHAIN_IDS, WSS_URLS, RPC_URLS, etc.) must have matching counts.