Skip to Content
DevelopersSDK Reference

SDK Reference

orbit-dlmm is a TypeScript SDK for the Orbit Finance DLMM on Solana.

GitHub | npm

Install

npm install orbit-dlmm @coral-xyz/anchor @solana/web3.js

CipherDlmm Class

The main entry point. Create an instance for a pool, then call methods.

Connect to a pool

import { Connection, PublicKey } from "@solana/web3.js"; import { CipherDlmm } from "orbit-dlmm"; const connection = new Connection("https://api.mainnet-beta.solana.com"); const poolAddress = new PublicKey("EoLGqHKvtK9NcxjjnvSxTYYuFMYDeWTFFyKYj1DcJyPB"); const dlmm = await CipherDlmm.create(connection, poolAddress);

Read pool state

// Current price const { binId, price } = dlmm.getActiveBin(); // Bin liquidity data const bins = await dlmm.getBinArrays(-1100, -900); // User positions const positions = await dlmm.getPositionsByUser(walletPubkey); // All positions across all pools const all = await CipherDlmm.getAllPositionsByUser(connection, walletPubkey);

Add liquidity

Returns unsigned VersionedTransaction[] — may be multiple txs if more than 32 bins.

const txs = await dlmm.addLiquidityByStrategy({ user: walletPubkey, positionNonce: 0n, totalBaseAmount: 1_000_000_000n, // 1 CIPHER (9 decimals) totalQuoteAmount: 5_000_000n, // 5 USDC (6 decimals) strategy: "concentrated", // or "uniform", "skew_bid", etc. decay: 0.3, // controls concentration tightness minBinId: -1020, maxBinId: -960, }); // Sign and send each tx for (const tx of txs) { const signed = await wallet.signTransaction(tx); const sig = await connection.sendRawTransaction(signed.serialize()); }

Remove liquidity

// Withdraw everything from a position const tx = await dlmm.removeLiquidity({ user: walletPubkey, position: positionPubkey, }); // Withdraw 50% from specific bins const tx = await dlmm.removeLiquidity({ user: walletPubkey, position: positionPubkey, binIndices: [-1000, -999, -998], bpsPct: 5000, // 50% });

Swap

const tx = await dlmm.swap({ user: walletPubkey, amountIn: 1_000_000n, // 1 USDC minAmountOut: 200_000_000n, // min 0.2 CIPHER swapForBase: true, // true = buy base, false = sell base });

Claim rewards

// One-time init (required before first claim) const initTx = await dlmm.initHolderState(walletPubkey); // Claim USDC rewards const claimTx = await dlmm.claimHolderRewards(walletPubkey);

Position lifecycle

// Create a new position const initTx = await dlmm.initializePosition(walletPubkey, 0n); // Close an empty position (must withdraw all liquidity first) const closeTx = await dlmm.closePosition(walletPubkey, positionPubkey);

Low-Level Functions

Everything is also exported as standalone functions if you don’t want the class.

PDA Derivation

import { derivePoolPda, deriveBinArrayPda, derivePositionPda, derivePositionBinPda, deriveLiquidityLockPda, deriveHolderGlobalStatePda, deriveUserHolderStatePda, getBinArrayLowerIndex, canonicalBinIndexU64, } from "orbit-dlmm"; // Derive pool PDA from token pair + fee config const [poolPda] = derivePoolPda(baseMint, quoteMint, binStepBps, baseFeeBps); // Derive bin array for a specific bin const lower = getBinArrayLowerIndex(-993); // => -1024 const [binArrayPda] = deriveBinArrayPda(poolPda, lower);

Price Math

import { calculatePriceQ64_64, q64_64ToDecimal, binIdToPrice, priceToBinId, estimatePriceRange, } from "orbit-dlmm"; // Decimal to Q64.64 const q = calculatePriceQ64_64(0.004, 9, 6); // Q64.64 to decimal const price = q64_64ToDecimal(q, 9, 6); // Bin ID to price multiplier const mult = binIdToPrice(100, 125); // bin 100 at 125bps step // Price to nearest bin const bin = priceToBinId(1.5, 125);

Distribution

import { calculateDistributionWeights, allocateToBins, validateDistribution, } from "orbit-dlmm"; const weights = calculateDistributionWeights("concentrated", 20, 0.3); const allocs = allocateToBins(binIndices, weights, baseAtoms, quoteAtoms, activeBin); const result = validateDistribution(allocs, baseAtoms, quoteAtoms);

Account Fetching

import { fetchPool, fetchBinArraysForRange, fetchAllUserPositions } from "orbit-dlmm"; const pool = await fetchPool(connection, poolAddress); const bins = await fetchBinArraysForRange(connection, poolAddress, -1100, -900); const positions = await fetchAllUserPositions(connection, walletPubkey);

Transaction Building

import { buildTransaction } from "orbit-dlmm"; const { transaction } = await buildTransaction(connection, { payer: walletPubkey, instructions: [ix1, ix2], computeUnitPrice: 100_000, computeUnitLimit: 400_000, includeHeapFrame: true, // 256KB, required by the program });

Error Handling

import { parseProgramError, CipherDlmmError } from "orbit-dlmm"; try { await connection.sendRawTransaction(signed.serialize()); } catch (err) { const parsed = parseProgramError(6006); if (parsed) { console.log(parsed.errorName); // "SlippageExceeded" console.log(parsed.message); // "Swap did not meet minimum output" } }

Constants

import { DEFAULT_PROGRAM_ID, // Fn3fA3fjsmpULNL7E9U79jKTe1KHxPtQeWdURCbJXCnM BIN_ARRAY_SIZE, // 64 MAX_BINS_PER_TX, // 32 REQUIRED_HEAP_BYTES, // 262144 KNOWN_MINTS, // { CIPHER, USDC, SOL } VALID_BIN_STEPS, // [1, 2, 4, 5, 8, 10, ...] } from "orbit-dlmm";

Building something?

Every integration that drives swap volume through Orbit Finance pools generates fees for the ecosystem. $CIPHER stakers earn 75% of the ecosystem share, paid weekly in USDC.

If you’re building a bot, aggregator, or app that touches Solana swaps, integrating with our pools means your users contribute to (and benefit from) the fee flywheel.

Learn about $CIPHER staking | Talk to us on X

Last updated on