# Refund Liquidity (v2)

Refund tokens that were sent to an LP account but were not added to the pool.

> The production-ready approach is **API-driven**. Use the STON.fi API to resolve router metadata, construct contracts via `dexFactory`, and let the SDK derive the correct on-chain calls. This avoids hardcoding addresses and remains forward-compatible with router updates.

## 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({
  routerAddress: lpAccountData.routerAddress?.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)

Only rely on testnet for experimentation. Because `api.ston.fi` is mainnet-only, you must hardcode contract addresses, mint or source the testnet jettons (TesREED/TestBlue), and create funded pools before you can refund LP accounts.

```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.


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

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

The question should be specific, self-contained, and written in natural language.
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.
