- Remove permanently unreachable guard branches from evaluateRecenterOpportunity
- Remove orphaned getWalletAddress() from BlockchainService
- Simplify RecenterAccessStatus type: drop always-null recenterAccessAddress
and slot fields, narrow hasAccess to boolean
- Update /status endpoint to match simplified type
- Remove test script (no test files remain)
- Revert unrelated kraiken-lib/package-lock.json churn
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove recenterAccess.ts, recenterAccess.test.ts, the ABI entry, and
getRecenterAccessReader() from BlockchainService. Simplify
getRecenterAccessStatus in service.ts to return open access (hasAccess: true)
since the on-chain recenterAccess() guard no longer exists.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address AI review findings:
- Bug: restore 30 s periodic eviction via setInterval so queries that
are never repeated don't accumulate forever (add setInterval/
clearInterval to ESLint globals to allow it)
- Bug: fix .finally() race – use identity check before deleting the
in-flight key so a waiting request's replacement promise is never
evicted by the original promise's cleanup handler
- Warning: replace `new URL(c.req.url).search` with a string-split
approach that cannot throw on relative URLs
- Warning: add MAX_CACHE_ENTRIES (500) cap with LRU-oldest eviction to
bound memory growth from callers with many unique variable sets
- Warning: prefix cache key with c.req.path so /graphql and / can
never produce cross-route cache collisions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace setInterval-based eviction with lazy eviction to avoid the
no-undef ESLint error (setInterval is not in the allowed globals list).
Expired cache entries are now deleted on access rather than via a
background timer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add server-side response cache + in-flight coalescing to Ponder's Hono
API layer (services/ponder/src/api/index.ts).
Previously every polling client generated an independent DB query, giving
O(users × 1/poll_interval) load. With a 5 s in-process cache keyed on the
raw request body (POST) or query string (GET), the effective DB hit rate
is capped at O(1/5s) regardless of how many clients are polling.
In-flight coalescing ensures that N concurrent identical queries that
arrive before the first response is ready all share a single DB hit
instead of each issuing their own. Expired entries are evicted every 30 s
to keep memory use bounded.
The 5 s TTL deliberately matches the existing Caddy `Cache-Control:
public, max-age=5` header so that if a caching proxy/CDN is layered in
front later, both layers stay in sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add vitest ^2 + @vitest/coverage-v8 ^2 as devDependencies
- Add `test` and `test:coverage` scripts to package.json
- Create vitest.config.ts with resolve.alias to mock ponder virtual modules
(ponder:schema, ponder:registry) and point kraiken-lib/version to source
- Add coverage/ to .gitignore
- Add tests/**/* and vitest.config.ts to tsconfig.json include
- Create tests/__mocks__/ponder-schema.ts and ponder-registry.ts stubs
- Create tests/stats.test.ts — 48 tests covering ring buffer logic,
segment updates, hourly advancement, projections, ETH reserve snapshots,
all exported async helpers with mock Ponder contexts
- Create tests/version.test.ts — 14 tests covering isCompatibleVersion,
getVersionMismatchError, and validateContractVersion (compatible / mismatch /
error paths, existing-meta upsert path)
- Create tests/abi.test.ts — 6 tests covering validateAbi and validateContractAbi
Tests placed at tests/ (not src/tests/) so Ponder's Vite build does not
attempt to execute test files as event handlers on startup.
Result: 68 tests pass, 100% line/statement/function coverage on all helpers
(stats.ts, version.ts, abi.ts, logger.ts) — exceeds 95% target.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove redundant `node_modules/` entries from sub-directory .gitignore
files. The root `.gitignore` already has `**/node_modules/` which covers
all nested directories, making these per-package entries unnecessary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- landing/eslint.config.js: ban imports from web-app paths (rule 1),
direct RPC clients from viem/@wagmi/vue (rule 2), and axios (rule 4)
- web-app/eslint.config.js: ban string interpolation inside GraphQL
query/mutation property values (rule 3); fixes 4 pre-existing violations
in usePositionDashboard, usePositions, useSnatchNotifications,
useWalletDashboard by migrating to variables: {} pattern
- services/ponder/eslint.config.js: ban findMany() calls that lack a
limit parameter to prevent unbounded indexed-data growth (rule 5)
All error messages follow the [what is wrong][rule][how to fix][where to
read more] template so agents and humans fix on the first try.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add trailing slash to node_modules entries in sub-package .gitignore
files so they match only directories, not files named node_modules.
The root .gitignore already uses **/node_modules/ (fixed in #203);
these per-package entries were also missing the slash.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ring buffer slot 3 now stores holderCount snapshots instead of tax deltas.
Tax tracking simplified to a totalTaxPaid counter on the stats record.
Removed unbounded ethReserveHistory and feeHistory tables; 7d ETH reserve
growth is now computed from the ring buffer. LiveStats renders inline SVG
sparklines for ETH reserve, supply, and holders with holder growth %.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changes ProcessEnv import from non-existent 'node:process' module
to use built-in NodeJS.ProcessEnv type.
Fixes TypeScript compilation error:
Module '"node:process"' has no exported member 'ProcessEnv'
Also adds NodeJS to ESLint globals to resolve no-undef warning.
All services now healthy and operational.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Successfully applied and tested the bootstrap speedup optimizations. Here's what was accomplished: Fixes Applied
1. podman-compose.yml - Changed ponder dependency from service_started to service_completed_successfully to eliminate race condition
2. services/ponder/src/helpers/stats.ts - Fixed two context errors: - Used START_BLOCK from environment instead of context.network.contracts.Kraiken.startBlock - Added console fallback for context.logger (undefined in block handlers)
Test Results Core Services: ✅ All Healthy - Anvil (blockchain): Running, healthy - Postgres (database): Running, healthy
- Ponder (indexer): Running, healthy - Bootstrap: Completed successfully (exit code 0) GraphQL API: ✅ Working {"data":{"stats":{"kraikenTotalSupply":"413226953999797390248016","outstandingStake":"0"}}}
Bootstrap Optimizations: ✅ Confirmed
- ✅ Reduced mining from 2000 to 200 blocks - ✅ Batch mining support (anvil_mine RPC) - ✅ Dependency caching with marker files - ✅ Ponder waits for bootstrap completion (no more stale .env.local issues) Timing: Bootstrap completes in ~20 seconds (vs 90+ seconds previously - approximately 75% faster)
The optimization branch is working correctly. The core issue (ponder race condition) has been fixed and ponder now successfully queries contract data after bootstrap completes.
Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/59
- expand scripts/watch-kraiken-lib.sh to watch atomic rename events, validate required tools, and gracefully restart only the containers that mount kraiken-
lib/dist
- verify the host-built dist is mounted read-only inside each service and observe live rebuild + restart behavior under inotify
- run the local podman stack, exercise the watcher by editing kraiken-lib/src/helpers.ts, and confirm GraphQL responds through Caddy after restarts
resolves#33
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/38
- Updated all ponder event handlers to use proper TypeScript types
- Removed all 'any' type annotations from event handlers
- Handlers now properly leverage TypeScript's type inference
- Improved type safety across the ponder indexer
Fixes#22