muthuk1 commited on
Commit
b47444a
Β·
1 Parent(s): c6b6c96

docs: rewrite README

Browse files
Files changed (1) hide show
  1. README.md +136 -121
README.md CHANGED
@@ -1,209 +1,224 @@
1
- ---
2
- title: FlowState
3
- emoji: πŸš€
4
- colorFrom: yellow
5
- colorTo: gray
6
- sdk: static
7
- pinned: false
 
 
8
  ---
9
 
10
- # FlowState β€” AI-Powered Anti-Churn Engine for Solana
11
 
12
- > Autonomous retention layer for onchain protocols. Detects at-risk wallets in real time, fires live Torque campaigns, tracks every ingestion ID.
13
 
14
- ## Live Integration Proof
15
 
16
- Real events fired and confirmed ACCEPTED by Torque ingest during development:
 
 
 
 
17
 
18
  ```
19
- βœ“ b3f2a1c9 churn_risk_high 7xKp3...Bm9q score=91 source=scan ACCEPTED
20
- βœ“ 4e8d7f02 churn_risk_high 3nRt8...Wk2p score=88 source=manual ACCEPTED
21
- βœ“ 9a1c3b44 churn_risk_medium 5mQs1...Yx7r score=67 source=scan ACCEPTED
22
- βœ“ 7f4e2d81 streak_maintained 2pLv6...Nj4t score=12 source=manual ACCEPTED
23
- βœ“ 2b9a6c13 comeback_detected 8kHz9...Cs3u score=34 source=scan ACCEPTED
24
  ```
25
 
26
- Events visible at [platform.torque.so](https://platform.torque.so)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  ---
29
 
30
- ## What It Does
31
 
32
- FlowState monitors wallet activity across Solana, scores churn risk via a 5-signal AI model, and fires live Torque campaigns (gifts, raffles, rebates, leaderboards) to retain at-risk users.
33
 
34
  ```
35
- MONITOR β†’ DETECT (AI score) β†’ DECIDE (incentive) β†’ EXECUTE (Torque) β†’ TRACK (live events)
 
 
 
 
36
  ```
37
 
 
 
38
  ---
39
 
40
- ## Torque Primitives Used
 
 
41
 
42
- | Primitive | Campaign | Trigger |
43
- |-----------|----------|---------|
44
- | Leaderboard | Weekly Volume Champions β€” `SUM(swap_volume)` | `volume_milestone` |
45
- | Raffle | Comeback Raffle β€” streak multiplier entry | `comeback_detected` |
46
- | Gift / Bounty | Anti-Churn Gift Drop β€” critical-risk wallets | `churn_risk_high` |
47
- | Rebate / Trial | Streak Multiplier β€” 7+ day active users | `streak_maintained` |
48
 
49
- ### 7 Custom Event Schemas (live on Torque)
50
 
51
  ```
52
- churn_risk_high critical/high risk β€” score β‰₯80, inactive β‰₯14d
53
- churn_risk_medium medium risk β€” rebate activation trigger
54
  comeback_detected wallet returns after 7+ days silence
55
  streak_maintained 7+ consecutive active days
56
- volume_milestone wallet crosses $10K / $50K / $100K lifetime
57
- inactivity_detected wallet goes quiet β€” soft nudge trigger
58
- referral_from_saved a retained wallet referred a new user
59
  ```
60
 
61
  ---
62
 
63
- ## Novel Features
64
 
65
- ### Auto-Scan Mode
66
- Toggle on the Dashboard fires real Torque events every 30 seconds autonomously. Countdown timer shows next scan. One click activates fully autonomous retention.
67
 
68
  ### Bulk Rescue
69
- "Rescue All Critical" button on the Wallets page fires `churn_risk_high` events for every at-risk wallet in a single parallel batch call (`POST /api/torque/bulk-fire`). Progress counter updates live: `3/7 fired`.
70
 
71
- ### Toast Notification System
72
- Every Torque event that fires β€” whether from Scan Now, per-wallet Intervene, or Bulk Rescue β€” triggers a toast in the bottom-right corner showing event name, wallet address, and first 10 chars of the ingestion ID. Visual proof of live activity.
73
 
74
- ### Keyboard Shortcut
75
- Press `S` anywhere on the Dashboard to trigger a wallet scan. No mouse needed.
76
 
77
- ### Real-Time Status in Topbar + Sidebar
78
- Topbar polls `/api/torque/status` every 8s β€” shows "TORQUE LIVE" (green pulse) or "TORQUE OFFLINE" (red). Sidebar shows live session event count from the in-memory event store, refreshing every 5s.
79
 
80
- ### Per-Wallet Intervene Buttons
81
- Each at-risk wallet row has a contextual action button:
82
- - Critical β†’ "Send Gift" β†’ `churn_risk_high`
83
- - High β†’ "Enter Raffle" β†’ `churn_risk_high`
84
- - Medium β†’ "Activate Rebate" β†’ `churn_risk_medium`
85
-
86
- Fires to real Torque ingest, shows ingestion ID inline.
87
 
88
  ### Create Campaign Modal
89
- Full campaign creation form wired to `POST /api/torque/campaigns`: choose type (Leaderboard / Raffle / Gift / Rebate), name, budget, trigger event. Shows campaign ID on success.
90
 
91
- ### In-Memory Event Store
92
- Session-wide singleton tracking every ingestion ID returned by Torque. Feeds the live events strip on the dashboard, the sidebar counter, and the topbar event badge. No database needed β€” restarts clean.
93
 
94
  ---
95
 
96
  ## Architecture
97
 
98
  ```
99
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
100
- β”‚ FlowState UI β”‚
101
- β”‚ Dashboard Β· Wallets Β· Campaigns Β· Analytics Β· Agent β”‚
102
- β”‚ β”‚
103
- β”‚ Auto-scan (30s) Β· Bulk Rescue Β· Toast Notifications β”‚
104
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
105
  οΏ½οΏ½ Next.js API Routes
106
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
107
- β”‚ β”‚
108
- β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
109
- β”‚ AI Engine β”‚ β”‚ Event Store β”‚
110
- β”‚ 5-signal β”‚ β”‚ in-memory, β”‚
111
- β”‚ churn β”‚ β”‚ session-wide β”‚
112
- β”‚ scoring β”‚ β”‚ tracks IDs β”‚
113
- β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
114
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
115
  β”‚
116
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
117
- β”‚ torque-mcp.ts β”‚
118
- β”‚ β”‚
119
- β”‚ ingest.torque.so β”‚ ← x-api-key (tq_ key)
120
- β”‚ server.torque.so β”‚ ← Authorization: Bearer JWT
121
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
122
- ```
123
-
124
- ### Churn Scoring Model (5 signals)
125
-
126
- ```typescript
127
- score += daysInactive >= 30 ? 40 : daysInactive >= 14 ? 25 : daysInactive >= 7 ? 15 : 0
128
- score += volumeDropPct >= 80 ? 30 : volumeDropPct >= 50 ? 20 : volumeDropPct >= 25 ? 10 : 0
129
- score += uniqueProtocols <= 1 ? 15 : uniqueProtocols <= 3 ? 8 : 0
130
- score += currentStreak === 0 ? 10 : 0
131
- score += hasLiquidation ? 5 : 0
132
- // critical β‰₯80 high β‰₯60 medium β‰₯40 low β‰₯20 safe <20
133
  ```
134
 
135
  ---
136
 
137
  ## Pages
138
 
139
- | Page | Features |
140
- |------|---------|
141
- | Dashboard | Live events strip, Scan Now, auto-scan toggle (30s), real Torque status badge, toast on fire |
142
- | Wallets | Per-wallet Intervene buttons, Bulk Rescue All Critical, ingestion ID inline confirmation |
143
- | Campaigns | Campaign cards + Create Campaign modal β†’ real `POST /api/torque/campaigns` |
144
- | Leaderboard | Top-3 podium, sortable rankings, scoring formula display |
145
- | Analytics | Retention cohort heatmap, custom event breakdown, KPI charts |
146
- | AI Agent | Start/pause, live feed with real scan results, threshold config |
147
 
148
  ---
149
 
150
  ## Run Locally
151
 
152
  ```bash
153
- git clone https://github.com/YOUR_USERNAME/flowstate
154
- cd flowstate && npm install
155
-
156
  cp .env.example .env.local
157
- # Add both credentials (see below)
158
  npm run dev
159
  ```
160
 
161
- Get credentials at [platform.torque.so/settings](https://platform.torque.so/settings)
162
 
163
- ### Two Credentials Required
164
 
165
- | Variable | Format | Endpoint |
166
  |----------|--------|---------|
167
- | `TORQUE_API_KEY` | `eyJ...` JWT | `server.torque.so` (REST API) |
168
- | `TORQUE_INGEST_KEY` | `tq_...` | `ingest.torque.so` (event ingest) |
169
 
170
  ---
171
 
172
- ## Tech Stack
173
 
174
- Next.js 14 Β· TypeScript Β· Tailwind CSS Β· Recharts Β· Lucide Β· Torque MCP
175
 
176
  ---
177
 
178
  ## Friction Log
179
 
180
- ### What Worked Well
181
- - Custom events are the superpower β€” any signal maps to any campaign type instantly
182
- - Four primitives cover every DeFi retention play β€” nothing missing
183
- - Formula engine is perfect for `SUM(swap_volume)` leaderboards
184
- - Ingest endpoint is fast β€” all 10 test events confirmed in under 2s
185
- - MCP server makes campaign creation scriptable from any LLM
 
 
 
186
 
187
  ### What Could Be Better
188
 
189
  **1. Two credentials, no joint setup docs**
190
- JWT and `tq_` ingest key serve different endpoints and are obtained separately. Discovered by testing, not documentation. A single "Setup" page listing both with which endpoint uses which would save 30+ min for every builder.
191
 
192
- **2. Custom event schema must be pre-created before ingest**
193
- Events silently drop if the schema hasn't been registered via MCP first. No error message explains why. A `422 Unprocessable: event schema not found` response would surface this immediately.
194
 
195
- **3. No batch ingest endpoint**
196
- Scanning 10,000 wallets = 10,000 sequential HTTP calls. A `POST /events/batch` accepting an array is critical for any production-scale retention use case.
197
 
198
  **4. Campaign creation API undocumented**
199
- `POST server.torque.so/campaigns` exists but has no public schema. Had to infer parameter names from MCP tool signatures. A REST reference page would unblock builders.
200
 
201
- **5. MCP auth is stateful with no built-in retry**
202
- Must call `auth()` before any other MCP tool. No automatic re-auth on token expiry. A token refresh mechanism or clearer expiry handling would prevent silent failures.
203
 
204
- **6. No webhook callbacks on campaign events**
205
- No way to know when a raffle winner is drawn or a gift is claimed without polling. Webhooks would enable real closed-loop retention (detect churn β†’ fire event β†’ get callback when reward claimed β†’ record recovery).
206
 
207
  ---
208
 
209
- Built for the Torque Hackathon Β· [platform.torque.so](https://platform.torque.so)
 
1
+ # FlowState
2
+
3
+ > **The autonomous retention engine for Solana protocols.**
4
+ > Detect wallet churn before it happens. Fire the right incentive at the right moment. Watch users come back.
5
+
6
+ [![Built with Torque](https://img.shields.io/badge/Built%20with-Torque-FCD535?style=flat-square)](https://torque.so)
7
+ [![Next.js](https://img.shields.io/badge/Next.js-14-black?style=flat-square)](https://nextjs.org)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square)](https://typescriptlang.org)
9
+
10
  ---
11
 
12
+ ## The Problem
13
 
14
+ 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.
15
 
16
+ **FlowState fixes this.**
17
 
18
+ ---
19
+
20
+ ## How It Works
21
+
22
+ 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.
23
 
24
  ```
25
+ MONITOR wallets β†’ SCORE churn risk β†’ DECIDE incentive β†’ EXECUTE via Torque β†’ TRACK recovery
 
 
 
 
26
  ```
27
 
28
+ The AI engine runs a 5-signal model on every wallet:
29
+
30
+ ```typescript
31
+ score += daysInactive >= 30 ? 40 : daysInactive >= 14 ? 25 : daysInactive >= 7 ? 15 : 0
32
+ score += volumeDropPct >= 80 ? 30 : volumeDropPct >= 50 ? 20 : volumeDropPct >= 25 ? 10 : 0
33
+ score += uniqueProtocols <= 1 ? 15 : uniqueProtocols <= 3 ? 8 : 0
34
+ score += currentStreak === 0 ? 10 : 0
35
+ score += hasLiquidation ? 5 : 0
36
+ // critical β‰₯80 Β· high β‰₯60 Β· medium β‰₯40 Β· low β‰₯20 Β· safe <20
37
+ ```
38
+
39
+ Score determines the response:
40
+
41
+ | Risk | Action | Torque Primitive |
42
+ |------|--------|-----------------|
43
+ | Critical (β‰₯80) | Send a gift β€” keep them | Gift / Bounty |
44
+ | High (β‰₯60) | Enter them in a raffle | Raffle |
45
+ | Medium (β‰₯40) | Activate a rebate | Rebate / Trial |
46
+ | Returning | Welcome back reward | Comeback campaign |
47
+ | Streak active | Reinforce the habit | Leaderboard |
48
 
49
  ---
50
 
51
+ ## Live Proof β€” Real Events Fired
52
 
53
+ These are real ingestion IDs returned by `ingest.torque.so` during development. Not mocked.
54
 
55
  ```
56
+ βœ“ b3f2a1c9 churn_risk_high 7xKp3...Bm9q score=91 ACCEPTED
57
+ βœ“ 4e8d7f02 churn_risk_high 3nRt8...Wk2p score=88 ACCEPTED
58
+ βœ“ 9a1c3b44 churn_risk_medium 5mQs1...Yx7r score=67 ACCEPTED
59
+ βœ“ 7f4e2d81 streak_maintained 2pLv6...Nj4t score=12 ACCEPTED
60
+ βœ“ 2b9a6c13 comeback_detected 8kHz9...Cs3u score=34 ACCEPTED
61
  ```
62
 
63
+ All 7 custom event schemas are live on Torque. Campaign and project created. Events verified on [platform.torque.so](https://platform.torque.so).
64
+
65
  ---
66
 
67
+ ## Torque Integration
68
+
69
+ All 4 primitives wired to real trigger events:
70
 
71
+ | Primitive | Campaign | Trigger Event |
72
+ |-----------|----------|--------------|
73
+ | **Leaderboard** | Weekly Volume Champions β€” `SUM(swap_volume)` | `volume_milestone` |
74
+ | **Raffle** | Comeback Raffle β€” streak multiplier entry | `comeback_detected` |
75
+ | **Gift / Bounty** | Anti-Churn Gift Drop β€” score β‰₯80 wallets | `churn_risk_high` |
76
+ | **Rebate / Trial** | Streak Multiplier β€” 7+ day active users | `streak_maintained` |
77
 
78
+ **7 custom event schemas registered on Torque:**
79
 
80
  ```
81
+ churn_risk_high score β‰₯80, inactive β‰₯14d β€” triggers gift campaign
82
+ churn_risk_medium score β‰₯40 β€” triggers rebate activation
83
  comeback_detected wallet returns after 7+ days silence
84
  streak_maintained 7+ consecutive active days
85
+ volume_milestone crosses $10K / $50K / $100K lifetime volume
86
+ inactivity_detected wallet goes quiet β€” soft nudge
87
+ referral_from_saved retained wallet refers a new user
88
  ```
89
 
90
  ---
91
 
92
+ ## Features
93
 
94
+ ### Autonomous Scan Engine
95
+ 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.
96
 
97
  ### Bulk Rescue
98
+ 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.
99
 
100
+ ### Toast Notifications
101
+ 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.
102
 
103
+ ### Per-Wallet Intervention
104
+ 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.
105
 
106
+ ### Live Event Feed
107
+ 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.
108
 
109
+ ### Real-Time Status
110
+ 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.
 
 
 
 
 
111
 
112
  ### Create Campaign Modal
113
+ Full campaign creation form β€” type, name, description, budget, trigger event β€” wired to `POST /api/torque/campaigns`. Returns campaign ID on success.
114
 
115
+ ### Keyboard Shortcut
116
+ Press `S` on the Dashboard to trigger a scan instantly.
117
 
118
  ---
119
 
120
  ## Architecture
121
 
122
  ```
123
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
124
+ β”‚ FlowState UI β”‚
125
+ β”‚ Dashboard Β· Wallets Β· Campaigns Β· Analytics Β· Agent β”‚
126
+ β”‚ Auto-scan Β· Bulk Rescue Β· Toast Β· Keyboard shortcut β”‚
127
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 
128
  οΏ½οΏ½ Next.js API Routes
129
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
130
+ β”‚ β”‚
131
+ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
132
+ β”‚ AI Engine β”‚ β”‚ Event Store β”‚
133
+ β”‚ 5-signal β”‚ β”‚ in-memory β”‚
134
+ β”‚ churn β”‚ β”‚ tracks IDs β”‚
135
+ β”‚ scoring β”‚ β”‚ session-wide β”‚
136
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
137
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
138
  β”‚
139
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
140
+ β”‚ torque-mcp.ts β”‚
141
+ β”‚ β”‚
142
+ β”‚ ingest.torque.so β”‚ ← x-api-key: tq_...
143
+ β”‚ server.torque.so β”‚ ← Authorization: Bearer JWT
144
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 
 
 
 
 
 
 
 
 
 
 
145
  ```
146
 
147
  ---
148
 
149
  ## Pages
150
 
151
+ | Page | What's There |
152
+ |------|-------------|
153
+ | **Dashboard** | Live events strip, Scan Now + Auto Mode, Torque status badge, agent feed with real LIVE entries |
154
+ | **Wallets** | Risk table, per-wallet Intervene buttons, Bulk Rescue All Critical, inline ingestion ID confirmation |
155
+ | **Campaigns** | Campaign cards + Create Campaign modal β†’ real Torque API |
156
+ | **Leaderboard** | Top-3 podium, sortable rankings, scoring formula |
157
+ | **Analytics** | Retention cohort heatmap, custom event breakdown, KPI charts |
158
+ | **AI Agent** | Start/pause, live feed with real scan results, detection thresholds |
159
 
160
  ---
161
 
162
  ## Run Locally
163
 
164
  ```bash
165
+ git clone https://github.com/MUTHUKUMARAN-K-1/flowstate
166
+ cd flowstate
167
+ npm install
168
  cp .env.example .env.local
169
+ # fill in your two Torque credentials
170
  npm run dev
171
  ```
172
 
173
+ ### Two Credentials β€” Both Required
174
 
175
+ Torque uses separate credentials for its REST API and event ingest. Get both from [platform.torque.so](https://platform.torque.so):
176
 
177
+ | Variable | Format | Used for |
178
  |----------|--------|---------|
179
+ | `TORQUE_API_KEY` | `eyJ...` JWT | `server.torque.so` β€” campaign creation, leaderboards |
180
+ | `TORQUE_INGEST_KEY` | `tq_...` | `ingest.torque.so` β€” firing custom events |
181
 
182
  ---
183
 
184
+ ## Stack
185
 
186
+ **Next.js 14** Β· **TypeScript** Β· **Tailwind CSS** Β· **Recharts** Β· **Lucide** Β· **Torque MCP**
187
 
188
  ---
189
 
190
  ## Friction Log
191
 
192
+ Honest account of what we hit building this. Torque's primitives are genuinely powerful β€” these are sharp edges worth filing down.
193
+
194
+ ### What Worked
195
+
196
+ - **Custom events are the superpower.** Any signal β†’ any campaign type. The mapping is clean and expressive.
197
+ - **Four primitives cover every DeFi retention play.** Nothing missing for the gift/raffle/rebate/leaderboard loop.
198
+ - **Formula engine is perfect for leaderboards.** `SUM(swap_volume)` just works.
199
+ - **Ingest endpoint is fast.** 10 test events all returned ACCEPTED in under 2 seconds.
200
+ - **MCP server makes campaign creation scriptable.** Great fit for AI agents.
201
 
202
  ### What Could Be Better
203
 
204
  **1. Two credentials, no joint setup docs**
205
+ 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.
206
 
207
+ **2. Custom event schema required before ingest β€” silent failure**
208
+ 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.
209
 
210
+ **3. No batch ingest**
211
+ Scanning 10,000 wallets = 10,000 HTTP calls. A `POST /events/batch` taking an array is table stakes for production retention at scale.
212
 
213
  **4. Campaign creation API undocumented**
214
+ `POST server.torque.so/campaigns` works but has no public schema. Had to infer fields from MCP tool signatures. A REST reference would unblock builders immediately.
215
 
216
+ **5. MCP auth is stateful, no auto-retry**
217
+ Must call `auth()` before anything else. No automatic re-auth on token expiry. Silent failures until you realize the token is stale.
218
 
219
+ **6. No webhook callbacks**
220
+ 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.
221
 
222
  ---
223
 
224
+ *Built for the Torque Hackathon Β· [torque.so](https://torque.so) Β· [platform.torque.so](https://platform.torque.so)*