How to Create an NFT on Mantle Tutorial Part II — Minting the Deployed NFT
02/22/2313 min read
by Mantle
Developers
NFT
Tutorials

In Part I of our NFT tutorial series, we accomplished the deployment of a smart contract to Mantle Testnet. Now, it’s time to showcase our web3 expertise by creating an NFT.
By the end of this tutorial, you will be able to generate any number of NFTs with the provided code. So, let’s begin!
Creating the Mint NFT Script
Step 1: Custom RPC config for Mantle
Open the repository from Part I in your favorite code editor (e.g. VSCode), and create a new file in the scripts folder called mint-nft.js.
We will be using the ethers.js library from Part I to connect to the Mantle’s custom RPC url. Add the following code to the file:
require("dotenv").config();
const { JsonRpcProvider, Signer } = require("@ethersproject/providers");
const ethers = require("ethers");
// Create a JsonRpcProvider instance
const rpcUrl = "https://rpc.testnet.mantle.xyz";
const chainId = 5001;
const provider = new JsonRpcProvider(rpcUrl, chainId);
If you’ve been following Part I of the same series, then the private key will have already been added. Be sure to add this to your .env file, so that it looks something like this:
PRIV_KEY = 0x"your-metamask-private-key"
Step 2: Grab Your Contract ABI
The contract Application Binary Interface (ABI) is an interface to interact with our smart contract. You can learn more about contract ABIs here.
Hardhat generates an ABI automatically and stores it in the MyNFT.json file.
Next, we must extract the contents by including the following code in the mint-nft.js file:
const abi = require("../artifacts/contracts/MyNFT.sol/MyNFT.json").abi;
Step 3: Configure the Metadata of Your NFT Using IPFS
The mintNFT smart contract function takes in a tokenURI parameter that should resolve to a JSON document describing the NFT’s metadata — which is really what brings the NFT to life, allowing it to have configurable properties, such as a name, description, image, and other attributes.
What exactly is IPFS? Interplanetary File System (IPFS) is a decentralized protocol and peer-to-peer network for storing and sharing data in a distributed file system.
We will be using Pinata, a convenient IPFS API and toolkit, to store our NFT asset and metadata and ensure that our NFT is truly decentralized. If you don’t have a Pinata account, sign up for a free account here.
Once you’ve created an account, follow the steps below:
- Navigate to the Pinata Upload+ button, this will be present right below where it says “Hey ‘YourName’”
- To upload an image to Pinata, click on “File” and select a file — this will be the image asset for your NFT. Feel free to name the asset whatever you wish.
- After you have uploaded the file, you’ll see it appearing on the main menu.
- Code the text right below CID: That is your Hash code.
- You can view your upload at: https://gateway.pinata.cloud/ipfs/<hash-code>
Save the above link as well — we will be copying the same link below.
In your root directory, make a new file called nft-metadata.json and add the following json code:
Note: The below code is changeable. Feel free to edit it based on your pet’s details! Or, feel free to use the same code and use any image of your choice.
{
"attributes": [
{
"trait_type": "Breed",
"value": "Labrador Retriever"
},
{
"trait_type": "Eye color",
"value": "Mocha"
}
],
"description": "The world's most excited and jolly pup.",
"image": "https://gateway.pinata.cloud/ipfs/QmQdFxyCzXFbQ2x2sZwhfLWthbWnBFgw8EeC36e7BjNfap",
"name": "Kiara"
}
Once you’re done editing the json file, save it and upload it to Pinata.
Step 4: Create a Signer and an Instance of the Contract
In order to be able to call the functions on our deployed contract, we need to define an ethers.js Signer using our wallet’s private key.
Next, we need to use the contract’s deployed address, the contract ABI, and the aforementioned signer to define a contract instance.
In the mint-nft.js file, add the following code:
// Create a signer using the private key from the environment variable
const privateKey = process.env.PRIV_KEY;
const signer = new ethers.Wallet(privateKey, provider);
// Get contract ABI and address
const abi = require("../artifacts/contracts/MyNFT.sol/MyNFT.json").abi;
const contractAddress = "0x1707dDe9a71334686E785bC80895Bb75ae6215b2";
// Create a contract instance
const myNftContract = new ethers.Contract(contractAddress, abi, signer);
In the code above, you can see that our contract’s deployed address is 0x1707dDe9a71334686E785bC80895Bb75ae6215b2. If you don’t remember your contract address or can’t find it on Etherscan, simply re-deploy the contract from Part I again and note down the new address.
Step 5: Call mintNFT Function of the Contract
Remember the metadata.json you uploaded to Pinata? Get its hashcode from Pinata and pass the following into a call to mintNFT: https://gateway.pinata.cloud/ipfs/<metadata-hash-code>
Here’s how the hashcode with the link should look like:
Now add the following piece of code to mint-nft.js to call the mintNFT function:
// Get the NFT Metadata IPFS URL
const tokenUri = "https://gateway.pinata.cloud/ipfs/QmUXZLiXHD4RpWYNopiKHMV6FWTzkc2FdYpVLsDTD1inF8";
// Call mintNFT function
async function mintNFT() {
let nftTxn = await myNftContract.mintNFT(signer.address, tokenUri);
await nftTxn.wait();
console.log(`NFT Minted! Check it out at: https://explorer.testnet.mantle.xyz/tx/${nftTxn.hash}`);
}
mintNFT()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Once you’ve made all the additions, the final mint-nft.js file should look something like this:
require("dotenv").config();
const { JsonRpcProvider, Signer } = require("@ethersproject/providers");
const ethers = require("ethers");
// Create a JsonRpcProvider instance
const rpcUrl = "https://rpc.testnet.mantle.xyz";
const chainId = 5001;
const provider = new JsonRpcProvider(rpcUrl, chainId);
// Create a signer using the private key from the environment variable
const privateKey = process.env.PRIV_KEY;
const signer = new ethers.Wallet(privateKey, provider);
// Get contract ABI and address
const abi = require("../artifacts/contracts/MyNFT.sol/MyNFT.json").abi;
const contractAddress = "0x1707dDe9a71334686E785bC80895Bb75ae6215b2";
// Create a contract instance
const myNftContract = new ethers.Contract(contractAddress, abi, signer);
// Get the NFT Metadata IPFS URL
const tokenUri = "https://gateway.pinata.cloud/ipfs/QmUXZLiXHD4RpWYNopiKHMV6FWTzkc2FdYpVLsDTD1inF8";
// Call mintNFT function
async function mintNFT() {
let nftTxn = await myNftContract.mintNFT(signer.address, tokenUri);
await nftTxn.wait();
console.log(`NFT Minted! Check it out at: https://explorer.testnet.mantle.xyz/tx/${nftTxn.hash}`);
}
mintNFT()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
We’re all set. Let’s mint our NFT by running the following command:
node scripts/mint-nft.js
You should get an output that looks something like this: “NFT Minted! Check it out at: https://explorer.testnet.mantle.xyz/tx/0x6258842492ebcce720d4ec79350d0ebe0b5974e9961b23ddff930cb92320cddb
You can check out your NFT mint on Etherscan by following the URL above.
Congrats! 🎉 ✨ You’ve minted your first NFT!
In Part III of this tutorial, we will add the same NFT to MetaMask