IBC Relaying Guide
Pryzm uses IBC (Inter-Blockchain Communication protocol) to enable cross-chain transfer of tokens. To support this capability it relies on relayers, processes that can be run by anyone which constantly scan for outbound packets on one chain and submits these packets alongside corresponding proofs on the destination chain. This section describes how one can setup a relayer and create new connections between chains. There are two standard implementations:
- Hermes built in Rust
- Go Relayer built in Go
The following guide explains how to establish IBC connections and relay packets between Pryzm mainnet and Cosmos hub mainnet networks by using the Hermes relayer.
Hermes
Hermes is an open-source
Rust implementation of an IBC relayer released as part of the
ibc-relayer-cli
crate. It includes a CLI for relaying packets between
Cosmos SDK chains, as well as Prometheus metrics and a REST API.
Please follow the steps at Hermes Quick Start
to install Hermes. Before proceeding, verify that Hermes is installed correctly by
running hermes version
.
Configuration
After you have successfully installed Hermes and created the necessary folders,
you now have to edit config.toml
and add the appropriate configurations for
the chains you want to relay between.
For this tutorial, we will be using the following chains:
- Pryzm's
pryzm-1
mainnet - Cosmos Hub's
cosmoshub-4
mainnet
Edit the Hermes configuration.
vim $HOME/.hermes/config.toml
[global]
log_level = "info"
[mode.clients]
enabled = true
refresh = true
misbehaviour = true
[mode.connections]
enabled = false
[mode.channels]
enabled = false
[mode.packets]
enabled = true
clear_interval = 100
clear_on_start = true
tx_confirmation = false
auto_register_counterparty_payee = false
[rest]
enabled = false
host = "127.0.0.1"
port = 3000
[telemetry]
enabled = false
host = "127.0.0.1"
port = 3001
[telemetry.buckets.latency_submitted]
start = 500
end = 20000
buckets = 10
[telemetry.buckets.latency_confirmed]
start = 1000
end = 30000
buckets = 10
[[chains]]
id = "cosmoshub-4"
type = "CosmosSdk"
rpc_addr = "[ COSMOS_RPC_ENDPOINT ]"
grpc_addr = "[ COSMOS_GRPC_ENDPOINT ]"
rpc_timeout = "10s"
trusted_node = false
account_prefix = "cosmos"
key_name = "[ KEY_NAME ]"
key_store_type = "Test"
store_prefix = "ibc"
default_gas = 100000
max_gas = 400000
gas_multiplier = 1.5
max_msg_num = 30
max_tx_size = 180000
max_grpc_decoding_size = 33554432
clock_drift = "5s"
max_block_time = "30s"
ccv_consumer_chain = false
memo_prefix = ""
sequential_batch_tx = false
[chains.event_source]
mode = "push"
url = "[ COSMOS_WS_ENDPOINT ]"
batch_delay = "500ms"
[chains.trust_threshold]
numerator = "1"
denominator = "3"
[chains.gas_price]
price = 0.025
denom = "uatom"
[chains.packet_filter]
policy = "allowall"
[chains.packet_filter.min_fees]
[chains.address_type]
derivation = "cosmos"
[[chains]]
id = "pryzm-1"
type = "CosmosSdk"
rpc_addr = "[ PRYZM_RPC_ENDPOINT ]"
grpc_addr = "[ PRYZM_GRPC_ENDPOINT ]"
rpc_timeout = "10s"
trusted_node = false
account_prefix = "pryzm"
key_name = "[ KEY_NAME ]"
key_store_type = "Test"
store_prefix = "ibc"
default_gas = 100000
max_gas = 3000000
gas_multiplier = 1.5
max_msg_num = 30
max_tx_size = 180000
max_grpc_decoding_size = 33554432
clock_drift = "5s"
max_block_time = "30s"
ccv_consumer_chain = false
memo_prefix = ""
sequential_batch_tx = false
[chains.event_source]
mode = "push"
url = "[ PRYZM_WS_ENDPOINT ]"
batch_delay = "500ms"
[chains.trust_threshold]
numerator = "1"
denominator = "3"
[chains.gas_price]
price = 0.1
denom = "factory/pryzm1jnhcsa5ddjsjq2t97v6a82z542rduxvtw6wd9h/uauuu"
[chains.packet_filter]
policy = "allowall"
[chains.packet_filter.min_fees]
[chains.address_type]
derivation = "cosmos"
Add relayer wallets
Now that we have successfully configured our relaying chains, we need to import the wallets that will be used for relaying. Please note that both wallets need to be funded with the native tokens of each chain.
Add your seed phrase to a file and upload it to the server. Do not use wallets for anything else but relaying to avoid running into account sequence errors.
Follow the steps at adding-keys-to-hermes to add keys for each chain
hermes keys add --chain pryzm-1 --mnemonic-file <seed-file>
hermes keys add --chain cosmoshub-4 --mnemonic-file <seed-file>
Verify configuration files
After editing config.toml
and adding wallet keys, it’s time to
test the configurations and ensure the system is healthy. Run the following:
hermes health-check
hermes config validate
If everything was set up correctly, you should see output like:
SUCCESS performed health check for all chains in the config
SUCCESS "configuration is valid"
Create a connection between 2 chains
If you’re attempting to create new connections, verify that the chains in question don’t already have connections and clients in place and use the existing ones if they do. In that case you can skip this step and go to Configure channels in Hermes section.
In this example, we are creating new clients and a new connection between pryzm-1
and cosmoshub-4
networks.
Create clients
To learn if a client already exists, you can use the following command:
hermes query clients --host-chain pryzm-1 --reference-chain cosmoshub-4
To create a new client, use the
create-client
command:
hermes create client --host-chain pryzm-1 --reference-chain cosmoshub-4
Create a second client:
hermes create client --host-chain cosmoshub-4 --reference-chain pryzm-1
Open connection over new clients
To create a new connection over clients, use the following command:
hermes create connection --a-chain pryzm-1 --b-chain cosmoshub-4
You should be seeing a similar output to this:
SUCCESS Connection {
delay_period: 0ns,
a_side: ConnectionSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "cosmoshub-4",
version: 0,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-2241",
),
connection_id: Some(
ConnectionId(
"connection-6473",
),
),
},
b_side: ConnectionSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "pryzm-1",
version: 4,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-10",
),
connection_id: Some(
ConnectionId(
"connection-10",
),
),
},
}
Now that the connection has been established over the clients, we need to create a new channel, by leveraging an existing connection:
hermes create channel --a-chain cosmoshub-4 --a-connection connection-6473 --a-port transfer --b-port transfer
You should be seeing a similar output to this:
SUCCESS Channel {
ordering: Unordered,
a_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "cosmoshub-4",
version: 0,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-2241",
),
connection_id: ConnectionId(
"connection-6473",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
"channel-100",
),
),
version: None,
},
b_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "pryzm-1",
version: 4,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-10",
),
connection_id: ConnectionId(
"connection-10",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
"channel-0",
),
),
version: None,
},
connection_delay: 0ns,
}
You have successfully created a new IBC connection between two networks.
Configure channels in Hermes
Now that we have created new connections and opened channels, we need to
edit config.toml
again and add the newly created channels, or use the
already existing ones.
For pryzm-1
add:
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-0'], # cosmoshub-4
]
For cosmoshub-4
add:
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-100'], # pryzm-1
]
Start the relayer
Start the relayer via hermes start
Transfer
The Pryzm state machine is built with the IBC transfer
module, allowing for the native Pryzm token to be
transferred to any other IBC enabled chain. Transfer can
be initialized through the pryzmd
CLI. Information
can be found via the help label as follows:
pryzmd tx ibc-transfer transfer --help