L2ToL2CrossDomainMessengerGatewayAdapterLib
Title: L2ToL2CrossDomainMessengerGatewayAdapterLib
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Optimism (https://github.com/ethereum-optimism/optimism)
Logic + ERC-7201 storage for the OP Superchain L2ToL2CrossDomainMessenger ERC-7786 gateway adapter.
sendMessage wraps the ERC-7930 envelope as the calldata the messenger will execute on the sibling
adapter and dispatches via messenger.sendMessage (no fee — the relayer pays gas at relayMessage);
receiveCrossChainMessage is the messenger-invoked delivery callback that authenticates the source
out-of-band via crossDomainMessageContext, de-duplicates, and delivers to the ERC-7930 recipient.
EVM (Superchain) chains only. Routes by BARE EVM chainId — no eid/selector translation.
INVERTED INBOUND AUTH: the adapter's inbound function is the _target the messenger CALLs during
relayMessage, so msg.sender is the messenger predeploy (NOT the remote gateway). Trust is therefore
established by reading the authenticated (sender, source) back from messenger.crossDomainMessageContext()
and matching sender to the registered remote adapter for source. The messenger self-dedups on the
message hash (relayMessage reverts on replay via successfulMessages), so the per-envelope guard here
is cheap defense-in-depth rather than the primary replay defense. Wire message =
abi.encodeCall(receiveCrossChainMessage, (senderInterop, recipient, payload)).
Functions
l2ToL2CrossDomainMessengerGatewayAdapterStorage
function l2ToL2CrossDomainMessengerGatewayAdapterStorage()
internal
pure
returns (L2ToL2CrossDomainMessengerGatewayAdapterStorage storage $);Returns
| Name | Type | Description |
|---|---|---|
| $ | L2ToL2CrossDomainMessengerGatewayAdapterStorage |
__L2ToL2CrossDomainMessengerGatewayAdapter_init
Registers the gateway-source ERC-165 id. The messenger is the fixed predeploy constant, so there is no endpoint/router to persist at init.
function __L2ToL2CrossDomainMessengerGatewayAdapter_init() internal;registerInterface
Writes true to the SHARED IERC7786GatewaySource ERC-165 map slot (0x11967553 → ...). Same slot
the CCIP/LayerZero/Wormhole/Axelar adapters register; a Diamond mounts at most one gateway.
function registerInterface() internal;messenger
function messenger() internal pure returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
getRemoteAdapter
function getRemoteAdapter(uint256 chainId) internal view returns (address);Parameters
| Name | Type | Description |
|---|---|---|
| chainId | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
supportsAttribute
No sendMessage attributes are supported by this adapter: gas is supplied by the relayer at
relayMessage, so there is no per-destination gas config to attach.
function supportsAttribute(bytes4) internal pure returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| _ | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
registerRemoteAdapter
function registerRemoteAdapter(uint256 chainId, address remoteAdapter) internal;Parameters
| Name | Type | Description |
|---|---|---|
| chainId | uint256 | |
| remoteAdapter | address |
sendMessage
ERC-7786 source. Wraps the ERC-7930 envelope as the calldata the messenger will execute on the
destination sibling adapter and dispatches it via messenger.sendMessage. Charges NO fee: gas is
supplied by the relayer at relayMessage and the messenger takes no native value, so a non-empty
msg.value is rejected. Returns the messenger's message hash as the ERC-7786 sendId.
No attributes are supported — any attribute reverts UnsupportedAttribute.
function sendMessage(bytes calldata recipient, bytes calldata payload, bytes[] calldata attributes)
internal
returns (bytes32);Parameters
| Name | Type | Description |
|---|---|---|
| recipient | bytes | |
| payload | bytes | |
| attributes | bytes[] |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bytes32 |
receiveCrossChainMessage
Messenger-invoked delivery callback (INVERTED AUTH). Authenticates: (1) msg.sender is the
messenger predeploy; (2) the authenticated cross-domain (sender, source) read from
crossDomainMessageContext() matches the registered (non-zero) remote adapter for source.
De-dups per (source, envelope id) marking BEFORE delivery (strict CEI), then delivers to the
ERC-7930 recipient after asserting it targets THIS chain.
The per-envelope guard is defense-in-depth: the messenger already self-dedups on the message hash,
reverting relayMessage on replay via successfulMessages.
function receiveCrossChainMessage(
bytes calldata sender,
bytes calldata recipient,
bytes calldata payload,
uint256 nonce
) internal;Parameters
| Name | Type | Description |
|---|---|---|
| sender | bytes | |
| recipient | bytes | |
| payload | bytes | |
| nonce | uint256 |