Skip to content
Lattice

ZetaChainGatewayAdapterLib

Git Source

Title: ZetaChainGatewayAdapterLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from ZetaChain (https://github.com/zeta-chain/protocol-contracts)

Logic + ERC-7201 storage for the ZetaChain GatewayEVM ERC-7786 gateway adapter. sendMessage builds the ERC-7930 envelope and dispatches it via gateway.call to the destination's ZEVM universal app (the hub), forwarding msg.value as the native messaging fee; onCall is the gateway-invoked delivery hook that authenticates the source out-of-band via the reverse app⇒chainId map, de-duplicates per (source, id), and delivers to the ERC-7930 recipient. EVM chains only.

HUB-ROUTED: a "remote" is the ZEVM UNIVERSAL APP for a hub chainId, not a direct peer adapter. Both a forward (chainId => app) and a reverse (app => chainId) map are kept because inbound onCall only exposes context.sender = the app. INVERTED/HUB INBOUND AUTH: onCall's msg.sender is the GatewayEVM (driven by the ZetaChain TSS/observer set), so trust is established by matching context.sender to a registered app and recovering its source chainId. Wire message (envelope) = abi.encode(senderInterop, recipientInterop, payload, nonce).

Functions

zetaChainGatewayAdapterStorage

function zetaChainGatewayAdapterStorage() internal pure returns (ZetaChainGatewayAdapterStorage storage $);

Returns

NameTypeDescription
$ZetaChainGatewayAdapterStorage

__ZetaChainGatewayAdapter_init

Stores the gateway + default revert gas, registers the hub route in BOTH maps, and registers the gateway-source ERC-165 id.

function __ZetaChainGatewayAdapter_init(
        address gateway_,
        uint256 hubChainId,
        address hubRemoteApp,
        uint256 defaultOnRevertGasLimit_
    ) internal;

Parameters

NameTypeDescription
gateway_addressThe ZetaChain GatewayEVM (deployed contract, per-connected-chain address).
hubChainIduint256The hub chainId whose ZEVM universal app terminates the route.
hubRemoteAppaddressThe trusted ZEVM universal app for hubChainId.
defaultOnRevertGasLimit_uint256The default onRevertGasLimit for per-message RevertOptions.

registerInterface

Writes true to the SHARED IERC7786GatewaySource ERC-165 map slot (0x11967553 → ...). Same slot the CCIP/LayerZero/OP/Axelar adapters register; a Diamond mounts at most one gateway.

function registerInterface() internal;

gateway

function gateway() internal view returns (address);

Returns

NameTypeDescription
<none>address

getRemoteApp

function getRemoteApp(uint256 chainId) internal view returns (address);

Parameters

NameTypeDescription
chainIduint256

Returns

NameTypeDescription
<none>address

getChainIdForApp

function getChainIdForApp(address remoteApp) internal view returns (uint256);

Parameters

NameTypeDescription
remoteAppaddress

Returns

NameTypeDescription
<none>uint256

defaultOnRevertGasLimit

function defaultOnRevertGasLimit() internal view returns (uint256);

Returns

NameTypeDescription
<none>uint256

supportsAttribute

No sendMessage attributes are supported: surfacing RevertOptions as a per-message ERC-7786 attribute is #77 open question #8 (DEFERRED) — an admin-configured default is used instead.

function supportsAttribute(bytes4) internal pure returns (bool);

Parameters

NameTypeDescription
_bytes4

Returns

NameTypeDescription
<none>bool

setGateway

function setGateway(address gateway_) internal;

Parameters

NameTypeDescription
gateway_address

registerRemote

function registerRemote(uint256 chainId, address remoteApp) internal;

Parameters

NameTypeDescription
chainIduint256
remoteAppaddress

setDefaultOnRevertGasLimit

function setDefaultOnRevertGasLimit(uint256 onRevertGasLimit) internal;

Parameters

NameTypeDescription
onRevertGasLimituint256

_registerRemote

One-shot registration of a trusted remote ZEVM universal app for chainId in BOTH maps.

Rejects zero app; rejects a chainId already mapped OR an app already mapped (either direction).

function _registerRemote(ZetaChainGatewayAdapterStorage storage $, uint256 chainId, address remoteApp) private;

Parameters

NameTypeDescription
$ZetaChainGatewayAdapterStorage
chainIduint256
remoteAppaddress

sendMessage

ERC-7786 source. Parses the ERC-7930 recipient into (destChainId, target), resolves the destination's trusted ZEVM universal app (the hub route terminus), wraps the ERC-7930 envelope with a source-minted monotonic nonce, and dispatches it via gateway.call. Forwards msg.value as the native messaging fee (there is NO on-chain quote or refund from the gateway). Returns the globally-unique keccak256(abi.encode(block.chainid, nonce)) as the ERC-7786 sendId.

No attributes are supported — any attribute reverts UnsupportedAttribute. The RevertOptions are an admin-configured default (revertAddress = msg.sender, callOnRevert = false); surfacing them per-message is #77 open question #8 (DEFERRED). remote = forward[destChainId] is the ZEVM universal app / hub-terminated route; an unset route reverts UnknownDestinationChain.

function sendMessage(bytes calldata recipient, bytes calldata payload, bytes[] calldata attributes)
        internal
        returns (bytes32);

Parameters

NameTypeDescription
recipientbytes
payloadbytes
attributesbytes[]

Returns

NameTypeDescription
<none>bytes32

onCall

Gateway-invoked delivery hook (INVERTED/HUB AUTH). Authenticates: (1) msg.sender is the configured GatewayEVM; (2) context.sender is a registered trusted ZEVM universal app, recovering the source chainId from the reverse map. De-dups per (source, delivery id) marking BEFORE delivery (strict CEI), then delivers to the ERC-7930 recipient after asserting it targets THIS chain. Returns empty bytes.

The delivery id is derived from the authenticated source + the source-minted nonce (NOT envelope content), so two byte-identical-but-distinct messages get distinct ids (neither dropped).

function onCall(MessageContext calldata context, bytes calldata message) internal returns (bytes memory);

Parameters

NameTypeDescription
contextMessageContext
messagebytes

Returns

NameTypeDescription
<none>bytes