Ponder 0.17 indexer (TypeScript, viem, Hono) for VeriJoule onchain events on Sepolia. Indexes mints, retirements, and settlement; exposes GraphQL for the web app.
These tokens are not legally recognized RECs and are not for compliance use. Facilities in this project are for demonstration only. Settlement runs on testnet and no real value is transacted. See Limitations & Scope.
Root: README.md · Web: apps/web/README.md · Contracts: contracts/README.md
- Syncs mint and retire events from the REC vault and settlement payment metadata
- Exposes GraphQL consumed by the web app (
RecLedgerPanel,MyRetirementsPanel) - Mint rows include
sourceHash(SHA-256 of the attested EIA row) for provenance
Proxy addresses: docs/deployed-contracts.md. Start block defaults in ponder.config.ts. Local setup and Render/Supabase recipes: docs/operations.md · AGENTS.md.
| Contract | Events | Purpose |
|---|---|---|
VeriJouleREC |
RECsMinted, RECsRetired |
Active ledger + user retirements (UI-critical) |
VeriJouleREC |
PlantApproved, PlantRevoked |
Plant allowlist |
VeriJouleSettlement |
RECsSettlementSent |
USDC payment audit trail |
VeriJouleSettlement |
ReferencePriceUpdated |
Price history |
VeriJouleSettlement |
FacilityWalletSet, FacilityWalletRemoved |
Payee wallets per plant |
Retirements are read from VeriJouleREC:RECsRetired. Settlement contract events supplement payment metadata; they are not required for the ledger UI.
Use GraphQL only (POST / or POST /graphql). SQL-over-HTTP is disabled.
Active ledger (RecLedgerPanel):
query ActiveVintages {
recVintageBalances(
where: { availableBalance_gt: "0" }
orderBy: "vintageId"
orderDirection: "asc"
limit: 500
) {
items { vintageId, availableBalance, totalMinted }
}
}Retirement queries: see [LedgerWindow.tsx](../web/components/LedgerWindow.tsx).
Vintage IDs use plant-month encoding (plantCode * 1_000_000 + YYYYMM). Decode with VintageId.sol or read plantCode / periodCode from recsMinteds.
| Path | Purpose |
|---|---|
GET /health |
Liveness |
GET /ready |
200 once historical backfill is complete; 503 while syncing |
GET /status |
Per-chain indexed block height |
- Node.js 22+ (Ponder 0.17 enforces this at startup). Local: use
nvm useinapps/indexer(.node-versionis22). Render: set envNODE_VERSION=22.
pnpm dev:indexer
# GraphQL: http://localhost:42069/graphqlAfter Solidity changes: forge build --root contracts then pnpm --filter @verijoule/indexer sync-abis.
Lint: ESLint 9 flat config (eslint.config.js).
- README.md — monorepo overview
- apps/web/README.md — map UI, ledger, retirement
- contracts/README.md — Receiver, REC, Settlement
- docs/operations.md — Render deploy, Supabase, env