Mint avec thirdweb
thirdweb est une plateforme qui propose des outils et une infrastructure pour construire des applications décentralisées sur plusieurs réseaux de blockchain. Elle simplifie l'intégration de la blockchain avec des SDK, des API et des composants préconstruits.
Dans le cas du minting NFT, thirdweb propose un tableau de bord soigné et un téléversement sur IPFS ainsi que des contrats audités et des SDKs étendus.
Mint d'un seul NFT manuellement
Si vous souhaitez simplement téléverser une seule image et la minter, thirdweb propose une interface de déploiement en un clic.
Tout d'abord, créez un compte thirdweb en utilisant votre portefeuille Web3 en tant que propriétaire. Cela vous donne accès à votre tableau de bord thirdweb.
À partir de là, vous pouvez choisir entre deux voies :
Utilisez leur TokenERC721 page et son bouton "Deploy Now".
Ou utilisez l'interface "Create Token" du tableau de bord.
Explorons rapidement chacune sur cette page. Le Portail développeur thirdweb vous donnera plus d'informations si vous en avez besoin.
Utilisation de la page TokenERC721
Allez sur la TokenERC721 page. Celle-ci s'appuie sur leur contrat pour créer une collection NFT.
Cliquez sur "Deploy Now" pour accéder à la page de déploiement du contrat.

Remplissez la section "Contract metadata" :
Téléversez l'image que vous souhaitez représenter votre collection NFT (ou simplement l'image que vous souhaitez minter).
Donnez-lui un nom unique et un symbole/ticker pour votre collection.
Donnez-lui une description.
thirdweb remplit automatiquement les adresses de destinataire pour les "Primary Sales" et les "Royalties", assurez-vous que les adresses Web3 correspondent bien à celle de votre portefeuille.
Dans les "Deploy Options", choisissez Chiliz Chain (ou Chiliz Spicy Testnet si ce n'est qu'un test) et cliquez sur "Deploy Now" :

thirdweb commencera à déployer le contrat, déclenchant une fenêtre de confirmation de votre portefeuille Web3. Confirmez-la pour terminer le déploiement.

Une fois terminé, cliquez sur le bouton "View Contract". Vous serez dirigé vers la page du contrat sur votre tableau de bord thirdweb, avec une liste de contrôle/barre de progression :

Comme vous pouvez le voir dans la liste de contrôle, pour l'instant vous avez seulement déployé un contrat, vous devez encore réellement minter le NFT. Dans la colonne de gauche, cliquez sur l'élément de menu "NFTs" pour ouvrir une nouvelle page, qui est pour l'instant vide :

Cliquez sur le bouton "Mint" et un panneau latéral s'ouvre avec un champ pour chaque attribut de votre NFT. C'est ici que vous créez les métadonnées de votre NFT :

Remplissez les différents champs. Vous pouvez créer des champs spécifiques à votre collection NFT, tels que "Artist_name" ou "Type_of_work", et explorer des options avancées, mais pour ce test vous pouvez rester minimal : nom, fichier média, description.
Cliquez sur le bouton "Mint NFT" en bas du panneau latéral, et approuvez la transaction depuis votre portefeuille.

thirdweb affichera ensuite la page "NFTs", avec votre NFT désormais visible, attaché à votre contrat NFT.
TERMINÉ ! Vous avez minté votre NFT !
Pour vérifier qu'il est bien sur Chiliz Chain, ouvrez Chiliscan (ou sa variante Testnet si vous utilisez Spicy Testnet) et copiez-collez le hash du NFT dans le champ de recherche. Cela devrait confirmer immédiatement que votre contrat est sur la chaîne, et son onglet "Inventory" devrait lister votre NFT avec vous (ou au moins l'ID de votre portefeuille) comme propriétaire.

Si vous avez minté votre NFT sur Chiliz Chain Mainnet, vous devriez le voir apparaître dans votre compte sur des marketplaces telles que Rarible ou OKX, et à partir de là, vous pouvez commencer à le vendre !
Utilisation du bouton "Create Token"
C'est en fait une méthode plus directe que celle ci-dessus, et c'est une addition récente à thirdweb.
Depuis n'importe quel dossier de projet dans votre tableau de bord thirdweb, cliquez sur l'option "Tokens" dans la barre latérale gauche :

Dans la page "Tokens" qui s'ouvre, cliquez sur le bouton "Create Token" à droite. Une fenêtre modale s'ouvre avec 2 options, choisissez "Create NFT Collection".

Cela vous conduira à une version pas-à-pas de la TokenERC721 page de déploiement (en effet, elle déploiera un contrat ERC-721 Drop). Remplissez tous les champs nécessaires pour ce contrat, puis appuyez sur le bouton "Next".
L'écran suivant concerne le NFT lui-même : téléversez l'image et remplissez les champs décrivant votre image, puis appuyez sur le bouton "Next".
thirdweb affiche maintenant un récapitulatif de la collection NFT que vous êtes sur le point de lancer. Vérifiez que tout est correct puis cliquez sur le bouton "Launch NFT Collection".
thirdweb se charge de déployer le contrat, de minter le NFT et de définir les conditions, le tout en une seule opération. Vous devrez confirmer trois transactions via votre portefeuille Web3.

Une fois cela fait, cliquez sur le bouton "View NFT", et vous serez ramené à votre tableau de bord thirdweb, affichant la page spécifique à ce contrat — et ses NFTs attachés.
À partir de là, vous pouvez vérifier qu'il est bien sur la chaîne via un explorateur de blocs, ou commencer à vendre votre NFT via une marketplace.
Mint d'un seul NFT de façon programmatique
Voici un exemple de code utilisant le thirdweb v5 SDK, qui téléverse le fichier média sur IPFS, génère le metadata.json fichier, puis le téléverse aussi sur IPFS.
Ceci exigera que vous ayez :
Un contrat ERC-721 déjà déployé sur Chiliz Chain. Dans ce cas vous devriez le faire en utilisant thirdweb plutôt qu'un autre outil.
Une clé API thirdweb, liée au contrat ERC-721 que vous avez déployé via thirdweb. Vous pouvez la trouver dans la page du projet du smart contract, sous le nom "Client ID".
Une installation locale du SDK thirdweb. Vous pouvez le faire en utilisant
npm:
npm install thirdweb dotenvLe dotenv paramètre génère un .env fichier, qui est nécessaire pour stocker des valeurs privées :
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # Depuis la page de votre projet thirdweb.
PRIVATE_KEY=0xabc... # Le portefeuille Web3 qui enverra la transaction.
CONTRACT_ADDRESS=0xYour721Address # Votre contrat TokenERC721 déployé.
CHAIN_ID=88882 # 88888=Mainnet, 88882=Spicy
IMAGE_PATH=./art/image.png # Le chemin local vers votre fichier média.
NAME=My Chiliz NFT
DESCRIPTION=Minted on Chiliz ChainN'exposez jamais votre PRIVATE_KEY ni THIRDWEB_SECRET_KEY dans du code côté client !
Conservez ce fichier sur un serveur/CI sécurisé, et ne le téléversez pas dans un dépôt public
Maintenant que tout est prêt, vous pouvez vous inspirer de ce script, qui va :
Téléverser le fichier média sur IPFS
Construire et téléverser le
metadata.jsonfichierMinter le NFT en utilisant la méthode mintTo du contrat.
Afficher le
tokenIdettokenUrlpour vous.
Ceci n'est qu'un exemple de code, vous devrez l'adapter à votre propre projet !
import 'dotenv/config';
import fs from 'fs';
import path from 'path';
import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
import { privateKeyToAccount } from "thirdweb/wallets";
import { mintTo, transferEvent, getNFT } from "thirdweb/extensions/erc721";
import { upload } from "thirdweb/storage";
function guessMime(p: string) {
const ext = path.extname(p).toLowerCase();
if (ext === ".png") return "image/png";
if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
if (ext === ".webp") return "image/webp";
if (ext === ".gif") return "image/gif";
if (ext === ".mp4") return "video/mp4";
if (ext === ".webm") return "video/webm";
return "application/octet-stream";
}
async function main() {
const client = createThirdwebClient({ secretKey: process.env.THIRDWEB_SECRET_KEY! });
const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 or 88882
const account = privateKeyToAccount({ client, privateKey: process.env.PRIVATE_KEY! });
const contract = getContract({
client,
chain,
address: process.env.CONTRACT_ADDRESS as `0x${string}`,
});
// Upload media file to IPFS
const filePath = process.env.IMAGE_PATH!;
const buffer = fs.readFileSync(filePath);
const file = new File([buffer], path.basename(filePath), { type: guessMime(filePath) });
const [imageUri] = await upload({ client, files: [file] }); // returns ipfs://...
// console.log("imageUri:", imageUri);
// Build & upload metadata.json referencing IPFS imageUri
const metadata = {
name: process.env.NAME!,
description: process.env.DESCRIPTION!,
image: imageUri
};
const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
const metaFile = new File([metaBlob], "metadata.json", { type: "application/json" });
const [metadataUri] = await upload({ client, files: [metaFile] });
// console.log("metadataUri:", metadataUri);
// Prepare & send mintTo transaction using the metadata URI
// mintTo accepts a string to use directly as tokenURI.
const tx = mintTo({
contract,
to: account.address,
nft: metadataUri, // The tokenURI
});
const { transactionHash } = await sendTransaction({ transaction: tx, account });
//console.log("tx:", transactionHash);
const receipt = await waitForReceipt({ client, chain, transactionHash });
// Parse Transfer event to display tokenId
const events = parseEventLogs({ logs: receipt.logs, events: [transferEvent()] });
const minted = events.find(e => e.eventName === "Transfer" && e.args.from === "0x0000000000000000000000000000000000000000");
const tokenId = minted ? (minted.args.tokenId as bigint) : undefined;
//console.log("tokenId:", tokenId?.toString() ?? "(not found)");
if (tokenId !== undefined) {
const nft = await getNFT({ contract, tokenId });
//console.log("tokenURI (read back):", nft.tokenURI);
}
}
main().catch((err) => (console.error(err), process.exit(1)));Les parties importantes dont s'inspirer sont :
uploadstocke des fichiers (et du JSON) sur IPFS et retourneipfs://…URIs.mintToaccepte une chaîne à utiliser directement commetokenURI.Nous analysons l'événement standard ERC-721
Transferpour lire le minttokenId.
Mint d'une collection de NFTs de façon programmatique
Le mint d'une collection de NFTs n'est pas très différent du mint d'un seul. La différence la plus notable est que votre .env fichier pointe vers le dossier qui contient toutes les images en utilisant IMAGE_DIR, plutôt que vers une seule image avec IMAGE_PATH.
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # Depuis la page de votre projet thirdweb.
PRIVATE_KEY=0xabc... # Le portefeuille Web3 qui enverra la transaction.
CONTRACT_ADDRESS=0xYour721Address # Votre contrat TokenERC721 déployé.
CHAIN_ID=88882 # 88888=Mainnet, 88882=Spicy
IMAGE_PATH=./art # Le chemin local vers vos fichiers médias.
NAME_PREFIX=My Chiliz NFT # Cela deviendra : "My Chiliz NFT <n>"
DESCRIPTION=Minted on Chiliz ChainLe code d'exemple que nous représentons ici prend donc cela en compte :
import 'dotenv/config';
import fs from 'fs';
import path from 'path';
import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
import { privateKeyToAccount } from "thirdweb/wallets";
import { mintTo, transferEvent, getNFT } from "thirdweb/extensions/erc721";
import { upload } from "thirdweb/storage";
function guessMime(p: string) {
const ext = path.extname(p).toLowerCase();
if (ext === ".png") return "image/png";
if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
if (ext === ".webp") return "image/webp";
if (ext === ".gif") return "image/gif";
if (ext === ".mp4") return "video/mp4";
if (ext === ".webm") return "video/webm";
return "application/octet-stream";
}
// Une façon de rassembler tous les fichiers
function listMediaFiles(dir: string) {
const allow = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif", ".mp4", ".webm", ".svg"]);
return fs
.readdirSync(dir)
.filter((f) => allow.has(path.extname(f).toLowerCase()))
.map((f) => path.join(dir, f));
}
async function main() {
const client = createThirdwebClient({ secretKey: process.env.THIRDWEB_SECRET_KEY! });
const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 or 88882
const account = privateKeyToAccount({ client, privateKey: process.env.PRIVATE_KEY! });
const contract = getContract({
client,
chain,
address: process.env.CONTRACT_ADDRESS as `0x${string}`,
});
// Téléverser les fichiers médias d'un dossier vers IPFS
const dirPath = process.env.IMAGES_DIR!;
const filePaths = listMediaFiles(dirPath);
if (!filePaths.length) {
throw new Error(`No media files found in ${dirPath}`);
}
const fileObjs = filePaths.map((p) => {
const buffer = fs.readFileSync(p);
return new File([buffer], path.basename(p), { type: guessMime(p) });
});
const imageUris = await upload({ client, files: fileObjs }); // returns ["ipfs://...", ...]
//console.log("Uploaded images to IPFS:", imageUris.length, "files");
// Construire & téléverser chaque metadata.json référencant son imageUri
// Utilise les envs NAME et DESCRIPTION ; les noms deviennent "<NAME> #<index>"
const namePrefix = process.env.NAME!;
const description = process.env.DESCRIPTION!;
// Créer un tableau d'objets File pour les JSON de métadonnées
const metaFiles = imageUris.map((imageUri, i) => {
const metadata = {
name: `${namePrefix} #${i + 1}`,
description,
image: imageUri
};
const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
return new File([metaBlob], `metadata-${i + 1}.json`, { type: "application/json" });
});
const metadataUris = await upload({ client, files: metaFiles }); // ["ipfs://.../metadata-1.json", ...]
//console.log("Uploaded metadata files to IPFS:", metadataUris.length);
// Préparer & envoyer les transactions mintTo en utilisant les metadata URIs (séquentiel)
const ZERO = "0x0000000000000000000000000000000000000000";
for (let i = 0; i < metadataUris.length; i++) {
const metadataUri = metadataUris[i];
const tx = mintTo({
contract,
to: account.address,
nft: metadataUri, // The tokenURI
});
const { transactionHash } = await sendTransaction({ transaction: tx, account });
console.log(`[${i + 1}/${metadataUris.length}] tx:`, transactionHash);
const receipt = await waitForReceipt({ client, chain, transactionHash });
// Analyser l'événement Transfer pour obtenir le tokenId de ce mint
const events = parseEventLogs({ logs: receipt.logs, events: [transferEvent()] });
const minted = events.find(
(e) => e.eventName === "Transfer" && typeof e.args.from === "string" && e.args.from.toLowerCase() === ZERO
);
const tokenId = minted ? (minted.args.tokenId as bigint) : undefined;
// console.log(`[${i + 1}/${metadataUris.length}] tokenId:`, tokenId?.toString() ?? "(not found)");
if (tokenId !== undefined) {
const nft = await getNFT({ contract, tokenId });
// console.log(`[${i + 1}/${metadataUris.length}] tokenURI (read back):`, nft.tokenURI);
}
}
}
main().catch((err) => (console.error(err), process.exit(1)));
Les changements détaillés sont :
IMAGES_DIRremplaceIMAGE_PATH.Ajouté
listMediaFilespour rassembler plusieurs entrées.Regroupé
uploadpour les images et pour les métadonnées (conserve l'ordre).Boucle pour
mintTochaquemetadataUri, en analysant chaqueTransferévénement pour sontokenId.Les noms sont auto-numérotés :
NAME #1,NAME #2, … en utilisant votreNAME/DESCRIPTION.
Encore une fois, veuillez utiliser ceci comme source d'inspiration pour votre propre code, ne pas l'utiliser tel quel !
Remarque : Si vous préférez faire du lazy minting, le contrat ERC-721 de thirdweb dispose d'une une lazyMint méthode.
Mis à jour
Ce contenu vous a-t-il été utile ?