> For the complete documentation index, see [llms.txt](https://docs.ferra.ag/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ferra.ag/integration/dlmm/typescript-sdk/position-management/close-position.md).

# Close Position

Remove all remaining liquidity and burn the position NFT in a single transaction. This method efficiently withdraws all tokens and fees before permanently closing the position.

### Prerequisites

Before closing a position:

* Own the position NFT you want to close
* Have sufficient gas for transaction
* Understand this action is irreversible
* Consider claiming fees first if needed separately

### Basic Usage

```typescript
// Get the pair
const pair = await sdk.Pair.getPair(pairAddress);
const positionId = "0x123...abc";

// Remove all liquidity and close position
const tx = await sdk.Pair.removeAndClosePosition(pair, positionId);

// Execute transaction
const result = await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx,
  signer: keypair
});

console.log("Position closed:", result.digest);
```

### Method Signature

```typescript
async removeAndClosePosition(
  pair: LBPair, 
  positionId: string, 
  tx?: Transaction
): Promise<Transaction>
```

#### Parameters

* `pair`: The LBPair where position exists
* `positionId`: Position NFT to close
* `tx`: Optional existing transaction to append to

#### Returns

* Transaction that removes liquidity and burns NFT
* Tokens are automatically sent to sender

### How It Works

The method performs these steps automatically:

1. **Fetch position bins** - Identifies all bins with liquidity
2. **Remove liquidity** - Withdraws from all active bins
3. **Collect fees** - Claims accumulated trading fees
4. **Close position** - Burns the position NFT
5. **Transfer tokens** - Sends all tokens to owner

### Complete Example

```typescript
// Close position with validation
async function closePositionSafely(pair: LBPair, positionId: string) {
  try {
    // Verify ownership
    const userPositions = await sdk.Position.getLbPositions([pair.id]);
    const ownsPosition = userPositions.some(p => p.id === positionId);
    
    if (!ownsPosition) {
      throw new Error("You don't own this position");
    }
    
    // Check current value before closing
    const bins = await sdk.Position.getPositionBins(pair, positionId);
    console.log(`Closing position with ${bins.length} active bins`);
    
    // Close position
    const tx = await sdk.Pair.removeAndClosePosition(pair, positionId);
    
    return await sdk.fullClient.signAndExecuteTransaction({
      transaction: tx,
      signer: keypair
    });
    
  } catch (error) {
    console.error("Failed to close position:", error);
    throw error;
  }
}
```

### Handling Empty Positions

```typescript
// The method handles empty positions gracefully
const bins = await sdk.Position.getPositionBins(pair, positionId);

if (bins.length === 0) {
  console.log("Position is empty, will only burn NFT");
}

// Still safe to call - will just burn the empty NFT
const tx = await sdk.Pair.removeAndClosePosition(pair, positionId);
```

### Batch Operations

```typescript
// Close multiple positions in one transaction
const tx = new Transaction();

for (const positionId of positionsToClose) {
  await sdk.Pair.removeAndClosePosition(pair, positionId, tx);
}

// Execute all closures at once
await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx,
  signer: keypair
});
```

### Alternative Approaches

#### Manual Two-Step Process

```typescript
// Step 1: Remove all liquidity (keep position)
const bins = await sdk.Position.getPositionBins(pair, positionId);
const binIds = bins.map(b => b.id);

const removeTx = await sdk.Pair.removeLiquidity(pair, {
  positionId,
  binIds
});

// Step 2: Close empty position later
const closeTx = TransactionUtil.closePosition(
  pair, 
  { positionId }, 
  sdk.sdkOptions
);
```

#### Partial Withdrawal Before Closing

```typescript
// Remove from specific bins first
await sdk.Pair.removeLiquidity(pair, {
  positionId,
  binIds: [8388608, 8388609] // Selected bins only
});

// Then close position with remaining liquidity
await sdk.Pair.removeAndClosePosition(pair, positionId);
```

### What Happens to Your Assets

When closing a position:

* **Liquidity tokens** are burned
* **Token X and Y** are returned based on current bin reserves
* **Accumulated fees** are included in the withdrawal
* **Position NFT** is permanently destroyed
* **All assets** are sent to transaction sender

### Common Use Cases

1. **Exit Strategy**: Complete withdrawal from a pool
2. **Position Migration**: Close old positions before creating new ones
3. **Portfolio Cleanup**: Remove empty or underperforming positions
4. **Emergency Exit**: Quick withdrawal of all funds

### Error Handling

```typescript
try {
  await sdk.Pair.removeAndClosePosition(pair, positionId);
} catch (error) {
  if (error.message.includes("Invalid sender address")) {
    console.error("Set valid sender address first");
  } else if (error.message.includes("not match with pair")) {
    console.error("Position doesn't belong to this pair");
  }
}
```

### Related Topics

* [Remove All Liquidity](/integration/dlmm/typescript-sdk/remove-liquidity/remove-all-liquidity.md) - Just remove without closing
* [Get Position Bins](/integration/dlmm/typescript-sdk/position-management/get-position-bins.md) - Check bins before closing
* [Calculate Output Amounts](/integration/dlmm/typescript-sdk/remove-liquidity/calculate-output-amounts.md) - Preview withdrawal
* [Open Position](/integration/dlmm/typescript-sdk/position-management/open-position.md) - Create new positions
