import { useEffect, useState, useRef } from 'react';
import { io } from 'socket.io-client';
function OrderbookWidget({ symbol }) {
const [orderbook, setOrderbook] = useState(null);
const [globalBook, setGlobalBook] = useState(null);
const [connected, setConnected] = useState(false);
const socketRef = useRef(null);
useEffect(() => {
// Connect to WebSocket
const socket = io('wss://api.renesis.fi', {
transports: ['websocket'],
path: '/order-execution/socket.io'
});
socketRef.current = socket;
socket.on('connect', () => {
console.log('Connected to orderbook stream');
setConnected(true);
});
socket.on('connected', (data) => {
console.log('Server acknowledged:', data.message);
});
socket.on('subscribed', (data) => {
console.log(`Subscribed to ${data.symbol}`);
});
socket.on('orderbook_update', (data) => {
// Update orderbook state for specific venue
setOrderbook(prev => ({
...prev,
[data.venue]: data
}));
});
socket.on('global_book', (data) => {
// Update global aggregated view
setGlobalBook(data.data);
});
socket.on('orderbook_snapshot', (data) => {
// Initialize with full snapshot
setOrderbook(data.venues);
});
socket.on('error', (data) => {
console.error('Orderbook error:', data.message);
});
socket.on('disconnect', () => {
setConnected(false);
});
return () => {
socket.disconnect();
};
}, []);
// Subscribe when symbol changes
useEffect(() => {
if (connected && socketRef.current) {
// Unsubscribe from previous symbol
socketRef.current.emit('unsubscribe_orderbook', { symbol });
// Subscribe to new symbol
socketRef.current.emit('subscribe_orderbook', {
symbol,
venues: ['binance', 'bybit', 'gateio'],
include_global: true,
depth: 10
});
}
}, [symbol, connected]);
if (!connected) {
return <div>Connecting...</div>;
}
return (
<div>
{/* Global Best Prices */}
{globalBook && (
<div className="global-book">
<h3>Best Prices</h3>
<div>
Best Bid: ${globalBook.best_bid?.price}
@ {globalBook.best_bid?.venue}
</div>
<div>
Best Ask: ${globalBook.best_ask?.price}
@ {globalBook.best_ask?.venue}
</div>
</div>
)}
{/* Per-Venue Orderbooks */}
{orderbook && Object.entries(orderbook).map(([venue, data]) => (
<div key={venue} className="venue-book">
<h4>{venue} ({data.quality})</h4>
<div className="bids">
{data.bids?.slice(0, 5).map(([price, qty], i) => (
<div key={i}>{price} - {qty}</div>
))}
</div>
<div className="asks">
{data.asks?.slice(0, 5).map(([price, qty], i) => (
<div key={i}>{price} - {qty}</div>
))}
</div>
</div>
))}
</div>
);
}
export default OrderbookWidget;