@metalayer/contracts v0.0.7
MetalayerRouter Contracts
📚 Overview
MetalayerRouter is a messaging layer built on top of Hyperlane. It is designed for EVM-compatible chains and offers enhanced functionality such as:
- 1-to-1 messaging between chains
- Predefined finality configurations (e.g., rollup-based, RPC soft confirmations).
- n-to-1 cross-chain reads via offchain aggregation and CCIP-compatible delivery.
- Package encoding for richer message semantics.
- Fallback compatibility with Hyperlane interfaces.
- Preset ISMs (Interchain Security Modules) and fee hooks controlled at the protocol level.
(Metalayer)https://caldera.xyz/metalayer makes it easy for developers to build sophisticated cross-chain applications without dealing with the complexities of cross-chain messaging infrastructure. The MetalayerRouter is the messaging piece of the overall metalayer product.
Message Flow
sequenceDiagram
participant SenderApp as Sender Smart Contract
participant MetalayerRouter
participant HyperlaneMailbox
participant OffchainRelayer as Offchain Relayer
participant DestinationHyperlaneMailbox as Destination HyperlaneMailbox
participant ISM
participant DestinationRouter as Destination MetalayerRouter
participant RecipientApp as Recipient App
SenderApp->>MetalayerRouter: sendMessage(destDomain, recipient, metadata, message)
MetalayerRouter->>MetalayerRouter: encodeMessageWithPackage()
MetalayerRouter->>HyperlaneMailbox: dispatch()
HyperlaneMailbox-->OffchainRelayer: Dispatch event emitted
OffchainRelayer->>DestinationHyperlaneMailbox: handle()
DestinationHyperlaneMailbox->>ISM: verify(metadata, message)
ISM-->>DestinationHyperlaneMailbox: verified
DestinationHyperlaneMailbox->>DestinationRouter: handle()
DestinationRouter->>RecipientApp: handle(metadata, message)
📁 File Overview
File | Description |
---|---|
MetalayerRouter.sol | Main entry point for sending/receiving messages; wraps Hyperlane mailbox. |
MetalayerIsm.sol | CCIP Read ISM used to process n-to-1 offchain reads |
interfaces/IMetalayerRouter.sol | Interface defining the external API for the MetalayerRouter. |
interfaces/IMetalayerRecipient.sol | Interface for contracts receiving messages via Metalayer. |
lib/MetalayerMessage.sol | Defines message encoding and decoding logic. |
✨ Core Concepts
Aggregation ISM (MetalayerIsm)
The Metalayer ISM is an Aggregation ISM that plays a key role in enabling cross-chain reads.
- Offchain relayers collect and aggregate state from one or more source chains.
- The result is encoded and delivered on the destination chain using a CCIP-compatible ISM.
- This ISM validates the aggregated result before forwarding the payload to the recipient app.
The ISM used to verify a message is defined on the destination chain. This means that:
🧠 The destination MetalayerRouter's ISM is what verifies the message, not the sender's.
This allows the destination chain to independently enforce:
- Required finality rules
- Aggregation strategies (eg CCIPReads + Multisig Validator Signing)
Finality Configurations
Supported finality options include:
- Rollup-based finality (e.g., L2 sequencer confirmations).
- Soft confirmations (e.g., N blocks deep RPC-based confirmations).
- Future finality rules defined via ISM.
These rules are enforced at message receipt via the destination ISM.
Package Encoding
Metalayer encodes messages as:
- Metadata: Finality proofs, aggregated read info, etc.
- Payload: Application-level content.
Encoding/decoding logic is defined in MetalayerMessage.sol
.
n-to-1 Cross Chain Reads
Applications can perform reads across multiple source chains, aggregate the result offchain, and deliver the final answer to a single destination chain.
- Relayers act as data aggregators.
- The result is posted onchain using the Aggregation ISM and verified via the CCIP-compatible mechanism.
Fallback Compatibility
Metalayer contracts conform to the same external interface as Hyperlane routers. This allows:
- Seamless integration with Hyperlane-native apps.
- Protocol-level switching between Hyperlane and Metalayer deployments without breaking changes.
Preset ISMs and Fee Hooks
- Each domain may use protocol-defined default ISMs and fee hooks.
- These are configured during deployment to standardize behavior across apps.
- This minimizes misconfiguration risk and improves consistency.
✉️ Messaging Flow
Write Flow
function dispatch(
uint32 _destinationDomain,
address _recipientAddress,
ReadOperation[] memory _reads, // can be empty
bytes memory _writeCallData,
FinalityState _finalityState,
uint256 _gasLimit
) external payable;
- App calls
dispatch
on the source MetalayerRouter. The reads can be empty. - Message and metadata are encoded.
- Hyperlane's
Mailbox
handles cross-chain dispatch. - A offchain Hyperlane relayer aggregates signatures from the Offchain validator and delivers the message the the destination chain.
- The destination Hyperlane
Mailbox
contract recieves the message, and forwards it to the MetalayerRouter - The
Mailbox
verifyies the message using the the ISM set on the destination MetalayerRouter. - The
MetalayerRouter
recieves the message and calls the recipient'shandle
method.
Read Flow (Cross-chain Aggregation)
The read flow is identical to the write, however, the read operations are populated on dispatch
.
When the offchain relayer processes the message, it inspects the ism configration on the
destination chain via an rpc call to modulesAndThreshold
.
function modulesAndThreshold(bytes calldata _message) public view override returns (address[] memory, uint8) {
[ ... ]
FinalityState finalityState = Message.body(_message).finalityState();
if (Message.body(_message).readCount() == 0) {
return finalityState == FinalityState.FINALIZED ? (onlyFinalizedMultisigIsm, 1) : (onlyMultisigIsm, 1);
} else {
return finalityState == FinalityState.FINALIZED ? (bothIsmsFinalized, 2) : (bothIsms, 2);
}
}
This requires a 2/2 agreement between the multisig ism as well as a CCIP Read ISM. This
CCIP Read ISM is implemented in MetalayerIsm.sol
. When this ISM verifies the message using the ISM metadata from the relayer, it verifies that the message payload with the
reads is properly signed, and persists the read payloads in the contract.
Finally, the handle function on the MetalayerRouter
is called by the HyperlaneMailbox
to read, unpack, and deliver the message that is saved on the ISM.
function handle(
uint32 _origin,
bytes32 _sender,
bytes calldata _message // This is the Metalayer message.
) external payable {
require(_sender.bytes32ToAddress() == routerAddresses[_origin], "only router can send hyperlane msg");
require(msg.sender == address(mailbox), "only mailbox can call");
uint256 readCount = _message.readCount();
bytes[] memory results = new bytes[](readCount);
if (readCount > 0) {
bytes memory packedData = metalayerIsm.responseMap(keccak256(_message));
// packedData has structs containing {uint32 length, bytes data}
uint256 offset = 0;
for (uint256 i = 0; i < readCount; i++) {
[ ... unpack reads ]
}
}
// Deliver message to the recipient with reads.
IMetalayerRecipient(_message.recipientAddress()).handle{value: msg.value}(
_message.origin(), _message.senderAddress(), _message.writeCallData(), _message.reads(), results
);
}
🚀 Deployment Instructions
Metalayer uses Foundry for deployment. You will need:
Prerequisites
- Foundry installed (
forge
) - RPC URLs and private key in
.env
- ISM and fee hook config per domain
Steps
- Clone the repo and install dependencies.
- Set up your
.env
file with deployer key and RPC endpoints. - Run the deployment script:
forge script script/MetalayerDeploy.s.sol --rpc-url <RPC> --broadcast --verify -vvvv
Note: Update
DeployMetalayer.s.sol
to configure ISMs, fee hooks, and router defaults.
🧠 Security Notes
- Metalayer leverages Hyperlane's Mailbox for low-level message passing.
- Message verification is performed via the destination chain's ISM, allowing strict control.
- Read aggregation is trust-minimized via CCIP-compatible ISM logic.
- Protocol-enforced hooks/ISMs reduce configuration errors across deployments.
📎 References
- Hyperlane Protocol Docs
- Hyperlane ISMs Overview
- Internal examples:
sample/BlockHeightProvider.sol
,BlockHeightReader.sol