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

# Liquidate

> Liquidate an underwater borrow position

Liquidate a position that has exceeded the protocol's liquidation threshold. You pay the borrow token (or absorb) and receive collateral. The SDK returns instructions that use address lookup tables; the transaction is built as a versioned (v0) transaction.

## Liquidate

## 1. Import Dependencies

Import web3.js for connection and versioned transactions, the borrow SDK, and BN for the debt amount.

```typescript theme={null}
import {
  Connection,
  Keypair,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";
import BN from "bn.js";
import { getLiquidateIx } from "@jup-ag/lend/borrow";
import fs from "fs";
import path from "path";
```

> [!NOTE]
>
> `getLiquidateIx` returns instructions and address lookup table accounts. Optional params: `colPerUnitDebt`, `absorb`, `to` (recipient of collateral).

## 2. Load keypair and set parameters

Load the signer and create the connection. Set the vault and the amount of debt to liquidate.

```typescript theme={null}
const KEYPAIR_PATH = "/path/to/your/keypair.json";
const RPC_URL = "https://api.mainnet-beta.solana.com";
const VAULT_ID = 1;
const DEBT_AMOUNT = new BN(100_000); // Debt to liquidate (borrow token base units)

function loadKeypair(keypairPath: string): Keypair {
  const fullPath = path.resolve(keypairPath);
  const secret = JSON.parse(fs.readFileSync(fullPath, "utf8"));
  return Keypair.fromSecretKey(new Uint8Array(secret));
}

const userKeypair = loadKeypair(KEYPAIR_PATH);
const connection = new Connection(RPC_URL, { commitment: "confirmed" });
const signer = userKeypair.publicKey;
```

> [!WARNING]
>
> Only positions that are liquidatable (e.g. LTV above threshold) can be liquidated. The liquidator typically receives collateral; ensure you have the borrow token to pay the debt if required by the vault.

## 3. Build liquidate instructions

Get the liquidate instructions and address lookup table accounts.

```typescript theme={null}
const { ixs, addressLookupTableAccounts } = await getLiquidateIx({
  vaultId: VAULT_ID,
  debtAmount: DEBT_AMOUNT,
  connection,
  signer,
});

if (!ixs?.length) {
  throw new Error("No liquidate instructions returned by Jupiter Lend SDK.");
}
```

> [!NOTE]
>
> You can pass optional `to` (PublicKey) for the collateral recipient, `absorb` (boolean), and `colPerUnitDebt` (BN) for pricing. Omit them to use defaults (e.g. signer as recipient).

## 4. Build versioned transaction and send

Build the v0 message with instructions and lookup tables, sign, send, and confirm.

```typescript theme={null}
const latestBlockhash = await connection.getLatestBlockhash();
const message = new TransactionMessage({
  payerKey: signer,
  recentBlockhash: latestBlockhash.blockhash,
  instructions: ixs,
}).compileToV0Message(addressLookupTableAccounts ?? []);

const transaction = new VersionedTransaction(message);
transaction.sign([userKeypair]);

const signature = await connection.sendTransaction(transaction, {
  skipPreflight: false,
  maxRetries: 3,
  preflightCommitment: "confirmed",
});
await connection.confirmTransaction(signature, "confirmed");

console.log("Liquidate successful! Signature:", signature);
```

> [!NOTE]
>
> Liquidation improves protocol health by closing underwater positions. The liquidator is incentivized with a discount on collateral or similar mechanism per vault design.

> [accordion] When can a position be liquidated?
>
> When the position's loan-to-value (LTV) or health factor crosses the vault's liquidation threshold. The exact rules and incentives are vault-specific: read `liquidationThreshold` and `liquidationPenalty` from the [vault config](https://developers.jup.ag/docs/lend/borrow/read-vault-data.md). The same Read SDK lists every position of a vault with its risk ratio (`getAllPositionsWithRiskRatio`). Prices come from the [Oracle program](https://developers.jup.ag/docs/lend/oracles.md).

> [accordion] Liquidator flow
>
> As liquidator you typically supply the borrow token (or use absorb) and receive collateral. A [flashloan](https://developers.jup.ag/docs/lend/flashloan.md) can source the borrow token within the same transaction. Check the vault's liquidation docs for exact parameters and rewards.

## Full code example

```typescript expandable theme={null}
import {
    Connection,
    Keypair,
    TransactionMessage,
    VersionedTransaction,
} from "@solana/web3.js";
import BN from "bn.js";
import { getLiquidateIx } from "@jup-ag/lend/borrow";
import fs from "fs";
import path from "path";

const KEYPAIR_PATH = "/path/to/your/keypair.json"; // Path to your local keypair file (update this path)
const RPC_URL = "https://api.mainnet-beta.solana.com"; // RPC endpoint
const VAULT_ID = 1; // Target vault (market)
const DEBT_AMOUNT = new BN(100_000); // Debt to liquidate, in smallest units (borrow token base units)

function loadKeypair(keypairPath: string): Keypair {
    const fullPath = path.resolve(keypairPath);
    const secret = JSON.parse(fs.readFileSync(fullPath, "utf8"));
    return Keypair.fromSecretKey(new Uint8Array(secret));
}

// 1. Load user keypair and establish connection
const userKeypair = loadKeypair(KEYPAIR_PATH);
const connection = new Connection(RPC_URL, { commitment: "confirmed" });
const signer = userKeypair.publicKey;

// 2. Get liquidate instructions from SDK
const { ixs, addressLookupTableAccounts } = await getLiquidateIx({
    vaultId: VAULT_ID,
    debtAmount: DEBT_AMOUNT,
    connection,
    signer,
});

if (!ixs?.length) {
    throw new Error("No liquidate instructions returned by Jupiter Lend SDK.");
}

// 3. Build versioned (v0) transaction with address lookup tables
const latestBlockhash = await connection.getLatestBlockhash();
const message = new TransactionMessage({
    payerKey: signer,
    recentBlockhash: latestBlockhash.blockhash,
    instructions: ixs,
}).compileToV0Message(addressLookupTableAccounts ?? []);

const transaction = new VersionedTransaction(message);
transaction.sign([userKeypair]);

// 4. Send and confirm the transaction
const signature = await connection.sendTransaction(transaction, {
    skipPreflight: false,
    maxRetries: 3,
    preflightCommitment: "confirmed",
});
await connection.confirmTransaction(
    { signature, ...latestBlockhash },
    "confirmed"
);

console.log("Liquidate successful! Signature:", signature);
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.