Métadonnées Metaplex

Les jetons SPL standards n'incluent pas de métadonnées comme un nom, un symbole ou une image. Le programme Metaplex Token Metadata résout ce problème en créant un compte de métadonnées lié à chaque mint de jeton.

Ce guide couvre le programme Metaplex Token Metadata qui peut être utilisé pour les jetons SPL standards et Token-2022. Pour utiliser l'extension Metadata de Token-2022, consultez le guide Extension Metadata qui stocke les métadonnées directement sur le compte mint.

Fonctionnement des métadonnées de jetons

Le programme Token Metadata crée un Program Derived Address (PDA) pour chaque mint de jeton. Ce compte de métadonnées stocke des informations on-chain comme le nom et le symbole du jeton, ainsi qu'un URI pointant vers des métadonnées JSON off-chain (images, descriptions, etc.).

┌─────────────────┐ ┌─────────────────────┐
│ Mint Account │ │ Metadata Account │
│ │ │ (PDA) │
│ - Supply │◄──────│ - Name │
│ - Decimals │ │ - Symbol │
│ - Authority │ │ - URI │
└─────────────────┘ │ - Seller Fee │
│ - Creators │
└─────────────────────┘

Le PDA de métadonnées est dérivé des seeds : ["metadata", program_id, mint_address]

Créer un jeton avec métadonnées

L'instruction createV1 crée à la fois le compte mint et ses métadonnées dans une seule transaction.

Typescript

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import {
getCreateV1InstructionAsync,
TokenStandard
} from "@metaplex-foundation/mpl-token-metadata-kit";
// Create connection
const rpc = createSolanaRpc("http://127.0.0.1:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");
// Generate keypairs
const payer = await generateKeyPairSigner();
const mint = await generateKeyPairSigner();
// Fund payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: payer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Create fungible token with metadata
const createInstruction = await getCreateV1InstructionAsync({
mint,
authority: payer,
payer,
name: "My Token",
symbol: "MTK",
uri: "https://example.com/token.json",
sellerFeeBasisPoints: 0,
tokenStandard: TokenStandard.Fungible
});
// Build and send transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(payer, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([createInstruction], tx)
);
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
console.log("Mint Address:", mint.address);

Récupérer les métadonnées d'un jeton

Pour apprendre à récupérer les métadonnées de jetons existants, consultez la recette cookbook Récupérer les métadonnées d'un jeton.

Mettre à jour les métadonnées d'un jeton

L'autorité de mise à jour peut modifier les métadonnées si le compte est mutable.

Kit
import {
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import {
getUpdateV1InstructionAsync,
findMetadataPda,
fetchMetadata
} from "@metaplex-foundation/mpl-token-metadata-kit";
const rpc = createSolanaRpc("http://127.0.0.1:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");
// authority must be a KeyPairSigner with update authority
const mintAddress = "YOUR_MINT_ADDRESS";
// Fetch current metadata to preserve existing values
const [metadataAddress] = await findMetadataPda({ mint: mintAddress });
const currentMetadata = await fetchMetadata(rpc, metadataAddress);
// Update metadata (must provide all data fields)
const updateInstruction = await getUpdateV1InstructionAsync({
mint: mintAddress,
authority, // Update authority signer
payer: authority,
data: {
name: "Updated Token Name",
symbol: "UPD",
uri: "https://example.com/updated-token.json",
sellerFeeBasisPoints: 100, // 1%
creators:
currentMetadata.data.creators.__option === "Some"
? currentMetadata.data.creators.value
: null
}
});
// Build and send transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(authority, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([updateInstruction], tx)
);
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
console.log("Metadata updated successfully");

Standards de jetons

Le programme Token Metadata prend en charge différents standards de jetons :

StandardDescriptionCas d'usage
FungibleJeton fongible standard avec métadonnéesDevises, points
FungibleAssetJeton fongible représentant un actif uniqueObjets semi-fongibles
NonFungibleNFT avec Master EditionŒuvre d'art 1/1
ProgrammableNonFungibleNFT avec royalties imposéesRoyalties créateurs
NonFungibleEditionCopie imprimée d'un NFTÉditions limitées
ProgrammableNonFungibleEditionCopie imprimée avec royalties imposéesÉditions limitées
import { TokenStandard } from "@metaplex-foundation/mpl-token-metadata-kit";
// For fungible tokens
tokenStandard: TokenStandard.Fungible;
// For NFTs
tokenStandard: TokenStandard.NonFungible;
// For programmable NFTs (enforced royalties)
tokenStandard: TokenStandard.ProgrammableNonFungible;

Format des métadonnées hors chaîne

Le champ uri pointe vers un fichier JSON contenant des métadonnées étendues. Le format standard suit le Standard de métadonnées de jeton Metaplex :

token-metadata.json
{
"name": "My Token",
"symbol": "MTK",
"description": "A description of the token",
"image": "https://example.com/token-image.png",
"external_url": "https://example.com",
"attributes": [
{
"trait_type": "Category",
"value": "Utility"
}
],
"properties": {
"files": [
{
"uri": "https://example.com/token-image.png",
"type": "image/png"
}
]
}
}

Stockez votre fichier JSON de métadonnées sur une solution de stockage fiable et permanente comme Arweave, IPFS ou un CDN dédié. Si l'URI devient inaccessible, les portefeuilles et explorateurs ne pourront pas afficher les métadonnées de votre jeton.

Structure du compte de métadonnées

Le compte de métadonnées en chaîne contient :

pub struct Metadata {
pub key: Key, // Account type identifier
pub update_authority: Pubkey, // Can update metadata
pub mint: Pubkey, // Associated mint
pub name: String, // Token name (max 32 chars)
pub symbol: String, // Token symbol (max 10 chars)
pub uri: String, // URI to off-chain JSON (max 200 chars)
pub seller_fee_basis_points: u16, // Royalty % (100 = 1%)
pub creators: Option<Vec<Creator>>, // Creator list with shares
pub primary_sale_happened: bool, // Primary sale flag
pub is_mutable: bool, // Can metadata be updated
pub edition_nonce: Option<u8>, // Edition nonce
pub token_standard: Option<TokenStandard>, // Token type
pub collection: Option<Collection>, // Collection info
pub uses: Option<Uses>, // Use tracking
}

Bonnes pratiques

  1. Définir la mutabilité appropriée : Utilisez isMutable: false pour les jetons qui ne devraient jamais changer
  2. Utiliser un hébergement URI fiable : Les métadonnées hors chaîne doivent être sur un stockage permanent
  3. Vérifier les créateurs : Les adresses des créateurs doivent être vérifiées pour confirmer l'authenticité
  4. Considérer les redevances : Définir sellerFeeBasisPoints pour les redevances sur les ventes secondaires (les places de marché peuvent ou non les appliquer)

Is this page helpful?

Table des matières

Modifier la page

Géré par

© 2026 Fondation Solana.
Tous droits réservés.
Restez connecté