Mint your daily mood as NFT on Base!
Each NFT art is generated by OpenAI (ChatGPT Image Model) or fallback SVG onchain art.
Built with Next.js, Wagmi, and Solidity — and soon integrated with Farcaster Mini App (Frames).
🧩 Live App: https://base-moodboard.vercel.app/
📦 Smart Contract: deployed on Base Testnet / Base Mainnet
- Overview
- Tech Stack
- Features
- Project Structure
- Smart Contract
- Frontend
- AI Art API
- Environment Variables
- Running Locally
- Deployment
- Next Steps (Farcaster Mini App)
Base Moodboard is an experimental Web3 app where users can:
- Choose their mood (😄 happy, 😢 sad, 🤩 excited, 😎 chill)
- Generate mood-based art using AI
- Mint the art as an NFT on Base blockchain
This combines AI creativity + onchain expression.
| Layer | Technology |
|---|---|
| Smart Contract | Solidity (ERC721) |
| Blockchain | Base Mainnet / Base Sepolia |
| Frontend | Next.js 14 (App Router), Tailwind CSS |
| Web3 Hooks | Wagmi + Viem |
| AI Generation | OpenAI Image API (gpt-image-1) |
| Deployment | Vercel |
| Farcaster (Planned) | Frames + Frames.js SDK |
✅ Connect Wallet (Injected / WalletConnect only)
✅ AI-powered image generation (via OpenAI API)
✅ Onchain NFT minting (Base chain)
✅ Fallback SVG generation when AI unavailable
✅ “Built on Base” footer
🚀 (Coming soon) Farcaster Mini App integration
src/
├── app/
│ ├── page.tsx # Main page UI
│ ├── api/
│ │ ├── generate-art/route.ts # AI art generation endpoint
│ │ └── frame/route.ts # (optional) Farcaster frame
│
├── components/
│ └── ClientConnectWallet.tsx # Wallet connect button
│
├── lib/
│ ├── contract.ts # Contract address + ABI
│ ├── generateMoodSVG.ts # Fallback SVG generator
│
├── public/
│ └── Base_basemark_blue.png # Base logo for footer
│
└── styles/
└── globals.css
File: contracts/MoodNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MoodNFT is ERC721, Ownable {
uint256 private _tokenIdCounter;
mapping(uint256 => string) private _moods;
mapping(uint256 => string) private _svgs;
constructor() ERC721("BaseMoodboard", "MOOD") {}
function mintMood(string memory mood, string memory svg) public {
uint256 tokenId = _tokenIdCounter++;
_safeMint(msg.sender, tokenId);
_moods[tokenId] = mood;
_svgs[tokenId] = svg;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
string memory json = string(abi.encodePacked(
'{"name": "Mood #', Strings.toString(tokenId),
'", "description": "Your daily mood onchain", "image": "data:image/svg+xml;base64,',
Base64.encode(bytes(_svgs[tokenId])),
'"}'
));
return string(abi.encodePacked("data:application/json;base64,", Base64.encode(bytes(json))));
}
}Deployed using Hardhat:
npx hardhat run scripts/deploy.ts --network baseSepoliaThen update src/lib/contract.ts with:
export const CONTRACT_ADDRESS = "0xYourContractAddress";Connect wallet & mint UI:
useAccount→ detect walletuseWriteContract→ send mint transaction- Mood selection via buttons
- AI image preview via
/api/generate-art
File: src/app/api/generate-art/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { mood } = await req.json();
const prompt = `High-quality digital artwork representing the mood "${mood}".
Make it colorful, expressive, modern, detailed, and artistic.`;
try {
const res = await fetch("https://api.openai.com/v1/images/generations", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: "gpt-image-1",
prompt,
size: "1024x1024",
}),
});
const data = await res.json();
if (!data.data?.[0]?.url) throw new Error("No image returned from OpenAI");
return NextResponse.json({ imageUrl: data.data[0].url });
} catch (err) {
console.error("AI Art generation failed:", err);
return NextResponse.json({ svg: `<svg ...fallback art...></svg>` });
}
}Create .env.local in the project root:
NEXT_PUBLIC_PROJECT_ID=your-walletconnect-project-id
OPENAI_API_KEY=sk-...
CONTRACT_ADDRESS=0xYourContractAddressgit clone https://github.com/sukabiru/base-moodboard.git
cd base-moodboard
npm install
npm run devVisit 👉 http://localhost:3000
Frontend:
Deploy easily via Vercel (supports Next.js automatically)
Smart Contract:
Deploy via Hardhat to Base Testnet:
npx hardhat run scripts/deploy.ts --network baseSepoliaWe're preparing Base Moodboard for Farcaster Frames integration — so users can mint directly inside Warpcast!
/api/frameendpoint responding to frame interactions- Mood selection buttons directly inside a cast
- Frame Wallet mint support (on Base chain)
Tech planned:
frames.js + Warpcast Developer Portal
Built with:
Made by 💻 @sukabiru
MIT License © 2025 — Feel free to fork & build upon it!