Deploy an SVM Warp Route
Outcomesβ
You will be deploying a Warp Route for an asset of your choice, between two SVM chains with an existing Hyperlane core deployment. At the time of writing this document, supported SVM chains are Solana and Eclipse, but you can find an up-to-date list here (all chain directory names with a core
subdirectory).
If you want your SVM rollup supported as a core Hyperlane deployment, or are looking to set up an EVM to SVM Warp Route, get in touch!
Warp Route Typesβ
The type of token used determines the Warp Route type, so it's important to understand the different Warp Route contracts available:
- Native: Handles the transfer of native gas tokens (e.g. SOL on Solana, ETH on Eclipse).
- Collateral: Handles the transfer of existing Token-2022 or Token tokens (the ERC20 equivalent on SVM).
- Synthetic: Handles synthetic tokens that are minted and burned as transfers occur through the Warp Route, to represent tokens from their origin chain. The tooling in this guide deploys a new Token-2022 token in this case, whose authority is set to the deployer key.
Here are the common Warp Route setups (you can find more details here):
- Native to Synthetic: Lock Native tokens on the origin chain to mint Synthetic ones on the destination. When transferring back, the Synthetic is burned. An example of this is a SOL Warp Route between Solana and Eclipse.
- Collateral to Synthetic: Lock Collateral tokens on the origin chain to mint Synthetic ones on the destination. When transferring back, the Synthetic is burned. An example of this is a USDC Warp Route between Solana and Eclipse.
- Other: Native to Native (such as ETH between Optimism and Arbitrum), as well as Collateral to Collateral, are also possible if the token already exists on both origin and destination chains. Rebalancing liquidity is an important consideration in this case.
Before You Startβ
Deploying a Warp Route requires there to be a core Hyperlane deployment that is connected (i.e. actively relayed and secured) to the rest of the Hyperlane ecosystem. The core Hyperlane deployments used in this guide are Solana (core artifacts) and Eclipse (core artifacts). You may need to refer to these core artifacts throughout the guide.
Walkthrough: Deploy a Sealevel Warp Routeβ
Step 1: Build the Warp Route Programsβ
-
Install
solana-cli 1.14.20
to build the Warp Route programs. Note that you must use this version, otherwise deployment may fail.sh -c "$(curl -sSfL https://release.solana.com/v1.14.20/install)"
-
Clone the hyperlane-monorepo
git clone https://github.com/hyperlane-xyz/hyperlane-monorepo
cd hyperlane-monorepo/rust/sealevel/programs -
Build the Warp Route programs on your machine
-
Build the Token program:
cd hyperlane-sealevel-token
cargo build-sbf -
Build the Token Collateral program:
cd hyperlane-sealevel-token-collateral
cargo build-sbf -
Build the Token Native program:
cd hyperlane-sealevel-token-native
cargo build-sbf
These steps compile the Solana programs, which is needed for deployment. To verify the build output, check the target/deploy directory for
.so
files inhyperlane-monorepo/rust/sealevel/target/deploy
-
Step 2: Prepare for Deploymentβ
-
To deploy the contracts, install
solana-cli 1.18.18
. Note that you must use this version, otherwise deployment may fail.sh -c "$(curl -sSfL https://release.solana.com/v1.18.18/install)"
After installing you can verify the version with:
solana --version
-
Create a Solana keypair. This key pays for the deployment and will be the owner of the deployed programs. An existing funded key can be used if you'd like.
solana-keygen new --outfile ./warp-route-deployer-key.json
-
To read the public key you just created:
solana-keygen pubkey ./warp-route-deployer-key.json
-
Check the balance:
solana balance --keypair ./warp-route-deployer-key.json
-
Step 3: Configure the Warp Routeβ
-
Create a directory for your Warp Route in
rust/sealevel/environments/mainnet3/warp-routes
with the name you want your Warp Route deployment to have.mkdir -p rust/sealevel/environments/mainnet3/warp-routes/<YOUR-WARP-ROUTE-NAME>
For example, the existing SOL Warp Route between Solana and Eclipse lives in
rust/sealevel/environments/mainnet3/warp-routes/eclipsesol
. -
Inside the directory you just created, create a configuration file named
token-config.json
.Configure the parameters of your Warp Route based on the
serde_json
serialization of the TokenConfig Rust struct. The value to set for theinterchainGasPaymaster
, can be found in the core deployment artifacts.The example below shows a testnet Native to Synthetic Warp Route that transfers SOL from Solana and mints synthetic SOL on Eclipse. You can also check this configuration of a production SOL Warp Route.
{
"solanatestnet": {
"type": "native",
"decimals": 9,
"interchainGasPaymaster": "<from core program addresses, choose the overhead igp>"
},
"eclipsetestnet": {
"type": "synthetic",
"decimals": 9,
"name": "Solana (testnet)",
"symbol": "SOL",
"uri": "<permalink to the metadata.json file you merged into hyperlane-registry>"
"interchainGasPaymaster": "<from core program addresses, choose the overhead igp>"
}
} -
(Optional) If your warp route creates a Synthetic token, you can open a PR to the
hyperlane-registry
with metadata to associate with this token (example PR here). Thehyperlane-registry
also gives your Warp Route visibility within the Hyperlane ecosystem.
Step 4: Deploy the Warp Routeβ
-
Fund the new keypair on both networks the Warp Route is being deployed to.
-
The public key should be the same across SVM networks, but double check with the wallets recommended by each chain, by loading the private key into them.
-
The funding should be enough to cover rent for all accounts related to the Warp Route, pay for transaction fees, and fund the ATA payer accounts (more on this below). For reference, the observed rent from one Hyperlane Warp Route account is
2.35 SOL
on Solana and0.025 ETH
on Eclipse, so it's a good idea to fund the key with at least5 SOL
/0.05 ETH
.
-
-
Deploy the warp route using the
warp-route deploy
subcommand from therust/sealevel/client
directory:Example usage:
cargo run -- -k ./warp-route-deployer-key.json \
warp-route deploy \
--warp-route-name <YOUR-WARP-ROUTE-NAME> \
--environment mainnet3 \
--environments-dir ../environments \
--built-so-dir ../target/deploy \
--token-config-file ../environments/mainnet3/warp-routes/<YOUR-WARP-ROUTE-NAME>/token-config.json \
--chain-config-file ../environments/mainnet3/chain-config.json \
--ata-payer-funding-amount 10000000- Overview of CLI flags:
--warp-route-name
: should match the directory name picked for the Warp Route earlier--environment
: keep asmainnet3
--environments-dir ../environments
: keep as../environments
--built-so-dir
: keep as../../target/deploy
, as it points to the compilation output directory of Warp Route programs--token-config-file
: point this to thetoken-config.json
file created earlier--chain-config-file
: keep as../environments/mainnet3/chain-config.json
, as this file has been pre-populated with chain settings for all Hyperlane-supported chains--ata-payer-funding-amount
: this flag specifies by how much to fund the Warp Route ATA payer accounts on both chains the deployment happens on. It's expressed in the lowest currency denomination, which means that it's interpreted as Lamports on Solana and Gwei on Eclipse (since it uses ETH as its native currency). In the command below, the value10000000
works out to0.001
ETH and0.001
SOL, which is enough for an initial deployment. ATA payers can always be topped up later, so itβs fine to pick a small value. For reference, every Warp Route transfer costs the ATA payer0.000000001 SOL
(on Solana) and0.000021 ETH
(on Eclipse) on the destination chain.
infoNote that since our goal was to make this tooling accessible to developers as soon as possible, it's not as reliable as we would hope. Please get in touch through a GitHub issue or via the
developers
channel on Discord if you run into issues.Troubleshotting tipsβ
-
The script is unlikely to work from the first try due to network congestion and program size, but the script should be idempotent and skip contracts that were already deployed/initialized.
-
Errors like
Error: 11 write transactions failed
orError: Custom: Invalid blockhash
can always be retried by re-running the command. If retriable errors persist, consider increasing the compute unit price here. -
For other error types, you may need to close the buffers and programs of your deployer key and redeploy everything from scratch. To display buffers and programs and close them one by one, follow the commands below. Closing programs also helps recover their rent deposit.
solana program show --programs --keypair ./warp-route-deployer-key.json --url <CHAIN_RPC_URL>
solana program show --buffers --keypair ./warp-route-deployer-key.json --url <CHAIN_RPC_URL>
# You'll need to add the `--bypass-warning` flag when closing program accounts (as opposed to closing buffers)
solana program close <YOUR_PROGRAM_ADDRESS> --url <CHAIN_RPC_URL>
-
-
To increase the odds of the deployment succeeding faster, you can set a private RPC url in the
--chain-config-file
passed to the script. (e.g. insolanamainnet.rpcUrls.http
) -
If deploying a synthetic token, the command below will create a new token mint and use the metadata token extension to set the token name, symbol, and metadata json using the fields in the
--token-config-file
file, runwarp-route deploy
:# run from `rust/sealevel/client`
cargo run -- -k ./warp-route-deployer-key.json warp-route deploy \
--warp-route-name eclipsesol \
--environment mainnet3 \
--environments-dir ../environments \
--built-so-dir ../../target/deploy \
--token-config-file ../environments/mainnet3/warp-routes/eclipsesol/token-config.json \
--chain-config-file ../environments/mainnet3/chain-config.json \
--ata-payer-funding-amount 10000000
- Overview of CLI flags:
Interacting with the Warp Routeβ
-
Query the Warp Route Program
You can check the program details like Mint Account, Mint Authority, and ATA payer account using the following command:
# run from `rust/sealevel/client`
cargo run -- -k ./warp-route-deployer-key.json \
-u <CHAIN_RPC_URL> token query \
--program-id <PROGRAM_ID> <TOKEN_TYPE>Replace:
<CHAIN_RPC_URL>
: e.g., https://api.devnet.solana.com<PROGRAM_ID>
: base58 address from program-ids.json (located in your warp-route directory).<TOKEN_TYPE>
: native|synthetic|collateral
If deploying a synthetic token, query the Mint Authority account to check out the metadata:
solana account <MINT_AUTHORITY> --url <CHAIN_RPC_URL>
-
Transfer Tokens Through the Warp Route
To test token transfers across chains, run the following command:
# run from `rust/sealevel/client`
cargo run -- -u <ORIGIN_CHAIN_RPC_URL> \
-k ./warp-route-deployer-key.json \
token transfer-remote ./warp-route-deployer-key.json \
<AMOUNT_IN_LOWEST_DENOM> <DESTINATION_CHAIN_DOMAIN_ID> <RECIPIENT_ADDRESS> \
<WARP_TOKEN_TYPE_ON_ORIGIN_CHAIN> --program-id <PROGRAM_ID><DESTINATION_CHAIN_DOMAIN_ID>
: You'll need the domain ID of the chain you're sending to, which you can find in the chain'smetadata.yaml
entry from the hyperlane-registry.<PROGRAM_ID>
: base58 address from program-ids.json (located in your warp-route directory).<WARP_TOKEN_TYPE_ON_ORIGIN_CHAIN>
: Type of token on the origin chain, options are: native|synthetic|collateral
-
Verify the Balance on the Destination Chain
Look for the balance of the recipient on the destination chain, by querying the Mint Account address:
spl-token balance --owner ./warp-route-deployer-key.json \
-u <DESTINATION_CHAIN_RPC_URL> <MINT_ACCOUNT_ADDRESS>- The final parameter here is the SPL token ID. So if this is a synthetic warp route you want to check the balance of, you need to use the Mint address from a prior query you made a few steps ago.
- You can also check out the last tx made to the recipient account in the explorer
-
Explore Additional CLI Commands
This guide has made heavy use of the
hyperlane-sealevel-client
CLI fromhyperlane-monorepo
. You may find its various commands useful for configuring the Warp Route, making state queries, sending transfers, and more. Check out the other utilities it provides, in particular those under thetoken
subcommand.# run from `rust/sealevel/client`
cargo run -- --help
For production deployments, we strongly recommend avoiding the use of hotkeys like those used in this guide. Instead, transfer ownership to a multisig setup, such as Squads, for enhanced security.