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

# Kamino Lend instructions

> Deploy vault capital into Kamino Lend through policy-gated execution

Use these instructions when your strategy vault should interact with [Kamino Lend](https://kamino.com). For direct Kamino Vault deposits and direct Kamino Farm staking, see [Kamino Vault instructions](/developer-strategy-vaults/kamino-vault-instructions) and [Kamino Farm instructions](/developer-strategy-vaults/kamino-farm-instructions).

## Transaction structure

Every Kamino Lend action goes through `createVaultSyncTransaction`.

```typescript theme={null}
import BN from "bn.js";
import {
  KaminoMarket,
  createVaultSyncTransaction,
  kaminoAction,
} from "@exponent-labs/exponent-sdk";
import {
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.deposit(KaminoMarket.MAIN, "USDC", new BN(100_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

| Part                | What it contains                                                                  |
| ------------------- | --------------------------------------------------------------------------------- |
| `setupInstructions` | Setup instructions that must run before refreshes or the sync step                |
| `preInstructions`   | Permissionless refresh instructions that must run before the sync step            |
| `instruction`       | The Squads sync transaction instruction that wraps the vault-signed Kamino action |
| `postInstructions`  | Permissionless refresh instructions that must run after the sync step             |

<Note>
  Kamino refresh instructions must stay top-level. Send the result in this order: `setupInstructions`, then `preInstructions`, then `instruction`, then `postInstructions`.
</Note>

## One-time setup

Before deposit, withdraw, borrow, or repay, the managed vault usually needs two Kamino Lending accounts.

### Init user metadata

Creates the Kamino `UserMetadata` PDA for the managed vault owner.

```typescript theme={null}
kaminoAction.initUserMetadata(KaminoMarket.MAIN)
```

### Init obligation

Creates the Kamino `Obligation` PDA for one lending market.

```typescript theme={null}
kaminoAction.initObligation(KaminoMarket.MAIN)
```

<Tip>
  Both setup actions are safe to include before a lending action in the same `createVaultSyncTransaction` call.
</Tip>

## Deposit

`kaminoAction.deposit` deposits the vault's reserve token ATA into a Kamino reserve and receives reserve collateral inside the obligation.

```typescript theme={null}
import BN from "bn.js";
import {
  KaminoMarket,
  createVaultSyncTransaction,
  kaminoAction,
} from "@exponent-labs/exponent-sdk";
import {
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.deposit(KaminoMarket.MAIN, "USDC", new BN(100_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter | Type           | Description                                       |
| --------- | -------------- | ------------------------------------------------- |
| `market`  | `KaminoMarket` | Kamino lending market such as `KaminoMarket.MAIN` |
| `asset`   | `string`       | Reserve key from `KAMINO_RESERVES[market]`        |
| `amount`  | `BN`           | Amount to deposit in native token units           |

A matching policy must exist before you execute the transaction. See [Policy Builders](/developer-strategy-vaults/policy-builders).

## Withdraw

`kaminoAction.withdraw` redeems reserve collateral back into the vault's reserve token ATA.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.withdraw(KaminoMarket.MAIN, "USDC", new BN(50_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter | Type           | Description                                |
| --------- | -------------- | ------------------------------------------ |
| `market`  | `KaminoMarket` | Kamino lending market                      |
| `asset`   | `string`       | Reserve key from `KAMINO_RESERVES[market]` |
| `amount`  | `BN`           | Amount to withdraw in native token units   |

<Tip>
  You specify the underlying token amount. The SDK resolves the collateral-side accounting from the reserve state.
</Tip>

A matching policy must exist before you execute the transaction. See [Policy Builders](/developer-strategy-vaults/policy-builders).

## Borrow

`kaminoAction.borrow` borrows reserve liquidity against the vault's Kamino obligation.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.borrow(KaminoMarket.MAIN, "SOL", new BN(1_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter | Type           | Description                            |
| --------- | -------------- | -------------------------------------- |
| `market`  | `KaminoMarket` | Kamino lending market                  |
| `asset`   | `string`       | Reserve key to borrow from             |
| `amount`  | `BN`           | Amount to borrow in native token units |

A matching policy must exist before you execute the transaction. See [Policy Builders](/developer-strategy-vaults/policy-builders).

## Repay

`kaminoAction.repay` repays borrowed reserve liquidity.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.repay(KaminoMarket.MAIN, "SOL", new BN(1_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Parameters

| Parameter | Type           | Description                           |
| --------- | -------------- | ------------------------------------- |
| `market`  | `KaminoMarket` | Kamino lending market                 |
| `asset`   | `string`       | Reserve key to repay                  |
| `amount`  | `BN`           | Amount to repay in native token units |

A matching policy must exist before you execute the transaction. See [Policy Builders](/developer-strategy-vaults/policy-builders).

## Full flow example

This flow deposits USDC into Kamino Lend, borrows SOL, repays the SOL borrow, and then withdraws the USDC collateral.

### Step 1: Setup and deposit

```typescript theme={null}
import BN from "bn.js";
import {
  ExponentVault,
  KaminoMarket,
  createVaultSyncTransaction,
  kaminoAction,
} from "@exponent-labs/exponent-sdk";
import {
  Connection,
  PublicKey,
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const vault = await ExponentVault.load({ connection, address: vaultAddress });

const vaultPda = vault.state.squadsVault;
const policyPda = new PublicKey("...");

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.initUserMetadata(KaminoMarket.MAIN),
      kaminoAction.initObligation(KaminoMarket.MAIN),
      kaminoAction.deposit(KaminoMarket.MAIN, "USDC", new BN(1_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Step 2: Borrow SOL against collateral

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.borrow(KaminoMarket.MAIN, "SOL", new BN(5_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Step 3: Repay the SOL borrow

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.repay(KaminoMarket.MAIN, "SOL", new BN(5_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

### Step 4: Withdraw USDC collateral

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoAction.withdraw(KaminoMarket.MAIN, "USDC", new BN(1_000_000_000)),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
```

## Available asset keys

Look up the supported reserve keys for one Kamino market:

```typescript theme={null}
import { KAMINO_RESERVES, KaminoMarket } from "@exponent-labs/exponent-sdk";

const assets = Object.keys(KAMINO_RESERVES[KaminoMarket.MAIN]);
```

## SOL handling

The SDK wraps and unwraps SOL automatically when the Kamino action uses SOL.
