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 de Raydium fournissent des crates CPI wrapper Anchor qui font ressembler le site d’appel à un appel de fonction typée, avec des structs de compte 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 une lecture autonome de leurs sections.
Dépendances Cargo
branch = "master" suit la source publiée la plus récente ; épinglez à un rev = "<commit>" spécifique si vous avez besoin d’une build 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 build sans avertissement.
Le flag de feature cpi fait compiler les crates à juste la surface CPI (structs de compte + invokers) plutôt que le programme complet, donc votre binaire reste petit.
anchor-lang / anchor-spl doivent correspondre à ce que la crate cible épingle :
Pour des exemples CPI fonctionnels qui câblent les structs de compte 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 repo comme la référence pour le câblage des structs de compte, pas pour les épingles de version que cette page impose.
Le motif CPI Anchor général
Cette section parcourt CPMM de bout en bout comme exemple travaillé : structAccounts, CpiContext, cpi::<ix>(). CLMM suit la même forme exacte, avec une liste de comptes différente et une exigence de remaining-accounts. LaunchLab suit la même mécanique mais sa liste de comptes contient 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 de supposer que la liste de comptes de cette procédure s’applique directement.
Construction de la liste de comptes
Chaque CPI Raydium nécessite une 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 de Raydium lui-même, puisque votre propre client généré par IDL les adresse par nom, pas par position :
UncheckedAccount parce que l’appelé (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 de documentation /// 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 reçoit la vérification d’adresse automatique d’Anchor au lieu d’une vérification manuelle /// CHECK:. Cette forme principalement UncheckedAccount, où Raydium valide ses propres comptes, est la même pour CLMM et LaunchLab. Cet exemple suppose que les deux mints sont des Token SPL classiques ; 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’une struct de comptes CPI (cpi::accounts::Swap, aliasée CpmmSwap ci-dessous). Contrairement à votre propre struct MyProxySwap ci-dessus, les noms et l’ordre des champs de celle-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. L’extension à Farm v6 n’est pas confirmée ; consultez sa section.
Graines de signataire (CPI signé par PDA)
Quand votre programme signe le CPI au nom d’une PDA (courant pour les vaults, les escrows, etc.), utilisezCpiContext::new_with_signer :
authority (ou un rôle de signataire similaire), le runtime Solana vérifie que la PDA signe via ces graines.
Remaining accounts
Certaines instructions Raydium prennent des remaining accounts, une liste de longueur variable ajoutée après les comptes fixes. Les helpers CPI d’Anchor ne font pas de vérification de type sur les remaining accounts ; passez-les via.with_remaining_accounts(...) :
- CLMM
SwapV2: tick arrays, ordonnés directionnellement. - Farm v6 : paires
(reward_vault, user_reward_ata), mais uniquement à partir du deuxième flux de récompense ; consultez Farm v6 pour voir ce qu’un 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 remaining-accounts pour les tick arrays. Le module #[program] de la crate est nommé raydium_clmm, qui est aussi son chemin Rust use.
TickArrayNotFound (consultez 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 array dans la direction du swap en premier.
Application du modèle : LaunchLab
LaunchLab est basé sur Anchor et publié via IDL :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, et non un nom alternatif du produit. Contrairement à CPMM et CLMM, le code source du programme lui-même n’est pas publiquement disponible (voir reference/program-addresses). Il n’y a pas de dépendance git = "..." pour pointer Cargo, et aucune source pour confirmer quel serait le vrai chemin Rust use d’une crate.
Générez les bindings à 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, sans source de programme requise. Le nom de la struct de comptes générée 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 modèle général. La liste de comptes et les arguments ci-dessous proviennent de l’instruction buy_exact_in de l’IDL on-chain, et non de products/launchlab/instructions.mdx :
pool_state.migrate_type, que products/launchlab/accounts.mdx indique ê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 depuis PoolState et créer une branche.
Propagation des erreurs
Chaque programme Raydium basé sur Anchor retourne sa propre énumération d’erreur ; Anchor les enveloppe, donc votre programme appelant les voit commeErr(ProgramError::Custom(code)). Pour gérer des erreurs spécifiques :
raydium_clmm::error::ErrorCode pour CLMM, etc.). Les numéros de code d’erreur sont stables selon la politique IDL (sdk-api/anchor-idl), vous pouvez donc tester des codes spécifiques en comparant avec la valeur numérique. Tableaux d’erreurs complets : CPMM, CLMM, AMM v4, Farm v6, et LaunchLab.
Budget de calcul dans les CPIs composés
Chaque frame CPI a une surcharge, et la consommation CU propre de l’appelé s’ajoute à la vôtre, donc une transaction qui appelle Raydium depuis l’intérieur de votre programme a besoin d’un budget de calcul explicite plutôt que de s’appuyer sur la limite par défaut de 200k CU.Mesuré, non estimé. Un
swap_base_input CPMM sur mainnet consomme ~23 000 CU dans le programme CPMM lui-même — échantillonné le 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 ; CLMM swap ~41 000 ; CLMM swap_v2 ~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 ATA — pas le coût de l’appelé. Les deux sont utiles, mais ce ne sont pas le même nombre, donc comparez des choses comparables. Mesurez votre propre transaction plutôt que de budgéter d’après 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 instruction ComputeBudgetProgram::set_compute_unit_limit(...) explicite dimensionnée à partir de votre propre mesure, et non d’un nombre copié depuis 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 à jour.
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 modèle 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 Rust Anchor pour ce programme.
Si vous avez besoin de Rust CPI 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 layouts TypeScript du SDK (raydium-sdk-V2’s farm module), en décodant les transactions réelles directement (voir ci-dessous), ou en vidant et désassemblant le programme déployé.
Pour la forme d’instruction sans argument cohérente avec un appel harvest ou claim, l’ordre réel des comptes est un préfixe fixe (token_program, le compte d’état de la farm, une PDA d’autorité de coffre, le premier coffre de récompense de cette PDA, une 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 ne font pas du tout partie de remaining_accounts.
Tester un flux CPI
Le développement local nécessite que les programmes Raydium soient disponibles dans votre validateur de test. Trois options :anchor testavec clonage de programme. Récupère le bytecode déployé sur mainnet dans votre validateur local ; consultez Cloner des programmes dans un validateur local ci-dessous pour la configurationAnchor.tomlet deux points qui peuvent poser problème lors des tests de création de pool.- Devnet. Raydium déploie la plupart des programmes sur devnet, mais avec des ID de programme différents de mainnet pour chaque programme (CPMM, CLMM, AMM v4, Stable AMM et LaunchLab ont chacun une adresse devnet distincte ; consultez le tableau Devnet dans
reference/program-addresses). Farm v3/v5/v6 ne sont pas publiés de manière fiable sur devnet ; l’API en direct (https://api-v3-devnet.raydium.io/main/info) affiche l’état actuel. Si vous utilisez les constantesDEVNET_PROGRAM_IDfournies avecraydium_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 tester 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 exécutez
anchor deploysur un validateur local. Cela ajoute une surcharge au cycle de test, mais vous permet de modifier le programme appelé pour le débogage.
anchor test, ou anchor build d’abord puis anchor test --skip-build après si vous itérez sur le fichier de test sans modifier le programme.
Cloner des programmes dans un validateur local
reference/program-addresses est la source de vérité pour chaque adresse ici.
Ressources
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 aux produits.sdk-api/anchor-idl: récupération d’IDL et régénération de client, y compris le chemin de codegen IDL pour LaunchLab.integration-guides/cpi-integration: modèles d’intégration de haut niveau comme les escrows, les vaults et la composition d’agrégateurs.
- raydium-cp-swap
- raydium-clmm
- raydium-idl : IDL LaunchLab (la source du programme elle-même est fermée)
- Anchor CPI docs

