> ## 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.

# CLMM SDK

> Get started with the Exponent CLMM SDK

Set up the Exponent SDK and walk through the complete CLMM lifecycle — from buying and selling PT/YT, to providing liquidity, withdrawing, and reading market state.

## Installation

<CodeGroup>
  ```bash yarn theme={null}
  yarn add @exponent-labs/exponent-sdk
  ```

  ```bash npm theme={null}
  npm install @exponent-labs/exponent-sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @exponent-labs/exponent-sdk
  ```
</CodeGroup>

## Setup

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

const connection = new Connection("https://api.mainnet-beta.solana.com");
const wallet = Keypair.fromSecretKey(/* your keypair */);
const marketAddress = new PublicKey("...");

const market = await MarketThree.load(LOCAL_ENV, connection, marketAddress);
```

<Steps>
  <Step title="Buy PT">
    Use `ixWrapperBuyPt` to buy PT (Principal Tokens) using base assets. This wraps the base into SY and swaps SY for PT in a single atomic operation.

    ```typescript theme={null}
    const { ixs, setupIxs } = await market.ixWrapperBuyPt({
      owner: wallet.publicKey,
      minPtOut: 1_000_000_000n,   // minimum PT to receive
      baseIn: 1_100_000_000n,     // base asset to spend
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet]);
    ```
  </Step>

  <Step title="Sell PT">
    Use `ixWrapperSellPt` to sell PT back for base assets. This swaps PT for SY and redeems SY for base in one transaction.

    ```typescript theme={null}
    const { ixs, setupIxs } = await market.ixWrapperSellPt({
      owner: wallet.publicKey,
      amount: 1_000_000_000n,     // PT to sell
      minBaseOut: 900_000_000n,   // minimum base to receive
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet]);
    ```
  </Step>

  <Step title="Buy YT">
    Use `ixWrapperBuyYt` to buy YT (Yield Tokens) using base assets. This wraps base into SY, strips SY into PT and YT, and sells the excess PT back — all atomically.

    ```typescript theme={null}
    const { ixs, setupIxs } = await market.ixWrapperBuyYt({
      owner: wallet.publicKey,
      ytOut: 1_000_000_000n,      // YT to receive
      maxBaseIn: 1_200_000_000n,  // maximum base to spend
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet]);
    ```
  </Step>

  <Step title="Sell YT">
    Use `ixWrapperSellYt` to sell YT back for base assets. This buys PT with SY, merges PT and YT back into SY, and redeems SY for base.

    ```typescript theme={null}
    const { ixs, setupIxs } = await market.ixWrapperSellYt({
      owner: wallet.publicKey,
      amount: 1_000_000_000n,     // YT to sell
      minBaseOut: 900_000_000n,   // minimum base to receive
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet]);
    ```
  </Step>

  <Step title="Provide Liquidity">
    Use `ixWrapperProvideLiquidity` to provide liquidity from base assets within a specified APY range. This wraps base into SY, strips into PT and YT, adds PT liquidity, and returns YT and LP tokens.

    ```typescript theme={null}
    const { ixs, setupIxs, signers } = await market.ixWrapperProvideLiquidity({
      depositor: wallet.publicKey,
      amountBase: 10_000_000_000n,  // base asset to deposit
      minLpOut: 9_000_000_000n,     // minimum LP tokens to receive
      lowerTickApy: 0.05,           // 5% APY lower bound
      upperTickApy: 0.15,           // 15% APY upper bound
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet, ...signers]);
    ```

    <Warning>
      The `signers` array contains the generated LP position keypair. You **must** include it when signing the transaction, otherwise the transaction will fail.
    </Warning>

    <Tip>
      The `lowerTickApy` and `upperTickApy` parameters are decimal numbers — use `0.05` for 5% APY, not `500` or `50000`.
    </Tip>
  </Step>

  <Step title="Withdraw Liquidity">
    Use `ixWithdrawLiquidityToBase` to withdraw an LP position back to base assets. You need the LP position's public key, which you can obtain from `getUserLpPositions`.

    ```typescript theme={null}
    const { ixs, setupIxs } = await market.ixWithdrawLiquidityToBase({
      owner: wallet.publicKey,
      amountLp: 9_000_000_000n,        // LP tokens to withdraw
      minBaseOut: 8_500_000_000n,       // minimum base to receive
      lpPosition: lpPositionPublicKey,  // from getUserLpPositions
    });

    const tx = new Transaction().add(...setupIxs, ...ixs);
    await sendAndConfirmTransaction(connection, tx, [wallet]);
    ```

    <Note>
      The `lpPosition` parameter is the public key of your LP position account. See the next step to learn how to retrieve it.
    </Note>
  </Step>

  <Step title="Check LP Positions">
    Use `getUserLpPositions` to retrieve all LP positions for a wallet in a specific market.

    ```typescript theme={null}
    const { lpPositions } = await market.getUserLpPositions(
      wallet.publicKey,
      marketAddress,
    );

    for (const positions of lpPositions) {
      for (const pos of positions) {
        console.log("Position:", pos.publicKey.toBase58());
        console.log("LP Balance:", pos.account.lpBalance);
        console.log("Lower Tick:", pos.account.lowerTickIdx);
        console.log("Upper Tick:", pos.account.upperTickIdx);
        console.log("Unclaimed PT fees:", pos.account.tokensOwedPt);
        console.log("Unclaimed SY fees:", pos.account.tokensOwedSy);
      }
    }
    ```
  </Step>

  <Step title="Calculate Withdrawal Amounts">
    Use `getPtAndSyOnWithdrawLiquidity` to preview how much PT and SY you would receive when withdrawing a position.

    ```typescript theme={null}
    const result = market.getPtAndSyOnWithdrawLiquidity(pos.account);

    console.log("PT to receive:", result.totalPtOut);
    console.log("SY to receive:", result.totalSyOut);
    ```

    <Tip>
      You can pass an optional second parameter to calculate a partial withdrawal: `market.getPtAndSyOnWithdrawLiquidity(position, partialLpAmount)`.
    </Tip>
  </Step>
</Steps>

## Reading Market State

The `MarketThree` instance exposes getter properties for reading onchain state:

```typescript theme={null}
// Token mints
console.log("PT Mint:", market.mintPt.toBase58());
console.log("SY Mint:", market.mintSy.toBase58());
console.log("YT Mint:", market.mintYt.toBase58());

// Market balances
console.log("PT Balance:", market.ptBalance);
console.log("SY Balance:", market.syBalance);
console.log("LP Balance:", market.lpBalance);

// Market parameters
console.log("SY Exchange Rate:", market.currentSyExchangeRate);
console.log("Seconds Remaining:", market.secondsRemaining);
console.log("Status Flags:", market.statusFlags);
```

## Next Steps

<CardGroup cols={2}>
  <Card href="/developer-clmm/concepts" title="Core Concepts">
    Understand APY-based ticks, fee decay, YT flash-swap routing, swap behavior, and the core accounts behind the CLMM.
  </Card>

  <Card href="/developer-clmm/typescript/instructions/overview" title="Instructions">
    Explore the full set of high-level instruction builders for PT and YT trading, liquidity provision, and liquidity withdrawal.
  </Card>

  <Card href="/developer-clmm/typescript/read-functions/overview" title="Read Functions">
    Query quotes, LP positions, withdrawal previews, balances, and market state without sending transactions.
  </Card>

  <Card href="/developer-clmm/account-references/market" title="Account References">
    Inspect the main market account and related CLMM accounts, including financial state, emissions, and configuration fields.
  </Card>
</CardGroup>
