Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
CPI («cross-program invocation» — кросс-программный вызов) — это механизм, посредством которого одна программа Solana вызывает другую. Большинство программ Raydium поставляются с крейтами-обёртками Anchor CPI, которые делают место вызова похожим на типизированный вызов функции с структурами аккаунтов, имеющими проверенные имена полей и помощники
cpi::<ix>(). На этой странице один раз документируется общий паттерн, затем описываются различия для каждой программы. Для работающих примеров на TypeScript см. страницу code-demos в главе каждого продукта.Какой паттерн применяется к какой программе
Если вы интегрируете CPMM, CLMM или LaunchLab, сначала прочитайте общий паттерн, затем перейдите к разделу вашей программы для списка аккаунтов и любых различий. Farm v6 и AMM v4 достаточно отличаются, чтобы их разделы стоило читать отдельно.
Зависимости Cargo
branch = "master" отслеживает последний опубликованный исходный код; закрепите конкретный rev = "<commit>", если вам нужна воспроизводимая сборка. Это рекомендуется после прототипирования, так как изменение макета аккаунта на master разломает вашу сборку без предупреждения.
Флаг функции cpi заставляет крейты компилироваться только в поверхность CPI (структуры аккаунтов + вызыватели), а не в полную программу, поэтому ваш бинарный файл остаётся маленьким.
anchor-lang / anchor-spl должны совпадать с тем, что закрепляет целевой крейт:
Для работающих примеров 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 следует идентичной структуре с другим списком аккаунтов и требованием remaining-accounts. 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> и передайте его как input_token_program/output_token_program этой стороны в вызове CPI ниже вместо token_program.
Построение вызова CPI
Anchor генерирует один помощник на инструкцию вместе со структурой CPI-аккаунтов (cpi::accounts::Swap, ниже обозначена как CpmmSwap). В отличие от вашей структуры MyProxySwap выше, имена и порядок полей этой структуры фиксированы IDL самого raydium-cp-swap и должны совпадать точно:
cpi::swap_base_input генерируется из IDL; его список аргументов зеркалирует список аргументов инструкции Anchor. Каждая подтверждённая программа Raydium на основе Anchor (CPMM, CLMM, LaunchLab) генерирует свои помощники cpi::<ix>() одинаково, с именем функции, совпадающим с именем инструкции в snake_case. Распространяется ли это на Farm v6, неподтверждено; см. его раздел.
Signer seeds (PDA-подписанный CPI)
Когда ваша программа подписывает CPI от имени PDA (обычно для хранилищ, escrow и т. д.), используйтеCpiContext::new_with_signer:
authority (или аналогичная роль подписывающего), Solana runtime проверяет, что PDA подписывает через эти seeds.
Remaining accounts
Некоторые инструкции Raydium принимают remaining accounts — список переменной длины, добавляемый после фиксированных аккаунтов. Помощники CPI Anchor не проверяют типы remaining accounts; передавайте их через.with_remaining_accounts(...):
- CLMM
SwapV2: tick arrays, упорядочены по направлению. - Farm v6: пары
(reward_vault, user_reward_ata), но только со второго потока вознаграждения и далее; см. Farm v6 для того, что показывает декодирование реальной транзакции.
Применение паттерна: CLMM
SwapV2 следует общему паттерну выше с другим списком аккаунтов и требованием remaining-accounts для tick arrays. Модуль #[program] крейта называется raydium_clmm, что также является его путём Rust use.
TickArrayNotFound (см. products/clmm/instructions для полной таблицы аккаунтов и списка ошибок). Передавайте их в направлении обхода цены: первый массив в направлении swap первым.
Применение паттерна: LaunchLab
LaunchLab построен на Anchor и опубликован в IDL:raydium_launchpad/raydium_launchpad.json в публичном репозитории raydium-idl. Внутренний идентификатор метаданных этого IDL — raydium_launchpad, техническое имя базовой программы, а не альтернативное название продукта. В отличие от CPMM и CLMM, исходный код самой программы не является публичным (см. reference/program-addresses). Нет зависимости git = "..." для Cargo и нет исходного кода, чтобы подтвердить, какой был бы реальный путь Rust use в крейте.
Генерируйте привязки из опубликованного IDL, используя макрос Anchor declare_program!. Сохраните JSON IDL как idls/raydium_launchpad.json в вашем крейте (Cargo ищет директорию idls/ относительно CARGO_MANIFEST_DIR), затем declare_program!(raydium_launchpad); генерирует структуры raydium_launchpad::cpi::accounts::<Ix> и функции cpi::<ix>() прямо из IDL, без исходного кода программы. Имя сгенерированной структуры accounts всегда — имя инструкции в PascalCase (buy_exact_in → BuyExactIn), а имена полей совпадают с именами accounts в IDL ровно, тот же список accounts, что уже используется в MyProxyBuy ниже.
Форма CPI следует общему паттерну. Список accounts и аргументы ниже взяты из инструкции buy_exact_in в IDL на цепи, а не из products/launchlab/instructions.mdx:
pool_state.migrate_type, который согласно products/launchlab/accounts.mdx устанавливается во время Initialize. Ваш список accounts для CPI должен быть подготовлен для обоих вариантов, или вам нужно сначала прочитать migrate_type из PoolState и разветвиться.
Распространение ошибок
Каждая программа Raydium на основе Anchor возвращает собственный enum ошибок; Anchor оборачивает их, поэтому вызывающая программа видит их какErr(ProgramError::Custom(code)). Для обработки конкретных ошибок:
raydium_clmm::error::ErrorCode для CLMM и так далее). Номера кодов ошибок стабильны согласно политике IDL (sdk-api/anchor-idl), поэтому вы можете проверять конкретные коды, сравнивая с числовым значением. Полные таблицы ошибок: CPMM, CLMM, AMM v4, Farm v6 и LaunchLab.
Бюджет вычислений в составных CPI
Каждый CPI фрейм имеет накладные расходы, и собственное потребление CU вызываемой программы складывается с вашим, поэтому транзакция, которая вызывает Raydium изнутри вашей программы, требует явного бюджета вычислений вместо полагания на стандартный лимит 200k CU.Измеренные, не оценённые значения. CPMM
swap_base_input в mainnet потребляет ~23 000 CU в самой программе CPMM — выборка от 2026-09-09 по восьми живым свопам в пуле с высоким объёмом (22 721–23 052), прочитано из строки лога Program CPMMoo8… consumed N of M compute units. Для сравнения: AMM v4 swap ~26 000; CLMM swap ~41 000; CLMM swap_v2 ~48 000 (43 838–52 887), растёт с каждым пересечением тика.Более ранняя версия этой страницы сообщала ~47 700 CU для CPI прокси-свопа. Это число было для всей транзакции (computeUnitsConsumed), что включает вашу собственную программу, CPI фрейм и любую настройку ATA — не стоимость вызываемой программы. Оба полезны, но это не одно и то же число, поэтому сравнивайте подобное с подобным. Измеряйте вашу собственную транзакцию вместо бюджетирования по любому из них.remaining_accounts, добавляя CU за каждый массив), но только приведённое выше значение для CPMM — это измеренное значение. Всегда устанавливайте явный лимит ComputeBudgetProgram::set_compute_unit_limit(...) на основе вашего собственного измерения, а не числа, скопированного из документации, так как стандартный лимит 200k CU будет молча исчерпан, а затраты на инструкцию смещаются при обновлении программ.
AMM v4: ручное построение Instruction
AMM v4 предшествует Anchor и не имеет CPI крейта, что делает его единственной программой в этом документе, которая не следует общему паттерну выше. ПостройтеInstruction вручную:
products/amm-v4/code-demos.
Farm v6
Используйте TS SDK, если это вариант для вашей интеграции.raydium.farm.deposit(...) (см. products/farm-staking/code-demos) проверена реальными демонстрациями и не зависит от того, существует ли крейт Rust Anchor для этой программы.
Если вам всё же нужен Rust CPI, например при составлении из другой программы на цепи, постройте Instruction вручную, так же как AMM v4: выведите реальный список accounts и дискриминаторы инструкций независимо, например декодируя макеты TypeScript SDK (raydium-sdk-V2’s farm модуль), декодируя реальные транзакции напрямую (см. ниже) или дампируя и дизассемблируя развёрнутую программу.
Для формы инструкции без аргументов, согласованной с вызовом harvest или claim, реальный порядок accounts — это фиксированный префикс (token_program, аккаунт состояния фермы, PDA органа-хранилища, первое хранилище вознаграждения этого PDA, второй PDA, вызывающий, и ATA вызывающего для первого mint вознаграждения), за которым следуют пары (reward_vault_i, user_reward_ata_i) в remaining_accounts для каждого потока вознаграждения после первого. Соглашение о парировании реально, но оно начинается только со второго потока вознаграждения: хранилище и ATA первого потока — это фиксированные accounts, не смежные друг с другом и вообще не являются частью remaining_accounts.
Тестирование потока CPI
Для локальной разработки требуется, чтобы программы Raydium были доступны в вашем локальном валидаторе. Есть три варианта:anchor testс клонированием программы. Загружает развёрнутый на мейннете байт-код в локальный валидатор; см. раздел Клонирование программ в локальный валидатор ниже для конфигурацииAnchor.tomlи двух моментов, которые часто вызывают проблемы при тестировании создания пула.- Devnet. Raydium развёртывает большинство программ на devnet, но с другими ID программ, чем на мейннете для каждой программы (CPMM, CLMM, AMM v4, Stable AMM и LaunchLab имеют отдельные адреса на devnet; см. таблицу Devnet в
reference/program-addresses). Farm v3/v5/v6 не всегда публикуются на devnet; текущую информацию можно найти в live API (https://api-v3-devnet.raydium.io/main/info). Если вы используете встроенные константыDEVNET_PROGRAM_IDизraydium_clmm(или эквивалент для других крейтов), не предполагайте, что 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 и регенерация клиента, включая путь IDL-codegen для LaunchLab.integration-guides/cpi-integration: высокоуровневые паттерны интеграции, такие как escrows, vaults и композиция агрегаторов.
- raydium-cp-swap
- raydium-clmm
- raydium-idl: IDL LaunchLab (исходный код программы закрыт)
- Anchor CPI docs

