[SOLVED] Metadata is not showing on opensea

i am trying to develop a nft mint daap. i deploy the erc 721 contract on bsc test net(b481eFed1099C03aEBA03a160cd4feE17Ace3257)/ The mint function is working but the metadata is not showing on opensea test net. for metadata and image i am using pinata, here is the link for metadata


my ultimate goal is once the user mint his nft he can view is on opensea.

here is my code

<!DOCTYPE html>

<html lang="en">


    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="style.css">

     <!-- INSTALL THE SDK and WEB3 -->

   <script src="https://unpkg.com/moralis-v1/dist/moralis.js"></script>

     <!-- / -->




    <div><button id="logn">Connect</button></div>

    <div id="address"> </div>

    <div ><input type="text " placeholder="quantity" id="quan"></div>

   <button id="mnt">mint</button>

   <div>  <button id="nft">view on opensea</button></div>

    <script src="main.js"></script>




const serverUrl = "xx"

  const appId = "xx"

   Moralis.start({serverUrl, appId})


/* Authentication code */

async function login() {

  let user = Moralis.User.current();

  user = await Moralis.authenticate({ signingMessage: ' done' });



    let addressOfUser= document.getElementById('address')





async function mint(quantity_){

  await Moralis.enableWeb3();

  let tic= document.getElementById('quan').value

  let options={

    contractAddress: "0xb481eFed1099C03aEBA03a160cd4feE17Ace3257",

    functionName: "mint",









  await Moralis.executeFunction(options)


document.getElementById('logn').onclick= login;


That 0xb481eFed1099C03aEBA03a160cd4feE17Ace3257 contract does not return a valid token URI for tokenId 1 (the only token currently) - it is returning an empty string or a value of "".

You will need to update this token URI to https://gateway.pinata.cloud/ipfs/Qmcchbbm2R6CdiwsYbcoLPcY7PSi7yska9HzDCvK977mMU.

from the contract, right? But i did set the base tokenURI ( setBaseTokenUri) that is in my contract ! should i have to change my contract?

from the contract, right?

Yes at a contract level. If you did set the base URI, it didn’t work. There’s no value if you call tokenURI function on your contract. So yes you would need to change it and redeploy, or try setting the base URI again.

Before worrying about metadata showing on OpenSea, after making changes to your contract, test if it gets a valid token URI; you can use runContractFunction.

But if you did use base URI, you would need to use a different IPFS link (directory) - your current one only points to one set of metadata instead of a base URI like https://gateway.pinata.cloud/ipfs/hash/ or ipfs://hash where https://gateway.pinata.cloud/ipfs/hash/1 is used for token 1, https://gateway.pinata.cloud/ipfs/hash/2 for token 2, and so on.

You mean i need to upload it again? or i set the basi uri like this"https://gateway.pinata.cloud/ipfs/Qmcchbbm2R6CdiwsYbcoLPcY7PSi7yska9HzDCvK977mMU"
can you please explain?

For example, this is BAYC contract’s base URI: ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/ and through a gateway - there’s all the metadata in this directory for each token.

You can look at doing this to update the token URI for token 1 with your current IPFS metadata. Don’t worry about base URI because you won’t be able to use that https://gateway.pinata.cloud/ipfs/Qmcchbbm2R6CdiwsYbcoLPcY7PSi7yska9HzDCvK977mMU properly.

If you want to use base URI, you can read about ERC721 or from OpenSea.

any particular reason?

Because if you set that as a base URI, then for token 1, it would try to use https://gateway.pinata.cloud/ipfs/Qmcchbbm2R6CdiwsYbcoLPcY7PSi7yska9HzDCvK977mMU/1 which isn’t a valid token URI.

Did you check out the links I posted?

i am going through those, and i will change my contract, hope it ill work. any good minting contract example i should
look at?

This one should be fine. Your contract is probably fine, you just need to set the token URI separately - you only have one NFT and a single metadata or token URI.

bit confused , can u show me? as far my understandings-

  1. i deploy the toke, 2. enable public minting then set the toke uri( https://gateway.pinata.cloud/ipfs/Qmcchbbm2R6CdiwsYbcoLPcY7PSi7yska9HzDCvK977mMU), right?

Which tutorial did you follow for creating this NFT contract, uploading to IPFS, etc.? It should explain this process of setting the token URI properly for your particular contract.

Working from that will be easier than trying to do another contract at this stage.

in the tutorial the dev did not set the uri, let say i have to use this contract, what i need to do exactly? where i am doing wrong?

What is the tutorial?

Your contract code (now that it’s verified) looks a little strange (setBaseTokenURI in particular and adding .json to the end) - you can start over. You can follow a tutorial like this step by step.

now i an using this contract(0x5542bD28FD0D8c22D4AC7D51E62735Ac32d32374)bsc testnet, but same problem.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

contract Minter is ERC721, Ownable{

  string private baseTokenURI;

  uint256 public mintPrice;

    uint256 public totalSupply;

    uint256 public maxSupply;

    uint256 public maxPerWallet;

    bool public isPublicMintEnabled;


    address public withdrawWallet;

    mapping (address=> uint256) public walletMints;

    constructor()  payable ERC721("NFTTutorial", "NFT") {


        mintPrice= 1 ether;

        totalSupply = 0;


        maxPerWallet= 25;



      function setIspublicMintEnable( bool isPublicMintEnabled_) external onlyOwner{

        isPublicMintEnabled= isPublicMintEnabled_;


      function mint(uint256 quantity_) public payable{

        require(isPublicMintEnabled,"minting not enabled");

        //require(msg.value== quantity_* mintPrice, " wrong mint value");

        require(totalSupply+quantity_<= maxSupply,"sold out");

        require(walletMints[msg.sender]+ quantity_<= maxPerWallet);

        for (uint256 i=0; i <quantity_; i++){

            uint256 newTokenId=totalSupply+1;


            walletMints[msg.sender] = walletMints[msg.sender] + quantity_;

            _safeMint(msg.sender, newTokenId);



   /// @dev Returns an URI for a given token ID

  function _baseURI() internal view virtual override returns (string memory) {

    return baseTokenURI;


  /// @dev Sets the base token URI prefix.

  function setBaseTokenURI(string memory _baseTokenURI) public {

    baseTokenURI = _baseTokenURI;


   function withdraw(address payable _to, uint _amount) public {




Please keep to the new topic you’ve made.