// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract ItemNFT is ERC721, ERC721Enumerable, ERC721Burnable, AccessControl {
using Counters for Counters.Counter;
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
Counters.Counter private _tokenIdCounter;
constructor() ERC721("Item NFT", "INFT") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
}
function _baseURI() internal pure override returns (string memory) {
return "https://dummy.com/api/v1/tokens/";
}
function safeMint(address to) public onlyRole(MINTER_ROLE) {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
ItemNFT.tsx
import React, { useContext, useState } from "react";
import { ItemNFTContext } from "./../hardhat/SymfoniContext";
import { SignerContext } from "./../hardhat/SymfoniContext";
import { BigNumber } from "ethers";
interface Props {}
export const ItemNFT: React.FC = () => {
const ItemNFT = useContext(ItemNFTContext);
const Signer = useContext(SignerContext);
const [address, setAddress] = useState("");
Signer[0]?.getAddress().then((address) => {
setAddress(address);
});
const [tokenId, setTokenId] = useState();
const [tokenURI, setTokenURI] = useState("");
const handleGetAccounts = async (
e: React.MouseEvent
) => {
e.preventDefault();
console.log(Signer);
};
const handleSafeMint = async (
e: React.MouseEvent
) => {
e.preventDefault();
if (!ItemNFT.instance) throw Error("ItemNFT instance not ready");
if (ItemNFT.instance) {
const tx = await ItemNFT.instance.safeMint(address);
const waitLog = await tx.wait();
const event = waitLog.events ? waitLog.events[0] : undefined;
if(event !== undefined){
const _tokenId = event.args ? event.args.tokenId : undefined;
setTokenId(_tokenId);
}
}
};
const handleTokenURI = async (
e: React.MouseEvent
) => {
e.preventDefault();
if (!ItemNFT.instance) throw Error("ItemNFT instance not ready");
if (ItemNFT.instance) {
if (tokenId !== undefined && tokenId.toNumber() >= 0){
const tokenURI = await ItemNFT.instance.tokenURI(tokenId);
setTokenURI(tokenURI);
}
}
};
return (
Signer: { address }
tokenId: { tokenId?.toNumber() }
tokenURI: { tokenURI }
);
};