本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
版本说明。 所有示例针对
@raydium-io/raydium-sdk-v2@0.2.64-alpha 在 Solana mainnet-beta 上运行,验证时间 2026-09-09 — 下面的每个构建器名称、参数名称和参数类型都已对照该版本的 src/raydium/farm/ 和 raydium-sdk-V2-demo/src/farm 进行了检查。SDK 根据 farm 的程序所有者在内部分发 v3 / v5 / v6;下面的示例假设为 v6 farm。有关三个程序 ID,请参阅 reference/program-addresses。farm 模块的方法名称不是你想象的那样:没有 getFarmById,也没有 setRewards。获取通过 raydium.api.fetchFarmInfoById 进行,奖励编辑构建器是 addNewRewardToken / addNewRewardsToken 和 restartReward / restartRewards。设置
这里的示例镜像raydium-sdk-V2-demo/src/farm 中的文件。引导程序遵循演示仓库的 config.ts.template:
按 ID 获取 farm
没有raydium.farm.getFarmById。每个 farm 示例都从 API 模块开始,它返回规范化的 FormatFarmInfoOut 形状,deposit / withdraw / harvestAllRewards 都接受这种形状:
fetchFarmInfoById 接受一个 逗号分隔的 ID 字符串 并返回一个数组,因此一次调用可以获取整个投资组合。如果你需要原始账户密钥而不是显示信息,raydium.api.fetchFarmKeysById({ ids }) 返回金库和权限 PDA;SDK 在下面每个构建器内部为你调用它。
质押 LP 代币
来源:src/farm/stake.ts
仅领取(收获)
来源:src/farm/harvest.ts
farmInfoList 是一个 按 farm ID 键入的 Record,不是数组,构建器返回 多个 交易 — 因此 execute 必须给定 sequentially: true:
txIds 而不是单个 txId。
对于单个 farm,使用 amount: 0 习语进行收获 — 这是 src/farm/harvest.ts 所做的,包括 v6 在内的每个版本:
取消质押
来源:src/farm/unstake.ts
创建 v6 farm
来源:src/farm/createAmmFarm.ts 和 editAmmFarm.ts
create 接受 pool 信息对象,用于其 LP mint 被质押的 pool(不是裸 mint),rewardInfos 的每个条目都是 FarmRewardInfo:{ mint: PublicKey, perSecond: string, openTime: number, endTime: number, rewardType: "Standard SPL" | "Option tokens" }。时间是 纯秒数,perSecond 是 字符串,不是 BN。programId 默认为 v6 程序,所以你很少传递它。
perSecond是每秒的发放速率,以奖励 mint 的 原始 单位表示,作为十进制字符串传递。SDK 在发送前将其打包到链上定点表示中。- 完整预算(
perSecond × (endTime − openTime))必须存在于你的奖励 ATA 中 —create以原子方式将其移入奖励金库。 - 此 SDK 版本的 farm 构建器不支持 Token-2022 奖励 mint;对奖励使用普通 SPL mint。
- 你可以在一个
create调用中设置最多 5 个奖励。账户列表按每个额外流增长(reward_mint, reward_vault, sender_ata, token_program);注意 1232 字节交易大小限制。对于 4+ 个奖励,使用 1–2 个创建,然后在后续交易中使用addNewRewardsToken。
添加新的奖励流
没有raydium.farm.setRewards。改变 farm 奖励的两个构建器是 addNewRewardToken / addNewRewardsToken(用 新 mint 占据一个空闲槽位)和 restartReward / restartRewards(重新启动流已结束的槽位)。两者都接受 create 使用的完全相同形状的 FarmRewardInfo 对象。
perSecond × duration)作为交易的一部分从支付者的 ATA 中提取。底层指令不能缩短流、不能降低活跃流上的 per_second、不能改变槽位的奖励 mint — 要交换 mint,请等待 end_time 并在释放的槽位上使用 addNewRewardsToken,或创建新 farm。
重启已完成的流
来源:src/farm/editAmmFarm.ts
restartRewards 接受 newRewardInfos(复数,一个数组);restartReward 是单项形式,接受 newRewardInfo。mint 字段是 mint,不是 rewardMint,它必须匹配 farm 上已存在的槽位 — 构建器按 mint 查找槽位,如果不存在则报错。
restartRewards 是 仅 v6 — 构建器读取 farm 的程序 ID,对 v3 / v5 farm 抛出错误。仅在目标槽位的 reward_state == 2(已结束)时有效;调用者必须是槽位的 reward_sender。注意 openTime >= endTime 在进行任何 RPC 之前被客户端拒绝。
Rust CPI
Farm v6 最后部署于 2024-05-13,从集成者的角度来看不是 Anchor 程序。如果你需要从自己的链上程序与其组合,手动构造Instruction — 独立派生账户列表和指令判别器(从 SDK 的 TypeScript 布局在 raydium-sdk-V2/src/raydium/farm/ 下,或通过解码真实交易),然后 invoke_signed 它。有关该过程,请参阅 sdk-api/rust-cpi。
无论你采取哪条路线,remaining_accounts 尾部必须与 farm 的活跃奖励槽位 1 对 1 匹配(按索引顺序的 reward_vault_i、user_reward_ata_i 对)。省略或错误排序这些会产生无声的错误计算 — 程序将转移错误的金额。
陷阱
- 取消质押前忘记领取。 无害 —
Withdraw首先结算待处理奖励。但如果你的 UI 将”领取”与”取消质押”分开显示,用户可能会认为在Withdraw后仍有东西可以领取。没有;直到那一点累积的所有东西都已支付。 - 发放期间
total_staked = 0。 在没有质押任何东西时累积的发放被没收(reward_per_share更新公式除以 0,程序跳过更新)。对于有计划open_time的程序,在 open_time 运行”种子质押”以避免这种情况。 - Token-2022 转账费用。 在具有 Token-2022 奖励 mint 的 v6 farm 上,转账费用适用于发放(金库 → 用户)。将其纳入 APR 报价中。
- v5 上的小
per_second。 v5 的u64速率意味着任何per_second < 1代币单位每秒(在具有 ≥9 位小数的 mint 上,这通常是所需速率)无法表示 — 流速率舍入为 0,farm 不发放任何东西。使用 v6。
接下来去哪里
products/farm-staking/instructions— 底层指令参考。products/clmm/fees— 与 CLMM 的原生奖励流进行比较。user-flows/migrate-amm-v4-to-cpmm— 通常与启动新 CPMM farm 配对。
- Raydium SDK v2
- Farm v6 IDL 捆绑在
raydium-io/raydium-sdk-V2中的src/raydium/farm/下。

