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

# Positions

> Open, deposit, read, withdraw, claim, close

## Open, deposit, claim, withdraw, close

```ts theme={null}
import { DistributionMode } from "@picon-finance/dlmm-sdk";

// Open a position and deposit in one flow.
const openPositionIxs = await pool.openPosition(ownerSigner, positionMintSigner, {
  lowerBinId: -10,
  upperBinId: 10,
});

const position = await pool.getPositionByPositionMint(positionMintSigner.address);

// depositByWeight checks the deposit against the pool's cached activeBinId — if time has
// passed since the pool was fetched (other activity could've moved the price since), refresh
// it first so the deposit isn't built/checked against a stale active bin.
await pool.refresh();

const depositIxs = await position.depositByWeight(ownerSigner, {
  amountX: 1_000_000n,
  amountY: 1_000_000n,
  lowerBinId: -10,
  binWeights: Array(21).fill(1),   // flat "Spot" weighting — see the note below
  maxActiveBinSlippage: 5,
  distributionMode: DistributionMode.Balanced,
});

// Later: claim fees, withdraw (partially or fully, by bps), close.
const claimFeeIxs = await position.claimFee(ownerSigner);
const withdrawIxs = await position.withdraw(ownerSigner, { bpsToRemove: 5_000 }); // bps, out of 10_000 = 100%
const closeIx = await position.close(ownerSigner);
```

<Note>
  `binWeights` is a raw per-bin weight array — the SDK doesn't ship shape presets (Spot / Curve
  / Bid-Ask). Generating a triangular or U-shaped curve from a shape name is a few lines of
  plain TypeScript you write yourself; see
  [Positions and liquidity](/concepts/positions-and-liquidity#depositing-by-weight).
</Note>

## Reading position state

`position.data` exposes the decoded on-chain `Position` account directly from the cached
account — no extra fetch needed:

```ts theme={null}
console.log(position.data.lowerBinId, position.data.upperBinId);
```

`position.getInfo()` returns a full summary — deposited amounts and the total fee a `claimFee`
call would sweep right now, each in both `gross*` (before any Token-2022 transfer fee) and
`net*` (what you'd actually receive) forms:

```ts theme={null}
const info = await position.getInfo();
console.log(`Deposited: ${info.netAmountX} X / ${info.netAmountY} Y`);
console.log(`Claimable fee: ${info.netFeeX} X / ${info.netFeeY} Y`);
```

`info.bins` (same as calling `position.getBinInfos()` directly) is the per-bin breakdown
`getInfo()` sums to produce those totals — always raw, since `gross*`/`net*` only apply once,
to the aggregate:

```ts theme={null}
for (const { bin, amountX, amountY, feeX, feeY } of position.getBinInfos()) {
  console.log(`bin ${bin.id}: deposited ${amountX} X / ${amountY} Y, fee ${feeX} X / ${feeY} Y`);
}
```

Both are computed entirely from cached data. `getBinInfos()` makes no RPC calls at all;
`getInfo()` makes exactly one round trip (via `Pool.getTransferFees()`) to resolve each mint's
live transfer-fee rate.

## Looking up positions

Refresh a position's cached state after it changes on-chain:

```ts theme={null}
await position.refresh();
```

Look up every position minted to a given owner, across all their pools:

```ts theme={null}
// Map<poolAddress, positionMintAddress[]>
const mintsByPool = await dlmmProgram.getAllPositionMintsByOwner(ownerSigner.address);

for (const [poolAddress, positionMints] of mintsByPool) {
  const ownerPool = await dlmmProgram.getPool(poolAddress);
  const positions = await ownerPool.getAllPositionsByPositionMints(positionMints);
  console.log(poolAddress, positions.map(p => p.address));
}
```

Or fetch a single position directly if you already know its address:

```ts theme={null}
const positionByAddress = await pool.getPosition(positionAddress);
```

## Claiming across many positions

```ts theme={null}
import { Position } from "@picon-finance/dlmm-sdk";

const positions = await pool.getAllPositionsByPositionMints(positionMints);
const claimTxs = await Position.claimAllFees(ownerSigner, positions);

for (const claimIxs of claimTxs) {
  // build + send one transaction per entry
}
```

`Position.claimAllFees()`:

* Skips positions with nothing pending, checked locally with no extra RPC.
* Batches the rest into fixed-size instruction groups (3 positions per transaction by default,
  overridable via a third argument), one transaction per batch.
* Shares a single set of ATA setup/teardown instructions across the whole batch, rather than
  repeating them per position.
* Requires every position in the call to belong to the same pool.
