harb/services/ponder/AGENTS.md
johba bff29e75a1 chore: gardener housekeeping 2026-03-27
AGENTS.md watermarks refreshed to HEAD (79a93d4).

Grooming: closed 2 prediction/actioned issues.
- #1179: /stakestake fix verified working in post-fix user-test (2026-03-27)
- #1177: fresh red-team session 2026-03-27 with 7 real attacks (floor_held)
Remaining open: #1166, #1141 (prediction/backlog, planner watching),
#857, #856, #383 (vision).
No blocked issues, no open PRs, no stale PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 18:04:08 +00:00

3.6 KiB

Ponder Indexer - Agent Guide

Ponder-based indexer that records Kraiken protocol activity and exposes the GraphQL API consumed by the app and automation bot.

Responsibilities

  • Track Kraiken token transfers and staking events to maintain protocol stats, hourly ring buffers, and position state.
  • Serve a GraphQL endpoint at http://localhost:42069/graphql for downstream consumers.
  • Support BASE_SEPOLIA_LOCAL_FORK, BASE_SEPOLIA, and BASE environments through a single TypeScript codebase.
  • Tax Rate Handling: Import TAX_RATE_OPTIONS from kraiken-lib (synced with Stake.sol via scripts/sync-tax-rates.mjs). The schema stores both taxRateIndex (source of truth) and taxRate decimal (for display). Event handlers extract the index from contract events and look up the decimal value.

Key Files

  • ponder.config.ts - Network selection and contract bindings (update addresses after deployments).
  • ponder.schema.ts - Stats, hourly data, and position tables.
  • src/kraiken.ts / src/stake.ts - Event handlers; rely on Ponder v0.13 helpers for on-chain reads during sync.
  • .ponder/ - Local SQLite/state cache (safe to delete when schemas change).

Development Workflow

  • Primary path: nohup ./scripts/dev.sh start & boots Anvil, deploys contracts, and launches Ponder in watch mode.
  • Docker stack: docker-compose up -d starts all services including PostgreSQL; bootstrap creates .env.local automatically.
  • Focused debugging: within services/ponder/, run npm install then PONDER_NETWORK=BASE_SEPOLIA_LOCAL_FORK npm run dev once the stack is already online.
  • For production-style runs, use npm run build followed by PONDER_NETWORK=BASE npm run start and point DATABASE_URL to PostgreSQL if persistence is required.

Operational Guidelines

  • Confirm handler timestamps are monotonic; large gaps (>168 hours) reset the ring buffer by design.
  • Regenerate typings after schema edits by restarting Ponder; generated artifacts live in generated/.
  • If the stack script fails during boot, check .ponder/logs and RPC quota usage before rerunning.

Containerized Environment (Podman/Docker)

  • Environment Loading: .env.local must be explicitly sourced in the entrypoint script before npm run dev. Ponder's built-in env loader may not find it in containerized environments.
  • Virtual Module Errors: If you see Failed to load url ponder:registry/ponder:schema/ponder:api, check:
    1. DATABASE_URL is properly set and accessible
    2. kraiken-lib ABIs exist (onchain/out/Kraiken.sol/Kraiken.json)
    3. ./scripts/build-kraiken-lib.sh has been run so kraiken-lib/dist/index.js exists
    4. ponder-env.d.ts is writable by the container user (chmod 666 or pre-create it)
    5. Ponder version is 0.13.8+ (earlier versions had virtual module generation bugs)
  • PostgreSQL Connection: Requires DATABASE_URL env var; Ponder falls back to PGlite if not set. The entrypoint must export this before Ponder starts.
  • File Permissions: Container runs as node user; ensure ponder-env.d.ts is writable (created with 666 permissions on host).
  • API Endpoint Requirement: Ponder 0.13.8+ requires src/api/index.ts to exist, even if you only use GraphQL. Missing it causes "API endpoint file not found" errors.

Quality Checks

  • Avoid reintroducing legacy subgraph assumptions; rely solely on Ponder schema helpers.
  • Keep handler logic deterministic and idempotent; reorgs trigger replays.
  • Use the Ponder client helpers (context.client, context.contracts) instead of manual RPC calls where possible.