Matrix logo

Chains

The chain profile manager loads presets from JSON, supports custom registration, resolves chains by id or numeric chain-id, and manages the active chain selection.

Source file: internal/chains/chains.go

The chain profile manager loads presets from a JSON file, supports custom chain registration at runtime, and resolves chains by id or numeric chain-id. It manages the active chain selection for the daemon.


Design decisions

Preset + custom model

Chains come from two sources:

  • Presets: Loaded from chains/presets.json at startup. Each preset may reference an environment variable for its RPC URL (rpc_url_env), resolved lazily on access.
  • Custom: Registered at runtime via ChainRegister. Stored in memory only (not persisted to disk).

Numeric chain-id fallback

Callers (and agents) commonly pass the numeric EVM chain-id (e.g., "125") rather than the profile id (e.g., "paxeer-mainnet"). The Get method maps numeric input to the matching profile by iterating presets and custom chains, so deploy/call/simulate resolve either way.

Inline RPC resolution

The Resolve method accepts three sources: chainID, rpcURL, and activeID. When rpcURL is provided directly, it returns an anonymous inline chain profile without requiring registration. This supports ad-hoc chain targeting.

Thread safety

All reads acquire RLock, all writes acquire Lock. The resolveEnv helper lazily resolves rpc_url_env references on each access.


ChainProfile

type ChainProfile struct {
    ID         string   `json:"id"`
    Name       string   `json:"name"`
    RPCURL     string   `json:"rpc_url,omitempty"`
    RPCURLEnv  string   `json:"rpc_url_env,omitempty"`
    ChainID    uint64   `json:"chain_id"`
    Preset     string   `json:"preset,omitempty"`
    Explorer   string   `json:"explorer,omitempty"`
    Features   []string `json:"features,omitempty"`
    Active     bool     `json:"active,omitempty"`
}

Custom chains are registered with Features: []string{"debug_trace"} by default.


Operations

MethodDescription
New(presetsPath)Load presets from JSON file
SetProjectRoot(root)Store default project root for relative lookups
List(activeID)Return all chains with active marker
Get(id)Resolve by profile id or numeric chain-id
Register(req)Add/update a custom chain (requires id, chain_id, rpc_url)
Resolve(chainID, rpcURL, activeID)Pick chain from id, inline rpc, or active
AvailableIDs()Return chain ids with configured RPC

Default presets path

func DefaultPresetsPath(projectRoot string) string {
    return filepath.Join(projectRoot, "chains", "presets.json")
}

Modifying the chain manager

What to changeWhere
Add chain fieldpkg/types/chain.go - ChainProfile
Change preset formatinternal/chains/chains.go - presetsFile struct
Add chain validationinternal/chains/chains.go - Register method
Persist custom chainsinternal/chains/chains.go - add file write on Register