The Pearfect frontend is a Next.js 14 App Router application styled to match Pear Protocol's design system. It is fully deployed on Vercel and designed to work against a mock API during development, switching seamlessly to live backend endpoints for production.
Sessionless UX — Users never log in. The device fingerprint is generated client-side on first visit, sent to the backend, and the returned wallet state is persisted in React context and localStorage as a cache (never as source of truth — that lives in the DB).
Mock-first development — Every API call goes through a typed client in /lib/api.ts. A NEXT_PUBLIC_USE_MOCKS=true flag swaps all real calls for local fixtures. This lets frontend development run in parallel with backend development without blockers.
Pear design parity — All components use Pear Protocol's exact colour tokens, typography, and component styles. Design assets coordinated directly with the Pear team before build.
App
├── WalletProvider (Context)
│ ├── walletId, address
│ ├── credits
│ └── tradesExecuted
│
├── TradeProvider (Context)
│ ├── currentThesis
│ ├── currentBasket { long[], short[] }
│ ├── tradeHistory[]
│ └── lastExecution { fillPrice, pnl }
│
└── Pages / Components (consumers)
No external state library — React Context is sufficient given the app's scope. State is initialised from the API on mount and kept in sync after each trade action.
- Displays truncated wallet address + current credit balance
- Subscribes to
WalletContext - Shows skeleton loader while wallet is generating
- Replaces the current hardcoded mock address
- Controlled textarea with character limit
- Debounced — does not call API on every keystroke
- Disabled state while basket is loading
- Shows confidence % returned by backend as a badge
- Renders LONG / SHORT columns from API response
- Each asset row has a weight slider (range 0–1, step 0.05)
- Enforces constraint: weights per side must sum to 1.0
- Auto-normalises on slider change (adjusts other assets proportionally)
- "Execute Trade" CTA — disabled if credits = 0
- Full-screen overlay mimicking MetaMask / real wallet confirm UX
- Shows: pair, direction, simulated fill price, credit cost
- Two actions: "Confirm" (proceed) / "Cancel" (dismiss)
- Purely frontend — no API call until Confirm is clicked
- Shown in-page after successful execution (no full page reload)
- Displays: fill prices per asset, simulated P&L, credits deducted, credits remaining
- Auto-dismisses after 8 seconds or on next thesis input
- Collapsible panel on
/demo/trade - Fetched fresh on mount from
GET /api/trade/history/:walletId - Shows: pair, direction, thesis (truncated), P&L, timestamp
- Persistent in nav alongside
WalletBadge - Animates downward on credit deduction (CSS transition)
- Turns amber below 300 credits, red below 100
- Fires when
credits === 0(caught on API response or via context watch) - Prominent full-screen modal — not a toast
- Primary CTA: UTM-tagged "Go to Pear" button
- On click: fires
POST /api/analytics/conversionthen navigates
/ Landing page + "Start Demo" CTA
/demo/trade Core demo experience
/agent Guided Trade Builder (AI pair analysis) — already live
/learn Learn page — already live
/analytics M2 sign-up + conversion dashboard (admin)
| Event | When | Where |
|---|---|---|
signup |
Immediately after wallet generated | POST /api/analytics/signup |
conversion |
On "Go to Pear" click | POST /api/analytics/conversion |
| UTM link built | Same moment as conversion event | lib/utm.ts |
These are fire-and-forget — frontend does not block on their response.
# Required
NEXT_PUBLIC_API_BASE_URL=https://pearfect-api.railway.app
# Dev only
NEXT_PUBLIC_USE_MOCKS=true # Swap API calls for local fixtures
NEXT_PUBLIC_PEAR_URL=https://pear.garden- Platform: Vercel (auto-deploy on push to
main) - Branch strategy:
main= production,dev= staging preview - Preview URLs: Generated per PR — useful for backend integration testing
| Item | Status | With |
|---|---|---|
| Pear design tokens (colours, fonts) | Needs assets from Pear | Pear team |
| API base URL for staging | Pending backend deploy | Co-worker |
| Device fingerprint library choice | @fingerprintjs/fingerprintjs proposed |
Co-worker (affects fingerprint format) |
| Credit deduction amount per trade | Not yet specified | Pear / co-worker |