Post-dispatch hooks allow developers to configure additional origin chain behavior with message content dispatched via the Mailbox.

This allows developers to integrate third party/native bridges, make additional chain commitments, or require custom fees all while maintaining a consistent single-call Mailbox interface.

Post Dispatch

In addition to the message dispatched via the Mailbox, the postDispatch function receives a metadata parameter. The metadata parameter is passed from the dispatch call through the Mailbox unmodified. This allows developers to pass any context they wish through to the hook.

function postDispatch(
    bytes calldata metadata,
    bytes calldata message
) external payable;

If the postDispatch function receives insufficient payment, it may revert.

Post-Dispatch Hooks may be replayable. Developers creating custom hooks should implement safe checks to prevent this behavior. Here is an example implementation.

Quote Dispatch (Fees)

Fees are often charged in postDispatch to cover costs such as destination chain transaction submission and security provisioning. To receive a quote for a corresponding postDispatch call, you can query the quoteDispatch function.

function quoteDispatch(
    bytes calldata metadata,
    bytes calldata message
) external view returns (uint256);

The Mailbox has a quoteDispatch function that returns the aggregate fee required for a dispatch call to be successful.

Move to implementing a hook guide here.

Overriding default Hook Metadata

To override the default metadata, there is a dispatch overload that takes an optional metadata parameter.

Hooks currently expect metadata to be formatted with the StandardHookMetadata library.

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

The custom metadata will be passed to the required hook’s quoteDispatch and postDispatch functions, before being passed to the default hook’s postDispatch function.

Examples

// send message from originChain to destinationChain TestRecipient
IMailbox mailbox = IMailbox("mailboxAddress");
mailbox.dispatch{value: msg.value}(
  destinationDomain,
  "paddedRecipient", // Convert recipient address to padded bytes32 format
  bytes("messageBody"),
  StandardHookMetadata.overrideGasLimit(200000)
);

Custom hook and metadata

After implementing the above interfaces, you can override default hook along the hook metadata by using the overloaded dispatch call in our mailbox:

function dispatch(
    uint32 destinationDomain,
    bytes32 recipientAddress,
    bytes calldata body,
    bytes calldata customHookMetadata,
    IPostDispatchHook customHook
) external payable returns (bytes32 messageId);

Examples

// send message from originChain to destinationChain TestRecipient
IMailbox mailbox = IMailbox("mailboxAddress");
IPostDispatchHook merkleTree = IPostDispatchHook("merkleTreeHookAddress");
mailbox.dispatch(
  destinationDomain,
  "paddedRecipient", // Convert recipient address to padded bytes32 format
  bytes("messageBody"),
  "0x", // empty metadata
  merkleTree
);