Incentivize an ICS 20 transfer packet
Register the counterparty payee
All incentivization fees are paid to accounts on the chain from where the IBC packets originate. To ensure that the relayer that delivers the MsgRecvPacket
on the destination chain is correctly compensated, the counterparty payee address (i.e. the account address of the relayer on the source chain) needs to be registered on the destination chain. Throughout this tutorial the source chain is chain1
and the destination chain is chain2
, therefore we need to register the account address of the relayer on chain chain1
(RLY_CHAIN1
) on chain chain2
(where the relayer has the account address RLY_CHAIN2
):
simd tx ibc-fee register-counterparty-payee transfer channel-0 $RLY_CHAIN2 $RLY_CHAIN1 \
--from $RLY_CHAIN2 \
--chain-id chain2 \
--keyring-backend test \
--home ../../gm/chain2 \
--node http://localhost:27010
Once the above command succeeds, then we can verify which counterparty payee is registered on chain chain2
for account RLY_CHAIN2
:
simd q ibc-fee counterparty-payee channel-0 $RLY_CHAIN2 --node http://localhost:27010
counterparty_payee: cosmos1vdy5fp0jy2l2ees870a7mls357v7uad6ufzcyz
We see that the counterparty payee address matches what we expected (i.e. the RLY_CHAIN1
address). In this tutorial we are going to send only one packet from chain chain1
to chain chain2
, so we only need to register the counterparty payee on chain chain2
. In real life circumstances relayers relay packets on both directions (i.e. from chain chain1
to chain2
and also vice-versa), and thus relayers should register as well on chain chain1
the counterparty payee address to be compensated for delivering the MsgRecvPacket
on chain chain1
.
Multi-message transaction with single MsgPayPacketFee
message
We first generate (not execute) an IBC transfer transaction (again 1000samoleans
from VALIDATOR_CHAIN1
to VALIDATOR_CHAIN2
):
simd tx ibc-transfer transfer transfer channel-0 $VALIDATOR_CHAIN2 1000samoleans \
--from $VALIDATOR_CHAIN1 \
--chain-id chain1 \
--keyring-backend test \
--home ../../gm/chain1 \
--node tcp://localhost:27000 \
--generate-only > transfer.json
Then we prepend a MsgPayPacketFee
, sign the transaction and broadcast it. Please note that jq
is used to manipulate the transaction JSON file, making it a multi-message transaction. In practice, this multi-message transaction would be built using a gRPC or web client, for example, a web-based wallet application could fulfill this role. Note also that the signer
field uses the address of VALIDATOR_CHAIN1
.
jq '.body.messages |= [{"@type":"/ibc.applications.fee.v1.MsgPayPacketFee","fee": {"recv_fee": [{"denom": "samoleans", "amount": "50"}], "ack_fee": [{"denom": "samoleans", "amount": "25"}], "timeout_fee": [{"denom": "samoleans", "amount": "10"}]}, "source_port_id": "transfer", "source_channel_id": "channel-0", "signer": "cosmos18phmkrpnn6gmpzscf6hnf5zpv06sygxc6f2v92" }] + .' transfer.json > incentivized_transfer.json
simd tx sign incentivized_transfer.json \
--from $VALIDATOR_CHAIN1 \
--chain-id chain1 \
--keyring-backend test \
--home ../../gm/chain1 \
--node tcp://localhost:27000 > signed.json
simd tx broadcast signed.json \
--home ../../gm/chain1 \
--node tcp://localhost:27000
We wait for the relayer to relay the packet, and then we query the balance of account VALIDATOR_CHAIN2
on chain chain2
and see that it has indeed received an equivalent amount of vouchers for the 1000samoleans
sent by VALIDATOR_CHAIN1
:
simd q bank balances $VALIDATOR_CHAIN2 --node http://localhost:27010
balances:
- amount: "1000"
denom: ibc/27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C
- amount: "100000000"
denom: samoleans
- amount: "99000000"
denom: stake
pagination:
total: "3"
We check as well the balance for account VALIDATOR_CHAIN1
on chain chain1
:
simd q bank balances $WALLET_1 --node http://localhost:16657
./simd q bank balances $VALIDATOR_CHAIN1 --node http://localhost:27000
balances:
- amount: "99998925"
denom: samoleans
- amount: "99000000"
denom: stake
pagination:
total: "2"
An amount of 1075samoleans
has been deducted, which is what we expected: 1000samoleans
have been transferred to VALIDATOR_CHAIN2
and 75stake
have been paid for the receive and acknowledgment fees. The timeout fee has been refunded to VALIDATOR_CHAIN1
and the relayer address RLY_CHAIN1
should have gained 75samoleans
for submitting the MsgRecvPacket
and the MsgAcknowledgement
messages.