Contributing to LightChallenge
Thank you for your interest in contributing to LightChallenge.
Getting Started
Prerequisites
- Node.js 22+
- PostgreSQL (Neon or local)
- Git
Setup
git clone <repo-url>
cd lightchallenge
npm install
cd webapp && npm install && cd ..
cp .env.example webapp/.env.local
# Fill in webapp/.env.local with your configuration (see .env.example for reference)Development Commands
# Compile contracts
npx hardhat compile
# Run contract tests
npx hardhat test
# TypeScript type checking
npx tsc --noEmit # root (offchain/scripts)
cd webapp && npx tsc --noEmit # webapp
# Run database migrations
npx tsx db/migrate.ts
# Start webapp (development)
cd webapp && npm run dev
# Start off-chain workers (each in separate terminal)
npx tsx offchain/workers/evidenceCollector.ts
npx tsx offchain/workers/evidenceEvaluator.ts
npx tsx offchain/dispatchers/challengeDispatcher.ts
npx tsx offchain/workers/challengeWorker.ts
npx tsx offchain/indexers/aivmIndexer.ts
npx tsx offchain/indexers/claimsIndexer.ts
npx tsx offchain/indexers/statusIndexer.tsProject Structure
contracts/ Solidity smart contracts
offchain/ TypeScript off-chain services
webapp/ Next.js 14 full-stack app
app/api/ Server-side API routes
lib/ Shared utilities
db/ PostgreSQL migrations
scripts/ Deploy, admin, and ops scripts
test/ Hardhat contract tests
docs/ Additional documentationCode Guidelines
Smart Contracts
- Solidity 0.8.24, OpenZeppelin v5.4.0
- Use custom errors (not require strings)
- All funds flow through Treasury (ChallengePay holds zero)
- Add tests for every state change
TypeScript
- Strict mode enabled
- Use
pgPool for DB connections; importsslConfigfromoffchain/db/sslConfig - Use
offchain/db/pool.tsfor shared pool instance - Use expression-based
ON CONFLICTfor upserts (not named constraints)
API Routes
- Authenticate state-mutating endpoints via
webapp/lib/auth.ts - Sanitize error responses (never leak
e.message) - Cap unbounded parameters
Testing
- Contract tests: Hardhat + ethers v6 + chai
- Use
loadFixturefor test isolation - Test both success paths and revert conditions
Pull Request Process
- Create a feature branch from
main - Make your changes
- Ensure all checks pass:
npx hardhat compile(no errors)npx hardhat test(all passing)npx tsc --noEmit(root + webapp, no errors)
- Write clear commit messages
- Open a PR with:
- Summary of changes
- Test plan
- Any breaking changes noted
Architecture Rules
- Keep responsibilities separated by layer (contract / offchain worker / API / frontend)
- Do not place business logic in API routes if it belongs in offchain services
- Do not duplicate evaluation logic
- Prefer DB-backed state over file/JSON state
- Keep AIVM + PoI as the primary validation path
- Archive legacy code instead of maintaining parallel paths