> For the complete documentation index, see [llms.txt](https://docs.ston.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ston.fi/developer-section/dex/sdk/refund-liquidity.md).

# Recover pending liquidity

Refund assets held in an LP account before LP issuance.

This operation returns tokens held in an LP account that have not been added to the pool. It does not burn an issued LP position; use [Withdraw liquidity](/developer-section/dex/sdk/burn-lp-tokens.md) for that. Supply the actual LP account and owner wallet for the selected DEX v2 router; see [Setup and environments](/developer-section/dex/sdk/v2.md).

## Mainnet workflow

1. Determine the router and LP account that needs the refund. You can fetch them from the simulation result, from `getPoolsByAssetPair`, or from `getWalletLpAccounts` on the STON.fi API.
2. Fetch the router metadata with `getRouter(routerAddress)` and build the contract instances dynamically.
3. Call `getRefundTxParams` on the LP account to obtain the message you need to send on-chain.

```typescript
import { Client, dexFactory } from "@ston-fi/sdk";
import { StonApiClient } from "@ston-fi/api";

const tonClient = new Client({
  endpoint: "https://toncenter.com/api/v2/jsonRPC",
  apiKey: process.env.TON_API_KEY,
});

const apiClient = new StonApiClient();

const routerMetadata = await apiClient.getRouter("<router address>");
const dexContracts = dexFactory(routerMetadata);

const lpAccount = tonClient.open(
  dexContracts.LpAccount.create("<lp account address>"),
);

// Optional: inspect the pending balances before refunding
const lpAccountData = await lpAccount.getLpAccountData();
console.log({
  userAddress: lpAccountData.userAddress.toString(),
  poolAddress: lpAccountData.poolAddress.toString(),
  tokenABalance: lpAccountData.amount0.toString(),
  tokenBBalance: lpAccountData.amount1.toString(),
});

const refundTxParams = await lpAccount.getRefundTxParams({
  queryId: 12345,
});
```

Send the resulting parameters using your preferred wallet integration (see the [transaction sending guide](/developer-section/common/transaction-sending.md)).

### Deriving the LP account address

If you only know the assets and the user wallet:

```typescript
const [poolInfo] = await apiClient.getPoolsByAssetPair({
  asset0Address: "<token A address or 'ton'>",
  asset1Address: "<token B address>",
});

if (!poolInfo) {
  throw new Error("Liquidity pool not found for the provided asset pair");
}

const routerMetadata = await apiClient.getRouter(poolInfo.routerAddress);
const dexContracts = dexFactory(routerMetadata);

const pool = tonClient.open(
  dexContracts.Pool.create(poolInfo.address),
);

const lpAccountAddress = (
  await pool.getLpAccountAddress({ ownerAddress: "<your wallet address>" })
).toString();
```

You can then pass `lpAccountAddress` into the main workflow above.

> **TON pools**: When a pool includes TON, the router metadata exposes `ptonMasterAddress`. `dexFactory` automatically wires the correct pool/LP implementations. No manual proxy setup is required.

## Testnet refund (manual setup)

To refund a testnet LP account, configure testnet contracts and use the wallet that owns the pending deposit. The `api.ston.fi` endpoint serves mainnet data.

```typescript
import { TonClient } from "@ton/ton";
import { DEX } from "@ston-fi/sdk";

const client = new TonClient({
  endpoint: "https://testnet.toncenter.com/api/v2/jsonRPC",
});

const router = client.open(
  DEX.v2_1.Router.CPI.create("kQALh-JBBIKK7gr0o4AVf9JZnEsFndqO0qTCyT-D-yBsWk0v"), // CPI Router v2.1.0 (testnet)
);

const pool = client.open(
  await router.getPool({
    token0: "kQDLvsZol3juZyOAVG8tWsJntOxeEZWEaWCbbSjYakQpuYN5", // TesREED jetton (testnet)
    token1: "kQB_TOJSB7q3-Jm1O8s0jKFtqLElZDPjATs5uJGsujcjznq3", // TestBlue jetton (testnet)
  }),
);

const lpAccount = client.open(
  await pool.getLpAccount({ ownerAddress: "<your testnet wallet>" }),
);

const txParams = await lpAccount.getRefundTxParams({
  queryId: 12345,
});
```

This manual approach is strictly **for testing**. Switch back to the API-driven workflow for any mainnet-facing integration.

## Check the result

After processing, read the LP account again and inspect return transfers to its owner. Recovery changes pending balances; it does not represent withdrawing already minted LP tokens. Use [Withdraw liquidity](/developer-section/dex/sdk/burn-lp-tokens.md) for an issued position.

Use the [REST transaction action tree](/developer-section/dex/api/reference.md#transaction-action-tree) to inspect the submitted operation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ston.fi/developer-section/dex/sdk/refund-liquidity.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
