NFT Minter
.nft-minter-container {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #f9f9f9;
}
.nft-image {
width: 100%;
height: 300px;
background-color: #eee;
border-radius: 8px;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.nft-image img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.nft-info {
margin-bottom: 20px;
}
.nft-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.nft-description {
font-size: 16px;
color: #666;
margin-bottom: 15px;
}
.nft-stats {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
font-size: 14px;
color: #555;
}
.connect-button, .mint-button {
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
padding: 12px 20px;
font-size: 16px;
cursor: pointer;
width: 100%;
transition: background-color 0.3s;
}
.connect-button:hover, .mint-button:hover {
background-color: #2980b9;
}
.connect-button:disabled, .mint-button:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
.wallet-info {
margin: 15px 0;
padding: 10px;
background-color: #f1f1f1;
border-radius: 5px;
font-size: 14px;
word-break: break-all;
}
.status-message {
margin-top: 15px;
padding: 10px;
border-radius: 5px;
font-size: 14px;
}
.status-pending {
background-color: #f9e79f;
color: #7d6608;
}
.status-success {
background-color: #abebc6;
color: #196f3d;
}
.status-error {
background-color: #f5b7b1;
color: #943126;
}
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(255,255,255,.3);
border-radius: 50%;
border-top-color: #fff;
animation: spin 1s ease-in-out infinite;
margin-right: 10px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@media (max-width: 768px) {
.nft-minter-container {
padding: 15px;
max-width: 100%;
}
.nft-image {
height: 250px;
}
.nft-title {
font-size: 20px;
}
}
@media (max-width: 480px) {
.nft-stats {
flex-direction: column;
gap: 10px;
}
}
Loading NFT data…
Connect Wallet
Mint NFT
https://cdn.jsdelivr.net/npm/thirdweb@latest/dist/thirdweb.js
document.addEventListener(‘DOMContentLoaded’, async function() {
const connectWalletBtn = document.getElementById(‘connect-wallet-btn’);
const mintBtn = document.getElementById(‘mint-btn’);
const walletInfo = document.getElementById(‘wallet-info’);
const walletAddressEl = document.getElementById(‘wallet-address’);
const statusMessageEl = document.getElementById(‘status-message’);
const availableSupplyEl = document.getElementById(‘available-supply’);
const nftTitleEl = document.getElementById(‘nft-title’);
const nftDescriptionEl = document.getElementById(‘nft-description’);
const nftImagePlaceholder = document.getElementById(‘nft-image-placeholder’);
const contractAddress = “0x61d925d3Fcb9cD38d36642FfD1244007776fBC91”;
const chainId = 137;
const clientId = “4db6a2e2682d39c3b56c74413ba8e61b”;
let client;
let contract;
let account;
let signer;
let totalSupply = 1000;
let claimedSupply = 0;
let userHasNFT = false;
let nftMetadata = null;
try {
client = window.thirdweb.createThirdwebClient({
clientId: clientId,
});
setStatus(“Connecting to contract…”, “pending”);
const polygonChain = window.thirdweb.defineChain(chainId);
contract = window.thirdweb.getContract({
client,
chain: polygonChain,
address: contractAddress,
});
await fetchContractData();
setStatus(“”, “”);
} catch (error) {
console.error(“Initialization error:”, error);
setStatus(“Failed to initialize: ” + getErrorMessage(error), “error”);
}
connectWalletBtn.addEventListener(‘click’, async function() {
try {
setStatus(“Connecting wallet…”, “pending”);
if (window.ethereum) {
const walletClient = window.thirdweb.createWalletClient({
transport: window.thirdweb.custom(window.ethereum)
});
const [address] = await walletClient.requestAddresses();
account = address;
signer = window.thirdweb.createThirdwebSigner({
client,
walletClient,
chain: window.thirdweb.defineChain(chainId)
});
walletAddressEl.textContent = formatAddress(account);
walletInfo.style.display = ‘block’;
connectWalletBtn.style.display = ‘none’;
mintBtn.style.display = ‘block’;
await checkUserHasNFT();
setStatus(“Wallet connected!”, “success”);
setTimeout(() => {
setStatus(“”, “”);
}, 3000);
} else {
setStatus(“Please install MetaMask or another Ethereum wallet”, “error”);
}
} catch (error) {
console.error(“Wallet connection error:”, error);
setStatus(“Failed to connect wallet: ” + getErrorMessage(error), “error”);
}
});
mintBtn.addEventListener(‘click’, async function() {
if (!account || !signer) {
setStatus(“Please connect your wallet first”, “error”);
return;
}
if (userHasNFT) {
setStatus(“You’ve already claimed this NFT”, “error”);
return;
}
try {
setStatus(“Minting NFT…”, “pending”);
mintBtn.disabled = true;
const transaction = window.thirdweb.claimTo({
contract,
to: account,
amount: 1
});
const { transactionHash } = await window.thirdweb.sendTransaction({
transaction,
account: signer,
});
setStatus(`NFT minted successfully! Transaction: ${transactionHash.slice(0, 10)}…`, “success”);
await fetchContractData();
userHasNFT = true;
updateMintButton();
} catch (error) {
console.error(“Minting error:”, error);
setStatus(“Failed to mint NFT: ” + getErrorMessage(error), “error”);
mintBtn.disabled = false;
}
});
async function fetchContractData() {
try {
const metadata = await window.thirdweb.getAllNFTsQuery({
contract,
start: 0,
count: 1
});
if (metadata && metadata.length > 0) {
nftMetadata = metadata[0];
nftTitleEl.textContent = nftMetadata.metadata.name || “NFT Collection”;
nftDescriptionEl.textContent = nftMetadata.metadata.description || “Exclusive NFT collection on Polygon”;
if (nftMetadata.metadata.image) {
const imageUrl = nftMetadata.metadata.image;
nftImagePlaceholder.innerHTML = ``;
} else {
nftImagePlaceholder.textContent = “No image available”;
}
}
const claimed = await window.thirdweb.totalClaimedSupplyQuery({
contract
});
claimedSupply = claimed || 0;
availableSupplyEl.textContent = (totalSupply – claimedSupply);
} catch (error) {
console.error(“Error fetching contract data:”, error);
setStatus(“Failed to fetch NFT data: ” + getErrorMessage(error), “error”);
}
}
async function checkUserHasNFT() {
if (!account) return;
try {
const userNFTs = await window.thirdweb.getNFTsQuery({
contract,
owner: account
});
userHasNFT = userNFTs && userNFTs.length > 0;
updateMintButton();
} catch (error) {
console.error(“Error checking user NFTs:”, error);
}
}
function updateMintButton() {
if (userHasNFT) {
mintBtn.disabled = true;
mintBtn.textContent = “Already Claimed”;
} else {
mintBtn.disabled = false;
mintBtn.textContent = “Mint NFT”;
}
}
function setStatus(message, type) {
if (!message) {
statusMessageEl.style.display = ‘none’;
return;
}
statusMessageEl.textContent = message;
statusMessageEl.style.display = ‘block’;
statusMessageEl.classList.remove(‘status-pending’, ‘status-success’, ‘status-error’);
if (type === ‘pending’) {
statusMessageEl.classList.add(‘status-pending’);
} else if (type === ‘success’) {
statusMessageEl.classList.add(‘status-success’);
} else if (type === ‘error’) {
statusMessageEl.classList.add(‘status-error’);
}
}
function formatAddress(address) {
return address.slice(0, 6) + ‘…’ + address.slice(-4);
}
function getErrorMessage(error) {
if (typeof error === ‘string’) return error;
if (error.reason) return error.reason;
if (error.message) return error.message;
return ‘Unknown error occurred’;
}
});
