flowstate / README.md
muthuk1's picture
feat: recovery attribution, pre-churn warnings, recovery card, threshold editor, telegram alerts
f667d47

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 Next.js TypeScript


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:

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.


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

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:

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 Β· platform.torque.so