Stablecoin Whale Monitor
Repository
Documentation

Documentation

Operations guide

Running the system locally, configuring it, deploying it, and keeping it healthy.

For a complete deployment walkthrough, follow the deployment runbook.

Local development

You need Node.js 20 with Corepack, and an Ethereum mainnet JSON-RPC endpoint. Local runs keep events and the checkpoint on disk under data/local-storage, so no cloud account is needed.

Copy the example environment file, paste your RPC URL into GOOGLE_BLOCKCHAIN_RPC_URL, then run the indexer and the API from the repository root:

Shell
cp .env.example .env
corepack enable
pnpm install --frozen-lockfile
pnpm indexer:once     # one cycle, or: pnpm indexer
pnpm api

In another terminal, start the website. Its example configuration points the browser at the local API on port 3001:

Shell
cp frontend/.env.example frontend/.env.local
pnpm --dir frontend install --frozen-lockfile
pnpm --dir frontend dev

Never commit .env, frontend/.env.local, credentials, Terraform variables or local state. The ignore rules cover them.

Configuration

The services read their settings from environment variables. These shape what the monitor shows:

VariableDefaultEffect
MIN_AMOUNT100000Indexing threshold in tokens
CONFIRMATION_BUFFER6Blocks behind the tip before a block is read
POLL_INTERVAL_MS30000Indexer poll interval
BLOCK_BATCH_SIZE5Blocks per processed range
RETENTION_DAYS7History the API serves
API_REFRESH_MS30000How often the API reloads its index
API_MAX_STALE_MS600000Index age after which query endpoints return 503
API_MAX_PAGE_SIZE50Largest allowed limit

The website is configured at build time:

VariableEffect
NEXT_PUBLIC_API_BASE_URLWhere the browser sends API requests. Empty in production, so requests go to the same origin.
NEXT_PUBLIC_SERVICES_PAUSEDtrue or false. Builds the maintenance mode, in which no API request is made. When unset, the default in frontend/lib/config.ts applies.
NEXT_PUBLIC_EXPECTED_RETURNReturn date shown during maintenance, as YYYY-MM-DD.
NEXT_PUBLIC_HISTORY_STARTSOptional YYYY-MM-DD. After a restart that moved the checkpoint forward, shows when history begins until the retention window has filled.

The defaults used in the website's copy live in frontend/lib/config.ts. Update it when the deployment configuration changes, so the docs and the interface keep matching.

Checks

These are the same checks the verification and CI pipelines run:

Shell
pnpm test
pnpm --dir frontend typecheck
NEXT_PUBLIC_API_BASE_URL= pnpm --dir frontend build
terraform fmt -check -recursive infra
terraform -chdir=infra/environments/test init -backend=false -input=false
terraform -chdir=infra/environments/test validate

Deployment

The supported Terraform root is infra/environments/test. The prod root is an empty scaffold and must be completed and reviewed as an independent environment before use. Before the first apply you need:

After Terraform has created the environment, releases flow through Cloud Build. Pull requests to main run the verify pipeline, which changes nothing. Each push to main runs CI, which tests, builds the image and the static site, and publishes a release manifest. Pushing a release tag runs CD, which waits for approval and deploys that exact image digest and site archive. Operators apply infrastructure changes separately through reviewed Terraform plans.

Verification and monitoring

After each deploy, CD runs the smoke test in infra/scripts/smoke-test.sh. It checks the site, caching headers, TLS, the API, checkpoint advancement and storage policy. You can check health by hand at any time:

Shell
curl -s "https://swm.josephdara.com/api/health"

Look for "status":"ok" and a small checkpointAgeSeconds. Cloud Monitoring alerts by email on failing uptime checks, 5xx responses, persistently degraded health, high p99 latency, a stopped indexer and a stalled indexer loop.

Maintenance

Pausing takes the indexer and API offline without destroying anything. Three switches control it:

SwitchWhere
services_paused localinfra/environments/test/main.tf
Frontend pause default, or NEXT_PUBLIC_SERVICES_PAUSEDfrontend/lib/config.ts
_SERVICES_PAUSED substitutioncloudbuild/cloudbuild-cd.yaml

To pause, set all three to true, apply Terraform, then cut a release. Terraform scales the indexer to zero, stops routing /api and disables the API and indexer alert policies. To resume, set all three to false and apply Terraform first. The indexer continues from its checkpoint and catches up before the release is cut.

If the checkpoint is moved forward before resuming, set NEXT_PUBLIC_HISTORY_STARTS so the monitor explains why older history is missing.

Rollback

Run the CD trigger against an earlier release tag and approve the build. The release manifest pins both the image digest and the site archive checksum, so they roll back together. Release artifacts expire after 14 days, which limits how far back you can go. See the runbook for the exact command.

Found a problem in this page? Open an issue in the repository.