TypeScript SDK

Client Configuration

Client class configuration, initialization options, and connection management

Client Configuration

The Client class is the main entry point for interacting with LX. For simple use cases, you can use the DEX() factory function. This guide covers all configuration options and initialization patterns.

Quick Start

import { DEX } from '@luxfi/trading'

// Simple initialization with DEX factory
const dex = await DEX({ rpcUrl: 'http://localhost:8080/rpc' })

// Place an order
const order = await dex.limitBuy('BTC-USD', '1.0', '50000')

Advanced Initialization

import { Client, ClientConfig } from '@luxfi/trading'

const client = new Client({
  rpcUrl: 'http://localhost:8080/rpc',
  wsUrl: 'ws://localhost:8081'
})

Configuration Options

ClientConfig Interface

interface ClientConfig {
  /** JSON-RPC endpoint URL */
  rpcUrl?: string

  /** WebSocket endpoint URL */
  wsUrl?: string

  /** gRPC endpoint URL (for high-performance operations) */
  grpcUrl?: string

  /** API key for authenticated requests */
  apiKey?: string

  /** API secret for request signing */
  apiSecret?: string

  /** Request timeout in milliseconds (default: 30000) */
  timeout?: number

  /** Retry configuration */
  retry?: {
    maxRetries: number
    backoffMs: number
  }
}

Full Configuration Example

import { Client } from '@luxfi/trading'

const client = new Client({
  // API endpoints
  rpcUrl: 'https://api.lux.network/rpc',
  wsUrl: 'wss://api.lux.network/ws',
  grpcUrl: 'api.lux.network:50051',

  // Authentication
  apiKey: process.env.LX_DEX_API_KEY,
  apiSecret: process.env.LX_DEX_API_SECRET,

  // Performance tuning
  timeout: 30000,
  retry: {
    maxRetries: 3,
    backoffMs: 1000
  }
})

Environment-Based Configuration

Configuration Factory Pattern

import { Client, ClientConfig } from '@luxfi/trading'

type Environment = 'development' | 'testnet' | 'production'

function createConfig(env: Environment): ClientConfig {
  const configs: Record<Environment, ClientConfig> = {
    development: {
      rpcUrl: 'http://localhost:8080/rpc',
      wsUrl: 'ws://localhost:8081',
      timeout: 60000 // Longer timeout for debugging
    },
    testnet: {
      rpcUrl: 'http://localhost:18080/rpc',
      wsUrl: 'ws://localhost:18081',
      timeout: 30000
    },
    production: {
      rpcUrl: 'https://api.lux.network/rpc',
      wsUrl: 'wss://api.lux.network/ws',
      apiKey: process.env.LX_DEX_API_KEY,
      timeout: 15000,
      retry: {
        maxRetries: 3,
        backoffMs: 500
      }
    }
  }

  return configs[env]
}

// Usage
const env = (process.env.NODE_ENV as Environment) || 'development'
const client = new Client(createConfig(env))

Connection Management

Connecting WebSocket

The WebSocket connection must be explicitly established for real-time subscriptions:

import { Client } from '@luxfi/trading'

async function setupClient(): Promise<Client> {
  const client = new Client({
    rpcUrl: 'http://localhost:8080/rpc',
    wsUrl: 'ws://localhost:8081'
  })

  // Connect WebSocket for real-time data
  await client.connect()
  console.log('WebSocket connected')

  return client
}

Disconnecting

function cleanup(client: Client): void {
  // Gracefully close WebSocket connection
  client.disconnect()
  console.log('Client disconnected')
}

Connection State Management

import { Client, ClientConfig } from '@luxfi/trading'

class TradingBot {
  private client: Client
  private connected: boolean = false

  constructor(config: ClientConfig) {
    this.client = new Client(config)
  }

  async connect(): Promise<void> {
    if (this.connected) {
      console.log('Already connected')
      return
    }

    try {
      await this.client.connect()
      this.connected = true
      console.log('Connected to LX')
    } catch (error) {
      console.error('Connection failed:', error)
      throw error
    }
  }

  async disconnect(): Promise<void> {
    if (!this.connected) {
      return
    }

    this.client.disconnect()
    this.connected = false
    console.log('Disconnected from LX')
  }

  isConnected(): boolean {
    return this.connected
  }
}

Sub-Clients

The main client exposes specialized sub-clients for different operations:

MarketDataClient

import { Client } from '@luxfi/trading'

const client = new Client({
  rpcUrl: 'http://localhost:8080/rpc'
})

// Access market data sub-client
const marketData = client.marketData

// Get market statistics
const stats = await marketData.getMarketStats('BTC-USD')
console.log('24h Volume:', stats.volume24h)
console.log('24h High:', stats.high24h)
console.log('24h Low:', stats.low24h)

LiquidationMonitor

import { Client, LiquidationInfo } from '@luxfi/trading'

async function monitorLiquidations(): Promise<void> {
  const client = new Client({
    rpcUrl: 'http://localhost:8080/rpc',
    wsUrl: 'ws://localhost:8081'
  })

  await client.connect()

  // Access liquidation monitor sub-client
  const monitor = client.liquidationMonitor

  // Subscribe to liquidation events
  monitor.subscribeLiquidations((liquidation: LiquidationInfo) => {
    console.log('Liquidation event:', liquidation)
    console.log('  User:', liquidation.userId)
    console.log('  Symbol:', liquidation.symbol)
    console.log('  Size:', liquidation.size)
    console.log('  Price:', liquidation.liquidationPrice)
  })
}

Health Checks

Ping Test

import { Client } from '@luxfi/trading'

async function checkHealth(client: Client): Promise<boolean> {
  try {
    const response = await client.ping()
    return response === 'pong'
  } catch (error) {
    console.error('Health check failed:', error)
    return false
  }
}

Node Information

import { Client, NodeInfo } from '@luxfi/trading'

async function getNodeStatus(client: Client): Promise<NodeInfo> {
  const info = await client.getInfo()

  console.log('Node Version:', info.version)
  console.log('Network:', info.network)
  console.log('Order Count:', info.orderCount)
  console.log('Trade Count:', info.tradeCount)
  console.log('Timestamp:', new Date(info.timestamp))

  return info
}

Singleton Pattern

For applications that need a single shared client instance:

import { Client, ClientConfig } from '@luxfi/trading'

class DexClientSingleton {
  private static instance: Client | null = null
  private static config: ClientConfig = {
    rpcUrl: 'http://localhost:8080/rpc',
    wsUrl: 'ws://localhost:8081'
  }

  private constructor() {}

  static configure(config: ClientConfig): void {
    if (DexClientSingleton.instance) {
      throw new Error('Client already initialized. Call reset() first.')
    }
    DexClientSingleton.config = config
  }

  static getInstance(): Client {
    if (!DexClientSingleton.instance) {
      DexClientSingleton.instance = new Client(DexClientSingleton.config)
    }
    return DexClientSingleton.instance
  }

  static reset(): void {
    if (DexClientSingleton.instance) {
      DexClientSingleton.instance.disconnect()
      DexClientSingleton.instance = null
    }
  }
}

// Usage
DexClientSingleton.configure({
  rpcUrl: 'https://api.lux.network/rpc',
  wsUrl: 'wss://api.lux.network/ws'
})

const client = DexClientSingleton.getInstance()

React Integration

Context Provider

import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'
import { Client, ClientConfig } from '@luxfi/trading'

interface DexContextType {
  client: Client | null
  connected: boolean
  error: Error | null
}

const DexContext = createContext<DexContextType>({
  client: null,
  connected: false,
  error: null
})

interface DexProviderProps {
  config: ClientConfig
  children: ReactNode
}

export function DexProvider({ config, children }: DexProviderProps): JSX.Element {
  const [client, setClient] = useState<Client | null>(null)
  const [connected, setConnected] = useState(false)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    const dexClient = new Client(config)
    setClient(dexClient)

    dexClient.connect()
      .then(() => setConnected(true))
      .catch((err) => setError(err))

    return () => {
      dexClient.disconnect()
    }
  }, [config])

  return (
    <DexContext.Provider value={{ client, connected, error }}>
      {children}
    </DexContext.Provider>
  )
}

export function useDexClient(): DexContextType {
  const context = useContext(DexContext)
  if (!context) {
    throw new Error('useDexClient must be used within DexProvider')
  }
  return context
}

Using the Provider

import React from 'react'
import { DexProvider, useDexClient } from './DexProvider'

function TradingPanel(): JSX.Element {
  const { client, connected, error } = useDexClient()

  if (error) {
    return <div>Connection error: {error.message}</div>
  }

  if (!connected || !client) {
    return <div>Connecting...</div>
  }

  return (
    <div>
      <h1>Trading Panel</h1>
      {/* Trading UI components */}
    </div>
  )
}

function App(): JSX.Element {
  return (
    <DexProvider config={{
      rpcUrl: 'http://localhost:8080/rpc',
      wsUrl: 'ws://localhost:8081'
    }}>
      <TradingPanel />
    </DexProvider>
  )
}

Utility Methods

The client provides static utility methods:

import { Client } from '@luxfi/trading'

// Format price with decimals
const formattedPrice = Client.formatPrice(50123.456789, 2)
// Result: "50123.46"

// Format size with decimals
const formattedSize = Client.formatSize(1.23456789, 8)
// Result: "1.23456789"

// Calculate order total
const total = Client.calculateTotal(50000, 0.5)
// Result: 25000

Next Steps