Making prediction markets accessible to everyone.
Tunamon is a consumer prediction app built on top of Polymarket. Every trade still settles against Polymarket's liquidity and infrastructure, but the experience feels like a clean web2 betting app: embedded wallets, card/Apple Pay deposits, plain-English questions, and one-tap trades. The name is a playful nod to Fortuna, the Roman goddess of luck (for-tuna → Tuna-mon), because our only job is to help normal people make smarter bets without ever thinking about "oracles", "CLOBs", or "outcome tokens."
Launch Date: January 7, 2025
Core Mission: Build the best Polymarket frontend that helps users make money—and make it obvious which bets are profitable.
- Node.js / Bun (18+ recommended)
- Package Manager: pnpm, npm, or bun
- Accounts: Polymarket API access, Privy app credentials
# 1. Backend
cd backend
cp .env.example .env # Fill in Polymarket + Privy config
bun install
bun run src/index.ts
# 2. MCP Server (optional - for AI agents)
cd mcp-server
bun install
bun dev
# 3. Frontend
cd frontend
cp .env.example .env # Set NEXT_PUBLIC_DASHBOARD_BACKEND_URL
bun install
bun run devEnvironment Variables:
- Frontend (
frontend/.env): Only vars prefixed withNEXT_PUBLIC_are exposed to the browser - Backend (
backend/.env): Polymarket keys, Privy secrets (NEVER prefix withNEXT_PUBLIC_)
This repository contains three interconnected applications powering the Tunamon experience:
The Tunamon prediction market app
- Technology: Next.js App Router (client-only), React, Chakra UI
- Purpose: Consumer-grade prediction market experience that helps users make money through:
- LLM-informed market analysis and probability calculations
- Event discovery optimized for profitability (not just volume)
- Simplified betting interface (Robinhood-style charts, one-click orders)
- Twitter-based onboarding with Privy embedded wallets
- Philosophy: "Just works, looks great, makes money" - appealing to normies who want to bet without learning crypto
- Key Features:
- 24-hour event feed sorted by moneymaking opportunity
- Event details with news, LLM analysis, and market commentary
- Portfolio overview (USDC balance, position value, P&L)
- Position management and activity history
- Responsive design from mobile to desktop
Polymarket integration layer + LLM analysis engine
- Technology: Bun.js, Fastify
- Purpose: Powers Tunamon's unique "money-making" features through:
- ✅ Polymarket API integration: Full CLOB order routing, position management, event data
- ✅ Privy delegated signing: Seamless UX with batched transactions and gas sponsorship
- ✅ Builder Program integration: Deploy Proxy wallets on behalf of users
- ~80% LLM Analysis Pipeline: Evaluates events/markets using news, odds comparison, and AI models
- ⏳ Security hardening (final 2 weeks before launch)
- ⏳ Scalability improvements (final 2 weeks before launch)
- Architecture:
- RESTful JSON endpoints for all Polymarket operations
- LLM-powered market analysis and probability adjustments
- Global rate limiting (100 req/min per IP)
- Future: Redis for distributed caching and multi-user support
Polymarket API documentation access without browser navigation
- Technology: Model Context Protocol (MCP), Bun.js
- Purpose: Provides fast, structured access to Polymarket's official developer documentation for AI agents and development tools
- Features:
- 27+ documented API endpoints (Gamma, Data, CLOB, RTDS)
- 10+ guide pages (Quickstart, Builders Program, CLOB concepts)
- Dual transport: stdio + HTTP with optional bearer token auth
- Keyword search, parameter lookup, and endpoint specification tools
- Use Case: Enables AI coding assistants to query Polymarket API docs without web scraping or manual navigation
Core Mission: Build the best Polymarket frontend that helps users make money—and make it obvious which bets are profitable.
How We're Different:
- LLM-Enhanced Insights: Display Polymarket-implied probability vs. Tunamon's probability (informed by LLMs, recent news, cross-platform odds)
- Profitability-First Discovery: Events sorted by moneymaking opportunity, not just volume or hype
- Normie-Friendly Language: No "outcome tokens," "conditional tokens," or "oracles"—just simple betting
- Seamless Onboarding: Twitter signup → Privy wallet → fund with credit card/ApplePay/GooglePay → bet in <2 minutes
- Premium UX: Robinhood-style charts, one-click market orders, no transaction signing prompts
Target User: Internet-native normies who want to make money betting on events but refuse to deal with crypto complexity. They've heard of Polymarket but bounced because it felt too technical. Tunamon is their entry point.
The Stigma Problem: "Connect your Twitter to this betting app" feels sketchy.
The Solution: Reframe prediction markets as skill-based reputation building:
-
Copy Principles:
- ✅ "Turn your takes into a track record"
- ✅ "Get paid for being right more often than you're wrong"
- ✅ "Prove your edge in politics/sports/macro – with receipts"
- ❌ Avoid casino language: No "spin", "gamble", "all in", slot machine animations
- ✅ Use: "Trade your beliefs", "Back your call", "Make a prediction"
-
Track Record Features:
- Display user win rate by category (Elections, Fed, Sports)
- Show "Edge vs. Crowd" stats
- Make share cards stat-rich and premium (not casino-y)
- X login = "connect your takes and your track record", NOT "log into gambling account"
-
Consistency is Critical:
- Every surface must emphasize: Prediction quality, P&L/edge/accuracy, Discipline/risk controls
- Layer in: Deposit limits, reminders, "This is high-risk. Don't bet what you can't lose."
- If framing breaks → it's obviously gambling again → stigma returns
Goal: Users share screenshots saying "I called it!" not "I'm a degen"
- Frontend: Next.js App Router (client-only), React, Chakra UI with access to Chakra UI Pro templates.
- Backend: Polymarket abstraction and data aggregator lives in
./backend; all server logic and Polymarket API calls happen there. This frontend only consumes those endpoints. - No server-side rendering or API routes in this app.
- Clean, minimalist styling that feels trustworthy and familiar to Polymarket users without cloning the site.
- Responsive layouts from desktop down to mobile; prioritize clarity of balances and positions.
- Use tooltips for explanatory copy and toasts for visible app events (errors/success/info).
- Read
AGENTS.mdbefore making changes, especially the Chakra UI resources and# Frontend Aestheticsguidance. - Next.js MCP server setup and tool usage: https://nextjs.org/docs/app/guides/mcp#development-tools
- Chakra UI MCP server setup and tool usage: https://chakra-ui.com/docs/get-started/ai/mcp-server
- Chakra UI V3 complete docs (large; reference sparingly):
.cursor/rules/chakra_ui_v3_docs.md
- Project goal: Dashboard showing account stats and open positions with Privy auth and Chakra UI layout.
- Tasks
- Investigate sidebar alignment on the home page layout.
- Add UI polish and responsive behavior for the sidebar and main content.
- Add tests covering
useUsdcBalanceandusePositionshooks.
- MCP Server tasks
- Build Polymarket MCP server that exposes documented endpoints and guides.
- Add HTTP transport + health tool for MCP server.
- Current task: MCP server ready; awaiting next request.
The "Money-Online, Time-Poor Normie"
- Profile: Saw prediction market odds on Twitter/Google/Polymarket and wants to bet NOW. Doesn't care about the underlying rails (Polymarket, Polygon, USDC, Privy)—just wants something that looks like Robinhood/Instagram and works in dollars.
- Motivation: Make money betting on events they understand. Care deeply about P&L screenshots and social clout ("I called it!").
- Desires: An app that "just works" like Robinhood or Cash App—simple, beautiful, trustworthy. Zero crypto nonsense.
- Pain Points:
- Doesn't want to learn about wallets, gas fees, seed phrases, CLOBs, or "outcome tokens"
- Overwhelmed by Polymarket's orderbook UI and trading jargon
- Unsure which events are actually profitable vs. just popular/trendy
- Bounces if signup takes >1 minute or requires MetaMask
- Will NOT connect external wallet for gambling (privacy, stigma, complexity)
- Goal: Log in with Twitter, fund with Apple Pay, place a bet in under 2 minutes, screenshot their prediction, tweet it for clout.
- Behavioral Insights:
- Social-First: If they signed in with Twitter, they're already in "post my wins" mode
- Bounce Rate Triggers: Any mention of "wallet connection," "seed phrases," "approve transaction," or technical onboarding
- Decision Drivers: Visual appeal + social proof. If it doesn't look premium, they won't trust it with money.
- Mobile-First: 80%+ will bet from their phones while scrolling Twitter/TikTok
- Guidance Seekers: Want to be SHOWN which bets are smart (via simple signals), not just given raw orderbook data
- Tunamon's Solution:
- Twitter-Only Signup (v1): One-click social login, Privy generates embedded wallet behind scenes. No external wallets supported initially.
- Embedded Wallets: Users never see addresses, private keys, seed phrases, or transaction signing prompts
- Fiat Onramps: Credit card, Apple Pay, Google Pay via MoonPay/Privy. Zero crypto knowledge required.
- Smart Discovery (phased approach, see LLM Integration section below)
- Simplified Language: "Questions" not "markets," "Answers" not "outcomes," "Cash" not "USDC balance"
- Premium Design: Robinhood-level polish, zero "crypto startup" aesthetic
- One-Tap Share: Tweet bet slips + P&L screenshots for social proof/growth
Privy Integration Strategy (Beta v1.0 - January 7 Launch)
-
Twitter-Only Signup (Beta):
- Landing page with "Sign In with Twitter" button (single option for beta)
- Privy creates embedded wallet automatically (user never sees it)
- Rich user data from Twitter populates Tunamon profile (avatar, handle, bio)
- One-click "Tweet Your Wins" feature leverages Twitter integration
- No external wallet connections for beta (fresh start for all users)
-
Future Iterations (Post-Beta):
- External wallet connection for existing Polymarket whales
- Email/phone signup options
- Position migration tools
-
Fiat Onramp:
- Privy + MoonPay integration for credit card, Apple Pay, Google Pay
- «Add Funds» button → Pay with card/Apple Pay → USDC arrives instantly
- Target: <90 seconds from signup to having tradable balance
-
Gas Abstraction & Delegated Signing:
- Privy's delegated signing: users authorize Tunamon to sign transactions on their behalf
- No transaction prompts for token approvals or bet placements
- All Polygon gas fees batched and sponsored (invisible to user)
- Ultra-strict guardrails at launch to prevent errors (see Order Placement Security below)
-
Order Placement Security (CRITICAL - Prevents Disaster):
[!CAUTION] Problem: User lag-clicks "Place Bet" 6 times → 6 orders placed → account blown up
Frontend Guardrails:
- Disable button on click: Once user clicks "Place Bet", button enters pending state and won't fire again until response/timeout
- Show explicit pending state: Spinner + "Placing..." text so user knows something is happening (prevents rage-clicking)
- Countdown timeout: If no response after 5s, show "Retry" option (don't leave user hanging)
Backend Guardrails (CRITICAL):
-
Idempotency Keys (
client_order_id):- Frontend generates unique ID for each click
- Backend checks: "Have I already processed this ID?"
- Yes → Return same result (no duplicate order)
- No → Place order
- Double-click with same ID = only 1 real order
-
Per-Market In-Flight Lock:
- For each user + market + side (e.g., User A, Fed Rates, Yes):
- Only allow ONE outstanding order placement at a time
- If another request comes while one is pending:
- Reject: "Previous order still processing"
- OR queue (more complex, post-v1)
- For each user + market + side (e.g., User A, Fed Rates, Yes):
-
Rate Limits & Exposure Checks:
- Hard limit: Max N orders per second per user (e.g., 1/sec)
- Hard cap: Total exposure across all positions (e.g., $5,000 max)
- Even if something goes catastrophically wrong, blast radius is bounded
-
Audit Logging (MANDATORY):
- Log EVERY order attempt: request payload, user,
client_order_id, timestamp, outcome - Full trail for debugging and compliance
- Log EVERY order attempt: request payload, user,
Worst-Case Scenario (With These Guardrails):
- User thinks click didn't work, tries again
- Backend sees same
client_order_id - Returns: "Order already placed" (shows existing order)
- ✅ No duplicate position
Without These Guardrails:
- User accidentally enters 10x the position
- Account wiped out
- Tunamon liable for losses
- 🔥 Disaster
-
Security without Friction:
- Biometric auth (Face ID/Touch ID) for returning users
- No wallet addresses, no seed phrases, no signing prompts
Important
Core Decision: We are NOT building for crypto-native users first. We're building for financially-online X users who want Robinhood/PrizePicks UX, not a dev tool.
Target Persona:
- Financially-online X user
- Degen-adjacent (comfortable with risk)
- NOT deeply crypto-technical
- Already sees Polymarket/Hyperliquid/Lighter screenshots
- Wants something that feels like Robinhood/PrizePicks, not a blockchain explorer
What This Means:
- They're comfortable with risk
- They live on Twitter/X
- They DO NOT want to touch MetaMask or think about networks/tokens/gas
1. No External Wallets for v1
- Privy embedded wallet ONLY
- Show balances in "dollars" (hide USDC/chain completely)
- "Add funds" NOT "Bridge USDC"
- "Account" NOT "Wallet"
- "Network" hidden completely (until advanced view post-v1)
2. Copy Avoids Crypto Terms
- NO: "Bridge", "Approve tokens", "Gas", "USDC", "Polygon", "CLOB", "Outcome tokens"
- YES: "Add money", "Place bet", "Prediction", "Question", "Answer", "Cash"
- Exception: "Nerd Section" in settings can show raw data (post-v1)
3. Trading UX
- Always show: Probability + Dollar Risk/Reward
- "You're risking $100 to win $147 (+$47 profit)"
- Charts, not orderbook walls (Robinhood-style giant chart)
- Market orders first, limit orders behind "Advanced" toggle
- No multi-step flows (1-tap to bet after amount input)
4. Social Layer
- X login = "connect your takes and build your track record"
- Share cards are stat-rich, premium design (NOT casino-y)
- Win rate by category
- Total P&L
- "Edge vs. Crowd"
- Encourage: "I called it!" culture
- Discourage: "I'm a degen gambler" culture
5. Mobile-First Design
- 80% of users will bet from phones while scrolling Twitter/TikTok
- Desktop is secondary
- Every flow must work perfectly on iPhone/Android
They'll Find You Anyway Because:
- You're the nicest interface on Polymarket
- You'll have deeper analytics and mobile-first UX
- Word spreads fast in crypto Twitter
Give Them an "Advanced" Tab Later (Post-v1):
- Show raw orderbook, fees, underlying CTF positions
- Export positions to external wallets
- Link external Polymarket accounts
- Display chain/gas metrics
But Don't Compromise v1 for Them:
- They can use regular Polymarket if they need advanced features NOW
- Tunamon's wedge is normie-first simplicity
How we translate Polymarket's jargon into human language:
| Polymarket Term | Our Term | Context |
|---|---|---|
| Market | Question or Event | "Will the Fed cut rates?" not "Fed rate market" |
| Outcome | Answer or Side | "Yes" / "No" are answers to the question |
| Shares | Tickets (optional) | "You own 100 Yes tickets" feels more tangible |
| Outcome Token | Hidden | Never expose this concept to users |
| Redeem | Collect Winnings | More celebratory and clear |
| Liquidity | Hidden/De-emphasized | Only show if user is advanced |
| Conditional Tokens (CTF) | Hidden | Backend implementation detail |
| USDC Balance | Cash (with USDC icon) | Familiar term, crypto logo for transparency |
Dashboard Backend (./backend):
- Backend service called "signer" - runs on
127.0.0.1:3003(configurable viaPORTenv var). - All Polymarket API calls, wallet interactions, and CLOB order routing happen server-side.
- Frontend is a pure consumer of HTTP JSON endpoints.
- Note: Currently a single-wallet custodial service. Privy integration will need multi-wallet support.
Actual API Endpoints (from dashboard-backend):
GET /status → "OK"
GET /data/balances/usdc → USDC.e balance (BigInt as string)
GET /data/balances/ctf/:tokenIds → CTF balances for comma-separated token IDs
GET /data/allowances → Current USDC.e & CTF approvals
POST /action/approve/usdc → Set max USDC.e allowance for Polymarket contracts
POST /action/approve/ctf/:tokenId → Set CTF approval for specific token
GET /data/openOrders → All open orders
POST /action/createAndPostOrder → Create & post single order
POST /action/createAndPostOrders → Create & post multiple orders
POST /action/cancelOrder → Cancel single order by ID
POST /action/cancelOrders → Cancel multiple orders by IDs
POST /action/cancelAllOrders → Cancel all open orders
GET /data/positions → All active positions
GET /data/closedPositions → All closed positions
GET /data/positions/:conditionIds → Active positions for specific condition IDs
GET /data/closedPositions/:conditionIds → Closed positions for specific condition IDs
GET /data/activity → Activity feed (buys, sells, redemptions)
GET /data/activity/:conditionIds → Activity for specific condition IDs
GET /data/trades → Paginated trades with cursor
GET /data/account → Complete account data (address, activities, allowances, USDC, orders, positions, trades)
GET /data/events/:maxTimeDays → Upcoming events within maxTimeDays (featured events merged & deduped)
GET /data/orderBook/:tokenId → Order book for specific token
POST /data/orderBooks → Batch order books (array of { token_id, side })
POST /action/redeemPositions → Redeem all redeemable positions (auto-detects standard vs neg-risk)
Missing Endpoints (need to be added to backend):
GET /api/portfolio/stats → Aggregate stats: portfolio value, total P/L (1D/1W/1M/ALL), biggest win, predictions count
(can be calculated from /data/account but should be a dedicated endpoint)
WS /ws/prices → Real-time price updates (currently polling required)
WS /ws/portfolio → Real-time portfolio value updates (currently polling required)
POST /api/auth/privy → Privy authentication integration (map Privy user → wallet address)
Authentication Strategy:
- Current backend is single-wallet custodial (uses
EOA_PRIVATE_KEY/EOA_ADDRESSfrom env). - For multi-user dashboard: Add Privy middleware to map
Privy User ID → Wallet Address. - Options:
- Privy Embedded Wallets: Each user gets a unique embedded wallet managed by Privy.
- Database Mapping: Store
privy_user_id → eoa_addressmapping, backend signs with corresponding private key. - Hybrid: Users can connect external wallets OR use Privy embedded wallets.
Real-Time Data Handling:
- Current: Polling required (e.g., poll
/data/balances/usdcevery 5s,/data/positionsevery 10s). - Future: Add WebSocket endpoints for live price feeds and portfolio updates.
- Optimistic UI: Show order immediately, poll
/data/openOrdersto confirm/rollback.
CRITICAL: All agents and developers MUST read and follow these guidelines before writing any code.
Core Principles:
- Safety First: Prioritize correctness and safety over cleverness. Readable code > clever code.
- Minimal Code: Use the least amount of code necessary to achieve each task. Delete unused code aggressively.
- Avoid Types Unless Necessary: TypeScript types are optional unless they add safety or clarity.
- Centralized Types: ALL custom types MUST be defined in
src/types.tsand imported where needed.
Example:
// ❌ BAD: Inline type definitions
const MyComponent = ({ data }: { data: { id: string; name: string } }) => { ... }
// ✅ GOOD: Centralized types
// In src/types.ts:
export type MarketData = { id: string; name: string };
// In component:
import type { MarketData } from '@/types';
const MyComponent = ({ data }: { data: MarketData }) => { ... }MANDATORY - Read these files before making any changes:
-
Airbnb React/JSX Style Guide
Path:.cursor/rules/airbnb_react_jsx_style_guide.md
What: Industry-standard React patterns, component structure, prop handling, naming conventions. -
Frontend Aesthetics
Path:AGENTS.md(section: "# Frontend Aesthetics")
What: Guidelines on avoiding "AI slop" aesthetics, typography, color, motion, backgrounds. -
Chakra UI V3 Docs (when using Chakra)
Path:.cursor/rules/chakra_ui_v3_docs.mdOR use Chakra UI MCP server
What: Component API, props, variants, theming. Always verify your Chakra code against these docs.
BEFORE committing any Chakra UI code:
- Check component props against
.cursor/rules/chakra_ui_v3_docs.mdOR Chakra UI MCP server - Verify prop names, values, and variants are correct for Chakra UI V3
- Test component renders without errors
Common Mistakes to Avoid:
- Using Chakra UI V2 prop names (e.g.,
colorSchemeinstead of V3 equivalent) - Assuming props from other UI libraries work the same way
- Not testing components before committing
MANDATORY: All external API calls MUST use Tanstack Query.
Pattern (reference: src/hooks/usePositions.ts):
import { useQuery } from "@tanstack/react-query";
const useMyData = () => {
const { user } = usePrivy(); // or other auth context
return useQuery({
queryKey: ["myData", user?.id], // Unique key with dependencies
enabled: Boolean(user?.id), // Only run when user exists
queryFn: async () => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_DASHBOARD_BACKEND_URL}/data/endpoint`,
);
return await response.json();
},
});
};Why Tanstack Query?
- Automatic caching, refetching, and cache invalidation
- Prevents race conditions and duplicate requests
- Built-in loading/error states
- Optimistic updates support
Mutations (for POST/PUT/DELETE):
import { useMutation, useQueryClient } from "@tanstack/react-query";
const useCreateOrder = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (orderData) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_DASHBOARD_BACKEND_URL}/action/createAndPostOrder`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(orderData),
},
);
return await response.json();
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["openOrders"] }); // Refresh orders
},
});
};File Organization:
src/
├── components/ # Reusable UI components
│ ├── EventCard.tsx
│ ├── PositionList.tsx
│ └── ...
├── hooks/ # Custom React hooks (Tanstack Query hooks go here)
│ ├── usePositions.ts
│ ├── useEvents.ts
│ └── ...
├── types.ts # ALL custom TypeScript types
├── app/ # Next.js App Router pages
│ ├── page.tsx
│ └── ...
└── ...
Component Best Practices:
- Keep components small (<150 lines). Extract logic into hooks or utils.
- One component per file.
- Use named exports for components (not default exports for consistency).
- Extract reusable logic into custom hooks.
API Calls:
const { data, error, isLoading } = useMyData();
if (isLoading) return <Skeleton />;
if (error) return <ErrorToast message={error.message} />;
return <DataDisplay data={data} />;User-Facing Errors:
- Use Chakra UI
useToast()for transient errors (network failures, validation errors) - Use dedicated error states/pages for critical failures (auth errors, 404s)
- Always provide actionable error messages ("Retry", "Contact Support", etc.)
Before Merging:
- Component renders without errors
- All Tanstack Query hooks have proper
queryKeyandenabledconditions - Types are defined in
src/types.ts(not inline) - Chakra UI components verified against V3 docs
- Code follows Airbnb React style guide
- No console errors or warnings in browser
Linting:
npm run lint- Lazy Load Images: Use Next.js
<Image>component withloading="lazy" - Code Splitting: Use dynamic imports for heavy components
- Memoization: Use
useMemo/useCallbackonly when necessary (profile first) - Tanstack Query: Leverage automatic caching, avoid manual state management for API data
- Use semantic HTML (
<button>,<nav>,<main>, etc.) - Ensure all interactive elements are keyboard-accessible
- Provide
aria-labelfor icon-only buttons - Maintain color contrast ratios (use Chakra's accessible color tokens)
Frontend variables (exposed to browser) MUST be prefixed with NEXT_PUBLIC_:
# frontend/.env
NEXT_PUBLIC_DASHBOARD_BACKEND_URL=http://127.0.0.1:3003Backend variables (server-only secrets) MUST NOT be prefixed with NEXT_PUBLIC_:
# backend/.env
POLYMARKET_API_KEY=your_key_here
PRIVY_APP_SECRET=your_secret_here
PRIVY_APP_ID=your_id_hereCritical: Never expose backend secrets to the browser by accidentally adding NEXT_PUBLIC_ prefix.
Never commit .env files. Use .env.example to document required variables.
Summary Checklist (for every PR/commit):
- Read Airbnb React guide & Frontend Aesthetics section
- All types in
src/types.ts - All API calls use Tanstack Query
- Chakra UI code verified against V3 docs
- Code is minimal, safe, and readable
- No console errors or warnings
- Linter passes (
npm run lint) - Read Airbnb React guide & Frontend Aesthetics section
- All types in
src/types.ts - All API calls use Tanstack Query
- Chakra UI code verified against V3 docs
- Code is minimal, safe, and readable
- No console errors or warnings
- Linter passes (
npm run lint)
Status: ~80% backend code exists (repurpose from ~/Desktop/polymarket/src/llm/), but phased rollout required
Caution
Why phased? If "Tunamon probability" is wrong or noisy, users will anchor on it and blame us. We need to build credibility BEFORE exposing AI-driven probabilities.
NO "Tunamon Probability" yet. Instead, show:
-
Market Movement Indicators:
- Polymarket implied probability vs. closing line shifts (24h / 7d)
- Volume trends, liquidity depth, spread width
- Last trade time ("Stale market" warning if >6 hours)
-
Cross-Platform Consensus (where legally available):
- Bookmaker odds from Kalshi, DraftKings for reference
- Show divergence: "Polymarket: 65% | Kalshi: 72% (+7pts)"
- Careful with ToS - display only, no arbitrage suggestions
-
Event Context:
- Static event description + resolution rules
- Category, end date, volume, open interest
UI: Event feed sorted by volume + recent activity, NOT profit score (yet)
Add news + commentary WITHOUT probability adjustments:
-
Recent News Cards (3-5 articles):
- Headline + source + timestamp
- Fetch via News API / Perplexity
- Deduplication (>80% title similarity)
-
LLM Event Summary (2-3 paragraphs):
- Plain-English context: "Here's what happened in the last 24h that might move this market"
- Key factors (bulleted list, max 5 items)
- NO probability prediction - just context
-
Confidence Indicator:
- High / Medium / Low based on data recency and source quality
UI: Event detail pages now have rich context, still no "Tunamon odds"
Only after building credibility. Expose "Tunamon-Adjusted Probability" IF:
-
Track Record Exists:
- "Our model has beaten the market X% of the time over last N events"
- Display calibration charts (predicted vs. actual outcomes)
-
Transparent Methodology:
- Explain what goes into the model (news sentiment, odds movement, historical patterns)
- Allow users to toggle it off and see only Polymarket odds
-
Conservative Defaults:
- Only show adjustment if confidence is "High" and edge is >5%
- Otherwise display: "Tunamon: Neutral (no clear edge detected)"
UI: Event feed can NOW be sorted by "Profit Score" (optional filter)
Phase 1 (Must-Have for Jan 7):
- Volume + liquidity indicators
- Cross-platform odds display (Kalshi API / scrape DraftKings)
- Market movement tracking (24h / 7d shifts)
Phase 2 (Nice-to-Have, Jan 14-21):
- News fetcher (
backend/src/services/news.ts) - LLM summary generator (adapt existing codebase)
- Caching layer (Redis or in-memory TTL for 30min)
Phase 3 (Post-Launch, Jan 28+):
- Probability adjustment model
- Track record database + calibration charts
- Profit score UI toggle
- A/B test: show vs. hide Tunamon odds to measure impact on user P&L
Timeline: 5 weeks until January 7 launch. Priorities reorganized for aggressive execution.
Philosophy: Ship the core "moneymaking" experience (Event List + Event Details) FIRST, then refine. We're building for normies who want a beautiful app that helps them profit—everything else is secondary.
- Privy React Developer Docs: Reference for Privy SDK features, wallet management, and authentication flows. Use this to understand what's possible with embedded wallets, social logins, and fiat onramps.
- Polymarket Developer Docs: Reference only for understanding available data from Polymarket services. ALL interactions with Polymarket API must go through Dashboard Backend - never call Polymarket APIs directly from the frontend.
Goal: Ship the core "moneymaking" experience that defines Tunamon. 90% done by tomorrow, refined iteratively.
A. Event List (Homepage)
The first thing users see: 24-hour events sorted by profit opportunity, not hype.
-
Backend:
- Endpoint:
GET /api/events/moneymakers?hours=24→ Returns events analyzed by LLM - For each event: fetch markets, run LLM analysis, calculate profitability score
- Return: Event metadata + Polymarket odds + Tunamon odds + profit score + key insight
- Cache aggressively (expensive LLM calls)
- Endpoint:
-
Frontend - Event List Component:
- Layout: Clean list/table view (not cards, optimized for dense info)
- Columns:
- Event title (clickable) + category icon
- Polymarket probability vs. Tunamon probability (side-by-side comparison)
- Profit score (color-coded: green = +EV, red = -EV, gray = neutral)
- 1-sentence LLM insight ("Market underpricing Yes by 15%")
- End date/time
- Sorting: Default to highest profit score first
- Filters: Category pills (Politics, Sports, Crypto, All)
- Mobile: Stack columns, prioritize profit score visibility
- Chakra UI Pro: Use Tables (enhanced table with sorting), Elements (category pills), Layouts (responsive table → cards on mobile)
B. Event Details Page (Robinhood-Style)
Where users actually place bets. Must be stunning, simple, and confidence-inspiring.
-
Backend:
- Endpoint:
GET /api/events/:id/details→ Event + markets + LLM analysis + news - Fetch recent news (3-5 articles max, deduplicated)
- LLM summary: 2-3 paragraphs explaining the event and key factors
- Cross-platform odds if available (Kalshi, DraftKings)
- Endpoint:
-
Frontend - Event Details Component:
- Hero Chart (Top 50% of screen):
- Giant, beautiful line chart (Recharts or Lightweight Charts)
- Two lines: "Yes" and "No" probabilities over time
- Time range selector: 1H / 1D / 1W / ALL
- Interactive hover: show exact price + time
- Chakra UI Pro: Use Charts section for inspiration
- Event Context (Below chart, left side):
- Event title + description
- Market question (e.g., "Will the Fed cut rates in December?")
- LLM Summary: Plain-English analysis (2-3 paragraphs)
- Recent News: 3 news cards with headline + source + timestamp (link out)
- Cross-platform odds: "DraftKings: 62% | Kalshi: 58% | Polymarket: 55%"
- Chakra UI Pro: Use Cards (news cards), Elements (odds comparison pills)
- Order Placement Box (Right side, sticky):
- Giant Outcome Buttons: "YES" and "NO" toggle (only one active at a time)
- Show current odds for selected outcome (e.g., "Yes @ 55¢")
- Input: "Amount to bet" in dollars (USDC)
- Live preview: "You'll receive ~182 shares. If Yes wins, you'll get $182 (+$82 profit)"
- Big green "Place Bet" button (market order default)
- Small "Advanced" link → reveals limit order option
- Chakra UI Pro: Use Forms (toggle buttons, input with preview), Cards (sticky panel)
- Mobile Layout:
- Chart stays full-width at top
- Order box becomes sticky bottom sheet (expand on tap)
- Event context scrolls between chart and order box
- Hero Chart (Top 50% of screen):
Goal: Keep existing portfolio features functional while we build core betting experience.
- Dashboard Overview: USDC Balance, Position Value, P&L, graph
- Positions List: Active/Closed tabs, sorting, increase/decrease actions
- Activity Feed: Transaction history with pagination
- Refinements (as time permits):
- Add "Biggest Win" gamification card
- Add user info from Twitter (handle, avatar, join date)
- Polish empty states
Goal: Get users from Twitter signup to first bet in <2 minutes.
-
Privy + Twitter Integration:
- "Sign In with Twitter" button on landing page
- Privy creates embedded wallet automatically
- Populate Tunamon profile with Twitter data (avatar, handle, bio)
- Biometric auth for returning users
-
Fiat Onramp:
- MoonPay integration via Privy
- "Add Funds" button → Credit card / Apple Pay / Google Pay
- Target: <90 seconds from click to tradable USDC
-
Onboarding Tour (3 slides, skippable):
- Slide 1: "Your account is ready" + show USDC balance
- Slide 2: "We help you find profitable bets" + show event list preview
- Slide 3: "Place a bet and tweet your wins" + CTA to event list
-
Error Handling:
- Auth failures → Retry with clear messaging
- Onramp failures → Show crypto deposit option
Goal: Apply the "wow" factor and ensure premium UX across all features.
-
Visual Polish:
- Ensure all components match Design Aesthetics (see section below)
- Micro-interactions for every interactive element (hover, press, load)
- Staggered animations for page loads
- Number tickers for balance/P&L changes
- Smooth transitions everywhere (cubic-bezier easing)
-
Content & Copy:
- Review all user-facing text for "normie" language (no jargon)
- Add helpful tooltips where needed
- Error messages: actionable and friendly
-
Performance:
- Image optimization (lazy loading)
- Code splitting for heavy components
- Redis caching for expensive LLM calls
-
Mobile Optimization:
- Test every flow on iPhone/Android
- Ensure touch targets are thumb-friendly (min 44px)
- Bottom sheet for order placement (sticky)
Goal: Security, scalability, and launch readiness.
-
Security Audit & Guardrails:
- Delegated Signing Limits (CRITICAL):
- Max stake per market (e.g., $500)
- Max daily net outflow per user (e.g., $2,000)
- Max pending exposure (sum of downside risk, e.g., $5,000)
- Kill-switch per user and globally
- Strict Signing Policy:
- Whitelist only: create order, cancel order, deposit, withdraw
- No raw transaction passthrough from client
- All pre-checks: user authenticated, limits not breached, payload matches frontend request
- Audit Logging:
- Every remote-signed action: who, what, when, before/after balances
- Full trail for compliance and debugging
- Failure Mode Testing:
- Insufficient balance → Clear error, no partial fills
- Order rejection → Rollback + user notification
- Signer down → "Trading temporarily paused" message (no silent failures)
- Rate limiting on all endpoints (especially LLM/news)
- Input sanitization (SQL injection, XSS, etc.)
- Delegated Signing Limits (CRITICAL):
-
Scalability:
- Redis for distributed caching (LLM responses, news, event data)
- Database for multi-user support (Privy user → wallet mapping)
- Load testing (simulate 1000+ concurrent users)
-
Jurisdictions & Compliance:
- Verify Polymarket geo-blocking (which countries are blocked?)
- MoonPay KYC + region restrictions (align with Polymarket's allowed countries)
- Display "View Odds Only" vs. "Bet Now" based on user region
- Responsible gambling copy: "This is high-risk. Only bet what you can afford to lose."
-
Launch Prep:
- Final QA across all devices (iPhone, Android, desktop)
- Bug bash with 10-20 real beta users
- Analytics setup (track: signups, deposits, bets placed, P&L, bounce rates)
- Customer support plan (Discord or email for v1)
- Marketing assets (landing page, Twitter announcement, demo video)
Launch Date: January 7, 2025 🚀
Important
5 weeks is tight. Ship a focused v1 that does ONE thing exceptionally well: help normies make their first Polymarket bet in under 2 minutes.
Core Betting Flow:
- Event feed (sorted by volume + recent activity)
- Event detail page (chart + simple order ticket, see Phase 0)
- Positions view + P&L (existing dashboard components)
- Onboarding (Twitter → Privy wallet → fund via MoonPay/USDC)
- Delegated signing + gas abstraction (with hard caps, see Phase 4)
Essential UX:
- Mobile-responsive (80% of users will be on phones)
- One-tap bet placement (market orders only for v1)
- Tweet bet slips ("I just bet $X on..." with auto-populated text + link)
Minimum Viable Guidance:
- Volume + liquidity indicators (Phase 1 LLM approach)
- Cross-platform odds (Kalshi at minimum)
- Basic event description + resolution rules
Don't treat these as mandatory for Jan 7 or you'll ship late / half-wired:
- LLM news summaries (Phase 2)
- "Tunamon Probability" with track record (Phase 3)
- Limit orders (market orders are fine for v1)
- Detailed portfolio stats (just show P&L for now)
- External wallet support (Privy embedded wallets only for v1)
- Email/phone signup (Twitter-only for v1)
- Hyper-detailed risk metrics (keep it simple: "You're risking $X to win $Y")
Post-Launch Priority: Iterate based on user feedback. Don't build features users don't ask for.
Guiding principles derived from Lighter.gg, Robinhood, Linear, and "Frontend Aesthetics" agent docs.
- Vibe: "Professional, Tech-Forward, Minimalist."
- Palette:
- Backgrounds: Deep blacks (
#000000,#0A0A0A) with semi-transparent overlays (bg-black/60) for depth. - Foreground: High-contrast off-white (
#EDEDED) for primary text. - Accents:
- Electric Green (
#00FF94) for success/positive P&L/buy actions. - Electric Red (
#FF3B5C) for risk/negative P&L/sell actions. - Electric Blue (
#00A8FF) for neutral/info states. - Avoid muddy or pastel colors.
- Electric Green (
- Backgrounds: Deep blacks (
- Typography:
- Monospace (Geist Mono, JetBrains Mono): ALL numbers, tickers, and data tables. Conveys precision.
- Sans-serif (Geist Sans, Inter alternative): Headings and body copy. Clean, geometric, modern.
- Font Weights: 400 (regular), 500 (medium for emphasis), 700 (bold for headings).
- Glassmorphism: Subtle backdrop blurs (
backdrop-blur-md) and semi-transparent backgrounds to create hierarchy. - Micro-interactions:
- Hover:
- Buttons: Glow effect + 1.05x scale + brightness increase.
- Cards: Subtle lift (shadow) + border color brighten.
- Links: Color shift to accent + underline fade-in.
- Active/Press: Scale down to 0.98x for tactile feedback.
- Loading: Skeleton loaders with pulsing dark gray (
animate-pulse).
- Hover:
- Data Visualization:
- Sparklines: Minimalist, single-color lines (green for up, red for down).
- Progress Bars: Slim (4px height), vibrant fills to show probabilities.
- Charts: Use Recharts or Lightweight Charts with custom dark theme.
- Timing:
- Fast interactions (hover, click):
150ms. - Medium (modals, drawers):
250ms. - Slow (page transitions):
400ms.
- Fast interactions (hover, click):
- Easing:
- Default:
cubic-bezier(0.4, 0, 0.2, 1)(ease-out). - Springy (buttons):
cubic-bezier(0.34, 1.56, 0.64, 1).
- Default:
- Stagger:
- List items: 50ms delay per item.
- Hero elements: 100ms between title → subtitle → CTA.
Primary References:
- Lighter.gg (leaderboard): Dark theme, monospace numbers, vibrant green accents.
- Robinhood (web app): Simplicity, mobile-first, delightful micro-animations.
- Linear (linear.app): Premium dark mode, keyboard shortcuts, buttery smooth transitions.
Secondary References:
- Arc Browser: Unexpected UI choices, bold colors, attention to detail.
- Stripe Dashboard: Clean data density, excellent hierarchy.
- Revolut: Modern fintech, great mobile UX, trust-building visuals.
- Rainbow Wallet: Crypto wallet with consumer-grade polish.
- Avoid:
- Generic Bootstrap/Material UI/Ant Design layouts.
- Cookie-cutter cards with default shadows/borders.
- Default browser fonts (Arial, Times New Roman, system-ui).
- Overused fonts (Inter, Roboto) unless paired with a distinctive monospace.
- Purple gradients on white backgrounds (crypto cliché).
- Predictable component patterns (centered login forms, generic dashboards).
- Embrace:
- Custom spacing (not just 8px multiples).
- Unexpected layouts (asymmetry, negative space).
- Contextual illustrations or 3D elements (sparingly).
- Personality in microcopy ("Let's go!" instead of "Submit").