How to Build an NFT Minting dApp

How to Build an NFT Minting dApp

In this tutorial, we'll walk you through the process of building a decentralized application (dApp) that allows users to mint NFTs from an ERC-721 smart contract using thirdweb. By the end of this guide, you'll have a fully functional NFT minting dApp with wallet connection, NFT metadata display, and minting functionality.

To see a video version of this tutorial, check out the YouTube video:

Step 1: Deploy an NFT Smart Contract

First, we need to deploy an ERC-721 NFT (NFTDrop) smart contract that we'll use to mint NFTs from our dApp.

NFT Drop - ERC721 | Published Smart Contract
Release collection of unique NFTs for a set price. Deploy NFT Drop in one click with thirdweb.
  1. Go to the thirdweb dashboard and navigate to the "Contracts" tab.
  2. Click the "Deploy Contract" button and select the "NFT Drop" contract from the NFTs section.
  3. Fill out the contract details like name, symbol, image, and description.
  4. Choose the network you want to deploy to
  5. Click "Deploy Now" and confirm the transaction in your wallet.

Step 2: Upload NFT Metadata

Next, we need to upload the metadata for the NFTs that will be minted from our contract.

  1. In the thirdweb dashboard, go to the "NFTs" tab under your deployed contract.
  2. You can either single upload NFT metadata manually or batch upload multiple NFTs at once.
  3. Prepare a folder with your NFT metadata files in JSON format. Each file should include properties like name, description, image (IPFS hash), and any custom attributes.
  4. Click "Batch Upload" and drag your metadata files into the uploader.
  5. Choose whether to do a normal mint (reveal upon mint) or a delayed reveal. For this example, we'll select "Delayed Reveal" which will hide the actual NFT metadata until we decide to reveal it later.
  6. Set a password for the delayed reveal, the placeholder metadata, and the number of NFTs to upload.
  7. Click "Upload NFTs" and confirm the transaction.

Step 3: Set Claim Conditions

To control how users can mint NFTs from our contract, we need to set claim conditions.

  1. Go to the "Claim Conditions" tab under your contract in the thirdweb dashboard.
  2. Click "Add Phase" to create a new claim phase. There are several options like only owner, allow list, public, etc.
  3. For this tutorial, we'll create a public claim phase where anyone can mint. Set a price (e.g. 0.01 ETH) per NFT and any other conditions like max quantity per wallet.
  4. Click "Save Phase" and confirm the transaction.

Want to watch a tutorial video going through the process of deploying and setting up an ERC-721 smart contract. You can view a full tutorial here:

Step 4: Set Up a Next.js Project

We'll be using Next.js and the thirdweb React SDK to build our minting dApp.

GitHub - thirdweb-example/next-starter: Starter kit to build with Next and thirdweb without additional initial configuration.
Starter kit to build with Next and thirdweb without additional initial configuration. - thirdweb-example/next-starter
  1. npx thirdweb create app --next
  2. Open the .env.example file and add your thirdweb API key (client ID).
  3. Rename .env.example to .env.local

Step 5: Connect User Wallet to App

Add a ConnectButton UI component to allow a user to connect a wallet to your app. ConnectButton component supports over 350 wallets.

youtube-nft-claim/src/app/page.tsx at main · thirdweb-example/youtube-nft-claim
Contribute to thirdweb-example/youtube-nft-claim development by creating an account on GitHub.
const chain = defineChain( <chain> );

<ConnectButton client={client} chain={chain}/>

Step 6: Build the Minting dApp UI

Now let's build the user interface for our NFT minting dApp. We'll create a component that displays the NFT metadata, a quantity selector, and a mint button.

youtube-nft-claim/src/app/page.tsx at main · thirdweb-example/youtube-nft-claim
Contribute to thirdweb-example/youtube-nft-claim development by creating an account on GitHub.
  1. Lets first get our contract so we can read information from it.
const contract = getContract({
  client: client,
  chain: chain,
  address: "<contract_address>"
});
  1. Now lets get some data from our smart contract using thirdweb extensions.
const { data: contractMetadata } = useReadContract( getContractMetadata,
  { contract: contract });

const { data: claimedSupply } = useReadContract( getTotalClaimedSupply,
  { contract: contract});

const { data: totalNFTSupply } = useReadContract( nextTokenIdToMint,
  { contract: contract });

const { data: claimCondition } = useReadContract( getActiveClaimCondition,
  { contract: contract } );
  1. Create a function to get the price of the NFT from the current claim condition.
const getNFTPrice = (quantity: number) => {
  const total = quantity * parseInt(
    claimCondition?.pricePerToken.toString() || "0"
  );
  return toEther(BigInt(total));
}
  1. Display information of contract like contract name, description, and image using the data from above.
{isLoadingContractMetadata ? (
  <p>Loading contract metadata...</p>
) : (
  <>
    <MediaRenderer
      client={client}
      src={contractMetadata?.image}
    />
    <h2>
      {contractMetadata?.name}
    </h2>
    <p>
      {contractMetadata?.description}
    </p>
  </>
)}
  1. Display the total supply and the total number of claimed NFTs from the collection.
{claimedSupply && totalNFTSupply && (
  <p className="text-lg mt-2 font-bold">
    Total NFT Supply: 
    {claimedSupply?.toString()}/{totalNFTSupply?.toString()}
  </p>
)}
  1. Create a component for the quantity selector for a user to select to quantity of the NFT they want to claim
const [quantity, setQuantity] = useState(1);
<div>
  <button onClick={() => setQuantity(Math.max(1, quantity - 1))}>
  -
  </button>
  <input
    type="number"
    value={quantity}
    onChange={(e) => setQuantity(parseInt(e.target.value))}
  />
  <button onClick={() => setQuantity(quantity + 1)}>
  +
  </button>
</div>
  1. Finally, lets create a button for a user to claim the selected quantity of NFTs. We'll be using thirdweb's TransactionButton UI component to easily do this.
<TransactionButton
  transaction={() => claimTo({
    contract: contract,
    to: account?.address || "",
    quantity: BigInt(quantity),
  })}
  onTransactionConfirmed={async () => {
    setQuantity(1);
    alert("NFT claimed!");
  }}
>
  {`Claim NFT (${getNFTPrice(quantity)} ETH)`}
</TransactionButton>

Conclusion

Congratulations, you've built a NFT claim dapp using thirdweb! In this guide, we covered how to:

  • Deploy an ERC-721 NFTDrop contract using thirdweb
  • Get and display data from our smart contract
  • Build a way for users to claim NFTs to their connected wallet

Feel free to explore the final source code, make modifications, and adapt it for your own projects. If you have any questions or feedback, don't hesitate to reach out.

Happy building! 🚀