Getting Started with Surge
Overview
Switchboard Surge is the industry's fastest oracle data delivery system, providing sub-100ms latency through direct WebSocket streaming. Built for perpetual exchanges, oracle-based AMMs, and high-frequency trading systems.
🚀 Zero Setup Required
Just like bundles, Surge requires NO data feed accounts:
❌ No need to create on-chain feed accounts
❌ No need to deploy or manage contracts
❌ No need to fund accounts with SOL
✅ Just get an API key and start streaming prices instantly!
How is Surge So Fast?
Surge capitalizes on Switchboard's SAIL framework to verify a hardware proof of the oracle upon joining the network, proving the oracle signing prices is only running verified Switchboard code. This oracle then streams directly from price discovery sources without needing to report state to any middleware layer like its own L1.
Other pull oracles gather price information, write to a state layer, and come to consensus. Surge verifies a hardware proof on bootup to prove its legitimacy and unalterability and streams directly to users.
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Price Sources │────▶│ Oracle Network │────▶│ Surge Gateway │
│ (CEX, DEX) │ │ (SAIL Verified)│ │ (WebSocket) │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
┌──────────▼──────────┐
│ Your Application │
│ • Event Listeners │
│ • Price Handlers │
│ • Bundle Converter │
└─────────────────────┘
Key Features
Sub-100ms Latency: Direct oracle-to-client streaming
Event-Driven: Receive updates as prices change
No Polling: Persistent WebSocket eliminates overhead
Bundle Compatible: Convert streams to on-chain bundles seamlessly
Auto-Reconnect: Built-in connection recovery
Implementation
import * as sb from "@switchboard-xyz/on-demand";
// Initialize Surge client
const surge = new sb.Surge({
apiKey: process.env.SURGE_API_KEY!,
// gatewayUrl is optional - leave empty for automatic selection
});
// Discover available feeds
const availableFeeds = await surge.getSurgeFeeds();
console.log(`Found ${availableFeeds.length} available feeds`);
// Subscribe to price feeds
await surge.connectAndSubscribe([
{ symbol: 'BTC/USD' },
{ symbol: 'SOL/USD' },
]);
// Handle real-time updates
surge.on('update', async (response: sb.SurgeUpdate) => {
console.log(`${response.data.symbol}: $${response.data.price}`);
console.log(`Latency: ${Date.now() - response.data.source_ts_ms}ms`);
// Option 1: Use price directly
await updatePriceDisplay(response.data);
// Option 2: Convert to on-chain bundle
if (shouldExecuteTrade(response)) {
const [sigVerifyIx, bundle] = response.toBundleIx();
await executeTrade(sigVerifyIx, bundle);
}
});
Primary Use Cases
📈 Perpetual Exchanges
// Real-time mark price updates for perpetuals
surge.on('update', async (response: sb.SurgeUpdate) => {
const market = perpetuals.get(response.data.symbol);
// Update mark price instantly
market.markPrice = response.data.price;
// Check liquidations with zero latency
const underwaterPositions = await market.checkLiquidations(response.data.price);
for (const position of underwaterPositions) {
const [ix, bundle] = response.toBundleIx();
await liquidatePosition(position, ix, bundle);
}
// Calculate funding rates
await market.updateFundingRate(response.data);
});
🔄 Oracle-Based AMMs
// Next-gen AMM using oracle prices (no impermanent loss)
class OracleAMM {
async handlePriceUpdate(response: sb.SurgeUpdate) {
// Update pricing curve with oracle data
this.pairs[response.data.symbol] = {
price: response.data.price,
timestamp: response.data.source_ts_ms
};
}
async swap(tokenA: string, tokenB: string, amount: number) {
const price = this.pairs[`${tokenA}/${tokenB}`].price;
const output = amount * price * (1 - FEE);
// Use bundle for on-chain verification
const [ix, bundle] = this.latestUpdate.toBundleIx();
return await executeSwap(ix, bundle, output);
}
}
High-Frequency Trading
surge.on('update', async (response: sb.SurgeUpdate) => {
const opportunity = checkArbitrage(response.data);
if (opportunity?.profit > MIN_PROFIT) {
// Execute within milliseconds
const [ix, bundle] = response.toBundleIx();
await executeArbitrageTrade(ix, bundle);
}
});
Using Crossbar to Stream Surge Prices to Your UI
What is Crossbar?
Crossbar is Switchboard's local gateway service that enables you to stream real-time oracle prices directly to your frontend applications.
Setting Up Crossbar
# Using Docker Compose (recommended)
git clone https://github.com/switchboard-xyz/crossbar
cd crossbar
docker-compose up -d
# Crossbar will be available at:
# HTTP: http://localhost:8080
# WebSocket: ws://localhost:8080/ws
Frontend Integration
// React example with real-time price updates
import { useEffect, useState } from 'react';
interface PriceData {
symbol: string;
price: number;
source_ts_ms: number;
feedHash: string;
}
export function PriceFeed({ symbol }: { symbol: string }) {
const [priceData, setPriceData] = useState<PriceData | null>(null);
useEffect(() => {
const websocket = new WebSocket('ws://localhost:8080/ws');
websocket.onopen = () => {
websocket.send(JSON.stringify({
type: 'subscribe',
feeds: [symbol]
}));
};
websocket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'price_update' && data.symbol === symbol) {
setPriceData({
symbol: data.symbol,
price: data.price,
source_ts_ms: data.source_ts_ms,
feedHash: data.feedHash
});
}
};
return () => websocket.close();
}, [symbol]);
if (!priceData) return <div>Loading...</div>;
return (
<div className="price-feed">
<h3>{priceData.symbol}</h3>
<div className="price">${priceData.price.toFixed(2)}</div>
<div className="latency">
Latency: {Date.now() - priceData.source_ts_ms}ms
</div>
</div>
);
}
Current Limits & Pricing
Cost: FREE during launch phase
Rate Limits: 5 concurrent WebSocket connections per API key
Auto-reconnect: Built-in automatic reconnection on disconnect
Approval Time: ~3 days for API key
Requirements: None - open to all developers
Getting Started
Request API access: https://tinyurl.com/yqubsr8e
Approval time: ~3 days
No requirements - open to all
Currently FREE with 5 concurrent connections
Set up WebSocket connection with your API key
Subscribe to desired price feeds
Auto-reconnection is handled automatically
FAQ
How is Surge different from bundles?
Surge streams data directly to your application via WebSocket for real-time use. Bundles are for on-chain smart contract integration. You can convert Surge updates to bundles when needed.
What happens on disconnect?
The SDK includes automatic reconnection logic with exponential backoff. Your application will seamlessly recover from network interruptions.
Can I use custom feeds?
Contact the Switchboard team for custom feed requests.
Next Steps
View the complete Surge overview
Explore code examples
Learn about Crossbar gateway
Join our Discord for support
Last updated