Interchain Accounts
Developers integrating Interchain Accounts may choose to firstly enable host chain functionality, and add authentication modules later as desired.
Documentation regarding authentication modules can be found in the IBC Developer Documentation.
Overview
The following repository contains a basic example of an Interchain Accounts authentication module and serves as a developer guide for teams that wish to use interchain accounts functionality.
The Interchain Accounts module is now maintained within the ibc-go
repository here.
Interchain Accounts is now available in the v3.0.0
release of ibc-go
.
Developer Documentation
Interchain Accounts developer docs can be found on the IBC documentation website.
https://ibc.cosmos.network/main/apps/interchain-accounts/overview.html
Setup
- Clone this repository and build the application binary
git clone https://github.com/cosmos/interchain-accounts-demo.git
cd interchain-accounts
make install
- Download and install an IBC relayer. (hermes, go relayer or both )
cargo install --version 0.15.0 ibc-relayer-cli --bin hermes --locked
git clone https://github.com/cosmos/relayer.git
cd relayer && git checkout v2.0.0-rc4
make install
- Bootstrap two chains, configure the relayer and create an IBC connection (on top of clients that are created as well)
make init-hermes
make init-golang-relayer
:warning: NOTE: When you want to use both relayers interchangeably, using both of these make
commands will set up two seperate connections (which is not needed and can lead to confusion). In the case of using both relayers, perform:
make init-golang-rly
./network/hermes/restore-keys.sh
- Start the relayer
make start-hermes
make start-golang-rly
:exclamation: NOTE: It is abstracted away in the script files, but in case you want to manually run rly start
with interchain accounts, you will need to add this flag: -p events
to it.
This is the situation before make init-*
. The blockchains are not live yet.
This is the situation after make init-*
. The chain binary's have been built and started, and an IBC connection between controller and host chains has been set up.
Demo
NOTE: For the purposes of this demo the setup scripts have been provided with a set of hardcoded mnemonics that generate deterministic wallet addresses used below.
export WALLET_1=$(icad keys show wallet1 -a --keyring-backend test --home ./data/test-1) && echo $WALLET_1;
export WALLET_2=$(icad keys show wallet2 -a --keyring-backend test --home ./data/test-1) && echo $WALLET_2;
export WALLET_3=$(icad keys show wallet3 -a --keyring-backend test --home ./data/test-2) && echo $WALLET_3;
export WALLET_4=$(icad keys show wallet4 -a --keyring-backend test --home ./data/test-2) && echo $WALLET_4;
Registering an Interchain Account via IBC
Register an Interchain Account using the intertx register
cmd.
Here the message signer is used as the account owner.
icad tx intertx register --from $WALLET_1 --connection-id connection-0 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
icad query intertx interchainaccounts connection-0 $WALLET_1 --home ./data/test-1 --node tcp://localhost:16657
export ICA_ADDR=$(icad query intertx interchainaccounts connection-0 $WALLET_1 --home ./data/test-1 --node tcp://localhost:16657 -o json | jq -r '.interchain_account_address') && echo $ICA_ADDR
This is the situation after registering the ICA. A channel has been created and an ICA has been registered on the host.
Funding the Interchain Account wallet
Allocate funds to the new Interchain Account wallet by using the bank send
cmd.
Note this is executed on the host chain to provide the account with an initial balance to execute transactions.
icad q bank balances $ICA_ADDR --chain-id test-2 --node tcp://localhost:26657
icad tx bank send $WALLET_3 $ICA_ADDR 10000stake --chain-id test-2 --home ./data/test-2 --node tcp://localhost:26657 --keyring-backend test -y
icad q bank balances $ICA_ADDR --chain-id test-2 --node tcp://localhost:26657
This is the situation after funding the ICA.
Sending Interchain Account transactions
Send Interchain Accounts transactions using the intertx submit
cmd.
This command accepts a generic sdk.Msg
JSON payload or path to JSON file as an arg.
- Example 1: Staking Delegation
cat ./data/test-2/config/genesis.json | jq -r '.app_state.genutil.gen_txs[0].body.messages[0].validator_address'
icad tx intertx submit \
'{
"@type":"/cosmos.staking.v1beta1.MsgDelegate",
"delegator_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz",
"validator_address":"cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k",
"amount": {
"denom": "stake",
"amount": "1000"
}
}' --connection-id connection-0 --from $WALLET_1 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
icad tx intertx submit [path/to/msg.json] --connection-id connection-0 --from $WALLET_1 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
icad q staking delegations-to cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k --home ./data/test-2 --node tcp://localhost:26657
This is the situation before after sending the staking tx. The user who is the owner of the ICA has staked funds on the host chain to a validator of choice through an interchain accounts packet.
icad tx intertx submit \
'{
"@type":"/cosmos.bank.v1beta1.MsgSend",
"from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz",
"to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw",
"amount": [
{
"denom": "stake",
"amount": "1000"
}
]
}' --connection-id connection-0 --from $WALLET_1 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
icad tx intertx submit [path/to/msg.json] --connection-id connection-0 --from $WALLET_1 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
icad q bank balances $ICA_ADDR --chain-id test-2 --node tcp://localhost:26657
Testing timeout scenario
-
Stop the relayer process and send an interchain accounts transaction using one of the examples provided above.
-
Wait for approx. 1 minute for the timeout to elapse.
-
Restart the relayer process
make start-hermes
make start-golang-rly
-
Observe the packet timeout and relayer reacting appropriately (issuing a MsgTimeout to testchain test-1
).
-
Due to the nature of ordered channels, the timeout will subsequently update the state of the channel to STATE_CLOSED
.
Observe both channel ends by querying the IBC channels for each node.
icad q ibc channel channels --home ./data/test-1 --node tcp://localhost:16657
icad q ibc channel channels --home ./data/test-2 --node tcp://localhost:26657
- Open a new channel for the existing interchain account on the same connection.
icad tx intertx register --from $WALLET_1 --connection-id connection-0 --chain-id test-1 --home ./data/test-1 --node tcp://localhost:16657 --keyring-backend test -y
- Inspect the IBC channels once again and observe a new creately interchain accounts channel with
STATE_OPEN
.
icad q ibc channel channels --home ./data/test-1 --node tcp://localhost:16657
icad q ibc channel channels --home ./data/test-2 --node tcp://localhost:26657
Collaboration
Please use conventional commits https://www.conventionalcommits.org/en/v1.0.0/
chore(bump): bumping version to 2.0
fix(bug): fixing issue with...
feat(featurex): adding feature...