> ## 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.

# Deploy an SVM HWR

## Outcomes

You will be deploying a Hyperlane Warp Route (HWR) 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](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/sealevel/environments/mainnet3) (all chain directory names with a `core` subdirectory).

<Info>
  **Looking for cross-VM guides?** See:

  * [EVM ↔ SVM Warp Route Guide](/docs/guides/warp-routes/evm-svm-warp-route-guide)
  * [Cosmos ↔ SVM Warp Route Guide](/docs/guides/warp-routes/cosmos-svm-warp-route-guide)

  If you want your SVM rollup supported as a core Hyperlane deployment, [get in touch](https://forms.gle/KyRTaWvo4XNmNvrq6)!
</Info>

## HWR Types

The type of token used determines the HWR type, so it's important to understand the different HWR contracts available:

* [Native](/docs/protocol/warp-routes/warp-routes-types#native-token-hwrs): Handles the transfer of native gas tokens (e.g. SOL on Solana, ETH on Eclipse).
* [Collateral](/docs/protocol/warp-routes/warp-routes-types#collateral-backed-erc20-hwr): Handles the transfer of existing [Token-2022](https://spl.solana.com/token-2022) or [Token](https://spl.solana.com/token) tokens (the ERC20 equivalent on SVM).
* [Synthetic](/docs/protocol/warp-routes/warp-routes-types#synthetic-erc20-hwr): Handles synthetic tokens that are minted and burned as transfers occur through the HWR, 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 HWR setups (you can find more details [here](/docs/protocol/warp-routes/warp-routes-example-usage)):

* **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 HWR 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 HWR 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 HWR 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](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/environments/mainnet3/solanamainnet/core/program-ids.json)) and Eclipse ([core artifacts](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/environments/mainnet3/eclipsemainnet/core/program-ids.json)). You may need to refer to these core artifacts throughout the guide.

## Walkthrough: Deploy a Sealevel HWR

### Step 1: Build the HWR Programs

1. Clone the [hyperlane-monorepo](https://github.com/hyperlane-xyz/hyperlane-monorepo)

   ```bash theme={null}
   git clone https://github.com/hyperlane-xyz/hyperlane-monorepo
   cd hyperlane-monorepo/rust/sealevel/programs
   ```

2. Build the HWR programs on your machine.

   <Note>
     The `./build-programs.sh` script handles installing and using the required
     Solana CLI version automatically.
   </Note>

   ```bash theme={null}
   # run from this directory
   cd rust/sealevel/programs
   # build the token programs
   ./build-programs.sh token
   ```

   This [script](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/programs/build-programs.sh) will **compile the Solana programs**, which is needed for deployment. It will use the required Solana CLI version (`3.0.14`) automatically and reset back to the previously used version afterward.

   To verify the build output, check the target/deploy directory for `.so` files in `hyperlane-monorepo/rust/sealevel/target/deploy`

### Step 2: Prepare for Deployment

1. To deploy the contracts, install `solana-cli 3.0.14`. Note that you **must** use this version, otherwise deployment may fail.

   ```bash theme={null}
   sh -c "$(curl -sSfL https://release.anza.xyz/v3.0.14/install)"
   ```

   After installing you can verify the version with:

   ```bash theme={null}
   solana --version
   ```

2. 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.

   ```bash theme={null}
   solana-keygen new --outfile ./warp-route-deployer-key.json
   ```

   * To read the public key you just created:

     ```bash theme={null}
     solana-keygen pubkey ./warp-route-deployer-key.json
     ```

   * Check the balance:
     ```bash theme={null}
     solana balance --keypair ./warp-route-deployer-key.json
     ```

### Step 3: Configure the HWR

1. Create a directory for your HWR in `rust/sealevel/environments/mainnet3/warp-routes` with the name you want your HWR deployment to have.

   ```bash theme={null}
   mkdir -p rust/sealevel/environments/mainnet3/warp-routes/<YOUR-WARP-ROUTE-NAME>
   ```

   For example, the existing SOL HWR between Solana and Eclipse lives in `rust/sealevel/environments/mainnet3/warp-routes/eclipsesol`.

2. Inside the directory you just created, create a configuration file named `token-config.json`.

   Configure the parameters of your HWR based on the `serde_json` serialization of the [TokenConfig](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/a5afd20f3ae69ccb3289d845d44b99dbdcde2c62/rust/sealevel/client/src/warp_route.rs#L114) Rust struct. The value to set for the `interchainGasPaymaster`, can be found in the [core deployment artifacts](#before-you-start).

   The example below shows a testnet **Native to Synthetic HWR** that transfers SOL from Solana and mints synthetic SOL on Eclipse. You can also check [this configuration](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/a5afd20f3ae69ccb3289d845d44b99dbdcde2c62/rust/sealevel/environments/mainnet3/warp-routes/eclipsesol/token-config.json) of a production SOL HWR.

   ```json theme={null}
   {
       "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>"
       }
   }
   ```

3. (Optional) If your HWR creates a Synthetic token, you can open a PR to the `hyperlane-registry` with metadata to associate with this token (example PR [here](https://github.com/hyperlane-xyz/hyperlane-registry/pull/142)). The `hyperlane-registry` also gives your HWR visibility within the Hyperlane ecosystem.

### Step 4: Deploy the HWR

1. Fund the new keypair on both networks the HWR 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 HWR, pay for transaction fees, and fund the [ATA](https://www.alchemy.com/overviews/associated-token-account) payer accounts (more on this below). For reference, the observed rent from one HWR account is `2.35 SOL` on Solana and `0.025 ETH` on Eclipse, so it's a good idea to fund the key with at least `5 SOL` / `0.05 ETH`.

2. Deploy the HWR using the `warp-route deploy` subcommand from the `rust/sealevel/client` directory:

   Example usage:

   ```bash theme={null}
   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 \
   --registry ~/path/to/your/local/hyperlane-registry \
   --ata-payer-funding-amount <REASONABLE-FUNDING-AMOUNT>
   ```

<Warning>
  Please choose a reasonable amount to fund the HWR ATA payer accounts. The
  recommended initial funding amount is `alert_threshold * 2`, with the
  threshold value found
  [here](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/infra/src/warp/helm.ts).
</Warning>

* Overview of CLI flags:
  * `--warp-route-name`: should match the directory name picked for the HWR earlier
  * `--environment`: keep as `mainnet3`
  * `--environments-dir ../environments`: keep as `../environments`
  * `--built-so-dir`: keep as `../target/deploy`, as it points to the compilation output directory of HWR programs
  * `--token-config-file`: point this to the `token-config.json` file created earlier
  * `--registry`: path to your local clone of the hyperlane-registry
  * `--ata-payer-funding-amount`: this flag specifies by how much to fund the HWR [ATA](https://www.alchemy.com/overviews/associated-token-account) 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 value `1000000` works out to `0.001` ETH and `0.001` SOL, which is enough for an initial deployment, but not for production usage. ATA payers can always be topped up later. For reference, every HWR transfer costs the ATA payer `0.000000001 SOL` (on Solana) and `0.000021 ETH` (on Eclipse) on the destination chain.

<Info>
  Note 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](https://github.com/hyperlane-xyz/hyperlane-monorepo/issues) or via the
  [GitHub
  Discussions](https://github.com/hyperlane-xyz/hyperlane-monorepo/discussions)
  if you run into issues.
</Info>

#### Troubleshooting 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` or `Error: Custom: Invalid blockhash` can always be retried by re-running the command. If retriable errors persist, consider increasing the compute unit price [here](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/44e0ff0733baf0da4d2b0304915f5f6cce92ffc7/rust/sealevel/client/src/cmd_utils.rs#L76).

  * 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.

    ```bash theme={null}
    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 configure a private RPC URL in your local clone of the hyperlane-registry. (e.g. in `solanamainnet.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, run `warp-route deploy`:
  ```bash theme={null}
  # 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  \
   --registry ~/path/to/your/local/hyperlane-registry \
   --ata-payer-funding-amount 10000000
  ```

## Interacting with the HWR

1. **Query the HWR Program**

   You can check the program details like Mint Account, Mint Authority, and ATA payer account using the following command:

   ```bash theme={null}
   # 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](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:

   ```bash theme={null}
   solana account <MINT_AUTHORITY> --url <CHAIN_RPC_URL>
   ```

2. **Transfer Tokens Through the HWR**

   To test token transfers across chains, run the following command:

   ```bash theme={null}
   # 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's `metadata.yaml` entry from the [hyperlane-registry](https://github.com/hyperlane-xyz/hyperlane-registry/tree/main/chains).
   * `<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

3. **Verify the Balance on the Destination Chain**

   Look for the balance of the recipient on the destination chain, by querying the Mint Account address:

   ```bash theme={null}
   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 HWR 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

4. **Explore Additional CLI Commands**

   This guide has made heavy use of the `hyperlane-sealevel-client` CLI from `hyperlane-monorepo`. You may find its various commands useful for configuring the HWR, making state queries, sending transfers, and more. Check out the other utilities it provides, in particular those under the `token` subcommand.

   ```bash theme={null}
   # run from `rust/sealevel/client`
   cargo run -- --help
   ```

<Warning>
  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](https://squads.so/), for enhanced security.
</Warning>
