With the bridge wired, the demo runs four scenarios end-to-end:Documentation Index
Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
Use this file to discover all available pages before exploring further.
- Cosmos → EVM: burns IFT tokens on Cosmos and mints the equivalent ERC-20 balance on Besu.
- EVM → Cosmos: burns the ERC-20 on Besu and mints IFT tokens back on Cosmos.
- Packet tracking: polls the relayer’s status API by transaction hash to show transfer state as it progresses.
- Timeout path: sends a packet with a short timeout while the relayer is paused, lets it expire, then resumes the relayer so it submits
MsgTimeoutand refunds the sender.
setup.sh:
What the script does
Cosmos → EVM transfer
- Submit the transfer
- Submit to relayer
- Relay delivery
MsgRecvPacket transaction, and submits it to the EVM chain. The ICS-27 GMP contract on the EVM side decodes the packet payload and calls iftMint on the IFTOwnable contract, minting ERC-20 tokens to the recipient address.
- Acknowledgement
WriteAcknowledgement event. The relayer picks it up, fetches a proof from the Proof API, and submits a MsgAcknowledgement to Cosmos. This completes the packet lifecycle on the source chain.
- Balance snapshot
EVM → Cosmos transfer
- Submit the transfer
iftTransfer burns the ERC-20 tokens from the sender, uses the registered CosmosIFTSendCallConstructor to encode a MsgIFTMint GMP payload, and calls ICS27GMP.sendCall on gmpport.
The packet is committed in the ICS26Router.
- Submit to relayer
- Relay delivery
MsgRecvPacket to the Cosmos chain, and the GMP module executes the embedded MsgIFTMint, minting COSMOS_IFT_DENOM tokens to the receiver.
- Acknowledgement
WriteAcknowledgement event. The relayer picks it up, fetches a proof from the Proof API, and calls ackPacket on the ICS26Router on the EVM chain. This clears the packet commitment on the EVM side and completes the packet lifecycle.
Packet tracking
After either transfer, the script polls the relayer’s status API with the transaction hash:TRANSFER_STATE_COMPLETE or TRANSFER_STATE_FAILED and prints the full status JSON.
Timeout path
This demo includes a script to simulate a timeout:- The relayer container is paused (
docker compose pause relayer). - A transfer is submitted with a 60-second timeout.
- The script waits for the timeout to expire.
- The relayer is resumed (
docker compose unpause relayer). - The relayer sees an expired packet, fetches a timeout proof from the Proof API, and submits
MsgTimeoutto Cosmos. - The Cosmos IFT module refunds the sender.
timeoutTx.txHash.
Observability
The script samples the following without any additional setup:| Endpoint | Content |
|---|---|
relayer:3000/health | Relayer HTTP health check |
relayer:9100/metrics | Prometheus metrics (packet counts, relay latency) |
attestor:9101 | Attestor gRPC server (used by Proof API) |
docker compose logs relayer | Structured JSON logs (fields: msg, source_chain_id, tx_hash, state) |
docker compose logs attestor | OpenTelemetry spans (fields: name, height, durationMs, status) |