Passer au contenu principal

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.

Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Les programmes plus récents de Raydium (CPMM, CLMM, Farm v6, LaunchLab) sont écrits en Anchor — un framework Rust qui s’appuie sur le modèle natif de Solana pour fournir la validation de comptes, la gestion des erreurs et une IDL (interface description). AMM v4 et les farms plus anciennes antérieures à Anchor. Comprendre les deux paradigmes vous aide à lire le code, générer des clients à partir de l’IDL et déboguer les erreurs inattendues.

Modèle de déploiement des programmes

Chaque programme Solana réside à une Pubkey. Le bytecode du programme est stocké dans un compte executable appartenant au BPF Upgradable Loader (BPFLoaderUpgradeab1e11111111111111111111111). Un déploiement de programme comprend trois comptes :
  1. Compte programme : petit compte de métadonnées à l’ID du programme. Propriétaire : BPF Upgradable Loader.
  2. Compte ProgramData : contient le bytecode réel. Dérivé comme [program_id, "programdata"].
  3. Compte Buffer (transitoire) : contient le nouveau bytecode pendant une mise à niveau. Supprimé après la mise à niveau.
Le compte ProgramData a une autorité de mise à niveau — une clé qui peut remplacer le bytecode par une nouvelle version. L’autorité de mise à niveau de Raydium est un multisig derrière un verrou temporel de 24 heures ; voir security/admin-and-multisig.

Vérifier un programme déployé

Pour confirmer que ce qui est on-chain correspond à la source approuvée par l’audit :
# Dump le programme depuis mainnet
solana program dump CPMMoo8L3F4NbTegBCKVNunggL7H1Zpdmwpwh8KMoZ0F cpmm-onchain.so

# Build à partir d'une source connue
cargo build-bpf --manifest-path raydium-cp-swap/programs/cp-amm/Cargo.toml
cp target/deploy/raydium_cp_swap.so cpmm-source.so

# Comparer
sha256sum cpmm-onchain.so cpmm-source.so
Des hashes identiques prouvent que vous interagissez avec la source que vous croyez. Raydium publie des instructions de build vérifié dans les notes de version.

Anchor : un framework au-dessus de Solana

Les programmes Solana bruts sont des fonctions Rust avec cette signature :
pub fn process_instruction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    instruction_data: &[u8],
) -> ProgramResult {
    // Analyser manuellement instruction_data
    // Valider manuellement les comptes
    // Désérialiser manuellement les données de compte
    // Vérifier manuellement les drapeaux signer/writable
    // ... puis faire le travail réel
}
Anchor enveloppe tout le code passe-partout et vous permet d’écrire :
#[program]
pub mod cpmm {
    use super::*;

    pub fn swap_base_input(
        ctx: Context<Swap>,
        amount_in: u64,
        min_out: u64,
    ) -> Result<()> {
        // Juste la logique métier — ctx est pré-validé
    }
}

#[derive(Accounts)]
pub struct Swap<'info> {
    pub payer: Signer<'info>,
    #[account(mut, seeds = [b"pool", config.key().as_ref(), ...], bump)]
    pub pool_state: AccountLoader<'info, PoolState>,
    #[account(mut)]
    pub input_vault: Box<Account<'info, TokenAccount>>,
    // ... plus de comptes
}
Anchor :
  • Génère automatiquement un discriminateur de 8 octets déterministe pour chaque instruction et chaque type de compte.
  • Valide les contraintes de compte (propriétaire, seeds, writable, signer, mint-matches, token-program-matches) avant l’exécution de votre code.
  • Génère une IDL — un fichier de description d’interface que les clients utilisent pour appeler le programme.
  • Est livré avec une bibliothèque client Rust, TypeScript et Python.

Le discriminateur de 8 octets

Chaque compte Anchor et chaque instruction Anchor commence par un discriminateur de 8 octets — les 8 premiers octets du SHA-256 d’une chaîne fixe :
Discriminateur de compte :     sha256("account:PoolState")[0..8]
Discriminateur d'instruction : sha256("global:swap_base_input")[0..8]
Lorsque vous appelez une instruction Anchor, les 8 premiers octets des données d’instruction sont ce discriminateur ; Anchor dispatche vers le bon handler en les recherchant. Lorsque vous lisez un compte Anchor, les 8 premiers octets indiquent son type — crucial pour les outils comme getProgramAccounts qui énumèrent tous les comptes d’un type.

Erreurs

Les programmes Anchor définissent les erreurs via #[error_code] :
#[error_code]
pub enum ErrorCode {
    #[msg("Slippage tolerance exceeded")]
    SlippageExceeded,
    #[msg("Pool is disabled")]
    PoolDisabled,
    // ...
}
Anchor attribue automatiquement ces codes numériques à partir de 6000 (0x1770). Le tableau complet des codes d’erreur de Raydium se trouve dans reference/error-codes.

L’IDL

Un fichier IDL (Interface Description Language) Anchor est une description JSON d’un programme : ses instructions, comptes, types, erreurs et événements. C’est l’équivalent d’un ABI Ethereum. Raydium publie des IDLs pour tous les programmes Anchor. Récupérez en direct on-chain :
anchor idl fetch CPMMoo8L3F4NbTegBCKVNunggL7H1Zpdmwpwh8KMoZ0F -o cpmm.idl.json
Ou à partir de la source du SDK : src/raydium/*/idl/*.json.

Structure de l’IDL

{
  "version":      "0.1.0",
  "name":         "raydium_cp_swap",
  "instructions": [ { "name": "swap_base_input", "accounts": [ ... ], "args": [ ... ] }, ... ],
  "accounts":     [ { "name": "PoolState", "type": { ... } }, ... ],
  "types":        [ { "name": "AmmConfig", "type": { ... } }, ... ],
  "errors":       [ { "code": 6000, "name": "SlippageExceeded", "msg": "..." }, ... ],
  "events":       [ { "name": "SwapEvent", "fields": [ ... ] }, ... ]
}

Générer un client à partir de l’IDL

La CLI anchor d’Anchor génère les types TypeScript et Rust :
anchor idl build -o target/idl/cpmm.json
# Les types TypeScript sont auto-générés par le ts-client d'Anchor
# Le SDK Raydium inclut déjà ceux-ci
Les outils tiers comme Kinobi peuvent générer des clients Rust, Python, C ou Go à partir d’une IDL.

Quand l’IDL est votre ami

Si vous voulez construire une intégration personnalisée qui ne passe pas par le SDK Raydium :
  1. Récupérez l’IDL (en direct on-chain ou depuis la source du SDK).
  2. Recherchez l’instruction que vous voulez (par ex., swap_base_input).
  3. Construisez les données d’instruction : discriminateur de 8 octets + args encodés.
  4. Passez les comptes dans l’ordre spécifié par l’IDL.
Voir sdk-api/anchor-idl pour des exemples détaillés.

Programmes pré-Anchor : AMM v4 et Farm v3/v5

Ces programmes antérieures à Anchor. Ils utilisent :
  • Dispatch manuel d’instructions : une balise u8 dans instruction_data avec une instruction match.
  • Validation manuelle de comptes : if accounts[0].owner != &expected_program { ... }.
  • Args d’instruction sérialisés en Borsh : pas de discriminateur, juste instruction_data[1..].
  • Layout via #[repr(C, packed)] : layout binaire de struct C.
Le SDK Raydium v2 fournit des layouts TypeScript pour les instructions AMM v4 non-Anchor afin que les clients puissent coder/décoder sans Anchor :
import { liquidityStateV4Layout, swapInstructionData }
  from "@raydium-io/raydium-sdk-v2";

const data = swapInstructionData.encode({
  instruction: 9,   // swap
  amountIn:    1_000_000n,
  minAmountOut: 950_000n,
});
Le modèle d’intégration est le même — vous n’avez juste pas l’auto-génération dirigée par l’IDL d’Anchor.

Mécaniques de mise à niveau du programme

Seule l’upgrade_authority de ProgramData peut effectuer une mise à niveau. Étapes :
  1. Compilez le nouveau bytecode.
  2. Écrivez-le dans un compte buffer (solana program write-buffer).
  3. Soumettez une instruction de mise à niveau : BpfLoaderUpgradeable::Upgrade { buffer, program, authority }.
  4. Le runtime remplace atomiquement le bytecode du programme par le contenu du buffer.
Raydium gère cela derrière un verrou temporel de 24 heures implémenté dans les paramètres du multisig Squads. Une transaction de mise à niveau doit attendre 24 heures après l’approbation du multisig avant l’exécution. Cela protège contre les mises à niveau précipitées / forcées. Voir security/admin-and-multisig.

Rendre un programme immuable

Une autorité de mise à niveau peut être définie à None, auquel cas le programme devient définitivement immuable. Raydium n’a fait cela pour aucun produit — l’équipe conserve la capacité de pousser des correctifs de sécurité. Compromis : les utilisateurs doivent faire confiance au processus multisig + verrou temporel.

Programmes et loyer

Le déploiement d’un programme consomme des lamports exempts de loyer :
  • Un programme de 50 KB : ~0,35 SOL en loyer.
  • Un programme de 200 KB : ~1,4 SOL en loyer.
Fermer un programme (via solana program close) retourne les lamports. Les programmes Raydium restent actifs et ne sont pas prévus pour fermeture.

Déboguer les programmes Anchor

Sortie des logs

La macro msg! d’Anchor écrit dans le log de la transaction. Simulez une transaction pour voir les logs :
const sim = await connection.simulateTransaction(tx);
console.log(sim.value.logs);
Les logs incluent :
  • Invocation du programme (Program CPMMoo8... invoke [1]).
  • Appels msg! depuis le code du programme.
  • Consommation d’unités de calcul (consumed 137842 of 400000 compute units).
  • Succès ou erreur du programme.

Codes d’erreur

Si un programme Anchor lève une exception, le log affiche :
Program CPMMoo8... failed: custom program error: 0x1770
0x1770 = 6000 décimal = la première erreur Anchor (par ex., SlippageExceeded). Comparez avec le tableau errors de l’IDL. Voir reference/error-codes pour le tableau complet des erreurs de Raydium.

Désaccords de layout de compte

Si vous passez le mauvais compte au mauvais emplacement, les macros de validation de compte d’Anchor retournent des erreurs comme :
AnchorError: AccountNotInitialized. Error Number: 3012
Les numéros d’erreur en dessous de 6000 sont les erreurs intégrées d’Anchor (voir l’enum ErrorCode d’Anchor) ; les erreurs ≥6000 sont les codes personnalisés du programme.

Pointeurs

Sources :