ICrosschainLink
Title: ICrosschainLink
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Adapted for EIP-2535 from OpenZeppelin CrosschainLinked v5.6.1 (https://github.com/OpenZeppelin/openzeppelin-contracts)
Admin/read surface for the CrosschainLink facet: an ERC-7786 send + receive endpoint that
registers per-chain (gateway, counterpart) links and routes inbound messages to handlers by
a leading 4-byte payload tag.
The receive entrypoint receiveMessage is declared by IERC7786Recipient; the facet implements
both. Chains and counterparts are ERC-7930 binary interoperable addresses: a chain is a
"chain-only" interoperable address (empty address), a counterpart is a full one (chain + address).
Every handler is called as processMessage (0x902d5027), so a diamond can host only ONE handler
facet; any other tag must route to an external handler contract or to a second diamond (issue #240).
Functions
getLink
Returns the gateway and counterpart registered for a source chain.
function getLink(bytes calldata chain) external view returns (address gateway, bytes memory counterpart);Parameters
| Name | Type | Description |
|---|---|---|
| chain | bytes | A "chain-only" ERC-7930 interoperable address (empty address). |
Returns
| Name | Type | Description |
|---|---|---|
| gateway | address | The ERC-7786 gateway trusted for chain. |
| counterpart | bytes | The full interoperable address authorized to send from chain. |
getHandler
Returns the handler registered for a message tag (zero if none).
function getHandler(bytes4 tag) external view returns (address handler);Parameters
| Name | Type | Description |
|---|---|---|
| tag | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| handler | address |
isProcessed
Returns whether a receiveId from gateway has already been processed (keyed per-gateway,
as ERC-7786 only guarantees receiveId uniqueness for the calling gateway).
function isProcessed(address gateway, bytes32 receiveId) external view returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| gateway | address | |
| receiveId | bytes32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
setLink
Registers (or overrides) the gateway + counterpart for the counterpart's source chain.
Caller must hold DEFAULT_ADMIN_ROLE. Reverts CrosschainLinkAlreadyRegistered if a link
exists and allowOverride is false.
function setLink(address gateway, bytes calldata counterpart, bool allowOverride) external;Parameters
| Name | Type | Description |
|---|---|---|
| gateway | address | The ERC-7786 gateway for this chain (must implement supportsAttribute). |
| counterpart | bytes | The full interoperable address of the remote counterpart. |
| allowOverride | bool | Whether to overwrite an existing link for the chain. |
setHandler
Registers a handler for inbound messages whose payload starts with tag (zero to clear).
Caller must hold DEFAULT_ADMIN_ROLE.
function setHandler(bytes4 tag, address handler) external;Parameters
| Name | Type | Description |
|---|---|---|
| tag | bytes4 | |
| handler | address |
sendMessage
Sends a message to the counterpart registered for chain via its ERC-7786 gateway.
Caller must hold DEFAULT_ADMIN_ROLE.
function sendMessage(bytes calldata chain, bytes calldata payload, bytes[] calldata attributes)
external
returns (bytes32 sendId);Parameters
| Name | Type | Description |
|---|---|---|
| chain | bytes | A "chain-only" interoperable address selecting the destination link. |
| payload | bytes | The message payload (handlers expect a leading 4-byte tag on the receiving side). |
| attributes | bytes[] | ERC-7786 gateway attributes (may be empty). |
Returns
| Name | Type | Description |
|---|---|---|
| sendId | bytes32 | The gateway-assigned send id (zero if no further processing is needed). |
Events
LinkRegistered
Emitted when a link is registered or overridden. counterpart is a full interoperable address.
event LinkRegistered(address gateway, bytes counterpart);Parameters
| Name | Type | Description |
|---|---|---|
| gateway | address | |
| counterpart | bytes |
HandlerRegistered
Emitted when a message handler is registered (or cleared, when handler is zero) for a tag.
event HandlerRegistered(bytes4 indexed tag, address handler);Parameters
| Name | Type | Description |
|---|---|---|
| tag | bytes4 | |
| handler | address |
MessageProcessed
Emitted when an inbound message is authenticated, de-duplicated, and dispatched to a handler.
event MessageProcessed(bytes32 indexed receiveId, bytes4 indexed tag, address handler);Parameters
| Name | Type | Description |
|---|---|---|
| receiveId | bytes32 | |
| tag | bytes4 | |
| handler | address |
Errors
CrosschainLinkAlreadyRegistered
A link already exists for chain and allowOverride was false. chain is chain-only.
error CrosschainLinkAlreadyRegistered(bytes chain);Parameters
| Name | Type | Description |
|---|---|---|
| chain | bytes |
CrosschainUnauthorizedGateway
The caller (gateway) is not the registered gateway for the source chain of sender.
error CrosschainUnauthorizedGateway(address gateway, bytes sender);Parameters
| Name | Type | Description |
|---|---|---|
| gateway | address | |
| sender | bytes |
CrosschainMessageAlreadyProcessed
receiveId has already been processed (replay protection).
error CrosschainMessageAlreadyProcessed(bytes32 receiveId);Parameters
| Name | Type | Description |
|---|---|---|
| receiveId | bytes32 |
CrosschainHandlerNotRegistered
No handler is registered for the payload's leading 4-byte tag.
error CrosschainHandlerNotRegistered(bytes4 tag);Parameters
| Name | Type | Description |
|---|---|---|
| tag | bytes4 |
CrosschainInvalidPayload
The payload is shorter than the 4-byte handler tag.
error CrosschainInvalidPayload();CrosschainZeroGateway
A zero gateway address was supplied to setLink.
error CrosschainZeroGateway();