Networks
How a DALP instance's served-network list is configured, validated, and extended, for EVM networks.
A DALP InstanceA DALP Instance is one self-contained copy of the platform, deployed inside a boundary you choose and connected to ledger networks you approve.Read the concept connects to the EVM networks in its networks configuration. Each entry defines a built-in chain or a custom chain. The platform validates this configuration before it serves traffic. Configure the baseline during deployment, or use the runtime catalog to add and edit networks without a redeployment.
Deployment values set the default network. Runtime catalog writes preserve that default and reject changes that would disconnect active systems or invalidate an RPC pool.
Network shapes
| Shape | Discriminator | Use |
|---|---|---|
| Built-in EVM | chain (a viem chain alias, for example sepolia) | A public or well-known EVM chain; inherits its name, native currency, and block explorer from viem |
| Custom EVM | chainId + name | A private or unlisted EVM chain, defined by hand |
Each built-in or custom EVM entry also includes contract addresses, RPC connection settings, indexing settings, and finality settings.
Choose a built-in entry when viem defines the chain: it supplies the name, native currency, and block explorer. Choose a custom entry for a private or unlisted EVM chain, and supply those fields yourself. Both shapes require connection and finality settings.
Validation at boot
The instance rejects the networks section at startup, before it serves traffic, when any of these hold:
- The section is empty. It needs at least one network.
- No EVM network sets
default: true. The boot failure here isExactly one EVM network must have 'default: true'. - More than one EVM network sets
default: true. This boot failure names every offending network:Multiple EVM networks marked as default: <names>. - A network that sets
default: truedoes not also setenabled: true.
A chain ID can repeat across two entries on purpose. That lets you rotate an RPC provider or promote a secondary alias to primary by keeping the old entry disabled beside its enabled replacement, and lets a primary and a fallback RPC alias share one chain ID.
Finality
Every EVM network declares supportsFinalizedTag. When the chain exposes an RPC finalized block tag, the indexer uses it directly. When it does not, the network must set an explicit finalityConfirmations value of 1 or more, so the indexer derives the finalized block as chainHead - finalityConfirmations. The instance only accepts a network with supportsFinalizedTag: false and no confirmations set when the entry also declares a test mode. A production chain configured that way fails validation, and the error names the missing setting: production chains must set finalityConfirmations to 1 or more to preserve a pruning safety margin.
Per-network indexing
An EVM entry's indexing block tunes how the indexer reads that chain. Its runtime knobs carry schema defaults and are editable on a network the runtime catalog holds: chunkSize, minChunkSize, and maxChunkSize, which bound the adaptive read range; livePollingIntervalMs, the chain's block time, which paces live head polls; and verifyBlockReceipts, which re-checks a block a log fetch flagged as possibly incomplete. livePollingIntervalMs is the one with no default of its own. With it set, the indexer times each block from the check that first saw it, waits until one second before the next is due, then checks every second until it lands, so a 12-second chain costs about two head reads per block instead of twelve. Omit it and the indexer checks the head every second. While the indexer is behind the head it reads the next range at once, whatever the setting. The indexer reads the value when it starts, so an edit takes effect after the next indexer restart.
indexing.startBlock is the exception in that block. It is a deployment-time value the platform-admin catalog refuses, and it names the lowest block the indexer may start scanning at on a chain it has not read yet, for a chain whose Directory deploy height is already known. With the key absent, the DALP InstanceA DALP Instance is one self-contained copy of the platform, deployed inside a boundary you choose and connected to ledger networks you approve.Read the concept resolves that height exactly: the earliest registered contract, else the Directory row, else block 0. On a long public chain, block 0 means walking millions of blocks before the first event the deployment cares about.
Two rules bound what it can do:
- A registered contract always wins. The floor fills the case with no rows to anchor on, and never raises the scan above a contract the indexer already knows about, because a contract that registers while the chain is catching up has to be inside the next range read.
- It only decides where a first pass starts. While a chain catches up, the indexer widens its reads and jumps over regions it has proven empty. Setting this key does not make an existing catch-up faster.
When the floor is safe, and when it is not
Set it only where the deployment block is known from the chain's own deploy record: a non-production chain, or a public testnet whose Directory you deployed and whose deployment block you can read back.
Leave it unset, or set it to a block at or below the Directory's deployment, on any chain where the indexer has to find the deployment itself. That discovery reads the Directory's own deployment and registration events to find the contracts seeded there and everything they deploy afterwards, and the same history is what bounds which implementations the indexer may still trust. The indexer never revisits a range it has passed, so a floor above those events is a floor above the discovery.
Failure modes at boot
| Symptom | Cause | Fix |
|---|---|---|
| Instance fails to start; error names "Multiple EVM networks marked as default" | Two or more EVM entries set default: true. | Set default: true on exactly one EVM network, and default: false (or omit it) on the rest. |
| Instance fails to start; error mentions a pruning safety margin | An EVM network sets supportsFinalizedTag: false with no finalityConfirmations, outside test mode. | Set finalityConfirmations to at least 1. |
Instance fails to start; the networks section is rejected as empty | No networks are declared at all. | Declare at least one network; the base Helm chart's own values ship one you can start from. |
A default: true network never takes effect | The same entry does not also set enabled: true. A default must be enabled. | Set enabled: true on the default network, or move default: true to a network that is already enabled. |
What ships enabled by default
The Helm chart's base values declare exactly one network, keyed default, and nothing else. It points at the platform's own bundled ledger service, arrives enabled: true and default: true, and runs a QBFT chain: consensus finalizes instantly, so it sets supportsFinalizedTag: false with finalityConfirmations: 1. The one-block offset satisfies the configuration requirement for a production chain without a finalized tag. It is separate from the consensus finality that QBFT provides.
The base chart includes one EVM network. Three things need overriding before a real deployment goes live on its own chain:
| Override | Why the shipped value is wrong for a real deployment | What goes wrong if you don't override it |
|---|---|---|
| Chain ID, name, and RPC URLs | They point at the chart's own in-cluster RPC service, correct only for the reference topology. | The deployment keeps dialing the bundled service instead of the chain you actually operate. |
rpc.allowPrivateUpstreams | It ships true only because the shipped network's RPC pool points at the bundled Besu service on cluster-private DNS, and the SSRF guard has to allow that address. Deploy-time only: the admin write surface refuses it for the same reason it refuses default. | Repoint the network at a chain you operate elsewhere and leave it true, and the SSRF guard keeps permitting private-address upstreams wider than that chain needs. Set it false while the pool still targets the bundled in-cluster service, and the guard refuses to dial it, so the deployment cannot reach its own default network. |
default flag, the moment you add a second EVM network | The base chart already puts default: true on the one network it ships. | Add another EVM entry without moving the flag first, and the boot check above rejects the release with "Multiple EVM networks marked as default". |
An environment overlay can add another EVM network. The merged configuration must still satisfy the startup validation rules.
Gas-charging networks
Two configuration values behave differently on a network that charges gas than on the QBFT chain the base chart ships, which charges no gas, and neither failure is obvious from a dashboard.
bundler.priorityFeeBaseFeeMultiplierbounds the tip a smart-account operation may carry, relative to the network's base fee, withbundler.minPriorityFeeas the absolute floor. Without a bound, a network on which the platform is the dominant sender can drive its own fee suggestion far above the base fee until the sponsorship ceiling rejects the operation. The multiplier defaults to 3 and the floor defaults to 0. A negligible base fee makes the relative bound negligible too. RaiseminPriorityFeeon those chains to keep the bound effective.bundler.callGasBufferNonDeploygives ordinary (non-deploying) operations headroom on top of the protocol's own gas-forwarding correction, defaulting to 1.3125 (a 1.333x total margin measured to clear a real out-of-gas failure). Set too low, the transaction is included while the work inside it runs out of gas: the operation looks mined and did nothing.
Confirm both against the target network before it carries production traffic. The symptom in each case is an operation that never completes, with no error at the point of submission.
A chain's own fee suggestion is an input, not an instruction. The backend caps
the tip a UserOperation may carry at
max(minPriorityFee, baseFee * priorityFeeBaseFeeMultiplier) before the
operation is hashed and signed, because the fee fields are inputs to that hash and
cannot be corrected afterwards. The bound applies only to operations the platform
signs: an externally-signed operation whose tip is under the configured floor is
rejected rather than adjusted, since raising it would invalidate the signature
that covers it.
Operators own two consequences: a tip ceiling that is too tight leaves operations uncompetitive during genuine congestion, and one that is too loose re-admits the runaway. Both are visible as operations that never reach inclusion, so pair any change with broadcast-latency and inclusion monitoring.
Per-network gas settings
The two bundler settings above bound what a smart-account operation may pay. A
separate per-network gas block decides what the platform asks an operator to
deposit when a wallet cannot pay at all, how long that request stays open, and
whether the chain charges for gas in the first place. Gas settings
is the reference for every key, its unit, its accepted range, and its default.
Each key resolves through four layers, and the first layer that names a field decides it:
- The network's own settings, saved through the platform-admin catalogue.
- The
gasblock on the network entry in the deployment values. - The
chainGasDefaultssection, keyed by chain ID, carrying calibrated figures for chains the platform has already measured. Six chain IDs ship there, so a deployment that adds one of them needs no entry of its own. - The built-in defaults.
Resolution is per field. A network that sets one value keeps every other value live against the layer beneath it, so a later calibration change still reaches that network.
zeroGas is the exception to that ladder. Left unset by every layer, it is not
defaulted at all: the platform probes the chain once and caches the answer. When
the probe cannot reach an answer, the chain is treated as one that charges gas,
because a chain wrongly treated as free puts every write back on the path where
an unfunded transaction fails at the node with no request raised and no wallet
named. The cost of the opposite error is one funding request an operator
declines.
Adding or changing a network
The served-network list has two write paths, and they carry different consequences.
The values you pass to the Helm chart (which mirror config.yml) fix the baseline in networks at deploy time. Changing the baseline needs a helm upgrade and a restart of the affected components; it is a change-controlled deployment event like any other configuration change, reviewed the way you review the rest of the release.
At startup, the platform adds each baseline network that its stored network catalog does not hold yet. It does not rewrite a network that the catalog already holds, so an administrator's runtime changes survive a release. To apply a changed baseline entry to a network that the catalog already holds, revert that network in the platform-admin network catalog. A revert puts back the entry from the current baseline.
A platform administrator can also register or edit a network at runtime, with no redeploy, through the platform-admin network catalog. Saving here writes only the network's definition: its chain ID or viem alias, name, policy settings, and its gas block, which decides what the platform asks an operator to deposit on that chain and whether it treats the chain as charging gas at all. RPC endpoints and their credentials belong to a separate write, the network's own RPC upstream pool, which encrypts them and probes them live before the network can serve traffic. This path exists for changing a network without a full release cycle, and it carries its own guardrails, checked in this order before a write is accepted:
- Optimistic-concurrency preconditions: the write names the catalog version it expects to change, and a concurrent change elsewhere fails the write rather than silently overwriting it.
- Registry-schema decode: the new entry itself must parse as a valid network definition.
- Prospective merged-catalog validation: the catalog as it would exist after the write, not just the new entry alone, must still satisfy the same boot-time rules described above, such as exactly one EVM default.
- Stranding refusal: a write that would leave a chain ID with no enabled network, while an organization has active systems deployed on that chain ID, is refused outright, naming the stranded chain IDs. You cannot disable or remove a network something is actively using through this path.
- Pool-hygiene refusal: moving a network's
chainIdwhile RPC upstream pools already exist for that network's name is refused. A runtime edit cannot quietly repoint an existing name at a different chain out from under configured RPC pools.
The runtime catalog cannot change the default network. The write schema rejects a default field, so changing the default requires a Helm upgrade. After the upgrade, revert the old default network and the new one in the platform-admin network catalog, so that the stored catalog takes the new default. RPC endpoints and credentials use the separate upstream pool.
How reversible a delete is depends on how the network got there. An entry that also has a deploy-time baseline reverts to that baseline rather than disappearing, and its RPC pool survives. An entry that exists only at runtime, with no baseline, is removed fully, and its RPC pool is cleared with it. Either way, the stranding refusal above applies first: an in-use network cannot be deleted regardless of which case it falls into.
That stranding protection is a runtime-catalog guardrail, not a boot-time rule: the checks the instance runs when it starts (validating one EVM default, a non-empty list) never ask whether an organization has active systems on the chain you are changing. A Helm upgrade that disables or removes a network carries no equivalent check. Confirming that nothing live still depends on a chain before taking it out in a release is the operator's responsibility; the platform will not stop you the way it stops a runtime-catalog write.
Frequently asked questions
Can one instance run more than two networks?
Yes. The network list has no fixed size, but it must contain exactly one enabled EVM default. Entries can describe different chains or RPC aliases for the same chain. Each entry needs connection, indexing, and finality settings.
Can I remove the base chart's default network entirely?
Only by replacing it, not by deleting it outright. The boot check requires exactly one EVM network with default: true, so a values file with zero EVM entries, or zero marked default, fails validation before the instance serves traffic. To move off the shipped network, add your own EVM entry, set default: true on it, and set default: false (or omit it) on the one the chart shipped, in the same Helm upgrade.
I registered a network through the runtime catalog. Can I later move it to a different chain ID?
Not while an RPC upstream pool already exists for that network's name. The pool-hygiene guardrail refuses a write that would repoint an existing name at a different chainId, because configured RPC pools are keyed by name and a silent repoint would send traffic meant for one chain to another. Remove the network and add it again under the new chain ID instead, subject to the stranding refusal if anything is still actively using it.
Security and compliance posture
The layered control model an operator reviews before accepting a DALP instance, from authentication and authorization through custody, compliance, and networks.
Gas settings
The per-network gas keys a DALP instance reads before it asks for funds, the layer order that decides each one, and the chains that ship calibrated.