---
title: "Tutorial de NFT minter: como criar um dApp full stack"
description: "Descubra o mundo dos NFTs com nosso tutorial completo de NFT Minter. Aprenda a criar um dApp full-stack e comece a mintar seus ativos digitais agora!"
---

# Tutorial de NFT minter: como criar um dApp full stack

Neste tutorial, você vai construir um NFT minter e aprender a criar uma dApp full stack conectando seu smart contract a um frontend React usando Metamask e ferramentas Web3.

Além disso, não deixe de conferir o restante da nossa série de tutoriais de NFT:

- 🌟  [How to mint an NFT using Web3.js](https://www.alchemy.com/blog/how-to-mint-an-nft-using-web3-js)
- 🪄  [How to mint an NFT with Ether.js](https://www.alchemy.com/blog/how-to-mint-an-nft-with-ethers-js)
- 👛  [How to view your NFT in your mobile wallet](https://www.alchemy.com/blog/how-to-view-your-nft-in-your-mobile-wallet)
- 💸  [How to set a price on an NFT](https://www.alchemy.com/blog/how-to-set-a-price-on-an-nft)

Um dos maiores desafios para desenvolvedores vindos de um background Web2 é descobrir como conectar seu smart contract a um projeto frontend e interagir com ele.

Ao construir um NFT minter — uma UI simples onde você insere um link para seu ativo digital, um título e uma descrição — você vai aprender a:

- Conectar-se ao Metamask através do seu projeto frontend
- Chamar métodos do smart contract a partir do seu frontend
- Assinar transações usando o Metamask

Neste tutorial, vamos usar [React](https://reactjs.org/) como nosso framework frontend. Como este tutorial é focado principalmente em [desenvolvimento Web3](https://www.alchemy.com/overviews/how-to-learn-web3-development), não vamos gastar muito tempo detalhando os fundamentos do React. Em vez disso, vamos focar em trazer funcionalidade ao nosso projeto

<CalloutBlock>

Como pré-requisito, você deve ter um entendimento de nível iniciante de React — saber como componentes, props, useState/useEffect e chamadas de função básicas funcionam. Se você nunca ouviu falar de nenhum desses termos antes, talvez valha a pena conferir este [Intro to React tutorial](https://reactjs.org/tutorial/tutorial.html). Para quem aprende melhor de forma visual, recomendamos fortemente esta excelente série de vídeos [Full Modern React Tutorial](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d), da Net Ninja.

</CalloutBlock>

Sem mais delongas, vamos começar!

## Passo 0: fazendo NFTs 101

Antes mesmo de começarmos a olhar qualquer código, é importante entender como funciona a criação de um NFT. Isso envolve duas etapas:

1\) Você publica um smart contract de NFT na blockchain Ethereum. Geralmente, é um smart contract [ERC-721](https://eips.ethereum.org/EIPS/eip-721) ou [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155).

<CalloutBlock>

A maior diferença entre os dois padrões de smart contract de NFT é que o ERC-1155 é um padrão multi-token e inclui funcionalidade de batch, enquanto o ERC-721 é um padrão de token único e, portanto, só suporta a transferência de um token por vez.

</CalloutBlock>

2\) Você chama a função de minting nesse smart contract de NFT para mintar o NFT. _Minting_ é simplesmente o ato de publicar uma instância única do seu token não fungível na blockchain.

Normalmente, essa função de minting exige que você passe duas variáveis como parâmetros: primeiro o recipient, que especifica o endereço que receberá seu NFT recém-mintado, e segundo o tokenURI do NFT, uma string que resolve para um documento JSON descrevendo os metadados do NFT.

<CalloutBlock>

Os metadados de um NFT são o que realmente dão vida a ele, permitindo que tenha propriedades como nome, descrição, imagem \(ou outro ativo digital\) e outros atributos. Aqui está [um exemplo de tokenURI](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2), que contém os metadados de um NFT.

</CalloutBlock>

Neste tutorial, vamos focar na parte 2, chamando a função de minting de um smart contract de NFT existente usando nossa UI React.

​[Aqui está um link](https://sepolia.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) para o smart contract de NFT ERC-721 que vamos chamar neste tutorial. Se você quiser aprender como o criamos, recomendamos fortemente que confira nosso outro tutorial, "[How to Create an NFT](https://www.alchemy.com/blog/how-to-create-an-nft)."​

Legal, agora que entendemos como funciona a criação de um NFT, vamos clonar nossos arquivos iniciais!

## Passo 1: clone os arquivos iniciais

Primeiro, vá até o repositório do github [nft-minter-tutorial](https://github.com/alchemyplatform/nft-minter-tutorial) para obter os arquivos iniciais deste projeto. Clone esse repositório no seu ambiente local.

<CalloutBlock>

Não sabe como clonar um repositório? Confira [este guia](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) do Github.

</CalloutBlock>

Ao abrir esse repositório clonado **nft-minter-tutorial**, você vai notar que ele contém duas pastas: **minter-starter-files** e **nft-minter**.

- **minter-starter-files** contém os arquivos iniciais \(essencialmente a UI React\) deste projeto. Neste tutorial, **vamos trabalhar neste diretório**, conforme você aprende a dar vida a essa UI conectando-a à sua carteira Ethereum e a um smart contract de NFT.
- **nft-minter** contém o tutorial completo já finalizado e está ali como **referência** **caso você fique travado.**

Em seguida, abra sua cópia de **minter-starter-files** no seu editor de código favorito \(na Alchemy, somos grandes fãs do [VSCode](https://code.visualstudio.com/download)\), e navegue até sua pasta **src**:

Vamos trabalhar dentro da pasta "src"

<ImageBlock
  src="https://media.alchemy.com/1704629644-open-minter-starter-files-in-editor.png"
  alt="VSCode com o projeto minter-starter-files aberto, mostrando a pasta src"
  width={2880}
  height={1798}
  caption="Abra o minter-starter-files no editor de sua escolha"
/>

Todo o código que vamos escrever vai ficar dentro da pasta **src**. Vamos editar o componente **Minter.js** e escrever arquivos javascript adicionais para dar funcionalidade Web3 ao nosso projeto.

## Passo 2: confira nossos arquivos iniciais

Antes de começar a codar, é importante conferir o que já foi disponibilizado para nós nos arquivos iniciais.

#### Rode seu projeto React

Vamos começar rodando o projeto React no nosso navegador. A beleza do React é que, uma vez que temos nosso projeto rodando no navegador, qualquer mudança que salvarmos será atualizada ao vivo no navegador.

Para rodar o projeto, navegue até o diretório raiz da pasta **minter-starter-files** e rode `npm install` no seu terminal para instalar as dependências do projeto:

Depois que a instalação terminar, rode `npm start` no seu terminal:

Isso deve abrir [http://localhost:3000/](http://localhost:3000/) no seu navegador, onde você vai ver o frontend do nosso projeto. Ele deve consistir em 3 campos: um lugar para inserir um link para o ativo do seu NFT, inserir o nome do seu NFT e fornecer uma descrição.

<ImageBlock
  src="https://media.alchemy.com/1704629829-frontend-for-our-project.png"
  alt="Frontend do NFT minter com campos para link do asset, nome e descrição"
  width={2876}
  height={1606}
  caption="Como deve ficar a UI do seu projeto"
/>

Se você tentar clicar nos botões "Connect Wallet" ou "Mint NFT", vai notar que eles não funcionam — isso porque ainda precisamos programar a funcionalidade deles! :\)

#### O componente minter.js

<CalloutBlock>

**NOTA:** Certifique-se de estar na pasta **minter-starter-files** e não na pasta **nft-minter**!

</CalloutBlock>

Vamos voltar para a pasta **src** no nosso editor e abrir o arquivo **Minter.js**. É muito importante entendermos tudo nesse arquivo, já que é o principal componente React com o qual vamos trabalhar.

No topo deste arquivo, temos nossas variáveis de estado, que vamos atualizar após eventos específicos.

<CalloutBlock>

Nunca ouviu falar de variáveis de estado do React ou state hooks? Confira [esta](https://reactjs.org/docs/hooks-state.html) documentação.

</CalloutBlock>

Aqui está o que cada uma das variáveis representa:

- **walletAddress** - uma string que armazena o endereço da carteira do usuário
- **status** - uma string que contém uma mensagem a ser exibida na parte inferior da UI
- **name** - uma string que armazena o nome do NFT
- **description** - uma string que armazena a descrição do NFT
- **url** - uma string que é um link para o ativo digital do NFT

Depois das variáveis de estado, você vai ver três funções não implementadas: `useEffect`, `connectWalletPressed` e `onMintPressed`. Você vai notar que todas essas funções são **async**, porque faremos chamadas de API assíncronas nelas! Seus nomes são homônimos das suas funcionalidades:

- [**useEffect**](https://reactjs.org/docs/hooks-effect.html) - este é um hook do React que é chamado depois que seu componente é renderizado. Como ele tem um prop de array vazio **\[\]** passado nele \(veja a linha 3\), ele só será chamado na _primeira_ renderização do componente. Aqui vamos chamar nosso wallet listener e outra função de wallet para atualizar nossa UI e refletir se uma carteira já está conectada.
- **connectWalletPressed** - esta função será chamada para conectar a carteira Metamask do usuário à nossa dApp.
- **onMintPressed** - esta função será chamada para mintar o NFT do usuário.

Perto do final deste arquivo, temos a UI do nosso componente. Se você examinar esse código com cuidado, vai notar que atualizamos nossas variáveis de estado `url`, `name` e `description` quando o input nos respectivos campos de texto muda.

Você também vai ver que `connectWalletPressed` e `onMintPressed` são chamados quando os botões com IDs **mintButton** e **walletButton** são clicados, respectivamente.‍

Por fim, vamos ver onde esse componente Minter é adicionado.

Se você for ao arquivo **App.js**, que é o componente principal no React que atua como container para todos os outros componentes, vai ver que nosso componente Minter é injetado na linha 7.

**Neste tutorial, vamos apenas editar o arquivo Minter.js e adicionar arquivos na nossa pasta src.**

Agora que entendemos com o que estamos trabalhando, vamos configurar nossa carteira Ethereum!

## Passo 3: configure sua carteira Ethereum

Para que os usuários consigam interagir com seu smart contract, eles precisarão conectar sua carteira Ethereum à sua dApp.

#### Baixe o MetaMask

Para este tutorial, vamos usar o Metamask, uma carteira virtual no navegador usada para gerenciar seu endereço de conta Ethereum. Se quiser entender mais sobre como funcionam as transações no Ethereum, confira [esta página](https://ethereum.org/en/developers/docs/transactions/) da Ethereum foundation.

Você pode baixar e criar uma conta Metamask gratuitamente [aqui](https://metamask.io/download.html). Ao criar uma conta, ou se você já tiver uma conta, certifique-se de mudar para a "Ropsten Test Network" no canto superior direito \(para que não lidemos com dinheiro de verdade\).

<ImageBlock
  src="https://media.alchemy.com/1704630094-sample-metamask-wallet.png"
  alt="Carteira MetaMask trocada para a rede de teste Ropsten"
  width={712}
  height={1194}
  caption="Exemplo de carteira Metamask"
/>

#### Adicione ether de um faucet

Para mintarmos nossos NFTs \(ou assinar qualquer transação na blockchain Ethereum\), vamos precisar de algum Eth fictício. Para obter Eth, você pode ir ao [Sepolia faucet](/faucets/ethereum-sepolia) e inserir o endereço da sua conta Ropsten, depois clicar em "Send Ropsten Eth." Você deve ver Eth na sua conta Metamask logo depois!

#### Confira seu saldo

Para confirmar que nosso saldo está lá, vamos fazer uma requisição `eth_getBalance` usando a [ferramenta composer da Alchemy](https://www.alchemy.com/composer/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Isso vai retornar a quantidade de Eth na nossa carteira. Depois de inserir o endereço da sua conta Metamask e clicar em "Send Request", você deve ver uma resposta assim:

<CalloutBlock>

**NOTA:** Esse resultado está em wei, não em eth. Wei é usado como a menor denominação de ether. A conversão de wei para eth é: 1 eth = 10¹⁸ wei. Então, se convertermos 0xde0b6b3a7640000 para decimal, obtemos 1\*10¹⁸, que é igual a 1 eth.

</CalloutBlock>

Ufa! Nosso dinheiro fictício está todo lá! 🤑

## Passo 4: conecte o MetaMask à sua UI

Agora que nossa carteira Metamask está configurada, vamos conectar nossa dApp a ela!

Como queremos seguir o paradigma [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), vamos criar um arquivo separado que contém nossas funções para gerenciar a lógica, os dados e as regras da nossa dApp, e depois passar essas funções para nosso frontend \(nosso componente Minter.js\).

#### A função connectWallet

Para fazer isso, vamos criar uma nova pasta chamada **utils** no seu diretório **src** e adicionar um arquivo chamado **interact.js** dentro dela, que vai conter todas as nossas funções de interação com a carteira e o smart contract.

No nosso arquivo **interact.js**, vamos escrever uma função `connectWallet`, que depois vamos importar e chamar no nosso componente **Minter.js**.

No seu arquivo **interact.js**, adicione o seguinte

Vamos analisar o que esse código faz:

Primeiro, nossa função verifica se `window.ethereum` está habilitado no seu navegador.

<CalloutBlock>

window.ethereum é uma API global injetada pelo Metamask e outros provedores de carteira que permite que sites solicitem as contas Ethereum dos usuários. Se aprovado, ele pode ler dados das blockchains às quais o usuário está conectado e sugerir que o usuário assine mensagens e transações. Confira a [documentação do Metamask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) para mais informações!

</CalloutBlock>

Se `window.ethereum` _não_ estiver presente, isso significa que o Metamask não está instalado. Isso resulta na devolução de um objeto JSON, onde o **address** retornado é uma string vazia, e o objeto JSX **status** informa que o usuário precisa instalar o Metamask.

<CalloutBlock>

**A maioria das funções que escrevemos vai retornar objetos JSON que podemos usar para atualizar nossas variáveis de estado e a UI.**

</CalloutBlock>

Agora, se `window.ethereum ` _estiver_ presente, é aí que as coisas ficam interessantes.

Usando um loop try/catch, vamos tentar conectar ao Metamask chamando [`window.ethereum.request\(\{ method: "eth\_requestAccounts" \}\);`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)` `. Chamar essa função abre o Metamask no navegador, e o usuário é solicitado a conectar sua carteira à sua dApp.

- Se o usuário escolher conectar, `method: "eth_requestAccounts"` retornará um array que contém todos os endereços de conta do usuário que se conectaram à dApp. No geral, nossa função `connectWallet` vai retornar um objeto JSON que contém o *primeiro* `address` desse array \(veja a linha 9\) e uma mensagem `status` que solicita ao usuário que escreva uma mensagem para o smart contract.
- Se o usuário rejeitar a conexão, então o objeto JSON vai conter uma string vazia para o `address` retornado e uma mensagem `status` que reflete que o usuário rejeitou a conexão.

#### Adicione a função connectWallet ao componente de UI minter.js

Agora que escrevemos essa função `connectWallet`, vamos conectá-la ao nosso componente **Minter.js**.

Primeiro, vamos ter que importar nossa função no nosso arquivo **Minter.js** adicionando

`import \{ connectWallet \} from "./utils/interact.js"`**;** no topo do arquivo Minter.js. Suas primeiras 11 linhas de **Minter.js** devem ficar assim:

Depois, dentro da nossa função `connectWalletPressed`, vamos chamar nossa função importada `connectWallet`, assim:

Percebeu como a maior parte da nossa funcionalidade fica abstraída do nosso componente **Minter.js** e no arquivo **interact.js**? Isso é para seguirmos o paradigma M-V-C!

Em `connectWalletPressed`, simplesmente fazemos uma chamada await para nossa função importada `connectWallet`, e usando sua resposta, atualizamos nossas variáveis `status` e `walletAddress` através dos seus state hooks.

Agora, vamos salvar os dois arquivos \(**Minter.js** e **interact.js**\) e testar nossa UI até aqui.

Abra seu navegador na página [http://localhost:3000/](http://localhost:3000/) e pressione o botão "Connect Wallet" no canto superior direito da página.

Se você tiver o Metamask instalado, deve ser solicitado a conectar sua carteira à sua dApp. Aceite o convite para conectar.

Você deve ver que o botão da carteira agora reflete que seu endereço está conectado! Yasssss 🔥

Agora, tente atualizar a página... isso é estranho. Nosso botão de carteira está solicitando que conectemos o Metamask, mesmo já estando conectado...

<ImageBlock
  src="https://media.alchemy.com/1704630515-the-problem-on-page-reload.gif"
  alt="Botão da carteira pedindo incorretamente para reconectar o MetaMask após recarregar a página"
  width={946}
  height={480}
  caption="O problema ao recarregar a página"
/>

Mas não se preocupe! Podemos resolver isso facilmente implementando uma função chamada `getCurrentWalletConnected`, que vai verificar se um endereço já está conectado à nossa dApp e atualizar nossa UI de acordo!

#### A função getCurrentWalletConnected

No seu arquivo **interact.js**, adicione a seguinte função `getCurrentWalletConnected`:

Esse código é _muito_ parecido com a função `connectWallet` que acabamos de escrever.

A principal diferença é que, em vez de chamar o método `eth_requestAccounts`, que abre o Metamask para o usuário conectar sua carteira, aqui chamamos o método `eth_accounts`, que simplesmente retorna um array contendo os endereços Metamask atualmente conectados à nossa dApp.

Para ver essa função em ação, vamos chamá-la na função `useEffect` do nosso componente **Minter.js**.

Assim como fizemos para `connectWallet`, precisamos importar essa função do nosso arquivo **interact.js** para o nosso arquivo **Minter.js**, assim:

Agora, simplesmente a chamamos na nossa função `useEffect`:

Percebeu que usamos a resposta da nossa chamada a `getCurrentWalletConnected` para atualizar nossas variáveis de estado `walletAddress` e `status`.

Depois de adicionar esse código, tente atualizar sua janela do navegador. O botão deve dizer que você está conectado e mostrar uma prévia do endereço da sua carteira conectada - mesmo depois de atualizar! 😅

#### Implemente o addWalletListener

O passo final na configuração da carteira da nossa dApp é implementar o wallet listener para que nossa UI se atualize quando o estado da nossa carteira mudar, como quando o usuário desconecta ou troca de contas.

No seu arquivo **Minter.js**, adicione uma função `addWalletListener` parecida com a seguinte:

Vamos analisar rapidamente o que está acontecendo aqui:

Primeiro, nossa função verifica se `window.ethereum` está habilitado \(ou seja, se o Metamask está instalado\).

- Se não estiver, simplesmente definimos nossa variável de estado `status` como uma string JSX que solicita ao usuário que instale o Metamask.
- Se estiver habilitado, configuramos o listener `window.ethereum.on("accountsChanged")` na linha 3, que escuta mudanças de estado na carteira Metamask, incluindo quando o usuário conecta uma conta adicional à dApp, troca de contas ou desconecta uma conta. Se houver pelo menos uma conta conectada, a variável de estado `walletAddress` é atualizada com a primeira conta no array `accounts` retornado pelo listener. Caso contrário, `walletAddress` é definido como uma string vazia.

Finalmente, precisamos chamá-la na nossa função `useEffect`:

E voilà! Terminamos de programar toda a nossa funcionalidade de carteira! Agora que nossa carteira está configurada, vamos descobrir como mintar nosso NFT!

## Passo 5: metadados de NFT 101

Então, lembra dos metadados de NFT que mencionamos no Passo 0 deste tutorial — eles dão vida a um NFT, permitindo que ele tenha propriedades, como um ativo digital, nome, descrição e outros atributos.

Vamos precisar configurar esses metadados como um objeto JSON e armazená-lo, para que possamos passá-lo como o parâmetro `tokenURI` ao chamar a função `mintNFT` do nosso smart contract.

O texto nos campos "Link to Asset", "Name" e "Description" vai compor as diferentes propriedades dos metadados do nosso NFT. Vamos formatar esses metadados como um objeto JSON, mas existem algumas opções de onde podemos armazenar esse objeto JSON:

- Poderíamos armazená-lo na blockchain Ethereum; no entanto, fazer isso seria SUPER caro \(estamos falando de valores acima de centenas de dólares\) devido à natureza do Ethereum. ❌
- Poderíamos armazená-lo em um servidor centralizado, como AWS ou Firebase. Mas isso iria contra nosso princípio de descentralização. ❌
- Poderíamos usar o IPFS, um protocolo descentralizado e rede peer-to-peer para armazenar e compartilhar dados em um sistema de arquivos distribuído. Como esse protocolo é descentralizado e gratuito, é nossa melhor opção! ✅

Para armazenar nossos metadados no IPFS, vamos usar o [Pinata](https://pinata.cloud/), uma API e toolkit de IPFS conveniente. No próximo passo, vamos explicar exatamente como fazer isso!

## Passo 6: use o Pinata para fixar seus metadados no IPFS

Se você não tem uma conta Pinata, cadastre-se para uma conta gratuita [aqui](https://app.pinata.cloud/register) e complete as etapas para verificar seu e-mail e conta.

#### Crie sua chave de API do Pinata

Navegue até a página [https://app.pinata.cloud/developers/api-keys](https://app.pinata.cloud/developers/api-keys), depois selecione o botão "New Key" no topo, defina o widget Admin como habilitado e nomeie sua chave.

<ImageBlock
  src="https://media.alchemy.com/1704630785-create-your-pinata-api-key.png"
  alt="Página de API keys do Pinata: criando uma nova key com o widget Admin habilitado"
  width={2880}
  height={1644}
  caption="Crie sua API key do Pinata"
/>

Em seguida, será exibido um popup com as informações da sua API. Certifique-se de guardar isso em um lugar seguro.

<ImageBlock
  src="https://media.alchemy.com/1704630855-save-your-api-key-and-secret.png"
  alt="Salve sua API key e secret em um lugar seguro"
  width={2880}
  height={1650}
  caption="Salve sua API key e secret em um lugar seguro"
/>

Agora que nossa chave está configurada, vamos adicioná-la ao nosso projeto para podermos usá-la.

#### Crie um arquivo .env

Podemos armazenar com segurança nossa chave e secret do Pinata em um arquivo de ambiente. Vamos instalar o [pacote dotenv](https://www.npmjs.com/package/dotenv) no diretório do seu projeto.

Abra uma nova aba no seu terminal \(separada da que está rodando o localhost\) e certifique-se de estar na pasta **minter-starter-files**, depois rode o seguinte comando no seu terminal:

Em seguida, crie um arquivo **.env** no diretório raiz do seu **minter-starter-files** inserindo o seguinte na sua linha de comando:

Isso vai abrir seu arquivo **.env** no vim \(um editor de texto\). Para salvá-lo, pressione "esc" \+ ":" \+ "q" no teclado, nessa ordem.

Em seguida, no VSCode, navegue até seu arquivo .env e adicione sua chave de API do Pinata e o API secret a ele, assim:

Salve o arquivo, e então você está pronto para começar a escrever a função que envia seus metadados JSON para o IPFS!

#### Implemente pinJSONToIPFS

Felizmente para nós, o Pinata tem uma [API especificamente para enviar dados JSON ao IPFS](https://docs.pinata.cloud#PinJSONToIPFS) e um exemplo conveniente em JavaScript com axios que podemos usar, com pequenas modificações.

Na sua pasta utils, vamos criar outro arquivo chamado pinata.js e depois importar nosso secret e chave do Pinata do arquivo .env, assim:

Em seguida, cole o código adicional abaixo no seu arquivo pinata.js. Não se preocupe, vamos detalhar o que tudo isso significa!

Então, o que esse código faz exatamente?

Primeiro, ele importa o [axios](https://www.npmjs.com/package/axios), um cliente HTTP baseado em promises para o navegador e node.js, que vamos usar para fazer uma requisição ao Pinata.

Depois temos nossa função assíncrona `pinJSONToIPFS`, que recebe um `JSONBody` como entrada e a chave e secret da api do Pinata no seu header, tudo para fazer uma requisição POST à API `pinJSONToIPFS` deles.

- Se essa requisição POST for bem-sucedida, então nossa função retorna um objeto JSON com o boolean `success` como true e o `pinataUrl` onde nossos metadados foram fixados. Vamos usar esse `pinataUrl` retornado como a entrada `tokenURI` para a função mint do nosso smart contract.
- Se essa requisição post falhar, então nossa função retorna um objeto JSON com o boolean `success` como false e uma string `message` que relata nosso erro.

Assim como com os tipos de retorno da nossa função `connectWallet`, estamos retornando objetos JSON para que possamos usar seus parâmetros para atualizar nossas variáveis de estado e a UI.

## Passo 7: carregue seu smart contract

Agora que temos uma forma de enviar os metadados do nosso NFT para o IPFS através da nossa função pinJSONToIPFS, vamos precisar de uma forma de carregar uma instância do nosso smart contract para podermos chamar sua função mintNFT.

<CalloutBlock>

Como mencionamos antes, neste tutorial vamos usar [este smart contract de NFT existente](https://sepolia.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE); no entanto, se você quiser aprender como o criamos, ou criar um você mesmo, recomendamos fortemente que confira nosso outro tutorial, "[How to Create an NFT](https://www.alchemy.com/blog/how-to-create-an-nft)."

</CalloutBlock>

#### O ABI do contrato

Se você examinou nossos arquivos com atenção, deve ter notado que no nosso diretório **src** há um arquivo **contract-abi.json**. Um ABI é necessário para especificar qual função um contrato vai invocar, bem como garantir que a função vai retornar dados no formato que você espera.

Também vamos precisar de uma chave de API da Alchemy e da Alchemy Web3 API para conectar à blockchain Ethereum e carregar nosso smart contract.

#### Crie sua chave de API da Alchemy

Se você ainda não tem uma conta Alchemy, [cadastre-se gratuitamente aqui](https://alchemy.com/?r=affiliate:d8895272-924f-412b-b63c-60124deb9357).

Depois de criar uma conta Alchemy, você pode gerar uma chave de API criando um app. Isso vai nos permitir fazer requisições à rede de teste Ropsten.

Navegue até a página "Create App" no seu Alchemy Dashboard passando o mouse sobre "Apps" na barra de navegação e clicando em "Create App"

<ImageBlock
  src="https://media.alchemy.com/1704631152-create-a-new-app.jpg"
  alt="Dashboard da Alchemy: criando um novo app a partir do menu Apps"
  width={2880}
  height={1640}
  caption="Crie um novo app"
/>

Nomeie seu app \(escolhemos "My First NFT!"\), ofereça uma breve descrição, selecione "Staging" para o Environment \(usado para a organização do seu app\) e escolha "Ropsten" para sua network.

<ImageBlock
  src="https://media.alchemy.com/1704631219-configure-your-app-details.png"
  alt="Dashboard da Alchemy: configurando nome, descrição e rede Ropsten do app"
  width={2880}
  height={1640}
  caption="Configure os detalhes do seu app"
/>

Clique em "Create app" e pronto! Seu app deve aparecer na tabela abaixo.

Ótimo, agora que criamos nossa URL de API HTTP da Alchemy, copie-a para sua área de transferência, assim…

<ImageBlock
  src="https://media.alchemy.com/1704631290-copy-your-alchemy-api-key.gif"
  alt="Dashboard da Alchemy: copiando a URL da HTTP API do app para o arquivo .env"
  width={843}
  height={480}
  caption="Copie sua API key da Alchemy"
/>

…e depois vamos adicioná-la ao nosso arquivo **.env**. No geral, seu arquivo .env deve ficar assim:

Agora que temos o ABI do nosso contrato e nossa chave de API da Alchemy, estamos prontos para carregar nosso smart contract usando o [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3).

#### Configure seu endpoint Alchemy Web3 e o contrato

Primeiro, se você ainda não tiver, precisará instalar o [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) navegando até o diretório raiz **nft-minter-tutorial** no terminal:

Em seguida, vamos voltar para nosso arquivo **interact.js**. No topo do arquivo, adicione o seguinte código para importar sua chave Alchemy do arquivo .env e configurar seu endpoint Alchemy Web3:

<CalloutBlock>

O [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) é um wrapper em torno do [Web3.js](https://web3js.readthedocs.io/en/v1.2.9/), que fornece métodos de API aprimorados e outros benefícios importantes para facilitar sua vida como desenvolvedor web3. Ele é projetado para exigir configuração mínima, então você pode começar a usá-lo no seu app imediatamente!

</CalloutBlock>

Em seguida, vamos adicionar o ABI do nosso contrato e o endereço do contrato ao nosso arquivo.

Uma vez que tivermos os dois, estamos prontos para começar a codar nossa função mint!

## Passo 8: implemente a função mintNFT

Dentro do seu arquivo **interact.js**, vamos definir nossa função, **mintNFT**, que, como o nome diz, vai mintar nosso NFT.

Como faremos diversas chamadas assíncronas \(ao Pinata para fixar nossos metadados no IPFS, à Alchemy Web3 para carregar nosso smart contract, e ao Metamask para assinar nossas transações\), nossa função também será assíncrona.

As três entradas da nossa função serão o `url` do nosso ativo digital, `name` e `description`. Adicione a seguinte assinatura de função abaixo da função `connectWallet`:

#### Tratamento de erros de entrada

Naturalmente, faz sentido ter algum tipo de tratamento de erros de entrada no início da função, para que saiamos dela caso nossos parâmetros de entrada não estejam corretos. Dentro da nossa função, vamos adicionar o seguinte código:

Essencialmente, se qualquer um dos parâmetros de entrada for uma string vazia, retornamos um objeto JSON onde o boolean `success` é false, e a string `status` informa que todos os campos na nossa UI devem ser preenchidos.

#### Envie os metadados para o IPFS

Uma vez que sabemos que nossos metadados estão formatados corretamente, o próximo passo é empacotá-los em um objeto JSON e enviá-los ao IPFS através da função `pinJSONToIPFS` que escrevemos!

Para isso, primeiro precisamos importar a função `pinJSONToIPFS` no nosso arquivo **interact.js**. Bem no topo do **interact.js**, vamos adicionar:

Lembre-se de que `pinJSONToIPFS` recebe um body JSON. Então, antes de fazermos uma chamada a ela, vamos precisar formatar nossos parâmetros `url`, `name` e `description` em um objeto JSON.

Vamos atualizar nosso código para criar um objeto JSON chamado `metadata` e depois fazer uma chamada a `pinJSONToIPFS` com esse parâmetro `metadata`:

Percebeu que armazenamos a resposta da nossa chamada a `pinJSONToIPFS(metadata)` no objeto `pinataResponse`? Então, analisamos esse objeto em busca de erros.

Se houver um erro, retornamos um objeto JSON onde o boolean `success` é false e nossa string `status` informa que nossa chamada falhou. Caso contrário, extraímos o `pinataURL` de `pinataResponse` e o armazenamos como nosso `tokenURIvariable`.

Agora é hora de carregar nosso smart contract usando a Alchemy Web3 API que inicializamos no topo do nosso arquivo. Adicione a seguinte linha de código ao final da função `mintNFT` para definir o contrato na variável global `window.contract`:

A última coisa a adicionar na nossa função `mintNFT` é nossa transação Ethereum:

Se você já está familiarizado com transações Ethereum, vai notar que a estrutura é bem parecida com o que já viu.

Primeiro, configuramos os parâmetros da nossa transação.

- `to` especifica o endereço do destinatário \(nosso smart contract\)
- `from` especifica o signatário da transação \(o endereço do usuário conectado ao Metamask: `window.ethereum.selectedAddress``\)`
- `data` contém a chamada ao método `mintNFT` do nosso smart contract, que recebe nosso `tokenURI` e o endereço da carteira do usuário, `window.ethereum.selectedAddress`, como entradas

Depois, fazemos uma chamada await, `window.ethereum.request`, onde pedimos ao Metamask para assinar a transação. Perceba que, nessa requisição, estamos especificando nosso método eth \(`eth\_SentTransaction`\) e passando nosso `transactionParameters`. Nesse ponto, o Metamask vai abrir no navegador e solicitar que o usuário assine ou rejeite a transação.

- Se a transação for bem-sucedida, a função vai retornar um objeto JSON onde o boolean `success` é definido como true e a string `status` sugere ao usuário que confira o Etherscan para mais informações sobre sua transação.
- Se a transação falhar, a função vai retornar um objeto JSON onde o boolean `success` é definido como false, e a string `status` relata a mensagem de erro.

No geral, nossa função `mintNFT` deve ficar assim:

Essa é uma função gigante! Agora, só precisamos conectar nossa função `mintNFT` ao nosso componente **Minter.js**...

## Passo 9: conecte o mintNFT ao nosso frontend minter.js

Abra seu arquivo **Minter.js** e atualize a linha `import \{ connectWallet \} from "./utils/interact.js"`; no topo para:

Por fim, implemente a função `onMintPressed` para fazer uma chamada await à sua função importada `mintNFT` e atualizar a variável de estado `status` para refletir se nossa transação teve sucesso ou falhou:

## Passo 10: implante seu NFT em um site ao vivo

‌Pronto para colocar seu projeto no ar para os usuários interagirem? Confira este [tutorial](https://app.gitbook.com/@alchemyapi/s/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) para implantar seu Minter em um site ao vivo:

## Passo 11: tome o mundo da blockchain de assalto 🚀

Brincadeira, você chegou ao final do tutorial! Recapitulando, ao construir um NFT minter, você aprendeu com sucesso a:

- Conectar-se ao Metamask através do seu projeto frontend
- Chamar métodos do smart contract a partir do seu frontend
- Assinar transações usando o Metamask

Provavelmente, você gostaria de conseguir mostrar os NFTs mintados através da sua dApp na sua carteira — então não deixe de conferir nosso tutorial rápido [How to View Your NFT in Your Wallet](/blog/how-to-view-your-nft-in-your-mobile-wallet)!

E, como sempre, se você tiver alguma dúvida, visite o [Alchemy support center](https://www.alchemy.com/support). Mal podemos esperar para ver como você vai aplicar os conceitos deste tutorial nos seus futuros projetos! 🧙‍♂️
