Mint avec Rarible

Rarible est un protocole et une place de marché NFT multichaîne qui fournit des SDK et des API pour créer des applications NFT sur plusieurs réseaux EVM.

Pour le minting de NFT, le Rarible Multichain SDK vous permet de frapper dans vos propres collections ou des collections partagées et de créer immédiatement des ordres de vente.

Parce que le SDK Rarible ne gère pas le téléchargement vers IPFS, nos exemples ici utilisent Pinata comme hôte IPFS. Vous aurez besoin d’un compte Pinata afin d’obtenir une clé JWT.

Ils exigeront également que vous ayez :

  • Un contrat ERC-721 déjà déployé sur Chiliz Chain. Vous devez déployer un contrat OpenZeppelin ERC-721 sur Chiliz Chain vous-même. Remix IDE vous offre un environnement dans le navigateur pour le faire. N’oubliez pas de vérifier le contrat en utilisant un explorateur de blocs !

  • Une clé API Rarible. Consultez leur guide de démarrage pour savoir comment en obtenir une :

Pour utiliser le SDK Rarible, nous avons besoin de quelques installations :

npm i @rarible/sdk @rarible/types ethers dotenv pinata

Frapper une collection de NFT

Tout d’abord, créez votre fichier .env :

# Chiliz RPC
RPC_URL=https://spicy-rpc.chiliz.com       # ou un RPC Mainnet
PRIVATE_KEY=0xabc...                       # clé du minter (CÔTÉ SERVEUR UNIQUEMENT)

# Rarible
RARIBLE_API_KEY=votre_cle_api_rarible
COLLECTION_ADDRESS=0xVotreCollectionSurChiliz
SUPPLY=1                                   # 1 = ERC-721, >1 = ERC-1155

# Pinata
PINATA_JWT=eyJhbGciOi...                   # JWT Pinata depuis le tableau de bord
PINATA_GATEWAY=votre-sous-domaine.mypinata.cloud

# Entrées média / métadonnées
IMAGE_PATH=./art/image.png
NAME=Mon NFT Chiliz
DESCRIPTION=Frappe on-chain via Rarible SDK

Notre flux de travail de choix est :

  1. Télécharger les médias sur IPFS via Pinata

  2. Construire et télécharger le fichier de métadonnées

  3. Rarible SDK + mint on-chain

Voici le script d’exemple complet dont vous pouvez vous inspirer :

import 'dotenv/config'
import fs from 'fs'
import path from 'path'
import { Wallet, JsonRpcProvider } from 'ethers'
import { createRaribleSdk } from '@rarible/sdk'
import { toCollectionId, toUnionAddress } from '@rarible/types'
import { PinataSDK } from 'pinata'

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() {
  // Télécharger les médias vers IPFS
  const pinata = new PinataSDK({
    pinataJwt: process.env.PINATA_JWT!,
  })

  const mediaPath = process.env.IMAGE_PATH!
  const mediaBlob = new Blob([fs.readFileSync(mediaPath)], { type: guessMime(mediaPath) })
  const mediaFile = new File([mediaBlob], path.basename(mediaPath), { type: guessMime(mediaPath) })

  const mediaUpload = await pinata.upload.public.file(mediaFile)
  const imageUri = `ipfs://${mediaUpload.cid}`
  // console.log('imageUri:', imageUri)

  // Construire et télécharger le fichier de métadonnées
  const metadata = {
    name: process.env.NAME!,
    description: process.env.DESCRIPTION!,
    image: imageUri,
    // animation_url: "ipfs://<cid>/video.mp4",
    // attributes: [{ trait_type: "Tier", value: "Gold" }],
  }
  const metaUpload = await pinata.upload.public.json(metadata)
  const metadataUri = `ipfs://${metaUpload.cid}`
  // console.log('metadataUri:', metadataUri)

  // Mint on-chain Rarible
  const provider = new JsonRpcProvider(process.env.RPC_URL!)
  const wallet = new Wallet(process.env.PRIVATE_KEY!, provider)
  const sdk = createRaribleSdk(wallet, 'prod', { apiKey: process.env.RARIBLE_API_KEY! })

  // Les IDs Union utilisent "<BLOCKCHAIN>:<address>" — ici BLOCKCHAIN est "CHILIZ"
  const collectionId = toCollectionId(`CHILIZ:${process.env.COLLECTION_ADDRESS}`)
  const creator = toUnionAddress(`CHILIZ:${wallet.address}`)

  const { transaction, itemId } = await sdk.nft.mint({
    collectionId,
    uri: metadataUri,
    supply: Number(process.env.SUPPLY || 1), // 1 pour 721, >1 pour 1155
  })

  const { hash } = await transaction.wait()
  console.log('Minted item:', itemId, 'tx:', hash)
}

main().catch((e) => (console.error(e), process.exit(1)))

Mint paresseux (lazy-minting) d’une collection NFT

Le Minting paresseux est une option pour ceux qui ne veulent pas supporter le coût initial de frapper un NFT avant de le mettre en vente. Ils peuvent mettre leur NFT en vente, puis le frapper uniquement lorsqu’il est acheté ou transféré. Les frais de gas font donc partie du processus de frappe, et sont payés par l’acheteur.

En bref, le minting paresseux consiste à inscrire le NFT sur la blockchain uniquement lorsqu’une personne achète le NFT, et non avant.

Vous aurez besoin d’un fichier .env correctement défini :

# Chiliz RPC / wallet
RPC_URL=https://spicy-rpc.chiliz.com
PRIVATE_KEY=0xabc...                         # clé du créateur (garder secrète)

# Rarible
RARIBLE_API_KEY=votre_cle_api_rarible
COLLECTION_ADDRESS=0xVotreCollectionSurChiliz   # ERC-721 ou ERC-1155

# Pinata
PINATA_JWT=eyJhbGciOi...                      # JWT Pinata depuis le tableau de bord
PINATA_GATEWAY=votre-sous-domaine.mypinata.cloud  # optionnel (pour les aperçus)

# Média / métadonnées
IMAGE_PATH=./art/image.png
NAME=Mon NFT Chiliz
DESCRIPTION=Minté paresseusement sur Rarible (Chiliz)
SUPPLY=1                                      # 1 pour 721 ; >1 pour éditions 1155

Et maintenant le code d’exemple pour mint paresseusement votre projet :

import 'dotenv/config'
import fs from 'fs'
import path from 'path'
import { Wallet, JsonRpcProvider } from 'ethers'
import { createRaribleSdk } from '@rarible/sdk'
import { toCollectionId, toUnionAddress } from '@rarible/types'
import { PinataSDK } from 'pinata'

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() {
  // Télécharger les médias vers IPFS
  const pinata = new PinataSDK({
    pinataJwt: process.env.PINATA_JWT!,
  })

  const mediaPath = process.env.IMAGE_PATH!
  const mediaBlob = new Blob([fs.readFileSync(mediaPath)], { type: guessMime(mediaPath) })
  const mediaFile = new File([mediaBlob], path.basename(mediaPath), { type: guessMime(mediaPath) })
  const mediaUp = await pinata.upload.public.file(mediaFile)
  const imageUri = `ipfs://${mediaUp.cid}`

  const metadata = {
    name: process.env.NAME!,
    description: process.env.DESCRIPTION!,
    image: imageUri,
    // animation_url: "ipfs://<cid>/video.mp4",
    // attributes: [{ trait_type: "Tier", value: "Gold" }],
  }
  const metaUp = await pinata.upload.public.json(metadata)
  const metadataUri = `ipfs://${metaUp.cid}`

  // Mint paresseux Rarible
  const provider = new JsonRpcProvider(process.env.RPC_URL!)
  const wallet = new Wallet(process.env.PRIVATE_KEY!, provider)
  const sdk = createRaribleSdk(wallet, 'prod', { apiKey: process.env.RARIBLE_API_KEY! })
  const collectionId = toCollectionId(`CHILIZ:${process.env.COLLECTION_ADDRESS}`)
  const creator = toUnionAddress(`CHILIZ:${wallet.address}`)

  // Préparer et soumettre le mint paresseux (élément hors chaîne ; l’acheteur frappe lors de l’achat)
  const prepared = await sdk.nft.mint.prepare({ collectionId })
  const result = await prepared.submit({
    uri: metadataUri,
    supply: Number(process.env.SUPPLY || 1),     // 1 pour 721 ; >1 pour 1155
    lazyMint: true,                              // Oui, le rendre paresseux s’il vous plaît
    creators: [{ account: creator, value: 10000 }], // 100 % vont à votre portefeuille
    royalties: [],                               // ex. [{ account: creator, value: 500 }] pour 5 %
  })

  // console.log('Lazy itemId:', result.itemId)
}

main().catch((e) => (console.error(e), process.exit(1)))

Mis à jour

Ce contenu vous a-t-il été utile ?