# Add liquidity

## Oveview

This walkthrough demonstrates how to inject liquidity into a Saros DLMM liquidity pool through your frontend integration. The two primary flows are:

* **Opening a new position** when none exists
* **Augmenting an existing position**

Key steps in both flows:

1. Compute token amounts to deposit
2. Invoke the relevant on‑chain instruction

## Creating a New Position

To create a new liquidity position, you'll need to:

1. Determine the bin range for the position by specifying relative bin IDs from the active bin:
   * `relative_bin_id_left`: The leftmost bin ID relative to the active bin
   * `relative_bin_id_right`: The rightmost bin ID relative to the active bin
2. Call the `create_position` instruction with these parameters
3. After creating the position, you can add liquidity using the `increase_position` instruction

### Example Implementation

```
import { createMint } from "@solana/spl-token";
import { PublicKey, SystemProgram } from "@solana/web3.js";
import { BN } from "@project-serum/anchor";
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";

// Create a new position
const relativeBinIdLeft = -5;  // 5 bins to the left of active bin
const relativeBinIdRight = 5;  // 5 bins to the right of active bin

// Create position mint first
const positionMint = await createMint(
  connection,
  wallet.payer,
  wallet.publicKey,
  null,
  0,
  undefined,
  undefined,
  TOKEN_2022_PROGRAM_ID
);

// Derive PDAs
const [positionPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("position"), positionMint.toBuffer()],
  program.programId
);

const [positionTokenAccount] = PublicKey.findProgramAddressSync(
  [
    wallet.publicKey.toBuffer(),
    TOKEN_2022_PROGRAM_ID.toBuffer(),
    positionMint.toBuffer(),
  ],
  ASSOCIATED_TOKEN_PROGRAM_ID
);

await program.methods
  .createPosition(new BN(relativeBinIdLeft), new BN(relativeBinIdRight))
  .accounts({
    pair: pairPda,
    position: positionPda,
    positionMint: positionMint,
    positionTokenAccount: positionTokenAccount,
    user: wallet.publicKey,
    systemProgram: SystemProgram.programId,
    tokenProgram: TOKEN_2022_PROGRAM_ID,
    associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
  })
  .signers([positionMint])
  .rpc();

// Add liquidity to the position
const amountX = new BN(1000000); // Amount of token X
const amountY = new BN(1000000); // Amount of token Y

// Define liquidity distribution across bins
const liquidityDistribution = [
  { relativeBinId: -5, distributionX: 1000, distributionY: 0 },
  { relativeBinId: -4, distributionX: 2000, distributionY: 0 },
  { relativeBinId: -3, distributionX: 3000, distributionY: 0 },
  { relativeBinId: -2, distributionX: 2000, distributionY: 0 },
  { relativeBinId: -1, distributionX: 1000, distributionY: 0 },
  { relativeBinId: 0, distributionX: 500, distributionY: 500 },
  { relativeBinId: 1, distributionX: 0, distributionY: 1000 },
  { relativeBinId: 2, distributionX: 0, distributionY: 2000 },
  { relativeBinId: 3, distributionX: 0, distributionY: 3000 },
  { relativeBinId: 4, distributionX: 0, distributionY: 2000 },
  { relativeBinId: 5, distributionX: 0, distributionY: 1000 },
];

// Derive bin array PDAs
const [binArrayLowerPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("bin_array"), pairPda.toBuffer(), Buffer.from([0])],
  program.programId
);

const [binArrayUpperPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("bin_array"), pairPda.toBuffer(), Buffer.from([1])],
  program.programId
);

await program.methods
  .increasePosition(amountX, amountY, liquidityDistribution)
  .accounts({
    pair: pairPda,
    position: positionPda,
    binArrayLower: binArrayLowerPda,
    binArrayUpper: binArrayUpperPda,
    tokenMintX: tokenMintX,
    tokenMintY: tokenMintY,
    tokenVaultX: tokenVaultXPda,
    tokenVaultY: tokenVaultYPda,
    userVaultX: userVaultXPda,
    userVaultY: userVaultYPda,
    positionTokenAccount: positionTokenAccount,
    tokenProgramX: TOKEN_2022_PROGRAM_ID,
    tokenProgramY: TOKEN_2022_PROGRAM_ID,
    positionTokenProgram: TOKEN_2022_PROGRAM_ID,
    systemProgram: SystemProgram.programId,
    memoProgram: MEMO_PROGRAM_ID,
  })
  .remainingAccounts([
    { pubkey: pairPda, isWritable: false, isSigner: false },
    { pubkey: binArrayLowerPda, isWritable: false, isSigner: false },
    { pubkey: binArrayUpperPda, isWritable: false, isSigner: false },
  ])
  .rpc();
​
```

### Increasing an Existing Position

To add more liquidity to an existing position:

1. Calculate the amounts of tokens X and Y to add
2. Define the liquidity distribution across bins
3. Call the `increase_position` instruction with:
   * `amountX`: Amount of token X to add
   * `amountY`: Amount of token Y to add
   * `liquidityDistribution`: Array of `BinLiquidityDistribution` objects specifying how to distribute liquidity across bins

### Liquidity Distribution Format

The `liquidityDistribution` parameter is an array of objects with the following structure:

```
interface BinLiquidityDistribution {
  relativeBinId: number;    // Relative bin ID from active bin
  distributionX: number;    // Distribution of token X (0-10000)
  distributionY: number;    // Distribution of token Y (0-10000)
}
```

Notes:

* The distribution values are in basis points (0-10000)
* For bins with negative relative IDs, only token X can be distributed
* For bins with positive relative IDs, only token Y can be distributed
* The active bin (relativeBinId = 0) can receive both tokens
* The sum of distributions should equal 10000 (100%)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.saros.xyz/saros-dlmm/technical-guides/add-liquidity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
