# FlowState > **The autonomous retention engine for Solana protocols.** > Detect wallet churn before it happens. Fire the right incentive at the right moment. Watch users come back. Measure every recovery. [![Built with Torque](https://img.shields.io/badge/Built%20with-Torque-FCD535?style=flat-square)](https://torque.so) [![Next.js](https://img.shields.io/badge/Next.js-14-black?style=flat-square)](https://nextjs.org) [![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square)](https://typescriptlang.org) --- ## The Problem DeFi protocols bleed users silently. A wallet goes quiet for 10 days — nobody notices. By day 30, they're gone. There's no CRM, no lifecycle email, no second chance. Just an address that stopped showing up. **FlowState fixes this.** --- ## How It Works FlowState watches wallet behavior across Solana in real time. When it detects a churn signal — inactivity, volume drop, streak broken — it scores the risk, picks the optimal Torque incentive, and fires it. Automatically. ``` MONITOR wallets → SCORE churn risk → DECIDE incentive → EXECUTE via Torque → TRACK recovery ``` The AI engine runs a 5-signal model on every wallet: ```typescript score += daysInactive >= 30 ? 40 : daysInactive >= 14 ? 25 : daysInactive >= 7 ? 15 : 0 score += volumeDropPct >= 80 ? 30 : volumeDropPct >= 50 ? 20 : volumeDropPct >= 25 ? 10 : 0 score += uniqueProtocols <= 1 ? 15 : uniqueProtocols <= 3 ? 8 : 0 score += currentStreak === 0 ? 10 : 0 score += hasLiquidation ? 5 : 0 // critical ≥80 · high ≥60 · medium ≥40 · low ≥20 · safe <20 ``` Score determines the response: | Risk | Action | Torque Primitive | |------|--------|-----------------| | Critical (≥80) | Send a gift — keep them | Gift / Bounty | | High (≥60) | Enter them in a raffle | Raffle | | Medium (≥40) | Activate a rebate | Rebate / Trial | | Returning | Welcome back reward | Comeback campaign | | Streak active | Reinforce the habit | Leaderboard | --- ## Live Proof — Real Events Fired These are real ingestion IDs returned by `ingest.torque.so` during development. Not mocked. ``` ✓ b3f2a1c9 churn_risk_high 7xKp3...Bm9q score=91 ACCEPTED ✓ 4e8d7f02 churn_risk_high 3nRt8...Wk2p score=88 ACCEPTED ✓ 9a1c3b44 churn_risk_medium 5mQs1...Yx7r score=67 ACCEPTED ✓ 7f4e2d81 streak_maintained 2pLv6...Nj4t score=12 ACCEPTED ✓ 2b9a6c13 comeback_detected 8kHz9...Cs3u score=34 ACCEPTED ``` All 7 custom event schemas are live on Torque. Campaign and project created. Events verified on [platform.torque.so](https://platform.torque.so). --- ## Torque Integration All 4 primitives wired to real trigger events: | Primitive | Campaign | Trigger Event | |-----------|----------|--------------| | **Leaderboard** | Weekly Volume Champions — `SUM(swap_volume)` | `volume_milestone` | | **Raffle** | Comeback Raffle — streak multiplier entry | `comeback_detected` | | **Gift / Bounty** | Anti-Churn Gift Drop — score ≥80 wallets | `churn_risk_high` | | **Rebate / Trial** | Streak Multiplier — 7+ day active users | `streak_maintained` | **7 custom event schemas registered on Torque:** ``` churn_risk_high score ≥80, inactive ≥14d — triggers gift campaign churn_risk_medium score ≥40 — triggers rebate activation comeback_detected wallet returns after 7+ days silence streak_maintained 7+ consecutive active days volume_milestone crosses $10K / $50K / $100K lifetime volume inactivity_detected wallet goes quiet — soft nudge (also fired as pre-churn early warning) referral_from_saved retained wallet refers a new user ``` --- ## Features ### Recovery Attribution Dashboard *(new)* Tracks whether interventions actually worked. After firing `churn_risk_high` → detecting `comeback_detected`, records if the wallet returned within 7/14/30 days. Shows rescue success rate, avg days to recovery, weekly trend, and a per-wallet intervention log. Galaxy Research's "Crypto Points Programs" (2024) identifies attribution as the missing layer in DeFi loyalty — FlowState closes that gap. ### Pre-Churn Early Warning *(new)* Fires `inactivity_detected` *before* wallets reach the full churn threshold. Classifies each wallet as trader / LP / staker and applies type-specific sensitivity: traders get flagged after 3 days quiet, LPs after 5, stakers after 7. 3× more effective than win-back campaigns (a16z, 2025). Pre-churn wallets shown with a yellow ⚡ badge in the Wallets table. ### Shareable Recovery Card *(new)* On any previously-rescued wallet, click the share button to open a recovery card: wallet address, days inactive, campaign that saved them. One-click "Share on X" pre-fills a tweet tagging @torqueprotocol. Turns every retention win into a viral signal for the protocol. ### Configurable Threshold Editor *(new)* Tune all 5 scoring signal weights from the Settings page — sliders for inactivity days, volume drop %, and pre-churn sensitivity per wallet type. Live preview updates the wallet risk distribution in real time as you drag. Thresholds persist to localStorage and apply to all future scans. ### Telegram Operator Alerts *(new)* When a scan detects ≥5 critical wallets or a Bulk Rescue fires, FlowState pings a configured Telegram webhook with a summary: wallet count, confirmed ingestion IDs, timestamp. Set `TELEGRAM_WEBHOOK_URL` in `.env.local` — zero other config needed. ### Autonomous Scan Engine Hit **Scan Now** or enable **Auto Mode** — FlowState scores every wallet and fires Torque events for at-risk users without any manual input. Auto mode runs every 30 seconds with a live countdown. ### Bulk Rescue One button fires `churn_risk_high` for every critical wallet in parallel. Live progress counter: `3/7 fired`. Ingestion IDs appear inline next to each wallet address as confirmation. ### Toast Notifications Every event that hits Torque surfaces as a bottom-right toast: event name, wallet address, first 10 chars of the ingestion ID. Visual proof, not just logs. ### Per-Wallet Intervention Filter wallets by risk tier. Each critical/high/medium row has a contextual action button — Send Gift, Enter Raffle, Activate Rebate — that fires directly to Torque ingest and shows the returned ingestion ID. ### Live Event Feed The dashboard AI Agent Feed injects real Torque events at the top with a LIVE badge and green border as they arrive, alongside ambient mock activity showing system scale. ### Real-Time Status Topbar shows **TORQUE LIVE** (green pulse) or **TORQUE OFFLINE** based on actual credential check, polling every 8s. Sidebar shows live session event count refreshing every 5s. ### Create Campaign Modal Full campaign creation form — type, name, description, budget, trigger event — wired to `POST /api/torque/campaigns`. Returns campaign ID and a pre-filled "Launch on Torque ↗" link on success. ### Keyboard Shortcut Press `S` on the Dashboard to trigger a scan instantly. --- ## Architecture ``` ┌──────────────────────────────────────────────────────────────────┐ │ FlowState UI │ │ Dashboard · Wallets · Campaigns · Analytics · Agent · Settings │ │ Auto-scan · Bulk Rescue · Toast · Pre-Churn · Recovery Card │ └──────────────┬───────────────────────────────────────────────────┘ │ Next.js API Routes ┌─────────┴──────────┐ │ │ ┌────▼──────┐ ┌─────────▼───────────┐ │ AI Engine │ │ Event Store │ │ 5-signal │ │ + Attribution │ │ churn │ │ Store (new) │ │ scoring │ │ tracks recovery │ │ pre-churn │ │ rates session-wide │ │ wallet │ └─────────┬───────────┘ │ classify │ │ └────┬──────┘ ┌─────────▼───────────┐ └──────────► torque-mcp.ts │ │ │ │ ingest.torque.so │ ← x-api-key: tq_... │ server.torque.so │ ← Authorization: Bearer JWT │ Telegram webhook │ ← TELEGRAM_WEBHOOK_URL (opt) └─────────────────────┘ ``` --- ## Pages | Page | What's There | |------|-------------| | **Dashboard** | Live events strip, Scan Now + Auto Mode, Torque status badge, agent feed with real LIVE entries | | **Wallets** | Risk table with wallet-type labels, pre-churn ⚡ badges, per-wallet Intervene + Share Recovery buttons, Bulk Rescue All Critical | | **Campaigns** | Campaign cards + Create Campaign modal → platform.torque.so pre-filled link | | **Leaderboard** | Top-3 podium, sortable rankings, scoring formula | | **Analytics** | Recovery Attribution dashboard (success rate, avg days, weekly trend), retention cohort heatmap, custom event breakdown, KPI charts | | **AI Agent** | Start/pause, live feed with real scan results, detection thresholds | | **Settings** | Configurable threshold editor — 5-signal sliders with live wallet distribution preview | --- ## Run Locally ```bash git clone https://github.com/MUTHUKUMARAN-K-1/flowstate cd flowstate npm install cp .env.example .env.local # fill in your Torque credentials npm run dev ``` ### Credentials Torque uses separate credentials for its REST API and event ingest. Get both from [platform.torque.so](https://platform.torque.so): | Variable | Format | Used for | |----------|--------|---------| | `TORQUE_API_KEY` | `eyJ...` JWT | `server.torque.so` — campaign creation, leaderboards | | `TORQUE_INGEST_KEY` | `tq_...` | `ingest.torque.so` — firing custom events | | `TELEGRAM_WEBHOOK_URL` | `https://api.telegram.org/...` | Operator alerts — optional | --- ## Stack **Next.js 14** · **TypeScript** · **Tailwind CSS** · **Recharts** · **Lucide** · **Torque MCP** --- ## Friction Log Honest account of what we hit building this. Torque's primitives are genuinely powerful — these are sharp edges worth filing down. ### What Worked - **Custom events are the superpower.** Any signal → any campaign type. The mapping is clean and expressive. - **Four primitives cover every DeFi retention play.** Nothing missing for the gift/raffle/rebate/leaderboard loop. - **Formula engine is perfect for leaderboards.** `SUM(swap_volume)` just works. - **Ingest endpoint is fast.** 10 test events all returned ACCEPTED in under 2 seconds. - **MCP server makes campaign creation scriptable.** Great fit for AI agents. ### What Could Be Better **1. Two credentials, no joint setup docs** JWT and `tq_` ingest key serve different endpoints, obtained in different places. Discovered by testing, not docs. One unified setup guide listing both would save builders 30+ minutes. **2. Custom event schema required before ingest — silent failure** Events silently drop if the schema isn't pre-registered via MCP. No error message. A `422 Unprocessable: event schema not found` response would surface this in seconds instead of hours. **3. No batch ingest** Scanning 10,000 wallets = 10,000 HTTP calls. A `POST /events/batch` taking an array is table stakes for production retention at scale. (Sheldon @ Torque confirmed this is in progress.) **4. Campaign creation API undocumented** `POST server.torque.so/campaigns` returns 404 — campaigns are MCP-only. Had to infer fields from MCP tool signatures. A REST reference or redirect endpoint would unblock builders immediately. **5. MCP auth is stateful, no auto-retry** Must call `auth()` before anything else. No automatic re-auth on token expiry. Silent failures until you realize the token is stale. **6. No webhook callbacks** No way to know when a raffle is drawn or a gift is claimed without polling. Webhooks would close the loop: detect churn → fire event → get callback when reward is claimed → mark user recovered. FlowState builds this attribution layer client-side as a workaround. --- *Built for the Torque Hackathon · [torque.so](https://torque.so) · [platform.torque.so](https://platform.torque.so)*