NFT Minting Web Interface: Smart Contracts, Merkle Tree

NFT Minting Web Interface: From Contract to Transaction

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1422
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1288
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    984
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    987
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    1001

NFT Minting Web Interface: From Contract to Transaction

Note: when a user clicks the Mint button, the frontend connects with the contract via a wallet. Errors like InsufficientFunds or InvalidMerkleProof scare users, and gas wars at peak demand require fast feedback. Without proper handling, a transaction can fail, costing the user $0.5 in wasted gas. We build interfaces that are predictable: wallet connection, condition checks (whitelist, limits, sale status), transaction submission with error decoding, and a final screen with the token. Clients often face incorrect whitelist status checks or wrong gas pricing. Our solution automatically selects optimal gas price via viem and verifies all conditions before submission. Our team has multi-year experience in blockchain development — we have implemented dozens of NFT projects with smart contract integration on Ethereum and EVM-compatible chains. We deliver clean TypeScript code using the latest wagmi and viem libraries.

Smart Contract Preparation

The first step is to study the ABI. A typical contract uses the ERC-721A standard for efficient batch minting. Essential functions: mint, whitelistMint, totalSupply, maxSupply, mintPrice, maxPerWallet, saleState, and numberMinted. Example ABI with viem — read contract state via multicall to fetch all data simultaneously:

// Typical mint contract functions function mint(uint256 quantity) external payable; function whitelistMint(uint256 quantity, bytes32[] calldata proof) external payable; function totalSupply() external view returns (uint256); function maxSupply() external view returns (uint256); function mintPrice() external view returns (uint256); function maxPerWallet() external view returns (uint256); function saleState() external view returns (uint8); // 0=paused, 1=whitelist, 2=public function numberMinted(address owner) external view returns (uint256); 

For reading state, we use multicall — it fetches totalSupply, maxSupply, mintPrice, maxPerWallet, saleState, and numberMinted for the wallet in a single RPC request. This reduces provider load and speeds up the UI.

Why Merkle Tree Is the Standard for Whitelist?

Storing all whitelist addresses in the contract costs gas at deployment. Merkle tree solves this: only the root is stored in the contract, and the proof is generated on the frontend from the user's address. It is 10x cheaper in gas. Implementation in TypeScript with the merkletreejs library:

// lib/merkle.ts import { MerkleTree } from 'merkletreejs'; import { keccak256, encodePacked } from 'viem'; // allowlist.json — array of addresses from CMS or API import allowlist from '@/data/allowlist.json'; function hashLeaf(address: string): `0x${string}` { return keccak256(encodePacked(['address'], [address as `0x${string}`])); } const leaves = allowlist.map(hashLeaf); const tree = new MerkleTree(leaves, keccak256, { sortPairs: true }); export function getMerkleProof(address: string): `0x${string}`[] { const leaf = hashLeaf(address); return tree.getHexProof(leaf) as `0x${string}`[]; } export function isWhitelisted(address: string): boolean { const leaf = hashLeaf(address); return tree.verify(tree.getHexProof(leaf), leaf, tree.getRoot()); } 
Verification method Deployment gas (10,000 addresses) Gas per mint Development complexity
Address array ~3,000,000 gas (0.1 ETH) 30,000 gas Low
Merkle Tree ~300,000 gas (0.01 ETH) 35,000 gas Medium

Deployment savings amount to 0.09 ETH — a strong argument for Merkle Tree. At an average gas of 20 Gwei, that's about $500 saved per deployment. Additionally, each whitelist check becomes cheaper, which is especially noticeable with many users.

What Are the Steps for Interface Integration?

  1. Analyze the contract ABI: extract all functions and events needed for minting.
  2. Design the React component structure: MintWidget, StatusBar, ErrorDisplay, TransactionProgress.
  3. Implement hooks for reading state using useReadContract and useReadContracts from wagmi.
  4. Add transaction submission logic via useWriteContract and track status with useWaitForTransactionReceipt.
  5. Integrate Merkle Tree: generate the proof on the frontend and pass it to the contract.
  6. Test on testnet, simulate all errors, deploy to production.

These steps cover the full development cycle. At each stage, we conduct code reviews and verify compliance with best practices.

How to Handle Minting Errors?

Minting fails for many reasons: insufficient ETH, wallet limit exceeded, sale not active, invalid proof. Errors from viem contain the ABI-decoded contract message:

import { ContractFunctionRevertedError, UserRejectedRequestError } from 'viem'; function parseMintError(error: Error): string { if (error instanceof UserRejectedRequestError) { return 'Transaction rejected in wallet'; } if (error instanceof ContractFunctionRevertedError) { const reason = error.data?.errorName ?? error.message; const messages: Record<string, string> = { 'ExceedsMaxPerWallet': 'Token limit per wallet exceeded', 'SaleNotActive': 'Sale has not started yet', 'InvalidMerkleProof': 'Your address is not whitelisted', 'InsufficientFunds': 'Insufficient ETH', 'MaxSupplyReached': 'All tokens have been minted', }; return messages[reason] ?? `Contract error: ${reason}`; } return 'Unknown error'; } 
Common minting errors and their resolution
  • InsufficientFunds: check wallet balance and increase ETH amount.
  • ExceedsMaxPerWallet: user has already minted the limit.
  • InvalidMerkleProof: address not in whitelist or proof expired.
  • SaleNotActive: check the sale status in the contract.
  • MaxSupplyReached: all tokens are sold out.

Testing and Security

Before launch, we simulate all contract states using Hardhat fork. We test edge cases: when maxSupply is reached, when the wallet has no ETH, when the proof is invalid. We follow checks-effects-interactions principles to prevent reentrancy attacks. Additionally, we set up monitoring via Etherscan API to track successful and failed transactions. This ensures users never see an incomprehensible error, and gas is not wasted.

Work Process and What's Included

Stage Description Duration
Contract analysis Study ABI, check mint conditions, create specification 1-2 days
Design Component architecture, configure React/Next.js, set up wagmi 1 day
Implementation Develop MintWidget, integrate Merkle Tree, handle errors 3-4 days
Testing Test on testnet, simulate errors, coverage tests 1-2 days
Deployment Set up production environment (Vercel/Netlify), DNS, Etherscan API 1 day

The deliverables include full TypeScript code, integration documentation, deployment instructions, and a one-month code warranty. We also provide team training on the code and support for one week after launch.

Timeline: basic version with public mint and progress bar — 2-3 days. Full implementation with whitelist, Merkle Tree, and deployment — 4-6 days.

Order minting interface development — contact us for a project assessment. Get a free consultation and an accurate cost estimate.