Skip to content

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:

  1. 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)
    • Returns an outbox ID to track the message
    • Emits a MessagePosted event
  2. 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

  1. 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.

  2. 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 and arbitrum-sepolia (Axelar name identifier)
    • In this transaction, we register a chain equivalence between eip155:84532 and base-sepolia (Axelar name identifier)
  3. 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).
  4. With the adapters configured, we just need a contract on the destination chain following IERC7786Receiver, in order to receive and execute the message.

Sending Message

  1. 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.
  2. 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.
  3. 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).