Getting Started
A comprehensive guide to setting up BlockbotX for local development.
Prerequisites
Before you begin, make sure the following tools are installed on your machine:
- Node.js 20+ -- required runtime (download)
- pnpm 10+ -- package manager (
corepack enable && corepack prepare pnpm@latest --activate) - PostgreSQL 16 -- primary database (or use Docker Compose, see below)
- Redis 7 -- caching, rate limiting, and job queues (or use Docker Compose)
- Git -- version control
Installation
-
Clone the repository
git clone https://github.com/your-org/BlockbotX.git cd BlockbotX -
Install dependencies
pnpm install -
Copy the environment file
cp .env.example .env.localThe application loads
.env.localfirst, then falls back to.env. You will configure the variables in the next section.
Environment Configuration
Open .env.local and fill in the values below. Variables are grouped by category and labeled as required or optional.
Application
These are pre-filled with sensible defaults. You typically do not need to change them for local development.
| Variable | Default | Notes |
|---|---|---|
NODE_ENV | development | Set to production for deploys |
NEXT_PUBLIC_APP_URL | http://localhost:3000 | Public-facing URL of the app |
NEXT_PUBLIC_WS_URL | ws://localhost:3000 | WebSocket URL for Socket.io |
HOSTNAME | 0.0.0.0 | Use localhost for local dev, 0.0.0.0 for Docker |
PORT | 3000 | HTTP server port |
Database -- REQUIRED
| Variable | Default | Notes |
|---|---|---|
DATABASE_URL | postgresql://blockbotx:blockbotx_dev_password@localhost:5432/blockbotx_dev?schema=public | PostgreSQL connection string. If using Docker Compose, this default works out of the box. |
Redis -- REQUIRED
Redis is used for session caching, rate limiting, and BullMQ job queues. You can configure it with either individual parameters or a connection URL.
| Variable | Default | Notes |
|---|---|---|
REDIS_HOST | localhost | Redis hostname |
REDIS_PORT | 6379 | Redis port |
REDIS_PASSWORD | (empty) | Password (Docker Compose default: blockbotx_dev_password) |
REDIS_URL | (empty) | Alternative: full connection URL (overrides the above) |
Authentication and Security -- REQUIRED
| Variable | Default / Example | Notes |
|---|---|---|
JWT_SECRET | CHANGE_ME_generate_with_openssl_rand_hex_64 | Must change. Minimum 64 characters. Generate with openssl rand -hex 64. |
JWT_EXPIRES_IN | 15m | Access token lifetime |
REFRESH_TOKEN_EXPIRES_IN | 7d | Refresh token lifetime |
NEXTAUTH_SECRET | CHANGE_ME_generate_with_openssl_rand_hex_64 | Must change. Used by NextAuth.js. Generate with openssl rand -hex 64. |
NEXTAUTH_URL | http://localhost:3000 | Must match your app URL |
ENCRYPTION_KEY | CHANGE_ME_exactly_32_characters! | Must change. AES-256-GCM key for encrypting exchange API keys. Must be exactly 32 characters. |
CORS_ALLOWED_ORIGINS | (empty) | Comma-separated additional allowed origins |
Exchange APIs -- Optional
Users connect their own exchange API keys via the Exchange Connections page in the app. No server-level exchange credentials are required. These settings control which environment the app points to.
| Variable | Default | Notes |
|---|---|---|
BINANCE_TESTNET | true | Set to true to route connections through Binance demo API |
BINANCE_API_URL | https://demo-api.binance.com/api | Automatically set based on testnet flag |
BINANCE_WS_URL | wss://demo-stream.binance.com/ws | WebSocket for market data |
OKX exchange is also supported. Users provide their API key, secret, and passphrase (OKX-specific) via the app UI.
Stripe -- Optional (billing and subscriptions)
Required only if you want to enable subscription billing.
| Variable | Example | Notes |
|---|---|---|
STRIPE_SECRET_KEY | sk_test_... | From Stripe Dashboard |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | pk_test_... | Client-side publishable key |
STRIPE_WEBHOOK_SECRET | whsec_... | Webhook signing secret for HMAC-SHA256 verification |
STRIPE_PRICE_BASIC_MONTHLY | price_basic_monthly_id | Stripe price IDs for each plan (Basic, Pro, Premium, Enterprise -- monthly and yearly) |
Email (SMTP) -- Optional
Required for email notifications (password resets, alerts, etc.).
| Variable | Default | Notes |
|---|---|---|
FROM_EMAIL | [email protected] | Sender email address |
SMTP_HOST | smtp.gmail.com | SMTP server hostname |
SMTP_PORT | 587 | SMTP port |
SMTP_SECURE | false | Use TLS |
SMTP_USER | (your email) | SMTP username |
SMTP_PASSWORD | (your app password) | SMTP password or app-specific password |
Telegram -- Optional (notifications)
| Variable | Notes |
|---|---|
TELEGRAM_BOT_TOKEN | Bot token from @BotFather |
TELEGRAM_BOT_USERNAME | Bot username (default: BlockbotXBot) |
Blockchain RPCs -- Optional (DeFi features)
Required only if you are working on DeFi-related features (staking, farming, liquidity).
| Variable | Notes |
|---|---|
BLOCKCHAIN_NETWORK | testnet (default) or mainnet -- defaults to testnet outside production |
ETHEREUM_RPC_URL | Mainnet Ethereum RPC (e.g., Alchemy) |
BSC_RPC_URL | Binance Smart Chain RPC |
POLYGON_RPC_URL | Polygon RPC |
ALCHEMY_API_KEY_ETH | Per-chain Alchemy key (optional, falls back to RPC URL) |
ALCHEMY_API_KEY_BSC | Per-chain Alchemy key |
ALCHEMY_API_KEY_POLYGON | Per-chain Alchemy key |
ETHEREUM_TESTNET_RPC_URL | Sepolia testnet RPC |
BSC_TESTNET_RPC_URL | BSC testnet RPC |
POLYGON_TESTNET_RPC_URL | Polygon Amoy testnet RPC |
NEXT_PUBLIC_SOLANA_RPC_URL | Solana RPC for Phantom wallet integration |
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID | WalletConnect v2 project ID from cloud.walletconnect.com |
Sentry -- Optional (error monitoring)
| Variable | Notes |
|---|---|
NEXT_PUBLIC_SENTRY_DSN | Sentry DSN from your project settings |
NEXT_PUBLIC_APP_VERSION | App version for release tracking (default: 1.0.0) |
File Storage -- Optional (exports and uploads)
| Variable | Default | Notes |
|---|---|---|
FILE_STORAGE_PROVIDER | local | local or s3 |
AWS_S3_BUCKET | -- | S3 bucket name (required if provider is s3) |
AWS_REGION | us-east-1 | AWS region |
AWS_ACCESS_KEY_ID | -- | S3 access key |
AWS_SECRET_ACCESS_KEY | -- | S3 secret key |
S3_ENDPOINT | -- | Custom S3 endpoint (for Hetzner, MinIO, DigitalOcean Spaces, etc.) |
Logging
| Variable | Default | Notes |
|---|---|---|
LOG_LEVEL | info | One of: debug, info, warn, error |
Database Setup
Option A: Use Docker Compose (recommended)
See the Docker Compose section below. The database will be created automatically.
Option B: Manual PostgreSQL setup
-
Create the database and user:
CREATE USER blockbotx WITH PASSWORD 'blockbotx_dev_password'; CREATE DATABASE blockbotx_dev OWNER blockbotx; -
Ensure your
DATABASE_URLin.env.localpoints to this database.
Run Migrations
Apply all database migrations to create the schema:
pnpm db:migrate
Seed Data (optional)
Populate the database with sample data for development:
pnpm db:seed
This runs drizzle/seed.ts via tsx.
Docker Compose (Alternative)
Docker Compose provides PostgreSQL, PgBouncer, and Redis with a single command. This is the easiest way to get the infrastructure running.
Start the services
docker compose up -d
This starts three containers:
| Service | Container | Port | Description |
|---|---|---|---|
| PostgreSQL 16 | blockbotx-postgres | 5432 | Primary database |
| PgBouncer | blockbotx-pgbouncer | 6432 | Connection pooler (transaction mode) |
| Redis 7 | blockbotx-redis | 6379 | Caching, rate limiting, job queues |
PgBouncer
PgBouncer sits between the application and PostgreSQL as a connection pooler. It runs in transaction pooling mode, which means connections are returned to the pool after each transaction completes. This is important for serverless and high-concurrency environments.
- Direct database access:
localhost:5432(bypass PgBouncer) - Pooled access:
localhost:6432(through PgBouncer) - Pool configuration: max 200 client connections, default pool size 20, minimum 5, reserve 5
For local development, connecting directly to PostgreSQL on port 5432 is fine. In production or Docker deployments, point DATABASE_URL at PgBouncer (port 6432) for better connection management.
Redis password
The Docker Compose Redis service uses the password blockbotx_dev_password by default (configurable via the REDIS_PASSWORD environment variable). Make sure your .env.local REDIS_PASSWORD matches.
Application container (optional)
To also run the Next.js application inside Docker:
docker compose --profile app up -d
The app service builds from the Dockerfile, connects to PgBouncer and Redis automatically, and serves on port 3000. It reads additional configuration from .env.local.
Stop the services
docker compose down
To also remove persisted data volumes:
docker compose down -v
Running the Development Server
Start the development server:
pnpm dev
This runs tsx server.ts, a custom server that boots the following subsystems:
- Next.js 16 app -- pages, API routes, and static assets
- Socket.io WebSocket server -- real-time updates (bot status, prices, notifications)
- Bot scheduler -- resumes execution of active bots, rebuilds position and paper-trading state from the database
- Portfolio tracker -- background worker for portfolio value snapshots
- Telegram bot -- notification delivery via Telegram (if configured)
- Rate limiter -- per-user rate limiting on API routes (skips webhooks and health checks)
The server performs environment validation on startup and will exit with an error if required variables are missing.
Once running, the server is available at:
http://localhost:3000
Verifying the Setup
After starting the development server, confirm everything is working:
-
Landing page -- open http://localhost:3000 in your browser. You should see the marketing landing page.
-
Health check -- verify the API is responding:
curl http://localhost:3000/api/healthA successful response confirms the database and Redis connections are working.
-
Register an account -- navigate to http://localhost:3000/signup and create a new account. During closed beta, registration requires an invite code. You will need an invite from an existing beta tester to sign up.
-
Sign in -- navigate to http://localhost:3000/signin and log in with your new credentials.
Available Scripts
All scripts are run with pnpm <script>.
Development
| Script | Command | Description |
|---|---|---|
dev | tsx server.ts | Start the development server (custom server with Socket.io, bot scheduler, etc.) |
build | next build | Create a production build |
start | tsx server.ts | Start the production server |
lint | eslint . | Run ESLint across the codebase |
Testing
| Script | Command | Description |
|---|---|---|
test | jest | Run all Jest tests |
test:watch | jest --watch | Run tests in watch mode |
test:coverage | jest --coverage | Run tests with coverage report |
test:unit | jest __tests__ | Run unit tests only |
test:api | jest tests/api | Run API integration tests only |
test:e2e | playwright test | Run end-to-end tests with Playwright |
test:e2e:ui | playwright test --ui | Run E2E tests with interactive UI |
test:e2e:debug | playwright test --debug | Run E2E tests in debug mode |
test:e2e:report | playwright show-report | View the last E2E test report |
test:all | pnpm test && pnpm test:e2e | Run all Jest and Playwright tests |
playwright:install | playwright install --with-deps | Install Playwright browsers and system dependencies |
Database
| Script | Command | Description |
|---|---|---|
db:generate | drizzle-kit generate | Generate SQL migration files from schema changes |
db:push | drizzle-kit push | Push schema changes directly (no migration file) |
db:migrate | drizzle-kit migrate | Apply pending migrations |
db:studio | drizzle-kit studio | Open Drizzle Studio (visual database browser) |
db:seed | tsx drizzle/seed.ts | Seed the database with sample data |
For production deployments, use pnpm db:migrate to apply pending migrations.
Troubleshooting
ENCRYPTION_KEY must be exactly 32 characters
The ENCRYPTION_KEY variable is used for AES-256-GCM encryption of exchange API keys. It must be exactly 32 characters long -- no more, no less. The server validates this on startup and will exit with an error if the length is wrong.
Generate a valid key:
openssl rand -hex 16
This produces exactly 32 hexadecimal characters.
Redis connection refused
Redis must be running for the application to start. Rate limiting, caching, and job queues all depend on it.
- If using Docker Compose:
docker compose up -d redis - If running locally: ensure Redis is started and accessible at the host/port specified in your
.env.local - Check the password matches between your
.env.localand the Redis server configuration
PostgreSQL connection failed
The database must be accessible at the URL specified in DATABASE_URL.
- If using Docker Compose:
docker compose up -d postgres - If running locally: ensure PostgreSQL is started and the database
blockbotx_devexists - Verify the username, password, host, and port in your connection string
- Run
pnpm db:migrateif the schema has not been applied yet
Port 3000 already in use
Another process is already listening on port 3000. Either stop the other process or change the PORT variable in .env.local:
PORT=3001 pnpm dev
Remember to also update NEXT_PUBLIC_APP_URL, NEXT_PUBLIC_WS_URL, NEXT_PUBLIC_BASE_URL, and NEXTAUTH_URL to match the new port.
Profile Avatars
BlockbotX uses NFT-based avatars. Profile avatars display NFT images from connected wallets, or auto-generated gradient avatars based on wallet address. There is no file upload for avatars -- connect a wallet with NFTs and select one from the NFT picker in profile settings.
Environment validation fails on startup
The custom server (server.ts) runs validateEnv() before starting. If required environment variables are missing or invalid, the process will exit with an error message indicating which variables need attention. Review the error output and update your .env.local accordingly.