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
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
| Group | Methods | Purpose | Typical Usage |
|---|
| Trading | getQuote, swap, quote | Price discovery and swaps | DEX interfaces, trading bots |
| Pool Discovery | fetchPoolMetadata, fetchPoolAddresses | Pool exploration | Pool explorers, analytics |
| Position Management | createPosition, getUserPositions, addLiquidityIntoPosition, removeMultipleLiquidity | LP operations | Liquidity management tools |
| Bin Operations | getBinArray, getBinArrayInfo, getBinsReserveInformation | Low-level pool data | Advanced integrations |
| Account Management | getUserVaultInfo, getPairVaultInfo | Token account handling | Transaction builders |
| Events | listenNewPoolAddress | Real-time monitoring | Live data feeds |
| Utilities | getDexName, getDexProgramId | SDK information | Integration 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 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);
}
}
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 Case | Primary Methods | Typical Flow |
|---|
| Simple Trading | getQuote → swap | Quote → Execute |
| Pool Analysis | fetchPoolAddresses → fetchPoolMetadata | Discover → Analyze |
| LP Management | createPosition → addLiquidityIntoPosition → getUserPositions | Create → Fund → Monitor |
| Portfolio Tracking | getUserPositions → getBinsReserveInformation | Query → Analyze |
| Pool Creation | createPairWithConfig | Configure → Create |
| Method | Complexity | Typical Latency | Rate Limit | Caching Recommended |
|---|
getQuote | O(log n) bins | 200-500ms | High | No (real-time) |
fetchPoolMetadata | O(1) | 100-200ms | Medium | Yes (60s) |
fetchPoolAddresses | O(n) pools | 1-5s | Low | Yes (5min) |
getUserPositions | O(n) positions | 300-800ms | Medium | Yes (30s) |
createPosition | O(1) + TX cost | 500-1200ms | Low | No |
swap | O(log n) + TX cost | 400-1000ms | Low | No |
Navigation
Reference Documentation
Getting Started (Tutorials)
Solve Problems (How-To Guides)
Understanding Concepts (Explanation)
Understanding Concepts (Explanation)