How It Works
LightChallenge follows a four-stage lifecycle: Create → Prove → Verify → Settle.
1. Create a Challenge
A user creates a challenge by calling createChallenge() on the ChallengePay smart contract, specifying:
- Goal — What they’re committing to (e.g., “10,000 steps per day for 7 days”)
- Stake — LCAI tokens locked in the contract
- Deadline — When the challenge expires
- Template — Which verification model to use (fitness-steps, gaming-dota2, etc.)
The stake is held in escrow by the smart contract until the challenge is finalized.
2. Submit Evidence
When the user has completed their goal, they submit evidence through the webapp:
- Fitness challenges — Connect Apple Health, Strava, Garmin, or Fitbit. The iOS collector app reads HealthKit data and submits it.
- Gaming challenges — Link Steam, Riot, or FACEIT accounts. The system pulls match data from gaming APIs.
- Custom challenges — Upload evidence manually.
Evidence is stored in the database with a cryptographic hash for integrity.
3. AI Verification
The evidence goes through a per-participant verification pipeline. Each participant with a passing local evaluation gets their own LightChain run — there’s no single shared verdict for a challenge:
- Evidence Evaluator — An off-chain worker evaluates the evidence against the challenge rules and produces a verdict (pass/fail with reasons + score)
- Challenge Dispatcher — Queues one job per
(challenge_id, participant)pair where the participant has a passing local verdict - Challenge Worker — Picks up each job and runs
runChallengePayLightchainJob(challengeId, subject):- Submits the prompt to a LightChain v2 worker (gateway-mediated, encrypted)
- LightChain worker runs the LLM, emits
JobCompletedon chain - Our runner records the verdict via
ChallengePayLightchainAttestor.attest(...) - Our runner calls
ChallengePay.submitProofFor(challengeId, subject, proof), which marks the participant as a winner on chain
Single-pass: 3 on-chain transactions per participant, no event-watching indexer needed.
4. Settlement
After the proof deadline passes, anyone can call ChallengePay.finalize(id). The contract snapshots winners:
- Winners get their stake back plus a pro-rata bonus from the loser pool.
- Losers get cashback (if configured) — otherwise they get nothing.
- No-winners case — the entire distributable pool goes to the protocol multi-sig as a Treasury bucket grant. This is the intentional admin recovery path; the multi-sig can redirect funds if a bug needs to be remediated.
Payouts are auto-distributed by autoDistributeWorker — users don’t have to manually claim. Allowances are pull-based via Treasury, so funds remain claimable indefinitely.
Architecture Diagram
User → Webapp → Evidence DB → Evaluator → Verdicts (per participant)
↓
Dispatcher → aivm_jobs
↓
│ (one per participant)
↓
Challenge Worker
↓
│ runChallengePayLightchainJob(id, subject)
↓
┌─ LightChain v2 worker (LLM) ──┐
│ ↓ encrypted relay → verdict │
└───────────────────────────────┘
↓
attest() + submitProofFor()
↓
ChallengePay.finalize() (after deadline)
↓
autoDistributeWorker → walletsChallenge Types
Binary Challenges
Simple pass/fail outcomes. Example: “Walk 10,000 steps today.”
Competitive Challenges (via EventChallengeRouter)
Multiple participants compete. The router manages multi-outcome resolution, ranking participants by their verified results.
Event Challenges
Tied to real-world events (matches, races). The EventChallengeRouter resolves outcomes based on external event results.