Skip to content
Lattice

IChainRegistry

Git Source

Title: IChainRegistry

Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)

Admin / read surface of the Lattice chain registry: a generic ERC-7201 registry of chains keyed by their ERC-7930 chain identity (chainKey = keccak256(abi.encodePacked(chainType, chainReference)), so EVM and non-EVM chains are supported identically), an informational native-id index per bridge ecosystem, a per-chain gateway COVERAGE map (which local gateway adapters can reach the chain, and whether only via an intermediate hub), and addEvmChain — the one-action admin fan-out that registers an EVM chain and pushes its config into every enabled gateway adapter in a single call.

COVERAGE AWARENESS, NOT ROUTING (issue #77 Q5): the registry is the config single-source-of-truth and the authority for M-of-N coverage math, but every adapter keeps its own cheap hot-path maps — the registry NEVER sits in any adapter send path. Enforcement is opt-in on the OpenBridge side (setMinDirectCoverage); hub-routed coverage (e.g. ZetaChain reaching connected chains only via the ZEVM hub) NEVER counts toward DIRECT coverage. Chains cannot be removed in v1 (YAGNI — a chain identity is permanent; coverage entries and native ids stay mutable).

Functions

chainKeyEvm

The chain key of an EVM chain: eip-155 chainType (0x0000) + the canonical minimal big-endian chain reference (exactly the InteroperableAddress.formatEvmV1 encoding — no leading zeros).

function chainKeyEvm(uint256 chainId) external pure returns (bytes32);

Parameters

NameTypeDescription
chainIduint256

Returns

NameTypeDescription
<none>bytes32

chainKeyOf

The chain key of any ERC-7930 chain identity: keccak256(abi.encodePacked(chainType, chainReference)).

function chainKeyOf(bytes2 chainType, bytes calldata chainReference) external pure returns (bytes32);

Parameters

NameTypeDescription
chainTypebytes2
chainReferencebytes

Returns

NameTypeDescription
<none>bytes32

isRegistered

Whether chainKey is a registered chain identity.

function isRegistered(bytes32 chainKey) external view returns (bool);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
<none>bool

chainInfoOf

The registered ERC-7930 identity of chainKey (evmChainId is 0 for non-EVM chains).

function chainInfoOf(bytes32 chainKey)
        external
        view
        returns (bytes2 chainType, bytes memory chainReference, uint256 evmChainId);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
chainTypebytes2
chainReferencebytes
evmChainIduint256

nativeIdsOf

The informational native bridge-ecosystem ids of chainKey.

function nativeIdsOf(bytes32 chainKey) external view returns (NativeIds memory);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
<none>NativeIds

gatewaysOf

The gateway adapters recorded as covering chainKey (direct AND hub-routed).

function gatewaysOf(bytes32 chainKey) external view returns (address[] memory);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
<none>address[]

coverageOf

The total number of gateways covering chainKey (direct + hub-routed).

function coverageOf(bytes32 chainKey) external view returns (uint256);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
<none>uint256

directCoverageOf

The number of gateways covering chainKey DIRECTLY (hub-routed coverage never counts).

O(n) over the coverage set — admin-bounded small (one entry per local gateway adapter).

function directCoverageOf(bytes32 chainKey) external view returns (uint256);

Parameters

NameTypeDescription
chainKeybytes32

Returns

NameTypeDescription
<none>uint256

registerChain

Registers a chain identity (EVM or non-EVM). Admin only. Reverts ChainRegistryAlreadyRegistered on re-register — chain identities are permanent in v1.

function registerChain(bytes2 chainType, bytes calldata chainReference, uint256 evmChainId) external;

Parameters

NameTypeDescription
chainTypebytes2The ERC-7930 chain type (0x0000 = eip-155).
chainReferencebytesThe ERC-7930 chain reference (for EVM chains use the canonical minimal
big-endian chainId encoding, or use addEvmChain which builds it).
evmChainIduint256The EVM chainId (informational; 0 for non-EVM chains).

setNativeIds

Sets the informational native ids of a registered chain. Admin only.

function setNativeIds(bytes32 chainKey, NativeIds calldata ids) external;

Parameters

NameTypeDescription
chainKeybytes32
idsNativeIds

setGatewayCoverage

Records (or clears) gateway's coverage of a registered chain. Admin only.

function setGatewayCoverage(bytes32 chainKey, address gateway, bool covered, bool hubRouted) external;

Parameters

NameTypeDescription
chainKeybytes32The registered chain key.
gatewayaddressThe local gateway adapter (non-zero).
coveredboolTrue to record coverage, false to remove it.
hubRoutedboolTrue when the gateway reaches the chain only via an intermediate hub (e.g. the
ZetaChain ZEVM hub) — hub-routed coverage never counts toward directCoverageOf.

addEvmChain

ONE structured admin action that adds an EVM chain everywhere: registers the chain identity (eip-155 + canonical minimal big-endian reference), records the native ids declared by the enabled sections, then fans the per-adapter config out into every ENABLED gateway adapter's own ERC-7201 storage via direct internal lib calls (msg.sender stays the admin — never external self-calls), and finally records the coverage entries. Admin only.

Reverts ChainRegistryAlreadyRegistered if the chain identity already exists. Sections for adapter facets the diamond does not host must be left disabled (see AddEvmChainConfig).

function addEvmChain(AddEvmChainConfig calldata cfg) external;

Parameters

NameTypeDescription
cfgAddEvmChainConfig

Events

ChainRegistered

Emitted when a chain identity is registered.

event ChainRegistered(bytes32 indexed chainKey, bytes2 chainType, bytes chainReference, uint256 evmChainId);

Parameters

NameTypeDescription
chainKeybytes32
chainTypebytes2
chainReferencebytes
evmChainIduint256

SetNativeIds

Emitted when a chain's informational native ids are set.

event SetNativeIds(bytes32 indexed chainKey, NativeIds ids);

Parameters

NameTypeDescription
chainKeybytes32
idsNativeIds

SetGatewayCoverage

Emitted when a gateway's coverage of a chain is set or cleared.

event SetGatewayCoverage(bytes32 indexed chainKey, address indexed gateway, bool covered, bool hubRouted);

Parameters

NameTypeDescription
chainKeybytes32
gatewayaddress
coveredbool
hubRoutedbool

ChainAdded

Emitted once per successful addEvmChain fan-out (the per-adapter libs emit their own events).

event ChainAdded(bytes32 indexed chainKey, uint256 indexed chainId);

Parameters

NameTypeDescription
chainKeybytes32
chainIduint256

Errors

ChainRegistryAlreadyRegistered

The chain identity is already registered (chain identities are permanent — no removal in v1).

error ChainRegistryAlreadyRegistered(bytes32 chainKey);

Parameters

NameTypeDescription
chainKeybytes32

ChainRegistryNotRegistered

The chain identity is not registered yet (register it before configuring it).

error ChainRegistryNotRegistered(bytes32 chainKey);

Parameters

NameTypeDescription
chainKeybytes32

ChainRegistryEmptyChainReference

The chain reference was empty (an ERC-7930 chain identity needs a reference).

error ChainRegistryEmptyChainReference();

ChainRegistryZeroGateway

The coverage gateway was the zero address.

error ChainRegistryZeroGateway();

ChainRegistryCoverageLengthMismatch

The coverage section's gateways and hubRouted arrays differ in length.

error ChainRegistryCoverageLengthMismatch(uint256 gateways, uint256 hubRouted);

Parameters

NameTypeDescription
gatewaysuint256
hubRouteduint256

ChainRegistryAxelarChainMismatch

The Axelar section's chain7930 is not the canonical chain-only ERC-7930 address of chainId.

error ChainRegistryAxelarChainMismatch();

ChainRegistryAxelarRemoteMismatch

The Axelar section's remote7930 does not address the chainId being added.

error ChainRegistryAxelarRemoteMismatch();

ChainRegistryStargateEidMismatch

The stargate section's eid contradicts the layerZero section's eid in the same config — Stargate rides LayerZero, so when both sections are enabled the eids must be equal.

error ChainRegistryStargateEidMismatch(uint32 lzEid, uint32 stargateEid);

Parameters

NameTypeDescription
lzEiduint32
stargateEiduint32

ChainRegistryNonCanonicalEvmReference

An eip-155 registration whose chainReference is not the canonical minimal-big-endian encoding of evmChainId (or whose evmChainId is 0) — such a key could never match send-time derivation.

error ChainRegistryNonCanonicalEvmReference(bytes chainReference, uint256 evmChainId);

Parameters

NameTypeDescription
chainReferencebytes
evmChainIduint256

ChainRegistryEvmChainIdOnNonEvmChain

A non-EVM registration supplied a non-zero evmChainId (meaningless for non-EVM chainTypes).

error ChainRegistryEvmChainIdOnNonEvmChain(uint256 evmChainId);

Parameters

NameTypeDescription
evmChainIduint256

Structs

NativeIds

Per-chain native identifiers of the major bridge ecosystems. Purely an INFORMATIONAL indexing layer (0 / empty = unset) — adapters keep their own authoritative hot-path maps.

struct NativeIds {
        /// @notice Chainlink CCIP chain selector (0 = unset).
        uint64 ccipSelector;
        /// @notice LayerZero v2 endpoint id (0 = unset).
        uint32 lzEid;
        /// @notice Wormhole chain id (0 = unset).
        uint16 wormholeId;
        /// @notice Circle CCTP domain (0 = unset; NOTE domain 0 is Ethereum — rely on the CCTP adapter's own
        ///         registered flag for authoritative reads, this field is informational).
        uint32 cctpDomain;
        /// @notice Axelar chain name (empty = unset).
        string axelarName;
        /// @notice Hyperlane domain (0 = unset; usually — but NOT guaranteed — the EVM chainId). APPENDED.
        uint32 hyperlaneDomain;
    }

Properties

NameTypeDescription
ccipSelectoruint64
lzEiduint32
wormholeIduint16
cctpDomainuint32
axelarNamestring
hyperlaneDomainuint32

CcipSection

CCIP fan-out section of AddEvmChainConfig (disabled sections are skipped entirely).

struct CcipSection {
        bool enabled;
        uint64 selector;
        address remoteGateway;
        uint256 gasLimit;
        bool allowOutOfOrderExecution;
    }

Properties

NameTypeDescription
enabledbool
selectoruint64
remoteGatewayaddress
gasLimituint256
allowOutOfOrderExecutionbool

LayerZeroSection

LayerZero v2 fan-out section of AddEvmChainConfig.

struct LayerZeroSection {
        bool enabled;
        uint32 eid;
        bytes32 peer;
        uint128 gas;
        uint128 msgValue;
    }

Properties

NameTypeDescription
enabledbool
eiduint32
peerbytes32
gasuint128
msgValueuint128

WormholeSection

Wormhole fan-out section of AddEvmChainConfig.

struct WormholeSection {
        bool enabled;
        uint16 wormholeId;
        address remote;
    }

Properties

NameTypeDescription
enabledbool
wormholeIduint16
remoteaddress

AxelarSection

Axelar fan-out section of AddEvmChainConfig. chain7930 MUST be the canonical chain-only ERC-7930 address of the chain being added (InteroperableAddress.formatEvmV1(chainId) — the exact bytes the Axelar adapter keys its equivalence map with) and remote7930 the full ERC-7930 address of the remote gateway ON that chain; both are validated against chainId.

struct AxelarSection {
        bool enabled;
        string axelarName;
        bytes remote7930;
        bytes chain7930;
    }

Properties

NameTypeDescription
enabledbool
axelarNamestring
remote7930bytes
chain7930bytes

ZetaSection

ZetaChain fan-out section of AddEvmChainConfig (remoteApp is the ZEVM universal app).

struct ZetaSection {
        bool enabled;
        address remoteApp;
    }

Properties

NameTypeDescription
enabledbool
remoteAppaddress

OpL2ToL2Section

OP Superchain L2-to-L2 fan-out section of AddEvmChainConfig.

struct OpL2ToL2Section {
        bool enabled;
        address remoteAdapter;
    }

Properties

NameTypeDescription
enabledbool
remoteAdapteraddress

CctpSection

Circle CCTP fan-out section of AddEvmChainConfig.

struct CctpSection {
        bool enabled;
        uint32 domain;
        uint256 maxFee;
        uint32 minFinalityThreshold;
        bytes32 destinationCaller;
    }

Properties

NameTypeDescription
enabledbool
domainuint32
maxFeeuint256
minFinalityThresholduint32
destinationCallerbytes32

HyperlaneSection

Hyperlane fan-out section of AddEvmChainConfig (remote is the 32-byte counterpart adapter; gasLimit 0 = the adapter's default handle gas).

struct HyperlaneSection {
        bool enabled;
        uint32 domain;
        bytes32 remote;
        uint256 gasLimit;
    }

Properties

NameTypeDescription
enabledbool
domainuint32
remotebytes32
gasLimituint256

StargateSection

Stargate token-bridge fan-out section of AddEvmChainConfig. Stargate rides LayerZero, so eid equals the LayerZero section's eid for the same chain — recorded in the Stargate adapter's OWN chainId ⇄ eid map (adapters never share hot-path storage; no separate NativeIds field — NativeIds.lzEid is the informational record).

struct StargateSection {
        bool enabled;
        uint32 eid;
    }

Properties

NameTypeDescription
enabledbool
eiduint32

HyperbridgeSection

Hyperbridge (ISMP) fan-out section of AddEvmChainConfig. The destination state machine id is DERIVED from chainId as the canonical bytes("EVM-" + chainId) — never caller-supplied (fail-closed); remoteModule is the counterpart adapter module on the chain being added and timeout the per-destination dispatch timeout in seconds (0 = no explicit timeout — the host's default handling).

struct HyperbridgeSection {
        bool enabled;
        bytes remoteModule;
        uint64 timeout;
    }

Properties

NameTypeDescription
enabledbool
remoteModulebytes
timeoutuint64

CoverageSection

Coverage entries recorded for the new chain (parallel arrays; empty = no coverage recorded).

struct CoverageSection {
        address[] gateways;
        bool[] hubRouted;
    }

Properties

NameTypeDescription
gatewaysaddress[]
hubRoutedbool[]

AddEvmChainConfig

The one-action add-chain config: the EVM chainId plus one OPTIONAL section per gateway adapter, each guarded by an enabled flag so any subset fans out. A section for an adapter facet the diamond does not host MUST be left disabled by the admin (the fan-out writes that adapter's ERC-7201 slots regardless — they would simply go unread until such a facet is cut).

struct AddEvmChainConfig {
        uint256 chainId;
        CcipSection ccip;
        LayerZeroSection layerZero;
        WormholeSection wormhole;
        AxelarSection axelar;
        ZetaSection zeta;
        OpL2ToL2Section opL2ToL2;
        CctpSection cctp;
        HyperlaneSection hyperlane;
        StargateSection stargate;
        HyperbridgeSection hyperbridge;
        CoverageSection coverage;
    }

Properties

NameTypeDescription
chainIduint256
ccipCcipSection
layerZeroLayerZeroSection
wormholeWormholeSection
axelarAxelarSection
zetaZetaSection
opL2ToL2OpL2ToL2Section
cctpCctpSection
hyperlaneHyperlaneSection
stargateStargateSection
hyperbridgeHyperbridgeSection
coverageCoverageSection