{{ message }}
Repository navigation
Expand file tree
/
Copy path.env.example
More file actions
383 lines (326 loc) · 16 KB
/
Copy path.env.example
File metadata and controls
383 lines (326 loc) · 16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# Noblocks Environment Variables
# Copy this file to .env.local and fill in your values
# See: docs/environment-variables.md for detailed info about each env. variable
#
# This file is the canonical list. __tests__/envDocumentation.test.ts fails CI if
# code reads a variable that is missing here, or if an entry here is read nowhere.
# =============================================================================
# Core Application
# =============================================================================
# Aggregator API
NEXT_PUBLIC_AGGREGATOR_URL=https://api.paycrest.io/v1
# KYC tier monthly swap limits (USD). Omitted or empty = defaults below.
# Tier 3 also accepts "unlimited" (case-insensitive) to remove the monthly cap.
# Do not use 0 for unlimited — tier 0 uses 0 to mean "no swaps until phone".
NEXT_PUBLIC_KYC_TIER_0_MONTHLY=0
NEXT_PUBLIC_KYC_TIER_1_MONTHLY=0.5
NEXT_PUBLIC_KYC_TIER_2_MONTHLY=1
NEXT_PUBLIC_KYC_TIER_3_MONTHLY=2
# Authentication Services
NEXT_PUBLIC_PRIVY_APP_ID=
# RPC provider key (Dwellir), interpolated into per-network RPC URLs.
# ⚠️ Ships in the browser bundle — balance reads happen client-side. Treat it as
# public and restrict it by origin at the provider; it is not a secret.
NEXT_PUBLIC_RPC_URL_KEY=
# Starknet JSON-RPC endpoint. REQUIRED whenever Starknet is reachable —
# app/lib/starknet.ts throws when it is missing or empty.
NEXT_PUBLIC_STARKNET_RPC_URL=
# Client error reporting (Sentry-compatible DSN, e.g. GlitchTip)
# Leave empty to disable. Browser-only; no @sentry/nextjs plugin or sourcemap upload.
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_SENTRY_ENVIRONMENT=
NEXT_PUBLIC_SENTRY_RELEASE=
# 0–1; default 0 (tracing off)
NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE=0
# Send events from local dev when "true"
NEXT_PUBLIC_SENTRY_ENABLE_IN_DEV=false
# =============================================================================
# Database & Authentication
# =============================================================================
# Supabase Database
# Get these from: Supabase Dashboard → Project Settings → API
# Server code reads SUPABASE_URL only — there is no NEXT_PUBLIC_ variant.
SUPABASE_URL=https://your-project.supabase.co
# Server API routes (supabaseAdmin): **Secret** key only — sb_secret
SUPABASE_SECRET_KEY=
# Passphrase for the encrypt_recipient_data / decrypt_recipient_data Postgres
# functions that protect saved recipient details. Rotating it makes existing
# encrypted rows unreadable.
ENCRYPTION_KEY=
# Privy Authentication
PRIVY_APP_SECRET=
PRIVY_JWKS_URL=https://auth.privy.io/api/v1/apps/<your-privy-app-id>/jwks.json
PRIVY_ISSUER=privy.io
# Optional: Privy wallet API base (defaults to https://api.privy.io)
PRIVY_WALLET_API_URL=
# Optional: authorization key for Privy wallet API calls (Starknet key export).
# When unset, only the user signature is sent.
PRIVY_WALLET_AUTH_PRIVATE_KEY=
# =============================================================================
# Analytics
# =============================================================================
# Client-side Analytics
NEXT_PUBLIC_MIXPANEL_TOKEN=
NEXT_PUBLIC_HOTJAR_SITE_ID=
# Datadog Real User Monitoring (browser). EU site; consent-gated like Mixpanel.
# Create an application at https://app.datadoghq.eu/rum/list
NEXT_PUBLIC_DD_APPLICATION_ID=
NEXT_PUBLIC_DD_CLIENT_TOKEN=
NEXT_PUBLIC_DD_SESSION_REPLAY_SAMPLE_RATE=100
NEXT_PUBLIC_DD_SITE=datadoghq.eu
NEXT_PUBLIC_DD_SERVICE=noblocks
NEXT_PUBLIC_DD_ENV=production
NEXT_PUBLIC_DD_VERSION=
NEXT_PUBLIC_DD_RUM_SAMPLE_RATE=100
NEXT_PUBLIC_DD_ENABLE_IN_DEV=false
NEXT_PUBLIC_DD_TRACING_ALLOWED_ORIGINS=
# Datadog server-side APM + structured logs. Both talk to the Agent sidecar
# (docker-compose.datadog.yml), never to Datadog directly — so the app needs no
# DD_API_KEY; only the agent does, via .env.datadog. See OBSERVABILITY.md.
DD_SERVICE=noblocks
DD_ENV=production
DD_VERSION=
DD_AGENT_HOST=datadog-agent
DD_TRACE_AGENT_PORT=8126
# "false" disables APM. Read at startup only — requires a restart to take effect.
DD_TRACE_ENABLED=true
LOG_LEVEL=info
# Server-side Analytics (app/lib/server-analytics.ts).
# Mixpanel's server token IS the project token, so this is usually the same
# value as NEXT_PUBLIC_MIXPANEL_TOKEN. Unset here, NEXT_PUBLIC_MIXPANEL_TOKEN is
# used as a fallback; with neither set, every server-side event is dropped.
MIXPANEL_SERVER_TOKEN=
MIXPANEL_PRIVACY_MODE=strict
MIXPANEL_INCLUDE_IP=false
MIXPANEL_INCLUDE_ERROR_STACKS=false
NEXT_PUBLIC_ENABLE_EMAIL_IN_ANALYTICS=false
# =============================================================================
# Security
# =============================================================================
# Internal API Security
# Generate with: openssl rand -hex 32
INTERNAL_API_KEY=
# Server-only: Sender API key UUID (aggregator dashboard). Used by the
# /api/v1/payment-orders* routes (API-Key header + encrypted offramp messageHash).
# Never NEXT_PUBLIC_ — it must not reach the browser.
AGGREGATOR_SENDER_API_KEY_ID=
# =============================================================================
# Feature Flags
# =============================================================================
# Enable wallet context sync in middleware
ENABLE_WALLET_CONTEXT_SYNC=false
# Starknet Earn (Vesu / Starkzap): wallet Earn CTA, deposit/withdraw, activity tab
NEXT_PUBLIC_EARN_ENABLED=false
# AVNU paymaster for Starknet gas sponsorship.
# Required whenever Starknet Earn is on (the paymaster runs in "sponsored" mode).
STARKNET_PAYMASTER_API_KEY=
# Optional: gas token address, used only in non-sponsored mode.
# Defaults to the first token the paymaster reports as supported.
STARKNET_GAS_TOKEN_ADDRESS=
# EVM → Starknet Earn (LayerSwap bridge + Vesu). Needs NEXT_PUBLIC_EARN_ENABLED=true
# as well — isEvmEarnEnabled() requires both flags.
NEXT_PUBLIC_EVM_EARN_ENABLED=false
LAYERSWAP_API_KEY=
# Optional; must use HTTPS if set
LAYERSWAP_API_BASE_URL=https://api.layerswap.io #optional
NEXT_PUBLIC_TRON_ENABLED=false
# Optional: custom Tron RPC URL (defaults to https://api.trongrid.io)
NEXT_PUBLIC_TRON_RPC_URL=
# Optional: TronGrid API key for balance lookups (higher rate limits).
# ⚠️ Ships in the browser bundle and is sent as the TRON-PRO-API-KEY header from
# client code. Restrict it by origin at TronGrid; treat it as public.
NEXT_PUBLIC_TRONGRID_API_KEY=
# Referral Program: show/hide all referral UI and API routes
NEXT_PUBLIC_REFERRAL_ENABLED=true
# Bridge/Swap (Convert): in-wallet cross-chain convert via NEAR Intents + LI.FI + Textile FX
NEXT_PUBLIC_BRIDGE_ENABLED=false
# Textile FX v2 RFQ: USDT↔cNGN on BSC + Celo (server key from contact@textilecredit.com)
NEXT_PUBLIC_TEXTILE_ENABLED=false
TEXTILE_API_KEY=
# NEAR Intents 1Click API JWT (server-side)
ONE_CLICK_JWT=
# LI.FI API key (server-side, optional)
LIFI_API_KEY=
# Default slippage tolerance for bridge quotes in basis points (e.g. 50 = 0.5%)
NEXT_PUBLIC_BRIDGE_DEFAULT_SLIPPAGE_BPS=50
# HyperFX: USDC/USDT↔cNGN on Base, Polygon, BNB Smart Chain, and Ethereum (Convert).
# Requires NEXT_PUBLIC_BRIDGE_ENABLED=true and ALCHEMY_API_KEY (server-only ERC-4337 bundler).
NEXT_PUBLIC_HYPERFX_ENABLED=false
ALCHEMY_API_KEY=
# Hyperbridge Nexus endpoints. The NEXT_PUBLIC_ pair is read by the browser swap
# client; the unprefixed pair by the server quote route. Both optional — each
# falls back to the public Polytope endpoint.
NEXT_PUBLIC_HYPERBRIDGE_WS_URL=
NEXT_PUBLIC_HYPERBRIDGE_INDEXER_URL=
HYPERBRIDGE_WS_URL=
HYPERBRIDGE_INDEXER_URL=
# Embeddable widget (/widget route, iframed by whitelisted partners)
NEXT_PUBLIC_EMBED_ENABLED=false
# Comma-separated origins allowed to iframe /widget (CSP frame-ancestors).
# Must be https:// (http:// allowed only for localhost/127.0.0.1 in dev).
# Wildcard subdomains ok, e.g. https://partner.com,https://*.partner.app
# Merged with the embed_allowed_origins table (via /api/internal/embed-origins).
EMBED_ALLOWED_ORIGINS=
# Trusted absolute base URL the edge middleware uses to fetch the DB-backed
# allowlist (e.g. https://noblocks.xyz). Required to consult the
# embed_allowed_origins table; if unset, only EMBED_ALLOWED_ORIGINS is used.
# Never derived from the request Host header (avoids SSRF / key leakage).
INTERNAL_API_BASE_URL=
# =============================================================================
# Injected-Wallet Session Auth (SIWE)
# =============================================================================
# Canonical public origin of this deployment (e.g. https://noblocks.xyz).
# SIWE sign-in messages must name this host (or an allowed embed origin) —
# configured, never derived from the request Host header, so a signature
# phished on another domain can't mint a session here.
# Read on the server only (app/lib/server-config.ts → getAppUrl). The legacy
# NEXT_PUBLIC_APP_URL still works as a fallback; prefer APP_URL when set.
# Replace this value with the deployment's public origin before deploying.
# Do not leave http://localhost:3000 in a deployed environment.
APP_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=
# HMAC secret for injected-wallet session JWTs minted by
# /api/auth/injected/verify and verified by the middleware (x-injected-token).
# Generate with: openssl rand -hex 32
INJECTED_SESSION_SECRET=
# =============================================================================
# External Services
# =============================================================================
# Notice Banner
# See docs/notice-banner.md
NEXT_PUBLIC_NOTICE_BANNER_TEXT=
# Maintenance Notice Modal
# Set to any truthy value (e.g. "1") to show the maintenance notice overlay.
# SCHEDULE is the bold date/time string shown in the notice body.
# Changing the schedule auto-resets dismissals so users see the new notice.
NEXT_PUBLIC_MAINTENANCE_NOTICE_ENABLED=true
NEXT_PUBLIC_MAINTENANCE_SCHEDULE=Friday, February 13th, from 7:00 PM to 11:00 PM WAT
# Brevo Email Marketing
# Get from: Brevo Dashboard → Settings → API Keys
BREVO_API_KEY=
# List ID from: Brevo Dashboard → Contacts → Lists (numeric ID)
BREVO_LIST_ID=
# From address on transactional email (defaults to no-reply@noblocks.xyz)
BREVO_SENDER_EMAIL=
# Brevo Conversations (Chat Widget)
# Get from: Brevo Dashboard → Conversations → Settings
NEXT_PUBLIC_BREVO_CONVERSATIONS_ID=
NEXT_PUBLIC_BREVO_CONVERSATIONS_GROUP_ID=
# Activepieces webhooks. Each is optional — an unset URL skips that forward.
# Deposit forwarding, fired from the Moralis stream webhook:
ACTIVEPIECES_WEBHOOK_URL=
ACTIVEPIECES_SIGNUP_VERIFY_WEBHOOK_URL=
ACTIVEPIECES_KYC_RESULT_WEBHOOK_URL=
# Moralis EVM streams — deposit watching. Server-only.
# Stream and key from: Moralis Dashboard → Streams
MORALIS_STREAM_ID=
MORALIS_API_KEY=
MORALIS_BASE_URL=https://api.moralis-streams.com
# Shared secret used to verify the x-signature header on incoming stream webhooks
MORALIS_WEBHOOK_SECRET=
# =============================================================================
# Phone Verification Services
# =============================================================================
# KudiSMS (for African phone numbers)
# Get from: KudiSMS Dashboard → Settings → API Keys
KUDISMS_API_KEY=your_kudisms_api_key
KUDISMS_APP_NAME_CODE=your_app_name_code
KUDISMS_TEMPLATE_CODE=your_template_code
KUDISMS_SENDER_ID=Noblocks
# Optional request timeout, default 10000
KUDISMS_TIMEOUT_MS=
# Twilio (for international phone numbers via Verify API)
# Get from: Twilio Console → Account Dashboard
TWILIO_ACCOUNT_SID=your_twilio_account_sid
TWILIO_AUTH_TOKEN=your_twilio_auth_token
# Verify service SID: Twilio Console → Verify → Services → create or use default
TWILIO_VERIFY_SERVICE_SID=VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional request timeout, default 5000
TWILIO_VERIFY_TIMEOUT_MS=
# =============================================================================
# SmileID KYC Verification Services
# =============================================================================
# API key from Smile Identity portal
SMILE_IDENTITY_API_KEY="your_api_key_here"
# Partner ID from Smile Identity portal
SMILE_IDENTITY_PARTNER_ID="your_partner_id_here"
# Callback URL for async job results (e.g. https://your-host/api/kyc/smile-id/callback)
SMILE_ID_CALLBACK_URL=""
# "0" = sandbox, "1" = production (or a legacy full API URL string)
SMILE_IDENTITY_SERVER="0"
# Optional override, checked before SMILE_IDENTITY_SERVER. "0" or "1" only.
SMILE_IDENTITY_SERVER_MODE=
# =============================================================================
# Dojah – Tier 3 address / proof-of-address verification
# =============================================================================
# Replace with your own credentials from https://app.dojah.io/developers/configuration
DOJAH_APP_ID=<DOJAH_APP_ID_PLACEHOLDER>
DOJAH_SECRET_KEY=<DOJAH_SECRET_KEY_PLACEHOLDER>
DOJAH_BASE_URL=https://api.dojah.io
# Optional request timeout, default 25000
DOJAH_TIMEOUT_MS=
# Supabase Storage bucket for KYC document uploads (create in Supabase Dashboard → Storage)
KYC_DOCUMENTS_BUCKET=kyc-documents
# =============================================================================
# Campaign Management
# =============================================================================
# Noblocks Play (fantasy league). Keep ENABLED=true for /play announcement + /play/admin.
NEXT_PUBLIC_FANTASY_ENABLED=true
# When true, public /play shows the campaign-ended announcement (deep links redirect to /play).
# /play/admin stays available. Flip false to revive a live league after rebranding.
NEXT_PUBLIC_FANTASY_CAMPAIGN_ENDED=true
# World Cup footer Lottie (requires fantasy enabled and not campaign-ended; ends Jul 19 2026 by default)
NEXT_PUBLIC_WORLDCUP_FOOTER_END_DATE=2026-07-19T23:59:59+01:00
# Noblocks Play backend.
# Admin key for /api/play/admin/* (sent as x-admin-key). Unset = admin tooling OFF.
FANTASY_ADMIN_KEY=
# Shared secret for the Cloudflare worker that POSTs /api/play/worker
# (sent as x-internal-auth). Falls back to INTERNAL_API_KEY when unset.
FANTASY_WORKER_SECRET=
# Dev-only: "true" compresses gameweek timing for local testing. Ignored in production.
FANTASY_LOCAL_TIMELAPSE=
# API-Football key used to pull fixtures, players and live scores
API_FOOTBALL_KEY=
# Referral Funding Wallet (pays referral rewards in app/api/referral/claim)
# ⚠️ WARNING: These credentials control funds and must be kept secure
# - Never commit these values to version control
# - Use secure secret management in production (AWS Secrets Manager, Vault, etc.)
# - Rotate keys regularly
# - Restrict access to authorized personnel only
# - Private key must be in format: 0x followed by 64 hex characters (66 chars total)
CASHBACK_WALLET_ADDRESS=
CASHBACK_WALLET_PRIVATE_KEY=
# =============================================================================
# Content Management (Sanity)
# =============================================================================
# Sanity Studio (server-side)
SANITY_STUDIO_DATASET=production
SANITY_STUDIO_PROJECT_ID=your_project_id_here
# Next.js App (client-side)
NEXT_PUBLIC_SANITY_DATASET=production
NEXT_PUBLIC_SANITY_PROJECT_ID=your_project_id_here
# =============================================================================
# Bundler / EIP-7702 sponsor
# =============================================================================
# Sponsor wallet that pays gas for batched EIP-7702 calls.
# PRIVATE_KEY is a legacy alias, still accepted as a fallback.
SPONSOR_EVM_WALLET_PRIVATE_KEY=0x...
PRIVATE_KEY=
# Onramp chained forwarding
# When true, onramp crypto settles to the user's Noblocks wallet first, then is auto-forwarded
# (client-signed, gas-sponsored) to the user's chosen destination if it differs.
NEXT_PUBLIC_ONRAMP_CHAINED_FORWARDING_ENABLED=false
NEXT_PUBLIC_KES_ONRAMP_ENABLED=false
NEXT_PUBLIC_REFERRAL_MIN_QUALIFYING_VOLUME_USD=20 # in USDC
NEXT_PUBLIC_REFERRAL_REWARD_AMOUNT_USD=1 # in USDC
# =============================================================================
# Scripts only (not read by the app)
# =============================================================================
# scripts/seed-fantasy.ts
SEED_DELAY_MS=
SEED_SKIP_PLAYERS=
SEED_TIMELAPSE_HOURS=
SEED_TIMELAPSE_GWS=
# scripts/backfill-moralis-from-privy.ts
DRY_RUN=
MORALIS_MS_DELAY=
You can’t perform that action at this time.
