Skip to content

sukabiru/Base-Moodboard

Repository files navigation

🩵 Base Moodboard — AI-Generated Mood NFT on Base

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).


🌐 Demo

🧩 Live App: https://base-moodboard.vercel.app/
📦 Smart Contract: deployed on Base Testnet / Base Mainnet


📜 Table of Contents


💡 Overview

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.


⚙️ Tech Stack

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

🎨 Features

✅ 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


🧩 Project Structure

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

💎 Smart Contract

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 baseSepolia

Then update src/lib/contract.ts with:

export const CONTRACT_ADDRESS = "0xYourContractAddress";

💻 Frontend (Next.js + Wagmi)

Connect wallet & mint UI:

  • useAccount → detect wallet
  • useWriteContract → send mint transaction
  • Mood selection via buttons
  • AI image preview via /api/generate-art

🧠 AI Art API

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>` });
  }
}

🔐 Environment Variables

Create .env.local in the project root:

NEXT_PUBLIC_PROJECT_ID=your-walletconnect-project-id
OPENAI_API_KEY=sk-...
CONTRACT_ADDRESS=0xYourContractAddress

🧑‍💻 Running Locally

git clone https://github.com/sukabiru/base-moodboard.git
cd base-moodboard
npm install
npm run dev

Visit 👉 http://localhost:3000


🚀 Deployment

Frontend:
Deploy easily via Vercel (supports Next.js automatically)

Smart Contract:
Deploy via Hardhat to Base Testnet:

npx hardhat run scripts/deploy.ts --network baseSepolia

🪩 Next Steps (Farcaster Mini App)

We're preparing Base Moodboard for Farcaster Frames integration — so users can mint directly inside Warpcast!

Planned Features:

  • /api/frame endpoint 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


🩵 Credits

Built with:

Made by 💻 @sukabiru


📜 License

MIT License © 2025 — Feel free to fork & build upon it!

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors