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
| Parameter | Type | Description |
|---|
farmState | PublicKey | Kamino Farm state address |
delegatee | PublicKey | Optional 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
| 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 |
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
| 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 |
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
| Parameter | Type | Description |
|---|
farmState | PublicKey | Kamino Farm state address |
delegatee | PublicKey | Optional 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
| 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 |
The SDK adds an idempotent reward ATA creation instruction before the harvest runs.
Related pages