Skip to main content

Market Data Exploration

Fetch and display available assets and trading pairs.
import { KaleidoClient } from 'kaleidoswap-sdk';

const client = KaleidoClient.create({
  baseUrl: 'https://api.regtest.kaleidoswap.com',
});

// Fetch assets and pairs
const [assets, pairs] = await Promise.all([
  client.maker.listAssets(),
  client.maker.listPairs(),
]);

console.log(`Assets: ${assets.assets.length}`);
console.log(`Trading Pairs: ${pairs.pairs.length}`);

// Display each pair
for (const pair of pairs.pairs) {
  console.log(`${pair.base_asset_ticker}/${pair.quote_asset_ticker}`);
  for (const route of pair.routes ?? []) {
    console.log(`  Route: ${route.from_layer} -> ${route.to_layer}`);
    console.log(`  Min: ${route.min_from_amount} / Max: ${route.max_from_amount}`);
  }
}

Getting a Quote

Request a price quote before creating a swap order.
const quote = await client.maker.getQuote({
  from_asset: { asset_id: 'BTC', layer: 'BTC_LN', amount: 100000 },
  to_asset: { asset_id: 'USDT', layer: 'RGB_LN' }
});

console.log(`RFQ ID: ${quote.rfq_id}`);
console.log(`From: ${quote.from_amount} sats`);
console.log(`To: ${quote.to_amount} USDT`);
console.log(`Price: ${quote.price}`);
console.log(`Expires: ${new Date(quote.expires_at * 1000).toISOString()}`);

Complete Order-Based Swap

The full swap flow: get a quote, create an order, and track it to completion.
import { KaleidoClient, KaleidoError } from 'kaleidoswap-sdk';

const client = KaleidoClient.create({
  baseUrl: 'https://api.regtest.kaleidoswap.com',
});

async function executeSwap() {
  // Step 1: Get a quote
  const quote = await client.maker.getQuote({
    from_asset: { asset_id: 'BTC', layer: 'BTC_LN', amount: 100000 },
    to_asset: { asset_id: 'USDT', layer: 'RGB_LN' }
  });

  console.log(`Quote received: ${quote.from_amount} -> ${quote.to_amount}`);
  console.log(`Price: ${quote.price}`);

  // Step 2: Create the swap order
  const order = await client.maker.createSwapOrder({
    rfq_id: quote.rfq_id,
    from_asset: { asset_id: 'BTC', layer: 'BTC_LN', amount: quote.from_amount },
    to_asset: { asset_id: 'USDT', layer: 'RGB_LN', amount: quote.to_amount },
    receiver_address: 'lnbc1...',  // your destination address/invoice
  });

  console.log(`Order created: ${order.order_id}`);
  console.log(`Deposit address: ${order.deposit_address}`);
  console.log(`Pay this invoice/address to proceed.`);

  // Step 3: Wait for the user to pay, then track to completion
  const completed = await client.maker.waitForSwapCompletion(order.order_id, {
    timeout: 600,
    pollInterval: 10,
    onStatusUpdate: (status) => console.log(`Status: ${status}`)
  });

  console.log(`Swap completed! Final status: ${completed.status}`);
}

executeSwap().catch(console.error);

WebSocket Quote Streaming

Stream real-time quotes using WebSocket.

Using streamQuotesByTicker

The simplest way to get live quotes:
import { KaleidoClient } from 'kaleidoswap-sdk';

const client = KaleidoClient.create({
  baseUrl: 'https://api.regtest.kaleidoswap.com',
});

// Enable WebSocket
client.maker.enableWebSocket('wss://api.regtest.kaleidoswap.com/ws/my-client');

// Stream quotes
const unsubscribe = await client.maker.streamQuotesByTicker(
  'BTC',
  'USDT',
  100000,
  (quote) => {
    console.log(`Price: ${quote.price}`);
    console.log(`From: ${quote.from_amount} -> To: ${quote.to_amount}`);
    console.log(`Fee: ${quote.fee.final_fee}`);
    console.log(`RFQ ID: ${quote.rfq_id}`);
  },
  { preferredFromLayer: 'BTC_LN', preferredToLayer: 'RGB_LN' }
);

// Stop streaming after 60 seconds
setTimeout(() => unsubscribe(), 60000);

Using WSClient Directly

For more control, use the WSClient event-based API:
import { KaleidoClient } from 'kaleidoswap-sdk';

const client = KaleidoClient.create({
  baseUrl: 'https://api.regtest.kaleidoswap.com',
});

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

ws.on('connected', () => {
  console.log('WebSocket connected');

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

ws.on('quoteResponse', (quote) => {
  console.log(`Price: ${quote.price}`);
  console.log(`RFQ ID: ${quote.rfq_id}`);
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error.message);
});

ws.on('disconnected', () => {
  console.log('WebSocket disconnected');
});

await ws.connect();

Order Management

Track and manage swap orders.
// Check order status
const status = await client.maker.getSwapOrderStatus({ order_id: 'order-123' });
console.log(`Status: ${status.status}`);
console.log(`Payment: ${status.payment_status}`);

// Get order history
const history = await client.maker.getOrderHistory({ limit: 20 });
for (const order of history.orders) {
  console.log(`${order.order_id}: ${order.status}`);
}

// Get analytics
const stats = await client.maker.getOrderAnalytics();
console.log(`Total orders: ${stats.total_orders}`);

Rate Decision Handling

Handle rate changes on pending orders.
const status = await client.maker.getSwapOrderStatus({ order_id: 'order-123' });

if (status.status === 'PENDING_RATE_DECISION') {
  // Accept the new rate
  const result = await client.maker.submitRateDecision({
    order_id: 'order-123',
    accept_new_rate: true
  });
  console.log('Rate accepted, swap continues');

  // Or reject and get a refund:
  // await client.maker.submitRateDecision({
  //   order_id: 'order-123',
  //   accept_new_rate: false
  // });
}

RLN Node Operations

Manage your RGB Lightning Node.
const client = KaleidoClient.create({
  baseUrl: 'https://api.regtest.kaleidoswap.com',
  nodeUrl: 'http://localhost:3001',
});

// Get node info
const nodeInfo = await client.rln.getNodeInfo();
console.log(`Pubkey: ${nodeInfo.pubkey}`);

// Get balances
const btcBalance = await client.rln.getBtcBalance();
console.log(`On-chain: ${btcBalance.vanilla.spendable} sats`);

// List RGB assets
const rgbAssets = await client.rln.listAssets();
console.log(`RGB assets: ${rgbAssets.nia.length} NIA assets`);

// List channels
const channels = await client.rln.listChannels();
console.log(`Channels: ${channels.channels.length}`);

// Create a Lightning invoice
const invoice = await client.rln.createLNInvoice({
  amt_msat: 100000,
  expiry_sec: 3600,
  description: 'Payment for service'
});
console.log(`Invoice: ${invoice.invoice}`);

Amount Conversion

Use precision utilities for safe amount conversion.
import { toSmallestUnits, toDisplayUnits, createPrecisionHandler } from 'kaleidoswap-sdk';

// Simple conversion
const sats = toSmallestUnits(0.001, 8);     // 100000
const btc = toDisplayUnits(100000, 8);       // 0.001

// Using PrecisionHandler with asset metadata
const pairs = await client.maker.listPairs();
// ... create mapped assets from pairs
// const handler = createPrecisionHandler(mappedAssets);
// const raw = handler.toRawAmount(0.5, 'BTC_ASSET_ID');
// const display = handler.toDisplayAmount(50000000, 'BTC_ASSET_ID');

Error Handling

Handle specific error types for robust applications.
import {
  KaleidoClient,
  KaleidoError,
  NetworkError,
  ValidationError,
  QuoteExpiredError,
  NodeNotConfiguredError,
} from 'kaleidoswap-sdk';

try {
  const quote = await client.maker.getQuote({ /* ... */ });
  const order = await client.maker.createSwapOrder({ /* ... */ });
} catch (error) {
  if (error instanceof QuoteExpiredError) {
    console.log('Quote expired, fetching a new one...');
  } else if (error instanceof ValidationError) {
    console.log(`Invalid input: ${error.message}`);
  } else if (error instanceof NodeNotConfiguredError) {
    console.log('Node not configured for this operation');
  } else if (error instanceof NetworkError) {
    console.log(`Network issue: ${error.message}`);
    if (error.isRetryable()) {
      console.log('Retrying...');
    }
  } else if (error instanceof KaleidoError) {
    console.log(`SDK error [${error.code}]: ${error.message}`);
  }
}