Skip to content

Latest commit

 

History

History
168 lines (127 loc) · 9.29 KB

File metadata and controls

168 lines (127 loc) · 9.29 KB

CLAUDE.md

Project guide for the Gnars DAO website. Keep terse, keep current.

Documentation Rules (Must Follow)

  • docs/INDEX.md is the canonical documentation map. Update it in the same change when adding/moving/removing docs.
  • All project docs live under docs/. Root allows only README.md, CLAUDE.md, AGENTS.md.
  • No docs in tasks/ or src/**/README.md. Scripts go in scripts/.
  • Docs must reflect current code. Stale doc → update or delete.
  • AGENTS.md covers subagent routing only; do not duplicate these rules there.

Project Overview

Next.js 16 App Router site (React 19) for Gnars DAO on Base (chain ID 8453). Built on Nouns Builder architecture. Wallet layer is split:

  • thirdweb v5 — login + writes + account abstraction (sponsorGas: true)
  • wagmi v2 + viem — reads transport only (connectors array empty)

Commands

pnpm dev           # dev server (Turbopack)
pnpm build         # prod build (do not run unless asked)
pnpm start         # prod server
pnpm lint          # eslint — run before PR
pnpm format        # prettier write
pnpm format:check  # prettier check
pnpm test          # vitest unit tests (src/**/*.test.ts)
pnpm exec playwright test  # e2e tests (tests/e2e/)

Unit tests via vitest (test, test:watch, test:coverage) — currently cover src/lib/proposal-*. Playwright e2e specs in tests/e2e/: propdates, gnars-gov, i18n, verify-nft-multiselect.

Source Layout

src/
├── app/              # App Router routes incl. /auctions /proposals /propose /tv /members /treasury /feed /propdates /droposals /installations /blogs /coin-proposal /community/bounties /map /mural /swap /rounds
│   ├── api/          # ~21 route groups (alchemy, coins, ens, og, pinata, propdates, proposals, treasury, tv, 0x, rounds, …)
│   └── md/           # markdown content-negotiation target (see proxy.ts)
├── components/       # ~24 feature dirs + ui/ (shadcn)
├── hooks/            # ~38 hooks — see naming note below
├── i18n/             # next-intl config (routing, request, navigation)
├── services/         # 17 data-layer modules (auctions, proposals, treasury, feed, members, farcaster, poidh, snapshot, rounds, …)
├── lib/              # config.ts, thirdweb.ts, wagmi.ts, subgraph.ts, ipfs.ts, zora-*, proposal-*, og-*, schemas/, types/
├── data/             # static JSON (installations.json)
├── types/            # shared TS interfaces
├── utils/abis/       # contract ABIs (erc20, …)
├── workers/          # client-side search workers (blog, proposal)
└── proxy.ts          # Accept: text/markdown → rewrite to /md/* (Next.js 16 proxy convention, formerly middleware.ts)

Hook naming (drift to be aware of)

Most files use use-kebab-case.ts; 9 use useCamelCase.ts (useCastVote, useCreateCoin, useDelegate, useMintDroposal, usePoidhBounties, useVotes, etc.). Prefer kebab-case for new hooks; don't rename existing ones speculatively.

Key Config Files

  • src/lib/config.tssingle source of truth for DAO addresses, chain, Zora creator allowlist, subgraph URLs, treasury token allowlist. Do not duplicate addresses elsewhere.
  • components.json — shadcn/ui (New York, RSC on)
  • tsconfig.json — path alias @/* → src/*
  • next.config.ts, eslint.config.mjs, postcss.config.mjs, playwright.config.ts

Web3 Integration

  • Chain hardcoded to Base (8453).
  • Login — thirdweb useConnectModal (social, email OTP, MetaMask, Coinbase, Rainbow, WalletConnect).
  • Writes — every onchain write goes through thirdweb sendTransaction({ account, transaction }) dispatched via useWriteAccount(). Signer matches the user's view mode (EOA direct vs SA via userop).
  • Reads — wagmi useReadContract, useReadContracts, useBalance, useWaitForTransactionReceipt, usePublicClient. Works with no connectors.
  • Address — single source is useUserAddress(){ address, saAddress, adminAddress, isConnected, isInAppWallet, viewMode, canSwitchView }. Never call wagmi's useAccount() — it's disconnected from thirdweb state.
  • View-mode toggle — external-wallet users can switch SA (sponsored) vs EOA (native prompt) via WalletDrawer; persisted to localStorage. In-app wallets pinned to SA.
  • Governance pre-checks — write hooks that gate on voting power must pre-read getPastVotes / getVotes and bail with a toast before prompting signatures.
  • Full provider tree + decision matrix: docs/architecture/thirdweb-wallet-layer.md.

Data Fetching

  • Server Components for initial load (SEO, perf).
  • Client Components only for interactive features (bidding, voting, wizard forms).
  • Builder DAO subgraph (Goldsky) for historical data via @buildeross/hooks / @buildeross/sdk.
  • src/services/* is the canonical data-access layer — prefer it over inline fetches.

Styling

  • Tailwind CSS v4, shadcn/ui components (New York).
  • Mobile-first; all DAO features must work on mobile.
  • Dark mode via next-themes.

i18n (next-intl)

  • Locales: EN + PT-BR. Messages in messages/{en,pt-br}/*.json (one namespace per file); config in src/i18n/.
  • Never mix EN and PT in one string ("Proposals recentes" → "Propostas recentes"). New UI strings go through next-intl, both locales, same change.
  • PT-BR glossary: bid → lance, auction → leilão, treasury → tesouro (not "tesouraria"), governance → governança, proposal → proposta, claim → resgate, delegation → delegação ("delegate" as a person stays "delegate").
  • Tone guide: docs/i18n/tone-brief.md — update it in the same change as any glossary/tone decision.

Environment Variables

Full list in env.example. Summary:

# Site
NEXT_PUBLIC_SITE_URL
NEXT_PUBLIC_BASE_URL

# RPC / chain
ALCHEMY_API_KEY
NEXT_PUBLIC_ALCHEMY_API_KEY
NEXT_PUBLIC_BASE_RPC_URL
BASE_RPC
BASESCAN_API_KEY

# Web3 auth (required for login + writes)
NEXT_PUBLIC_THIRDWEB_CLIENT_ID
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID

# Subgraph / data
NEXT_PUBLIC_GOLDSKY_PROJECT_ID
NEXT_PUBLIC_ZORA_COINS_SUBGRAPH_URL

# External APIs
NEXT_PUBLIC_ZORA_API_KEY
COINGECKO_API_KEY
PINATA_JWT
NEYNAR_API_KEY
ZEROX_API_KEY        # 0x Swap API (server-only)

# Optional
USDC_BASE

Secrets never go in client code. NEXT_PUBLIC_* is public by definition.

Notable Dependencies

  • Web3: thirdweb, wagmi, viem, @buildeross/hooks, @buildeross/sdk, @0xsplits/splits-sdk
  • Creator coins: @zoralabs/coins-sdk
  • Social: @farcaster/miniapp-sdk
  • 3D / viz: three, @react-three/fiber, @react-three/drei, react-globe.gl, ogl, gsap, recharts
  • Maps: leaflet, react-leaflet, leaflet-draw, leaflet.markercluster
  • Forms: react-hook-form, zod
  • Data/UX: @tanstack/react-query, next-intl, sonner (toasts), framer-motion, minisearch, pg (rounds)
  • @rainbow-me/rainbowkit is in package.json but unused in src/ — slated for removal.

Important Notes

  • Single-DAO site (Gnars only), not a multi-DAO platform.
  • Deploy target: Vercel.
  • Do not run pnpm build unless explicitly asked.
  • Before PR: pnpm lint + pnpm format:check.

Definition of Done (rules from past mistakes)

  • Verify UI changes at runtime. Any UI change: run pnpm dev, exercise the changed flow (and its mobile layout) before declaring done or pushing. Reviewing a PR means running it, not just reading the diff. Past misses: missing cursor-pointer, broken media rendering, wrong links — all found by the user clicking around.
  • Address displays link to the internal profile /members/[address], never Basescan.
  • Never invent user-facing status copy ("coming soon", "beta", "unstable") from code state — confirm the feature's real status with the user first.
  • Format + lint before every commit, not after CI flags it: pnpm format on touched files, then pnpm lint. Pre-existing lint errors outside your diff: report, don't fix.
  • End every change with the one-line report: <projeto> · <sha curto> · <o que mudou> · deploy <success|building|failed>. A change is NOT done until its deploy is success (verify via GitHub deployments API, full sha).
  • Continuing an existing PR: git fetch origin pull/<N>/head:pr-<N> and commit on that branch — don't create a new one. Fresh worktrees need pnpm install first (or invoke binaries from the main repo's node_modules/.bin/).

Direct-to-Main Protocol (Vlad, 2026-08-24 — supersedes the old PR protocol)

Everything lands directly on main and in production. Do not open a PR and wait for review — the goal is visibility, not speed: work sitting in unreviewed PRs made it impossible to know what was live.

  • After EVERY change, report in ONE line: <projeto> · <sha curto> · <o que mudou> · deploy <success|building|failed>.
  • A change is not done until the deploy is success. A commit on main without a confirmed deploy is the old blindness, only faster.
  • Gates that still apply before pushing: tsc and the test suite green; PT-BR capture for any layout change; a failed read renders as a failure, never as zero.
  • Do NOT wait for approval on routine changes. Ask first ONLY for: changes touching power or money (governance, funds, permissions), hard-to-reverse actions, and anything touching credentials.
  • PRs are the exception, used only when explicitly requested. Worktrees still apply when the main repo has unrelated work in progress.