> ## Documentation Index
> Fetch the complete documentation index at: https://docs.exponent.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Exponent CLMM Instructions

> Provide liquidity and trade on the Exponent CLMM through policy-gated vault execution

The CLMM instructions module enables vault managers and allocators to provide concentrated liquidity, trade PT and YT, and claim farm emissions on the [Exponent CLMM](/developer-clmm/overview). All interactions are executed as Squads sync transactions validated against onchain policies.

## Transaction Structure

Every CLMM interaction goes through `createVaultSyncTransaction`, which returns three parts:

```typescript theme={null}
const { preInstructions, instruction, postInstructions, signers } =
  await createVaultSyncTransaction({
    instructions,   // Array of VaultInstruction descriptors
    owner,          // Vault PDA (the Squads smart account)
    connection,
    policyPda,      // Policy authorizing this execution
    vaultPda,       // Squads vault PDA
    signer,         // The allocator or manager wallet
    vaultAddress,   // ExponentStrategyVault PDA (auto-resolves hook accounts)
  });

// Send all three parts in order
const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet, ...signers]);
```

| Part               | What it contains                                                       | Why it's separate                                 |
| ------------------ | ---------------------------------------------------------------------- | ------------------------------------------------- |
| `preInstructions`  | Any permissionless setup instructions                                  | Must be top-level instructions                    |
| `instruction`      | Squads sync transaction wrapping all vault-signed instructions         | Executes with the vault's smart account as signer |
| `postInstructions` | Any post-operation instructions                                        | Must be top-level instructions                    |
| `signers`          | Additional signers (e.g., LP position keypair from `depositLiquidity`) | Must be included when signing the transaction     |

***

## Deposit Liquidity

`clmmAction.depositLiquidity` creates a new LP position on the CLMM with a specified tick range. The LP position keypair is generated internally and returned in `result.signers`.

```typescript theme={null}
import {
  clmmAction,
  createVaultSyncTransaction,
} from "@exponent-labs/exponent-sdk";

const { preInstructions, instruction, postInstructions, signers } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.depositLiquidity({
        market: new PublicKey("..."),      // CLMM MarketThree address
        ptInIntent: 1_000_000_000n,       // Maximum PT to deposit
        syInIntent: 1_000_000_000n,       // Maximum SY to deposit
        lowerTickKey: 500,                // Lower tick boundary (APY value)
        upperTickKey: 1500,               // Upper tick boundary (APY value)
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet, ...signers]);

// signers[0] is the generated LP position keypair — save its public key
const lpPositionAddress = signers[0].publicKey;
```

### Parameters

| Parameter      | Type        | Description                          |
| -------------- | ----------- | ------------------------------------ |
| `market`       | `PublicKey` | The CLMM MarketThree account address |
| `ptInIntent`   | `bigint`    | Maximum amount of PT to deposit      |
| `syInIntent`   | `bigint`    | Maximum amount of SY to deposit      |
| `lowerTickKey` | `number`    | Lower tick boundary (APY value)      |
| `upperTickKey` | `number`    | Upper tick boundary (APY value)      |

<Note>
  The LP position keypair is generated internally by the SDK. After calling `createVaultSyncTransaction`, the keypair is available in `result.signers[0]`. Save the public key to reference this position in future operations (add liquidity, withdraw, claim emissions).
</Note>

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Add Liquidity

`clmmAction.addLiquidity` adds more liquidity to an existing LP position.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.addLiquidity({
        market: new PublicKey("..."),
        lpPosition: new PublicKey("..."),   // Existing LP position address
        ptInIntent: 500_000_000n,
        syInIntent: 500_000_000n,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter    | Type        | Description                                |
| ------------ | ----------- | ------------------------------------------ |
| `market`     | `PublicKey` | The CLMM MarketThree account address       |
| `lpPosition` | `PublicKey` | The existing LpPosition account public key |
| `ptInIntent` | `bigint`    | Maximum amount of PT to add                |
| `syInIntent` | `bigint`    | Maximum amount of SY to add                |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Withdraw Liquidity

`clmmAction.withdrawLiquidity` removes liquidity from an LP position, receiving PT and SY back.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.withdrawLiquidity({
        market: new PublicKey("..."),
        lpPosition: new PublicKey("..."),
        lpIn: 1_000_000_000n,              // Amount of LP units to remove
        minPtOut: 900_000_000n,            // Minimum PT to receive
        minSyOut: 900_000_000n,            // Minimum SY to receive
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter    | Type        | Description                                 |
| ------------ | ----------- | ------------------------------------------- |
| `market`     | `PublicKey` | The CLMM MarketThree account address        |
| `lpPosition` | `PublicKey` | The LpPosition account to withdraw from     |
| `lpIn`       | `bigint`    | Amount of liquidity (LP units) to remove    |
| `minPtOut`   | `bigint`    | Minimum PT to receive — slippage protection |
| `minSyOut`   | `bigint`    | Minimum SY to receive — slippage protection |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Buy PT

`clmmAction.buyPt` buys PT with SY on the CLMM.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.buyPt({
        market: new PublicKey("..."),
        amountSy: 1_000_000_000n,           // Amount of SY to spend
        outConstraint: 900_000_000n,        // Minimum PT to receive
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter           | Type        | Description                                        |
| ------------------- | ----------- | -------------------------------------------------- |
| `market`            | `PublicKey` | The CLMM MarketThree account address               |
| `amountSy`          | `bigint`    | Amount of SY to spend                              |
| `outConstraint`     | `bigint`    | Minimum PT to receive — slippage protection        |
| `lnImpliedApyLimit` | `number`    | Optional. Price limit expressed as ln(implied APY) |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Sell PT

`clmmAction.sellPt` sells PT for SY on the CLMM.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.sellPt({
        market: new PublicKey("..."),
        amountPt: 1_000_000_000n,           // Amount of PT to sell
        outConstraint: 900_000_000n,        // Minimum SY to receive
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter           | Type        | Description                                        |
| ------------------- | ----------- | -------------------------------------------------- |
| `market`            | `PublicKey` | The CLMM MarketThree account address               |
| `amountPt`          | `bigint`    | Amount of PT to sell                               |
| `outConstraint`     | `bigint`    | Minimum SY to receive — slippage protection        |
| `lnImpliedApyLimit` | `number`    | Optional. Price limit expressed as ln(implied APY) |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Buy YT

`clmmAction.buyYt` buys YT with SY on the CLMM.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.buyYt({
        market: new PublicKey("..."),
        ytOut: 1_000_000_000n,              // Minimum YT to receive
        maxSyIn: 1_100_000_000n,            // Maximum SY to spend
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter           | Type        | Description                                        |
| ------------------- | ----------- | -------------------------------------------------- |
| `market`            | `PublicKey` | The CLMM MarketThree account address               |
| `ytOut`             | `bigint`    | Minimum amount of YT to receive                    |
| `maxSyIn`           | `bigint`    | Maximum amount of SY to spend                      |
| `lnImpliedApyLimit` | `number`    | Optional. Price limit expressed as ln(implied APY) |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Sell YT

`clmmAction.sellYt` sells YT for SY on the CLMM.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.sellYt({
        market: new PublicKey("..."),
        ytIn: 1_000_000_000n,               // Amount of YT to sell
        minSyOut: 900_000_000n,             // Minimum SY to receive
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter           | Type        | Description                                        |
| ------------------- | ----------- | -------------------------------------------------- |
| `market`            | `PublicKey` | The CLMM MarketThree account address               |
| `ytIn`              | `bigint`    | Amount of YT to sell                               |
| `minSyOut`          | `bigint`    | Minimum SY to receive — slippage protection        |
| `lnImpliedApyLimit` | `number`    | Optional. Price limit expressed as ln(implied APY) |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Trade PT (Low-Level)

`clmmAction.tradePt` is a low-level PT/SY swap that accepts a `SwapDirection`. For most use cases, prefer `buyPt` or `sellPt`.

```typescript theme={null}
import {
  clmmAction,
  createVaultSyncTransaction,
  SwapDirection,
} from "@exponent-labs/exponent-sdk";

const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.tradePt({
        market: new PublicKey("..."),
        traderAmount: 1_000_000_000n,
        outConstraint: 900_000_000n,
        swapDirection: SwapDirection.SyToPt,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter           | Type            | Description                                        |
| ------------------- | --------------- | -------------------------------------------------- |
| `market`            | `PublicKey`     | The CLMM MarketThree account address               |
| `traderAmount`      | `bigint`        | Amount of the input token                          |
| `outConstraint`     | `bigint`        | Minimum output amount — slippage protection        |
| `swapDirection`     | `SwapDirection` | `SwapDirection.SyToPt` or `SwapDirection.PtToSy`   |
| `lnImpliedApyLimit` | `number`        | Optional. Price limit expressed as ln(implied APY) |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Claim Farm Emission

`clmmAction.claimFarmEmission` claims farm emissions from an LP position.

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.claimFarmEmission({
        market: new PublicKey("..."),
        lpPosition: new PublicKey("..."),
        farmIndex: 0,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter    | Type        | Description                          |
| ------------ | ----------- | ------------------------------------ |
| `market`     | `PublicKey` | The CLMM MarketThree account address |
| `lpPosition` | `PublicKey` | The LpPosition account to claim from |
| `farmIndex`  | `number`    | Index of the farm emission to claim  |

A matching policy must exist before executing. See [Policy Builders](/vault-sdk/typescript/manager-operations/policy-builders#clmm-policy).

***

## Full Flow Example

This example demonstrates providing concentrated liquidity on the CLMM, buying PT, and then withdrawing the liquidity position.

### Step 1: Deposit Liquidity (Create LP Position)

```typescript theme={null}
import {
  clmmAction,
  createVaultSyncTransaction,
} from "@exponent-labs/exponent-sdk";
import { Connection, PublicKey, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");

const CLMM_MARKET = new PublicKey("...");

const { preInstructions, instruction, postInstructions, signers } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.depositLiquidity({
        market: CLMM_MARKET,
        ptInIntent: 2_000_000_000n,
        syInIntent: 2_000_000_000n,
        lowerTickKey: 500,
        upperTickKey: 1500,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet, ...signers]);

// Save the LP position address for later use
const lpPositionAddress = signers[0].publicKey;
```

### Step 2: Buy PT with SY

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.buyPt({
        market: CLMM_MARKET,
        amountSy: 1_000_000_000n,
        outConstraint: 900_000_000n,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Step 3: Withdraw Liquidity

```typescript theme={null}
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      clmmAction.withdrawLiquidity({
        market: CLMM_MARKET,
        lpPosition: lpPositionAddress,
        lpIn: 2_000_000_000n,
        minPtOut: 0n,
        minSyOut: 0n,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```
