Search code examples
reactjsethereumsolidityweb3js

Nft Minter Dapp - Unable to mint the nft


I hard coded a NFT-minter dApp. I tried minting it on the Polygon Mumbai Testnet, but it seems like the NFT is not minting. Although the transaction was successful and I have the transaction hash, the NFT doesn't show up in the wallet.

Can anyone help me troubleshoot this issue?

My Smart Contract Code ->

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.1;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFTCollection is ERC721, Ownable {
    uint256 public constant MAX_NFTS = 10;
    uint256 public constant PRICE = 0.01 ether;
    uint256 public nextTokenId = 1;

    constructor() ERC721("MyNFTCollection", "MYNFT") {}

    function mint() public payable {
        require(nextTokenId < MAX_NFTS, "Maximum number of NFTs minted");
        require(msg.value >= PRICE, "Not enough Ether sent");

        _safeMint(msg.sender, nextTokenId);
        nextTokenId++;
    }

    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

}

App.js file code ->

import React, { useState } from 'react';
import Web3 from 'web3';
import { Container, Row, Col, Button, Navbar } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.css';
import MyNFTCollection from './contract/MyNFTCollection.json';
import img1 from './images/1.png'
import './App.css';

function App() {

  const [web3, setWeb3] = useState(null);
  const [contract, setContract] = useState(null);
  const [account, setAccount] = useState("");
  const [tokenOwned, setTokenOwned] = useState([]);
  const [error, setError] = useState("");

  const connectWeb3 = async () => {
    try{
      if(window.ethereum){
        const web3 = new Web3(window.ethereum);
        //await window.ethereum.enable();
        await window.ethereum.request({ method: 'eth_requestAccounts' });
        setWeb3(web3);
        const contract = new web3.eth.Contract(
          MyNFTCollection.abi, "0xD5C6ba7fD9AB133d8CfCE96bF144B152C218B107"
        );
        setContract(contract);
        const accounts = await web3.eth.getAccounts();
        setAccount(accounts[0]);
        const tokenOwned = await contract.methods
          .tokenOfOwner(accounts[0])
          .call();
        setTokenOwned(tokenOwned);
      }else{
        setError("Please install Metamask!");
      }
    }catch(err) {
      console.error(err);
      setError("Failed to connect to Ethereum network!");
    }
  };

  const buyToken = async() => {
    try{
      const result = await contract.methods.mint().send({
        from: account,
        value: web3.utils.toWei("0.01", "ether"),
      });
      console.log(result);
      setTokenOwned([...tokenOwned, result]);
    }catch(err){
      console.error(err);
    }
  };

  if(!web3){
    return(
      <div className="connect-web3">
        <Button variant="primary" onClick={connectWeb3}>Connect to Ethereum Network</Button>
        {error && <p>{error}</p>}
      </div>
    );
  }

  return (
    <>
      <Navbar bg="dark" varient="dark">
        <Navbar .Brand>&nbsp; Moon Monkey NFT </Navbar .Brand>
        <Navbar .Text>{account}</Navbar .Text>
      </Navbar>
      <br/>
      <Container className="my-nft">
        <Row className="justify-content-center">
          <Col xs={12} md={8} lg={6}>
            <Row className="justify-content-center">
              {[1,2,3,4,5,6,7,8,9].map((tokenId) => (
                <Col xs={12} md={6} lg={4} key={tokenId}>
                  <div className="nft-card">
                    <img
                      src={img1}
                      alt={`NFT #${tokenId}.png`}
                      width={200}
                      style={{marginBottom: "10px"}}
                    />
                  </div>
                </Col>
              ))}
            </Row>
            <br/>
            <div className="text-center">
              <Button variant="success" onClick={buyToken}>Buy NFT</Button>
              <p className="mt-2">
                Cost: 0.01 MATIC
              </p>
              <p>
                You own {tokenOwned.length}/{10} NFTs.{" "}
              </p>
            </div>
          </Col>
        </Row>
      </Container>
    </>
  );
}

export default App;

Solution

  • Although the transaction was successful and I have the transaction hash,

    If you were able to invoke a mint() transaction, and that has completed, then you have minted this NFT successfully. The data for the NFT is on chain.

    the NFT doesn't show up in the wallet.

    This is a separate issue from whether or not the mint transaction was successful. It is because EVM-compatible wallets do not (and cannot possibly) know the addresses of every single token that you are interested in. It may know of a few common ones that are very popular/ established by default, but not any brand new ones, especially ones that you have just deployed.

    If you are using the MetaMask browser extension, check out this article

    (select "Extension", then select "Adding NFTs manually")

    And then you'll see step by steps instructions on how to import you NFT by using the deployed address of your new smart contract. Other wallets follow a similar pattern.