Skip to main content

Overview

The SDK provides WebSocket support for real-time quote streaming. The WebSocket client handles connection management, automatic reconnection with exponential backoff, and ping/pong keep-alive. There are two ways to use WebSocket:
  1. High-level: Use streamQuotes / streamQuotesByTicker convenience methods on MakerClient
  2. Low-level: Use WSClient directly with event-based message handling

Enabling WebSocket

Before streaming quotes, enable the WebSocket connection:
const ws = client.maker.enableWebSocket('wss://api.kaleidoswap.com/ws/my-client-id');
The URL includes a client ID for session tracking. The enableWebSocket method returns a WSClient instance.

High-Level API

streamQuotesByTicker / stream_quotes_by_ticker

The simplest way to stream quotes. Automatically discovers routes and starts streaming.
const unsubscribe = await client.maker.streamQuotesByTicker(
  'BTC',           // fromTicker
  'USDT',          // toTicker
  100000,          // amount
  (quote) => {     // callback
    console.log(`Price: ${quote.price}, RFQ: ${quote.rfq_id}`);
  },
  {                // options (optional)
    preferredFromLayer: 'BTC_LN',
    preferredToLayer: 'RGB_LN'
  }
);

// Stop streaming when done
unsubscribe();

streamQuotes / stream_quotes

Stream quotes for a specific route (asset IDs and layers).
const unsubscribe = await client.maker.streamQuotes(
  'BTC',           // from_asset ID
  'USDT',          // to_asset ID
  100000,          // from_amount (or null)
  'BTC_LN',        // from_layer (or null)
  'RGB_LN',        // to_layer (or null)
  (quote) => {
    console.log(`${quote.from_amount} -> ${quote.to_amount}`);
  }
);

streamQuotesForAllRoutes / stream_quotes_for_all_routes

Stream quotes for all available routes between two tickers simultaneously.
const unsubscribers = await client.maker.streamQuotesForAllRoutes(
  'BTC', 'USDT', 100000,
  (route, quote) => {
    console.log(`Route ${route}: price=${quote.price}`);
  }
);
// Returns: Map<string, () => void>
// Call each unsubscriber to stop, or iterate and call all

getAvailableRoutes / get_available_routes

Discover available routes for a pair before streaming.
const routes = await client.maker.getAvailableRoutes('BTC', 'USDT');
// Returns: Array<{ from_layer: string; to_layer: string }>
for (const route of routes) {
  console.log(`${route.from_layer} -> ${route.to_layer}`);
}

Low-Level WSClient API

For full control, use the WSClient directly.

Connection

const ws = client.maker.enableWebSocket('wss://api.kaleidoswap.com/ws/my-client');

await ws.connect();
console.log(`Connected: ${ws.isConnected()}`);

// When done
ws.disconnect();

Events

Subscribe to events using on / off:
EventDataDescription
connectedConnection established
disconnectedConnection closed
reconnectingattempt: numberAttempting reconnection
quoteResponse / quote_responseQuoteResponseNew quote received
connectionEstablished / connection_establishedconnection dataServer confirmed connection
pongPongResponsePong received
errorErrorAn error occurred
maxReconnectExceeded / max_reconnect_exceededMax reconnection attempts reached
ws.on('connected', () => console.log('Connected'));
ws.on('disconnected', () => console.log('Disconnected'));
ws.on('reconnecting', (attempt) => console.log(`Reconnecting: attempt ${attempt}`));
ws.on('quoteResponse', (quote) => console.log(`Quote: ${quote.price}`));
ws.on('error', (error) => console.error(`Error: ${error.message}`));
ws.on('maxReconnectExceeded', () => console.log('Max reconnects exceeded'));

// Unsubscribe
const handler = (quote) => { /* ... */ };
ws.on('quoteResponse', handler);
ws.off('quoteResponse', handler);

Requesting Quotes

ws.requestQuote({
  from_asset: 'BTC',
  to_asset: 'USDT',
  from_amount: 100000,
  from_layer: 'BTC_LN',
  to_layer: 'RGB_LN'
});

Ping / Keep-Alive

The WSClient automatically pings the server at the configured interval. You can also ping manually:
ws.ping();

Configuration

The WSClient accepts configuration options:
OptionDefaultDescription
maxReconnectAttempts / max_reconnect_attempts5Maximum reconnection attempts
reconnectDelay / reconnect_delay1000ms / 1.0sBase delay between reconnections (exponential backoff)
pingInterval / ping_interval30000ms / 30.0sInterval between keep-alive pings
Reconnection uses exponential backoff: delay * 2^attempt.

WebSocket Protocol

The WebSocket uses a JSON message protocol:

Message Types

ActionDirectionDescription
quote_requestClient -> ServerRequest a price quote
quote_responseServer -> ClientQuote update
pingClient -> ServerKeep-alive ping
pongServer -> ClientKeep-alive response
connection_establishedServer -> ClientConnection confirmed
errorServer -> ClientError message

QuoteResponse Fields

FieldTypeDescription
from_assetstringSource asset ID
to_assetstringDestination asset ID
from_amountnumberSource amount
to_amountnumberDestination amount
pricenumberExchange rate
rfq_idstringRequest-for-quote ID (use to create orders)
price_precisionnumberPrice decimal precision
timestampnumberServer timestamp
expires_atnumberQuote expiry timestamp
feeFeeFee breakdown

Best Practices

Subscribe to disconnected and reconnecting events. The WSClient automatically reconnects with exponential backoff, but you should handle the case where max attempts are exceeded.
streamQuotesByTicker handles route discovery, connection management, and quote routing for you. Only use the low-level WSClient when you need custom control.
Always call the unsubscribe function returned by streamQuotes / streamQuotesByTicker when you no longer need quotes. This prevents memory leaks and unnecessary network traffic.
The rfq_id in each quote response is what you pass to createSwapOrder. Use the most recent quote to ensure the rate is still valid.