Skip to content
Pool Manager

Manage liquidity with the SDK

Prepare position creation, liquidity changes, fee collection, and account closure.

Fetch the pool with client.fetchPool(poolAddress) before constructing a range. The client validates the pool's owner, layout version, PDA, mints, and vaults. The user guide explains the economic choices; this page describes the operation contract.

Open a range

import type { GraplClient, PreparedTransaction } from "@grapl/sdk";
import type { Address } from "@solana/kit";

export async function prepareFullRangePosition(
  client: GraplClient,
  pool: Address,
  positionId: bigint,
): Promise<PreparedTransaction> {
  return client.prepareOpenPosition({
    pool,
    positionId,
    range: { fullRange: true },
  });
}

For a concentrated position, supply range: { tickLower, tickUpper }. Ticks must be aligned to the pool's spacing and within its supported domain. Confirm the position creation before preparing a separate add transaction that reads it.

Add or remove

prepareAddLiquidity and prepareRemoveLiquidity take the same core fields: pool, position, positive liquidity, limitA, and limitB. liquidity is a liquidity unit amount, not token atoms. Limits are token atoms:

OperationlimitA and limitB mean
AddMaximum amounts of A and B you permit the operation to spend
RemoveMinimum amounts of A and B you require back

The SDK resolves associated token accounts and prepares missing accounts idempotently. actor, tokenAccountA, and tokenAccountB can be explicit overrides. Custom accounts must match the actor and mint. Pool hooks still apply; unsupported or missing hook resolvers reject preparation.

Collect fees and close

Use prepareCollectPositionFees({ pool, position }) for a position's accrued fees. Configured beneficiary fees use prepareCollectBeneficiaryFees({ pool, beneficiaryIndex }); they are a separate claim.

Remove all liquidity and collect owed balances before prepareClosePosition({ position }). Close only after the prior transactions have confirmed. Inspect the actual rent refund and network fee independently; shared pool/tick storage is not automatically closed with a position.

prepareDonate({ pool, amountA, amountB }) donates into the pool's fee accounting; it is not an add-liquidity operation. For more detail, see LP lifecycle, positions, and fees.