Local Development Setup
Get Stacks Wars running locally — backend, frontend, and all required services.
Prerequisites
Before starting, make sure you have the following installed:
| Tool | Version | Purpose |
|---|---|---|
| Rust | Latest stable | Backend server |
| Node.js | 20+ | Frontend apps |
| Bun | 1.x | Package manager & runtime |
| Redis | 7+ | Real-time state & pub/sub |
| PostgreSQL | 15+ | Persistent storage |
| Git | Any | Source control |
Clone & Install
git clone https://github.com/Stacks-Wars/stacks-wars/
cd stacks-wars
bun installThis installs dependencies for all workspaces (web, fumadocs, native, and shared packages).
Backend Setup
The backend is a Rust server using Axum, PostgreSQL, and Redis. Configuration lives in apps/backend/.env.
1. Create your environment file
cp apps/backend/.env.example apps/backend/.env2. Configure Redis
Redis handles real-time lobby state, player state, WebSocket pub/sub, and chat.
Option A: Local Redis
Install and start Redis locally:
# macOS
brew install redis && brew services start redis
# Linux (Ubuntu/Debian)
sudo apt install redis-server && sudo systemctl start redisYour REDIS_URL will be:
REDIS_URL=redis://127.0.0.1:6379Option B: Redis Cloud (Free Tier)
- Go to Redis Cloud and create a free database
- Copy the connection string into your
.env:
REDIS_URL=redis://default:your-password@your-host.redis.cloud:portTip: Install Redis Insight to visually browse your Redis data during development.
3. Configure PostgreSQL
PostgreSQL stores users, lobbies, games, seasons, leaderboards, and player results.
Option A: Local PostgreSQL
# macOS
brew install postgresql && brew services start postgresql
# Linux
sudo apt install postgresql && sudo systemctl start postgresqlCreate a database:
createdb stacks_warsDATABASE_URL=postgres://your_user:your_password@localhost/stacks_warsOption B: Neon (Free Tier)
- Go to neon.tech and create a free serverless Postgres database
- Copy the connection string:
DATABASE_URL=postgres://user:password@ep-xxx.us-east-2.aws.neon.tech/neondb?sslmode=require4. Configure Authentication
The JWT secret is used to sign and verify authentication tokens:
JWT_SECRET="any-strong-random-string-here"
TOKEN_EXPIRY_DAYS="14"5. Configure Hiro API Key
The Hiro API is used for on-chain verification and token lookups on the Stacks blockchain.
- Visit the Hiro Platform and create an API key
- Add it to your
.env:
HIRO_API_KEY=your-hiro-api-key6. Telegram Bot (Optional)
The backend can send lobby creation notifications to a Telegram group.
- Message @BotFather on Telegram to create a new bot
- Add the bot to your target group and get the chat ID
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=-your-group-chat-id7. Start the Backend
cd apps/backend
cargo runThe server will start on http://localhost:3001 (or whatever PORT you set).
Frontend Setup
The web frontend is a Next.js app at apps/web/.
1. Create your environment file
cp apps/web/.env.example apps/web/.env.local2. Configure API URLs
Point the frontend at your local backend:
NEXT_PUBLIC_HTTP_URL=http://localhost:3001
NEXT_PUBLIC_WS_URL=ws://localhost:30013. Configure the Network
Set the Stacks network (use testnet for development unless you need mainnet):
NEXT_PUBLIC_NETWORK="testnet"4. Configure the Trusted Signer Key
The TRUSTED_SECRET_KEY is a BIP39 mnemonic passphrase used to sign game results. The smart contracts verify these signatures to authorize prize claims.
TRUSTED_SECRET_KEY="your 12/24 word mnemonic passphrase goes here"Derive the Public Key
After setting your passphrase, you need to derive the corresponding public key and update the smart contracts. Run this script:
import { generateWallet } from "@stacks/wallet-sdk";
import { privateKeyToPublic } from "@stacks/transactions";
const wallet = await generateWallet({
secretKey: "your 12/24 word mnemonic passphrase goes here",
password: "",
});
const publicKey = privateKeyToPublic(wallet.accounts[0].stxPrivateKey);
console.log(`0x${publicKey}`);Update the Smart Contracts
Take the public key output (starting with 0x) and update the TRUSTED-PUBLIC-KEY constant in each vault contract:
apps/backend/contract/stacks/contracts/stx-vault.clarapps/backend/contract/stacks/contracts/ft-vault.clarapps/backend/contract/stacks/contracts/sponsored-stx-vault.clarapps/backend/contract/stacks/contracts/sponsored-ft-vault.clar
Find the line:
(define-constant TRUSTED-PUBLIC-KEY 0x...)Replace the existing key with your derived public key.
5. Start the Frontend
From the repository root:
bun run dev:webThe web app will start on http://localhost:4002.
Running Everything Together
From the repository root, you can start all apps at once:
# Start all apps (frontend + docs)
bun run dev
# Start only the web frontend
bun run dev:web
# Start the backend separately (in another terminal)
cd apps/backend && cargo runOther Useful Commands
# Backend
cargo test # Run all backend tests
cargo check # Type-check without building
cargo run --bin hydrate # Hydrate Redis from PostgreSQL
# Frontend
bun run build # Build all apps
bun run check-types # Type-check all TypeScript appsTroubleshooting
Redis connection refused
Make sure Redis is running. Check with:
redis-cli ping
# Should return: PONGDatabase migration errors
Ensure your DATABASE_URL is correct and the database exists. For Neon, make sure ?sslmode=require is in the connection string.
WebSocket connection failing
Check that NEXT_PUBLIC_WS_URL matches your backend's address and port. If using CORS, ensure ALLOWED_ORIGINS in the backend .env includes your frontend URL.
Contract key mismatch
If prize claims fail on-chain, verify that the public key in the vault contracts matches the private key derived from your TRUSTED_SECRET_KEY passphrase.