A full-stack Web3 marketplace where creators can:
- Deploy ERC‑721 NFT collections via a factory,
- Mint NFTs with IPFS-hosted metadata,
- Trade via fixed-price listings and on-chain auctions,
- Track activity and earnings in a modern, responsive UI.
Built with Solidity 0.8.20+, OpenZeppelin v5, React + TypeScript, and Vite.
-
Collection Factory
- One transaction to deploy a new
NFTCollectioncontract. - Stores global protocol fees for creation and minting.
- One transaction to deploy a new
-
NFT Collections
- ERC‑721 with per-token URIs (
ERC721URIStorage). - Default 5% royalties using
ERC2981. - Collection-level metadata (name, image, description) stored on IPFS and surfaced in the UI.
- ERC‑721 with per-token URIs (
-
Marketplace
- Fixed-price listings (instant buy).
- Timed auctions with bid management and finalization.
- Pull-based withdrawals to reduce reentrancy risk.
-
Royalties & Fees
- EIP‑2981 compliant royalties for creators.
- Creation and mint fees configurable in
CollectionFactory. - Platform fee on marketplace sales for the treasury.
-
Frontend
- Dark, responsive design with a fixed navbar and elegant footer.
- Skeleton loading states and clear error handling.
- Profile dashboard with:
- My NFTs (owned + escrowed listings/auctions),
- Admin-style balances (withdrawable, platform fees, factory fees),
- On-chain transaction history (with pagination).
Located in smartcontract/contracts:
-
CollectionFactory.sol- Deploys and tracks
NFTCollectioncontracts. - Holds
creationFeeandprotocolMintFee. - Owner can adjust fees and withdraw accumulated ETH.
- Deploys and tracks
-
NFTCollection.sol- ERC‑721 token contract with URI storage.
- Uses
IFactory(protocolMintFee)to enforce mint fee. - Sets default royalty to the collection creator.
-
Marketplace.sol- Global listing/auction contract.
- Handles:
- Fixed-price listings,
- Auctions (with end time and bid state),
- Finalization and withdrawals.
- Uses EIP‑2981 royalty info from
NFTCollection.
| Action | Fee | Recipient |
|---|---|---|
| Collection creation | 0.05 ETH | Factory contract (owner withdraws) |
| Token minting | 0.01 ETH | Factory owner |
| Marketplace sale | 2.5% | Marketplace treasury |
| Creator royalty (resale) | 5.0% | Collection creator |
Tune these values before deploying to mainnet.
Located in frontend/:
- Home: Hero, featured collections, top NFTs, trending auctions.
- Collections: Desktop table + mobile cards, per-collection detail pages.
- Create: Tabs for “Create Collection” and “Mint NFT”.
- Auctions: Featured auctions and full list with sort options.
- Profile: My NFTs (including escrowed ones), withdraw panels, on-chain history.
- Footer: Minimal identity (Victor Valdes), copyright, email, and GitHub link.
The frontend talks to the deployed contracts via ABIs in frontend/src/abi/.
-
Clone the repo
git clone <repo-url> cd CollectionFactory
-
Install dependencies (run in both folders)
cd smartcontract && npm install && cd .. cd frontend && npm install && cd ..
-
Start a local Hardhat node (in a separate terminal)
cd smartcontract npx hardhat nodeKeep this running (default:
http://127.0.0.1:8545). -
Deploy contracts to the local node (see Deployment guide below). For local dev:
cd smartcontract npx hardhat run scripts/deploy.js --network localhostCopy the printed Factory and Marketplace addresses.
-
Connect the frontend to your deployment
- From the repo root, copy ABIs into the frontend:
node frontend/copy-abis.js
- Update
frontend/src/blockchain/contracts/addresses.jswith the addresses from step 4. - For local chain, add chain ID
31337tofrontend/src/abi/networks.js(see Supported networks).
- From the repo root, copy ABIs into the frontend:
-
Run the frontend
cd frontend npm run devOpen the dev server (usually
http://localhost:5173). In your wallet, switch to the local Hardhat network (e.g. addhttp://127.0.0.1:8545with chain ID31337).
Optional: create frontend/.env with Pinata keys for IPFS uploads:
VITE_APP_PINATA_KEY=your_pinata_key
VITE_APP_PINATA_SECRET=your_pinata_secretThe app can run against:
| Environment | Network | Chain ID | Use case |
|---|---|---|---|
| Local | Hardhat node | 31337 | Development; run npx hardhat node then deploy with --network localhost. |
| Testnet | Sepolia | 11155111 | Staging; configure INFURA_API_KEY and SEPOLIA_PRIVATE_KEY in Hardhat (see below). |
| Mainnet | Ethereum mainnet | 1 | Production; add mainnet in hardhat.config.js and in frontend/src/abi/networks.js; tune fees before deploying. |
- Frontend: Supported chain IDs and labels are in
frontend/src/abi/networks.js. Contract addresses are infrontend/src/blockchain/contracts/addresses.js. For a new network, add an entry to both (and deploy contracts to that network first). - Wallet: Users must connect to one of the supported chains; the UI will prompt to switch if they’re on a different network.
-
ABIs – After compiling or changing contracts, sync ABIs to the frontend:
node frontend/copy-abis.js
This copies from
smartcontract/artifacts/contracts/intofrontend/src/abi/(collectionFactoryAbi.json,marketplaceAbi.json,nftAbi.json). -
Addresses – Edit
frontend/src/blockchain/contracts/addresses.jsand set:COLLECTION_FACTORY_ADDRESS– from Factory deployment.MARKETPLACE_ADDRESS– from Marketplace deployment.
NFT collection addresses are per collection and come from the app (e.g.CollectionCreatedevents), not from this file.
-
Networks – In
frontend/src/abi/networks.js, ensure the chain ID you’re using (e.g. 31337 for local, 11155111 for Sepolia) is present inSUPPORTED_NETWORKSso the wallet and UI recognize it.
- Start the node:
cd smartcontract && npx hardhat node. - In another terminal:
npx hardhat run scripts/deploy.js --network localhost. - Copy the logged Factory and Marketplace addresses into
frontend/src/blockchain/contracts/addresses.js. - Run
node frontend/copy-abis.js, then start the frontend withnpm run devfromfrontend/.
- In
smartcontract/, configure Hardhat vars:npx hardhat vars set INFURA_API_KEY <your-infura-key> npx hardhat vars set SEPOLIA_PRIVATE_KEY <your-sepolia-account-private-key>
- Deploy:
npx hardhat run scripts/deploy.js --network sepolia
- Update
frontend/src/blockchain/contracts/addresses.jswith the new addresses and runnode frontend/copy-abis.js. Sepolia (chain ID 11155111) is already infrontend/src/abi/networks.js.
- Add a mainnet entry in
smartcontract/hardhat.config.js(e.g.url,accounts) and set any API keys viavarsor env. - Tune fees in the contracts (e.g. creation fee, mint fee, marketplace fee) and in the factory/marketplace logic before deploying.
- Run:
npx hardhat run scripts/deploy.js --network mainnet
- Add chain ID
1and a label tofrontend/src/abi/networks.js, and set the deployed addresses infrontend/src/blockchain/contracts/addresses.js.
From smartcontract/:
npm install
npx hardhat compile
npx hardhat testFrom frontend/:
npm install
npm run devFrom frontend/:
npm run buildDeploy the contents of frontend/dist/ to your preferred static host:
- Vercel
- Netlify
- S3 + CloudFront
- Any static file hosting
Make sure:
- Contract addresses used in the frontend match the current network.
- Environment variables are configured in your deployment environment.
Created by Victor Valdes
GitHub: @kick3top-stack
Email: kick.3top@gmail.com