Meteora
  • Meteora: The most dynamic and sustainable liquidity layer on Solana
  • PRODUCT OVERVIEW
    • Meteora Liquidity Pools
      • DLMM Overview
        • What is DLMM?
        • DLMM Program
        • Dynamic Fees
        • Strategies & Use Cases
        • DLMM Farming Rewards
      • DLMM Launch Pool Overview
      • Dynamic AMM Overview
        • What is a Dynamic AMM Pool?
        • Dynamic AMM LP Fee and APY Calculation
        • Creating a Dynamic AMM Pool via the UI
        • Claiming Fees from Permanently Locked Liquidity
        • Dynamic AMM Stable Pools
        • Dynamic LST Pools
        • Additional yield from Dynamic Vaults
        • Dynamic AMM Farm Overview
      • DAMM v2 Overview
      • Memecoin Pool Overview
        • Memecoin Pool v2
          • What is Memecoin Pool v2?
        • Memecoin Pool v1
          • What is Memecoin Pool v1?
          • Permanently Locking Liquidity
      • Stake2Earn Pool Overview
        • What is a Stake2Earn Pool?
        • Stake2Earn for Launchpads
      • Multi-Token Stable Pool Overview
    • Alpha Vault Overview
    • Dynamic Vault Overview
      • What is a Dynamic Vault?
      • Dynamic Vault Program
      • Hermes - Meteora's Keeper
        • Algorithm to find optimal yield allocations
        • Rebalance crank
        • Operation fee calculation
      • Design Goals
      • Security
      • Dynamic Vaults Whitepaper
      • Dynamic Vaults Community Explainers
      • Affiliate Program for Dynamic Vault
        • Become an Affiliate Partner (Dynamic Vaults)
    • Dynamic Bonding Curve (DBC) Overview
      • What is the Dynamic Bonding Curve?
      • Customizable Pool Configuration
      • Bonding Curve Formula
      • DBC Migrator Keeper
    • Meteora’s Anti-Sniper Suite
  • INTEGRATION
    • DLMM Integration
      • DLMM SDK
        • DLMM TypeScript SDK
        • CPI Examples
      • DLMM API
      • Fetching information on locked liquidity in a DLMM
    • Dynamic AMM Pool Integration
      • Dynamic AMM SDK
        • Dynamic AMM TypeScript SDK
        • CPI Examples
      • Dynamic AMM API
        • Pool Info
        • Pool State
      • Setting Pool and Fee Config for Dynamic AMM Pools
      • Create Dynamic Pool with Timestamp/Slot Activation
      • Dynamic AMM - Farm Integration
    • DAMM v2 Integration
      • DAMM v2 SDK
        • DAMM v2 TypeScript SDK
        • DAMM v2 Rust SDK
      • Setting Pool and Fee Config for DAMM v2
      • Technical FAQ
    • Memecoin Pool Integration
      • Memecoin Pool v2 Integration
        • Setting Pool and Fee Config for Memecoin Pool v2
      • Memecoin Pool v1 Integration
        • TypeScript Code Examples
        • CPI Examples
        • Setting Pool and Fee Config for Memecoin Pool v1
        • Track permanently-locked liquidity in Memecoin Pool v1
        • Track Protocol Fee from swaps in Memecoin Pool v1
    • Stake2Earn Pool Integration
    • Dynamic Vault Integration
      • Using TypeScript-Client
      • Using Rust-Client
      • Using CPI
      • Vault API
        • Vault Info
        • Vault State
      • Vault Developer Resources
    • Alpha Vault Integration
      • Alpha Vault TypeScript SDK
      • Alpha Vault without Whitelist Setup
      • Alpha Vault with Whitelist Setup
    • Dynamic Bonding Curve (DBC) Integration
      • DBC SDK
        • DBC TypeScript SDK
        • DBC Rust SDK
      • DBC Fee Scheduler Formula
      • Program Repo
      • Technical FAQ
  • TOKEN LAUNCH POOLS
    • Steps to Create a Pool for a Token Launch
      • Create: DLMM Launch Pool
      • Create: Dynamic AMM Pool
      • Create: Memecoin Pool v1
      • Create: Stake2Earn Pool
      • Create: Pools with Alpha Vault
        • Create: DLMM Launch Pool with Alpha Vault
        • Create: Dynamic AMM Pool with Alpha Vault
        • Create: Memecoin Pool with Alpha Vault
        • Create: Stake2Earn Pool with Alpha Vault
    • Anti-Sniper Fee Suite for a Token Launch
  • Resources
    • Audits
    • Meteora Program IDs
    • Meteora APIs
    • Devnet Testing
    • Community Data Dashboards & Tools
    • Meteora Brand Assets
    • THE MASSIVE METEORA STIMULUS PACKAGE
      • Overview
      • 1. Dynamic Liquidity Market Maker (DLMM)
      • 2. Formation Of An LP Army DAO
      • 3. The 10% Stimulus Proposal
  • USER FAQ
    • Getting Started LPing
      • Supported Wallets
      • Prepare SOL
      • SOL required for Rent
      • What is Wrapped SOL?
      • What is an AMM?
      • What does it mean to provide liquidity?
      • How to swap to the tokens required for adding liquidity to a pool
      • How to quickly check if a token has any risks
      • Viewing your transaction history
      • My wallet has been compromised. What should I do?
    • Differences between DLMM and Dynamic Pools
    • DLMM FAQ
    • Dynamic AMM FAQ
      • How is the pool price of the token calculated in a Dynamic AMM?
      • What is a Meteora LP token?
      • How do I see fees earned on a Dynamic AMM Pool?
      • How to track your earnings for a Dynamic Pool?
      • What is Virtual Price in a Dynamic Pool?
      • How do LP tokens, fees, and virtual price work for Dynamic Pools?
      • Why must I add liquidity in non-stable Dynamic Pools using a 50:50 value ratio?
      • What is AMP in a Dynamic Pool with stable coins?
      • Why is the USDT-USDC pool not 1:1 in ratio of assets?
      • Can I create an LST, FX, or Multi-token pool using the Dynamic Pool creation tool?
    • Alpha Vault FAQ
    • Why is the token sometimes not picked up and tradable on Jupiter?
    • How do I create a new farm?
    • Video Tutorials to Get Started
      • LP Army Boot Camp
      • DLMM Strategy Sessions / Jam Sessions
  • Security and Risks
    • Risk of Impermanent Loss (IL)
    • Risk of depositing into an imbalanced pool / pool with price out of sync
    • Smart contract risk
    • Risk of a stablecoin depeg
    • Operational risk for dynamic vaults and pools
    • Lending risk for dynamic vaults and pools
  • legal
    • Terms of Service
    • Stake2Earn Terms of Service
Powered by GitBook
On this page
  • List of sections
  • Getting started
  • 1. Install dependencies and initialize DLMM instance
  • 1.1 Install dependencies
  • 1.2 Initialize DLMM instance
  • 2. Code examples to interact with the DLMM
  • Get Active Bin
  • Creating a New Liquidity Position
  • Get list of positions
  • Add liquidity to an existing position
  • Remove Liquidity
  • Claim Fee
  • Close Position
  • Swap
  • Static functions
  • DLMM instance functions
  1. INTEGRATION
  2. DLMM Integration
  3. DLMM SDK

DLMM TypeScript SDK

This Typescript SDK is meant to help developers easily integrate Meteora's DLMM pools into their protocols. This SDK uses the latest AddLiquidityByStrategy endpoint (instead of AddLiquidityByWeight).

PreviousDLMM SDKNextCPI Examples

Last updated 1 month ago

List of sections

Getting started

  • NPM:

  • SDK on github:

  • Program ID: LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo

  • Devnet:

1. Install dependencies and initialize DLMM instance

1.1 Install dependencies

You will need to first install these SDK dependencies in order for it to function properly

npm i @meteora-ag/dlmm @coral-xyz/anchor @solana/web3.js

1.2 Initialize DLMM instance

import DLMM from '@meteora-ag/dlmm'

const USDC_USDT_POOL = new PublicKey('ARwi1S4DaiTG5DX7S4M4ZsrXqpMD1MrTmbu9ue2tpmEq') // You can get your desired pool address from the API https://dlmm-api.meteora.ag/pair/all
const dlmmPool = await DLMM.create(connection, USDC_USDT_POOL);

// If you need to create multiple, can consider using `createMultiple`
const dlmmPool = await DLMM.createMultiple(connection, [USDC_USDT_POOL, ...]);

2. Code examples to interact with the DLMM

Get Active Bin

const activeBin = await dlmmPool.getActiveBin();
const activeBinPriceLamport = activeBin.price;
const activeBinPricePerToken = dlmmPool.fromPricePerLamport(
  Number(activeBin.price)
);

Creating a New Liquidity Position

When creating a new liquidity position, there are a few different liquidity position scenarios to consider.

  • You can create a Balance Position, Imbalance Position, or One-Sided Position

  • For StrategyType: you can select StrategyType.Spot, StrategyType.BidAsk, or StrategyType.Curve

A) Create Balance Position

To create a new liquidity position with a Balance Position. This functions like enabling "Auto-Fill" on the user interface, which automatically calculates the required amount of Token Y to match the equivalent value of Token X when creating a position.

const TOTAL_RANGE_INTERVAL = 10; // 10 bins on each side of the active bin
  const minBinId = activeBin.binId - TOTAL_RANGE_INTERVAL;
  const maxBinId = activeBin.binId + TOTAL_RANGE_INTERVAL;

  const totalXAmount = new BN(100 * 10 ** baseMint.decimals);
  const totalYAmount = autoFillYByStrategy(
    activeBin.binId,
    dlmmPool.lbPair.binStep,
    totalXAmount,
    activeBin.xAmount,
    activeBin.yAmount,
    minBinId,
    maxBinId,
    StrategyType.Spot // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
  );
  const newBalancePosition = new Keypair();

  // Create Position
  const createPositionTx =
    await dlmmPool.initializePositionAndAddLiquidityByStrategy({
      positionPubKey: newBalancePosition.publicKey,
      user: user.publicKey,
      totalXAmount,
      totalYAmount,
      strategy: {
        maxBinId,
        minBinId,
        strategyType: StrategyType.Spot, // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
      },
    });

try {
  const createBalancePositionTxHash = await sendAndConfirmTransaction(
    connection,
    createPositionTx,
    [user, newBalancePosition]
  );
} catch (error) {}

B) Create Imbalance Position

To create a new liquidity position with an Imbalance Position. This is similar to disabling "Auto-Fill" on the user interface, which allows users to manually specify the amount to be added for token X and token Y without maintaining an equal value balance between both assets.

const TOTAL_RANGE_INTERVAL = 10; // 10 bins on each side of the active bin
  const minBinId = activeBin.binId - TOTAL_RANGE_INTERVAL;
  const maxBinId = activeBin.binId + TOTAL_RANGE_INTERVAL;

  const totalXAmount = new BN(100 * 10 ** baseMint.decimals);
  const totalYAmount = new BN(0.5 * 10 ** 9); // SOL
  const newImbalancePosition = new Keypair();

  // Create Position
  const createPositionTx =
    await dlmmPool.initializePositionAndAddLiquidityByStrategy({
      positionPubKey: newImbalancePosition.publicKey,
      user: user.publicKey,
      totalXAmount,
      totalYAmount,
      strategy: {
        maxBinId,
        minBinId,
        strategyType: StrategyType.Spot, // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
      },
    });

    try {
  const createBalancePositionTxHash = await sendAndConfirmTransaction(
    connection,
    createPositionTx,
    [user, newImbalancePosition]
  );
} catch (error) {}

C) Create One-Sided Position

To create a new one-sided/single-sided liquidity position with only one token added; typically used to DCA (dollar cost average) into or out of a position.

const TOTAL_RANGE_INTERVAL = 10; // 10 bins on each side of the active bin
  const minBinId = activeBin.binId;
  const maxBinId = activeBin.binId + TOTAL_RANGE_INTERVAL * 2;

  const totalXAmount = new BN(100 * 10 ** baseMint.decimals);
  const totalYAmount = new BN(0);
  const newOneSidePosition = new Keypair();

  // Create Position
  const createPositionTx =
    await dlmmPool.initializePositionAndAddLiquidityByStrategy({
      positionPubKey: newOneSidePosition.publicKey,
      user: user.publicKey,
      totalXAmount,
      totalYAmount,
      strategy: {
        maxBinId,
        minBinId,
        strategyType: StrategyType.Spot, // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
      },
    });

  try {
    const createOneSidePositionTxHash = await sendAndConfirmTransaction(
      connection,
      createPositionTx,
      [user, newOneSidePosition]
    );
  } catch (error) {}

Get list of positions

To get the list of liquidity positions for a specified pair and pool

const { userPositions } = await dlmmPool.getPositionsByUserAndLbPair(
  user.publicKey
);
const binData = userPositions[0].positionData.positionBinData;

Add liquidity to an existing position

To add liquidity to an existing liquidity position

const TOTAL_RANGE_INTERVAL = 10; // 10 bins on each side of the active bin
  const minBinId = activeBin.binId - TOTAL_RANGE_INTERVAL;
  const maxBinId = activeBin.binId + TOTAL_RANGE_INTERVAL;

  const totalXAmount = new BN(100 * 10 ** baseMint.decimals);
  const totalYAmount = autoFillYByStrategy(
    activeBin.binId,
    dlmmPool.lbPair.binStep,
    totalXAmount,
    activeBin.xAmount,
    activeBin.yAmount,
    minBinId,
    maxBinId,
    StrategyType.Spot, // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
  );

  // Add Liquidity to existing position
  const addLiquidityTx = await dlmmPool.addLiquidityByStrategy({
    positionPubKey: newBalancePosition.publicKey,
    user: user.publicKey,
    totalXAmount,
    totalYAmount,
    strategy: {
      maxBinId,
      minBinId,
      strategyType: StrategyType.Spot, // can be StrategyType.Spot, StrategyType.BidAsk, StrategyType.Curve
    },
  });

try {
  const addLiquidityTxHash = await sendAndConfirmTransaction(
    connection,
    addLiquidityTx,
    [user]
  );
} catch (error) {}

Remove Liquidity

To remove liquidity from an existing liquidity position

const userPosition = userPositions.find(({ publicKey }) =>
  publicKey.equals(newBalancePosition.publicKey)
);
// Remove Liquidity
const binIdsToRemove = userPosition.positionData.positionBinData.map(
  (bin) => bin.binId
);
const removeLiquidityTx = await dlmmPool.removeLiquidity({
  position: userPosition.publicKey,
  user: user.publicKey,
  fromBinId: binIdsToRemove[0],
  toBinId: binIdsToRemove[binIdsToRemove.length - 1],
  liquiditiesBpsToRemove: new Array(binIdsToRemove.length).fill(
    new BN(100 * 100)
  ), // 100% (range from 0 to 100)
  shouldClaimAndClose: true, // should claim swap fee and close position together
});

try {
  for (let tx of Array.isArray(removeLiquidityTx)
    ? removeLiquidityTx
    : [removeLiquidityTx]) {
    const removeBalanceLiquidityTxHash = await sendAndConfirmTransaction(
      connection,
      tx,
      [user],
      { skipPreflight: false, preflightCommitment: "singleGossip" }
    );
  }
} catch (error) {}

Claim Fee

To claim all swap fees earned in your liquidity position so far

async function claimFee(dlmmPool: DLMM) {
  const claimFeeTxs = await dlmmPool.claimAllSwapFee({
    owner: user.publicKey,
    positions: userPositions,
  });

  try {
    for (const claimFeeTx of claimFeeTxs) {
      const claimFeeTxHash = await sendAndConfirmTransaction(
        connection,
        claimFeeTx,
        [user]
      );
    }
  } catch (error) {}
}

Close Position

To close an existing liquidity position

const closePositionTx = await dlmmPool.closePosition({
  owner: user.publicKey,
  position: newBalancePosition.publicKey,
});

try {
    const closePositionTxHash = await sendAndConfirmTransaction(
      connection,
      closePositionTx,
      [user],
      { skipPreflight: false, preflightCommitment: "singleGossip" }
    );
} catch (error) {}

Swap

To swap tokens within the specified liquidity pool

const swapAmount = new BN(0.1 * 10 ** 9);
  // Swap quote
  const swapYtoX = true;
  const binArrays = await dlmmPool.getBinArrayForSwap(swapYtoX);

  const swapQuote = await dlmmPool.swapQuote(swapAmount, swapYtoX, new BN(1), binArrays);

// Swap
const swapTx = await dlmmPool.swap({
    inToken: dlmmPool.tokenX.publicKey,
    binArraysPubkey: swapQuote.binArraysPubkey,
    inAmount: swapAmount,
    lbPair: dlmmPool.pubkey,
    user: user.publicKey,
    minOutAmount: swapQuote.minOutAmount,
    outToken: dlmmPool.tokenY.publicKey,
  });

try {
  const swapTxHash = await sendAndConfirmTransaction(connection, swapTx, [
    user,
  ]);
} catch (error) {}

Static functions

Function
Description
Return

create

Given the DLMM address, create an instance to access the state and functions

Promise<DLMM>

createMultiple

Given a list of DLMM addresses, create instances to access the state and functions

Promise<Array<DLMM>>

getAllPresetParameters

Get all the preset params (use to create DLMM pool)

Promise<PresetParams>

createPermissionLbPair

Create DLMM Pool

Promise<Transcation>

getClaimableLMReward

Get Claimable LM reward for a position

Promise<LMRewards>

getClaimableSwapFee

Get Claimable Swap Fee for a position

Promise<SwapFee>

getAllLbPairPositionsByUser

Get user's all positions for all DLMM pools

Promise<Map<string, PositionInfo>>

DLMM instance functions

Function
Description
Return

refetchStates

Update onchain state of DLMM instance. It's recommend to call this before interact with the program (Deposit/ Withdraw/ Swap)

Promise<void>

getBinArrays

Retrieves List of Bin Arrays

Promise<BinArrayAccount[]>

getBinArrayForSwap

Retrieves List of Bin Arrays for swap purpose

Promise<BinArrayAccount[]>

getFeeInfo

Retrieves LbPair's fee info including base fee, protocol fee & max fee

FeeInfo

getDynamicFee

Retrieves LbPair's dynamic fee

Decimal

getBinsAroundActiveBin

retrieves a specified number of bins to the left and right of the active bin and returns them along with the active bin ID.

Promise<{ activeBin: number; bins: BinLiquidity[] }>

getBinsBetweenMinAndMaxPrice

Retrieves a list of bins within a specified price

Promise<{ activeBin: number; bins: BinLiquidity[] }>

getBinsBetweenLowerAndUpperBound

retrieves a list of bins between a lower and upper bin ID and returns the active bin ID and the list of bins.

Promise<{ activeBin: number; bins: BinLiquidity[] }>

toPricePerLamport

Converts a real price of bin to lamport price

string

fromPricePerLamport

converts a price per lamport value to a real price of bin

string

getActiveBin

Retrieves the active bin ID and its corresponding price

Promise<{ binId: number; price: string }>

getPriceOfBinByBinId

Get the price of a bin based on its bin ID

string

getBinIdFromPrice

get bin ID based on a given price and a boolean flag indicating whether to round down or up.

number

getPositionsByUserAndLbPair

Retrieves positions by user and LB pair, including active bin and user positions.

Promise<{ activeBin: { binId: any; price: string; }; userPositions: Array<Position>;}>

initializePositionAndAddLiquidityByStrategy

Initializes a position and adds liquidity

Promise<Transaction|Transaction[]>

addLiquidityByStrategy

Add liquidity to existing position

Promise<Transaction|Transaction[]>

removeLiquidity

function is used to remove liquidity from a position, with the option to claim rewards and close the position.

Promise<Transaction|Transaction[]>

closePosition

Closes a position

Promise<Transaction|Transaction[]>

swapQuote

Quote for a swap

SwapQuote

swap

Swap token within the LbPair

Promise<Transaction>

claimLMReward

Claim rewards for a specific position owned by a specific owner

Promise<Transaction>

claimAllLMRewards

Claim all liquidity mining rewards for a given owner and their positions.

Promise<Transaction[]>

claimSwapFee

Claim swap fees for a specific position owned by a specific owner

Promise<Transaction>

claimAllSwapFee

Claim swap fees for multiple positions owned by a specific owner

Promise<Transaction>

claimAllRewards

Claim swap fees and LM rewards for multiple positions owned by a specific owner

Promise<Transaction[]>

syncWithMarketPrice

Sync the pool current active bin to match nearest market price bin

Promise<Transaction>

getPairPubkeyIfExists

Get existing pool address given parameter, if not return null

Promise<PublicKey | null>

getMaxPriceInBinArrays

Get max price of the last bin that has liquidity given bin arrays

Promise<string | null>

Below are the code examples of how you can change parameters for key DLMM actions and to interact with the lb_pair / or pool. To view other SDK files on github, .

To get the where the current pool price resides

click here
Getting the active bin
Creating a new liquidity position
Creating a Balance Position
Creating an Imbalance Position
Creating a One-Sided Position
Getting the list of positions
Adding liquidity to an existing position
Removing liquidity from an existing position
Claiming swap fees
Closing your liquidity position
Swapping tokens within a specified pool
active bin
Getting started
Install dependencies and initialize DLMM instance
Code examples to interact with the DLMM
Static functions
DLMM instance functions
https://www.npmjs.com/package/@meteora-ag/dlmm
https://github.com/MeteoraAg/dlmm-sdk
https://devnet.meteora.ag/
LogoGitHub - MeteoraAg/dlmm-sdk: An SDK for building applications on top of Dynamic CLMMGitHub