Skip to main content

Documentation Index

Fetch the complete documentation index at: https://kamino.com/docs/llms.txt

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

Overview

Kamino Farms is the rewards distribution layer for Kamino products. Farms distribute incentive tokens to depositors, suppliers, and borrowers across the protocol, including KMNO emissions on vaults and lending positions. The TypeScript SDK provides access to farm and user state, along with instructions to stake, unstake, and harvest rewards.
Farms attached to lending positions and kvaults are delegated: position accounting lives in the parent program (klend or kvault), and unstake is a two-step flow gated by a cooldown. Read Farm rewards for the conceptual model before integrating.

Key Components of Farms Integration

Farm State

Decode a farm’s reward tokens, per-second emission rates, total staked amount, cooldown period, and scope-oracle binding.

User Positions

Read a wallet’s stake across one or many farms, pending rewards per reward token, and pending-unstake cooldown status.

Stake & Claim

Initialize user state, stake / unstake (with cooldown handling), and harvest accrued rewards in one or all reward tokens.

Locating a Farm Address

The SDK reads any farm given its pubkey. Three places that pubkey can come from:
SourceWhere to look
CDNhttps://cdn.kamino.finance/resources.json, under mainnet-beta.extraFarms.
Klend reserve fieldsA reserve account’s state.farmCollateral (supply side) or state.farmDebt (borrow side) field.
Kvault stateA kvault account’s state.vaultFarm field. List vaults at https://api.kamino.finance/kvaults/vaults.

Integration Options

TypeScript SDK

On-chain reads and transaction building for stake, unstake, harvest, and user-state management. TS/JS only.

Stake

import { createSolanaRpc, address } from '@solana/kit';
import { Farms, FarmState } from '@kamino-finance/farms-sdk';
import { getScopePricesFromFarm } from '@kamino-finance/farms-sdk/dist/utils/option';
import Decimal from 'decimal.js';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const farms = new Farms(rpc);

const FARM = address('9wSacmF3KBr4HmgncxXeBhDdw4Shi2X9ETAFzWJS6pG6');
const STAKE_MINT = address('3EmfhZ3KUaYdwKZ9CwfGoKRqQqUV1MhSCVL5Ch7szX7e');

const farmState = await FarmState.fetch(rpc, FARM);
if (!farmState) console.log(`Farm not found: ${FARM}`);

const scopePrices = getScopePricesFromFarm(farmState);
const amountLamports = new Decimal(0.02).mul(
  new Decimal(10).pow(farmState.token.decimals.toNumber()),
);

// Refresh the farm so reward accounting is current, then stake.
const instructions = [
  await farms.refreshFarmIx(FARM, scopePrices),
  await farms.stakeIx(signer, FARM, amountLamports, STAKE_MINT, scopePrices),
];

console.log('Stake Instructions:', instructions);
View Code
For the full stake flow including first-time user-state creation and transaction confirmation, see Stake.

Unstake

import { createSolanaRpc, address } from '@solana/kit';
import { Farms, FarmState } from '@kamino-finance/farms-sdk';
import { getScopePricesFromFarm } from '@kamino-finance/farms-sdk/dist/utils/option';
import { WAD } from '@kamino-finance/farms-sdk/dist/utils/utils';
import Decimal from 'decimal.js';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const farms = new Farms(rpc);

const FARM = address('9wSacmF3KBr4HmgncxXeBhDdw4Shi2X9ETAFzWJS6pG6');

const farmState = await FarmState.fetch(rpc, FARM);
if (!farmState) console.log(`Farm not found: ${FARM}`);

const scopePrices = getScopePricesFromFarm(farmState);
const { key: userStateKey } =
  await farms.getUserStateKeyForUndelegatedFarm(signer.address, FARM);

// unstakeIx takes WAD-scaled shares. Refresh the farm and user, then unstake.
const amountScaled = new Decimal(0.02)
  .mul(new Decimal(10).pow(farmState.token.decimals.toNumber()))
  .mul(WAD);

const instructions = [
  await farms.refreshFarmIx(FARM, scopePrices),
  await farms.refreshUserIx(userStateKey, FARM, scopePrices),
  await farms.unstakeIx(signer, FARM, amountScaled, scopePrices),
];

console.log('Unstake Instructions:', instructions);
View Code
Unstaking starts the withdrawal cooldown. After it elapses, withdraw the tokens back to your wallet. See Unstake.

What’s Covered

Farms

Read farm state, discover farms, and compute or simulate incentive APY.

User Position Data

Fetch a wallet’s stake, lockup and cooldown status, and pending rewards.

Stake

Initialize user state and stake share tokens into a farm.

Unstake

Unstake into pending withdrawal and start the cooldown.

Withdraw

Move unstaked tokens back to your wallet after the cooldown.

Harvest

Claim all pending reward tokens in one transaction.

Farms SDK repository

TypeScript SDK source, on-chain program docs, and example scripts.

KFarms program

Rust source for the on-chain farms program.

NPM SDK package

Install the TypeScript SDK to integrate reward operations.

Farm Rewards Concepts

Vault Farm, Autocompound, Insurance Pool farm, and cooldowns explained.