Chaque actif échangeable sur Solana — y compris les actifs de base et de cotation de chaque pool Raydium — est un token frappé par l’un de deux programmes : le programme SPL Token hérité ou son successeur, Token-2022. Il s’agit de programmes distincts à des adresses différentes, avec des schémas de compte et une sémantique d’extension différents. Raydium supporte les deux, mais pas partout : CPMM, CLMM et Farm v6 acceptent les mints Token-2022 ; AMM v4 ne les accepte pas. Comprendre cette distinction est essentiel avant d’intégrer un pool.
Les deux programmes
| SPL Token | Token-2022 |
|---|
| ID du programme | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| Lancement | 2020 | 2022 |
| Taille du compte (compte token) | 165 B | 165 B + extensions (variable) |
| Extensions | Non | Oui — 17+ extensions officielles |
| Compatibilité héritée | Complète | Optionnel par mint |
Les deux sont maintenus par l’équipe Solana Labs (maintenant Anza) et vivent dans le dépôt solana-program-library.
Pourquoi deux programmes ?
SPL Token a été figé pour la compatibilité ascendante — son bytecode est effectivement immuable, offrant une ligne de base claire pour tout l’écosystème. À mesure que les cas d’usage se sont multipliés (stablecoins voulant des frais de transfert, mints institutionnels nécessitant des autorités de gel nuancées, NFTs nécessitant des pointeurs de métadonnées), l’équipe Solana a introduit Token-2022 comme un programme distinct et extensible plutôt que de mettre à niveau SPL Token. Cela préserve les intégrations existantes et laisse chaque mint opter pour exactement les extensions dont il a besoin.
Token-2022 est un sur-ensemble strict en fonctionnalité, pas en espace d’adresse : les deux programmes coexistent, et un mint à une adresse donnée appartient à exactement l’un d’eux.
Structure du compte
Compte Mint
Définit l’identité d’un token.
Mint SPL Token (82 bytes) :
u32 mint_authority_option
Pubkey mint_authority
u64 supply
u8 decimals
bool is_initialized
u32 freeze_authority_option
Pubkey freeze_authority
Mint Token-2022 : même schéma de base, plus zéro ou plusieurs enregistrements extension TLV (type-longueur-valeur) ajoutés après la base.
Compte Token
Détient un solde d’un mint spécifique pour un propriétaire spécifique.
Compte SPL Token (165 bytes) :
Pubkey mint
Pubkey owner
u64 amount
u32 delegate_option
Pubkey delegate
u8 state // initialized, frozen
u32 is_native_option
u64 is_native
u64 delegated_amount
u32 close_authority_option
Pubkey close_authority
Compte Token-2022 : même base, plus enregistrements d’extension TLV si des extensions sont actives.
Extensions Token-2022
Les extensions sont des fonctionnalités modulaires qui peuvent être attachées aux mints ou aux comptes. Chaque extension est un enregistrement TLV distinct. Les clés pour Raydium :
Transfer fee
Le mint peut percevoir une redevance en pourcentage sur chaque transfert. Les frais vont à une autorité de retrait configurée. Supporté par Raydium CPMM et CLMM via SwapV2 — le programme tient compte des frais lors du calcul des taux de change, donc la mathématique du pool reste cohérente.
let extension = TransferFeeConfig {
transfer_fee_config_authority,
withdraw_withheld_authority,
withheld_amount: 0,
older_transfer_fee: ...,
newer_transfer_fee: ...,
};
Transfer hook
Le mint pointe vers un programme que le runtime invoque sur chaque transfert. Le programme hook peut rejeter le transfert ou effectuer des effets secondaires (mettre à jour un état de conformité, journaliser, etc.). Raydium CPMM/CLMM invoque le hook via SwapV2 — la transaction inclut le programme hook et tous les comptes supplémentaires dont il a besoin.
Interest-bearing
Le solde en chaîne accumule des intérêts à un taux configuré. Affichage uniquement (les soldes semblent plus élevés au fil du temps) plutôt que mint réel ; l’approvisionnement sous-jacent est inchangé.
Mint close authority
Permet au mint d’être fermé une fois que l’approvisionnement atteint zéro.
Permanent delegate
Un portefeuille désigné peut transférer ou brûler des tokens de n’importe quel compte sans condition. Raydium bloque la création de pool pour les mints avec cette extension — elle est incompatible avec l’invariant selon lequel les réserves du pool ne peuvent pas être saisies.
Non-transferable
Les tokens ne peuvent pas être déplacés du compte dans lequel ils sont frappés. Raydium bloque la création de pool — un actif non échangeable ne peut pas être la base ou la cotation d’un pool LP.
Default account state
Les nouveaux comptes tokens pour ce mint sont gelés par défaut et doivent être dégelés par l’autorité de gel. Utilisable mais rare.
Confidential transfer
Les soldes et les montants de transfert sont chiffrés. Raydium ne supporte pas les mints de transfert confidentiel (la mathématique du pool nécessite des soldes en texte clair).
Remplace les métadonnées Metaplex pour les mints Token-2022. Supporté pour les listes de pools Raydium.
Group / Member pointer
Déclare un mint comme appartenant à un groupe (par exemple, une collection NFT). Informatif ; Raydium l’utilise pour l’affichage.
Consultez la page officielle des extensions Token-2022 pour la liste complète.
Quels produits Raydium supportent quoi
| Produit | SPL Token | Token-2022 | Notes |
|---|
| AMM v4 | Oui | Non | L’intégration OpenBook nécessite SPL Token |
| CPMM | Oui | Oui | Nécessite SwapV2 pour les pools Token-2022 |
| CLMM | Oui | Oui | Nécessite SwapV2 pour les pools Token-2022 |
| Farm v6 | Oui | Oui | Supporté pour les mints de stake et de reward |
| LaunchLab | Oui | Oui | Les pools CPMM diplômés héritent du support Token-2022 |
Éligibilité des mints pour les pools Raydium — toutes les extensions sont autorisées sauf indication contraire :
- Bloquées : non-transferable, permanent delegate, confidential transfer, default account state (dans les configurations rejetées).
- Autorisées avec réserves (LP doit accepter le risque) : transfer fee, transfer hook, freeze authority active.
- Entièrement autorisées : interest-bearing, metadata pointer, group pointer, mint close authority.
La réponse getPoolInfoFromRpc inclut les drapeaux d’extension du mint — les clients doivent vérifier avant de devenir LP.
Standards de compte Token
Associated Token Account (ATA)
Les deux programmes partagent la convention Associated Token Account : un PDA dérivé de [owner, programId, mint] via l’Associated Token Program (ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL). Presque chaque compte token utilisateur sur Solana est un ATA.
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
// SPL Token
const ata = getAssociatedTokenAddressSync(mint, owner);
// Token-2022
const ata22 = getAssociatedTokenAddressSync(
mint,
owner,
false, // allowOwnerOffCurve
TOKEN_2022_PROGRAM_ID,
);
Le programme ATA crée des comptes détenus par le programme token approprié en fonction du programme qui possède le mint.
Comptes token non-ATA
Un portefeuille peut avoir plusieurs comptes tokens pour un seul mint ; ATA est juste la convention. Les coffres de pool, par exemple, ne sont pas des ATA — ce sont des PDAs du programme pool, détenant les réserves du pool.
Détecter quel programme possède un mint
Le compte de chaque mint a un champ owner pointant vers SPL Token ou Token-2022 :
const mintInfo = await connection.getAccountInfo(mintPubkey);
if (mintInfo.owner.equals(TOKEN_PROGRAM_ID)) {
console.log("SPL Token mint");
} else if (mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {
console.log("Token-2022 mint");
}
Le SDK Raydium gère cette détection automatiquement — getPoolInfoFromRpc retourne le programId approprié par token afin que les clients puissent construire les ATA correctes.
Instructions de swap par programme
CPMM et CLMM de Raydium ont chacun deux instructions de swap :
| Instruction | Mints supportés |
|---|
Swap / SwapBaseInput (hérité) | SPL Token uniquement |
SwapV2 / SwapBaseInputV2 | SPL Token et Token-2022 |
SwapV2 prend des comptes supplémentaires : comptes mint pour les deux côtés, le programme token pour chaque côté (car ils peuvent différer), et — pour les mints avec transfer hook — le programme hook et ses comptes requis.
Les clients doivent toujours utiliser SwapV2 lorsqu’au moins un côté est Token-2022 ; SwapV2 fonctionne aussi pour les pools SPL uniquement, mais le Swap hérité est moins cher en calcul.
Le SDK choisit la variante correcte automatiquement.
Migrer un projet SPL Token vers Token-2022
Token-2022 n’est pas un remplaçant prêt à l’emploi au niveau du mint — un mint à l’adresse X est soit SPL soit Token-2022, et c’est fixé à la création. Pour « migrer », vous devez :
- Créer un nouveau mint sous Token-2022 avec les extensions que vous souhaitez.
- Fournir un mécanisme de swap/wrap pour les détenteurs du ancien mint SPL pour échanger contre le nouveau.
- Mettre à jour tous les pools LP, farms et intégrations pour référencer le nouveau mint.
C’est lourd. La plupart des projets lancés sous SPL restent sous SPL à moins qu’un besoin d’extension spécifique ne force le déménagement.
Exemple concret : créer un mint Token-2022 avec transfer fee
import {
Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID, ExtensionType, createInitializeMintInstruction,
getMintLen, createInitializeTransferFeeConfigInstruction,
} from "@solana/spl-token";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const payer = Keypair.generate();
const mint = Keypair.generate();
const extensions = [ExtensionType.TransferFeeConfig];
const mintLen = getMintLen(extensions);
const rentLamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const tx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mint.publicKey,
space: mintLen,
lamports: rentLamports,
programId: TOKEN_2022_PROGRAM_ID,
}),
createInitializeTransferFeeConfigInstruction(
mint.publicKey,
payer.publicKey, // transfer fee authority
payer.publicKey, // withdraw-withheld authority
50, // 50 bps = 0.5%
BigInt(1_000_000), // max fee per transfer (smallest units)
TOKEN_2022_PROGRAM_ID,
),
createInitializeMintInstruction(
mint.publicKey,
9, // decimals
payer.publicKey, // mint authority
null, // freeze authority
TOKEN_2022_PROGRAM_ID,
),
);
await sendAndConfirmTransaction(connection, tx, [payer, mint]);
Ce mint peut être LP dans un pool CPMM Raydium ; les swappeurs paieront le 0.5% de frais de transfert en plus des frais de swap du pool.
Considérations de sécurité
Avant de faire de LP ou d’échanger via un mint Token-2022 :
- Vérifiez
freeze_authority. S’il n’est pas nul et détenu par une partie centralisée, ils peuvent geler votre ATA (et potentiellement le coffre du pool).
- Vérifiez
transfer_hook. Le programme hook peut bloquer les transferts arbitrairement — DYOR sur la source du hook.
- Vérifiez
transfer_fee. Tenez compte des frais dans la sortie de swap attendue.
- Vérifiez
permanent_delegate et non_transferable. Le programme Raydium rejette ces extensions, mais vérifiez si vous construisez une intégration personnalisée.
Consultez security/oracle-and-token-risks pour le cadre complet d’acceptation des risques.
Pointeurs
Sources :