Skip to content

Environment Variables Reference

Complete, canonical reference for every environment variable PayWarden reads. The source of truth is src/config/env.ts — if this page ever drifts, the Zod schema wins.

PayWarden validates the environment at startup with Zod. Any missing required var or invalid value causes process.exit(1) with a descriptive error.

Copy-paste template

dotenv
# ── Required ───────────────────────────────────────────────
DATABASE_URL=postgresql://paywarden:localdev123@localhost:5432/paywarden
REDIS_URL=redis://localhost:6379
API_KEY=pw_your_api_key_here                 # min 10 chars
WEBHOOK_SECRET=whsec_your_secret_here        # min 10 chars
VAULT_KEY=                                   # exactly 64 hex chars (openssl rand -hex 32)
HMAC_SECRET=                                 # min 32 chars (openssl rand -hex 32)
ADMIN_PASSWORD=                              # min 8 chars
JWT_SECRET=                                  # min 32 chars (openssl rand -hex 32)
TRONGRID_API_KEY=                            # from trongrid.io
USDT_CONTRACT=TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf   # Nile testnet USDT

# ── Optional (common) ──────────────────────────────────────
PORT=3000
HOST=0.0.0.0
NODE_ENV=development
LOG_LEVEL=info
TRON_NETWORK=nile
ORDER_TTL=1800
MIN_CONFIRMATIONS=19
SCAN_INTERVAL=3000
SCAN_MODE=address
DEMO_MODE=false

Server

VariableRequiredDefaultDescription
PORTno3000HTTP server port.
HOSTno0.0.0.0Bind address for the Fastify server.
NODE_ENVnodevelopmentOne of development / production / test.
LOG_LEVELnoinfoPino log level: trace / debug / info / warn / error / fatal.

Database & Redis

VariableRequiredDefaultDescription
DATABASE_URLyesPostgreSQL connection string. Must be a valid URL.
REDIS_URLyesRedis connection string. Must be a valid URL.

Docker Compose defaults:

  • DATABASE_URL=postgresql://paywarden:localdev123@localhost:5432/paywarden
  • REDIS_URL=redis://localhost:6379

Security

VariableRequiredDefaultDescription
API_KEYyesMerchant API authentication key. Minimum 10 chars. Sent as the X-API-Key header.
WEBHOOK_SECRETyesKey used to HMAC-SHA256 sign outgoing webhook bodies. Minimum 10 chars.
VAULT_KEYyesExactly 64 hex characters (32 bytes). Encrypts the BIP39 mnemonic stored in the vault/ directory (as vault/seed.enc) with AES-256-GCM. Generate with openssl rand -hex 32. Back it up — loss = vault unrecoverable.
HMAC_SECRETyesMinimum 32 chars. Used to HMAC-hash merchant API keys stored in the database. Generate with openssl rand -hex 32.

Admin Dashboard

Both variables below are required. PayWarden will refuse to start without them.

VariableRequiredDefaultDescription
ADMIN_PASSWORDyesPassword for /admin login. Minimum 8 chars.
JWT_SECRETyesSigns admin-session JWTs. Minimum 32 chars. Generate with openssl rand -hex 32.

TRON

VariableRequiredDefaultDescription
TRONGRID_API_KEYyesFree API key from trongrid.io.
TRON_NETWORKnonileOne of mainnet / nile / shasta.
USDT_CONTRACTyesUSDT (TRC-20) contract address. Mainnet: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t. Nile: TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf.

Payment

VariableRequiredDefaultDescription
ORDER_TTLno1800Seconds an unpaid order stays active before expiring (default = 30 minutes).
MIN_CONFIRMATIONSno19Block confirmations required before an order transitions to confirmed. TRON produces ~1 block / 3s, so 19 ≈ 57s.
SCAN_INTERVALno3000Chain-watcher polling interval in milliseconds.

Chain Watcher

VariableRequiredDefaultDescription
SCAN_MODEnoaddressaddress polls each pending address individually (best for low volume). block scans every new block for USDT Transfer events (best for > 10 concurrent orders).
DEMO_MODEnofalseBoolean (true / 1 to enable). Exposes the /demo checkout route that auto-creates test orders.

Fund Sweep

Sweeping is disabled unless both HOT_WALLET_KEY and COLD_WALLET_ADDRESS are set.

VariableRequiredDefaultDescription
HOT_WALLET_KEYnoHot wallet private key, exactly 64 hex chars. Unset = sweep disabled.
COLD_WALLET_ADDRESSnoDestination TRON address for swept USDT. Unset = sweep disabled.
SWEEP_MODEnoburnburn or delegate.
SWEEP_GAS_TOPUP_TRXno20TRX amount sent to each payment address before sweeping, to cover energy/bandwidth.
SWEEP_MIN_USDTno0.5Minimum USDT balance on an address that triggers a sweep.
SWEEP_DELAY_MSno30000Delay in milliseconds between confirmation and sweep execution.
HOT_WALLET_ALERT_TRXno50Emit a low-balance alert when hot-wallet TRX drops below this value.

Alerting / Notifications

All optional. At least one channel should be configured in production so that low-balance, webhook-failed, and sweep-failed events reach an operator. Alerts are de-duplicated per event type for 30 minutes.

VariableRequiredDefaultDescription
TELEGRAM_BOT_TOKENnoBot token from @BotFather.
TELEGRAM_CHAT_IDnoTarget chat ID (user or group).
SMTP_HOSTnoSMTP server host.
SMTP_PORTno587SMTP port.
SMTP_USERnoSMTP username.
SMTP_PASSnoSMTP password.
SMTP_FROMnoFrom address (falls back to SMTP_USER).
ALERT_EMAIL_TOnoDestination email address for alerts.

Proxy & Safety

These toggles guard against IP spoofing, cross-origin abuse, and SSRF. All default to the safe value — do not flip them on unless you understand the consequences.

VariableRequiredDefaultDescription
TRUST_PROXYnofalseTrust X-Forwarded-* headers. Set true only when PayWarden is genuinely behind a trusted reverse proxy (Caddy / Nginx) that strips client-supplied X-Forwarded-For. If you enable this while exposing PayWarden directly, any client can spoof their IP and bypass rate limits.
CORS_ORIGINnoComma-separated list of allowed origins, e.g. https://paywarden.io,https://api.paywarden.io. Leave unset to disable CORS entirely.
ALLOW_PRIVATE_CALLBACKSnofalseWhen false, the webhook delivery subsystem rejects any callback_url that resolves to a loopback / RFC1918 / link-local / *.local address. This prevents a stolen API key from turning the webhook fetcher into an internal-network probe (SSRF). Set to true only for local development against http://localhost:4000/webhook style receivers.

Generating secure values

bash
# VAULT_KEY — most critical, back this up!
openssl rand -hex 32

# HMAC_SECRET, JWT_SECRET
openssl rand -hex 32

# API_KEY, WEBHOOK_SECRET
openssl rand -hex 32

Released under the BSL 1.1 License.