> For the complete documentation index, see [llms.txt](https://docs.chiliz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chiliz.com/pt-br/desenvolver/avancado/trabalhar-com-nfts/mintar-com-rarible.md).

# Mintar com Rarible

O Rarible é um protocolo e marketplace NFT multichain que fornece SDKs e APIs para criar aplicações NFT em diversas redes EVM.

Para mintagem de NFTs, o [Rarible Multichain SDK](https://docs.rarible.org/reference/getting-started) permite mintar em coleções próprias ou compartilhadas e criar ordens de venda imediatamente.

Como o Rarible SDK não lida com upload de IPFS, os exemplos aqui usam o [Pinata](https://pinata.cloud/) como host IPFS. Você precisará de uma conta Pinata para obter uma chave JWT.

Também será necessário ter:

* Um contrato ERC-721 já implantado na Chiliz Chain. Você precisa implantar um [contrato OpenZeppelin ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) na Chiliz Chain. O [Remix IDE](https://remix.ethereum.org/) oferece uma IDE no navegador para isso. Não se esqueça de verificar o contrato usando um block explorer!
* Uma chave de API Rarible. Consulte o "Getting Started" deles para obtê-la:

{% embed url="<https://docs.rarible.org/docs/rarible-protocol>" %}

Para usar o Rarible SDK, precisamos de algumas instalações:

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

{% hint style="warning" %}
Você notará que estamos usando `ethers`, que é uma alternativa ao `viem` usado em outras seções.\
De fato, o [Rarible recomenda](https://docs.rarible.org/reference/getting-started#interacting-with-evm-wallets) que desenvolvedores usem ethers.js ou web3.js para trabalhar com carteiras Web3 — e o [web3.js](https://web3js.org/#/) [foi descontinuado em março de 2025](https://blog.chainsafe.io/web3-js-sunset/), deixando apenas o `ethers` como escolha padrão.
{% endhint %}

## Mintando uma coleção de NFTs

Primeiro, crie seu arquivo `.env`:

```
# Chiliz RPC
RPC_URL=https://spicy-rpc.chiliz.com       # ou um RPC da Mainnet
PRIVATE_KEY=0xabc...                       # chave do mintador (somente lado do servidor)

# Rarible
RARIBLE_API_KEY=your_rarible_api_key
COLLECTION_ADDRESS=0xYourCollectionOnChiliz
SUPPLY=1                                   # 1 = ERC-721, >1 = ERC-1155

# Pinata
PINATA_JWT=eyJhbGciOi...                   # JWT do Pinata do dashboard
PINATA_GATEWAY=your-subdomain.mypinata.cloud

# Entradas de mídia / metadados
IMAGE_PATH=./art/image.png
NAME=My Chiliz NFT
DESCRIPTION=Minted on-chain via Rarible SDK
```

Nosso fluxo de trabalho preferido é:

1. Fazer upload da mídia para o IPFS via Pinata
2. Construir e fazer upload do arquivo de metadados
3. Rarible SDK + mint on-chain

Aqui está o script de exemplo completo do qual você pode se inspirar:

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```bash
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() {
  // Upload de mídia para o 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)

  // Construir e fazer upload do arquivo de metadados
  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 com 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! })

  // IDs Union usam "<BLOCKCHAIN>:<address>" — aqui BLOCKCHAIN é "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 para 721, >1 para 1155
  })

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

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

{% endcode %}

## Lazy-minting de uma coleção de NFTs

O Lazy Minting é uma opção para quem não quer o custo inicial de mintar um NFT antes de colocá-lo à venda. O NFT pode ser listado para compra e mintado somente quando for comprado ou transferido. As taxas de gas fazem parte do processo de mintagem, pagas pelo comprador.

Em resumo, lazy-minting significa colocar o NFT na blockchain somente quando alguém o compra, não antes.

Você precisará de um arquivo `.env` devidamente definido:

```
# Chiliz RPC / wallet
RPC_URL=https://spicy-rpc.chiliz.com
PRIVATE_KEY=0xabc...                         # chave do criador (mantenha em segredo)

# Rarible
RARIBLE_API_KEY=your_rarible_api_key
COLLECTION_ADDRESS=0xYourCollectionOnChiliz   # ERC-721 ou ERC-1155

# Pinata
PINATA_JWT=eyJhbGciOi...                      # JWT do Pinata do dashboard
PINATA_GATEWAY=your-subdomain.mypinata.cloud  # opcional (para pré-visualizações)

# Mídia / metadados
IMAGE_PATH=./art/image.png
NAME=My Chiliz NFT
DESCRIPTION=Lazy-minted on Rarible (Chiliz)
SUPPLY=1                                      # 1 para 721; >1 para edições 1155
```

E agora o código de exemplo para fazer lazy-mint do seu projeto:

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```typescript
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() {
  // Upload de mídia para o 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}`

  // Lazy mint com 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}`)

  // Preparar e enviar lazy mint (item off-chain; comprador minta na compra)
  const prepared = await sdk.nft.mint.prepare({ collectionId })
  const result = await prepared.submit({
    uri: metadataUri,
    supply: Number(process.env.SUPPLY || 1),        // 1 para 721; >1 para 1155
    lazyMint: true,                                  // Sim, lazy mint por favor
    creators: [{ account: creator, value: 10000 }], // 100% vai para sua carteira
    royalties: [],                                   // ex.: [{ account: creator, value: 500 }] para 5%
  })

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

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

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.chiliz.com/pt-br/desenvolver/avancado/trabalhar-com-nfts/mintar-com-rarible.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
