Skip to main content

Send a message

To send interchain messages, developers call Mailbox.dispatch().

This function takes as parameters the message contents, the destination chain ID, and the recipient address. Each message gets inserted as a leaf into an incremental merkle tree stored by the Mailbox. Hyperlane's proof of stake protocol uses this merkle tree to verify fraud proofs.

Dispatch

Calling this function dispatches a message to the destination domain and recipient.

warning

Hyperlane can only deliver messages to smart contracts that implement the handle function. See the receive a message documentation for more information.

Depending on the post-dispatch hook configuration, some payment may be required. See the quoteDispatch section for more information.

function dispatch(
uint32 destinationDomain,
bytes32 recipientAddress,
bytes calldata messageBody
) external payable returns (bytes32 messageId);
info

Recipient addresses are left-padded to bytes32 for compatibility with virtual machines that are addressed differently. The following utility is provided in the TypeCasts library for convenience.

// alignment preserving cast
function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}

Examples

// send message from abstracttestnet to alephzeroevmtestnet TestRecipient
IMailbox mailbox = IMailbox("0x28f448885bEaaF662f8A9A6c9aF20fAd17A5a1DC");
bytes32 messageId = mailbox.dispatch{value: msg.value}(
2039,
"0x0000000000000000000000009EC79CA89DeF61BFa2f38cD4fCC137b9e49d60dD",
bytes("Hello, world")
);

Quote Dispatch

Fees are often configured to cover Interchain Gas Payments (IGP) as well as protocol costs. These include transaction submission on the destination chain, security provisioning, and maintenance. To receive a quote for a corresponding dispatch call, you can query the quoteDispatch function.

function quoteDispatch(
uint32 destinationDomain,
bytes32 recipientAddress,
bytes calldata messageBody
) external view returns (uint256 fee);

The quoted fee must be passed as value to the dispatch call to ensure it does not revert.

Examples

// quote sending message from abstracttestnet to alephzeroevmtestnet TestRecipient
IMailbox mailbox = IMailbox("0x28f448885bEaaF662f8A9A6c9aF20fAd17A5a1DC");
uint32 destination = 2039;
bytes32 recipient = "0x0000000000000000000000009EC79CA89DeF61BFa2f38cD4fCC137b9e49d60dD";
bytes memory body = bytes("Hello, world");
uint256 fee = mailbox.quoteDispatch(destination, recipient, body);
mailbox.dispatch{value: fee}(destination, recipient, body);
danger

Underpayment to dispatch will revert. If you are composing hooks together, overpayment may not be refunded to the message sender.

Post-Dispatch Hook Config

There are two hooks configured on a Mailbox

  • required: invoked for all dispatch calls with value that covers the required fee
  • default: invoked (unless overridden) with remaining value after required hook

Required Hook

To query the required hook configuration, you can call the requiredHook function.

function requiredHook() external view returns (IPostDispatchHook);

Default Hook

To query the default hook configuration, you can call the defaultHook function.

function defaultHook() external view returns (IPostDispatchHook);

To override the default hook with a custom hook in the dispatch call, see the Hooks Reference.