-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Description
Stellar Explain has no way to surface real usage numbers — transactions explained, accounts checked, total lookups. These numbers build trust and social proof on the landing page. This issue adds lightweight, fully anonymous counters to the backend and displays them on the landing page.
No personal data. No user tracking. No cookies. Just simple increment counters.
Part 1 — Backend
Option A — In-memory (start here)
Add atomic counters directly in the Axum app state. Resets on restart but good enough for early stage.
pub struct AppState {
// ... existing fields ...
pub stats: Arc<AppStats>,
}
pub struct AppStats {
pub transactions_explained: AtomicU64,
pub accounts_checked: AtomicU64,
}Increment transactions_explained in the GET /tx/:hash handler on success.
Increment accounts_checked in the GET /account/:address handler on success.
New endpoint: GET /stats
Response:
{
"transactions_explained": 1284,
"accounts_checked": 743,
"total_lookups": 2027
}total_lookups is just transactions_explained + accounts_checked computed at response time.
Key files (backend):
packages/core/src/main.rs(add AppStats to state)packages/core/src/routes/stats.rs(new route)packages/core/src/routes/mod.rs(register route)packages/core/src/routes/tx.rs(increment counter on success)packages/core/src/routes/account.rs(increment counter on success)
Part 2 — Frontend
Add fetchStats() to src/lib/api.ts
export interface StatsResponse {
transactions_explained: number;
accounts_checked: number;
total_lookups: number;
}
export async function fetchStats(): Promise<StatsResponse>Add proxy route: src/app/api/stats/route.ts
Create src/components/landing/StatsSection.tsx
A clean section on the landing page showing 3 live numbers:
| Stat | Label |
|---|---|
total_lookups |
Explanations generated |
transactions_explained |
Transactions decoded |
accounts_checked |
Accounts inspected |
- Numbers animate from 0 to their value on scroll into view (count-up effect)
- If the fetch fails, show placeholder dashes
—gracefully - Non-blocking: page renders immediately, numbers fill in when ready
- Style consistent with the dark landing page aesthetic
Wire between HowItWorksSection and WhatWeDecodeSection in src/app/page.tsx
Key files (frontend):
src/lib/api.ts(add fetchStats)src/types/index.ts(add StatsResponse)src/app/api/stats/route.ts(proxy route)src/components/landing/StatsSection.tsx(new component)src/app/page.tsx(wire in)
Acceptance Criteria
- Backend:
GET /statsreturns correct counts - Counters increment on every successful
/tx/:hashand/account/:addressresponse - Frontend: stats section renders on landing page
- Numbers animate in on scroll with count-up effect
- Fetch failure shows
—gracefully, no crash - Page does not wait for stats before rendering
- Zero personal data collected — no IPs, no addresses, no hashes stored
Complexity: High · 200 pts
Stage: S10 — Power Features