Skip to main content
本页内容由 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
SDK 处理任何待处理奖励的预结算,因此如果此钱包已在此 farm 中有质押,指令将在同一交易中向用户的 ATA 支付累积的奖励。

仅领取(收获)

来源:src/farm/harvest.ts farmInfoList 是一个 按 farm ID 键入的 Record,不是数组,构建器返回 多个 交易 — 因此 execute 必须给定 sequentially: true:
构建器在 1232 字节限制允许的范围内尽可能多地打包每个交易中的 farm,并将其余的分成后续交易,这就是为什么它返回 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。
restartRewards 和 addNewRewardsToken 各自返回一个构建器,因此单个交易可以同时执行两者。src/farm/editAmmFarm.ts 展示了该模式:editFarmBuilder.builder.addInstruction(addNewRewardBuildData.builder.AllTxData),然后一个 versionBuild({ txVersion })。

重启已完成的流

来源: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

没有 raydium_farm_v6 Anchor crate。 crates.io 上不存在该名称的 crate,Farm v6 程序不发布链上 IDL(既没有旧版 anchor:idl 账户,也没有程序元数据程序中的条目),不存在公开源代码仓库。本页的早期版本显示了 raydium_farm_v6::cpi::deposit 示例;它没有针对任何东西编译,已被删除。
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。

接下来去哪里

来源: