# Project export: dAIos

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2025
- Tagline: Create and join communities powered by a DAO launchpad and funding platform that uses decentralized, verifiable, and autonomous agentic admittance criteria.
- Devpost: https://devpost.com/software/daios
- GitHub: https://github.com/rohan-patra/daios
- Demo: https://github.com/vardhanshorewala/avs
- Video: https://www.youtube.com/embed/WAfQk9bFt8s?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 2 GitHub contributor(s) — Rohan Patra (17 commits), Vardhan Shorewala (1 commits)

## Devpost submission (written by the team)

### Overview

Recently with the release of daos.fun, decentralized autonomous organizations have gained immense popularity with some DAOs generating over $2 billion in market cap. The TL;DR of daos.fun is that people create DAOs hosted by the site and then are able to raise money for their organization through funding rounds and whitelists. This sounds great on paper, but in practice, it has one major problem: the whitelist problem. The Whitelist Problem The whitelist problem is the issue of determining which users get early access and allocation to join each DAO in order to raise initial liquidity to support the DAO token’s liquidity pool. Currently, the way in which whitelists are determined is through DAO creators manually reviewing thousands of addresses that they were flooded with on Twitter or a Google Form they sent out. This process is often frustrating for both the creator of the DAO, who is just trying to find the right people for their organization, and even more frustrating for whitelist applicants who are fighting against an army of Twitter bots all trying to take their spot. Introducing dAIos To fight against this issue, we introduce dAIos, a DAO launchpad with eligibility entirely managed by autonomous agents. To create a DAO, all a user has to do is talk to our agent to determine what the necessary entry requirements should be. The agent will generate a list of requirements to join as well as give the creator the ability to mint DAO tokens and NFTs for future members of the DAO. NFT holders will be whitelist members and will be given a fixed allocation they can buy into before the token launches in order to get in early and generate initial liquidity. The DAO owner can also decide if NFT holders can get a share of the revenue generated by trading once the DAO token launches. How It Works To join a DAO, you will have to meet the eligibility criteria set by the DAO owner, determined by an agent that will search for your information online and ask you questions if it needs to confirm anything. If the agent finds you to be eligible, you will be given the DAO NFT and the opportunity to buy into the DAO token early through allocation. For example, say someone created RevengeDAO, a DAO where the target audience is people who have lost a lot of money in the past. In order to join, the agent might ask if you have any wallets that show you lost a considerable amount of money on a project. If you qualify, you will be given the NFT and early access to the token. Lessons Learned & Challenges Faced This project tackled a problem that all of our team members have personally experienced when using daos.fun. The whitelist process is full of bugs, spam, and major challenges for everyone involved. We truly believe that this product could drastically improve the status quo. When building this project, we learned just how difficult it is to build a cohesive app that manages so many components at once. Our biggest challenges were: Configuring AVS to verify our agent's findings. Ensuring that our smart contracts and tokenomics were airtight. In the end, we were left with an MVP that we are proud of and excited to develop further.

## README (from the GitHub repository)

# DAIOS - Decentralized AI Organization System

DAIOS is a modern web3 platform that combines decentralized autonomous organizations (DAOs) with AI capabilities, built on the T3 Stack and Ethereum blockchain.

## 🌟 Features

- **Smart Contract Integration**: Create and manage DAOs using Ethereum smart contracts
- **AI-Powered Chat**: Integrated AI chat system for DAO management and decision making
- **Web3 Authentication**: Secure wallet-based authentication using Web3Modal
- **Modern UI**: Beautiful and responsive interface built with Next.js 15 and Tailwind CSS
- **Type Safety**: End-to-end type safety with TypeScript

## 🚀 Tech Stack

- **Frontend**:

  - Next.js 15 (App Router)
  - React 18
  - Tailwind CSS
  - shadcn/ui components
  - Framer Motion for animations
  - Web3Modal for wallet connections

- **Blockchain**:

  - Wagmi for Ethereum interactions
  - Viem for Ethereum data handling
  - Custom Solidity smart contracts

- **AI & Backend**:
  - OpenAI integration
  - Next.js API routes
  - Environment variable management with T3 Env

## 📦 Prerequisites

- Node.js 18+ and npm/yarn/pnpm
- Git
- Foundry (for smart contract development)
- MetaMask or any Web3 wallet
- OpenAI API key

## 🛠 Setup

1. **Clone the repository**

   ```bash
   git clone https://github.com/yourusername/daios.git
   cd daios
   ```

2. **Install dependencies**

   ```bash
   # Install main project dependencies
   npm install

   # Install and update smart contract dependencies
   cd contracts
   forge install
   ```

3. **Environment Setup**

   ```bash
   # Copy the example env file
   cp .env.example .env

   # Fill in required environment variables:
   # - AUTH_SECRET (generate with: npx auth secret)
   # - AUTH_DISCORD_ID and AUTH_DISCORD_SECRET (from Discord Developer Portal)
   # - Other required variables for your deployment
   ```

4. **Smart Contract Setup**
   ```bash
   cd contracts
   forge build
   ```

## 🏃‍♂️ Development

1. **Start the development server**

   ```bash
   npm run dev
   ```

2. **Run smart contract tests**

   ```bash
   cd contracts
   forge test
   ```

3. **Code Quality**

   ```bash
   # Type checking
   npm run typecheck

   # Linting
   npm run lint

   # Format code
   npm run format:write
   ```

## 📝 Scripts

- `npm run dev` - Start development server
- `npm run build` - Build for production
- `npm run start` - Start production server
- `npm run lint` - Run ESLint
- `npm run typecheck` - Run TypeScript compiler check
- `npm run format:write` - Format code with Prettier
- `npm run format:check` - Check code formatting

## 🌐 Deployment

1. **Frontend**

   - Deploy to Vercel (recommended)
   - Or follow deployment guides for [Netlify](https://create.t3.gg/en/deployment/netlify) or [Docker](https://create.t3.gg/en/deployment/docker)

2. **Smart Contracts**
   - Deploy using Foundry to your chosen network
   - Update contract addresses in the frontend configuration

## 🤝 Contributing

1. Fork the repository
2. Create a new branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

## 🙏 Acknowledgments

- [T3 Stack](https://create.t3.gg/)
- [OpenZeppelin](https://www.openzeppelin.com/) for smart contract libraries
- [shadcn/ui](https://ui.shadcn.com/) for UI components


## Detected evidence (automated analysis)

Indexed codebase: 44 recognized source files, 159 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Solidity (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- FastAPI (technology) — claimed on Devpost, not found in the code
- LangChain (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (63 of 63)

```
.env.example
.eslintrc.cjs
.gitignore
.gitmodules
bun.lock
components.json
contracts/.gitignore
contracts/.gitmodules
contracts/broadcast/DaoFactory.s.sol/11155111/run-1739698519.json
contracts/broadcast/DaoFactory.s.sol/11155111/run-1739698662.json
contracts/broadcast/DaoFactory.s.sol/11155111/run-1739704836.json
contracts/broadcast/DaoFactory.s.sol/11155111/run-1739710386.json
contracts/broadcast/DaoFactory.s.sol/11155111/run-1739710513.json
contracts/broadcast/DaoFactory.s.sol/11155111/run-latest.json
contracts/foundry.toml
contracts/README.md
contracts/remappings.txt
contracts/script/DaoFactory.s.sol
contracts/src/DaoFactory.sol
contracts/src/DaoToken.sol
contracts/src/MegaETH.sol
contracts/test/DaoFactory.t.sol
data/chats.json
next.config.js
package.json
postcss.config.js
prettier.config.js
README.md
src/app/[slug]/components/ai-chat-dialog.tsx
src/app/[slug]/components/copy-button.tsx
src/app/[slug]/components/dao-header.tsx
src/app/[slug]/components/trading-card.tsx
src/app/[slug]/layout.tsx
src/app/[slug]/page.tsx
src/app/api/auth/[...nextauth]/route.ts
src/app/api/chat/route.ts
src/app/api/generate-criteria/route.ts
src/app/launch/page.tsx
src/app/layout.tsx
src/app/page.tsx
src/backend-python/connector/__init__.py
src/backend-python/connector/etherscan.py
src/backend-python/connector/github.py
src/backend-python/connector/twitter.py
src/backend-python/main.py
src/components/ui/button.tsx
src/components/ui/card.tsx
src/components/ui/carousel.tsx
src/components/ui/dialog.tsx
src/components/ui/input.tsx
src/components/ui/scroll-area.tsx
src/components/ui/sonner.tsx
src/components/ui/textarea.tsx
src/env.js
src/lib/utils.ts
src/providers/web3-provider.tsx
src/server/auth/config.ts
src/server/auth/index.ts
src/services/connections.ts
src/styles/globals.css
src/types/chat.ts
tailwind.config.ts
tsconfig.json
```

### Dependencies

- package.json: @radix-ui/react-dialog@^1.1.6, @radix-ui/react-scroll-area@^1.2.3, @radix-ui/react-slot@^1.1.2, @t3-oss/env-nextjs@^0.10.1, @tanstack/react-query@^5.66.0, @types/eslint@^8.56.10, @types/node@^20.14.10, @types/react@^18.3.3, @types/react-dom@^18.3.0, @types/uuid@^10.0.0, @typescript-eslint/eslint-plugin@^8.1.0, @typescript-eslint/parser@^8.1.0, @web3modal/wagmi@^5.1.11, class-variance-authority@^0.7.1, clsx@^2.1.1, embla-carousel-react@^8.5.2, eslint@^8.57.0, eslint-config-next@^15.0.1, framer-motion@^12.4.3, geist@^1.3.0, lucide-react@^0.475.0, next@^15.0.1, next-auth@5.0.0-beta.25, next-themes@^0.4.4, openai@^4.85.1, postcss@^8.4.39, prettier@^3.3.2, prettier-plugin-tailwindcss@^0.6.5, react@^18.3.1, react-dom@^18.3.1, sonner@^1.7.4, tailwind-merge@^3.0.1, tailwindcss@^3.4.3, tailwindcss-animate@^1.0.7, typescript@^5.5.3, uuid@^11.0.5, viem@^2.23.2, wagmi@^2.14.11, zod@^3.23.3

### Recent commits (newest first)

- update README
- Hotwiring for AVS
- fxes
- Update route.ts
- Merge branch 'main' of https://github.com/rohan-patra/daios
- wallet connection logic
- merged data connector in python
- Update page.tsx
- add wallet connection on launch
- update contracts
- Update env.js
- integration stuff
- forge install: openzeppelin-contracts
- forge install: forge-std
- contracts
- add launch funcionality
- updates
- UI scaffold
- init

## Key source files (fetched from GitHub, selected and truncated for size)

### package.json

```
{
  "name": "daios",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "next build",
    "check": "next lint && tsc --noEmit",
    "dev": "next dev --turbo",
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "preview": "next build && next start",
    "start": "next start",
    "typecheck": "tsc --noEmit",
    "format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
    "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache"
  },
  "dependencies": {
    "@radix-ui/react-dialog": "^1.1.6",
    "@radix-ui/react-scroll-area": "^1.2.3",
    "@radix-ui/react-slot": "^1.1.2",
    "@t3-oss/env-nextjs": "^0.10.1",
    "@tanstack/react-query": "^5.66.0",
    "@types/uuid": "^10.0.0",
    "@web3modal/wagmi": "^5.1.11",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "embla-carousel-react": "^8.5.2",
    "framer-motion": "^12.4.3",
    "geist": "^1.3.0",
    "lucide-react": "^0.475.0",
    "next": "^15.0.1",
    "next-auth": "5.0.0-beta.25",
    "next-themes": "^0.4.4",
    "openai": "^4.85.1",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "sonner": "^1.7.4",
    "tailwind-merge": "^3.0.1",
    "tailwindcss-animate": "^1.0.7",
    "uuid": "^11.0.5",
    "viem": "^2.23.2",
    "wagmi": "^2.14.11",
    "zod": "^3.23.3"
  },
  "devDependencies": {
    "@types/eslint": "^8.56.10",
    "@types/node": "^20.14.10",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@typescript-eslint/eslint-plugin": "^8.1.0",
    "@typescript-eslint/parser": "^8.1.0",
    "eslint": "^8.57.0",
    "eslint-config-next": "^15.0.1",
    "postcss": "^8.4.39",
    "prettier": "^3.3.2",
    "prettier-plugin-tailwindcss": "^0.6.5",
    "tailwindcss": "^3.4.3",
    "typescript": "^5.5.3"
  },
  "ct3aMetadata": {
    "initVersion": "7.38.1"
  }
}

```

### src/app/layout.tsx

```typescript
import "@/styles/globals.css";
import { Inter } from "next/font/google";
import { type Metadata } from "next";
import { Toaster } from "sonner";
import { Web3Provider } from "@/providers/web3-provider";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "dAIos - AI-Powered DAO Platform",
  description:
    "Launch and manage DAOs with intelligent, unbiased member admittance",
  icons: [{ rel: "icon", url: "/favicon.ico" }],
};

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en" className={`${inter.className}`}>
      <body>
        <Web3Provider>
          {children}
          <Toaster theme="dark" position="top-center" />
        </Web3Provider>
      </body>
    </html>
  );
}

```

### src/backend-python/main.py

```python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from connector.twitter import fetch_twitter
from connector.etherscan import fetch_wallet_activity
from connector.github import fetch_github_activity
from langchain.tools import Tool
import asyncio

app = FastAPI()


class TwitterRequest(BaseModel):
    username: str


class EtherscanRequest(BaseModel):
    wallet_address: str
    chain_id: int = 1


class GithubRequest(BaseModel):
    username: str


@app.post("/twitter")
async def get_twitter_data(request: TwitterRequest):
    """Fetch data from Twitter connector asynchronously."""
    try:
        twitter_tool = Tool(
            name="TwitterActivityFetcher",
            func=lambda username: fetch_twitter(username, tweet_count=10),
            description="Fetches the latest tweets and engagement stats for a given Twitter handle."
        )

        activity_data = await asyncio.to_thread(twitter_tool.run, request.username)
        return activity_data

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/etherscan")
async def get_etherscan_data(request: EtherscanRequest):
    """Fetch data from Etherscan connector asynchronously."""
    try:
        etherscan_tool = Tool(
            name="EtherscanWalletActivity",
            func=lambda wallet_address, chain_id=1: fetch_wallet_activity(wallet_address, chain_id),
            description="Fetches wallet activity (ETH balance, transactions, token transfers) from Etherscan."
        )

        activity_data = await asyncio.to_thread(
            etherscan_tool.run, request.wallet_address, request.chain_id
        )
        return activity_data

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/github")
async def get_github_data(request: GithubRequest):
    """Fetch data from GitHub connector asynchronously."""
    try:
        github_activity_tool = Tool(
            name="GitHubActivityFetcher",
            func=lambda username: fetch_github_activity(username),
            description="Fetches GitHub activity stats including total commits, repos contributed to, and stars."
        )

        activity_data = await asyncio.to_thread(github_activity_tool.run, request.username)
        return activity_data

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8001)

```

### src/server/auth/index.ts

```typescript
import NextAuth from "next-auth";
import { cache } from "react";

import { authConfig } from "./config";

const { auth: uncachedAuth, handlers, signIn, signOut } = NextAuth(authConfig);

const auth = cache(uncachedAuth);

export { auth, handlers, signIn, signOut };

```

### src/app/page.tsx

```typescript
"use client";

import { useEffect, useState, type MouseEvent } from "react";
import Link from "next/link";
import { motion, useAnimation } from "framer-motion";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  ArrowRight,
  CheckCircle,
  Cpu,
  Globe,
  LockKeyhole,
  Rocket,
  Users,
} from "lucide-react";
import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
} from "@/components/ui/carousel";

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const MotionLink = motion(Link);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const MotionButton = motion(Button);

export default function LandingPage() {
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
  const controls = useAnimation();
  const [isVisible, setIsVisible] = useState(false);

  const scrollToSection = (
    e: MouseEvent<HTMLAnchorElement>,
    sectionId: string,
  ) => {
    e.preventDefault();
    const element = document.getElementById(sectionId);
    if (element) {
      element.scrollIntoView({ behavior: "smooth" });
    }
  };

  useEffect(() => {
    const handleScroll = () => {
      if (window.scrollY > 100) {
        setIsVisible(true);
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
        void controls.start("visible");
      } else {
        setIsVisible(false);
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
        void controls.start("hidden");
      }
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, [controls]);

  const fadeInUp = {
    hidden: { opacity: 0, y: 20 },
    visible: { opacity: 1, y: 0, transition: { duration: 0.6 } },
  };

  const staggerChildren = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: 0.2,
      },
    },
  };

  const pulseAnimation = {
    scale: [1, 1.05, 1],
    transition: { duration: 2, repeat: Number.POSITIVE_INFINITY },
  };

  return (
    <div className="flex min-h-screen flex-col bg-[#1a1635] text-[#e0d9ff]">
      <motion.header
        className="fixed z-50 flex h-14 w-full items-center bg-[#13102b] px-4 lg:px-6"
        initial={{ y: -100 }}
        animate={{ y: 0 }}
        transition={{ type: "spring", stiffness: 300, damping: 30 }}
      >
        <MotionLink
          className="flex items-center justify-center"
          href="#"
          whileHover={{ scale: 1.05 }}
        >
          <Rocket className="mr-2 h-6 w-6 text-[#14f195]" />
          <span className="font-bold text-[#e0d9ff]">dAIos</span>
        </MotionLink>
        <nav className="ml-auto flex gap-4 sm:gap-6">
          <MotionLink
            className="text-sm font-medium transition-colors hover:text-[#14f195]"
            href="#features"
            onClick={(e: React.MouseEvent<HTMLAnchorElement>) =>
              scrollToSection(e, "features")
            }
            whileHover={{ scale: 1.1 }}
          >
            Features
          </MotionLink>
          <MotionLink
            className="text-sm font-medium transition-colors hover:text-[#14f195]"
            href="#how-it-works"
            onClick={(e: React.MouseEvent<HTMLAnchorElement>) =>
              scrollToSection(e, "how-it-works")
            }
            whileHover={{ scale: 1.1 }}
          >
            How It Works
          </MotionLink>
          <MotionLink
            className="text-sm font-medium transition-colors hover:text-[#14f195]"
            href="#benefits"
            onClick={(e: React.MouseEvent<HTMLAnchorElement>) =>
              scrollToSection(e, "benefits")
            }
            whileHover={{ scale: 1.1 }}
          >
            Benefits
          </MotionLink>
        </nav>
      </motion.header>
      <main className="flex-1 pt-14">
        <section className="w-full py-12 md:py-20 lg:py-24 xl:py-32">
          <div className="container mx-auto max-w-7xl px-4 md:px-6">
            <motion.div
              className="flex flex-col items-center space-y-4 text-center"
              initial="hidden"
              animate="visible"
              variants={staggerChildren}
            >
              <motion.div className="space-y-2" variants={fadeInUp}>
                <h1 className="text-3xl font-bold tracking-tighter text-[#e0d9ff] sm:text-4xl md:text-5xl lg:text-6xl/none">
                  Build Fair DAOs with AI-Powered Member Selection
                </h1>
                <p className="mx-auto max-w-[700px] text-[#b3a8e0] md:text-xl">
                  Eliminate bias in DAO membership with our intelligent
                  admittance system. Set objective criteria and let AI ensure
                  fair, transparent, and merit-based community growth.
                </p>
              </motion.div>
              <Link href="/launch">
                <motion.div className="space-x-4" variants={fadeInUp}>
                  <MotionButton
                    className="bg-[#14f195] text-[#13102b] hover:bg-[#0dc77b]"
                    whileHover={{ scale: 1.05 }}
                    whileTap={{ scale: 0.95 }}
                  >
                    Get Started
                  </MotionButton>
                  <MotionButton
                    variant="outline"
                    className="border-[#14f195] bg-transparent text-[#14f195] hover:bg-[#14f195]/10"
                    whileHover={{ scale: 1.05 }}
                    whileTap={{ scale: 0.95 }}
                  >
                    Learn More
                  </MotionButton>
                </motion.div>
              </Link>
            </motion.div>
          </div>
        </section>
        <
[truncated — 14811 more characters]
```

### src/app/[slug]/layout.tsx

```typescript
import { type Metadata } from "next";
import { use } from "react";

// Mock data store - replace with actual data fetching
const mockDaos = {
  "defi-governance": {
    name: "DeFi Governance DAO",
    description: "Decentralized financial protocols governance",
  },
  "nft-creators": {
    name: "NFT Creators Guild",
    description: "Digital artists and NFT creators collective",
  },
  "climate-action": {
    name: "Climate Action DAO",
    description: "Funding climate change initiatives",
  },
};

type Props = {
  params: Promise<{ slug: string }>;
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  const dao = mockDaos[slug as keyof typeof mockDaos];

  if (!dao) {
    return {
      title: "DAO Not Found",
      description: "The requested DAO does not exist.",
    };
  }

  return {
    title: `${dao.name} - dAIos Platform`,
    description: dao.description,
  };
}

export default function DaoLayout({ children }: { children: React.ReactNode }) {
  return children;
}

```

### src/app/launch/page.tsx

```typescript
"use client";

import { useState, useEffect } from "react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import {
  ArrowLeft,
  ArrowRight,
  Upload,
  CheckCircle2,
  Github,
  Twitter,
  Wallet,
  Heart,
  Loader2,
} from "lucide-react";
import {
  useAccount,
  useConnect,
  useWriteContract,
  useWaitForTransactionReceipt,
} from "wagmi";
import { toast } from "sonner";
import { useWeb3Modal } from "@web3modal/wagmi/react";
import { parseEther } from "viem";

type Step = {
  title: string;
  description: string;
};

const steps: Step[] = [
  {
    title: "Token Details",
    description: "Set your DAO's name, symbol, and description",
  },
  {
    title: "Eligibility Criteria",
    description: "Define who can join your DAO",
  },
  {
    title: "Review & Launch",
    description: "Review your DAO configuration",
  },
];

type DaoConfig = {
  name: string;
  description: string;
  image: string | null;
  tokenSymbol: string;
  systemPrompt: string;
  generatedCriteria: Array<{
    title: string;
    description: string;
    icon: "github" | "twitter" | "wallet" | "generic";
  }> | null;
};

type GenerateCriteriaResponse = {
  criteria: Array<{
    title: string;
    description: string;
    icon: "github" | "twitter" | "wallet" | "generic";
  }>;
};

const DAOFACTORY_ADDRESS = "0x897D2065a4ac35B97D8c9063037C56D7b6004c4b";
const DAOFACTORY_ABI = [
  {
    type: "function",
    name: "createDao",
    inputs: [
      { name: "baseURI", type: "string", internalType: "string" },
      { name: "tokenName", type: "string", internalType: "string" },
      { name: "tokenSymbol", type: "string", internalType: "string" },
      { name: "tokenInitialSupply", type: "uint256", internalType: "uint256" },
      { name: "mintPrice", type: "uint256", internalType: "uint256" },
      { name: "maxMintPerNFT", type: "uint256", internalType: "uint256" },
    ],
    outputs: [],
    stateMutability: "nonpayable",
  },
] as const;

export default function LaunchPage() {
  const router = useRouter();
  const [currentStep, setCurrentStep] = useState(0);
  const [isGenerating, setIsGenerating] = useState(false);
  const { address, isConnected } = useAccount();
  const { connect, connectors } = useConnect();
  const { open } = useWeb3Modal();
  const [daoConfig, setDaoConfig] = useState<DaoConfig>({
    name: "",
    description: "",
    image: null,
    tokenSymbol: "",
    systemPrompt: "",
    generatedCriteria: null,
  });

  const { writeContract, data: hash } = useWriteContract();

  const { isLoading: isDeploying, isSuccess: isDeployed } =
    useWaitForTransactionReceipt({
      hash,
    });

  useEffect(() => {
    if (address) {
      console.log("Connected wallet address:", address);
      toast.success("Wallet connected successfully!");
    }
  }, [address]);

  useEffect(() => {
    if (hash) {
      toast.success("Transaction submitted!");
      router.push(`/revenge-dao`);
    }
  }, [hash, router]);

  const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files?.[0]) {
      const reader = new FileReader();
      reader.onload = (event) => {
        const result = event.target?.result;
        if (result) {
          setDaoConfig((prev) => ({
            ...prev,
            image: result as string,
          }));
        }
      };
      reader.readAsDataURL(e.target.files[0]);
    }
  };

  const generateCriteria = async () => {
    try {
      setIsGenerating(true);

      const response = await fetch("/api/generate-criteria", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          prompt: daoConfig.systemPrompt,
          daoName: daoConfig.name,
          tokenSymbol: daoConfig.tokenSymbol,
        }),
      });

      if (!response.ok) {
        throw new Error("Failed to generate criteria");
      }

      const data = (await response.json()) as GenerateCriteriaResponse;
      setDaoConfig((prev) => ({
        ...prev,
        generatedCriteria: data.criteria,
      }));
    } catch (error) {
      console.error("Error generating criteria:", error);
      // You might want to show an error toast here
    } finally {
      setIsGenerating(false);
    }
  };

  const handleNext = () => {
    if (currentStep === 2 && !daoConfig.generatedCriteria) {
      void generateCriteria();
    }
    setCurrentStep((prev) => Math.min(prev + 1, steps.length - 1));
  };

  const handleBack = () => {
    setCurrentStep((prev) => Math.max(prev - 1, 0));
  };

  const handleLaunch = async () => {
    if (!isConnected) {
      try {
        await open();
        if (!address) {
          toast.error("Please connect your wallet to continue");
          return;
        }
      } catch (error) {
        console.error("Failed to connect wallet:", error);
        toast.error("Failed to connect wallet. Please try again.");
        return;
      }
    }

    // TODO: Save DAO configuration and create new DAO
    router.push("/defi-governance");
  };

  const handleDeploy = async () => {
    if (!isConnected) {
      try {
        await open();
        return;
      } catch (error) {
        console.error("Failed to connect wallet:", error);
        toast.error("Failed to connect wallet. Please try again.");
        return;
      }
    }

    try {
      writeContract({
        address: DAOFACTORY_ADDRESS,
        abi: DAOFACTORY_ABI,
        functionName: "createDao",
        args: [
          "https://test-metadata.com/", // baseURI (string)
          "Test DAO", // tokenName (string)
          "TEST", // tokenSymbol (string)
          0n, // tokenInitialSupply (uint256)
          1000000000000000n, // mintPrice (uint256) - 0.001 ETH in
[truncated — 12123 more characters]
```

### src/app/[slug]/page.tsx

```typescript
"use client";

import { notFound } from "next/navigation";
import Image from "next/image";
import Link from "next/link";
import { useState, use } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
  Twitter,
  Search,
  Github,
  Wallet,
  CheckCircle2,
  Heart,
} from "lucide-react";
import CopyButton from "./components/copy-button";
import TradingCard from "./components/trading-card";
import { AIChatDialog } from "./components/ai-chat-dialog";

// Mock data store - replace with actual data fetching
const mockDaos = {
  "defi-governance": {
    name: "DeFi Governance DAO",
    image: "https://i.imgur.com/hBKRN4C.png",
    description: "Decentralized financial protocols governance",
    tokenAddress: "0x1234567890123456789012345678901234567890",
    tokenSymbol: "DGOV",
    tokenPrice: "12.45",
    tokenChange24h: "+5.67%",
    discordUrl: "https://discord.gg/defigovernance",
    eligibilityCriteria: [
      {
        title: "GitHub Activity",
        description:
          "Active contributions to blockchain/DeFi projects, smart contract development experience",
        icon: "github",
      },
      {
        title: "Community Engagement",
        description:
          "Active participation in web3 discussions, meaningful interactions with other DAOs",
        icon: "twitter",
      },
      {
        title: "On-Chain Activity",
        description:
          "History of DeFi protocol usage, governance participation, and responsible token management",
        icon: "wallet",
      },
      {
        title: "Personal Qualities",
        description:
          "Eager to learn and share knowledge about DeFi, passionate about decentralized governance, and committed to collaborative decision-making",
        icon: "generic",
      },
    ],
    members: [
      {
        name: "Alice Crypto",
        twitter: "alicecrypto",
        avatar: "https://randomuser.me/api/portraits/women/1.jpg",
      },
      {
        name: "Bob Blockchain",
        twitter: "bobblockchain",
        avatar: "https://randomuser.me/api/portraits/men/1.jpg",
      },
      {
        name: "Carol Chain",
        twitter: "carolchain",
        avatar: "https://randomuser.me/api/portraits/women/2.jpg",
      },
      {
        name: "David DeFi",
        twitter: "daviddefi",
        avatar: "https://randomuser.me/api/portraits/men/2.jpg",
      },
      {
        name: "Eva Ethereum",
        twitter: "evaethereum",
        avatar: "https://randomuser.me/api/portraits/women/3.jpg",
      },
      {
        name: "Frank Finance",
        twitter: "frankfinance",
        avatar: "https://randomuser.me/api/portraits/men/3.jpg",
      },
      {
        name: "Grace Governance",
        twitter: "gracegovernance",
        avatar: "https://randomuser.me/api/portraits/women/4.jpg",
      },
      {
        name: "Henry Hodl",
        twitter: "henryhodl",
        avatar: "https://randomuser.me/api/portraits/men/4.jpg",
      },
      {
        name: "Ivy Investment",
        twitter: "ivyinvestment",
        avatar: "https://randomuser.me/api/portraits/women/5.jpg",
      },
      {
        name: "Jack Yield",
        twitter: "jackyield",
        avatar: "https://randomuser.me/api/portraits/men/5.jpg",
      },
      {
        name: "Kelly Keys",
        twitter: "kellykeys",
        avatar: "https://randomuser.me/api/portraits/women/6.jpg",
      },
      {
        name: "Liam Liquidity",
        twitter: "liamliquidity",
        avatar: "https://randomuser.me/api/portraits/men/6.jpg",
      },
    ],
  },
  "nft-creators": {
    name: "NFT Creators Guild",
    image: "/placeholder-dao-2.png",
    description: "Digital artists and NFT creators collective",
    tokenAddress: "0x5678901234567890123456789012345678901234",
    tokenSymbol: "NFTG",
    tokenPrice: "8.32",
    tokenChange24h: "-2.14%",
    discordUrl: "https://discord.gg/nftcreators",
    eligibilityCriteria: [
      {
        title: "GitHub Activity",
        description:
          "Experience with NFT smart contracts and marketplace development",
        icon: "github",
      },
      {
        title: "Community Engagement",
        description:
          "Active participation in NFT communities and art collectives",
        icon: "twitter",
      },
      {
        title: "On-Chain Activity",
        description:
          "History of NFT creation, trading, and marketplace participation",
        icon: "wallet",
      },
      {
        title: "Personal Qualities",
        description:
          "Passionate about digital art and NFT innovation, willing to mentor others, and committed to fostering a creative community",
        icon: "generic",
      },
    ],
    members: [
      {
        name: "Charlie Digital",
        twitter: "charliedigital",
        avatar: "https://randomuser.me/api/portraits/men/7.jpg",
      },
      {
        name: "Diana NFT",
        twitter: "dianaNFT",
        avatar: "https://randomuser.me/api/portraits/women/7.jpg",
      },
      {
        name: "Emma Art",
        twitter: "emmaart",
        avatar: "https://randomuser.me/api/portraits/women/8.jpg",
      },
      {
        name: "Felix Pixel",
        twitter: "felixpixel",
        avatar: "https://randomuser.me/api/portraits/men/8.jpg",
      },
      {
        name: "Gina Gallery",
        twitter: "ginagallery",
        avatar: "https://randomuser.me/api/portraits/women/9.jpg",
      },
      {
        name: "Harry Hologram",
        twitter: "harryhologram",
        avatar: "https://randomuser.me/api/portraits/men/9.jpg",
      },
      {
        name: "Iris Illustrator",
        twitter: "irisillustrator",
        avatar: "https://randomuser.me/api/portraits/women/10.jpg",
      },
      {
        name: "Jake JPEG",
        twitter: "jakejpeg",
        avatar: "https://randomuser.me/api/portraits/men/10.jpg",
      },
[truncated — 14927 more characters]
```

### src/app/api/generate-criteria/route.ts

```typescript
import { env } from "@/env";
import { OpenAI } from "openai";
import { type ChatCompletionMessageParam } from "openai/resources/chat/completions";
import { type ChatCompletion } from "openai/resources";
import { type NextRequest } from "next/server";

type RequestBody = {
  prompt: string;
  daoName: string;
  tokenSymbol: string;
};

type CriteriaResponse = {
  criteria: Array<{
    title: string;
    description: string;
    icon: "github" | "twitter" | "wallet" | "generic";
  }>;
};

if (!env.OPENAI_API_KEY) {
  throw new Error("OPENAI_API_KEY is not set");
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const openai = new OpenAI({
  apiKey: env.OPENAI_API_KEY,
});

export async function POST(req: NextRequest) {
  try {
    const body = (await req.json()) as RequestBody;
    const { prompt, daoName, tokenSymbol } = body;

    const systemPrompt = `You are an AI tasked with evaluating DAO membership applications. Given the following description of eligibility criteria for the DAO "${daoName}" (${tokenSymbol}), generate professional, abstract criteria summaries.

IMPORTANT RULES:
1. Only use concepts EXPLICITLY provided in the user's description
2. Do not add requirements that weren't mentioned
3. Do not split a single requirement into multiple similar ones
4. Generate ONLY the number of criteria that are actually distinct in the description
5. Make each criterion abstract and professional, avoiding direct quotes or specific wording from the input
6. Use the most appropriate icon for each criterion:
   - github: for code and technical contributions
   - twitter: for social and community engagement (ONLY if specifically mentioned)
   - wallet: for financial or on-chain activity (ONLY if specifically mentioned)
   - generic: for values, principles, and any criteria that doesn't fit the above

Format the response as a JSON object with a 'criteria' array containing objects for each distinct criterion mentioned:
- title: A professional, generalized title that captures the essence of the requirement
- description: A polished, abstract description that conveys the requirement without mirroring the input text
- icon: One of "github", "twitter", "wallet", or "generic" (use ONLY relevant icons)

Example format:
{
  "criteria": [
    {
      "title": "Technical Expertise",
      "description": "Demonstrated excellence in blockchain development through substantial open-source contributions",
      "icon": "github"
    }
  ]
}

Remember: Focus on conveying the essence of each requirement in a professional, abstract manner without revealing the exact input phrasing.`;

    const userPrompt = `DAO Description: ${prompt}

Generate abstract, professional criteria based on the core requirements in the description. Avoid mirroring the exact input text.`;

    const messages: ChatCompletionMessageParam[] = [
      { role: "system", content: systemPrompt },
      { role: "user", content: userPrompt },
    ];

    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
    const completion = (await openai.chat.completions.create({
      model: "gpt-4-turbo-preview",
      messages,
      temperature: 0.7,
      response_format: { type: "json_object" },
    })) satisfies ChatCompletion;

    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
    const content = completion.choices[0]?.message.content;
    if (typeof content !== "string") {
      throw new Error("No content in response");
    }

    try {
      const parsedContent = JSON.parse(content) as CriteriaResponse;
      if (!parsedContent.criteria || !Array.isArray(parsedContent.criteria)) {
        throw new Error("Invalid response format");
      }
      return Response.json({ criteria: parsedContent.criteria });
    } catch (parseError) {
      console.error("Error parsing OpenAI response:", parseError);
      return Response.json(
        { error: "Failed to parse criteria" },
        { status: 500 },
      );
    }
  } catch (error) {
    console.error("Error in generate-criteria:", error);
    return Response.json(
      { error: "Failed to generate criteria" },
      { status: 500 },
    );
  }
}

```

### src/app/api/chat/route.ts

```typescript
import { env } from "@/env";
import { OpenAI } from "openai";
import { type ChatCompletionMessageParam } from "openai/resources/chat/completions";
import { type ChatCompletion } from "openai/resources";
import { type NextRequest } from "next/server";
import { v4 as uuidv4 } from "uuid";
import { promises as fs } from "fs";
import path from "path";
import {
  type ChatMessage,
  type ChatSession,
  type ChatStorage,
} from "@/types/chat";
import { type ToolCall } from "openai/resources/chat/completions";
import { type Address } from "viem";

if (!env.OPENAI_API_KEY) {
  throw new Error("OPENAI_API_KEY is not set");
}

const openai = new OpenAI({
  apiKey: env.OPENAI_API_KEY,
});

const CHATS_FILE = path.join(process.cwd(), "data/chats.json");

async function fetchData(randomName: string) {
  try {
    const response = await fetch("http://localhost:3000/create-task", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ randomName }),
    });

    const resultText = await response.text();

    return JSON.parse(resultText);
  } catch (error) {
    console.error("Error creating task:", error);
    throw error;
  }
}


async function fetchEtherscanData(
  wallet_address: string,
  chain_id: number = 1,
) {
  try {
    const URL="http://localhost:8001/etherscan";

    const response_avs = await fetchData(URL);
    console.log("response_avs",response_avs);

    const response = await fetch(URL , {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ wallet_address, chain_id }),
    });

    if (!response.ok) {
      throw new Error(`Etherscan API error: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    console.error("Etherscan fetch error:", error);
    return null;
  }
}

async function fetchGithubData(username: string) {
  try {
    const URL="http://localhost:8001/github";
    const response_avs = await fetchData(URL);
    console.log("response_avs",response_avs);
    const response = await fetch(URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ username }),
    });

    if (!response.ok) {
      throw new Error(`GitHub API error: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    console.error("GitHub fetch error:", error);
    return null;
  }
}

async function fetchTwitterData(username: string) {
  try {
    const response = await fetch("http://localhost:8001/twitter", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ username }),
    });

    if (!response.ok) {
      throw new Error(`Twitter API error: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    console.error("Twitter fetch error:", error);
    return null;
  }
}

async function ensureChatsFile() {
  try {
    await fs.mkdir(path.dirname(CHATS_FILE), { recursive: true });
    try {
      await fs.access(CHATS_FILE);
    } catch {
      await fs.writeFile(CHATS_FILE, JSON.stringify({}));
    }
  } catch (error) {
    console.error("Error ensuring chats file:", error);
    throw error;
  }
}

async function loadChats(): Promise<ChatStorage> {
  await ensureChatsFile();
  const content = await fs.readFile(CHATS_FILE, "utf-8");
  return JSON.parse(content) as ChatStorage;
}

async function saveChats(chats: ChatStorage) {
  await ensureChatsFile();
  await fs.writeFile(CHATS_FILE, JSON.stringify(chats, null, 2));
}

const systemPrompt = `You are an AI evaluator for DAO membership applications. Your role is to:

1. Systematically verify EACH eligibility criterion in order, one at a time
2. Request account connections (GitHub, Twitter, Wallet) when needed to verify specific criteria
3. Track and confirm which criteria have been met
4. Make a final decision only after ALL criteria have been verified

Follow these rules:
- Start by explaining the evaluation process
- For each criterion:
  1. State which criterion you're currently evaluating
  2. Request the relevant account connection if needed
  3. After receiving a connection, explicitly confirm the username/address received
  4. Analyze the data from the respective API endpoint and use to evaluate if the criterion is met
  5. Verify if the criterion is met before moving to the next one

- Do not proceed to the next criterion until the current one is fully verified
- Keep track of which criteria are verified and which are pending
- Make decisions based ONLY on the verified criteria
- Provide clear feedback for each verification step
- Each message from you should either be the final tool call or a prompt for the user to respond to

IMPORTANT: You must respond in JSON format with this structure:
{
  "message": "Your response message here",
  "toolCalls": [
    {
      "type": "connection_request",
      "account_type": "github" // or "twitter" or "wallet"
    }
  ],
  "mint": boolean // Set to true ONLY when ALL criteria are verified and met
}

Guidelines for responses:
1. When starting a new chat:
   - Explain that you'll verify each criterion in order
   - Start with the first criterion
   - Request relevant connection if needed

2. After receiving a connection:
   - Acknowledge the specific account connected (e.g., "I see you've connected your GitHub account: username")
   - Verify if this connection satisfies the current criterion
   - Either mark the criterion as verified or explain why it's not met
   - Move to the next criterion only after current is verified

3. When making a decision:
   - For acceptance: Confirm ALL criteria are met, set mint to true
   - For rejection: List specific criteria that weren't met

The toolCalls array is optional and should only be included when you need to request account connections.
Your responses in the "message" field should be professional, encouraging, and clear.`;

interface AccountC
[truncated — 6901 more characters]
```

[32 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]