Skip to content

Instantly share code, notes, and snippets.

@taitruong
Last active June 7, 2024 16:48
Show Gist options
  • Save taitruong/c561fbebc46a99b3723d37a1dc3ff0af to your computer and use it in GitHub Desktop.
Save taitruong/c561fbebc46a99b3723d37a1dc3ff0af to your computer and use it in GitHub Desktop.
InterChain NFT Transfer: Stargaze > Osmosis

InterChain NFT Transfer example: Stargaze > Osmosis

NOTE: interchain contracts on testnets have rate limits disabled - so there is no need to WL collections and channels!

ICS721 settings

For ease-of-use checkout these testnet env files [here]((https://gist.github.com/taitruong):

  • osmosis_testnet.env
  • stargaze_testnet.env
  • juno_testnet.env
  • terra2_testnet.env
  • aura_testnet.env

Setup cw721-base

First create a collection for this contract: https://github.com/CosmWasm/cw-nfts/tree/main/contracts/cw721-base

$CLI tx wasm instantiate $CODE_ID_CW721 '{"name":"Ark Test", "symbol":"ark-test", "minter":"MINTER_ADDR"}' --from WALLET_KEY --label 'Ark Test' --admin WALLET_KEY --gas-prices $CLI_GAS_PRICES --gas $CLI_GAS --gas-adjustment $CLI_GAS_ADJUSTMENT -b $CLI_BROADCAST_MODE --yes --node $CHAIN_NODE --chain-id $CHAIN_ID --output $CLI_OUTPUT

Then mint a few NFTs:

$CLI tx wasm execute $CW721_ADDR '{"mint": {"token_id":"1", "owner":"OWNER_ADDR" , "token_uri": "ipfs://foo.bar"}}' --from $MINTER_ADDR --gas-prices $CLI_GAS_PRICES --gas $CLI_GAS --gas-adjustment $CLI_GAS_ADJUSTMENT -b $CLI_BROADCAST_MODE --node $CHAIN_NODE --chain-id $CHAIN_ID --yes --output json

NOTE: On Stargaze only contracts can instantiate sg721-base. You can use this for creating one: https://studio.publicawesome.dev/collections/create/

source osmosis_testnet.env
# query for all tokens
$CLI query wasm contract-state smart $ADDR_CW721_TEST '{"all_tokens":{"limit": 100}}' --chain-id $CHAIN_ID --node $CHAIN_NODE --output json

# make sure you are the owner. output: {"data":{"owner":"YOUR_WALLET_ADDY","approvals":[]}}
$CLI query wasm contract-state smart $ADDR_CW721_TEST '{"owner_of": {"token_id":"1"}}' --node $CHAIN_NODE --chain-id $CHAIN_ID

ICS721 NFT transfer

cosmwasm-based ICS721 contract uses an outgoing proxy, so NFTs are sent to the proxy - and not to ICS721.

Call send_nft to proxy will trigger ics721 transfer. As part of send_nft a msg is passed to ICS721:

# create ICS721 message with:
# - recipient of NFT on target chain (Osmosis)
# - source channel: Stargaze channel referencing ICS721 contracts/ports on both chains
# - timeout: expiration in case relayer doesnt relay on time
TIMESTAMP=`date -d "+30 minutes" +%s%N` # time in nano seconds, other options: "+1 day"
printf -v RAW_MSG '{
"receiver": "%s",
"channel_id": "%s",
"timeout": { "timestamp": "%s" } }' \
"$RECIPIENT" \
"$ICS721_CHANNEL_1_OSMOSIS_TO_STARGAZE" \
"$TIMESTAMP"

# Base64 encode msg
MSG=`echo "$RAW_MSG" | base64 | xargs | sed 's/ //g'` # xargs concats multiple lines into one (with spaces), sed removes spaces

# send nft msg for $TOKEN
printf -v EXECUTE_MSG '{"send_nft": {
"contract": "%s",
"token_id": "%s",
"msg": "%s"}}' \
"$ADDR_OUTGOING_PROXY" \
"$TOKEN" \
"$MSG"

# execute transfer
CMD="$CLI tx wasm execute '$ADDR_CW721_TEST' '$EXECUTE_MSG' \
--from "$MY_WALLET" \
--gas-prices "$CLI_GAS_PRICES" \
--gas "$CLI_GAS" \
--gas-adjustment "$CLI_GAS_ADJUSTMENT" \
-b "$CLI_BROADCAST_MODE" \
--chain-id $CHAIN_ID --node $CHAIN_NODE \
--yes"
eval $CMD

Relaying packets

Once transfer is started. Relayer needs to pickup packets. These relayer configs can be used here:

  • Cosmos Relayer/rly (install here) - config.yaml
  • Hermes Relayer (install here) - config.toml

rly vs hermes:

  • rly doesnt need gRPC: on mainnet there are public gRPCs, on testnet it is not guaranteed
  • hermes: allows relayer specific channels (clear packet)
# NOTE: no matter from what chain you transfer (e.g. osmosis -> stargaze or stargaze -> osmosis)
# relayers make sure all packets (receive/acknowledge)) are relayed.
# so like for `hermes clear packet --chain elgafar-1 ...` may start looking on Stargaze testnet (elgafar-1), but it will also relay packets on Osmosis side.
hermes --config ./relayer/hermes/testnet/config.toml clear packets --chain $CHAIN_ID --channel $ICS721_CHANNEL_1_STARGAZE_TO_OSMOSIS --port wasm.$ADDR_ICS721

# switch to osmosis and check whether NFT has been transferred and owned by recipient
source osmosis_testnet.env
# query for all tokens
$CLI query wasm contract-state smart $ADDR_CW721_TEST '{"all_tokens":{"limit": 100}}' --chain-id $CHAIN_ID --node $CHAIN_NODE --output json
# make sure you are the owner. output: {"data":{"owner":"YOUR_WALLET_ADDY","approvals":[]}}
$CLI query wasm contract-state smart $ADDR_CW721_TEST '{"owner_of": {"token_id":"1"}}' --node $CHAIN_NODE --chain-id $CHAIN_ID

For callbacks pls check README.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment