Skip to main content

Live Trades

Stream real-time trade executions from Deepbook pools as they occur on-chain. Each event represents a completed order fill with full execution details including price, quantities, fees, and order IDs.

Event Type

Events are emitted with type deepbook_live_trades and include complete trade metadata from the blockchain.

Endpoint

GET /deepbook/{poolName}/live-trades

Parameters

ParameterTypeRequiredDescription
poolNamestringYesTrading pool name (e.g., "SUI_USDC")
api-keystringYesYour Surflux API key (query parameter)

Event Structure

{
"type": "deepbook_live_trades",
"timestamp_ms": 1758629823918,
"checkpoint_id": 193054501,
"tx_hash": "FgUfRsYpC6ynW3pRvtgCLaa4WniBZYdsSLP94jrZ3pj7",
"data": {
"event_digest": "FgUfRsYpC6ynW3pRvtgCLaa4WniBZYdsSLP94jrZ3pj70",
"digest": "FgUfRsYpC6ynW3pRvtgCLaa4WniBZYdsSLP94jrZ3pj7",
"sender": "0xb117b12facd947cabb3d17d68a67b3d8d6865280edb0644cb4d25a9d86646966",
"checkpoint": 193054501,
"checkpoint_timestamp_ms": 1758629823918,
"package": "0xf6cc231ead142d35c37494a4c36d9e78c97503c0be9f9a0652f6e1127304096a",
"pool_id": "0xe05dafb5133bcffb8d59f4e12465dc0e9faeaa05e3e342a08fe135800e3e4407",
"maker_order_id": "170141183460531590950028478855175318595",
"taker_order_id": "62359236787919212896114997",
"maker_client_order_id": "5797765110082330991",
"taker_client_order_id": "8",
"price": 3380500,
"taker_fee": 646286,
"taker_fee_is_deep": true,
"maker_fee": 0,
"maker_fee_is_deep": false,
"taker_is_bid": true,
"base_quantity": 443700000000,
"quote_quantity": 1499927850,
"maker_balance_manager_id": "0x344c2734b1d211bd15212bfb7847c66a3b18803f3f5ab00f5ff6f87b6fe6d27d",
"taker_balance_manager_id": "0x939adae6836dd87de7b7a2a48a5bd703dc1add7eb304d0c580217e000ccd2b10",
"onchain_timestamp": 1758629823805
}
}

Field Reference

Event Metadata

FieldTypeDescription
typestringAlways "deepbook_live_trades" for trade events
timestamp_msnumberEvent timestamp in milliseconds
checkpoint_idnumberSui checkpoint when trade occurred
tx_hashstringTransaction hash containing the trade

Trade Data

FieldTypeDescription
pool_idstringDeepbook pool identifier
pricenumberExecution price (in smallest units)
base_quantitynumberAmount of base asset traded (in smallest units)
quote_quantitynumberAmount of quote asset traded (in smallest units)
taker_is_bidbooleantrue if taker bought, false if taker sold
maker_order_idstringMaker's order ID
taker_order_idstringTaker's order ID
maker_client_order_idstringClient-assigned maker order ID
taker_client_order_idstringClient-assigned taker order ID

Fee Information

FieldTypeDescription
taker_feenumberFee paid by taker
taker_fee_is_deepbooleanWhether taker paid fee in DEEP tokens
maker_feenumberFee paid by maker (typically 0)
maker_fee_is_deepbooleanWhether maker paid fee in DEEP tokens

Blockchain Metadata

FieldTypeDescription
senderstringAddress that initiated the transaction
packagestringDeepbook package address
maker_balance_manager_idstringMaker's balance manager address
taker_balance_manager_idstringTaker's balance manager address
onchain_timestampnumberOn-chain timestamp in milliseconds

Use Cases

Live Trade Feed

Display the latest trades in a trading interface:

const trades = [];

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);

if (data.type === 'deepbook_live_trades') {
const trade = {
price: data.data.price / 1e6, // Convert from smallest units (USDC decimals)
amount: data.data.base_quantity / 1e9, // Convert from smallest units (SUI decimals)
side: data.data.taker_is_bid ? 'buy' : 'sell',
timestamp: new Date(data.data.checkpoint_timestamp_ms)
};

// Add to feed and keep last 50 trades
trades.unshift(trade);
if (trades.length > 50) trades.pop();

updateTradesFeed(trades);
}
};

Volume Calculation

Track trading volume over time:

let volumeTracker = {
baseVolume: 0,
quoteVolume: 0,
tradeCount: 0,
startTime: Date.now()
};

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);

if (data.type === 'deepbook_live_trades') {
volumeTracker.baseVolume += data.data.base_quantity;
volumeTracker.quoteVolume += data.data.quote_quantity;
volumeTracker.tradeCount++;

// Calculate volume per hour
const elapsedHours = (Date.now() - volumeTracker.startTime) / (1000 * 60 * 60);
const hourlyVolume = volumeTracker.quoteVolume / elapsedHours;

updateVolumeDisplay(hourlyVolume);
}
};

Price Chart Updates

Build live candlestick charts:

let currentCandle = null;
const candleInterval = 60000; // 1 minute

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);

if (data.type === 'deepbook_live_trades') {
const price = data.data.price;
const timestamp = data.data.checkpoint_timestamp_ms;
const candleTime = Math.floor(timestamp / candleInterval) * candleInterval;

if (!currentCandle || currentCandle.time !== candleTime) {
// Start new candle
if (currentCandle) {
chartData.push(currentCandle);
updateChart(chartData);
}

currentCandle = {
time: candleTime,
open: price,
high: price,
low: price,
close: price,
volume: 0
};
}

// Update current candle
currentCandle.high = Math.max(currentCandle.high, price);
currentCandle.low = Math.min(currentCandle.low, price);
currentCandle.close = price;
currentCandle.volume += data.data.base_quantity;

updateCurrentCandle(currentCandle);
}
};

Trading Bot Trigger

Execute automated strategies based on trade activity:

const strategy = {
tradeThreshold: 1000, // Minimum trade size in base asset
priceMovementPercent: 0.5 // 0.5% price movement
};

let lastSignificantPrice = null;

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);

if (data.type === 'deepbook_live_trades') {
const tradeSize = data.data.base_quantity / 1e9; // Convert to SUI
const price = data.data.price;

// Check for significant trades
if (tradeSize >= strategy.tradeThreshold) {
console.log('Large trade detected:', tradeSize, 'SUI');

if (lastSignificantPrice) {
const priceChange = ((price - lastSignificantPrice) / lastSignificantPrice) * 100;

if (Math.abs(priceChange) >= strategy.priceMovementPercent) {
// Trigger strategy
executeTradingStrategy(data.data.taker_is_bid ? 'buy' : 'sell', price);
}
}

lastSignificantPrice = price;
}
}
};

Understanding Trade Sides

The taker_is_bid field indicates the taker's side:

  • true — Taker placed a buy order (bid), taking liquidity from sell side

    • This is a market buy or aggressive limit buy
    • Typically shown as green/bullish in trading UIs
  • false — Taker placed a sell order (ask), taking liquidity from buy side

    • This is a market sell or aggressive limit sell
    • Typically shown as red/bearish in trading UIs

Price and Quantity Conversion

All values are in smallest units based on asset decimals. Convert using pool metadata from the Get Pools endpoint.

Example for SUI_USDC

  • Base asset (SUI): 9 decimals
  • Quote asset (USDC): 6 decimals
// Convert price
const rawPrice = 3380500;
const humanPrice = rawPrice / Math.pow(10, 6); // = 3.3805 USDC per SUI

// Convert base quantity
const rawBaseQty = 443700000000;
const humanBaseQty = rawBaseQty / Math.pow(10, 9); // = 443.7 SUI

// Convert quote quantity
const rawQuoteQty = 1499927850;
const humanQuoteQty = rawQuoteQty / Math.pow(10, 6); // = 1499.93 USDC

Connection Example

Complete example connecting to the live trades stream:

const poolName = 'SUI_USDC';
const apiKey = 'YOUR_API_KEY';

const url = `https://flux.surflux.dev/deepbook/${poolName}/live-trades?api-key=${apiKey}`;

const eventSource = new EventSource(url);

eventSource.onopen = () => {
console.log('Connected to Deepbook live trades stream');
};

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);

if (data.type === 'deepbook_live_trades') {
console.log('Trade:', {
pool: data.data.pool_id.slice(0, 10) + '...',
price: data.data.price,
amount: data.data.base_quantity,
side: data.data.taker_is_bid ? 'BUY' : 'SELL',
time: new Date(data.data.checkpoint_timestamp_ms).toISOString()
});
}
};

eventSource.onerror = (error) => {
console.error('Stream error:', error);
eventSource.close();

// Reconnect after 5 seconds
setTimeout(() => {
location.reload(); // Simple reconnection strategy
}, 5000);
};

Best Practices

  • Cache Pool Decimals — Fetch decimals once from Get Pools endpoint and reuse for all conversions
  • Filter by Trade Size — Ignore dust trades by checking base_quantity threshold
  • Aggregate for Display — Don't update UI on every single trade; batch updates every 100-200ms
  • Monitor Connection Health — SSE connections can drop; implement automatic reconnection with exponential backoff
  • Combine with Order Book — Use both trade stream and order book depth for complete market view

Next Steps