Version banner. All demos target
@raydium-io/raydium-sdk-v2@0.2.42-alpha against Solana mainnet-beta, verified 2026-04. The SDK dispatches v3 / v5 / v6 internally based on the farm’s program owner; examples below assume a v6 farm. See reference/program-addresses for the three program IDs.Setup
Demos here mirror files inraydium-sdk-V2-demo/src/farm. Bootstrap follows the demo repo’s config.ts.template:
Fetch a farm by id
getFarmById pulls FarmState off-chain, decodes per program version, and normalizes the fixed-point emission rate into a plain Decimal per second.
Stake LP tokens
Source:src/farm/stake.ts
Claim-only (harvest)
Source:src/farm/harvest.ts
harvestAllRewards accepts a list — for UIs showing a portfolio view, batch the call. Each farm is claimed in a separate instruction within one transaction (subject to the 1232-byte size limit; for >~6 farms, split into multiple transactions).
For a single farm on v6, you can also use the explicit Harvest path:
amount: 0 idiom is required; the SDK dispatches it correctly.
Unstake
Source:src/farm/unstake.ts
Create a v6 farm
Source:src/farm/createAmmFarm.ts and editAmmFarm.ts
perSecondis the integer emission rate per second. The SDK packs it into Q64.64 before sending. For a fractional rate, scale and adjust duration.- The full budget (
perSecond × duration) must be present in your reward ATA —createmoves it into the reward vault atomically. - You can seed up to 5 rewards in one
createcall. The account list grows by(reward_mint, reward_vault, sender_ata, token_program)per extra stream; stay aware of the 1232-byte transaction size limit. For 4+ rewards, create with 1–2 and useAddRewardin follow-up transactions.
Top up an existing reward stream
setRewards extends end_time and transfers the delta budget. The instruction cannot shorten a stream, cannot lower per_second on a live stream, and cannot change the reward mint. To swap mints, wait for end_time and use AddReward on a freed slot (if any), or create a new farm.
Restart a finished stream
reward_state == 2 (ended). The caller must be the slot’s reward_sender (v6) or the farm owner (v5).
Rust CPI
Unlike AMM v4, the v6 farm program ships with an Anchor crate (raydium_farm_v6) published alongside the frontend and SDK sources. A minimal Deposit sketch:
remaining_accounts slice must match the farm’s active reward slots 1-for-1 (pairs of reward_vault_i, user_reward_ata_i in index order). Omitting or misordering these produces a silent mis-accounting — the program will transfer the wrong amount.
Pitfalls
- Forgetting to claim before withdrawing. Harmless —
Withdrawsettles pending rewards first. But if your UI shows “claim” separately from “withdraw”, the user may think there is still something to claim after aWithdraw. There is not; everything accrued up to that point was paid out. total_staked = 0during emissions. Emissions accrued while nothing was staked are forfeited (thereward_per_shareupdate formula divides by 0 and the program skips the update). For programs with scheduledopen_time, run a “seed stake” at open_time to avoid this.- Token-2022 transfer fees. On v6 farms with Token-2022 reward mints, the transfer fee applies on emit (vault → user). Factor this into APR quotes.
- Small
per_secondon v5. v5’su64rate means anyper_second < 1token-unit per second (on mints with ≥9 decimals this is often the desired rate) cannot be expressed — the stream rate rounds to 0 and the farm emits nothing. Use v6.
Where to go next
products/farm-staking/instructions— underlying instruction reference.products/clmm/fees— compare to CLMM’s native reward streams.user-flows/migrate-amm-v4-to-cpmm— often paired with spinning up a new CPMM farm.
- Raydium SDK v2
- Farm v6 IDL bundled in
raydium-io/raydium-sdk-V2undersrc/raydium/farm/.

