# 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 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 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.
Recently the Hermes relayer upgraded the major version to v1. This is the first stable release and contains loads of improvements which you can check out in the changelog (opens new window). It is recommended to use v1 or higher from this point forward, and the commands below assume you are using v1.x.y.
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 into the aforementioned folder.
See the config info (opens new window) and a sample configuration (opens new window) for a detailed explanation on all aspects of the config. 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 for 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 official 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).
# Testing locally
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 use a docker-compose
network with two local checkers
chains and a relayer between them.
The example presented is based on the demo in the b9lab/cosmos-ibc-docker (opens new window) repository.
Start by cloning the repository:
Then build the images for the checkers blockchain if you did not already do so in the Go Relayer section:
You can build the relayer image manually, or just start the network via docker-compose
and let it build the missing image for the hermes
relayer:
Observe the output of docker-compose
until the chains are ready - the chains will take some time.
When the chains are ready, go into the relayer container and run a bash:
First, check the Hermes version with:
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
.
You can find the configuration in cosmos-ibc-docker/tokentransfer/relayer_hermes/config.toml
.
You will see two [[chains]]
sections in the config.toml
. The first one includes comments about configuration.
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 demo includes a script to start the relayer, but do the steps manually to practice a bit.
# Manual testing - setting up relayer keys
You need some keys to sign a transaction. Populate the aliases:
Get the user addresses for the checkersa chain:
Now get the user addresses for the checkersb chain:
In the config.toml
the default user key is set to alice
for checkersa
and bob
for checkersb
, so you do not need to specify a user if you want to sign a transaction with those.
Now check the balance of those accounts in another terminal:
# Manual testing - create a channel
It is time to create a channel in order to send some tokens from checkersa
to checkersb
. In the relayer container, run:
To query the clients for the chain checkersa, run:
There should be one CometBFT client for the chain checkersb.
Query the connections for checkersa:
There should be one connection established between checkersa and checkersb.
Query the channels for checkersa:
You should see one channel and the port binding transfer. All this is part of the create channel
command. It will create a client, a connection, and a channel as well as a binding to a port. You can redo some steps to better understand the CLI.
Create another connection for both chains:
In the output of this command, you receive the connection_id
s for both chains. Use the connection_id
for the checkersa chain and create a channel:
This repeats the port binding transfer
. Check that the channel is created again with:
# Manual testing - send an IBC transfer
Next up, send an IBC transfer using the second 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, you want to relay the transfer transaction by hand.
First, query packet commitments on checkersa:
You can see that there is one packet:
You can also query for unreceived packets:
The output should be similar to:
There you can observe an unreceived packet.
You can get the connection_id
and channel_id
for checkersb 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 checkersa. You should see no change in the balance of bob
on checkersb because the transfer is initiated but it is not relayed yet.
Now submit the RecvPacket
message to checkersb:
In case of success, you will see an output like:
Send an acknowledgement to checkersa:
Check the balances again. A new denom should appear because of the recent transfer. As an exercise, transfer the tokens back to checkersa.
If you are finished with the tests, make sure to shut down your network with:
To summarize, this section has explored:
- Hermes, an open-source Rust implementation of an IBC relayer, which is widely used in production by relayer operators due to its great logging and debugging options, but may require more detailed knowledge of IBC for effective use.
- How to install and configure Hermes, and then perform automated and manual end-to-end testing of Docker containers for two-chain instances and a relayer instance.