本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
CPI(「跨程式呼叫」)是一個 Solana 程式呼叫另一個程式的機制。Raydium 的大多數程式都提供 Anchor CPI 包裝 crate,使呼叫位置看起來像一個型別化的函式呼叫,具有經過驗證的欄位名稱的帳戶結構和
cpi::<ix>() 輔助程式。本頁記錄了一般模式,然後是各程式的差異。如需可執行的 TypeScript,請參閱每個產品章節的 code-demos 頁面。哪個模式適用於哪個程式
如果你正在整合 CPMM、CLMM 或 LaunchLab,請先閱讀一般模式,然後跳到你的程式章節以了解帳戶列表和任何差異。Farm v6 和 AMM v4 的差異足夠大,值得獨立閱讀其章節。
Cargo 依賴
branch = "master" 追蹤最新發佈的原始碼;如果你需要可重現的構建,請固定到特定的 rev = "<commit>"。一旦你超過原型設計階段,這是推薦的做法,因為上游在 master 上的帳戶佈局變更將無警告地破壞你的構建。
cpi 功能標誌使 crate 編譯為僅 CPI 表面(帳戶結構 + 呼叫程式),而不是完整程式,因此你的二進位檔案保持較小。
anchor-lang / anchor-spl 必須與目標 crate 固定的相符:
如需端到端連接帳戶結構的可執行 CPI 範例,請參閱
raydium-io/raydium-cpi-example(涵蓋 AMM v4、CPMM 和 CLMM)。其最新分支是 anchor-0.31.0 — 還沒有 Anchor 1.x 分支,所以將該倉庫視為帳戶結構連接的參考,而不是本頁規定的版本固定。
通用 Anchor CPI 模式
本節以 CPMM 為完整範例逐步說明:Accounts 結構、CpiContext、cpi::<ix>()。CLMM 遵循相同的模式,但帳戶清單不同且需要剩餘帳戶。LaunchLab 遵循相同的機制,但其帳戶清單包含多個 CPMM/CLMM 沒有的帳戶(global_config、platform_config、event_authority、program),因此應將其視為相同的模式而非相同的結構。請參閱各程式的專屬章節,而不要假設本逐步說明的帳戶清單可直接轉移。
帳戶清單構建
每個 Raydium CPI 都需要在呼叫程式中有一個Accounts 結構。其欄位是你的指令所需的任何帳戶,並帶有欄位級驗證器;它們的宣告順序不必與 Raydium 自身的指令帳戶順序相符,因為你自己的 IDL 生成客戶端按名稱而非位置來尋址它們:
UncheckedAccount,因為被呼叫者(Raydium)負責驗證。你的呼叫程式只需嚴格驗證你擁有的帳戶,例如使用者 ATA 和你自己的 PDA。/// CHECK: 文件註解會抑制 Anchor 關於缺少檢查的警告。唯一的 Raydium 端例外是 cpmm_program 本身:它是被呼叫的程式而非 Raydium 內部驗證的資料帳戶,因此它被型別化為 Program<T> 並獲得 Anchor 的自動位址檢查,而不是手動的 /// CHECK:。這種大多為 UncheckedAccount 的形狀(Raydium 驗證自己的帳戶)對 CLMM 和 LaunchLab 也是相同的。本範例假設兩個 mint 都是經典 SPL Token;如果任一方可以是 Token-2022 mint,請新增 token_program_2022: Program<'info, anchor_spl::token_2022::Token2022> 欄位,並在下面的 CPI 呼叫中將其作為該方的 input_token_program/output_token_program 傳遞,而不是 token_program。
構建 CPI 呼叫
Anchor 為每個指令生成一個輔助函式,以及一個 CPI 帳戶結構(cpi::accounts::Swap,下面別名為 CpmmSwap)。與上面你自己的 MyProxySwap 結構不同,這個結構的欄位名稱和順序由 raydium-cp-swap 自身的 IDL 固定,必須完全相符:
cpi::swap_base_input 由 IDL 生成;其引數清單鏡像 Anchor 指令的引數清單。每個已確認的基於 Anchor 的 Raydium 程式(CPMM、CLMM、LaunchLab)都以相同方式生成其 cpi::<ix>() 輔助函式,函式名稱與指令名稱以蛇形命名法相符。這是否擴展到 Farm v6 尚未確認;請參閱其章節。
簽署者種子(PDA 簽署的 CPI)
當你的程式代表 PDA 簽署 CPI 時(對於保管庫、託管等很常見),使用CpiContext::new_with_signer:
authority(或類似簽署者角色)傳遞的任何帳戶,Solana 執行時會檢查 PDA 是否透過這些種子簽署。
剩餘帳戶
某些 Raydium 指令採用剩餘帳戶,這是附加在固定帳戶之後的可變長度清單。Anchor 的 CPI 輔助函式不對剩餘帳戶進行型別檢查;透過.with_remaining_accounts(...) 傳遞它們:
- CLMM
SwapV2:tick 陣列,按方向排序。 - Farm v6:
(reward_vault, user_reward_ata)對,但僅從第二個獎勵流開始;請參閱 Farm v6 以了解實際交易解碼顯示的內容。
應用模式:CLMM
SwapV2 遵循上面的通用模式,但帳戶清單不同,且需要 tick 陣列的剩餘帳戶。該 crate 的 #[program] 模組名為 raydium_clmm,這也是其 Rust use 路徑。
TickArrayNotFound 回復(請參閱 /zh-Hant/products/clmm/instructions 以取得完整帳戶表和錯誤清單)。按價格走向的方向傳遞它們:交換方向的第一個陣列優先。
應用模式:LaunchLab
LaunchLab 基於 Anchor 並發佈了 IDL:公開raydium-idl 儲存庫中的 raydium_launchpad/raydium_launchpad.json。該 IDL 的內部元資料識別符是 raydium_launchpad,這是底層程式的技術名稱,而非產品的替代名稱。不過,與 CPMM 和 CLMM 不同的是,該程式的原始碼並未公開(見 reference/program-addresses)。沒有 git = "..." 依賴項指向 Cargo,也沒有原始碼可確認真實 crate 的 Rust use 路徑會是什麼。
使用 Anchor 的 declare_program! 巨集從已發佈的 IDL 生成繫結。將 IDL JSON 儲存為 crate 中的 idls/raydium_launchpad.json(Cargo 會在相對於 CARGO_MANIFEST_DIR 的 idls/ 目錄中查找),然後 declare_program!(raydium_launchpad); 會直接從 IDL 生成 raydium_launchpad::cpi::accounts::<Ix> 結構體和 cpi::<ix>() 函式,無需程式原始碼。生成的帳戶結構體名稱始終是 PascalCase 格式的指令名稱(buy_exact_in → BuyExactIn),欄位名稱與 IDL 的帳戶名稱完全相符,與下面 MyProxyBuy 中已使用的帳戶清單相同。
CPI 形狀遵循通用模式。下面的帳戶清單和引數來自鏈上 IDL 的 buy_exact_in 指令,而非 products/launchlab/instructions.mdx:
pool_state.migrate_type,products/launchlab/accounts.mdx 說該值在 Initialize 時設定。你的 CPI 帳戶清單必須為兩者做好準備,或者你需要先從 PoolState 讀取 migrate_type 並進行分支。
錯誤傳播
每個基於 Anchor 的 Raydium 程式都會返回自己的錯誤列舉;Anchor 會包裝它們,所以你的呼叫程式會看到Err(ProgramError::Custom(code))。要處理特定錯誤:
raydium_clmm::error::ErrorCode,以此類推)。根據 IDL 政策(sdk-api/anchor-idl),錯誤代碼編號在每個程式中是穩定的,所以你可以通過與數值進行比較來測試特定代碼。完整錯誤表:CPMM、CLMM、AMM v4、Farm v6 和 LaunchLab。
組合 CPI 中的計算預算
每個 CPI 框架都有開銷,被呼叫者自己的 CU 消耗會疊加在你的之上,所以從你的程式內部呼叫到 Raydium 的交易需要明確的計算預算,而不是依賴 200k CU 的預設值。實測,非估計。 主網上的 CPMM
swap_base_input 在 CPMM 程式本身中消耗 約 23,000 CU — 2026-09-09 在高交易量池上的八次實時交換中採樣(22,721–23,052),從 Program CPMMoo8… consumed N of M compute units 日誌行讀取。相比之下:AMM v4 交換約 26,000;CLMM swap 約 41,000;CLMM swap_v2 約 48,000(43,838–52,887),隨著每次 tick 穿越而增加。本頁的早期版本報告代理交換 CPI 約 47,700 CU。該數字是整個交易(computeUnitsConsumed),包括呼叫者自己的程式、CPI 框架和任何 ATA 設定 — 而非被呼叫者的成本。兩者都有用,但它們不是同一個數字,所以要進行類似的比較。根據你自己的測量來衡量你的交易,而不是根據文件中複製的數字進行預算。remaining_accounts 走過額外的 tick 陣列,每個陣列增加 CU),但上面只有 CPMM 數字是實測值。始終根據你自己的測量設定明確的 ComputeBudgetProgram::set_compute_unit_limit(...) 指令,而不是從文件中複製的數字,因為預設 200k CU 限制會無聲地耗盡,且隨著程式升級,每條指令的成本會變化。
AMM v4:手動指令構造
AMM v4 早於 Anchor,沒有 CPI crate,使其成為本文件中唯一不遵循上述通用模式的程式。手動構建Instruction:
products/amm-v4/code-demos。
Farm v6
如果這對你的整合是一個選項,請使用 TS SDK。raydium.farm.deposit(...) (見 products/farm-staking/code-demos)由真實示例驗證,不依賴是否存在此程式的 Rust Anchor crate。
如果你無論如何都需要 Rust CPI,例如從另一個鏈上程式進行組合,手動構建 Instruction,方式與 AMM v4 相同:獨立推導真實帳戶清單和指令判別器,例如通過解碼 SDK 的 TypeScript 佈局(raydium-sdk-V2 的 farm 模組)、直接解碼真實交易(見下文),或轉儲和反彙編已部署的程式。
對於與收穫或領取呼叫一致的零引數指令形狀,真實帳戶順序是固定前綴(token_program、farm 的狀態帳戶、vault 授權 PDA、該 PDA 的第一個獎勵 vault、第二個 PDA、呼叫者和呼叫者的該第一個獎勵 mint 的 ATA),後面跟著 remaining_accounts 中的 (reward_vault_i, user_reward_ata_i) 對,用於第一個之後的每個獎勵流。配對慣例是真實的,但它只從第二個獎勵流開始:第一個流的 vault 和 ATA 是固定帳戶,彼此不相鄰,根本不是 remaining_accounts 的一部分。
測試 CPI 流程
本地開發需要 Raydium 程式在你的測試驗證器中可用。有三個選項:- 使用程式複製的
anchor test。 將已部署的主網位元組碼拉入本地驗證器;請參閱下方的將程式複製到本地驗證器,了解Anchor.toml設定以及特別會影響池建立測試的兩個問題。 - Devnet。 Raydium 將大多數程式部署到 devnet,但使用的程式 ID 與主網不同(CPMM、CLMM、AMM v4、Stable AMM 和 LaunchLab 各有不同的 devnet 位址;請參閱
reference/program-addresses中的 Devnet 表格)。Farm v3/v5/v6 在 devnet 上並未可靠地發佈;實時 API(https://api-v3-devnet.raydium.io/main/info)提供當前情況。如果你使用raydium_clmm的內附DEVNET_PROGRAM_ID常數(或其他 crate 的等效項),不要假設主網 ID 也能在 devnet 上運作。一旦你有了正確的位址,執行anchor test --provider.cluster devnet來測試實時程式碼。 - 本地部署。 複製 Raydium 儲存庫(CPMM、CLMM;LaunchLab 的原始碼不適用於此選項)並
anchor deploy到本地驗證器。增加測試週期開銷,但讓你可以修改被呼叫程式以進行除錯。
anchor test 執行,或如果你在迭代測試檔案而不改變程式,先執行 anchor build,然後執行 anchor test --skip-build。
將程式複製到本地驗證器
reference/program-addresses 是所有位址的真實來源。
參考資源
products/cpmm/code-demos、products/clmm/code-demos、products/amm-v4/code-demos、products/farm-staking/code-demos、products/launchlab/code-demos:產品特定的 CPI 和 TypeScript 範例。sdk-api/anchor-idl:IDL 檢索和用戶端重新生成,包括 LaunchLab 的 IDL 代碼生成路徑。integration-guides/cpi-integration:更高層級的整合模式,如託管、金庫和聚合器組合。
- raydium-cp-swap
- raydium-clmm
- raydium-idl:LaunchLab IDL(程式原始碼本身已關閉)
- Anchor CPI 文件

