Implementation Guide
Last updated
Last updated
A Hyperlane implementation for a new chain architecture is comprised of the following:
: expose the interface for application developers to send and receive messages with
: operate the protocol by adding security and relaying messages
: applications that use the protocol and demonstrate its capabilities
Before getting started here, it is recommended to review the
Below describes the onchain contract spec for the Hyperlane protocol. It uses solidity types for familiarity but everything should be generalizable to other languages.
address
should be interpreted as the local chain's address type
payable
describes a function that allows callers to pass native tokens
The message is the core data structure used by the Hyperlane protocol. It is a packed data structure that contains all the information needed to route a message from one domain to another.
The mailbox is the entrypoint for developers to send and receive messages from.
Dispatches a message to the destination domain and recipient.
Attempts to deliver message
to its recipient. Verifies message
via the recipient's ISM using the provided metadata
.
Returns the number of messages dispatched
Returns root of merkle tree which contains all dispatched message IDs as leaves.
A contract that wants to receive a message must expose the following handler.
They may optionally specify a security module to verify messages before they are handled.
Interchain security modules are used to verify messages before they are processed.
Returns an enum that represents the type of security model encoded by this ISM.
Relayers infer how to fetch and format metadata from this type.
Defines a security model responsible for verifying interchain messages based on the provided metadata.
Validators announce their signature storage location so that relayers can fetch and verify their signatures.
Announces a validator signature storage location
Returns a list of all announced storage locations
Implements a security module that checks if the metadata provided to verify satisfies a quorum of signatures from a set of configured validators.
To be used with the MESSAGE_ID_MULTISIG module type implementation in the relayer, the metadata must be formatted as follows:
Returns the set of validators responsible for verifying message and the number of signatures required
Can change based on the content of _message
The gas paymaster is used to pay for the gas required in message processing on the destination chain. This is not strictly required if relayers are willing to subsidize message processing.
Deposits msg.value as a payment for the relaying of a message to its destination chain.
Overpayment will result in a refund of native tokens to the refundAddress. Callers should be aware that this may present reentrancy issues.
Emitted when a payment is made for a message's gas costs.
Below describes the agent spec for a new chain implementation. The rust implementations hope to support all chains, but the spec is intended to be chain agnostic.
In addition to indexing messages dispatched from the mailbox, validators produce attestations for the messages they observe to be used on the destination chain for security.
They also publish these augmented checkpoints on their syncer.
the message recipient ISM returns an unknown module type
module type is known but metadata fails to verify
metadata verifies but dry running (gas estimation) message processing fails
Token router application that routes tokens between domains on demand.
Transfers amountOrId
token to recipient
on destination
domain.
To be interoperable with warp routes on other chains, the body
of a transfer message must be a byte packed TransferMessage
struct.
After implementing these three contracts, you can reach your first milestone to test, mocking a message transfer, by calling a Mailbox
's dispatch
function to send a message to a recipient and assert that the recipient received the message. See a
After implementing the MultisigISM, you reach the second milestone to test that your Mailbox only processes after a recipient's ISM returns true. You can test that with a TestISM
that you can statically set to accept or reject any message. See a
All agents must index from the origin . In the solidity mailbox, we dispatched. Other chains may have different ways of surfacing this information, but the agent must be able to get message content reliably and with consistent ordering -- see the trait.
Validators produce attestations called from the which commit via merkle to all dispatched message IDs.
Validators use the latest checkpoint method on the to get the latest checkpoint from the mailbox and submit signatures to some highly available storage using the .
Validators use indexed messages to join the with the corresponding message ID emitted from the mailbox.
In addition to indexing messages dispatched from the mailbox, relayers process messages on the destination chain. This requires building metadata that satisfies the message 's verification requirements, and signing transactions that the message on the destination .
Each implies a different metadata format for to succeed. Relayers need each module trait (eg ) to be implemented.
The relayer will attempt to process messages on the destination mailbox (see ). If
then the message will be kicked to an exponential backoff retry queue. The relayer relies on implementations of the and traits for these checks.
Relayers may also require gas payment for a specific message ID on the origin chain before processing the message on the destination chain. To do this, they must have an deployed with their address set as beneficiary and index events. See . We recommend to start with no gas payment enforcement policy and then gradually support more restrictive ones.
See this for inspiration.