Skip to content

Add anonymous activity counters for social proof — backend + frontend #175

@Tinna23

Description

@Tinna23

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 /stats returns correct counts
  • Counters increment on every successful /tx/:hash and /account/:address response
  • 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    frontendcreate high-quality web applications with the power of React components.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions