Every environment variable read by either repo. Use this as the canonical reference when filling in a new .env, debugging missing-config errors, or reviewing a PR that touches config.
Sources scanned:
Backend: src/shared/config/index.ts, src/app.ts, every process.env.* reference in src/, and .env.sentry.example.
Frontend: .env.development, .env.local, .env.production, .env.sentry.example, next.config.ts, all process.env.* references in src/.
[!warning] Many secrets in the checked-in .env.* files of the frontend are publicly visible (Alchemy key, WalletConnect ID, Google OAuth client ID, Sentry DSN). Rotate these immediately if the repo leaks. Anything not marked NEXT_PUBLIC_ is not exposed to the browser.
How env is loaded
Backend
src/shared/config/index.ts calls dotenv.config({ path: '.env.development' }) and then dotenv.config() (default .env). In Docker dev, docker-compose.dev.yml injects env_file: .env.local and in production env_file: .env. There is no fallback: if a required var is missing, the typed access (process.env.JWT_SECRET!) yields undefined and the service crashes on first use.
Frontend
Next.js auto-loads .env, .env.local, .env.development, .env.production in the standard precedence order. Only variables prefixed NEXT_PUBLIC_ are exposed to the browser bundle. The production Dockerfile hard-codes several NEXT_PUBLIC_* values via ENV directives at build time so they are baked into the static bundle (see Docker Setup#frontend-dockerfile).
Database
Name
Repo
Required
Default
Example
Purpose
MONGODB_URI
backend
REMOVED
—
—
REMOVED — MongoDB has been completely removed from the backend (v2.9.12). Do not set this variable.
DB_NAME
backend
REMOVED
—
—
REMOVED — Was the Mongo database name; no longer used.
PG_URL
backend
✅REQUIRED
—
postgres://amanat:...@postgres:5432/amanat_dev
Drizzle runtime DSN. PostgreSQL is the only database layer; this must be set for the backend to start.
MIGRATION_PG_URL
backend
migration only
—
postgres://amanat:...@postgres:5432/amanat_dev
DSN used by backfill/migration scripts. Guarded by non-prod host allowlist.
PostgreSQL (Drizzle ORM) is the only database layer as of v2.9.12. MongoDB and Mongoose have been completely removed. 19 migrations (0000–0019) have landed covering 32 tables.
The following variables are also REMOVED and must not be set: MONGO_CONNECT_MODE, MONGO_URL, MONGODB_URI. Any .env file referencing them can have those lines deleted.
Cache / Redis
Name
Repo
Required
Default
Example
Purpose
REDIS_URI
backend
✅
—
redis://redis:6379
Connection string used by services/redis
REDIS_PASSWORD
backend
prod only
—
super-secret
Substituted into the prod Redis command line (--requirepass)
In dev, Redis runs without a password. In production the compose entrypoint is redis-server --requirepass "$REDIS_PASSWORD" so include :password@ in REDIS_URI accordingly.
Auth / JWT
Name
Repo
Required
Default
Example
Purpose
JWT_SECRET
backend
✅
—
64 hex chars
HMAC key for access tokens
JWT_EXPIRES_IN
backend
✅
—
1h
Access token lifetime
REFRESH_TOKEN_EXPIRES_IN
backend
✅
—
30d
Refresh token lifetime
ADMIN_EMAIL
backend
optional
admin@marketplace.com
—
Email of the initial admin created by init-admin
ADMIN_PASSWORD
backend
optional
Moji6364
—
Password for the initial admin
ADMIN_FIRST_NAME
backend
optional
Admin
—
First name for the seeded admin
ADMIN_LAST_NAME
backend
optional
User
—
Last name for the seeded admin
GOOGLE_CLIENT_ID
backend
optional
—
...apps.googleusercontent.com
Verifies Google ID tokens server-side
[!warning] Rotate JWT_SECRET only during a maintenance window — every active session is invalidated.
Allows explicit Request Network test webhooks only for controlled smoke tests
ESCROW_WALLET_ADDRESS
backend
✅
—
0xa304…
Master escrow address used by payments service
RECEIVER_WALLET_ADDRESS
backend
optional
—
0x…
Used by alternative payout flows
Historical SHKeeper keys
SHKEEPER_* variables may still appear in legacy migration docs or old .env files. They are not the current primary checkout path and should not be used for new payment work unless a deliberate legacy-record reconciliation task requires them.
Payments — Provider Selection
Name
Repo
Required
Default
Example
Purpose
PAYMENT_PROVIDER
backend
optional
request.network
request.network
Active provider for new payment intents
PAYMENT_DEFAULT_PROVIDER
backend
optional
request.network
request.network
Fallback alias when PAYMENT_PROVIDER is unset
PAYMENT_ENABLED_PROVIDERS
backend
optional
request.network
request.network
Comma-separated providers allowed at runtime
PAYMENT_ROLLBACK_PROVIDER
backend
optional
request.network
request.network
Provider used when selected provider is not enabled
PAYMENT_PROVIDER_MODE
backend
optional
live
dry-run
Provider mode: live, dry-run, or read-only
REQUEST_NETWORK_ENABLED
backend
optional
false
true
Adds request.network to enabled providers when no explicit list is set
PAYMENT_REQUEST_NETWORK_COHORT_PERCENT
backend
optional
0
10
Percent of new checkout cohort eligible for Request Network
REQUEST_NETWORK_ALLOW_TEST_WEBHOOKS
backend
optional
false
false
Allows x-request-network-test webhook bypass only in explicit test mode. Keep false in dev/prod unless running a controlled smoke test.
TRANSACTION_SAFETY_ENABLED
backend
optional
true
true
Enables the Transaction Safety Provider gate before Request Network pay-ins are marked completed.
TRANSACTION_SAFETY_REQUIRE_TX_HASH
backend
optional
true
true
Blocks completion when provider evidence does not include a transaction hash.
TRANSACTION_SAFETY_REQUIRE_TRANSFER_MATCH
backend
optional
true
true
Requires on-chain token/recipient/amount evidence to match the expected payment.
TRANSACTION_SAFETY_MIN_CONFIRMATIONS
backend
optional
12
chain floor
Fallback minimum confirmations for unknown chains. Known chains use built-in acceptance floors unless a higher admin-configured value exists.
RPC_URL_CHAIN_97
backend
optional
https://bsc-testnet-rpc.publicnode.com
https://bsc-testnet-rpc.publicnode.com
Overrides the backend verifier RPC for BSC Testnet (bsc-testnet, bnb-testnet, numeric 97).
BSC_TESTNET_RPC_URL / BNB_TESTNET_RPC_URL
backend
optional
RPC_URL_CHAIN_97 fallback
https://...
Alternate BSC Testnet RPC override names consumed by the legacy verifier path.
TRANSACTION_SAFETY_AML_PROVIDER
backend
optional
none
none
AML/sanctions provider adapter name. Non-none values should block until implemented/configured.
PAYMENT_LEDGER_ENFORCEMENT
backend
optional
false
true
Enforce ledger gates for release/refund
PAYMENT_RECONCILIATION_ENABLED
backend
optional
false
true
Enable scheduled provider reconciliation jobs
TREZOR_SAFEKEEPING_REQUIRED
backend
optional
false
true
Optional hardware-signature gate for release/refund confirmation. Only the literal value true enforces Trezor proof.
Payments — AMN Pay Scanner
Backend scanner settings:
Name
Repo
Required
Default
Example
Purpose
AMN_SCANNER_URL
backend
required when amn.scanner is enabled
—
http://amn-scanner:8080
Internal scanner service base URL used by amnPayAdapter helpers.
AMN_SCANNER_API_KEY
backend
prod
—
64 hex chars
Bearer token sent to scanner when scanner SCANNER_API_KEY is configured.
AMN_SCANNER_WEBHOOK_SECRET
backend
required when amn.scanner is enabled
—
64 hex chars
Shared HMAC key used to verify scanner intent and balance-watch webhooks.
AMN_SCANNER_DEFAULT
backend
optional
false
true
Makes AMN scanner the default pay-in provider where provider selection allows it.
Scanner service settings:
Name
Repo
Required
Default
Example
Purpose
SCANNER_API_KEY
scanner
prod
—
64 hex chars
Bearer token required for all scanner endpoints except /health.
BALANCE_WATCH_TICK_SEC
scanner
optional
60
60
How often the balance-watch scheduler queries for due watches.
BALANCE_WATCH_BATCH_SIZE
scanner
optional
50
50
Max due balance watches processed per scheduler tick.
DB_PATH
scanner
optional
./scanner.db
/data/scanner.db
SQLite state path for intents, checkpoints, and balance watches.
CHAINS_JSON_PATH
scanner
optional
./supported-chains.json
/app/supported-chains.json
Chain registry path.
TOKENS_JSON_PATH
scanner
optional
./tokens.json
/app/tokens.json
Token registry path used for token/tokenSymbol balance requests.
SCANNER_ENABLED_CHAINS
scanner
optional
all configured chains
56,1,97
Restricts scanner startup to selected chain ids; dev includes chain 97 for BSC Testnet testing.
EVM RPC overrides used by intent scanners and balanceOf reads.
Direct-address balance checks and watches currently support EVM ERC-20 only. Backend code should use checkScannerTokenBalance, createScannerBalanceWatch, and stopScannerBalanceWatch from amnPayAdapter.ts.
Repository Mode Flags (Migration Layer)
[!warning] These flags are obsolete as of v2.9.12. MongoDB and Mongoose have been completely removed. The repository factory returns Drizzle (PostgreSQL) repos exclusively. All domain stores are Postgres-only. The values mongo, dual, and DualWrite* are no longer valid — only postgres is valid, and it is the hardcoded default. These env vars are ignored at runtime and should not be set.
Name
Repo
Required
Default
Example
Purpose
REPO_DEFAULT
backend
OBSOLETE
—
—
REMOVED — Only postgres is valid; the factory always returns Drizzle repos.
REPO_USER
backend
OBSOLETE
—
—
REMOVED — mongo and dual modes no longer exist.
REPO_PAYMENT
backend
OBSOLETE
—
—
REMOVED — mongo and dual modes no longer exist.
REPO_POINTS
backend
OBSOLETE
—
—
REMOVED — mongo and dual modes no longer exist.
REPO_MARKETPLACE
backend
OBSOLETE
—
—
REMOVED — mongo and dual modes no longer exist.
Payments — Oracle Quoting / Depeg Protection
Name
Repo
Required
Default
Example
Purpose
ORACLE_QUOTING_ENABLED
backend
optional
false
true
Enables server-authoritative seller-offer quoting on /api/payment/request-network/intents.
PRICE_ORACLE_PROVIDERS
backend
optional
chainlink,offchain_fx
chainlink,offchain_fx
Ordered provider list used by the quote engine.
ORACLE_MAX_STALENESS_S
backend
optional
120
120
Rejects stale FX/token rates.
ORACLE_DISAGREE_BPS
backend
optional
100
100
Maximum allowed provider disagreement before the quote is blocked.
DEPEG_HARD_CAP_BPS
backend
optional
500
500
Blocks automatic quoting beyond this stablecoin depeg.
QUOTE_VALIDITY_S
backend
optional
90
90
Quote expiry window.
REQUOTE_RECONFIRM_BPS
backend
optional
50
50
Frontend/backend threshold for buyer reconfirmation after a material re-quote.
OFFCHAIN_FX_URL
backend
conditional
—
https://fx.example/rates
Required when offchain_fx is enabled for fiat currencies without Chainlink coverage.
OFFCHAIN_FX_REQUEST_TIMEOUT_MS
backend
optional
8000
8000
HTTP timeout for the off-chain FX provider.
CHAINLINK_RPC_1
backend
conditional
—
https://...
Ethereum RPC for Chainlink stablecoin/USD reads.
CHAINLINK_RPC_56
backend
conditional
—
https://...
BSC RPC for Chainlink stablecoin/USD reads.
Payments — Wallet UI (frontend)
Name
Repo
Required
Default
Example
Purpose
NEXT_PUBLIC_DEPAY_INTEGRATION_ID
frontend
legacy only
—
1330e2d3-…
Historical DePay widget integration ID
NEXT_PUBLIC_ESCROW_WALLET_ADDRESS
frontend
✅
—
0xa304…
Escrow address shown to buyers in the wallet flow
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
frontend
✅
—
283b54dd…
WalletConnect v2 project ID
NEXT_PUBLIC_ALCHEMY_API_KEY_MAINNET
frontend
✅
—
—
Alchemy RPC for mainnet
NEXT_PUBLIC_ALCHEMY_API_KEY_POLYGON
frontend
✅
—
—
Alchemy RPC for Polygon
NEXT_PUBLIC_ALCHEMY_API_KEY_SEPOLIA
frontend
optional
—
—
Alchemy RPC for Sepolia (testing)
OAuth
Name
Repo
Required
Default
Example
Purpose
GOOGLE_CLIENT_ID
backend
optional
—
…apps.googleusercontent.com
Verifies Google ID tokens server-side
NEXT_PUBLIC_GOOGLE_CLIENT_ID
frontend
✅ for Google login
—
…apps.googleusercontent.com
Client ID used by Google Identity Services in the browser
OpenAI
Name
Repo
Required
Default
Example
Purpose
OPENAI_API_KEY
backend
✅ for AI features
—
sk-…
Used by services/ai
OPENAI_DEFAULT_MODEL
backend
✅ for AI
gpt-4o-mini
gpt-4o
Default chat model
OPENAI_MODEL
backend
optional
falls back to default
gpt-4o
Per-call override read in legacy paths
OPENAI_MAX_TOKENS
backend
✅ for AI
1024
4096
Hard cap per request
OPENAI_TEMPERATURE
backend
✅ for AI
0.7
0.2
Decoded as float
App URLs
Name
Repo
Required
Default
Example
Purpose
FRONTEND_URL
backend
✅
—
http://localhost:8083
Used by CORS, Socket.IO origin, password-reset email links
BACKEND_URL
backend
optional
derived from PORT
http://localhost:5001
Used in webhook callbacks & emails
API_URL
backend
optional
${BACKEND_URL}/api
http://localhost:5001/api
Self-reference for outbound webhooks
PORT
backend
✅
—
5001
HTTP listen port
TRUST_PROXY
backend
optional
auto-on in prod
true
Enables app.set('trust proxy', 1) for Nginx
NEXT_PUBLIC_APP_URL
frontend
✅
—
http://localhost:8083
Self-URL used in metadata + OG tags
NEXT_PUBLIC_APP_NAME
frontend
optional
AMN
ایسکرو آنلاین
Display name in nav / titles
NEXT_PUBLIC_APP_VERSION
frontend
optional
package.json
2.8.94
Shown in the version logger
NEXT_PUBLIC_API_URL
frontend
✅
—
http://localhost:5001/api
Axios base URL
NEXT_PUBLIC_API_BASE_URL
frontend
optional
derived
http://localhost:5001
Used by a few legacy callers
NEXT_PUBLIC_BACKEND_URL
frontend
✅
—
http://localhost:5001
Used by file URL builders
NEXT_PUBLIC_SERVER_URL
frontend
optional
mirror of backend URL
http://localhost:5001
Server-side rendering fallback
NEXT_PUBLIC_SOCKET_URL
frontend
✅
—
http://localhost:5001
Socket.IO endpoint
NEXT_PUBLIC_ASSETS_DIR
frontend
optional
""
/assets
Prefix for static asset URLs
NEXT_PUBLIC_MAPBOX_API_KEY
frontend
optional
—
pk.…
Mapbox token for delivery map
Rate limiting / files
Name
Repo
Required
Default
Example
Purpose
RATE_LIMIT_WINDOW_MS
backend
✅
—
900000
Express-rate-limit window
RATE_LIMIT_MAX_REQUESTS
backend
✅
—
100
Requests allowed per window per IP
MAX_FILE_SIZE
backend
✅
—
10485760 (10 MB)
Multer upload cap (bytes)
UPLOAD_PATH
backend
optional
/app/uploads
/var/uploads
Disk path for uploads (mounted volume)
Feature flags / seeding
Name
Repo
Required
Default
Example
Purpose
AUTO_SEED_ON_START
backend
optional
false
true
Re-seeds users/addresses/templates on boot if users is empty
SEED_USERS
backend
optional
false
true
One-shot user seeding flag honoured by seedUsers.ts
FORCE_SEED_TEMPLATES
backend
optional
false
true
Re-creates request templates even if some exist
BUILD_STATIC_EXPORT
frontend
optional
false
true
Static export build (currently unused)
NEXT_PUBLIC_IS_DEVELOPMENT
frontend
optional
false
true
Shows the dev-only banner & debug helpers
NEXT_PUBLIC_ENABLE_DEBUG
frontend
optional
false
true
Verbose console logging in the browser
NEXT_TELEMETRY_DISABLED
frontend
optional
0
1
Disables Next.js telemetry
Passkey / WebAuthn (frontend)
Name
Repo
Required
Default
Example
Purpose
NEXT_PUBLIC_PASSKEY_RP_NAME
frontend
optional
Amn
Amn
Relying-party display name
NEXT_PUBLIC_PASSKEY_RP_ID
frontend
optional
localhost
amn.gg
Relying-party origin host
NEXT_PUBLIC_PASSKEY_ORIGIN
frontend
optional
derived
https://amn.gg
Allowed origin for the WebAuthn challenge
Sentry
Name
Repo
Required
Default
Example
Purpose
NEXT_PUBLIC_SENTRY_DSN
frontend
optional
—
https://…ingest.sentry.io/…
Browser & server Sentry DSN
SENTRY_ORG
frontend
build-time
—
manawenuz
Used by @sentry/nextjs source-map upload
SENTRY_PROJECT
frontend
build-time
—
escrow-frontend
Sentry project slug
SENTRY_AUTH_TOKEN
frontend
build-time
—
—
Auth token for source-map upload (CI secret)
SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING
frontend
optional
—
1
Silences known dev warning
SENTRY_SUPPRESS_GLOBAL_ERROR_HANDLER_FILE_WARNING
frontend
optional
—
1
Silences known dev warning
SENTRY_DSN
backend
optional
—
https://…ingest.sentry.io/…
Backend Sentry DSN (set in src/config/sentry.ts)
The backend Sentry init runs before any other import (src/app.ts line 1) so DSN must be present in the env at process start.
Quick .env.local template (backend, dev)
NODE_ENV=development
PORT=5001TRUST_PROXY=false# Database (PostgreSQL only — MongoDB removed in v2.9.12)PG_URL=postgres://amanat:secret@postgres:5432/amanat_dev
# CacheREDIS_URI=redis://redis:6379
# AuthJWT_SECRET=<openssl rand -hex 32>
JWT_EXPIRES_IN=1h
REFRESH_TOKEN_EXPIRES_IN=30d
# URLsFRONTEND_URL=http://localhost:8083
BACKEND_URL=http://localhost:5001
# Rate limitRATE_LIMIT_WINDOW_MS=900000RATE_LIMIT_MAX_REQUESTS=100# FilesMAX_FILE_SIZE=10485760UPLOAD_PATH=/app/uploads
# SMTPSMTP_HOST=smtp.example.com
SMTP_PORT=465SMTP_SECURE=trueSMTP_USER=SMTP_PASS=SMTP_FROM="AMN <no-reply@amn.gg>"# PaymentsPAYMENT_PROVIDER=request.network
PAYMENT_ENABLED_PROVIDERS=request.network
PAYMENT_ROLLBACK_PROVIDER=request.network
REQUEST_NETWORK_ENABLED=trueREQUEST_NETWORK_API_KEY=REQUEST_NETWORK_API_BASE_URL=https://api.request.network
REQUEST_NETWORK_ORIGIN=https://dev.amn.gg
REQUEST_NETWORK_MERCHANT_REFERENCE=REQUEST_NETWORK_NETWORK=bsc
REQUEST_NETWORK_PAYMENT_CURRENCY=USDC
REQUEST_NETWORK_WEBHOOK_CALLBACK_URL=https://dev.amn.gg/api/payment/request-network/webhook
REQUEST_NETWORK_WEBHOOK_SECRET=REQUEST_NETWORK_ALLOW_TEST_WEBHOOKS=falsePAYMENT_LEDGER_ENFORCEMENT=truePAYMENT_RECONCILIATION_ENABLED=falseTREZOR_SAFEKEEPING_REQUIRED=false# OpenAI (optional)OPENAI_API_KEY=OPENAI_DEFAULT_MODEL=gpt-4o-mini
OPENAI_MAX_TOKENS=1024OPENAI_TEMPERATURE=0.7
# SeedingAUTO_SEED_ON_START=true# WalletsESCROW_WALLET_ADDRESS=0xa3049825c0785095EEd5E7976E0E539466c84044
ADMIN_PAYOUT_WALLET_ADDRESS=# Derived destinations (per-(buyer, sellerOffer) RN ephemeral wallets — Task #7)# Backend ONLY needs the xpub. The master seed must live in KMS/Trezor.DERIVED_DESTINATION_XPUB=# Only set DERIVED_DESTINATION_XPRIV when DERIVED_DESTINATION_SWEEP_SIGNER=hot-key# (dev shortcut). For prod, leave this blank and use the Trezor flow (Task #11).DERIVED_DESTINATION_XPRIV=DERIVED_DESTINATION_BASE_PATH=m/44'/60'/0'DERIVED_DESTINATION_CHAIN_ID=56DERIVED_DESTINATION_SWEEP_SIGNER=build-only
DERIVED_DESTINATION_MIN_SWEEP_AMOUNT=0DERIVED_DESTINATION_SWEEP_INTERVAL_MS=300000DERIVED_DESTINATION_SWEEP_AUTOSTART=true# Master sweep wallet private key (pays gas for permit() + transferFrom() on non-BSC# chains; sends BNB gas top-ups on BSC). Should be a dedicated low-balance hot wallet# — NOT the same key used for escrow release/refund.SWEEP_MASTER_PRIVKEY=# BSC gas top-up thresholds (in BNB). If derived address BNB balance is below MIN, top up by TOP_UP.SWEEP_GAS_MIN_BNB=0.001
SWEEP_GAS_TOP_UP_BNB=0.002
# AMN Pay Scanner (replaces Request Network for pay-in detection)AMN_SCANNER_URL=AMN_SCANNER_API_KEY=AMN_SCANNER_WEBHOOK_SECRET=AMN_SCANNER_DEFAULT=false# Oracle quoting / stablecoin depeg protection# Keep disabled until feeds and the off-chain FX source are configured.ORACLE_QUOTING_ENABLED=falsePRICE_ORACLE_PROVIDERS=chainlink,offchain_fx
ORACLE_MAX_STALENESS_S=120ORACLE_DISAGREE_BPS=100DEPEG_HARD_CAP_BPS=500QUOTE_VALIDITY_S=90REQUOTE_RECONFIRM_BPS=50OFFCHAIN_FX_URL=OFFCHAIN_FX_REQUEST_TIMEOUT_MS=8000CHAINLINK_RPC_1=CHAINLINK_RPC_56=# OAuthGOOGLE_CLIENT_ID=
[!tip] Generate JWT_SECRET deterministically per environment so you don't accidentally invalidate sessions when restarting. Store it in your team's secret manager.
[!warning] DERIVED_DESTINATION_XPRIV is a development-only shortcut. In production, set DERIVED_DESTINATION_SWEEP_SIGNER=build-only and pair with Task #11 Trezor signing so the master seed never sits on the backend host.