# Hermes Relayer
Before you dive into Go relayers, make sure to:
- Install Go.
- Install Docker.
- Install Rust.
For all installations, please see the setup page.
In this section, you will learn:
- How to get started with the Hermes relayer
- Basic Hermes relayer commands
Hermes (opens new window) is a an open-source Rust implementation of a relayer for the Inter-Blockchain Communication Protocol (IBC). Hermes is most widely used in production by relayer operators. It offers great logging and debugging options, but compared to the Go relayer may require some more detailed knowledge of IBC to use it properly.
Installation instructions can be found in the Hermes documentation from Informal Systems (opens new window). Check the CLI commands with hermes -h
. Alternatively, check out the commands reference (opens new window) on the Hermes website.
If you type:
You get:
When comparing the list of commands with the requirements from the introduction, recognize the ability to query and submit a transaction (tx), keys management, and a config command. However, no immediate commands are available to add chains and path information. The Hermes relayer does not support fetching data from the chain-registry (opens new window) automatically yet, but this is on the roadmap.
For now, you need to manually add the data to the config file config.toml
, which is by default stored at $HOME/.hermes/config.toml
.
The config is not added automatically. The first time you run Hermes, you will have to copy a template and paste it in the aforementioned folder.
See the config info (opens new window) and the a sample configuration (opens new window) for a detailed explanation on all aspects of the config. We will take a closer look at the [[chains]]
section:
Pay particular attention to the RPC
, gRPC
, and websocket
endpoints and make sure they correspond with the node you are running. Remember that it is recommended to run your own full node instead of using publicly available endpoints when relaying outside of testing purposes. Also make sure the key_name
corresponds to the funded address from which you intend to pay relayer fees. The other parameters can be found in the chain-registry (opens new window) for deployed chains, or set by yourself when creating a new chain (either in production or for testing).
Hermes does not require path information in the config. By default it will relay over all possible paths over all channels that are active on the configured chains. However, it is possible to change this by filtering. Add the following to the chain config:
This filters only the transfer
channel for the Hub to Osmosis in this example.
# Hermes Start
When the chains have been configured, you can start the relayer with the start command:
This powerful command bundles a lot of functionality where Hermes will be listening or events signaling IBC packet send requests, submitting ReceivePacket
and AcknowledgePacket
messages, and periodically checking if the clients on serviced chains need updating. However, during the tutorials it makes sense to look at the commands in a more granular way to understand what is going on.
When starting the Hermes relayer, it will assume that the channels you wish to relay over are set up. This will be the case if you want to start relaying on an existing canonical channel, meaning the offical and agreed-upon channel (for example, used for fungible token transfers).
This is perfectly possible and the right approach, given that creating a new channel would make assets relayed over it non-fungible with assets relayed over the canonical channel. Most tutorials will create new channels (and possibly clients and connections) as this provides more insight into the software. However, it is important to note that you only need to create new channels if no canonical channel is present (for example, for a newly deployed chain).
# E2E Testing
The Hermes documentation provides a guided tutorial (opens new window) to start relaying between two local gaia
chains. Furthermore, demos are available that spin up a Hermes relayer between two Ignite CLI (opens new window) chains, like this one (opens new window). Be sure to check those out.
Here you will take a somewhat different approach, and set up a flow for end-to-end (E2E) testing where you set up Docker containers for 2 chain instances and a relayer instance. You will refer to the automated testing file and also do some manual testing on the Docker images.
# Installation & Building Docker Images
Clone the Hermes repository (opens new window) in a new folder. It contains a folder for end-to-end (E2E) testing (opens new window). This helps you deploy two chains and test the relayer. It also contains a Docker Compose file, which spins up two blockchain nodes and a relayer.
Make sure that you have installed Docker Compose (opens new window) and Docker (opens new window) before continuing.
The test needs you to build the Docker images from the Docker files. The Docker images run a Linux on x86_64. You can build Hermes with Cargo (opens new window) from the repository for the target x86_64-unknown-linux-gnu
, or you can download (opens new window) a release version into the repository folder (make sure the binary is present in the repository folder).
After you clone the repository and download a release version of Hermes for x86_64, go into the folder and run:
This builds the relayer docker image. Start the Docker Compose network with two chains and a relayer:
Check that everything is working as expected:
The e2e.sh
(opens new window) uses run.py
(opens new window) to automatically run a couple of tests.
# Hermes CLI Manual Testing
Go into the relayer container and run a bash:
First, check the Hermes version with:
Which returns:
In this section you have to run commands both inside the Docker container and on your local terminal. By default, coding examples will indicate the Docker terminal; a comment will inform you when you have to use the local terminal.
You can check the CLI commands with hermes -h
. The Hermes CLI offers help for each CLI command you can use when trying hermes <command> -h
.
Check the default configuration:
In the [[chains]]
section of the simple_config.toml
, you can find the configuration for two chains, ibc-0 and ibc-1. In it, the chain IDs need to be specified, as well as the RPC, GRPC, and WebSocket addresses.
Do a validation check on the configuration file:
Next do a health check:
You should see that both chains are healthy. The E2E test will create clients, connections, and a channel.
To query the clients for the chain ibc-0, run:
There should be one Tendermint client for the chain ibc-1.
Query the connections for ibc-0:
There should be two connections, both established between ibc-0 and ibc-1.
Query the channels for ibc-0:
You should see two channels and the port binding transfer. All this is part of the E2E testing. You can redo some steps to better understand the CLI.
Create another connection for the both chains:
In the output of this command you receive the connection_id
s for both chains. Use the connection_id
for the ibc-0 chain and create a channel:
This repeats the port binding transfer
. Check that the channel is created again with:
The E2E testing already created some accounts (via keys add testkey --output json
) for the tests and added them to the Hermes relayer via:
Get the user addresses for the ibc-0 chain:
Now get the user addresses for the ibc-1 chain:
In the simple_confing.toml
the default user key is set to testkey
, so you do not need to specify a user if you want to sign a transaction with testkey
.
Now check the balance of those accounts on the chain ibc-0. Replace the $testkey
with the addresses you get in your test:
Repeat this check for ibc-1 with the corresponding address.
These accounts keep some samoleans. You will also see another denom because of the E2E test.
Please see the fungible token transfers section for more information on the IBC denom.
Do a transfer and use the channel that was created:
In case you do not want to test with the default user, you can specify the sender with a -k
flag and the receiver on the other chain with a -r
flag.
Usually the Hermes relayer automatically relays packets between the chains if it runs via:
In this case, we want to relay the transfer transaction by hand.
First, query packet commitments on ibc-0:
You can see that there is one packet.
You can also query for unreceived packets:
You can get the connection_id
and channel_id
for ibc-1 in the output of the hermes create connection
and hermes create channel
commands.
If you check the balances again, you should only see a change for ibc-0. You should see no change in the balance of testkey
on ibc-1 because the transfer is initiated but it is not relayed yet.
Now submit the RecvPacket
message to ibc-1:
Send an acknowledgement to ibc-0:
Check the balances again. A new denom should appear because of our recent channel. As an exercise, transfer the tokens back to ibc-0.
# Next up
With this introduction to the Hermes relayer, you are all set for relaying. In the next section, you can find an overview of helpful tools for IBC.