Cross-site comment layer: Privy auth, Postgres (via Prisma) for domains / threads / pools, optional Redis for hot counters, Next.js UI plus a minimal /embed/... route for iframe-style widgets.
Extension: minimalist landing at /download (Chrome / Firefox / Brave tiles). Until store URLs are set, tiles link to the GitHub extension repo. Override with NEXT_PUBLIC_EXTENSION_CHROME_WEBSTORE_URL, NEXT_PUBLIC_EXTENSION_FIREFOX_AMO_URL, and NEXT_PUBLIC_EXTENSION_BRAVE_WEBSTORE_URL in .env.local. Official browser marks live in public/download/ (chrome.svg from Google, firefox.svg from Wikimedia Commons, brave.svg from Brave — replace with your own mock assets if you prefer).
You do not need a subdomain. commentprotocol.com/download is enough for the landing page, privacy policy links, and store “website” fields.
Optional: download.commentprotocol.com (or extensions.…) if you want a short marketing URL — add a DNS CNAME to Vercel, attach the domain in the Vercel project, then either serve the same app or add a redirect to /download. No extra backend.
| Item | What you need |
|---|---|
| Chrome | A Chrome Web Store developer account (Google charges a one-time registration fee; check current pricing in their console). You upload a .zip of the extension/ folder (built ui/ included). |
| Firefox | A free Firefox Add-ons (AMO) developer account. Submit the extension (Firefox build uses manifest.firefox.json / web-ext per the extension repo README). Review may require source or notes if the bundle is large/minified. |
| Brave | Brave is Chromium-based: users usually install the same package from the Chrome Web Store. You do not need a separate paid “Brave store” for a typical MV3 extension. |
You already have (or should add on the main site, not new SaaS):
- Privacy policy URL (stores require it) —
https://commentprotocol.com/privacy(published policy; still have counsel review for your entity and jurisdictions). - Support contact or page — stores ask for maintainer/support info.
- Privy — allow
chrome-extension://…and OAuth redirect hosts for the packaged extension id (already documented in the extension repo).
No extra paid API is required beyond what the web app already uses (Privy + your deployed commentprotocol.com APIs), unless you add analytics or error reporting later.
Deployment: after pushing main, confirm Vercel (or your host) shows a successful production deploy so /download is not 404.
- Node 20+
- Docker (optional, for local Postgres + Redis)
-
Copy environment variables:
cp .env.example .env.local
-
Fill in Privy credentials:
NEXT_PUBLIC_PRIVY_APP_IDPRIVY_APP_SECRET- Optional:
PRIVY_JWT_VERIFICATION_KEY(avoids a network fetch when verifying tokens)
-
Start databases:
docker compose up -d
-
Push schema and seed demo domains:
npm install npm run db:push npm run db:seed
-
Dev server:
npm run dev
Open http://localhost:3000. Pick a domain, then discuss at /thread/<hostname> (e.g. /thread/commentprotocol.com). Embed-friendly view: /embed/<hostname>.
Locations: /locations — search an address or paste lat, lng. With NEXT_PUBLIC_GOOGLE_MAPS_API_KEY set (Maps JavaScript API + Geocoding API enabled in Google Cloud), the map uses Google Maps and Google Geocoding (Nominatim remains a fallback). Without that key, the app uses OpenStreetMap tiles + Nominatim. HN-style thread per pinned coordinate (same votes/karma as domain threads).
Stars: /stars — SIMBAD TAP search + NASA SkyView DSS2 preview + per-object comments (/api/stars/search, /api/stars/comments).
| Method | Path | Notes |
|---|---|---|
GET |
/api/domains |
List domains + pool stats |
GET |
/api/domains/:hostname/comments |
Thread tree + pool |
POST |
/api/domains/:hostname/comments |
Authorization: Bearer <Privy access token>, body { body, parentId? } |
GET |
/api/geocode?q= |
Address / coordinate search (Google Geocoding if key set, else Nominatim) |
GET / POST |
/api/places/comments |
GET ?lat=&lng=&label= thread; POST JSON { lat, lng, body, parentId?, label? } + Bearer |
GET |
/api/stars/search?q= |
SIMBAD TAP name search + SkyView JPEG URL hints |
GET / POST |
/api/stars/comments |
GET ?oid=<SIMBAD oid>; POST JSON { oid, body, parentId? } + Bearer |
Set Environment Variables in the project dashboard: DATABASE_URL, Privy keys, optional REDIS_URL, NEXT_PUBLIC_GOOGLE_MAPS_API_KEY (restrict key by HTTP referrer to your Vercel domains), SIMBAD_USER_AGENT, NOMINATIM_USER_AGENT. After first deploy, run npx prisma db push against your production database (or use a migration workflow) so StarObject and related columns exist.
Posting increments RewardPool.commentCount and bumps an optional Redis key domain:<id>:comments.
dailyDistributionBps: basis points (100 = 1% per day).prizePoolCents: integer USD cents for display and future payout logic.
npm run db:generate— Prisma Clientnpm run db:push— apply schema (dev)npm run db:seed— seed domain list + sample pool numbersnpm run db:studio— Prisma Studio
Next.js (App Router) · TypeScript · Tailwind v4 · Prisma · PostgreSQL · Redis (optional) · Privy (@privy-io/react-auth + @privy-io/node)