Hyperlane

Testing Warp Route

Test cross-chain token transfers between BitSong and Base Sepolia using your deployed Hyperlane warp route.

This guide covers how to test cross-chain token transfers on your deployed warp route. You will send tokens from BitSong to Base Sepolia (Cosmos → EVM) and back (EVM → Cosmos).

You must complete the Warp Token Deployment guide before testing. You need the TOKEN_ID, HYP_ERC20_ADDR, and other environment variables from that guide.

Prerequisites

Before testing, ensure:

Configuration Reference

These environment variables are needed for testing. If you followed the Warp Token Deployment guide, they should already be set:

Terminal
export CHAIN_ID="crescendo-1"
export DOMAIN_ID="7171"
export REMOTE_DOMAIN="84532"
export DENOM="utbtsg"
export KEY_NAME="<your-key-name>"
export NODE="tcp://localhost:26657"

# From the deployment guide
export TOKEN_ID="<your-token-id>"
export HYP_ERC20_ADDR="<your-hyp-erc20-address>"
export EVM_KEY="0x<your-evm-private-key>"
export EVM_RPC="https://sepolia.base.org"

Cosmos to EVM

Send tokens from BitSong to Base Sepolia. The tokens are locked as collateral on Cosmos and minted as HypERC20 on the EVM chain.

Terminal
# Convert recipient EVM address to bytes32
RECIPIENT_ADDR="0x<evm-recipient-address>"
RECIPIENT_BYTES32=$(printf "0x%064s" "${RECIPIENT_ADDR#0x}" | tr ' ' '0')

# Look up the IGP ID
IGP_ID=$(bitsongd query hyperlane hooks igps -o json --node $NODE | jq -r '.igps[0].id')
echo "IGP ID: $IGP_ID"

# Query the required interchain gas fee
REQUIRED_FEE=$(bitsongd query hyperlane hooks quote-gas-payment $IGP_ID $REMOTE_DOMAIN 300000 -o json --node $NODE | jq -r '.gas_payment[0].amount')
echo "Required fee: ${REQUIRED_FEE}utbtsg"

# Transfer 1000 utbtsg (0.001 TBTSG) to Base Sepolia
bitsongd tx warp transfer \
    $TOKEN_ID $REMOTE_DOMAIN $RECIPIENT_BYTES32 1000 \
    --max-hyperlane-fee "${REQUIRED_FEE}utbtsg" \
    --from $KEY_NAME \
    --keyring-backend test \
    --chain-id $CHAIN_ID \
    --node $NODE \
    --gas auto --gas-adjustment 1.5 \
    --fees 10000${DENOM} \
    --output json -y

After the relayer delivers the message, check the HypERC20 supply and recipient balance on Base Sepolia:

Terminal
# Total supply across all holders
cast call "$HYP_ERC20_ADDR" "totalSupply()(uint256)" --rpc-url "$EVM_RPC"

# Balance for the specific recipient
cast call "$HYP_ERC20_ADDR" "balanceOf(address)(uint256)" "$RECIPIENT_ADDR" --rpc-url "$EVM_RPC"

EVM to Cosmos

Send tokens back from Base Sepolia to BitSong. The HypERC20 tokens are burned on EVM and the collateral is unlocked on Cosmos.

The bitsongd keys parse command below requires the bitsongd binary. Run this on your BitSong node, or any machine where bitsongd is installed.
Terminal
# Convert Cosmos recipient (bech32) to bytes32
COSMOS_RECIPIENT="bitsong1..." # replace with the actual bitsong address
ADDR_HEX=$(bitsongd keys parse "$COSMOS_RECIPIENT" 2>&1 | grep bytes | awk '{print $2}')
RECIPIENT_BYTES32="0x$(printf '%064s' "$ADDR_HEX" | tr ' ' '0')"
echo "Recipient bytes32: $RECIPIENT_BYTES32"
transferRemoteburns tokens from the caller. If you haven't done a Cosmos → EVM transfer first, the transaction will revert with ERC20: burn amount exceeds balance. Check your balance before sending:
Terminal
EVM_SENDER=$(cast wallet address --private-key "$EVM_KEY")
cast call "$HYP_ERC20_ADDR" "balanceOf(address)(uint256)" "$EVM_SENDER" --rpc-url "$EVM_RPC"
If the balance is 0, send tokens from Cosmos first using the section above.
Terminal
cast send "$HYP_ERC20_ADDR" \
    "transferRemote(uint32,bytes32,uint256)" \
    "$DOMAIN_ID" "$RECIPIENT_BYTES32" 1000 \
    --value 1 \
    --private-key "$EVM_KEY" \
    --rpc-url "$EVM_RPC"
The --value 1 sends 1 wei as interchain gas payment. On testnet with gas enforcement disabled, any non-zero value works.

Troubleshooting

Copyright © 2026