Node.js theorytheory 0/50 · 0%
Web3 integration · hard

44. Serving multiple environments (testnets/mainnet)

Config-driven chain selection instead of hard-coded values.

A dApp backend commonly needs to support several chains/environments (mainnet, a testnet, a local dev chain) without duplicating code — the clean approach is a config map keyed by chain id or name, selected via environment variable, with every chain-specific value (RPC URL, contract addresses, explorer URL) looked up through it.

js
const CHAINS = {
  base: { id: 8453, rpcUrl: process.env.BASE_RPC_URL, explorer: "https://basescan.org" },
  "base-sepolia": { id: 84532, rpcUrl: process.env.BASE_SEPOLIA_RPC_URL, explorer: "https://sepolia.basescan.org" },
};

function getChain(name) {
  const chain = CHAINS[name];
  if (!chain) throw new Error(`unknown chain: ${name}`);
  return chain;
}

const active = getChain(process.env.ACTIVE_CHAIN ?? "base-sepolia");

This pattern avoids the failure mode where a mainnet contract address accidentally leaks into a testnet deployment (or vice versa) because a value was hard-coded somewhere deep in the code instead of resolved through one config source.

Check your understanding

  1. 1. Why centralize chain-specific values (RPC URL, contract address) in one config map?

  2. 2. What real risk does hard-coding a contract address deep in code create?

  3. 3. How should the active chain typically be selected in this pattern?