Skip to main content

Documentation Index

Fetch the complete documentation index at: https://v2-docs.exponent.finance/llms.txt

Use this file to discover all available pages before exploring further.

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.
delegatee defaults to the managed vault owner. stake, unstake, and withdrawUnstakedDeposits only support direct farms. harvestReward supports delegated farms, including obligation-owned farm entries.
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.

Transaction structure

At the low level, each Kamino Farm action is built with createVaultSyncTransaction.
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]);
createVaultSyncTransaction defaults autoManagePositions to false. If you use that default and the farm user_state does not exist yet, initialize it first.

Initialize user

kaminoFarmAction.initializeUser creates the farm user_state PDA for the managed vault owner by default.
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

ParameterTypeDescription
farmStatePublicKeyKamino Farm state address
delegateePublicKeyOptional delegatee. Defaults to the managed vault owner
For delegated farms, initializeUser only supports the managed vault owner path. The SDK rejects initialization for another delegatee on a delegated farm.

Stake

kaminoFarmAction.stake stakes the managed vault’s underlying token ATA into a direct Kamino Farm.
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

ParameterTypeDescription
farmStatePublicKeyKamino Farm state address
amountBN | "ALL"Amount of the farm underlying token to stake
delegateePublicKeyOptional delegatee. Defaults to the managed vault owner
stake rejects delegated farms. If the target farm is delegated, the SDK throws instead of building a direct stake instruction.

Unstake

kaminoFarmAction.unstake unstakes a scaled share amount from a direct Kamino Farm.
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

ParameterTypeDescription
farmStatePublicKeyKamino Farm state address
stakeSharesScaledBNScaled share amount to unstake
delegateePublicKeyOptional delegatee. Defaults to the managed vault owner
unstake rejects delegated farms.

Withdraw unstaked deposits

kaminoFarmAction.withdrawUnstakedDeposits withdraws matured unstaked deposits from a direct Kamino Farm back into the managed vault ATA.
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

ParameterTypeDescription
farmStatePublicKeyKamino Farm state address
delegateePublicKeyOptional delegatee. Defaults to the managed vault owner
withdrawUnstakedDeposits rejects delegated farms.

Harvest reward

kaminoFarmAction.harvestReward harvests one reward index into the managed vault reward ATA. This action supports delegated farms.
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

ParameterTypeDescription
farmStatePublicKeyKamino Farm state address
rewardIndexnumberReward slot to harvest from the farm
delegateePublicKeyOptional delegatee. Defaults to the managed vault owner
The SDK adds an idempotent reward ATA creation instruction before the harvest runs.