> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hyperlane.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Mailbox

> Core smart contract interface for sending and receiving cross-chain messages in Hyperlane

The Hyperlane `Mailbox` smart contracts expose an on-chain API for sending and receiving interchain messages. There is a `Mailbox` contract deployed on every chain Hyperlane supports.

The network of `Mailboxes` facilitates the connective tissue between blockchains that developers leverage to create interchain applications, and add interchain functionality to their existing applications.

```mermaid theme={null}
flowchart LR
    subgraph Origin Chain
      Sender
      M_O[(Mailbox)]
      Sender -- "dispatch(destination, recipient, body)" --> M_O
    end

    subgraph Destination Chain
      Recipient[Recipient]
      M_D[(Mailbox)]

      M_D -- "handle(origin, sender, body)" --> Recipient
    end

    M_O -. "relay" .-> M_D
```

* To [**send**](/docs/reference/messaging/send) interchain messages, call the `dispatch` function.
* To [**receive**](/docs/reference/messaging/receive) interchain messages, implement the `handle` function.

## Interface

The [`IMailbox`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/interfaces/IMailbox.sol) interface exposes two state-mutating functions; `dispatch()` and `process()`, which are used to send and receive messages, respectively.

<Accordion title="IMailbox Interface">
  ```solidity theme={null}
  // SPDX-License-Identifier: MIT OR Apache-2.0
  pragma solidity >=0.8.0;

  import {IInterchainSecurityModule} from "./IInterchainSecurityModule.sol";
  import {IPostDispatchHook} from "./hooks/IPostDispatchHook.sol";

  interface IMailbox {
      // ============ Events ============
      /**
       * @notice Emitted when a new message is dispatched via Hyperlane
       * @param sender The address that dispatched the message
       * @param destination The destination domain of the message
       * @param recipient The message recipient address on `destination`
       * @param message Raw bytes of message
       */
      event Dispatch(
          address indexed sender,
          uint32 indexed destination,
          bytes32 indexed recipient,
          bytes message
      );

      /**
       * @notice Emitted when a new message is dispatched via Hyperlane
       * @param messageId The unique message identifier
       */
      event DispatchId(bytes32 indexed messageId);

      /**
       * @notice Emitted when a Hyperlane message is processed
       * @param messageId The unique message identifier
       */
      event ProcessId(bytes32 indexed messageId);

      /**
       * @notice Emitted when a Hyperlane message is delivered
       * @param origin The origin domain of the message
       * @param sender The message sender address on `origin`
       * @param recipient The address that handled the message
       */
      event Process(
          uint32 indexed origin,
          bytes32 indexed sender,
          address indexed recipient
      );

      function localDomain() external view returns (uint32);

      function delivered(bytes32 messageId) external view returns (bool);

      function defaultIsm() external view returns (IInterchainSecurityModule);

      function defaultHook() external view returns (IPostDispatchHook);

      function requiredHook() external view returns (IPostDispatchHook);

      function latestDispatchedId() external view returns (bytes32);

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

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

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

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

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

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

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

      function recipientIsm(
          address recipient
      ) external view returns (IInterchainSecurityModule module);
  }
  ```
</Accordion>

### Message Headers

The Mailbox prepends message bodies with a header containing the following fields:

| **Field**     | **Description**                                                |
| ------------- | -------------------------------------------------------------- |
| `version`     | The version of the Mailbox contract                            |
| `nonce`       | A unique identifier for each message sent from a given Mailbox |
| `origin`      | The domain of the origin chain                                 |
| `sender`      | The address of the sender on the origin chain                  |
| `destination` | The domain of the destination chain                            |
| `recipient`   | The address of the recipient on the destination chain          |

See the [`Message` library](/docs/reference/messaging/send) for more information on the message encoding.

### Uniqueness

The `nonce` is a monotonically increasing integer for each message sent from a given Mailbox. It is incremented each time a message is dispatched to serve as a separator for otherwise identical messages.

<CodeGroup>
  ```solidity Solidity theme={null}
  function delivered(bytes32 messageId) external view returns (bool);
  ```
</CodeGroup>

The `messageId` is a globally unique message identifier, returned from the `dispatch` call, computed as the `keccak256` hash of the message (with headers).

### Replay Protection

The Mailbox maintains a mapping of already delivered `messageId` values to prevent replay attacks. If a message is received with a `messageId` that has already been delivered, the message is rejected.

## Dispatch

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 get inserted as a leaf into an [incremental merkle tree](https://medium.com/@josephdelong/ethereum-2-0-deposit-merkle-tree-13ec8404ca4f) stored by the `Mailbox`.

Hyperlane's proof of stake protocol uses this merkle tree to verify fraud proofs.

## Process

To deliver interchain messages, the [relayer](/docs/protocol/agents/relayer) calls `Mailbox.process()`.

This function takes as parameters the message to deliver as well as arbitrary metadata that can be specified by the relayer.

The `Mailbox` will pass the message and metadata to the recipient's interchain security module for verification. If the ISM successfully verifies the message, the `Mailbox` delivers the message to the recipient by calling `recipient.handle()`.

<Note>
  See
  [`Message.sol`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/Message.sol)
  for more details on Hyperlane message encoding
</Note>
