Skip to Content
Welcome to RitoSwap's documentation!
dAppEnvironment Config

Environment Configuration Reference

RitoSwap validates every environment variable as the app boots (see app/config/public.env.ts and app/config/server.env.ts). Incorrect or incomplete settings throw immediately, and some flags change behavior across the entire stack (state worker enablement, JWT signing, Cloudflare worker routing, etc.). Use this page to understand each flag, its default, and the conditional rules enforced by the validators.

Public Environment (NEXT_PUBLIC_*)

These variables ship to the browser, so the schema (lines 32‑99) enforces strict typing before exporting publicEnv and publicConfig. Defaults are safe for local development—even if a variable is omitted, the parser fills in deterministic values.

All public flags run through a custom BoolEnv transformer. Strings such as yes, 1, on, or true become true; everything else (including empty strings) becomes false.

VariableDefaultNotes / Conditional Rules
NEXT_PUBLIC_ENABLE_STATE_WORKERfalseMaster switch for SIWE + rate limiting. When true, the server also requires STATE_WORKER_URL and STATE_WORKER_API_KEY (see server table).
NEXT_PUBLIC_ACTIVE_CHAINsepoliaDetermines runtime chain selection (ethereum, sepolia, ritonet). If set to ritonet, the fields below become mandatory.
NEXT_PUBLIC_DOMAINlocalhost:3000Comma‑delimited host allowlist for SIWE + legacy auth.
NEXT_PUBLIC_LOCAL_CHAIN_IDUnsetRequired when NEXT_PUBLIC_ACTIVE_CHAIN=ritonet. Used to derive CHAIN_IDS.ritonet.
NEXT_PUBLIC_LOCAL_BLOCKCHAIN_NAMERitoNetDisplay name for local network / chain info provider.
NEXT_PUBLIC_LOCAL_BLOCKCHAIN_RPCUnsetRequired when running on RitoNet. Must be a valid URL.
NEXT_PUBLIC_LOCAL_BLOCKCHAIN_WSSUnsetRequired when running on RitoNet. Validated via regex for ws:// or wss://.
NEXT_PUBLIC_ALCHEMY_API_KEYUnsetOptional. Enables Alchemy RPCs for Ethereum/Sepolia; otherwise the app uses public RPCs.
NEXT_PUBLIC_WALLETCONNECT_PROJECT_IDUnsetOptional. When missing, the server logs a warning because WalletConnect UI is disabled.
NEXT_PUBLIC_APP_NAMEApp NameUsed by ConnectKit / wallet UI metadata.
NEXT_PUBLIC_APP_DESCRIPTIONApp DescriptionDisplayed alongside the app name in wallet prompts.
NEXT_PUBLIC_SWfalseEnables the service worker / PWA layer. Surfaced via publicConfig.features.serviceWorker.
NEXT_PUBLIC_LOG_LEVELdebug (dev) / warn (prod)Optional literal (debug, info, warn, error). Falls back to environment‑aware defaults.
NEXT_PUBLIC_LOCAL_NOTIFICATIONStrueControls browser notification prompts inside the dapp.

Derived Helpers

  • publicEnv – frozen object containing all validated values (lines 148‑150).
  • publicConfig – friendly helpers exposed to both server and client (chain, log level, feature flags).

Server Environment (serverEnv)

The server validator (app/config/server.env.ts) runs before any server component executes. It throws immediately if a critical variable is missing and emits warnings for optional but recommended values (e.g., R2 config).

VariableDefault / RequirementNotes / Conditional Rules
DATABASE_URLRequiredApp refuses to boot without it.
STATE_WORKER_API_KEY, STATE_WORKER_URLOptional unless NEXT_PUBLIC_ENABLE_STATE_WORKER=trueBoth must be present once the public flag is enabled; otherwise validation fails.
BREVO_API_KEY, SENDER_EMAIL, RECEIVER_EMAILOptionalWithout them, the code logs warnings and skips production email delivery.
USE_CLOUDFLARE_WORKERfalseParser coerces strings/numbers to booleans. If true, CLOUDFLARE_WORKER_URL must be defined.
CLOUDFLARE_WORKER_URLOptionalRequired only when USE_CLOUDFLARE_WORKER evaluates to true.
R2_API_*OptionalMissing values trigger warnings because uploads/signing won’t work.
BACKDOOR_TOKENfalseIf true, TOKEN_ID must be set. In production, BACKDOOR_ADDRESS must also be defined.
JWT_ALGHS256Determines which signing material is required (see below).
JWT_SECRETRequired when JWT_ALG=HS256Validator warns if the secret is shorter than 32 characters.
JWT_PRIVATE_KEY, JWT_PUBLIC_KEYRequired when JWT_ALG is EdDSA or ES256Validator checks for PEM markers and throws if either key is missing.
JWT_ISSRequired (URL)Issuer claim for minted access tokens.
JWT_AUDRequired (comma list)Must contain at least one audience; parsed into serverConfig.jwt.aud.
JWT_ACCESS_TTL900 secondsPositive integer TTL for gate access tokens.
JWT_CLOCK_TOLERANCE5 secondsAllowable clock skew passed to downstream JWT verification.

serverConfig Helpers

The module exports a frozen serverConfig object that downstream code can safely import:

  • serverConfig.email – indicates whether Brevo credentials exist and whether worker delegation is enabled.
  • serverConfig.stateService – exposes isActive, url, and apiKey for the Durable Object client.
  • serverConfig.jwt – shares non-secret metadata such as issuer, audiences, TTL, algorithm, and booleans indicating whether signing material is present (without exposing the secret/private key).

Runtime Validation Workflow

app/config/validate.ts ties everything together. Importing the module triggers no work; you must explicitly call validateEnvironment() during server startup (for example, in app/layout.tsx before rendering the shell).

Key details:

  • Server-only – the function throws if invoked in the browser.
  • Run-once guard – it stores a promise on globalThis.__ENV_VALIDATION_PROMISE, preventing duplicate validation/log spam under React Strict Mode.
  • What it does:
    1. Dynamically imports server.env.ts, public.env.ts, chain.ts, and ai.server.ts, forcing each file’s zod schema to run.
    2. Builds a “startup configuration” summary (environment, feature flags, chain RPC metadata, AI quota settings, infra health).
    3. Logs the summary via @logger and emits production-only warnings if something isn’t configured (email missing, Alchemy key absent, backdoor enabled, AI quota misconfigured, etc.).
    4. Throws if any import fails, ensuring deployment halts before serving traffic.

Recommended usage:

// app/layout.tsx import { validateEnvironment } from '@/app/config/validate' export default async function RootLayout({ children }) { await validateEnvironment() // Fail fast if env is misconfigured return ( <html lang="en"> <body>{children}</body> </html> ) }

If your deployment uses a custom server entry point, call the validator before bootstrapping the Next handler. This guarantees every environment change gets revalidated on cold start.

Deployment Checklist

  1. Decide on your primary chain. If you stick with the Sepolia default, no extra envs are required. For RitoNet, set every NEXT_PUBLIC_LOCAL_BLOCKCHAIN_* field plus matching RPC endpoints in other workspaces.
  2. Enable the state worker by setting NEXT_PUBLIC_ENABLE_STATE_WORKER=true and providing STATE_WORKER_URL/STATE_WORKER_API_KEY.
  3. Configure JWT signing material appropriate for your chosen algorithm.
  4. Choose an email delivery mode:
    • Brevo inline: set BREVO_API_KEY, SENDER_EMAIL, RECEIVER_EMAIL, leave USE_CLOUDFLARE_WORKER=false.
    • Worker delegation: set USE_CLOUDFLARE_WORKER=true and provide CLOUDFLARE_WORKER_URL (the worker itself needs the Brevo secrets via Wrangler).
  5. (Optional) Wire Cloudflare R2 for gated audio downloads.

Keeping these contracts in sync with their validators ensures your deployment fails fast when configuration drifts, instead of producing subtle runtime bugs.

Security Schemas (shared Zod helpers)

app/config/security.public.ts centralizes the low-level validation used by every API. Refer to these specs when implementing clients or new endpoints.

HelperDefinitionUsage
NONCE_BYTES, NONCE_ENCODING, NonceSchema16 bytes, encoded as lowercase hex (32 chars). Regex enforced via ^[0-9a-fA-F]{32}$./api/nonce, /api/gate-access (SIWE flow) – clients must send the exact hex string returned by the nonce endpoint.
SignatureSchema65-byte ECDSA signature (0x + 130 hex chars). Compact 64-byte signatures are disabled unless ALLOW_COMPACT_SIGNATURES is flipped.Gate access & form-submission requests. Sending a shorter signature triggers a 400 before any cryptographic checks run.
AddressSchemaStrict 0x[a-fA-F0-9]{40} regex with lowercase normalization.All API bodies that accept an address (gate access, form submission, token status) reuse this schema to prevent mixed-case drift.
TokenIdInputSchema / TokenIdStringSchemaAccepts either a number or numeric string (for JSON bodies) and coerces to number. Path params use the string-only variant.Gate access, form submission, token status routes, and any CLI tooling that needs to accept human-friendly inputs.

🥡 Takeaway: Instead of duplicating regexes in every route, always import these schemas. That way, updating nonce or signature rules happens in one place and the request DTOs automatically inherit the stricter contract.

Chain Metadata Helpers

Multi-network UI components reuse the pure TypeScript helpers in app/schemas/domain/chains.ts. That file intentionally avoids touching env state so it can be imported by client utilities (Chain Info Provider, ConnectKit config, MCP tools):

  • SupportedChainSchema – a Zod enum listing every chain the UI can mention (mainnet, sepolia, polygon, arbitrum, avalanche, base, optimism, fantom, ritonet). Use it whenever you accept arbitrary strings from user input or query params.
  • CHAIN_DISPLAY_NAMES / formatChainName() – canonical casing for badges and dropdowns (“RitoNet”, “Sepolia”, etc.). Keeps marketing copy consistent with the environment selectors described earlier.
  • CHAIN_NATIVE_SYMBOLS – lightweight map for showing the correct ticker (ETH, MATIC, AVAX, …) alongside balances.
  • isSupportedChain() – type guard you can run before calling more expensive chain-specific logic.

Because the helpers live in app/schemas/domain, they can be shared between the docs site, MCP integrations, and the dapp without risking accidental bundling of env-sensitive config.

RitoSwap Docs does not store, collect or access any of your conversations. All saved prompts are stored locally in your browser only.