This project implements a Web3 NFT marketplace with conditional minting after an approved transfer, built with Solidity, React, and Node.js. It focuses on a full-stack Web3 application flow, deploying smart contracts on the Base Testnet.
To create a Web3 application with the following flow:
- User Interaction: Users access the platform, browse NFT items (name + image).
- Purchase Flow: Upon clicking "Buy", the system:
- Opens MetaMask for an ETH transfer (fixed value) from the user's wallet to the platform's wallet.
- The transaction is recorded on-chain, and the backend (Node.js) is notified.
- The backend simulates a manual or automatic purchase analysis (e.g., random approval or simple criteria).
- Based on the analysis:
- If Approved: An NFT is minted via a smart contract on Base Testnet, using IPFS for metadata and image storage. The NFT is then sent to the user's wallet.
- If Rejected: The system refunds the paid ETH amount to the user's wallet (implemented via a
refund()
function in the contract or a backend command using a private key).
- Smart Contracts: Solidity (developed with Foundry)
- Frontend: React.js, Next.js, wagmi, RainbowKit (for wallet connection and interaction)
- Backend: Node.js with tRPC (for API routes and backend logic)
- Database: PostgreSQL with Prisma ORM
- IPFS Storage: Pinata (for storing NFT metadata and images)
- Blockchain Network: Base Testnet (Sepolia)
- Styling: Tailwind CSS
The repository is structured as follows:
src/
: Contains the Solidity smart contract (PetNft.sol
).test/
: Unit and integration tests for the Solidity contract.script/
: Foundry scripts for contract deployment.web/
: The Next.js frontend and Node.js backend application.web/src/app/
: Next.js pages and API routes.web/src/components/
: React components.web/src/lib/
: Web3 client configurations (wagmi, contract ABI).web/src/server/
: Backend services (tRPC routers, contract interaction, Pinata integration, Prisma).web/prisma/
: Prisma schema and migrations.
The PetNft.sol
contract is an ERC721 token that includes:
requestPurchase()
: Apayable
function allowing users to send ETH and signal a purchase intent. Emits aPurchaseRequested
event.approvePurchase(address buyer, string memory uri)
: Callable by the contract owner, mints an NFT to thebuyer
with the provided IPFSuri
. Emits aPurchaseApproved
event.rejectPurchase(address buyer, uint256 amount)
: Callable by the contract owner, refunds the specifiedamount
to thebuyer
. Emits aPurchaseRejected
event.Ownable
andReentrancyGuard
from OpenZeppelin for security.
The frontend provides:
- NFT Listing: Displays available NFTs with their details and prices.
- Purchase Flow: A multi-step process for purchasing an NFT:
- Confirm: User confirms purchase details and connects wallet.
- Processing: Displays transaction status while waiting for blockchain confirmation.
- Success: Confirms successful transaction and notifies the user about backend analysis.
- Error: Handles transaction failures.
- Admin Panel: (
/admin/purchases
) for the marketplace owner to manually approve or reject pending purchases. - User Purchases: (
/my-purchases
) to view the status of their purchases. - Feedback: Utilizes
sonner
for toast notifications and loading indicators.
The backend handles:
- Purchase Management: Stores purchase requests in a PostgreSQL database (via Prisma).
- Approval Logic: Provides tRPC procedures (
approvePurchase
,rejectPurchase
) that interact with the smart contract for minting NFTs or processing refunds. - IPFS Integration: Uses
PinataService
to handle NFT metadata. - Contract Interaction:
ContractService
usesviem
to interact with the deployed Solidity contract for minting and refunding. - Environment: Configured for local development (Anvil) and Base Testnet (Sepolia).
- Node.js (v18.x or higher)
- pnpm (or npm/yarn)
- Foundry (for Solidity development and testing)
- MetaMask browser extension
git clone https://github.com/your-username/web3-marketplace-hackathon.git
cd web3-marketplace-hackathon
# Install Foundry dependencies
forge install
# Build the contracts
forge build
# Run tests
forge test
# Deploy to local Anvil or Base Sepolia
# (Requires .env with PRIVATE_KEY and ETHERSCAN_API_KEY for Sepolia)
# Check script/DeployPetNft.s.sol for deployment logic
# You'll need to update the contract address in web/src/lib/contract/nft-marketplace.ts
# after deployment to Base Sepolia.
The contract is already deployed to Base Sepolia at 0xa8bebcc1781e2c8c70e783b68dbe6fa5afa2000f
.
cd web
# Install dependencies
pnpm install
# Set up environment variables
# Create a .env file based on .env.example
# Ensure you have DATABASE_URL, NEXT_PUBLIC_OWNER_PRIVATE_KEY, PINATA_JWT, etc.
cp .env.example .env
# Generate Prisma client and run migrations
npx prisma migrate dev --name init # if starting from scratch or after db push
npx prisma generate
# Start the development server
pnpm dev
The application will be accessible at http://localhost:3000
.
Access the admin panel at http://localhost:3000/admin/purchases
to approve or reject pending NFT purchases.
- Event-Driven Verification: The contract emits
PurchaseRequested
events, allowing the backend to listen for and process new purchases. - Unit & Integration Tests: Comprehensive tests for critical contract functions using Foundry.
- Pleasant User Interface: Responsive design with clear feedback mechanisms (toasts, loading states, step-by-step purchase flow).