0

Contract Code:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract MyNFT is ERC721URIStorage, Ownable { using Counters for Counters.Counter; uint256 public constant MAX_MINT_COUNT = 10; uint256 public constant MINT_PRICE = 0.000018 ether; Counters.Counter private _tokenIdTracker; mapping(address => uint256) private _mintedCount; address payable public ownerWallet; event NFTMinted(address indexed minter, uint256 indexed tokenId); constructor(address payable _ownerWallet) ERC721("MyNFT", "MNFT") { ownerWallet = _ownerWallet; } function mint(string memory metadataURI) external payable { require(_tokenIdTracker.current() < MAX_MINT_COUNT, "Max mint limit reached"); require(msg.value >= MINT_PRICE, "Insufficient ETH sent for minting"); uint256 tokenId = _tokenIdTracker.current() + 1; _safeMint(msg.sender, tokenId); _tokenIdTracker.increment(); _mintedCount[msg.sender] = _mintedCount[msg.sender] + 1; emit NFTMinted(msg.sender, tokenId); _setTokenURI(tokenId, metadataURI); } function mintedCount(address account) external view returns (uint256) { return _mintedCount[account]; } function withdraw() external onlyOwner { uint256 balance = address(this).balance; ownerWallet.transfer(balance); } receive() external payable { _autoWithdraw(); } function _autoWithdraw() internal { uint256 contractBalance = address(this).balance; ownerWallet.transfer(contractBalance); } } 

mintNFT.js Code

const { Web3 }= require('web3'); const contractABI = require('./contracts/MyNFT.json').abi; const contractAddress = 'contract address'; const web3 = new Web3('my rpc url'); const contract = new web3.eth.Contract(contractABI, contractAddress); async function mintNFT(metadataURI) { try { const accounts = await web3.eth.getAccounts(); const sender = accounts[0]; const gasPrice = await web3.eth.getGasPrice(); const gasLimit = 30000000; const mintPrice = web3.utils.toWei('0.000018', 'ether'); const valueToSend = mintPrice.toString(); const txData = contract.methods.mint(metadataURI).encodeABI(); const tx = { to: contractAddress, gas: gasLimit, gasPrice: gasPrice, data: txData, from: sender, value: valueToSend, }; const txReceipt = await web3.eth.sendTransaction(tx); console.log('NFT minted successfully with transaction hash:', txReceipt.transactionHash); } catch (error) { console.error('Error minting NFT:', error); } } module.exports = mintNFT; 

NFTCard.js

import React from 'react'; import mintNFT from './mintNFT'; import './NFTCard.css'; const NFTCard = ({ image, title, price }) => { const handleMint = async () => { try { const metadataURI = 'URI'; await mintNFT(metadataURI); } catch (error) { console.error('Error minting NFT:', error); } }; return ( <div className="NFTCard"> <div className="NFTImageContainer"> <img src={image} alt={title} className="NFTImage" /> </div> <div className="NFTContent"> <h3 className="NFTTitle">{title}</h3> <div className="NFTDetails"> <span className="NFTPrice">{price}<img src="/images/sepeth.png" alt="Price Image" className="pricelogo" /></span> <button className="NFTButton" onClick={handleMint}>Mint</button> </div> </div> </div> ); }; export default NFTCard; 

I did compiled and deployed contract and it deployed successfully But as soon as i click on mint button on frontend it throws error

I also copied the full folder named "contracts" from build to src\components\contracts because contracts cant be accessed outside src

Please help to fix this issue

1 Answer 1

0

You're facing the error because you're not passing the signer by creating it using the browser's injected provider (i.e., window.ethereum) from the frontend. To achieve that, you also need to implement the connectWallet() function in order to prompt the user to connect his desired account using the MetaMask pop-up.

And, moreover you don't need to explicitly call the mint() function of the contract explicitly from a different file using web3.js or so, as you can achieve the same in the handleMint() function itself using web3.js or ethers.js.

Here's the revised code for your NFTCard.js file containing the connectWallet() function as well as the implementation of the NFT contract's mint() function call within the handleMint() function:

Using web3.js:

import { React, useState } from 'react'; import Web3 from 'web3'; // Import web3.js import './NFTCard.css'; const contractABI = [ /* NFT_CONTRACT_ABI */ ]; const contractAddress = 'NFT_CONTRACT_ADDRESS'; const NFTCard = ({ image, title, price }) => { const [walletConnected, setWalletConnected] = useState(false); const [isMinting, setIsMinting] = useState(false); const handleMint = async () => { try { // Check if Web3 provider is available if (window.ethereum) { const web3 = new Web3(window.ethereum); // Request account access if needed await window.ethereum.request({ method: 'eth_requestAccounts' }); const accounts = await web3.eth.getAccounts(); const metadataURI = 'URI'; const contract = new web3.eth.Contract(contractABI, contractAddress); const MINT_PRICE = await contract.methods.MINT_PRICE().call(); setIsMinting(true); const txResponse = await contract.methods.mint(metadataURI).send({ from: accounts[0], value: MINT_PRICE }); // Get the transaction hash from the receipt await web3.eth.getTransactionReceipt(txResponse.transactionHash); setIsMinting(false); alert(`NFT minted successfully with transaction hash: ${txResponse.transactionHash}`); } else { // Web3 provider is not available, handle error throw new Error('Web3 provider is not available'); } } catch (error) { console.error('Error minting NFT:', error); } }; const connectWallet = async () => { try { // Check if Web3 provider is available if (window.ethereum) { // Request account access if needed await window.ethereum.request({ method: 'eth_requestAccounts' }); // Web3 provider is connected console.log('Wallet connected'); setWalletConnected(true); } else { // Web3 provider is not available, handle error throw new Error('Web3 provider is not available'); } } catch (error) { console.error('Error connecting wallet:', error); } }; return ( <div className="NFTCard"> <div className="NFTImageContainer"> <img src={image} alt={title} className="NFTImage" /> </div> <div className="NFTContent"> <h3 className="NFTTitle">{title}</h3> <div className="NFTDetails"> <span className="NFTPrice">{price}<img src="/images/sepeth.png" alt="Price Image" className="pricelogo" /></span> <button className="NFTButton" onClick={handleMint}>Mint</button> <button className="WalletConnectButton" onClick={connectWallet}> {walletConnected ? 'Connected' : 'Connect Wallet'} </button> <p>{isMinting ? "MINTING..." : ""}</p> </div> </div> </div> ); }; export default NFTCard; 

Using ethers.js:

import { React, useState } from 'react'; import { ethers } from 'ethers'; // Import ethers.js import './NFTCard.css'; const contractABI = [ /* NFT_CONTRACT_ABI */ ]; const contractAddress = 'NFT_CONTRACT_ADDRESS'; const NFTCard = ({ image, title, price }) => { const [walletConnected, setWalletConnected] = useState(false); const [isMinting, setIsMinting] = useState(false); const handleMint = async () => { try { // Check if MetaMask is installed if (window.ethereum) { // Request account access if needed await window.ethereum.request({ method: 'eth_requestAccounts' }); // Get the signer from MetaMask const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); // Pass the signer while calling mintNFT function const metadataURI = 'URI'; // Get the contract instance const contract = new ethers.Contract(contractAddress, contractABI, signer); const MINT_PRICE = await contract.MINT_PRICE(); // Call the mint function of the contract const txResponse = await contract.mint(metadataURI, { value: MINT_PRICE }); setIsMinting(true); // Wait for transaction confirmation await txResponse.wait(); setIsMinting(false); alert(`NFT minted successfully with transaction hash: ${txResponse.transactionHash}`); } else { // MetaMask is not installed, handle error throw new Error('MetaMask is not installed'); } } catch (error) { console.error('Error minting NFT:', error); } }; const connectWallet = async () => { try { // Check if MetaMask is installed if (window.ethereum) { // Request account access if needed await window.ethereum.request({ method: 'eth_requestAccounts' }); // MetaMask is connected console.log('Wallet connected'); setWalletConnected(true); } else { // MetaMask is not installed, handle error throw new Error('MetaMask is not installed'); } } catch (error) { console.error('Error connecting wallet:', error); } }; return ( <div className="NFTCard"> <div className="NFTImageContainer"> <img src={image} alt={title} className="NFTImage" /> </div> <div className="NFTContent"> <h3 className="NFTTitle">{title}</h3> <div className="NFTDetails"> <span className="NFTPrice">{price}<img src="/images/sepeth.png" alt="Price Image" className="pricelogo" /></span> <button className="NFTButton" onClick={handleMint}>Mint</button> <button className="WalletConnectButton" onClick={connectWallet}> {walletConnected ? 'Connected' : 'Connect Wallet'} </button> <p>{isMinting ? "MINTING..." : ""}</p> </div> </div> </div> ); }; export default NFTCard; 
2
  • Thanks it worked Commented May 2, 2024 at 5:31
  • Great. You’re welcome, @LuckyRajput. Happy coding! Commented May 2, 2024 at 5:40

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.