Environment and reference

Every variable the Solana chain module reads, the ones that only affect metadata, the ones read by nothing, plus the chain registry values, database rows and admin endpoints this product touches.

3 min readUpdated 6 August 2026environment, reference, endpoints, permissions, chain-registry

Everything on this page is read from the project root .env, the database, or the chain registry. None of the Solana variables appear in .env.example, so on a fresh install every one of them is unset until you add it.

Ecosystem's own environment reference covers the vault, ScyllaDB and every other chain. This page covers only what Solana touches.

Solana variables

Cluster selector. "mainnet" resolves to mainnet-beta and "testnet" to testnet. Every other value — unset, misspelled, or the plausible-looking "mainnet-beta" — silently resolves to devnet. Requires a backend restart to take effect.
A separate variable that selects nothing. It is stamped into the wallet address record when an address is generated, and is read by nothing afterwards. Keep it equal to SOL_NETWORK or the stored record misreports the cluster.
Read only by the admin token-deployment cost estimate, which queries the rent-exempt minimum for a 165-byte token account. The runtime Solana service ignores it and always uses the public cluster endpoint. It also defaults to mainnet regardless of SOL_NETWORK, so on a testnet install the estimate is a mainnet figure.

Read by nothing that matters

Key Reality
SOL_MAINNET_RPC, SOL_TESTNET_RPC, SOL_DEVNET_RPC The Solana chain service never reads any of them. The requirements report labels them "DISPLAY-ONLY" for that reason — the Ecosystem overview badge only checks whether one is present to decide how to draw the chain. That label is true of this product and no longer true of the install: if the Swap addon is present, resolveServerRpc in dex/utils/chains.ts takes SOL_<NETWORK>_RPC as the last rung of its RPC ladder, under the chain row's override and APP_DEX_RPC_SOLANA. So one of these can be carrying Swap traffic while still carrying none of this chain's.

SolanaService in backend/src/blockchains/sol.ts builds its Connection in the constructor from clusterApiUrl(), fed by SOL_NETWORK alone — "mainnet" becomes mainnet-beta, "testnet" becomes testnet, and every other value falls through to devnet. Neither SOLANA_RPC_URL nor any SOL_*_RPC value is read there, so pointing one at a paid provider moves no traffic at all: deposits, withdrawals and balance reads keep going to the public cluster, and the rate limits you were trying to escape are unchanged.

The one that costs money is SOL_NETWORK="mainnet-beta". It looks like the correct cluster name, it is not one of the two accepted values, and nothing logs the fall-through in the request path — the install simply runs on devnet while every screen looks healthy.

The requirements report labels these explicitly, which is the fastest way to confirm the list has not changed under you.

Ecosystem variables that shape Solana behaviour

These are not Solana-specific, but Solana is the chain most likely to make you reach for them. See Network and RPC for when.

Set to "false" to disable the background deposit scanner for every chain. Solana deposits then depend on a live deposit-page session being open.
Solana override for the background scanner's pace, in address scans per second. The built-in default is deliberately conservative because the public cluster quota is shared with every other anonymous client.
Fallback scanner rate for any chain without its own override.
How often each address in the working set is re-scanned, in milliseconds.
How long an address stays in the background working set after its last deposit-page visit, in milliseconds. The default is 72 hours; lowering it is usually the safest way to cut Solana RPC load.
How long the scanner naps when nothing is due, in milliseconds.

The vault variables — ENCRYPTED_ENCRYPTION_KEY and ENCRYPTION_KEY_PASSPHRASE — are Ecosystem's, and every Solana private key on the install depends on them. They are documented under Master wallets and the vault; do not edit either by hand.

Chain registry values

These are compiled into the platform, not configurable.

Property Value
Chain symbol SOL
Display name Solana
Native currency SOL
Decimals 9
Token standard SPL
Mainnet explorer https://explorer.solana.com
Testnet explorer https://explorer.solana.com?cluster=testnet
Devnet explorer https://explorer.solana.com?cluster=devnet
Configured confirmation depth none — pending Solana deposits are credited on the next verification pass
Custodial contracts never; Solana is a non-custodial chain in Ecosystem's model
Network filtering of token rows none; Solana is network-agnostic, so a token's network label is never checked

Contract types behave as follows on this chain:

contractType Meaning on Solana
NATIVE SOL itself. Deposits and withdrawals use the customer's own address, and the network fee comes out of the withdrawn balance
PERMIT An SPL token. Deposits land in the customer's associated token account; withdrawals are signed by the customer with the master wallet as fee payer
NO_PERMIT Ignored. The deposit path uses the customer's own address anyway rather than looking for a custodial contract that cannot exist here

Where the data lives

Record What it holds
ecosystem_blockchain The seeded Solana row: chain = "SOL", productId = "54514052", status — the enable toggle
lic/54514052.lic The activated licence file, encrypted and machine-bound. Its presence is checked at the toggle and again at service construction, cached for five minutes
ecosystem_master_wallet One row for chain = "SOL". data is the encrypted keypair blob and is the only persisted copy
wallet.address JSON map on the ECO wallet. The SOL entry carries the address, the network label from SOLANA_NETWORK, and a display balance
wallet_data One row per wallet on chain = "SOL", holding the encrypted mnemonic, derivation path and secret key. index is always 0 on this chain and is not a derivation index
ecosystem_token The token definition. On Solana, contract is the SPL mint address and is used verbatim to build deposit subscriptions
transaction Deposits and withdrawals. trxId is the Solana transaction signature

Admin endpoints

Every one of these is an Ecosystem endpoint that Solana participates in; there are no Solana-only routes.

Full per-chain requirements report — the variables the runtime reads, whether each is set, and the non-environment prerequisites
Runs live read-only probes against the resolved cluster and returns readiness per platform flow
Reads one seeded blockchain row
Enables or disables a seeded blockchain by product ID. Enabling returns 403 when the licence file is absent.
Lists the chains available for token and wallet creation. Solana appears only once its row is enabled.
Master wallet balance plus the estimated token deployment cost. For Solana the estimate is the rent-exempt minimum for a 165-byte token account.
Generates, encrypts and stores a master wallet for a chain. One per chain — a second attempt returns 409.
Lists master wallets, and refreshes each balance as a side effect. This is the route that reads the Solana balance — getEcosystemMasterWalletBalance in wallet/master/utils.ts, which has the SOL branch, cached in Redis for one minute.
Refreshes every master wallet balance — except Solana's. It handles UTXO chains directly and sends everything else through getProvider, which is EVM-only, and caches for five minutes.
Deploys an SPL mint signed by the master wallet, then queues the initial supply minting as a background task
Holders of one ecosystem token. It cannot work on Solana — see below.
User-facing withdrawal submission. Rate-limited per user as a money-movement endpoint.

GET /api/admin/ecosystem/wallet/master/balance carries its own copy of the balance refresh, and that copy knows about UTXO chains and getProvider() and nothing else. getProvider() builds an ethers JSON-RPC provider from chainConfigs, and it cannot produce one for SOL at all: it wants a SOL_<NETWORK>_RPC variable and then a chainId, and the SOL entry carries explorer URLs and no chainId. Which of the two errors you find in the log depends only on how far it got — on a normal install, where no SOL_*_RPC is set because nothing on this chain reads one, it throws first on the missing variable, "Environment variable SOL_MAINNET_RPC is not set"; set that variable and it reaches the second, "Chain ID not found for SOL on mainnet". Either way the error is caught, logged to the console, and the row keeps its old balance. The Solana branch — and the one-minute cache — live in getEcosystemMasterWalletBalance, which only the list route calls.

The token-holders view is worse, because it has no working version at all. fetchTokenHolders in ecosystem/utils/tokens.ts builds one URL shape for every chain: https://<registry explorer>/api?module=account&action=tokentx&…, which is the Etherscan family's API. The registry explorer value for SOL is already a full URL, https://explorer.solana.com, so the string it fetches begins https://https:// — the request is malformed before it is even pointed at an API Solana does not serve. Expect a 500 reading "Failed to fetch token holders", or, if you have set no SOL_EXPLORER_API_KEY or ETHERSCAN_API_KEY, an earlier 500 complaining about the missing key. No configuration fixes either one; read holders from a Solana explorer or an indexer instead.

Permission keys follow the platform-wide convention and are granted per role. See Ecosystem: admin console for the full permission list and where each screen lives.