Live Deployment
| Component | URL |
|---|---|
| App | shoot-production-f218.up.railway.app |
| Documentation | docs-1f2b6c2c.mintlify.app |
| On-chain program | 4HVnwG8...2iMG (devnet) |
Prerequisites
| Component | Version | Notes |
|---|---|---|
| Node.js | >= 20 LTS | Frontend, API server, Autopilot SDK |
| Rust | >= 1.78 | Keeper service |
| PostgreSQL | >= 14 | Required — all state persisted to DB (no localStorage fallbacks) |
| Docker | >= 24 | For production deployment |
Stack
- Next.js 16 with React 19 for the full-stack app
- Prisma ORM with PostgreSQL for all server-side persistence
- Rust / Axum for the keeper service (position monitor, scoring engine, lifecycle FSM)
- Privy for wallet authentication (embedded + external wallets)
- Adrena Data API (
datapi.adrena.trade) for real position data - Yellowstone gRPC for real-time Solana position monitoring
- Solana (devnet) for on-chain entry fees, settlement, and agent registration via the Shoot Anchor program
Local Development
Deploy to Railway (Docker)
The app is containerized with a multi-stage Dockerfile:Railway Configuration
| Setting | Value |
|---|---|
| Build Command | prisma generate && next build |
| Start Command | node server.js |
| Port | 3000 |
| Health Check | GET / |
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string (Railway provides this if you add a Postgres plugin) |
NEXT_PUBLIC_COMPETITION_PROVIDER | Yes | Always adrena for production |
NEXT_PUBLIC_PRIVY_APP_ID | Yes | Privy app ID from dashboard.privy.io |
NEXT_PUBLIC_PRIVY_APP_SECRET | Yes | Privy app secret |
NEXT_PUBLIC_SOLANA_CLUSTER | Yes | devnet (or mainnet for production) |
ADRENA_DATA_API_BASE_URL | No | Defaults to https://datapi.adrena.trade |
CRON_SECRET | Yes | Bearer token for /api/cron/* authentication |
ADMIN_SECRET | Yes | Bearer token for /api/admin/* authentication |
DISCORD_WEBHOOK_URL | No | Discord webhook for competition notifications |
DISCORD_OPS_WEBHOOK_URL | No | Separate webhook for sybil alerts |
BUYBACK_WALLET_KEYPAIR | No | JSON array of secret key bytes for Jupiter ADX buyback wallet. If not set, buybacks are recorded as “pending”. |
Privy Configuration
- Create app at dashboard.privy.io
- Enable: Embedded Wallets, External Wallets (Phantom, Backpack, Solflare)
- Set allowed origins:
https://your-domain.up.railway.app,http://localhost:3000 - Copy App ID to
NEXT_PUBLIC_PRIVY_APP_ID
Cron Jobs
All cron endpoints are POST requests authenticated with a Bearer token. They are triggered by an external scheduler (Railway cron, GitHub Actions, cron-job.org, etc.) — this is by design to avoid Vercel cron dependency.| Endpoint | Frequency | What It Does |
|---|---|---|
POST /api/cron/refresh-scores | Every 5 min | Fetch positions, compute scores, emit quest events, run sybil detection, auto-settle expired cohorts |
POST /api/cron/rotate-cohorts | Every 15 min | Transition cohort state machine (upcoming → live → settled) |
On-Chain Program
The Shoot Anchor program handles USDC entry fees, vault escrow, and settlement on Solana.| Property | Value |
|---|---|
| Program ID | 4HVnwG8iz7wdUbEQDH8cYGD6EuxNmMuEbvCrz8Ke2iMG |
| Cluster | Devnet |
| Authority | CChvxUR37fry8i2Gdvyrmwu2PH8vgZeTcFwtNqLxaHDW |
| Explorer | View on Solana Explorer |
Keeper Service (Rust)
The keeper monitors Adrena positions via Yellowstone gRPC, computes scores, and manages competition lifecycle. It matches Adrena’s own keeper infrastructure pattern.Keeper Docker
Keeper Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
GRPC_ENDPOINT | Yes | — | Yellowstone gRPC URL |
GRPC_TOKEN | Yes | — | Auth token for gRPC |
DATABASE_URL | Yes | — | PostgreSQL connection string |
ADRENA_PROGRAM_ID | No | 13gDzEXCdocbj8iAiqrScGo47NiSuYENGsRqi3SEAwet | Adrena program to monitor |
LISTEN_ADDR | No | 0.0.0.0:8080 | HTTP server bind address |
Autopilot SDK
Install and test the autonomous trading SDK:Claude Code Skill
Theshoot-trading skill gives Claude Code agents complete context for the trading stack — 12 tools, transaction signing flow, on-chain lifecycle, and Surfpool-based local testing. Drop it into any working directory and run Claude Code non-interactively.
Install:
.claude/skills/ — no additional config needed.
See Claude Code Skill for full reference including Surfpool quirks, token symbols, and lifecycle sequence.
MCP Server
The app ships an MCP server at/api/mcp that exposes all 12 trading tools to Claude Code, Claude Desktop, Cursor, and any other MCP-compatible agent host.
Vercel (Preview Deploys Only)
Avercel.json exists for preview deploys during development. Production deployment targets Railway.
Architecture Overview
adrena-live-adapter.tsreadsdata/competition-cohorts.jsonfor enrolled wallets- Fetches positions from
datapi.adrena.trade/position?user_wallet=... computeMetricsFromPositions()derives PnL%, volume, win rate, consistency, drawdowncomputeTournamentScore()produces composite ranking score- Sybil detection runs across the cohort
buildCompetitionSnapshotFromSources()assembles the full snapshot for the UI
Adding New Wallets
Editdata/competition-cohorts.json and add wallet addresses to a cohort’s enrolledWallets array. The adapter will fetch their real positions from Adrena on the next snapshot request.