Skip to main content
This overview maps the actual structure of the DLMM TypeScript SDK, showing how components connect and organize to deliver concentrated liquidity functionality.
Current Version: v1.3.2 | Main Class: LiquidityBookServices | Architecture: Single-class with method groups
DLMM TypeScript SDK component flow showing relationships between pools, positions, and swaps Component relationships and data flow - this shows how the TypeScript SDK components interact with each other

Version Compatibility & Requirements

  • Current Stable (v1.3.2+)
  • Legacy Support (v1.2.x)
  • Network Compatibility
Recommended for production
  • Node.js: 16.0+ (18.0+ recommended)
  • TypeScript: 4.5+ (5.0+ recommended)
  • Solana Web3.js: ^1.78.0
  • React: 17.0+ (18.0+ recommended)
Breaking Changes from v1.2.x:
  • getQuote() method signature updated
  • Position interface restructured
  • Error handling standardized across all methods

Actual SDK Architecture

DLMM TypeScript Architecture Overview

Core SDK Structure

import { LiquidityBookServices } from '@saros-finance/dlmm-sdk';

// Primary SDK class structure (actual implementation)
export class LiquidityBookServices extends LiquidityBookAbstract {
  // Core infrastructure
  connection: Connection;
  lbProgram: Program<Idl>;
  hooksProgram: Program<Idl>;
  
  // Primary method groups
  // 1. Trading & Quotes
  getQuote(params: GetTokenOutputParams): Promise<GetTokenOutputResponse>
  swap(params: SwapParams): Promise<Transaction>
  quote(amount: number, metadata: PoolMetadata, optional?: QuoteOptions): Promise<GetTokenOutputResponse>
  
  // 2. Pool Management  
  fetchPoolMetadata(pair: string): Promise<PoolMetadata>
  fetchPoolAddresses(): Promise<string[]>
  createPairWithConfig(params: CreatePairWithConfigParams): Promise<PairCreationResult>
  
  // 3. Position Management
  createPosition(params: CreatePositionParams): Promise<{position: string}>
  getUserPositions(params: UserPositionsParams): Promise<PositionInfo[]>
  addLiquidityIntoPosition(params: AddLiquidityIntoPositionParams): Promise<void>
  removeMultipleLiquidity(params: RemoveMultipleLiquidityParams): Promise<RemoveMultipleLiquidityResponse>
  
  // 4. Bin Array Operations
  getBinArray(params: GetBinArrayParams): Promise<PublicKey>
  getBinArrayInfo(params: GetBinsArrayInfoParams): Promise<{bins: any[], resultIndex: number}>
  getBinsReserveInformation(params: GetBinsReserveParams): Promise<GetBinsReserveResponse[]>
  
  // 5. Account Management
  getUserVaultInfo(params: GetUserVaultInfoParams): Promise<PublicKey>
  getPairVaultInfo(params: VaultInfoParams): Promise<PublicKey>
  
  // 6. Event System
  listenNewPoolAddress(callback: (address: string) => Promise<void>): void
  
  // 7. Utility Methods
  getDexName(): string
  getDexProgramId(): PublicKey
}

Method Organization by Functionality

GroupMethodsPurposeTypical Usage
TradinggetQuote, swap, quotePrice discovery and swapsDEX interfaces, trading bots
Pool DiscoveryfetchPoolMetadata, fetchPoolAddressesPool explorationPool explorers, analytics
Position ManagementcreatePosition, getUserPositions, addLiquidityIntoPosition, removeMultipleLiquidityLP operationsLiquidity management tools
Bin OperationsgetBinArray, getBinArrayInfo, getBinsReserveInformationLow-level pool dataAdvanced integrations
Account ManagementgetUserVaultInfo, getPairVaultInfoToken account handlingTransaction builders
EventslistenNewPoolAddressReal-time monitoringLive data feeds
UtilitiesgetDexName, getDexProgramIdSDK informationIntegration helpers

Trading Operations Architecture

Quote-to-Swap Workflow

class TradingWorkflow {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async executeOptimalSwap(
    pair: PublicKey,
    tokenBase: PublicKey,
    tokenQuote: PublicKey,
    amount: bigint,
    payer: PublicKey
  ): Promise<string> {
    
    const quote = await this.dlmm.getQuote({
      pair,
      tokenBase,
      tokenQuote,
      amount,
      swapForY: true,
      isExactInput: true,
      tokenBaseDecimal: 6,
      tokenQuoteDecimal: 9,
      slippage: 0.5
    });
    
    const swapTx = await this.dlmm.swap({
      tokenMintX: tokenBase,
      tokenMintY: tokenQuote,
      amount,
      otherAmountOffset: quote.otherAmountOffset,
      swapForY: true,
      isExactInput: true,
      pair,
      hook: await this.getHookAddress(),
      payer
    });
    
    return await sendAndConfirmTransaction(
      this.dlmm.connection,
      swapTx,
      [payerKeypair]
    );
  }
}

Quote Calculation Engine

// Internal quote calculation flow
class QuoteEngine {
  async calculatePreciseQuote(params: GetTokenOutputParams): Promise<QuoteBreakdown> {
    // Uses internal LBSwapService for bin-level calculations
    const swapService = LBSwapService.fromLbConfig(
      this.dlmm.lbProgram, 
      this.dlmm.connection
    );
    
    // Core calculation through bin arrays
    const result = await swapService.calculateInOutAmount(params);
    
    return {
      amountIn: result.amountIn,
      amountOut: result.amountOut,
      binsCrossed: this.calculateBinsCrossed(params),
      feeBreakdown: this.calculateFees(params),
      priceImpact: this.calculatePriceImpact(params, result)
    };
  }
}

Position Management Architecture

Position Lifecycle Flow

// Complete position lifecycle implementation
class PositionLifecycle {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async createAndManagePosition(
    wallet: PublicKey,
    pool: PublicKey,
    binRange: [number, number],
    amounts: [number, number]
  ): Promise<string> {
    
    // 1. Create position NFT and account
    const positionMint = Keypair.generate().publicKey;
    const tx = new Transaction();
    
    const result = await this.dlmm.createPosition({
      payer: wallet,
      relativeBinIdLeft: binRange[0],
      relativeBinIdRight: binRange[1],
      pair: pool,
      binArrayIndex: 0,
      positionMint,
      transaction: tx
    });
    
    // 2. Add liquidity with custom distribution
    await this.dlmm.addLiquidityIntoPosition({
      positionMint,
      payer: wallet,
      pair: pool,
      transaction: tx,
      liquidityDistribution: this.calculateDistribution(binRange),
      amountX: amounts[0],
      amountY: amounts[1],
      binArrayLower: await this.getBinArrayAddress(pool, binRange[0]),
      binArrayUpper: await this.getBinArrayAddress(pool, binRange[1])
    });
    
    return result.position;
  }
  
  // Monitor position performance
  async monitorPosition(positionId: string): Promise<PositionMetrics> {
    const reserves = await this.dlmm.getBinsReserveInformation({
      position: new PublicKey(positionId),
      pair: poolAddress,
      payer: wallet.publicKey
    });
    
    return this.calculateMetrics(reserves);
  }
}

Pool Discovery Architecture

Pool Metadata System

// Pool discovery and analysis system
class PoolDiscoveryEngine {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async discoverAllPools(): Promise<PoolAnalysis[]> {
    // Get all pool addresses
    const poolAddresses = await this.dlmm.fetchPoolAddresses();
    
    // Fetch metadata in batches for performance
    const batchSize = 10;
    const pools: PoolAnalysis[] = [];
    
    for (let i = 0; i < poolAddresses.length; i += batchSize) {
      const batch = poolAddresses.slice(i, i + batchSize);
      
      const metadataBatch = await Promise.all(
        batch.map(address => this.dlmm.fetchPoolMetadata(address))
      );
      
      pools.push(...metadataBatch.map(this.analyzePool));
    }
    
    return pools.sort((a, b) => b.score - a.score);
  }
  
  private analyzePool(metadata: PoolMetadata): PoolAnalysis {
    return {
      address: metadata.poolAddress,
      tvl: this.calculateTVL(metadata),
      tradingFee: metadata.tradeFee,
      tokens: [metadata.baseMint, metadata.quoteMint],
      score: this.calculatePoolScore(metadata),
      recommendation: this.generateRecommendation(metadata)
    };
  }
}

Connection and Network Architecture

Network Layer Structure

// Network abstraction layer
class NetworkLayer {
  private connections: Map<MODE, Connection>;
  
  constructor(config: ILiquidityBookConfig) {
    // Initialize connections for each network
    this.connections = new Map([
      [MODE.TESTNET, new Connection("https://api.testnet.solana.com")],
      [MODE.DEVNET, new Connection("https://api.devnet.solana.com")],
      [MODE.MAINNET, new Connection("https://api.mainnet-beta.solana.com")]
    ]);
  }
  
  getConnection(mode: MODE): Connection {
    return this.connections.get(mode)!;
  }
  
  async healthCheck(mode: MODE): Promise<NetworkHealth> {
    const connection = this.getConnection(mode);
    
    try {
      const slot = await connection.getSlot();
      const blockTime = await connection.getBlockTime(slot);
      
      return {
        mode,
        status: 'healthy',
        latency: Date.now() - (blockTime! * 1000),
        slot
      };
    } catch (error) {
      return {
        mode,
        status: 'unhealthy',
        error: error.message
      };
    }
  }
}

Data Flow Architecture

Request Processing Pipeline

Internal State Management

// SDK internal state and caching
class InternalStateManager {
  // Program interfaces
  public readonly lbProgram: Program<Idl>;
  public readonly hooksProgram: Program<Idl>;
  public readonly connection: Connection;
  
  // Caching layer
  private poolCache = new Map<string, PoolMetadata>();
  private binArrayCache = new Map<string, BinArray>();
  private positionCache = new Map<string, PositionInfo[]>();
  
  constructor(config: ILiquidityBookConfig) {
    this.connection = new Connection(
      config.options?.rpcUrl || CONFIG[config.mode].rpc,
      config.options?.commitmentOrConfig || "confirmed"
    );
    
    const provider = new AnchorProvider(this.connection, {} as Wallet);
    this.lbProgram = new Program(LiquidityBookIDL as Idl, provider);
    this.hooksProgram = new Program(MdmaIDL as Idl, provider);
  }
  
  // Efficient pool metadata caching
  async getCachedPoolMetadata(address: string): Promise<PoolMetadata> {
    if (!this.poolCache.has(address)) {
      const metadata = await this.fetchPoolMetadata(address);
      this.poolCache.set(address, metadata);
      
      // Auto-expire after 60 seconds
      setTimeout(() => this.poolCache.delete(address), 60000);
    }
    
    return this.poolCache.get(address)!;
  }
}

Error Handling Architecture

Actual Error Patterns

// Real error handling based on SDK source code
class DLMMErrorHandler {
  static handleStandardErrors(error: any): never {
    if (error.message?.includes('Pair not found')) {
      throw new PoolNotFoundError(error.message);
    }
    
    if (error.message?.includes('crosses too many bins')) {
      throw new InsufficientLiquidityError(
        'Swap size too large for available liquidity',
        { maxBins: 30 }
      );
    }
    
    if (error.message?.includes('Bin not found')) {
      throw new BinNotFoundError(error.message);
    }
    
    if (error.message?.includes('index mismatch')) {
      throw new BinArrayError('Bin array indices do not match expected sequence');
    }
    
    // Generic network/RPC errors
    if (error.code === -32601 || error.code === -32602) {
      throw new NetworkError('RPC method failed', { retryable: true });
    }
    
    throw new UnknownError(error.message);
  }
}

// Production error recovery
class ProductionErrorRecovery {
  async executeWithRetry<T>(
    operation: () => Promise<T>,
    maxRetries: number = 3
  ): Promise<T> {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        return await operation();
      } catch (error: any) {
        // Don't retry liquidity-related errors
        if (error.message?.includes('bins') || error.message?.includes('Bin')) {
          throw error;
        }
        
        // Don't retry on final attempt
        if (attempt === maxRetries) {
          throw error;
        }
        
        // Exponential backoff for network errors
        const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }
}

Real-World Integration Patterns

Production Trading Integration

// Production-ready trading implementation
class ProductionDLMMTrader {
  constructor(
    private dlmm: LiquidityBookServices,
    private wallet: AnchorWallet
  ) {}
  
  async executeProductionSwap(
    poolAddress: string,
    fromMint: string,
    toMint: string,
    amount: bigint,
    maxSlippage: number
  ): Promise<{ signature: string; actualAmountOut: bigint }> {
    
    // 1. Get pool metadata for token info
    const metadata = await this.dlmm.fetchPoolMetadata(poolAddress);
    
    // 2. Calculate quote using simplified interface
    const quote = await this.dlmm.quote(Number(amount), metadata, {
      isExactInput: true,
      swapForY: true,
      slippage: maxSlippage
    });
    
    // 3. Build and execute swap transaction
    const swapTx = await this.dlmm.swap({
      tokenMintX: new PublicKey(fromMint),
      tokenMintY: new PublicKey(toMint), 
      amount,
      otherAmountOffset: quote.otherAmountOffset,
      swapForY: true,
      isExactInput: true,
      pair: new PublicKey(poolAddress),
      hook: new PublicKey("11111111111111111111111111111111"), // Default hook
      payer: this.wallet.publicKey
    });
    
    // 4. Sign and send
    const signedTx = await this.wallet.signTransaction(swapTx);
    const signature = await this.dlmm.connection.sendRawTransaction(signedTx.serialize());
    
    return {
      signature,
      actualAmountOut: quote.amountOut
    };
  }
}

Pool Analytics Integration

// Pool analysis using actual SDK methods
class PoolAnalyzer {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async analyzeAllPools(): Promise<PoolRanking[]> {
    // Get all available pools
    const poolAddresses = await this.dlmm.fetchPoolAddresses();
    
    // Analyze each pool's metadata
    const analyses = await Promise.all(
      poolAddresses.map(async address => {
        const metadata = await this.dlmm.fetchPoolMetadata(address);
        return this.scorePool(metadata);
      })
    );
    
    return analyses
      .sort((a, b) => b.score - a.score)
      .slice(0, 20); // Top 20 pools
  }
  
  private scorePool(metadata: PoolMetadata): PoolRanking {
    const tvl = parseFloat(metadata.baseReserve) + parseFloat(metadata.quoteReserve);
    const feeScore = this.calculateFeeScore(metadata.tradeFee);
    const tokenScore = this.calculateTokenScore(metadata.baseMint, metadata.quoteMint);
    
    return {
      address: metadata.poolAddress,
      tvl,
      feeRate: metadata.tradeFee,
      score: (tvl * 0.4) + (feeScore * 0.3) + (tokenScore * 0.3),
      recommendation: this.generateRecommendation(tvl, metadata.tradeFee)
    };
  }
}

Position Management Architecture

Real Position Management Flow

// Actual position management using SDK
class RealPositionManager {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async createOptimalPosition(
    wallet: PublicKey,
    pool: PublicKey,
    strategy: 'conservative' | 'aggressive' | 'balanced'
  ): Promise<PositionCreationResult> {
    
    // 1. Determine optimal bin range based on strategy
    const binRange = this.calculateOptimalRange(strategy);
    
    // 2. Create position account
    const positionMint = Keypair.generate().publicKey;
    const tx = new Transaction();
    
    const positionResult = await this.dlmm.createPosition({
      payer: wallet,
      relativeBinIdLeft: binRange[0],
      relativeBinIdRight: binRange[1],
      pair: pool,
      binArrayIndex: 0,
      positionMint,
      transaction: tx
    });
    
    // 3. Add liquidity with optimized distribution
    const distribution = this.generateDistribution(strategy, binRange);
    
    await this.dlmm.addLiquidityIntoPosition({
      positionMint,
      payer: wallet,
      pair: pool,
      transaction: tx,
      liquidityDistribution: distribution,
      amountX: 1000000000, // 1000 tokens
      amountY: 10000000000, // 10000 tokens
      binArrayLower: await this.getBinArrayForBin(pool, binRange[0]),
      binArrayUpper: await this.getBinArrayForBin(pool, binRange[1])
    });
    
    return {
      positionId: positionResult.position,
      transaction: tx,
      expectedYield: this.calculateExpectedYield(strategy),
      riskLevel: this.calculateRiskLevel(strategy)
    };
  }
  
  // Portfolio management
  async managePositionPortfolio(wallet: PublicKey, pools: PublicKey[]): Promise<PortfolioSummary> {
    const allPositions: PositionInfo[] = [];
    
    // Get positions across all pools
    for (const pool of pools) {
      const positions = await this.dlmm.getUserPositions({
        payer: wallet,
        pair: pool
      });
      allPositions.push(...positions);
    }
    
    // Analyze portfolio performance
    const portfolioMetrics = await this.analyzePortfolio(allPositions);
    
    return {
      totalPositions: allPositions.length,
      totalValue: portfolioMetrics.totalValue,
      totalUnclaimedFees: portfolioMetrics.unclaimedFees,
      riskScore: portfolioMetrics.riskScore,
      recommendations: portfolioMetrics.recommendations
    };
  }
}

Low-Level Architecture Components

Bin Array Management System

// Low-level bin array operations
class BinArrayManager {
  constructor(private dlmm: LiquidityBookServices) {}
  
  async analyzeBinLiquidity(pool: PublicKey, centerBin: number): Promise<LiquidityDistribution> {
    // Get surrounding bin arrays
    const binArrayIndex = Math.floor(centerBin / BIN_ARRAY_SIZE);
    
    const { bins, resultIndex } = await this.dlmm.getBinArrayInfo({
      binArrayIndex,
      pair: pool,
      payer: this.getDefaultPayer()
    });
    
    return {
      centerBin,
      activeBins: bins.length,
      liquidityDistribution: this.analyzeBinDistribution(bins),
      utilizationRate: this.calculateUtilization(bins),
      efficiency: this.calculateEfficiency(bins, centerBin)
    };
  }
  
  // Advanced bin analysis
  async getOptimalBinRange(
    pool: PublicKey,
    strategy: LiquidityStrategy,
    targetAPY: number
  ): Promise<OptimalBinRange> {
    const metadata = await this.dlmm.fetchPoolMetadata(pool.toBase58());
    const currentBinId = await this.getCurrentActiveBin(pool);
    
    // Historical analysis to find optimal range
    return this.calculateHistoricalOptimalRange(
      metadata,
      currentBinId,
      strategy,
      targetAPY
    );
  }
}

Event System Architecture

Real-Time Pool Monitoring

// Real event system implementation
class PoolEventMonitor {
  private subscriptions = new Map<string, { callback: Function; active: boolean }>();
  
  constructor(private dlmm: LiquidityBookServices) {}
  
  // Monitor new pool creation
  monitorNewPools(callback: (poolAddress: string) => Promise<void>): void {
    this.dlmm.listenNewPoolAddress(async (address) => {
      try {
        await callback(address);
      } catch (error) {
        console.error(`Error processing new pool ${address}:`, error);
      }
    });
  }
  
  // Custom pool monitoring (using connection subscriptions)
  monitorPoolChanges(poolAddress: string, callback: (change: PoolChange) => void): string {
    const subscriptionId = this.dlmm.connection.onAccountChange(
      new PublicKey(poolAddress),
      (accountInfo) => {
        const change = this.parsePoolChange(accountInfo);
        callback(change);
      },
      'confirmed'
    );
    
    this.subscriptions.set(subscriptionId.toString(), {
      callback,
      active: true
    });
    
    return subscriptionId.toString();
  }
  
  unsubscribe(subscriptionId: string): void {
    const numericId = parseInt(subscriptionId);
    this.dlmm.connection.removeAccountChangeListener(numericId);
    this.subscriptions.delete(subscriptionId);
  }
}

Performance Optimization Architecture

Connection Pool Management

// Optimized connection management
class OptimizedConnectionManager {
  private connectionPool: Connection[];
  private requestQueue: RequestQueue;
  private rateLimiter: RateLimiter;
  
  constructor(config: ILiquidityBookConfig) {
    // Create connection pool for parallel requests
    this.connectionPool = Array.from({ length: 3 }, () => 
      new Connection(
        config.options?.rpcUrl || CONFIG[config.mode].rpc,
        config.options?.commitmentOrConfig || "confirmed"
      )
    );
    
    this.requestQueue = new RequestQueue({ maxConcurrent: 10 });
    this.rateLimiter = new RateLimiter({ requestsPerSecond: 50 });
  }
  
  async executeOptimizedRequest<T>(
    operation: (connection: Connection) => Promise<T>
  ): Promise<T> {
    await this.rateLimiter.acquire();
    
    const connection = this.getLeastBusyConnection();
    return this.requestQueue.add(() => operation(connection));
  }
  
  // Batch multiple pool metadata requests
  async batchPoolMetadata(addresses: string[]): Promise<PoolMetadata[]> {
    const batchSize = 5;
    const results: PoolMetadata[] = [];
    
    for (let i = 0; i < addresses.length; i += batchSize) {
      const batch = addresses.slice(i, i + batchSize);
      
      const batchResults = await Promise.all(
        batch.map(address => this.dlmm.fetchPoolMetadata(address))
      );
      
      results.push(...batchResults);
    }
    
    return results;
  }
}

Testing and Development Architecture

SDK Testing Strategy

// Real-world SDK testing patterns
class DLMMTestSuite {
  private testnet: LiquidityBookServices;
  private devnet: LiquidityBookServices;
  
  constructor() {
    this.testnet = new LiquidityBookServices({ mode: MODE.TESTNET });
    this.devnet = new LiquidityBookServices({ mode: MODE.DEVNET });
  }
  
  async testCoreQuotingEngine(): Promise<TestResult> {
    const testPools = await this.devnet.fetchPoolAddresses();
    const samplePool = testPools[0];
    
    // Test quote accuracy
    const metadata = await this.devnet.fetchPoolMetadata(samplePool);
    
    const quote = await this.devnet.quote(1000000, metadata, {
      isExactInput: true,
      swapForY: true,
      slippage: 0.5
    });
    
    return {
      test: 'quote-accuracy',
      passed: quote.amountOut > 0n,
      metrics: {
        quoteLatency: Date.now(),
        priceImpact: quote.priceImpact,
        amountOut: quote.amountOut.toString()
      }
    };
  }
  
  async testPositionManagement(): Promise<TestResult> {
    // Test position lifecycle on devnet
    const pools = await this.devnet.fetchPoolAddresses();
    const testPool = new PublicKey(pools[0]);
    const testWallet = Keypair.generate().publicKey;
    
    try {
      // Test position creation
      const positions = await this.devnet.getUserPositions({
        payer: testWallet,
        pair: testPool
      });
      
      return {
        test: 'position-management',
        passed: Array.isArray(positions),
        metrics: { positionCount: positions.length }
      };
    } catch (error) {
      return {
        test: 'position-management', 
        passed: false,
        error: error.message
      };
    }
  }
}

Integration Best Practices

React Application Architecture

// Real React integration pattern
function DLMMProvider({ children }: { children: React.ReactNode }) {
  const [dlmm, setDLMM] = useState<LiquidityBookServices | null>(null);
  const [isReady, setIsReady] = useState(false);
  
  useEffect(() => {
    const initializeDLMM = async () => {
      const instance = new LiquidityBookServices({
        mode: MODE.MAINNET,
        options: {
          rpcUrl: process.env.REACT_APP_RPC_URL!,
          commitmentOrConfig: "confirmed"
        }
      });
      
      setDLMM(instance);
      setIsReady(true);
    };
    
    initializeDLMM();
  }, []);
  
  return (
    <DLMMContext.Provider value={{ dlmm, isReady }}>
      {children}
    </DLMMContext.Provider>
  );
}

// Custom hooks for common operations
export function usePoolMetadata(poolAddress: string) {
  const { dlmm } = useContext(DLMMContext);
  const [metadata, setMetadata] = useState<PoolMetadata | null>(null);
  const [loading, setLoading] = useState(false);
  
  useEffect(() => {
    if (dlmm && poolAddress) {
      setLoading(true);
      dlmm.fetchPoolMetadata(poolAddress)
        .then(setMetadata)
        .finally(() => setLoading(false));
    }
  }, [dlmm, poolAddress]);
  
  return { metadata, loading };
}

SDK Initialization Patterns

Environment-Specific Initialization

// Different initialization patterns by environment
class DLMMInitializer {
  // Development setup
  static forDevelopment(): LiquidityBookServices {
    return new LiquidityBookServices({
      mode: MODE.DEVNET,
      options: {
        rpcUrl: "https://api.devnet.solana.com",
        commitmentOrConfig: "confirmed"
      }
    });
  }
  
  // Production setup with optimizations
  static forProduction(rpcUrl: string): LiquidityBookServices {
    return new LiquidityBookServices({
      mode: MODE.MAINNET,
      options: {
        rpcUrl,
        commitmentOrConfig: {
          commitment: "confirmed",
          disableRetryOnRateLimit: false,
          confirmTransactionInitialTimeout: 60000
        }
      }
    });
  }
  
  // Testing setup
  static forTesting(): LiquidityBookServices {
    return new LiquidityBookServices({
      mode: MODE.TESTNET,
      options: {
        rpcUrl: "https://api.testnet.solana.com",
        commitmentOrConfig: "processed" // Faster for tests
      }
    });
  }
}

Quick Reference Summary

Core Class Methods

LiquidityBookServices Methods:
├── Trading Operations
│   ├── getQuote(GetTokenOutputParams) → GetTokenOutputResponse
│   ├── swap(SwapParams) → Transaction
│   └── quote(amount, metadata, options) → GetTokenOutputResponse
├── Pool Discovery
│   ├── fetchPoolMetadata(string) → PoolMetadata
│   └── fetchPoolAddresses() → string[]
├── Position Management  
│   ├── createPosition(CreatePositionParams) → {position: string}
│   ├── getUserPositions(UserPositionsParams) → PositionInfo[]
│   ├── addLiquidityIntoPosition(AddLiquidityIntoPositionParams) → void
│   └── removeMultipleLiquidity(RemoveMultipleLiquidityParams) → RemoveMultipleLiquidityResponse
├── Bin Array Operations
│   ├── getBinArray(GetBinArrayParams) → PublicKey
│   ├── getBinArrayInfo(GetBinsArrayInfoParams) → {bins, resultIndex}
│   └── getBinsReserveInformation(GetBinsReserveParams) → GetBinsReserveResponse[]
├── Account Management
│   ├── getUserVaultInfo(GetUserVaultInfoParams) → PublicKey
│   └── getPairVaultInfo(VaultInfoParams) → PublicKey
├── Events & Monitoring
│   └── listenNewPoolAddress(callback) → void
└── Utilities
    ├── getDexName() → "Saros DLMM"
    └── getDexProgramId() → PublicKey

Common Integration Patterns

Use CasePrimary MethodsTypical Flow
Simple TradinggetQuoteswapQuote → Execute
Pool AnalysisfetchPoolAddressesfetchPoolMetadataDiscover → Analyze
LP ManagementcreatePositionaddLiquidityIntoPositiongetUserPositionsCreate → Fund → Monitor
Portfolio TrackinggetUserPositionsgetBinsReserveInformationQuery → Analyze
Pool CreationcreatePairWithConfigConfigure → Create

Performance Characteristics

Method Performance Profiles

MethodComplexityTypical LatencyRate LimitCaching Recommended
getQuoteO(log n) bins200-500msHighNo (real-time)
fetchPoolMetadataO(1)100-200msMediumYes (60s)
fetchPoolAddressesO(n) pools1-5sLowYes (5min)
getUserPositionsO(n) positions300-800msMediumYes (30s)
createPositionO(1) + TX cost500-1200msLowNo
swapO(log n) + TX cost400-1000msLowNo

Reference Documentation

Getting Started (Tutorials)

Solve Problems (How-To Guides)

Understanding Concepts (Explanation)

Understanding Concepts (Explanation)