Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
CPI (« cross-program invocation ») est le mécanisme par lequel un programme Solana en appelle un autre. La plupart des programmes Raydium fournissent des crates CPI wrapper Anchor qui font ressembler le site d’appel à un appel de fonction typée, avec des structs de comptes ayant des noms de champs validés et des helpers
cpi::<ix>(). Cette page documente le motif général une fois, puis les différences par programme. Pour du TypeScript exécutable, consultez la page code-demos de chaque chapitre produit.Quel motif s’applique à quel programme
Si vous intégrez CPMM, CLMM ou LaunchLab, lisez d’abord le motif général, puis passez à la section de votre programme pour la liste des comptes et les différences. Farm v6 et AMM v4 sont suffisamment différents pour justifier la lecture de leurs sections de manière autonome.
Dépendances Cargo
branch = "master" suit la dernière source publiée ; épinglez à un rev = "<commit>" spécifique si vous avez besoin d’une construction reproductible. Ceci est recommandé une fois que vous avez dépassé le prototypage, car un changement de disposition de compte en amont sur master cassera votre construction sans avertissement.
Le flag de feature cpi fait que les crates se compilent en juste la surface CPI (structs de comptes + invocateurs) plutôt que le programme complet, donc votre binaire reste petit.
anchor-lang / anchor-spl doivent correspondre à ce que la crate cible épingle, et à partir de 2026-09 les deux crates Raydium publiques ne s’accordent pas :
Pour des exemples CPI fonctionnels qui câblent les structs de comptes de bout en bout, voir
raydium-io/raydium-cpi-example (couvre AMM v4, CPMM et CLMM). Sa branche la plus récente est anchor-0.31.0 — il n’y a pas encore de branche Anchor 1.x, donc traitez ce dépôt comme la référence pour le câblage des structs de comptes, pas pour les pins de version que cette page impose.
Le motif Anchor CPI général
Cette section parcourt CPMM de bout en bout comme l’exemple travaillé : structAccounts, CpiContext, cpi::<ix>(). CLMM suit la forme identique, avec une liste de comptes différente et une exigence de comptes restants. LaunchLab suit la même mécanique mais sa liste de comptes porte plusieurs comptes sans équivalent CPMM/CLMM (global_config, platform_config, event_authority, program), donc traitez-le comme le même motif, pas la même forme. Consultez la section propre à chaque programme plutôt que d’assumer que la liste de comptes de cette procédure pas à pas se transfère directement.
Construction de la liste des comptes
Chaque CPI Raydium nécessite un structAccounts dans le programme appelant. Ses champs sont tous les comptes dont votre instruction a besoin, avec des validateurs au niveau des champs ; leur ordre de déclaration n’a pas besoin de correspondre à l’ordre des comptes d’instruction propre à Raydium, puisque votre propre client généré par IDL les adresse par nom, pas par position :
UncheckedAccount car le callee (Raydium) possède la validation. Votre programme appelant valide strictement uniquement les comptes que vous possédez, comme les ATA utilisateur et vos propres PDA. Le commentaire doc /// CHECK: supprime l’avertissement d’Anchor concernant les vérifications manquantes. L’exception côté Raydium est cpmm_program lui-même : c’est le programme invoqué plutôt qu’un compte de données que Raydium valide en interne, donc il est typé Program<T> et obtient la vérification d’adresse automatique d’Anchor au lieu d’une vérification manuelle /// CHECK:. Cette forme largement UncheckedAccount, où Raydium valide ses propres comptes, est la même pour CLMM et LaunchLab. Cet exemple suppose que les deux mints sont du Token SPL classique ; si l’un ou l’autre peut être un mint Token-2022, ajoutez un champ token_program_2022: Program<'info, anchor_spl::token_2022::Token2022> et passez-le comme input_token_program/output_token_program de ce côté dans l’appel CPI ci-dessous au lieu de token_program.
Construction de l’appel CPI
Anchor génère un helper par instruction, ainsi qu’un struct de comptes CPI (cpi::accounts::Swap, aliasé CpmmSwap ci-dessous). Contrairement à votre propre struct MyProxySwap ci-dessus, les noms et l’ordre des champs de celui-ci sont fixés par l’IDL propre de raydium-cp-swap et doivent correspondre exactement :
cpi::swap_base_input est généré à partir de l’IDL ; sa liste d’arguments reflète la liste d’arguments de l’instruction Anchor. Chaque programme Raydium basé sur Anchor confirmé (CPMM, CLMM, LaunchLab) génère ses helpers cpi::<ix>() de la même manière, le nom de la fonction correspondant au nom de l’instruction en snake_case. Que cela s’étende à Farm v6 n’est pas confirmé ; voir sa section.
Graines de signataire (CPI signé par PDA)
Quand votre programme signe le CPI au nom d’un PDA (courant pour les coffres, les séquences, etc.), utilisezCpiContext::new_with_signer :
authority (ou rôle de signataire similaire), le runtime Solana vérifie que le PDA signe via ces graines.
Comptes restants
Certaines instructions Raydium prennent des comptes restants, une liste de longueur variable ajoutée après les comptes fixes. Les helpers CPI d’Anchor ne vérifient pas les comptes restants ; passez-les via.with_remaining_accounts(...) :
- CLMM
SwapV2: tableaux de ticks, ordonnés directionnellement. - Farm v6 : paires
(reward_vault, user_reward_ata), mais seulement à partir du deuxième flux de récompense en avant ; voir Farm v6 pour ce que le décodage d’une vraie transaction montre.
Application du motif : CLMM
SwapV2 suit le motif général ci-dessus avec une liste de comptes différente et une exigence de comptes restants pour les tableaux de ticks. Le module #[program] de la crate est nommé raydium_clmm, qui est aussi son chemin Rust use.
TickArrayNotFound (voir products/clmm/instructions pour la table de comptes complète et la liste des erreurs). Passez-les dans la direction de la marche des prix : premier tableau dans la direction du swap en premier.
Application du motif : LaunchLab
LaunchLab est basé sur Anchor et IDL-publié :raydium_launchpad/raydium_launchpad.json dans le dépôt public raydium-idl. L’identifiant de métadonnées interne de cet IDL est raydium_launchpad, un nom technique pour le programme sous-jacent, pas un nom alternatif pour le produit. Contrairement à CPMM et CLMM, cependant, la source du programme elle-même n’est pas disponible publiquement (voir reference/program-addresses). Il n’y a pas de dépendance git = "..." vers laquelle pointer Cargo, et pas de source pour confirmer quel serait le chemin Rust use d’une vraie crate.
Générez les liaisons à partir de l’IDL publié en utilisant la macro declare_program! d’Anchor. Enregistrez le JSON IDL sous idls/raydium_launchpad.json dans votre crate (Cargo cherche un répertoire idls/ relatif à CARGO_MANIFEST_DIR), puis declare_program!(raydium_launchpad); génère les structs raydium_launchpad::cpi::accounts::<Ix> et les fonctions cpi::<ix>() directement à partir de l’IDL, aucune source de programme requise. Le nom du struct de comptes généré est toujours le nom de l’instruction en PascalCase (buy_exact_in → BuyExactIn), et les noms de champs correspondent exactement aux noms de comptes de l’IDL, la même liste de comptes déjà utilisée dans MyProxyBuy ci-dessous.
La forme CPI suit le motif général. La liste des comptes et les arguments ci-dessous proviennent de l’instruction buy_exact_in de l’IDL on-chain, pas de products/launchlab/instructions.mdx :
pool_state.migrate_type, que products/launchlab/accounts.mdx dit être défini au moment de Initialize. Votre liste de comptes CPI doit être préparée pour l’un ou l’autre, ou vous devez d’abord lire migrate_type hors de PoolState et vous brancher.
Propagation d’erreur
Chaque programme Raydium basé sur Anchor retourne son propre enum d’erreur ; Anchor les enveloppe, donc votre programme appelant les voit commeErr(ProgramError::Custom(code)). Pour gérer les erreurs spécifiques :
raydium_clmm::error::ErrorCode pour CLMM, et ainsi de suite). Les numéros de code d’erreur sont stables selon la politique IDL (sdk-api/anchor-idl), donc vous pouvez tester contre des codes spécifiques en comparant la valeur numérique. Tables d’erreurs complètes : CPMM, CLMM, AMM v4, Farm v6 et LaunchLab.
Budget de calcul dans les CPI composés
Chaque frame CPI a une surcharge, et la consommation CU propre du callee s’empile sur la vôtre, donc une transaction qui appelle Raydium de l’intérieur de votre programme a besoin d’un budget de calcul explicite plutôt que de compter sur la limite par défaut de 200k CU.Mesuré, pas estimé. Un
swap_base_input CPMM sur mainnet consomme ~23 000 CU dans le programme CPMM lui-même — échantillonné 2026-09-09 sur huit swaps en direct sur un pool à haut volume (22 721–23 052), lu à partir de la ligne de log Program CPMMoo8… consumed N of M compute units. Pour comparaison : swap AMM v4 ~26 000 ; swap CLMM ~41 000 ; swap_v2 CLMM ~48 000 (43 838–52 887), augmentant avec chaque croisement de tick.Une révision antérieure de cette page rapportait ~47 700 CU pour un CPI proxy-swap. Ce chiffre était la transaction entière (computeUnitsConsumed), qui inclut votre propre programme, le frame CPI et toute configuration d’ATA — pas le coût du callee. Les deux sont utiles, mais ce ne sont pas le même nombre, donc comparez comme avec comme. Mesurez votre propre transaction plutôt que de budgéter hors de l’un ou l’autre.remaining_accounts, ajoutant du CU par tableau), mais seul le chiffre CPMM ci-dessus est une valeur mesurée. Définissez toujours une limite ComputeBudgetProgram::set_compute_unit_limit(...) explicite dimensionnée à partir de votre propre mesure, pas un nombre copié de la documentation, car la limite par défaut de 200k CU s’épuisera silencieusement et les coûts par instruction changent à mesure que les programmes sont mis à niveau.
AMM v4 : construction manuelle d’instruction
AMM v4 est antérieur à Anchor et n’a pas de crate CPI, ce qui en fait le seul programme de ce document qui ne suit pas le motif général ci-dessus. Construisez l’Instruction à la main :
products/amm-v4/code-demos pour la liste complète des comptes.
Farm v6
Utilisez le SDK TS si c’est une option pour votre intégration.raydium.farm.deposit(...) (voir products/farm-staking/code-demos) est exercé par des démos réelles et ne dépend pas de l’existence d’une crate Anchor pour ce programme.
Si vous avez besoin du CPI Rust malgré tout, par exemple en composant à partir d’un autre programme on-chain, construisez l’Instruction à la main, de la même manière que AMM v4 : dérivez la vraie liste de comptes et les discriminateurs d’instruction indépendamment, par exemple en décodant les dispositions TypeScript du SDK (raydium-sdk-V2’s farm module), en décodant les vraies transactions directement (voir ci-dessous), ou en vidant et en désassemblant le programme déployé.
Pour la forme d’instruction sans argument cohérente avec un appel de récolte ou de réclamation, l’ordre de compte réel est un préfixe fixe (token_program, le compte d’état de la ferme, un PDA d’autorité de coffre, le premier coffre de récompense de ce PDA, un deuxième PDA, l’appelant, et l’ATA de l’appelant pour ce premier mint de récompense), suivi de paires (reward_vault_i, user_reward_ata_i) dans remaining_accounts pour chaque flux de récompense après le premier. La convention d’appairage est réelle, mais elle ne commence qu’au deuxième flux de récompense : le coffre et l’ATA du premier flux sont des comptes fixes, pas adjacents l’un à l’autre, et pas du tout partie de remaining_accounts.
Test d’un flux CPI
Le dev local nécessite que les programmes Raydium soient disponibles dans votre validateur de test. Trois options :anchor testavec clonage de programme. Tire le bytecode déployé mainnet dans votre validateur local ; voir Clonage de programmes dans un validateur local ci-dessous pour la configAnchor.tomlet deux choses qui trébuchent spécifiquement les tests de création de pool.- Devnet. Raydium déploie la plupart des programmes sur devnet, mais à des ID de programme différents que mainnet pour chaque programme (CPMM, CLMM, AMM v4, Stable AMM et LaunchLab ont chacun une adresse devnet distincte ; voir le tableau Devnet dans
reference/program-addresses). Farm v3/v5/v6 ne sont pas fiablement publiés sur devnet ; l’API en direct (https://api-v3-devnet.raydium.io/main/info) a l’image actuelle. Si vous utilisez les constantesDEVNET_PROGRAM_IDgroupées deraydium_clmm(ou l’équivalent pour d’autres crates), ne supposez pas qu’un ID mainnet fonctionne aussi sur devnet. Exécutezanchor test --provider.cluster devnetpour frapper le code en direct une fois que vous avez les bonnes adresses. - Déploiement local. Clonez les dépôts Raydium (CPMM, CLMM ; la source de LaunchLab n’est pas disponible pour cette option) et
anchor deploysur un validateur local. Ajoute une surcharge de cycle de test mais vous permet de modifier le callee pour le débogage.
anchor test, ou anchor build d’abord et anchor test --skip-build après si vous itérez sur le fichier de test sans changer le programme.
Clonage de programmes dans un validateur local
reference/program-addresses est la source de vérité pour chaque adresse ici.
Pointeurs
products/cpmm/code-demos,products/clmm/code-demos,products/amm-v4/code-demos,products/farm-staking/code-demos,products/launchlab/code-demos: exemples CPI et TypeScript spécifiques au produit.sdk-api/anchor-idl: récupération IDL et régénération client, y compris le chemin IDL-codegen pour LaunchLab.integration-guides/cpi-integration: motifs d’intégration de haut niveau comme les séquences, les coffres et la composition d’agrégateur.
- raydium-cp-swap
- raydium-clmm
- raydium-idl : IDL LaunchLab (la source du programme elle-même est fermée)
- Docs CPI Anchor

