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

# Remove Liquidity Guide

> Remove liquidity from BEX pools with the SDK.

Using the [Berancer SDK](https://github.com/berachain/berancer-sdk), you can remove liquidity using two primary methods (see [RemoveLiquidityKind](https://github.com/berachain/berancer-sdk/blob/main/src/entities/removeLiquidity/types.ts)):

1. *Proportional* - remove liquidity proportionally across all tokens
2. *SingleTokenExactIn* - remove liquidity and receive a single token

<Tip>
  For more comprehensive remove liquidity examples, see the [remove liquidity
  examples](https://github.com/berachain/bex-sdk/tree/main/examples/remove-liquidity) in the BEX SDK
  repository.
</Tip>

## Example: single token exit

In this example, we'll demonstrate how to remove liquidity and receive a single token (BERA) while calculating the price impact of the transaction.

```javascript theme={null}
import { ethers } from "ethers";
import {
  BalancerApi,
  RemoveLiquidity,
  RemoveLiquidityKind,
  Slippage,
  PriceImpact,
} from "@berachain-foundation/berancer-sdk";

// Initialize provider and wallet
const RPC_URL = "https://rpc.berachain.com/";
const provider = new ethers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const balancerApi = new BalancerApi("https://api.berachain.com/", 80094);

// Get pool data
const poolId = "POOL_ID";
const poolState = await balancerApi.pools.fetchPoolState(poolId);

// Prepare remove liquidity input for single token exit
const removeLiquidityInput = {
  chainId: CHAIN_ID,
  kind: RemoveLiquidityKind.SingleTokenExactIn,
  rpcUrl: RPC_URL,
  bptIn: {
    address: poolState.address,
    decimals: 18,
    rawAmount: ethers.parseUnits("0.1", 18), // 0.1 BPT
  },
  tokenOut: WBERA_TOKEN,
};

const removeLiquidity = new RemoveLiquidity();

// Query expected outputs and calculate price impact in parallel
const [queryOutput, priceImpact] = await Promise.all([
  removeLiquidity.query(removeLiquidityInput, poolState),
  PriceImpact.removeLiquidity(removeLiquidityInput, poolState),
]);

console.log(
  "Expected Token Out:",
  ethers.formatUnits(queryOutput.amountsOut[0].amount, queryOutput.amountsOut[0].token.decimals),
  queryOutput.amountsOut[0].token.symbol
);
console.log("Price Impact:", priceImpact.percentage, "%");

// Build transaction with 1% slippage
const slippage = Slippage.fromPercentage("1");
const deadline = BigInt(Math.floor(Date.now() / 1000) + 60);

const callData = removeLiquidity.buildCall({
  ...queryOutput,
  sender: wallet.address,
  recipient: wallet.address,
  wethIsEth: true,
  slippage,
  deadline,
});

// Send transaction
const tx = await wallet.sendTransaction({
  to: callData.to,
  data: callData.callData,
  value: callData.value,
});

console.log("Transaction sent:", tx.hash);

const receipt = await tx.wait();
```

Below we breakdown the code example above.

### Helper classes

The main helper classes we use from the SDK are:

* `BalancerApi` - to simplify retrieving pool data from the Pools API
* `RemoveLiquidity` - to build removeLiquidity queries and transactions
* `Slippage` - to simplify creating limits with user defined slippage
* `PriceImpact` - to calculate the price impact of single token exits

### Fetching pool data

After initializing the `BalancerApi` class, we can fetch current pool data using `fetchPoolState`.

```javascript theme={null}
const balancerApi = new BalancerApi("https://api.berachain.com/", 80094);

// Get pool data
const poolId = "POOL_ID";
const poolState = await balancerApi.pools.fetchPoolState(poolId);
```

### Simulation and slippage setting

The `PriceImpact` class calculates the price impact of unbalanced liquidity operations. A [PriceImpactAmount](https://github.com/berachain/berancer-sdk/blob/main/src/entities/priceImpactAmount.ts#L4) is returned, with the price impact expressed in a number of different units.

Its use in the above example is informational, but can be used to provide detailed slippage information.

```javascript theme={null}
const [queryOutput, priceImpact] = await Promise.all([
  removeLiquidity.query(removeLiquidityInput, poolState),
  PriceImpact.removeLiquidity(removeLiquidityInput, poolState),
]);

const slippage = Slippage.fromPercentage("1");
```

### Building the transaction

The `RemoveLiquidity` class has a `buildCall` method that allows us to build the transaction. This method takes in the `queryOutput` and address parameters.

```javascript theme={null}
const slippage = Slippage.fromPercentage("1");
const callData = removeLiquidity.buildCall({
  ...queryOutput,
  sender: wallet.address,
  recipient: wallet.address,
  wethIsEth: true,
  slippage,
  deadline,
});
```
