A collection worth owning.

ERC-721 written from scratch: a Merkle-tree whitelist phase, a public phase with per-wallet caps, a pre/post-reveal flow and ERC-2981 royalties — 5000 supply, no OpenZeppelin.

Minted—
Max supply—
Phase—
Revealed—
Royalty—
Your NFTs—
🪙

Public mint

Price — · max — per wallet.

🌳

Whitelist mint Merkle

Price — · max — per wallet. Paste your Merkle proof (32-byte hex hashes, one per line).

Gallery (recent mints from the chain)

Live Activity (recent events from the chain)

EventDetailsBlockTx
Loading…
showing the latest 15 events

How it works (learn the dApp before you mint)

🧭

How to use

  1. Press Connect Wallet in the top-right header. The dApp runs on the Sepolia testnet (chain id 11155111) — switch networks in your wallet if prompted.
  2. Point the app at a collection. If the setup banner shows, paste the deployed GenesisNFT address and press Use this collection; you can change it anytime via ⚙ Settings → Save & reload.
  3. Mint an NFT. In the Public mint card, choose a quantity and press Mint; in the Whitelist mint card, paste your Merkle proof (one 32-byte hash per line) and press Mint (whitelist).
  4. Follow the result. Your token appears in the Gallery and the transaction in Live Activity; press ↻ Refresh to re-pull the latest 15 events.
  5. Owner only — manage the drop. If you own the collection, Owner Controls unlocks: set phase, set Merkle root, toggle reveal, update URIs, set royalties, reserve-mint and withdraw.
⛓️

The process — what happens on-chain

  1. GenesisNFT.mintWhitelist checks the phase is WHITELIST and that you sent exactly 0.05 ETH per token (max 2 per wallet) before minting.
  2. MerkleProof.verify recomputes the Merkle root from your proof; the leaf is keccak256(address), so a proof can never be reused by another wallet.
  3. The hand-written ERC721 contract mints via _mintBatch: sequential token ids, updated balances and Transfer events, capped at 5000 supply.
  4. tokenURI returns the shared pre-reveal placeholder until the owner calls setRevealed(true); then it becomes baseURI + id + ".json" served via IPFS.
  5. royaltyInfo (ERC-2981) pays 5% of every secondary sale to the owner — marketplaces settle the artist automatically.
  6. withdraw() sends the contract's full ETH balance to the owner, guarded by ReentrancyGuard; the owner reserve respects the 5000 cap too.
🔀

Flow graph

1 Whitelist mint GenesisNFT.mintWhitelist 2 Merkle check MerkleProof.verify 3 Tokens minted ERC721._mintBatch 4 Reveal metadata GenesisNFT.tokenURI 5 Royalty payout GenesisNFT.royaltyInfo public mint: same path, 0.08 ETH × qty

Every token shows the same placeholder until the owner reveals the collection; royalties are paid on secondary sales by marketplaces.