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 →
Chaque transaction Solana définit (implicitement ou explicitement) deux paramètres : une limite d’unités de calcul (max CUs que la tx peut consommer ; par défaut 200 000 × nombre d’instructions jusqu’à un plafond par-transaction) et un frais de priorité en micro-lamports par CU. Sous-dimensionner l’un ou l’autre tue les transactions — les limites de CU trop basses causent ProgramFailedToComplete ; les frais de priorité trop bas font que la tx reste non confirmée jusqu’à l’expiration.

Les deux paramètres

import { ComputeBudgetProgram } from "@solana/web3.js";

const tx = new Transaction()
  .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 250_000 }))
  .add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 50_000 }))
  .add(yourRaydiumSwapIx);
  • setComputeUnitLimit(units) — plafonne le calcul ; la transaction paie au maximum units CUs.
  • setComputeUnitPrice(microLamports) — enchère sur les frais de priorité, en micro-lamports par CU. Frais de priorité totaux = units × microLamports × 1e-6 lamports.
Calcul du coût : une limite de 250k CUs à 50k micro-lamports/CU enchérit 250_000 × 50_000 / 1e6 = 12 500 lamports ≈ 0,0000125 SOL ≈ $0,003 à 200 $ SOL. Les frais de priorité à cette échelle sont négligeables pour la plupart des swaps utilisateurs mais importants pour les bots effectuant 1000 tx/jour.

Repères de CU par instruction

Repères issus des journaux d’exécution mainnet, moyennés sur les exécutions récentes. Les nombres sont approximatifs (±15 %) ; remesurer pour vos flux spécifiques.
InstructionSPL TokenToken-2022 (simple)Token-2022 (transfer fee)
CPMM initialize_pool180 000200 000
CPMM swap_base_input140 000180 000200 000
CPMM swap_base_output150 000185 000205 000
CPMM deposit130 000160 000180 000
CPMM withdraw120 000150 000170 000
CLMM create_pool70 00085 000
CLMM open_position_v2120 000140 000160 000
CLMM increase_liquidity_v2150 000175 000195 000
CLMM decrease_liquidity_v2140 000165 000185 000
CLMM swap_v2 (0 tick crossings)170 000205 000225 000
CLMM swap_v2 (1 tick crossing)220 000255 000275 000
CLMM swap_v2 (3 tick crossings)320 000355 000375 000
CLMM collect_fee80 00095 000105 000
AMM v4 swap_base_in140 000
AMM v4 deposit120 000
AMM v4 withdraw110 000
Farm v6 create_farm70 00085 000
Farm v6 deposit (1 reward slot)130 000155 000175 000
Farm v6 deposit (3 reward slots)220 000255 000275 000
Farm v6 withdrawmatches deposit
Farm v6 harvestmatches deposit
Farm v3/v5 deposit100 000
LaunchLab initialize100 000
LaunchLab buy_exact_in140 000
LaunchLab graduate250 000
La ligne « tick crossings » pour CLMM est la plus grande variable de CU. Si vous ne savez pas combien de ticks le swap traversera, budgétisez pour le cas le plus défavorable — 8 traversées est le plafond dur (le programme charge au maximum 8 tableaux de ticks).

Transactions composées

Additionnez les budgets individuels et ajoutez :
  • +1 500 CU par cadre CPI — le surcoût fixe du runtime pour chaque appel inter-programmes.
  • +20 000 CU par création d’ATAcreate_associated_token_account n’est pas gratuit.
  • +5 000 CU pour chaque setComputeUnitLimit / setComputeUnitPrice.
Exemple : un swap utilisateur qui crée l’ATA de sortie et enveloppe le SOL natif :
wrap_sol (create_ata + system transfer + sync_native)   ≈ 30 000
CPMM swap_base_input (SPL)                              ≈ 140 000
close_account (unwrap)                                  ≈ 5 000
ComputeBudget instructions                              ≈ 10 000
────────────────────────────────────────────────────────
Total                                                   ≈ 185 000 → budget 250 000
Marge : fixez la limite de CU ~25 % au-dessus de l’utilisation attendue. Sous-estimer coûte toute la tx ; sur-estimer augmente juste proportionnellement le coût des frais de priorité (les frais de priorité sont units × microLamports, donc ~25 % au-dessus du budget coûte 25 % supplémentaires en frais de priorité).

Estimation des frais de priorité

Le marché des frais local de Solana signifie que les frais de priorité sont par-compte-inscriptible. Une tx qui écrit sur un compte chaud (état de pool populaire) paie plus qu’une tx qui écrit sur un compte froid. Le niveau de frais global n’est pas la bonne métrique pour les swaps Raydium ; vous voulez les frais sur les pools spécifiques que vous touchez.

Stratégie 1 : Estimateur du fournisseur RPC

Chaque fournisseur RPC majeur publie un estimateur de frais de priorité qui interroge les frais récents sur des comptes spécifiques :
// Helius
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${apiKey}`, {
  method: "POST",
  body: JSON.stringify({
    jsonrpc: "2.0",
    id:      "fee-estimate",
    method:  "getPriorityFeeEstimate",
    params: [{
      accountKeys: [poolStatePubkey.toBase58()],
      options:     { priorityLevel: "High" },
    }],
  }),
});
const { result } = await response.json();
const microLamports = result.priorityFeeEstimate;
Les niveaux de priorité selon la plupart des fournisseurs : Min / Low / Medium / High / VeryHigh / UnsafeMax. Mappez-les aux percentiles :
NiveauPercentileCas d’usage
Min25eTrafic bot en arrière-plan, non-urgent
Low50eSwaps utilisateur normaux
Medium60ePar défaut pour les UIs portefeuille
High75eArbitrage sensible au temps
VeryHigh95eLiquidations, sorties de dernière chance
Fournisseurs : Helius (getPriorityFeeEstimate), Triton (getRecentPrioritizationFees avec liste de comptes), QuickNode (similaire).

Stratégie 2 : Requête RPC directe

Utilisez la RPC standard getRecentPrioritizationFees :
const fees = await connection.getRecentPrioritizationFees({
  lockedWritableAccounts: [poolStatePubkey],
});

// fees: Array<{ slot, prioritizationFee }>
// N emplacements récents ; par défaut ~150 emplacements.

const median = percentile(fees.map(f => f.prioritizationFee), 0.5);
C’est la méthode RPC Solana vanille ; fonctionne avec n’importe quel fournisseur. Inconvénient : l’échantillon est petit (150 emplacements ≈ 60 secondes) et bruyant. Pour des estimations plus fluides, utilisez l’agrégation d’un fournisseur.

Stratégie 3 : Auto-ajustement historique

Pour les bots fonctionnant en flux constant, suivez vos propres taux d’atterrissage vs expiration :
cible par pool : taux d'atterrissage 80 % à <30s
si current_land_rate < 80 % : priorityFee += 10 %
si current_land_rate > 95 % : priorityFee -= 5 %
Ceci se corrige plus rapidement que les estimateurs publics et capture la structure par-pool que les estimateurs publics ne voient pas toujours.

Gestion des défaillances d’épuisement de CU

Symptôme : tx échoue avec exceeded maximum number of instructions allowed (200000) ou ProgramFailedToComplete. Diagnostic :
solana confirm <tx-sig> -v
# Cherchez « consumed N of M compute units » et quelle instruction a épuisé les ressources.
Correctifs :
  1. Augmentez la limite de CU. Si votre tx utilisait 195k sur un budget de 200k, passez à 300k.
  2. Divisez la transaction. Si vous atteignez le plafond de 1,4M par-tx, divisez en deux tx. Le farm harvest then stake est un classique à diviser quand les récompenses sont nombreuses.
  3. Réduisez les comptes. Chaque compte inscriptible supplémentaire ajoute ~2 000 CU. L’élagage des comptes inutilisés aide dans les cas marginaux.
  4. Utilisez les tables de lookup. Les recherches LUT coûtent ~50 CU par adresse résolue, économisant les 5 000 CU d’une référence de compte complète par entrée.

Gestion des transactions bloquées

Symptôme : tx soumise, jamais confirmée, finit par expirer avec BlockhashNotFound. Diagnostic :
  • getSignatureStatuses([sig]) retourne null → le leader ne l’a jamais vu.
  • Retourne { confirmationStatus: null } → le leader l’a vu mais ne l’a pas inclus.
Correctifs :
  1. Augmentez les frais de priorité. Renvoyez avec 2× les frais actuels.
  2. Reconstruisez avec un blockhash frais. La durée de vie du blockhash est ~60 secondes ; au-delà la tx est invalide indépendamment des frais.
  3. Diffusion multi-RPC. Certaines RPCs ont une meilleure connectivité au leader que d’autres. Soumettez à 3–5 en parallèle.
  4. Basculez vers les bundles Jito. Voir integration-guides/routing-and-mev. Les bundles contournent les files d’attente publiques de paquets.
Squelette de logique de retry :
async function submitWithRetry(buildTx, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const tx = await buildTx({
      priorityFee: basePriorityFee * Math.pow(1.5, attempt),
      blockhash:   (await connection.getLatestBlockhash()).blockhash,
    });

    try {
      const sig = await connection.sendRawTransaction(tx.serialize(), {
        skipPreflight: attempt > 0,  // skip after first try to save latency
      });

      const result = await connection.confirmTransaction(sig, "confirmed");
      if (result.value.err) {
        // Logic error; don't retry.
        throw result.value.err;
      }
      return sig;

    } catch (e) {
      if (isExpiredError(e)) continue;  // retry
      if (isRevertError(e)) throw e;    // don't retry; deterministic failure
      throw e;
    }
  }
  throw new Error("submit: exhausted retries");
}

Sous congestion

Quand le réseau est congestionné (les tableaux de bord Jupiter / Jito bundle montrent un arriéré, la latence RPC monte en flèche, les taux d’expiration des tx grimpent), ajustez :
ParamètreConditions normalesConditions congestionnées
Limite de CU+25 % au-dessus de l’estimation+25 % au-dessus de l’estimation (inchangé)
Percentile de frais de priorité50e75e–95e
Nombre de retries35–7
Backoff de retry500ms1000ms
Utiliser les bundles JitoOptionnelFortement recommandé
Rafraîchissement du blockhash en retryOuiOui, obligatoire
Surveillance des signaux de congestion :
  • Percentile 75e de frais de priorité > 500k micro-lamports : congestion.
  • Percentile 50e de pourboire Jito > 0,001 SOL : congestion.
  • RPC réponse p99 > 2s : problème spécifique RPC ou congestion.

Budgétisation des frais pour les bots

Un bot de trading exécutant ~1000 tx/jour a besoin d’un budget de frais de priorité. Estimation rapide :
CU moyen par tx :           ~250 000
Frais 50e percentile :      ~20 000 micro-lamports/CU
Coût par tx :               250_000 × 20_000 × 1e-6 = 5_000 lamports = 5e-6 SOL
Coût quotidien (1000 tx) :  5e-3 SOL ≈ $1 @ 200 $ SOL
Coût mensuel :              ~$30
C’est le minimum. Pendant la congestion, multipliez par 5–10×. Prévoyez ~$150–300/mois en frais de priorité pour un bot en flux constant. Les bots qui doivent atterrir dans des emplacements spécifiques (liquidations, arb) paient continuellement le 95e percentile et dépensent ~10× plus. Les pourboires des bundles Jito dominent à cette échelle — souvent $1000+/mois — mais l’alternative (être front-runné ou expirer) est pire.

Pièges

1. Oublier la limite de CU

Par défaut c’est 200k CUs × (instructions dans tx). Un swap d’une seule instruction par défaut à 200k ; c’est suffisant pour CPMM sur SPL Token mais pas CLMM avec traversée de ticks ou quoi que ce soit Token-2022. Fixez-le toujours explicitement.

2. Frais de priorité sur le mauvais compte

Si vous estimez les frais de priorité contre le mint de token mais le compte chaud est l’état du pool, votre estimation est trop basse. L’état du pool est le bon compte inscriptible à cibler pour Raydium.

3. Les frais augmentent avec la limite de CU

total_priority_fee = units × microLamports. Augmenter units de 200k à 1M à 50k micro-lamports/CU multiplie les frais de priorité par 5×. Ne sur-budgétisez pas les CU juste au cas où ; mesurez.

4. Version tx par défaut

Les transactions legacy ont des limites de compte plus basses ; les transactions V0 avec les tables de lookup d’adresses débloquent des routes plus grandes. Le SDK utilise V0 par défaut en txVersion: TxVersion.V0. Ne reveniez à legacy que si vous avez besoin de compatibilité portefeuille.

5. skipPreflight cache les erreurs de CU

skipPreflight: true envoie la tx sans simulation locale. Vous gagnez ~100ms mais perdez les retours précoces sur l’épuisement de CU. Utilisez-le seulement sur les retries, pas à la première tentative.

Pointeurs

Sources :