SDK Reference
orbit-dlmm is a TypeScript SDK for the Orbit Finance DLMM on Solana.
Install
npm install orbit-dlmm @coral-xyz/anchor @solana/web3.jsCipherDlmm 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.
Last updated on