Networks and compatibility

For architects.

In short

CryptoRail works with EVM networks through standard Ethereum JSON-RPC over plain HTTP: public networks with a fee market, and permissioned consortium networks where gas is free. Several networks run side by side in one deployment, each declared in configuration with a profile that sets coherent defaults for fees, finality and stuck transactions. Compatibility is declared against the JSON-RPC specification, not against one node implementation, and proven on every change against Anvil and a Hyperledger Besu QBFT network, with sponsored execution against a self-hosted bundler. Public test networks were exercised by recorded manual runs. Chains outside the EVM family are not supported.

Networks, side by side

Every network is declared in the configuration with its chain id, a name, a profile and one or more node endpoints. There is no default network: every identity, contract, transaction, paymaster and subscription names the one it belongs to, so a record can never be sent to the wrong chain by omission.

flowchart LR
    CORE[CryptoRail] --> R[Provider router per network<br/>first healthy endpoint, lag-aware]
    R --> OWN[Your own nodes<br/>Besu, Geth, Nethermind, Erigon]
    R --> RMT[Nodes in your infrastructure]
    R --> PRV[Node providers]
    OWN --> N1[(A public network)]
    PRV --> N1
    RMT --> N2[(Your consortium network)]

The node behind an endpoint can be yours, a remote one in your infrastructure, or a provider’s; CryptoRail does not distinguish between them beyond configuration. HTTP is enough for full correctness; a WebSocket endpoint is optional and only speeds up the notice of new blocks. Each endpoint is asked which network it serves when the process starts, and one serving another chain is refused before anything is sent to it. Provider quirks, such as a maximum block range for log queries, are configured per endpoint and respected on CryptoRail’s side.

Several networks at once, each declared in configuration, with every record carrying the network it belongs to.

Works with your own nodes or a provider's, through standard Ethereum JSON-RPC over plain HTTP.

Every endpoint is asked which network it serves when the process starts; one that answers with another chain id is refused before anything is sent to it.

An endpoint counts as healthy only when it answers in time and its head is within a set number of blocks of the most advanced endpoint; rate and concurrency limits per endpoint, and provider limits such as the eth_getLogs block range, are respected on CryptoRail's side.

Several node endpoints per network: calls go to the first healthy one, an operation stays on the endpoint it started on, and a dead or lagging node is left aside without losing anything.

Network profiles

An operator configuring a consortium network should not have to know which of a dozen settings differ from a public chain. The profile fills them; any one can still be overridden on its own.

Settingpublicpermissioned
Gas policyEIP-1559 market (or, when set, a legacy market or a fixed price)Free: zero fee, no fee-market query
FinalityA number of blocks on top, or the node’s finalized blockInstant: deterministic finality
Stuck transactionReplaced at the same nonce with a higher fee, within the capRebroadcast, or a fresh zero-fee attempt at the same nonce
Priority tiersFee multipliers, caps and bump percentagesOnly the stuck thresholds matter
Gas balance neededYes, for every paying identityNo
flowchart LR
    C["chains[]: chainId, name, profile, endpoints"] --> P{profile}
    P -->|public| PU[EIP-1559 fees, finality after N blocks, fee bumps]
    P -->|permissioned| PE[free gas, instant finality, rebroadcast]
    PU --> O[overrides from the file, one setting at a time]
    PE --> O
    O --> V[validated at startup, every problem listed]

Two network profiles, public and permissioned, fill coherent defaults for fees, finality, stuck thresholds and priority tiers; every default can be overridden on its own.

Fees follow the network's gas policy (EIP-1559 market, legacy market, fixed price or free) and the sending identity's tier, never the caller's guess; an override is allowed only under the cap.

Each network declares its finality rule: a number of blocks on top, the node's finalized block, or instant on networks with deterministic finality, with coherent defaults for public and permissioned networks.

The life of a transaction explains how fees, stuck transactions and finality are handled inside the state machine.

Free-gas consortium networks

Permissioned networks on Hyperledger Besu with QBFT consensus are first-class, including those where gas costs nothing. On such a network a transaction is sent with a zero fee, no fee-market query is made, no identity needs a balance, and a caller’s fee override above zero is refused. Gas is still metered: estimation and the block gas limit apply as usual.

A stuck transaction is never “bumped” on a free network, because there is no fee to raise. If the node no longer knows it, it is rebroadcast unchanged; if the node still knows it, a fresh attempt at the same nonce replaces it, because an identical rebroadcast would be ignored. Nobody needs sponsorship where nobody pays, so a paymaster on a free-gas network is refused as a configuration error.

Permissioned consortium networks with free gas (Hyperledger Besu with QBFT): no fee market, no gas balance to keep topped up.

The requirement covers IBFT 2.0 as well as QBFT; only QBFT is tested.

What is tested, and against what

Every change to the code runs the integration suites against real nodes in CI. No test in CI spends funds or sends anything to a public network; the fork journeys only read a public network’s state at a pinned block. Anything that needs real funds is a manual procedure, recorded with its date when it is run.

flowchart TB
    PR[A change to the code] --> A[Anvil, Prague hardfork<br/>reorgs, drops, outages, process kills]
    PR --> B[Besu QBFT, four validators, zero gas price]
    PR --> AL[Alto bundler on Anvil<br/>canonical ERC-4337 contracts]
    PR --> N[Node.js 22 and 24]
    PR --> J[Journeys on the full stack in Docker]
    M[Manual, dated runs] --> PUB[Public test networks:<br/>Base Sepolia, Sepolia]
TargetVersionWhat runs there
Anvil (Foundry)Foundry’s stable release, installed fresh by CI (anvil 1.8.3 when last recorded), Prague hardforkThe pipeline, forced reorganisations, dropped transactions, a fault-injecting provider, process kills, the indexer, approvals, EIP-7702 onboarding
Hyperledger Besu26.8.1, four QBFT validators, zero minimum gas priceDeploy and call from an identity holding no ether, stuck handling without fees, the indexer, the tokenisation pack
Pimlico Alto bundlerPinned by image digestSponsored execution end to end: account deployment, both nonce spaces, the paymaster
ERC-4337 contracts on AnvilEntryPoint v0.7, Kernel v3.3, with the runtime bytes copied from mainnetThe same code hashes the production pins verify
Node.js22 and 24Every package’s tests
PostgreSQL17Storage, database roles, the deployment journeys
Forks of public networksEthereum mainnet and Base Sepolia at pinned blocksThe stablecoin, attestation and Aave packs against the real contracts

Foundry is not pinned to one version: CI takes the stable release, and a local run older than CI’s can disagree on genesis contracts of the Prague hardfork, which the contributor guide calls out. Besu does not host the ERC-4337 harness, so sponsored execution is tested on Anvil with Alto only.

On every change to the code, the integration suites run against Anvil on the Prague hardfork, against a four-validator Hyperledger Besu QBFT network with zero gas price, and, for sponsored execution, against the Alto bundler pinned by digest; no test in CI spends funds or sends anything to a public network.

Runs on Node.js 22 and 24, both tested on every change; the service ships as an OCI container image over PostgreSQL, tested on PostgreSQL 17.

Tested with a real wallet on a public test network, beyond the automated tests against a bundler.

The pinned contracts

Sponsored execution relies on contracts CryptoRail does not write: the canonical ERC-4337 EntryPoint, an audited account implementation and a verifying paymaster. Each is pinned per network by address and by the hash of its deployed code, and checked against the node when the process starts.

ContractVersionAddress
EntryPointeth-infinitism v0.7.00x0000000071727De22E5E9d8BAf0edAc6f37da032
AccountZeroDev Kernel v3.30xd6CEDDe84be40893d153Be9d467CD6aD37875b28
Account factoryKernel v3.30x2577507b78c2008Ff367261CB6285d44ba5eF2E9
Signing validatorKernel ECDSAValidator0x845ADb2C711129d4f3966735eD98a9F09fC4cE57
Approval validator, for on-chain approvalsKernel v3.3 WeightedECDSAValidator 0.0.30xeD89244160CfE273800B58b1B534031699dFeEEE
Paymastereth-infinitism v0.7.0 VerifyingPaymasterDeployed per deployment; its code hash is pinned

The code hashes were read from mainnet and cross-checked on Base and Arbitrum. Kernel’s hash differs from chain to chain, so on any other network it is read from that network’s node when the network is configured. Kernel v3.3 and the validators stand on the audits of their lineage, not on an audit of these exact bytes; that is recorded in the decision and is one of the items the external audit must cover.

The EntryPoint, account and validator contracts are pinned per network by address and code hash; a process whose node shows other code, or none, at a pinned address refuses to start, naming the network, the contract and both hashes.

Only the canonical EntryPoint and public account and paymaster contracts from audited lineages, pinned per network; no custom contract.

Where the pilot packs ran

Each pilot pack is tested on every change against a local network or a fork; the three that use contracts already on public networks were also run there, by hand, with the outcome recorded.

PackTested on every changeRun on a public test network
Stablecoin payoutsFork of Ethereum mainnet, real USDC and USDTBase Sepolia, Circle’s test USDC
TokenisationBesu QBFT, free gasNone: our own contract, by the owner’s decision
Customer programmesAnvil with Alto, a paymaster payingNone: our own contract, by the owner’s decision
AttestationsFork of Base Sepolia, the real Ethereum Attestation ServiceBase Sepolia
Treasury on Aave V3Fork of Ethereum mainnet, Aave V3 and ChainlinkSepolia, in test EURS while Aave’s test USDC is over its supply cap

Run on Base Sepolia, a public test network, with Circle's official test USDC: a payout confirmed, a payout to an unlisted address refused, a payout above the threshold held until the approver signed, the daily limit enforced, and an incoming payment delivered as a signed webhook.

Run on Base Sepolia, a public test network, against the network's own Ethereum Attestation Service: the schema registered once, an accreditation attested and delivered as a signed webhook, an attestation under another schema refused, a revocation held until the reviewer approved, each visible on EAS's explorer.

Run on Sepolia, a public test network, against Aave's own test market and Chainlink's live feeds, in test EURS while Aave's test USDC is over its supply cap: two supplies as ordered batches, the larger one held until the treasurer approved, an approval to another spender and a supply past the daily cap refused, and withdrawals of part and of everything, each visible on the explorer.

Proven on every change on a Hyperledger Besu QBFT network without fees: the asset deployed through CryptoRail by an identity holding no ether, every function called by name, an issuance above a threshold held until the issuer's board approved, the contract's refusals reported with their reason, and every event delivered to the back office as a signed webhook.

Run on public test networks by manual procedures recorded with their dates: a real wallet asking for sponsorship on Base Sepolia, the stablecoin and attestation packs on Base Sepolia, the Aave treasury pack on Sepolia.

The public runs earn their keep: the Aave run on Sepolia found a defect the fork journeys had not shown (a step of an ordered batch simulated before the step it depended on was mined), and it was fixed.

What it does not do

  • Blockchains outside the EVM family. Not supported
  • Private transactions on Besu (privacy groups). Not supported
  • It does not certify node clients. Any node that follows the Ethereum JSON-RPC specification is expected to work; Anvil and Besu are the ones tested.
  • It does not declare a public network “supported” by name. Public test networks were exercised by the manual runs listed above; a production network is configured, and its contract pins read from its node, when you add it.
  • It does not run sponsored execution on Besu or on any network without the canonical EntryPoint; on a free-gas network there is nothing to sponsor.
  • It does not use a newer EntryPoint yet. v0.8 and v0.9 exist; v0.7 is the version pinned, chosen because every audited account and bundler examined at the time of the decision supported it.
  • Load spread across healthy node endpoints: by design one endpoint is used at a time, in the configured order. Not supported

Evidence

Every claim above links to its evidence on the evidence page. The main ones:

SubjectRequirements and decisionsJourneys
Several networks, JSON-RPC, endpointsFR-CHN-01 to FR-CHN-07, FR-CHN-09, FR-CHN-14, FR-CHN-15J06, J39
Profiles, gas and finality policiesFR-CHN-12, FR-CHN-13, FR-CHN-16, FR-FIN-01J05, J06, J08
Free-gas Besu networksFR-CHN-08, FR-CHN-11J05, J17, J54
Tested targets, no funds in CINFR-INT-03, NFR-INT-05, NFR-INT-06, NFR-QA-02, NFR-QA-05J05, J31, J32
Pinned contractsNFR-SEC-09, FR-SPN-06, ADR-0003J32
Public test networksNFR-INT-06, FR-PLT-05, FR-PLT-24, FR-PLT-29J52, J58, J60