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 IGP payments 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.

/**
* @notice Computes quote for dipatching a message to the destination domain & recipient
* using the default hook and empty metadata.
* @param destinationDomain Domain of destination chain
* @param recipientAddress Address of recipient on destination chain as bytes32

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.