Examples
1. Sending a message using ERC7786 with Axelar adapter
This tutorial is using Base Sepolia
as source chain and Arbitrum Sepolia
as destination chain.
Concepts
ERC7786 defines two main interfaces for cross-chain messaging:
-
IERC7786GatewaySource
- The source chain interface that allows sending messages. Key components:sendMessage
: Function to initiate message sending, taking:- destinationChain (CAIP-2 format, e.g.
eip155:421614
for Arbitrum Sepolia) - receiver address
- payload (arbitrary bytes)
- attributes (optional protocol-specific parameters)
- destinationChain (CAIP-2 format, e.g.
- Returns an outbox ID to track the message
- Emits a
MessagePosted
event
-
IERC7786Receiver
- The destination chain interface that receives messages. Key components:executeMessage
: Function called by the destination gateway to deliver the message- Must verify the calling gateway is trusted
- Must return a specific selector (
0x675b049b
) to confirm successful execution
Important concepts to understand:
- Some protocols (like Axelar) may require additional steps like:
- Registering chain equivalences between protocol-specific and CAIP-2 identifiers
- Registering remote adapter addresses
- Paying for destination chain gas fees and potentially relayer or protocol fees
- Message approval and execution on the destination chain
The standard is designed to be protocol-agnostic while allowing protocol-specific features through the attributes parameter.
Adapter Setup
-
The first step is to deploy the adapters on source and destination chains. Adapters can be receive-only, send-only or work both ways. In order to be able to send messages in both directions, we deployed
AxelarGatewayDuplex.sol
in both chains. Note that when deploying the contract, one of the constructor parameters is the Axelar gateway proxy, which is the contract responsible for receiving (or sending) all messages in the respective chain. Note that each chain has its own gateway proxy (at least one). This archicteture is used to centralize all messages in one place, where relayers can easily listen for events. This is equivalent to LayerZero Endpoints and Hyperlane Mailboxes, for example. The contract addresses for the gateways on different chains for Axelar can be seen at its docs.- Contract deployed on source chain: 0xBb6A11d2FdEF18522cC9d14DdAdb676c8c126AEE
- Contract deployed on destination chain: 0x050193203845D4145Dea5200C7eA49EF28b5f870
-
With the contracts deployed (source and destination chains), we need to register the chain equivalence between axelar ids and the ERC7786 standard. This is because when sending a message, the destination chain parameter should follow the CAIP-2 standard to identify the destination chain. However, Axelar uses its own set of ids for the chains. This is also the case for other protocols such as LayerZero, with its eids. This makes it necessary to keep a mapping of CAIP-2 identifiers to each bridge protocol's own set of chain identifiers.
AxelarGatewatBase.sol
solves this by registering a chain equivalence with the identifiers.- In this transaction, we register a chain equivalence between
eip155:421614
andarbitrum-sepolia
(Axelar name identifier) - In this transaction, we register a chain equivalence between
eip155:84532
andbase-sepolia
(Axelar name identifier)
- In this transaction, we register a chain equivalence between
-
The next step is to register the remote adapters so that the adapter on the source chain knows about the adapter on the destination chain (and vice-versa).
- In this transaction, we map the address
0x050193203845D4145Dea5200C7eA49EF28b5f870
(adapter on destination chain) to its chain's CAIP-2 identifier (eip155:421614
). - In this transaction, we map the address
0xBb6A11d2FdEF18522cC9d14DdAdb676c8c126AEE
(adapter on source chain) to its chain's CAIP-2 identificer (eip155:84532
).
- In this transaction, we map the address
-
With the adapters configured, we just need a contract on the destination chain following
IERC7786Receiver
, in order to receive and execute the message.- Receiver contract deployed on destination chain: 0x60Ff0d6060722DB7357F6976C8E5B8f2F42b8759
Sending Message
-
To send a message, the function
sendMessage
should be called in the source chain adapter.- In this transaction, we are sending a message from the source chain to the destination chain.
The parameters are:
eip155:421614
(destinationChain, following the CAIP-2 standard),0x60ff0d6060722db7357f6976c8e5b8f2f42b8759
(receiver, contract on the destination chain supporting IERC7786Receiver), a random payload and an empty list of attributes.
- In this transaction, we are sending a message from the source chain to the destination chain.
The parameters are:
-
The next step is to pay to pay for the execution on the destination chain. This can be done in multiple ways depending on the protocol and adapter.
- In this transaction, we add native gas to the message using Axelar's native gas service.
-
In Axelar's architecture, the message is approved by the gateway proxy and then executed by the adapter
- In this transaction, we are approving the transaction in the gateway proxy.
- In this transaction, we are executing the messge in the adapter (which calls the receiver).
The whole flow (of setup and message sending) can be reproduced using this script (not yet merged to master and not ready for production).