EnvLoader is the singleton that reads process.env, optionally loads .env / ../.env via dotenv, and builds partial ClientConfig objects for a single ApiType. CantonRuntime calls EnvLoader.getConfig when an API’s ApiConfig was not supplied explicitly on ClientConfig.
Use it when writing tooling or tests that must introspect what would load from disk without constructing a full Canton instance, or when debugging missing-variable failures.
import { EnvLoader, ApiTypes } from '@fairmint/canton-node-sdk';
Example
import { EnvLoader, ApiTypes } from '@fairmint/canton-node-sdk';
const ledgerOnly = EnvLoader.getConfig(ApiTypes.LEDGER_JSON_API, {
network: 'devnet',
provider: '5n',
});
console.log(ledgerOnly.network, ledgerOnly.apis?.LEDGER_JSON_API?.apiUrl);
const summary = EnvLoader.getConfigSummary(ApiTypes.VALIDATOR_API, {
network: 'localnet',
provider: 'app-provider',
});
console.log(summary.missingVars);
.env discovery
On module load, dotenv runs twice in order:
./.envin the current working directory.- If that fails and
../.envexists, load../.env.
There is no deeper upward search. Paths are relative to the process cwd when the SDK bundle is evaluated.
getConfig behavior
EnvLoader.getConfig(apiType, options?):
- Resolves
networkfromoptions.networkorCANTON_CURRENT_NETWORK(viagetCurrentNetwork()). - Resolves
providerfromoptions.provider, or defaultslocalnetto'app-provider'if unset, or readsCANTON_CURRENT_PROVIDERfor other networks (required there). - Reads
authUrlviagetAuthUrl(network, provider)— forlocalnetwithapp-provider/app-user, built-in cn-quickstart URLs apply when env is empty. - Loads
ApiConfigvia internalloadApiConfig. Forlocalnet, if both URI and client id env vars are absent, cn-quickstart defaults apply (getLocalnetDefaults) with fixed ports and client credentials.
Throws ConfigurationError when provider cannot be determined, when required API env keys are missing for non-default paths, or when getAuthUrl cannot resolve a URL.
Environment variable matrix
Placeholder: <NET> = uppercase network (DEVNET, MAINNET, …), <PROV> = uppercase provider (5N, APP-PROVIDER, …), <API> = LEDGER_JSON_API | VALIDATOR_API | SCAN_API.
Selection (all networks)
| Variable | Role |
|---|---|
CANTON_CURRENT_NETWORK | Required for paths that call getCurrentNetwork() without an override: devnet, testnet, mainnet, localnet, staging. |
CANTON_CURRENT_PROVIDER | Required when provider is not passed and network is not using the localnet default-provider shortcut. |
Per network + provider (shared)
| Variable | Role |
|---|---|
CANTON_<NET>_<PROV>_AUTH_URL | OAuth2 token endpoint. Localnet may fall back to baked-in URLs for app-provider / app-user. |
CANTON_<NET>_<PROV>_PARTY_ID | Required when loading full API config from env (used when merging party onto ApiConfig). |
CANTON_<NET>_<PROV>_USER_ID | Optional Daml user id merged onto ApiConfig. |
CANTON_<NET>_<PROV>_MANAGED_PARTIES | Comma-separated extra parties; trimmed and split. |
Per API (<API> as above)
| Variable | Role |
|---|---|
CANTON_<NET>_<PROV>_<API>_URI | Base URL for that HTTP client. |
CANTON_<NET>_<PROV>_<API>_CLIENT_ID | OAuth client id. |
CANTON_<NET>_<PROV>_<API>_CLIENT_SECRET | Enables client_credentials grant when present with client id. |
CANTON_<NET>_<PROV>_<API>_USERNAME | Together with _PASSWORD, selects password grant when secret is absent. |
CANTON_<NET>_<PROV>_<API>_PASSWORD | Password grant companion. |
Grant priority inside loadApiConfig: CLIENT_SECRET → client_credentials; else if username + password → password; else client_credentials with no secret (may warn downstream depending on IdP).
Network-level utilities (non-provider-scoped)
Used by getConfigSummary and helpers such as Amulet fixtures:
| Variable | Role |
|---|---|
CANTON_<NET>_DATABASE_URL | Database URL for that network. |
CANTON_WALLET_TEMPLATE_ID_<NET> | Template id helper env. |
CANTON_PREAPPROVAL_TEMPLATE_ID_<NET> | Template id helper env. |
CANTON_AMULET_RULES_CONTRACT_ID_<NET> | Contract id helper env. |
CANTON_VALIDATOR_WALLET_APP_INSTALL_CONTRACT_ID_<NET> | Contract id helper env. |
Special API URI
| Variable | Role |
|---|---|
CANTON_<NET>_LIGHTHOUSE_API_URI | Resolved without provider segment in getApiUri('LIGHTHOUSE_API', ...). |
Debugging / logging env
| Variable | Role |
|---|---|
NODE_ENV | Must be development, production, or test if read via getNodeEnv(). |
FAIRMINT_AUTH_DEBUG | When truthy, emits structured [FAIRMINT_AUTH_DEBUG] lines for token lifecycle (requires oauth2-type auth in manager). |
CANTON_DEBUG | Interpreted by runtime as verbose/client logging toggle. |
DISABLE_FILE_LOGGER | Disables FileLogger file writes when truthy. |
FILE_LOGGER_DIR | Overrides default log directory for FileLogger. |
API surface
EnvLoader.getInstance(options?)— singleton; optionalcurrentNetwork/currentProviderstick on the instance.EnvLoader.resetInstance()— clears singleton (tests).EnvLoader.getConfig(apiType, options?)— returnsClientConfigwith a single populatedapis[apiType]plusnetwork,provider,authUrl.EnvLoader.getConfigSummary(apiType, options?)— returns{ network, provider, envVars, missingVars }for debugging.
Instance methods (getAuthUrl, getPartyId, getApiUri, …) read live process.env.
Errors and pitfalls
- Stale singleton:
getInstancemerges options into an existing instance — tests should callresetInstance()between cases. getPartyIdstrictness: Loading API config from env callsgetPartyId; missingPARTY_IDthrowsConfigurationError. Localnet defaults path can return before that branch when no URI/client id env is set.- Provider required off localnet: Without
CANTON_CURRENT_PROVIDERoroptions.provider,getConfigthrows for non-localnet networks.
See also
- CantonConfig — explicit overrides instead of env.
- AuthenticationManager — how resolved
AuthConfigis consumed. - Quickstart — practical
.envexamples. - Reference home — covers utilities and higher-level helpers that consume configured clients.
Source
src/core/config/EnvLoader.ts on GitHub.