Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
バージョン情報。 すべてのコード例は @raydium-io/raydium-sdk-v2@0.2.42-alpha を対象としており、Solana mainnet-beta で動作確認されています(2026 年 4 月時点)。SDK は内部的にファームのプログラム所有者に基づいて v3 / v5 / v6 をディスパッチします。以下の例は v6 ファームを想定しています。reference/program-addresses で 3 つのプログラム ID を確認してください。
セットアップ
このセクションのコード例は raydium-sdk-V2-demo/src/farm のファイルを反映しています。ブートストラップは デモリポジトリの config.ts.template に従います:
import { Connection, Keypair, clusterApiUrl, PublicKey } from "@solana/web3.js";
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";
import fs from "node:fs";
const connection = new Connection(process.env.RPC_URL ?? clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync(process.env.KEYPAIR!, "utf8"))),
);
const raydium = await Raydium.load({
owner,
connection,
cluster: "mainnet",
disableFeatureCheck: true,
blockhashCommitment: "finalized",
});
export const txVersion = TxVersion.V0;
ID でファームを取得
const farmId = new PublicKey("<FARM_ID>");
const farm = await raydium.farm.getFarmById({ farmId });
console.log("Staking mint:", farm.symbolMint.toBase58());
console.log("Total staked:", farm.totalStaked.toString());
console.log("Rewards:");
for (const r of farm.rewardInfos) {
console.log(
" -", r.mint.toBase58(),
"rate(1e-" + r.decimals + "/s):", r.perSecond.toString(),
"open:", new Date(r.openTime * 1000).toISOString(),
"end: ", new Date(r.endTime * 1000).toISOString(),
);
}
getFarmById は FarmState をオンチェーンから取得し、プログラムバージョンに応じてデコードして、固定小数点の発行レートを 1 秒あたりの純粋な Decimal に正規化します。
LP トークンをステーク
ソース:src/farm/stake.ts
const amount = new BN(1_000_000_000); // 1 LP (assuming 9 decimals)
const { execute } = await raydium.farm.deposit({
farmInfo: farm,
amount,
txVersion: TxVersion.V0,
});
const { txId } = await execute({ sendAndConfirm: true });
console.log("Deposit tx:", txId);
SDK は保留中の報酬の事前決済を処理するため、このウォレットがこのファームに既にステークを持っている場合、命令は同じトランザクション内でユーザーの ATA に累積報酬を支払います。
報酬の請求のみ(ハーベスト)
ソース:src/farm/harvest.ts
const { execute } = await raydium.farm.harvestAllRewards({
farmInfoList: [farm],
txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
harvestAllRewards はリストを受け付けます。ポートフォリオビューを表示する UI の場合、呼び出しをバッチ処理してください。各ファームは 1 つのトランザクション内で個別の命令で請求されます(1232 バイトの制限に従うため、6 個を超えるファームの場合は複数のトランザクションに分割してください)。
v6 の単一ファームでは、明示的な Harvest パスも使用できます:
const { execute } = await raydium.farm.withdraw({
farmInfo: farm,
amount: new BN(0), // 0 = harvest-only path, even on v6
txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
v3 および v5 では amount: 0 のイディオムが必須です。SDK は正しくディスパッチします。
ステークを解除
ソース:src/farm/unstake.ts
const amount = new BN(500_000_000); // 0.5 LP
const { execute } = await raydium.farm.withdraw({
farmInfo: farm,
amount,
txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
v6 ファームを作成
ソース:src/farm/createAmmFarm.ts および editAmmFarm.ts
import { CurveCalculator } from "@raydium-io/raydium-sdk-v2"; // optional, for APR planning
const stakingMint = new PublicKey("<LP_MINT>"); // e.g. a CPMM LP mint
const rewardMint = new PublicKey("<REWARD_MINT>"); // e.g. your project's token
const now = Math.floor(Date.now() / 1000);
const openTime = now + 60 * 60; // start in 1h
const duration = 60 * 60 * 24 * 30; // 30 days
const endTime = openTime + duration;
const totalBudget = new BN(1_000_000).mul(new BN(10).pow(new BN(9))); // 1M reward tokens (9 dec)
const perSecond = totalBudget.div(new BN(duration)); // integer, SDK lifts to Q64.64
const { execute, extInfo } = await raydium.farm.create({
programId: /* v6 program ID, from reference/program-addresses */,
poolInfo: { lpMint: { address: stakingMint, decimals: 9, programId: /* SPL Token */ } as any },
rewardInfos: [
{
mint: rewardMint,
openTime: new BN(openTime),
endTime: new BN(endTime),
perSecond,
rewardSender: owner.publicKey, // who pays the initial budget
mintProgramId: /* SPL Token or Token-2022 */,
},
],
txVersion: TxVersion.V0,
});
const { txId } = await execute({ sendAndConfirm: true });
console.log("Farm:", extInfo.farmId.toBase58(), "createTx:", txId);
重要なポイント:
perSecond は 1 秒あたりの整数発行レートです。SDK はこれを Q64.64 にパックして送信します。小数レートの場合、スケーリングして期間を調整してください。
- 完全な予算(
perSecond × duration)は報酬 ATA に存在する必要があります。create はこれをアトミックに報酬ボールトに移動させます。
- 1 つの
create 呼び出しで最大 5 つの報酬をシードできます。アカウントリストは追加ストリームごとに (reward_mint, reward_vault, sender_ata, token_program) だけ増加します。1232 バイトのトランザクションサイズ制限に注意してください。4 個以上の報酬の場合は、1~2 個で作成し、後続のトランザクションで AddReward を使用してください。
既存の報酬ストリームを補充
const additionalDays = 30;
const extraSeconds = 60 * 60 * 24 * additionalDays;
const extraBudget = perSecond.mul(new BN(extraSeconds));
const { execute } = await raydium.farm.setRewards({
farmInfo: farm,
rewardInfos: [
{
rewardMint: rewardMint,
newEndTime: new BN(farm.rewardInfos[0].endTime + extraSeconds),
newPerSecond: perSecond, // keep same rate
payer: owner.publicKey,
},
],
txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
setRewards は end_time を延長し、差額の予算を転送します。この命令はストリームを短縮することはできず、ライブストリームで per_second を低下させることはできず、報酬ミントを変更することはできません。ミントを交換するには、end_time まで待機して、解放されたスロット(存在する場合)で AddReward を使用するか、新しいファームを作成してください。
終了したストリームを再開
const { execute } = await raydium.farm.restartRewards({
farmInfo: farm,
newRewardInfo: {
rewardMint: rewardMint,
openTime: new BN(Math.floor(Date.now() / 1000) + 60 * 60),
endTime: new BN(Math.floor(Date.now() / 1000) + 60 * 60 + 60 * 60 * 24 * 14),
perSecond: new BN("1000000000"),
payer: owner.publicKey,
},
txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
対象スロットの reward_state == 2(終了)の場合にのみ有効です。呼び出し元はスロットの reward_sender(v6)またはファーム所有者(v5)である必要があります。
Rust CPI
AMM v4 とは異なり、v6 ファームプログラムは Anchor クレート(raydium_farm_v6)を同梱して出荷され、フロントエンドおよび SDK ソースと共に公開されています。最小限の Deposit スケッチ:
use anchor_lang::prelude::*;
use raydium_farm_v6::{self, cpi::accounts::Deposit as RaydiumDeposit};
#[derive(Accounts)]
pub struct ProxyFarmDeposit<'info> {
/// CHECK:
pub farm_program: UncheckedAccount<'info>,
#[account(mut)] pub user: Signer<'info>,
#[account(mut)] /// CHECK:
pub user_ledger: UncheckedAccount<'info>,
#[account(mut)] /// CHECK:
pub farm_state: UncheckedAccount<'info>,
/// CHECK:
pub farm_authority: UncheckedAccount<'info>,
#[account(mut)] /// CHECK:
pub staking_vault: UncheckedAccount<'info>,
#[account(mut)] /// CHECK:
pub user_staking_ata: UncheckedAccount<'info>,
// Followed in remaining_accounts by (reward_vault_i, user_reward_ata_i) pairs
// for each live reward stream on the farm.
pub token_program: UncheckedAccount<'info>,
pub system_program: Program<'info, System>,
}
pub fn proxy_deposit<'info>(
ctx: Context<'_, '_, '_, 'info, ProxyFarmDeposit<'info>>,
amount: u64,
) -> Result<()> {
let cpi_ctx = CpiContext::new(
ctx.accounts.farm_program.to_account_info(),
RaydiumDeposit {
user: ctx.accounts.user.to_account_info(),
user_ledger: ctx.accounts.user_ledger.to_account_info(),
farm_state: ctx.accounts.farm_state.to_account_info(),
farm_authority: ctx.accounts.farm_authority.to_account_info(),
staking_vault: ctx.accounts.staking_vault.to_account_info(),
user_staking_ata: ctx.accounts.user_staking_ata.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
},
).with_remaining_accounts(ctx.remaining_accounts.to_vec());
raydium_farm_v6::cpi::deposit(cpi_ctx, amount)
}
remaining_accounts スライスはファームのアクティブな報酬スロットと 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 転送手数料。 v6 ファームで Token-2022 報酬ミントの場合、転送手数料は発行時に適用されます(ボールト → ユーザー)。これを APR 見積もりに組み入れてください。
- v5 での小さい
per_second。 v5 の u64 レートは per_second < 1 トークン単位/秒(小数点以上 9 桁のミントでは、これが望ましいレートであることが多い)が表現できないことを意味します。ストリームレートは 0 に丸められ、ファームは何も発行しません。v6 を使用してください。
次のステップ
ソース: