Files
explorer-monorepo/backend/api/rest
Devin 945e637d1d refactor(ai): split the 1180-line ai.go into focused files
Decomposes backend/api/rest/ai.go (which the review flagged at 1180 lines
and which was the largest file in the repo by a wide margin) into six
purpose-built files inside the same package, so no import paths change
for any caller and *Server receivers keep working:

  ai.go           198  handlers + feature flags + exported AI* DTOs
  ai_context.go   381  buildAIContext + indexed-DB queries
                       (stats / tx / address / block) + regex patterns +
                       extractBlockReference
  ai_routes.go    139  queryAIRoutes + filterAIRouteMatches +
                       routeMatchesQuery + normalizeHexString
  ai_docs.go      136  loadAIDocSnippets + findAIWorkspaceRoot +
                       scanDocForTerms + buildDocSearchTerms
  ai_xai.go       267  xAI / OpenAI request/response types +
                       normalizeAIMessages + latestUserMessage +
                       callXAIChatCompletions + parseXAIError +
                       extractOutputText
  ai_helpers.go   112  pure-function utilities (firstRegexMatch,
                       compactStringMap, compactAnyMap, stringValue,
                       stringSliceValue, uniqueStrings, clipString,
                       fileExists)

ai_runtime.go (rate limiter + metrics + audit log) is unchanged.

This is a pure move: no logic changes, no new public API, no changes to
HTTP routes. Each file carries only the imports it actually uses so
goimports is clean on every file individually. Every exported symbol
retained its original spelling so callers (routes.go, server.go, and
the AI e2e tests) keep compiling without edits.

Verification:
  go build  ./...  clean
  go vet    ./...  clean
  go test   ./api/rest/...  PASS
  staticcheck ./...  clean on the SA* correctness family

Advances completion criterion 6 (backend maintainability): 'no single
Go file exceeds a few hundred lines; AI/LLM plumbing is separated from
HTTP handlers; context-building is separated from upstream calls.'
2026-04-18 19:13:38 +00:00
..

REST API Server

REST API implementation for the ChainID 138 Explorer Platform.

Structure

  • server.go - Main server setup and route configuration
  • routes.go - Route handlers and URL parsing
  • auth.go - Wallet auth, user-session auth, RPC product access, subscriptions, and API keys
  • blocks.go - Block-related endpoints
  • transactions.go - Transaction-related endpoints
  • addresses.go - Address-related endpoints
  • search.go - Unified search endpoint
  • mission_control.go - Mission-control bridge trace and cached liquidity helpers
  • validation.go - Input validation utilities
  • middleware.go - HTTP middleware (logging, compression)
  • errors.go - Error response utilities

API Endpoints

Auth

  • POST /api/v1/auth/nonce - Create a wallet-signature nonce
  • POST /api/v1/auth/wallet - Authenticate a wallet and receive a track JWT
  • POST /api/v1/auth/register - Create an access-console user session
  • POST /api/v1/auth/login - Log in to the access console

Blocks

  • GET /api/v1/blocks - List blocks (paginated)
  • GET /api/v1/blocks/{chain_id}/{number} - Get block by number
  • GET /api/v1/blocks/{chain_id}/hash/{hash} - Get block by hash

Transactions

  • GET /api/v1/transactions - List transactions (paginated, filterable)
  • GET /api/v1/transactions/{chain_id}/{hash} - Get transaction by hash

Addresses

  • GET /api/v1/addresses/{chain_id}/{address} - Get address information
  • GET /api/v1/search?q={query} - Unified search (auto-detects type: block number, address, or transaction hash)

Health

  • GET /health - Health check endpoint

Mission control

  • GET /api/v1/mission-control/stream - SSE stream for bridge/RPC health
  • GET /api/v1/mission-control/bridge/trace?tx=0x... - Blockscout-backed tx trace with Chain 138 contract labels
  • GET /api/v1/mission-control/liquidity/token/{address}/pools - 30-second cached proxy to token-aggregation pools

Access and API keys

  • GET /api/v1/access/me - Current signed-in access user and subscriptions
  • GET /api/v1/access/products - RPC product catalog for Core, Alltra, and Thirdweb lanes
  • GET /api/v1/access/subscriptions - List product subscriptions
  • POST /api/v1/access/subscriptions - Request or activate a product subscription
  • GET /api/v1/access/admin/subscriptions - List pending or filtered subscriptions for admin review
  • POST /api/v1/access/admin/subscriptions - Approve, suspend, or revoke a subscription as an admin
  • GET /api/v1/access/api-keys - List issued API keys
  • POST /api/v1/access/api-keys - Create an API key for a tier, product, scopes, expiry, and optional quota override
  • POST /api/v1/access/api-keys/{id} - Revoke an API key
  • DELETE /api/v1/access/api-keys/{id} - Alternate revoke verb
  • GET /api/v1/access/usage - Per-product usage summary
  • GET /api/v1/access/audit - Recent validated API-key usage rows for the signed-in user
  • GET /api/v1/access/admin/audit - Admin view of recent validated API-key usage rows, optionally filtered by product
  • POST /api/v1/access/internal/validate-key - Internal edge validation hook for API-key enforcement and usage logging
  • GET /api/v1/access/internal/validate-key - auth_request-friendly validator for nginx or similar proxies

Track 4 operator

  • POST /api/v1/track4/operator/run-script - Run an allowlisted script under OPERATOR_SCRIPTS_ROOT

Features

  • Input validation (addresses, hashes, block numbers)
  • Pagination support
  • Query timeouts for database operations
  • CORS headers
  • Request logging
  • Error handling with consistent error format
  • Health checks with database connectivity
  • Wallet JWT auth for track endpoints
  • Email/password user sessions for the explorer access console
  • RPC product catalog, subscription state, API key issuance, revocation, and usage summaries

Running

cd backend/api/rest
go run main.go

Or use the development script:

./scripts/run-dev.sh

Configuration

Set environment variables:

  • DB_HOST - Database host
  • DB_PORT - Database port
  • DB_USER - Database user
  • DB_PASSWORD - Database password
  • DB_NAME - Database name
  • PORT - API server port (default: 8080)
  • CHAIN_ID - Chain ID (default: 138)
  • RPC_URL - Chain RPC used by Track 1 and mission-control health/SSE data
  • TOKEN_AGGREGATION_BASE_URL - Upstream token-aggregation base URL for mission-control liquidity proxy
  • BLOCKSCOUT_INTERNAL_URL - Internal Blockscout base URL for bridge trace lookups
  • EXPLORER_PUBLIC_BASE - Public explorer base URL used in mission-control trace responses
  • CCIP_RELAY_HEALTH_URL - Optional relay health probe URL, for example http://192.168.11.11:9860/healthz
  • CCIP_RELAY_HEALTH_URLS - Optional comma-separated named relay probes, for example mainnet=http://192.168.11.11:9860/healthz,bsc=http://192.168.11.11:9861/healthz,avax=http://192.168.11.11:9862/healthz
  • MISSION_CONTROL_CCIP_JSON - Optional JSON snapshot fallback when relay health is provided as a file instead of an HTTP endpoint
  • OPERATOR_SCRIPTS_ROOT - Root directory for allowlisted Track 4 scripts
  • OPERATOR_SCRIPT_ALLOWLIST - Comma-separated list of permitted script names or relative paths
  • OPERATOR_SCRIPT_TIMEOUT_SEC - Optional Track 4 script timeout in seconds (max 599)
  • JWT_SECRET - Shared secret for wallet and user-session JWT signing
  • ACCESS_ADMIN_EMAILS - Comma-separated email allowlist for access-console admins
  • ACCESS_INTERNAL_SECRET - Shared secret used by internal edge validators calling /api/v1/access/internal/validate-key

Auth model

There are now two distinct auth planes:

  1. Wallet auth

    • POST /api/v1/auth/nonce
    • POST /api/v1/auth/wallet
    • Used for wallet-oriented explorer tracks and operator features.
  2. Access-console user auth

    • POST /api/v1/auth/register
    • POST /api/v1/auth/login
    • Used for /api/v1/access/* endpoints and the frontend /access console.

RPC access model

The access layer currently models three RPC products:

  • core-rpc
    • Provider: besu-core
    • VMID: 2101
    • Approval required
    • Intended for operator-grade and sensitive use
  • alltra-rpc
    • Provider: alltra
    • VMID: 2102
    • Self-service subscription model
  • thirdweb-rpc
    • Provider: thirdweb
    • VMID: 2103
    • Self-service subscription model

The explorer can now:

  • register and authenticate users
  • publish an RPC product catalog
  • create product subscriptions
  • issue scoped API keys
  • set expiry presets and quota overrides
  • rotate keys by minting a replacement and revoking the old one
  • review approval-gated subscriptions through an admin surface
  • revoke keys
  • show usage summaries
  • show recent audit activity for users and admins
  • validate keys for internal edge enforcement and append usage records
  • support nginx auth_request integration through the GET /api/v1/access/internal/validate-key form

Current limitation:

  • the internal validation hook exists, but nginx/Besu/relay still need to call it or replicate its rules to enforce traffic at the edge
  • billing collection and invoicing are not yet handled by this package

Operational reference:

  • explorer-monorepo/deployment/ACCESS_EDGE_ENFORCEMENT_RUNBOOK.md
  • explorer-monorepo/deployment/common/nginx-rpc-api-key-gate.conf

Mission-control deployment notes

  • Include explorer-monorepo/deployment/common/nginx-mission-control-sse.conf in the same nginx server block that proxies /explorer-api/.
  • Keep the nginx upstream port aligned with the Go API PORT.
  • Verify internal reachability to BLOCKSCOUT_INTERNAL_URL and TOKEN_AGGREGATION_BASE_URL from the API host before enabling the mission-control cards in production.