Permissionless Deployment

Everything you need to deploy Hyperlane to a new chain
Hyperlane is designed to be deployed to new chains by anyone, at any time. Read on to learn how to deploy Hyperlane to your favorite EVM chain.

Overview

This tutorial is intended for users who want to deploy Hyperlane to a new EVM chain, so that interchain messages can be sent between that local chain and other remote chains with Hyperlane deployments.
At a high level, this requires the following actions:
  1. 1.
    Deploying the core smart contracts (Mailbox, InterchainGasPaymaster) to the local chain. This script will also deploy and configure an Interchain Security Module on the local chain. Applications may use this ISM to verify interchain messages sent to the local chain.
  2. 2.
    Running one or more validators for the local chain, to provide security for outgoing messages
  3. 3.
    Deploying and configuring Interchain Security Modules on the remote chain(s). Applications will use these ISMs to verify interchain messages sent from the local chain.
  4. 4.
    Running a relayer for the local chain, to deliver interchain messages sent from the local chain to the remote chain(s).
  5. 5.
    Running a relayer for the remote chain(s), to deliver incoming messages sent from the remote chain(s) to the local chain.
  6. 6.
    Testing that messages can be sent from the local chain to each of the remote chains, and vice versa.

1. Deploy the core smart contracts

First, set up the hyperlane-deploy repo. This repo contain scripts to deploy Hyperlane contracts. You will need to install yarn and foundry if you haven't already.
git clone [email protected]:hyperlane-xyz/hyperlane-deploy.git
cd hyperlane-deploy
yarn install
git submodule init && git submodule update --remote
Next, add an empty entry for the local chain to hyperlane-deploy/config/networks.json, e.g.
"foochain": {
// The Chain ID
"id": 123456,
// The address that will own ownable contracts post-deployment.
"owner": "0xfaD1C94469700833717Fa8a3017278BC1cA8031C",
"contracts": {
"proxyAdmin": "",
"mailbox": "",
"interchainGasPaymaster": "",
"create2Factory": "",
"testRecipient": ""
}
},
You can then run the following command to deploy the core contracts to your chain.
# The name of the chain to deploy to. Used to configure the localDomain for the
# Mailbox contract.
export LOCAL=YOUR_CHAIN_NAME
# An RPC url for the chain to deploy to.
export RPC_URL=YOUR_CHAIN_RPC_URL
# Deployer private key, must have a balance to pay for gas
# Any of the following alternatives to --private-key will work
# https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw
export PRIVATE_KEY=YOUR_PRIVATE_KEY
# The comma separated name(s) of the chains to receive messages from.
# Used to configure the default MultisigIsm.
export REMOTES=ethereum,polygon,avalanche,celo,arbitrum,optimism,bsc,moonbeam
forge script scripts/DeployCore.s.sol --broadcast --rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
This script will write a partial Hyperlane agent config to hyperlane-deploy/config/$LOCAL_agent_config.json, which will be used in the following step.
Deployed contract addresses will be written to hyperlane-deploy/config/networks.json

2. Run validators

When using the agent config, the numerical fields index.from and domain must be converted to strings by surrounding them with quotes.
Follow the Validators guide to run validators for the mailbox on your chain. Include the agent config from 1. Deploy the core smart contracts in CONFIG_FILES. If you use docker, you will need to mount the file into the container.
Make sure to collect the validator addresses for use in the next step.

3. Deploy remote ISMs

Using the validator addresses from 2. Run validators, add an entry to hyperlane-deploy/config/multisig_ism.json for the local chain.
This config will be used to deploy a MultisigIsm to each remote chain that you'd like to be able to send messages to. Applications will be able to use this ISM to verify interchain messages sent from the local chain.
Applications using this ISM will only be able to verify messages sent from the chains specified in the REMOTES env var.
# Be sure to deploy a MultisigIsm to each chain that you'd like to be able to
# send messages to.
# This address will wind up owning the MultisigIsm after it's deployed.
export OWNER=0x1234
# The private key that will be used to deploy the contracts. Does not have any
# permissions post-deployment, any key with a balance will do.
# An RPC url for the chain to deploy to.
export RPC_URL=YOUR_CHAIN_RPC_URL
# Deployer private key, must have a balance to pay for gas
# Any of the following alternatives to --private-key will work
# https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw
export PRIVATE_KEY=YOUR_PRIVATE_KEY
# The comma separated name(s) of the chain(s) to receive messages from.
# Probably just the name of your chain.
export REMOTES=YOUR_CHAIN_NAME
forge script scripts/DeployMultisigIsm.s.sol --broadcast --rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
You should see the following output. Save the contract addresses for future use. Applications will be able to use the MultisigIsm to verify messages sent from your chain. You will use the TestRecipient contract to verify that everything is working properly in step 6. Send test messages.
[] Compiling...
[] Compiling 2 files with 0.8.17
[] Solc 0.8.17 finished in 1.36s
Compiler run successful
Script ran successfully.
== Logs ==
MultisigIsm deployed at address 0x5307B8c7A4e8E992ea47126A2F974e65bc43E6e0
TestRecipient deployed at address 0x2952EAB89729522252249d08883449e7CaD21326

4. Run a relayer for the local chain

Similar to 2. Run validators, follow the Relayers instructions to run a relayer for the local chain by including the agent config in CONFIG_FILES
This relayer will deliver messages sent from the local chain to each of the remote chains. Remember to set the HYP_RELAYER_DESTINATIONCHAINNAMESfor your supported remotes appropriately. You will need the validator addresses and S3 bucket names/regions from 2. Run validatorsin order to properly configure the relayer.

5. Run relayer(s) for the remote chain(s)

Reversely, follow the Relayers instructions to run a relayer for each of the remote chains.
These relayers will deliver messages sent from the remote chains to the local chain. Remember to set the HYP_RELAYER_DESTINATIONCHAINNAMESfor your supported remotes appropriately.
You can reference the validator addresses and S3 bucket names/regions needed to configure the relayer in either of the following files: testnet, mainnet.

6. Send test messages

You can check everything is working correctly by sending a test message between each pair of chains.
This script will log the message ID and a link to the message explorer.
The explorer may not properly display your message, as it was sent to a chain that the explorer does not know about.
# An RPC url for the origin chain
export RPC_URL=YOUR_CHAIN_RPC_URL
# Sender private key, must have a balance to pay for gas
# Any of the following alternatives to --private-key will work
# https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw
export PRIVATE_KEY=YOUR_PRIVATE_KEY
# The name of the chain to send the message from.
export ORIGIN=ORIGIN_CHAIN_NAME
# The name of the chain to send the message to.
export DESTINATION=DESTINATION_CHAIN_NAME
# The address of the contract receiving the message.
# If sending to your chain, use the address of the TestRecipient you deployed
# in step 1.
# If sending to a remote chain, use the address of the corresponding TestRecipient
# from step 3.
export RECIPIENT=TEST_RECIPIENT_ADDRESS
# The name of the chain to send the message to, e.g. "hello world"
export BODY=BODY
forge script scripts/SendTestMessage.s.sol --broadcast --rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
If your message is not showing up in the explorer, you can check its delivery status by running the following script:
# The message ID of the message you sent.
export MESSAGE_ID=YOUR_MESSAGE_ID
# An RPC url for the origin chain.
export RPC_URL=YOUR_CHAIN_RPC_URL
# The name of the chain the message was sent to.
export DESTINATION=DESTINATION_CHAIN_NAME
forge script scripts/CheckMessage.s.sol --rpc-url $RPC_URL