Skip to content
DocsSelf-hosting

Tech

Self-hosting and deployment

Run Animr locally or deploy it to Vercel: environment variables, Redis, crons and the external pulse.

Run it locally

Terminal
npm install
cp .env.example .env.local   # every value is optional
npm run dev                  # http://localhost:3000

With no keys at all, everything except the LLM works: the League, Time Machine, Versus, Bell (genome calls) and heist (template defender). State goes to .data/ as JSON files.

Environment variables

Names and purpose only. NEXT_PUBLIC_* values are inlined at build time, so changing one needs a rebuild. Never give a secret a NEXT_PUBLIC_ prefix.

Environment variables
VariableTypePurpose
CRON_SECRETSecretProtects /api/bell/cron and /api/agent/tick. Required in production, where the external pulse sends it as a Bearer header.
UPSTASH_REDIS_REST_URL / _TOKEN, or KV_REST_API_URL / _TOKENSecretShared state: Bells, rides, fan cards, the heist's counters and budget, agents. Required in production: without it state is per instance and lost on cold starts, and the heist fails closed (the House Chog naps). On Vercel, connect Upstash from the Marketplace.
ZG_API_KEYSecret0G Compute Router key. Without it, rules and templates decide.
ZG_MODEL, ZG_BASE_URL, ZG_JSON_MODE, ZG_THINKING, ZG_VERIFY_TEEConfigOptional 0G settings (server-only)
OPERATOR_PRIVATE_KEYSecretThe AI operator key for on-chain mode and trophy mints. A fresh hot wallet with gas only.
OPERATOR_ADDRESSConfigThe operator's public address, for the heist proof and the deploy script
NEXT_PUBLIC_TRADE_GUARD_ADDRESSConfigThe guard. Unset on mainnet means the live guard; empty means paper only.
NEXT_PUBLIC_TROPHIES_ADDRESSConfigAnimrTrophies. Unset turns the cabinet and awards off.
HOUSE_CHOG_TOKEN_IDConfigThe House Chog's token ID (1399), never its CHOG # number
ORACLE_PURSE_CHOGConfigWhole $CHOG per Oracle Purse; unset or 0 means none. The Daily Bell page shows this deployment's value. Set the same value where the purse job runs.
HEIST_DAILY_USD_CAPConfig0G spend per UTC day on heist replies (default 3)
HEIST_ADMIN_SECRETSecretBearer token for Hall of Fame moderation
HEIST_IP_SALTSecretKey for hashing visitors' IPs (default: derived from CRON_SECRET)
CHOG_CHAT_DAILY_CALLSConfigAsk this Chog's 0G calls per UTC day (default 1500)
ANIMR_MANUAL_RUNS_PER_DAYConfigGlobal Think now cap (default 400)
NEXT_PUBLIC_PRIVY_APP_ID, NEXT_PUBLIC_PRIVY_CLIENT_IDConfigPrivy login. Unset means the plain wallet menu.
NEXT_PUBLIC_SITE_URLConfigOrigin for share-card URLs (optional on Vercel)
NEXT_PUBLIC_RPC_URL, NEXT_PUBLIC_IPFS_GATEWAYConfigOptional overrides; they ship to every browser
OPENSEA_API_KEYSecretOptional; without it the app requests a short-lived key for /market
FARCASTER_HEADER, FARCASTER_PAYLOAD, FARCASTER_SIGNATUREConfigMini App account association (server-only)
ANIMR_ENV, ANIMR_DATA_DIRConfigRedis namespace and local file store; leave unset on Vercel
HOUSE_PRIVATE_KEY, HOUSE_ADDRESS, ADMIN_ADDRESSSecretScripts only. Never on Vercel.

Never change the Chog NFT, $CHOG, account implementation or salt variables: that would move every wallet address.

Deploy on Vercel

  • Import the repo with the Next.js preset and no overrides; keep Fluid Compute on (the Bell routes use a 300-second max duration).
  • Connect Upstash Redis from the Vercel Marketplace (it adds KV_REST_API_URL and KV_REST_API_TOKEN; the UPSTASH_REDIS_REST_* pair works too), then add the variables above (secrets as Secret, production only) and redeploy. Redis is required: without it the Bell, rides and the heist don't persist, and the House Chog naps.
  • vercel.json already calls /api/bell/cron at 15:00 and 16:00 UTC, but Vercel Hobby only allows daily crons and fires them anywhere within the hour. Add two jobs on an external scheduler (for example cron-job.org), each a GET with Authorization: Bearer <CRON_SECRET>: /api/bell/cron at minutes 1 and 11 of every hour (1,11 * * * *) and /api/agent/tick at minute 30 (30 * * * *). On-chain agents decide only on that tick and at the Bell.
  • Only the production deployment sends guarded trades and trophy mints (VERCEL_ENV = production, or ANIMR_ENV elsewhere). Previews with the same variables stay paper-only.
  • The Oracle Purse is a scheduled job the team runs outside Vercel: scripts/send-oracle-purse.mts --broadcast with ANIMR_ENV=production, the production Redis pair, HOUSE_PRIVATE_KEY and the same ORACLE_PURSE_CHOG. The app never reads the House key.
  • Redeploy after any variable change. /guard, the landing page and the docs are prerendered, so House Chog and purse changes show after a rebuild.

Contracts

contracts/
forge test --fork-url https://rpc.monad.xyz -vv
OPERATOR_ADDRESS=0x... ADMIN_ADDRESS=0x... forge script script/DeployAnimrTradeGuard.s.sol --rpc-url monad   # dry run

Details: AnimrTradeGuard.