> ## 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 Farm instructions

> Initialize, stake, unstake, withdraw, and harvest Kamino Farm positions through policy-gated vault execution

Use these instructions when your strategy vault should interact with a Kamino Farm `user_state`. The examples below assume the managed vault already holds the farm's underlying token ATA.

<Note>
  `delegatee` defaults to the managed vault owner. `stake`, `unstake`, and `withdrawUnstakedDeposits` only support direct farms. `harvestReward` supports delegated farms, including obligation-owned farm entries.
</Note>

<Tip>
  These examples use `createVaultSyncTransaction` because each Kamino Farm action is a single low-level sync step. For chained flows such as Kamino Vault deposit-then-stake, use [VaultTransactionBuilder](/developer-strategy-vaults/vault-transaction-builder).
</Tip>

## Transaction structure

At the low level, each Kamino Farm action is built with `createVaultSyncTransaction`.

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

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.stake({
        farmState,
        amount: new BN(1_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]);
```

<Tip>
  `createVaultSyncTransaction` defaults `autoManagePositions` to `false`. If you use that default and the farm `user_state` does not exist yet, initialize it first.
</Tip>

## Initialize user

`kaminoFarmAction.initializeUser` creates the farm `user_state` PDA for the managed vault owner by default.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.initializeUser({
        farmState,
      }),
    ],
    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                                             |
| ----------- | ----------- | ------------------------------------------------------- |
| `farmState` | `PublicKey` | Kamino Farm state address                               |
| `delegatee` | `PublicKey` | Optional delegatee. Defaults to the managed vault owner |

<Warning>
  For delegated farms, `initializeUser` only supports the managed vault owner path. The SDK rejects initialization for another delegatee on a delegated farm.
</Warning>

## Stake

`kaminoFarmAction.stake` stakes the managed vault's underlying token ATA into a direct Kamino Farm.

```typescript theme={null}
import BN from "bn.js";

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.initializeUser({
        farmState,
      }),
      kaminoFarmAction.stake({
        farmState,
        amount: new BN(1_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                                             |
| ----------- | ------------- | ------------------------------------------------------- |
| `farmState` | `PublicKey`   | Kamino Farm state address                               |
| `amount`    | `BN \| "ALL"` | Amount of the farm underlying token to stake            |
| `delegatee` | `PublicKey`   | Optional delegatee. Defaults to the managed vault owner |

<Warning>
  `stake` rejects delegated farms. If the target farm is delegated, the SDK throws instead of building a direct stake instruction.
</Warning>

## Unstake

`kaminoFarmAction.unstake` unstakes a scaled share amount from a direct Kamino Farm.

```typescript theme={null}
import BN from "bn.js";

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.unstake({
        farmState,
        stakeSharesScaled: new BN("1000000000000000000"),
      }),
    ],
    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                                             |
| ------------------- | ----------- | ------------------------------------------------------- |
| `farmState`         | `PublicKey` | Kamino Farm state address                               |
| `stakeSharesScaled` | `BN`        | Scaled share amount to unstake                          |
| `delegatee`         | `PublicKey` | Optional delegatee. Defaults to the managed vault owner |

<Warning>
  `unstake` rejects delegated farms.
</Warning>

## Withdraw unstaked deposits

`kaminoFarmAction.withdrawUnstakedDeposits` withdraws matured unstaked deposits from a direct Kamino Farm back into the managed vault ATA.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.withdrawUnstakedDeposits({
        farmState,
      }),
    ],
    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                                             |
| ----------- | ----------- | ------------------------------------------------------- |
| `farmState` | `PublicKey` | Kamino Farm state address                               |
| `delegatee` | `PublicKey` | Optional delegatee. Defaults to the managed vault owner |

<Warning>
  `withdrawUnstakedDeposits` rejects delegated farms.
</Warning>

## Harvest reward

`kaminoFarmAction.harvestReward` harvests one reward index into the managed vault reward ATA. This action supports delegated farms.

```typescript theme={null}
const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      kaminoFarmAction.harvestReward({
        farmState,
        rewardIndex: 0,
        delegatee: obligation,
      }),
    ],
    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                                             |
| ------------- | ----------- | ------------------------------------------------------- |
| `farmState`   | `PublicKey` | Kamino Farm state address                               |
| `rewardIndex` | `number`    | Reward slot to harvest from the farm                    |
| `delegatee`   | `PublicKey` | Optional delegatee. Defaults to the managed vault owner |

<Tip>
  The SDK adds an idempotent reward ATA creation instruction before the harvest runs.
</Tip>

## Related pages

* [Kamino Vault instructions](/developer-strategy-vaults/kamino-vault-instructions) covers minting the Kamino Vault shares that direct farms stake.
* [Policy Builders](/developer-strategy-vaults/policy-builders#kamino-farm-policy) covers `createKaminoFarmPolicy`.
