diff --git a/src/lib/config.ts b/src/lib/config.ts index 452ba9829..185ad25b8 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -100,21 +100,50 @@ function getMetaTxApiKey(envConfig: ProtocolConfig) { return apiKey; } -export const envConfigsFilteredByEnv: ProtocolConfig[] = getEnvConfigs(envName); +// Chains the dapp exposes, per environment. getEnvConfigs() returns every chain +// the SDK supports for the environment (Polygon, Optimism and Arbitrum +// included); the dapp deliberately offers a subset in the network selector. +// Chain ids are hardcoded rather than imported from lib/constants/chains to +// avoid a circular import (that module reads envChainIds from here). +const supportedChainIdsPerEnv: Record = { + local: [31337], // Local Hardhat + testing: [11155111, 84532], // Sepolia, Base Sepolia + staging: [11155111, 84532], // Sepolia, Base Sepolia + production: [1, 8453] // Ethereum, Base +}; + +// envName is an unchecked cast of an env var, so at runtime it can be any +// string: look the chain ids up defensively and fail with a message that names +// the accepted values, rather than letting an unrelated error surface further +// down. +const supportedChainIds: number[] | undefined = + supportedChainIdsPerEnv[envName]; +if (!supportedChainIds) { + throw new Error( + `REACT_APP_ENV_NAME is "${envName}", expected one of ${Object.keys( + supportedChainIdsPerEnv + ).join(", ")}` + ); +} + +export const envConfigsFilteredByEnv: ProtocolConfig[] = getEnvConfigs( + envName +).filter((envConf) => supportedChainIds.includes(envConf.chainId)); if (!envConfigsFilteredByEnv.length) { // Fail fast with context: everything below assumes at least one config, and // without this the app would crash later on an undefined defaultEnvConfig. - throw new Error(`No protocol config is available for envName ${envName}`); + throw new Error( + `No protocol config is available for envName ${envName} and chain ids ${supportedChainIds.join( + ", " + )}` + ); } export const envChainIds = envConfigsFilteredByEnv.map( (envConf) => envConf.chainId ); -// Chain the dapp starts on, per environment. getEnvConfigs() lists the Polygon -// config first, so without this the app would default to Polygon (Amoy on -// testing/staging). Chain ids are hardcoded rather than imported from -// lib/constants/chains to avoid a circular import (that module reads -// envChainIds from here). +// Chain the dapp starts on, per environment. Pinned explicitly rather than +// relying on whichever config getEnvConfigs() happens to return first. const defaultChainIdPerEnv: Record = { local: 31337, // Local Hardhat testing: 84532, // Base Sepolia