diff --git a/guides/assets/hyperlane-use-tia-for-gas/add-tokenfactory.diff b/guides/assets/hyperlane-use-tia-for-gas/add-tokenfactory.diff new file mode 100644 index 000000000..d27e969d9 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/add-tokenfactory.diff @@ -0,0 +1,113 @@ +diff --git a/app/app.go b/app/app.go +index 44934ea..8e8c829 100644 +--- a/app/app.go ++++ b/app/app.go +@@ -10,6 +10,9 @@ import ( + "strings" + "sync" + ++ "github.com/Stride-Labs/tokenfactory/tokenfactory" ++ tokenfactorykeeper "github.com/Stride-Labs/tokenfactory/tokenfactory/keeper" ++ tokenfactorytypes "github.com/Stride-Labs/tokenfactory/tokenfactory/types" + abci "github.com/cometbft/cometbft/abci/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + dbm "github.com/cosmos/cosmos-db" +@@ -176,10 +179,11 @@ var maccPerms = map[string][]string{ + govtypes.ModuleName: {authtypes.Burner}, + nft.ModuleName: nil, + // non sdk modules +- ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, +- ibcfeetypes.ModuleName: nil, +- icatypes.ModuleName: nil, +- wasmtypes.ModuleName: {authtypes.Burner}, ++ ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, ++ ibcfeetypes.ModuleName: nil, ++ icatypes.ModuleName: nil, ++ wasmtypes.ModuleName: {authtypes.Burner}, ++ tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + } + + var ( +@@ -226,6 +230,7 @@ type WasmApp struct { + ICAHostKeeper icahostkeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + WasmKeeper wasmkeeper.Keeper ++ TokenFactoryKeeper tokenfactorykeeper.Keeper + + ScopedIBCKeeper capabilitykeeper.ScopedKeeper + ScopedICAHostKeeper capabilitykeeper.ScopedKeeper +@@ -326,6 +331,7 @@ func NewWasmApp( + capabilitytypes.StoreKey, ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, + wasmtypes.StoreKey, icahosttypes.StoreKey, + icacontrollertypes.StoreKey, ++ tokenfactorytypes.StoreKey, + ) + + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) +@@ -563,6 +569,16 @@ func NewWasmApp( + app.BankKeeper, + ) + ++ // Token factory keeper ++ app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper( ++ keys[tokenfactorytypes.StoreKey], ++ app.GetSubspace(tokenfactorytypes.ModuleName), ++ maccPerms, ++ app.AccountKeeper, ++ app.BankKeeper, ++ app.DistrKeeper, ++ ) ++ + // create evidence keeper with router + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, +@@ -725,6 +741,7 @@ func NewWasmApp( + ibcfee.NewAppModule(app.IBCFeeKeeper), + ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + ibctm.AppModule{}, ++ tokenfactory.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), + // sdk + crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // always be last to make sure that it checks for all invariants and not only part of them + ) +@@ -770,6 +787,7 @@ func NewWasmApp( + icatypes.ModuleName, + ibcfeetypes.ModuleName, + wasmtypes.ModuleName, ++ tokenfactorytypes.ModuleName, + ) + + app.ModuleManager.SetOrderEndBlockers( +@@ -786,6 +804,7 @@ func NewWasmApp( + icatypes.ModuleName, + ibcfeetypes.ModuleName, + wasmtypes.ModuleName, ++ tokenfactorytypes.ModuleName, + ) + + // NOTE: The genutils module must occur after staking so that pools are +@@ -811,6 +830,7 @@ func NewWasmApp( + ibcfeetypes.ModuleName, + // wasm after ibc transfer + wasmtypes.ModuleName, ++ tokenfactorytypes.ModuleName, + } + app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) + app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) +@@ -899,9 +919,6 @@ func NewWasmApp( + // At startup, after all modules have been registered, check that all proto + // annotations are correct. + protoFiles, err := proto.MergedRegistry() +- if err != nil { +- panic(err) +- } + err = msgservice.ValidateProtoAnnotations(protoFiles) + if err != nil { + // Once we switch to using protoreflect-based antehandlers, we might +@@ -1209,5 +1226,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino + paramsKeeper.Subspace(icahosttypes.SubModuleName).WithKeyTable(icahosttypes.ParamKeyTable()) + + paramsKeeper.Subspace(wasmtypes.ModuleName) ++ paramsKeeper.Subspace(tokenfactorytypes.ModuleName) + return paramsKeeper + } + diff --git a/guides/assets/hyperlane-use-tia-for-gas/docker-compose.yml b/guides/assets/hyperlane-use-tia-for-gas/docker-compose.yml new file mode 100644 index 000000000..3491955e7 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/docker-compose.yml @@ -0,0 +1,99 @@ +services: + da: + image: golang:1.22-alpine + container_name: da + entrypoint: ["sh", "-c"] + command: + - | + apk add curl perl jq bash git make + curl -sSL https://rollkit.dev/install-local-da.sh -o start.sh + perl -i -pe 's;./build/local-da;./build/local-da -listen-all;' start.sh + sh start.sh + ports: + - 7980:7980 + localwasm: + image: localwasm + container_name: localwasm + build: + context: ../../wasmd + dockerfile: Dockerfile + entrypoint: ["sh", "-c"] + command: + - | + if [ -f /opt/restart-wasm.sh ]; then + bash /opt/restart-wasm.sh + else + apt-get update && apt-get install -y curl perl jq netcat + until nc -z -v da 7980; do + echo "Waiting for the DA layer to start..." + sleep 2 + done + curl -sSL https://rollkit.dev/cosmwasm/init.sh | + perl -pe 's;127.0.0.1;0.0.0.0;g' | + perl -pe 's;http://localhost:7980;http://da:7980;g' | + perl -pe 's;--rollkit.aggregator;--rollkit.aggregator --api.address tcp://0.0.0.0:1317;g' | + bash + fi + ports: + - 36657:36657 + - 1317:1317 + - 9290:9290 + relayer: + container_name: hpl-relayer + image: gcr.io/abacus-labs-dev/hyperlane-agent:8a66544-20240530-111322 + platform: linux/amd64 + user: root + # restart: always + entrypoint: ["sh", "-c"] + command: + - | + rm -rf /app/config/* && \ + cp "/etc/hyperlane/agent-config.docker.json" "/app/config/agent-config.json" && \ + CONFIG_FILES="/etc/hyperlane/relayer.json" \ + ./relayer + ports: + - 9110:9090 + volumes: + - ./hyperlane:/etc/hyperlane + - ./relayer:/etc/data + - ./validator:/etc/validator + + validator-localwasm: + container_name: hpl-validator-localwasm + image: gcr.io/abacus-labs-dev/hyperlane-agent:8a66544-20240530-111322 + platform: linux/amd64 + user: root + # restart: always + entrypoint: ["sh", "-c"] + command: + - | + rm -rf /app/config/* && \ + cp "/etc/hyperlane/agent-config.docker.json" "/app/config/agent-config.json" && \ + CONFIG_FILES="/etc/hyperlane/validator.localwasm.json" \ + ./validator + ports: + - 9120:9090 + volumes: + - ./hyperlane:/etc/hyperlane + - ./validator:/etc/validator + - ./validator/localwasm:/etc/data + + validator-strideinternal1: + container_name: hpl-validator-strideinternal1 + image: gcr.io/abacus-labs-dev/hyperlane-agent:8a66544-20240530-111322 + platform: linux/amd64 + user: root + # restart: always + entrypoint: ["sh", "-c"] + command: + - | + rm -rf /app/config/* && \ + cp "/etc/hyperlane/agent-config.docker.json" "/app/config/agent-config.json" && \ + CONFIG_FILES="/etc/hyperlane/validator.strideinternal1.json" \ + ./validator + ports: + - 9121:9090 + volumes: + - ./hyperlane:/etc/hyperlane + - ./validator:/etc/validator + - ./validator/strideinternal1:/etc/data diff --git a/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config-2.yaml b/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config-2.yaml new file mode 100644 index 000000000..b8eeefd59 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config-2.yaml @@ -0,0 +1,66 @@ +networks: + - id: "localwasm" + hrp: "wasm" + endpoint: + rpc: "http://127.0.0.1:36657" + rest: "http://127.0.0.1:1317" + grpc: "http://127.0.0.1:9290" + gas: + price: "0.025" + denom: "uwasm" + domain: 963 + signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" # wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 + - id: "stride-internal-1" + hrp: "stride" + endpoint: + rpc: "https://stride-testnet-rpc.polkachu.com" + rest: "https://stride-testnet-api.polkachu.com" + grpc: "http://stride-testnet-grpc.polkachu.com:12290" + gas: + price: "0.01" + denom: "ustrd" + domain: 1651 + signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" # stride133xh839fjn9wxzg6vhc0370lcem8939z2sd4gn + +# wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 +# stride133xh839fjn9wxzg6vhc0370lcem8939z2sd4gn +signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" + +deploy: + ism: + type: multisig + owner: + validators: + 963: + addrs: + - + threshold: 1 + hooks: + default: + type: aggregate + owner: + hooks: + - type: merkle + + - type: igp + owner: + token: "ibc/1A7653323C1A9E267FF7BEBF40B3EEA8065E8F069F47F2493ABC3E0B621BF793" + configs: + 963: + exchange_rate: 1000 + gas_price: 10000 + default_gas_usage: 100000 + + required: + type: aggregate + owner: + hooks: + - type: pausable + owner: + paused: false + + - type: fee + owner: + fee: + denom: "ibc/1A7653323C1A9E267FF7BEBF40B3EEA8065E8F069F47F2493ABC3E0B621BF793" + amount: 1 diff --git a/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config.yaml b/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config.yaml new file mode 100644 index 000000000..2f5fbee98 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config.yaml @@ -0,0 +1,65 @@ +networks: + - id: "localwasm" + hrp: "wasm" + endpoint: + rpc: "http://127.0.0.1:36657" + rest: "http://127.0.0.1:1317" + grpc: "http://127.0.0.1:9290" + gas: + price: "0.025" + denom: "uwasm" + domain: 963 + signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" # wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 + - id: "stride-internal-1" + hrp: "stride" + endpoint: + rpc: "https://stride-testnet-rpc.polkachu.com" + rest: "https://stride-testnet-api.polkachu.com" + grpc: "http://stride-testnet-grpc.polkachu.com:12290" + gas: + price: "0.01" + denom: "ustrd" + domain: 1651 + signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" # stride133xh839fjn9wxzg6vhc0370lcem8939z2sd4gn + +# wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 +# stride133xh839fjn9wxzg6vhc0370lcem8939z2sd4gn +signer: "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" + +deploy: + ism: + type: multisig + owner: + validators: + 1651: + addrs: + - + threshold: 1 + hooks: + default: + type: aggregate + owner: + hooks: + - type: merkle + + - type: igp + owner: + configs: + 1651: + exchange_rate: 1000 + gas_price: 10000 + default_gas_usage: 100000 + + required: + type: aggregate + owner: + hooks: + - type: pausable + owner: + paused: false + + - type: fee + owner: + fee: + denom: uwasm + amount: 1 diff --git a/guides/assets/hyperlane-use-tia-for-gas/relayer.json b/guides/assets/hyperlane-use-tia-for-gas/relayer.json new file mode 100644 index 000000000..c5ef1148b --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/relayer.json @@ -0,0 +1,32 @@ +{ + "db": "/etc/data/db", + "relayChains": "localwasm,strideinternal1", + "allowLocalCheckpointSyncers": "true", + "gasPaymentEnforcement": [{ "type": "none" }], + "whitelist": [ + { + "origindomain": [963], + "destinationDomain": [1651] + }, + { + "origindomain": [1651], + "destinationDomain": [963] + } + ], + "chains": { + "localwasm": { + "signer": { + "type": "cosmosKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31", + "prefix": "wasm" + } + }, + "strideinternal1": { + "signer": { + "type": "cosmosKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31", + "prefix": "stride" + } + } + } +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/stride-internal-1.json b/guides/assets/hyperlane-use-tia-for-gas/stride-internal-1.json new file mode 100644 index 000000000..2319fabf4 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/stride-internal-1.json @@ -0,0 +1,25 @@ +{ + "artifacts": { + "hpl_mailbox": 362, + "hpl_validator_announce": 363, + "hpl_ism_aggregate": 364, + "hpl_ism_multisig": 365, + "hpl_ism_pausable": 366, + "hpl_ism_routing": 367, + "hpl_igp": 368, + "hpl_hook_aggregate": 369, + "hpl_hook_fee": 370, + "hpl_hook_merkle": 371, + "hpl_hook_pausable": 372, + "hpl_hook_routing": 373, + "hpl_hook_routing_custom": 374, + "hpl_hook_routing_fallback": 375, + "hpl_test_mock_hook": 376, + "hpl_test_mock_ism": 377, + "hpl_test_mock_msg_receiver": 378, + "hpl_igp_oracle": 379, + "hpl_warp_cw20": 380, + "hpl_warp_native": 381 + }, + "deployments": {} +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/utia-localwasm.json b/guides/assets/hyperlane-use-tia-for-gas/utia-localwasm.json new file mode 100644 index 000000000..ea54f635a --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/utia-localwasm.json @@ -0,0 +1,11 @@ +{ + "type": "native", + "mode": "bridged", + "id": "TIA.stride-localwasm", + "owner": "", + "config": { + "bridged": { + "denom": "utia" + } + } +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/utia-stride.json b/guides/assets/hyperlane-use-tia-for-gas/utia-stride.json new file mode 100644 index 000000000..766347196 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/utia-stride.json @@ -0,0 +1,11 @@ +{ + "type": "native", + "mode": "collateral", + "id": "TIA.stride-localwasm", + "owner": "", + "config": { + "collateral": { + "denom": "ibc/1A7653323C1A9E267FF7BEBF40B3EEA8065E8F069F47F2493ABC3E0B621BF793" + } + } +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/validator.localwasm.json b/guides/assets/hyperlane-use-tia-for-gas/validator.localwasm.json new file mode 100644 index 000000000..ab84b0566 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/validator.localwasm.json @@ -0,0 +1,21 @@ +{ + "db": "/etc/data/db", + "checkpointSyncer": { + "type": "localStorage", + "path": "/etc/validator/localwasm/checkpoint" + }, + "originChainName": "localwasm", + "validator": { + "type": "hexKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31" + }, + "chains": { + "localwasm": { + "signer": { + "type": "cosmosKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31", + "prefix": "wasm" + } + } + } +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/validator.strideinternal1.json b/guides/assets/hyperlane-use-tia-for-gas/validator.strideinternal1.json new file mode 100644 index 000000000..b0a57b006 --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/validator.strideinternal1.json @@ -0,0 +1,21 @@ +{ + "db": "/etc/data/db", + "checkpointSyncer": { + "type": "localStorage", + "path": "/etc/validator/strideinternal1/checkpoint" + }, + "originChainName": "strideinternal1", + "validator": { + "type": "hexKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31" + }, + "chains": { + "strideinternal1": { + "signer": { + "type": "cosmosKey", + "key": "0xf0517040b5669e2d93ffac3a3616187b14a19ad7a0657657e0f655d5eced9e31", + "prefix": "stride" + } + } + } +} diff --git a/guides/assets/hyperlane-use-tia-for-gas/wasmd.Dockerfile b/guides/assets/hyperlane-use-tia-for-gas/wasmd.Dockerfile new file mode 100644 index 000000000..a2d910a5d --- /dev/null +++ b/guides/assets/hyperlane-use-tia-for-gas/wasmd.Dockerfile @@ -0,0 +1,15 @@ +FROM golang:1.22.5-bullseye + +RUN set -eux; apt-get update && apt-get install -y git make; + +WORKDIR /code +COPY . /code/ + +RUN LEDGER_ENABLED=false make build +RUN cp /code/build/wasmd /usr/bin/wasmd + +WORKDIR /opt + +EXPOSE 1317 +EXPOSE 36656 +EXPOSE 36657 \ No newline at end of file diff --git a/guides/hyperlane-use-tia-for-gas.md b/guides/hyperlane-use-tia-for-gas.md new file mode 100644 index 000000000..64267b4ee --- /dev/null +++ b/guides/hyperlane-use-tia-for-gas.md @@ -0,0 +1,434 @@ +# How to use Hyperlane token (TIA) as gas token in your rollup + +This guide builds upon [CosmWasm rollup](../tutorials/cosmwasm.md), where you set up a local rollup with integrated CosmWasm. In this guide, we will be exploring how to integrate Hyperlane as a safer IBC alterative for token transfers in your rollup. + + + + +:::tip + +::: + + + +## 📝 Deploy a CosmWasm rollup {#deploy-rollup} + +This is a gist of the [CosmWasm rollup](../tutorials/cosmwasm.md) guide. + +### Prepare rollup binary + +```bash +git clone --branch v0.50.0 --depth 1 https://github.com/CosmWasm/wasmd.git +cd wasmd +``` + +#### Add token factory to app.go: + +```bash +curl -sSL https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/add-tokenfactory.diff | git apply +``` + +#### Update packages to use rollkit and accommodate x/tokenfactory: + +```bash +# Use rollkit +go mod edit -replace github.com/cosmos/cosmos-sdk=github.com/rollkit/cosmos-sdk@v0.50.7-rollkit-v0.13.6-no-fraud-proofs.0.20240730125236-04ca9ba69219 + +# Update the dependencies to accommodate x/tokenfactory +go mod edit -replace cosmossdk.io/core=cosmossdk.io/core@v0.11.0 +go mod edit -replace github.com/cosmos/ibc-go/v8=github.com/cosmos/ibc-go/v8@v8.0.0 +go get -v github.com/Stride-Labs/tokenfactory@a301020c313d6bd8b45e474ca242922bdd133f6b + +# Perform module tidying and download dependencies +go mod tidy -compat=1.17 +go mod download +``` + +#### Build the rollup binary locally + +```bash +make install +``` + +### Configure Local Clients + +Config the `wasmd` and `strided` CLI for ease of use: + +```bash +wasmd config set client chain-id localwasm +wasmd config set client node tcp://127.0.0.1:36657 +wasmd config set client output json +wasmd config set client keyring-backend test + +git clone --branch v24.0.0 --depth 1 https://github.com/Stride-Labs/stride ../stride +cd ../stride +make install +strided config chain-id stride-internal-1 +strided config node https://stride-testnet-rpc.polkachu.com:443 +strided config keyring-backend test +cd ../wasmd +``` + +Add the signer accounts to each keyring + +```bash +SEED="join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" +echo $SEED | wasmd keys add my-key --recover +echo $SEED | strided keys add my-key --recover + +:::tip +In this guide, we're using a predefined seed phrase for simplicity. Alternatively you can generate and use your own: + +```bash +wasmd keys add my-key +``` + +To get your Stride address, import the generated seed phrase to the `strided` CLI using: + +```bash +strided keys add --recover my-key +``` + +To get the private key, run: + +```bash +wasmd keys export --unsafe --unarmored-hex my-key +``` + +::: + +### Deploy local data availability service and rollup + + + +Create a Dockerfile in the `wasmd` repo that will be used to run the rollup. + +```bash +wget -O Dockerfile https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/wasmd.Dockerfile +``` + +Fork the cw-hyperlane repo + +```bash +# Back out to the same level as the wasmd repo +cd .. + +git clone --depth 1 git@github.com:many-things/cw-hyperlane.git +cd cw-hyperlane +git checkout 4f5656d4704178ac54d10467ca7edc3df2312c4b +``` + +Create the docker compose file that will be used for the data availability service, the localwasm chain, and the Hyperlane validators and relayers. + +```bash +wget -O example/docker-compose.yml https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/docker-compose.yml +``` + +To start the data availability service, run: + +```bash +docker compose -f example/docker-compose.yml up da +``` + +Then start the localwasm chain: + +```bash +docker compose -f example/docker-compose.yml up localwasm +``` + +With that, we have kickstarted our `wasmd` network! 🎉 + +### Fund our accounts + +#### Stride Account + +If you're using the account specified in this guide, the stride account should already be funded! + +If you're using a new account, you can fund it from the faucet at [Stride testnet faucet](https://stride-faucet.pages.dev). + + + +#### Rollup Account + +We can fund the rollup account through one of the genesis accounts in the docker container + +```bash +docker exec -it localwasm \ + wasmd tx bank send localwasm-key wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 \ + 10000000uwasm -y --gas auto --gas-adjustment 1.5 --gas-prices 0.025uwasm \ + --keyring-backend test --node http://localhost:36657 +``` + +:::info +`localwasm-key` is the genesis validator's address. See https://rollkit.dev/cosmwasm/init.sh for more info. +::: + +:::tip +To check if the transaction was successful, get the `txhash` field from the response to the `wasmd tx bank send` command above, and run: + +```bash +wasmd q tx $TXHASH +``` + +The transaction was successful if the `code` field is 0 (success). +::: + +## Deploy Hyperlane + +### Deploy Contracts + +#### Create `config.yaml` with our networks setup: + + + +```bash +wget -O config.yaml https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config.yaml +``` + +:::tip +The `domain` IDs were generated as a sum or the ascii values of the chain ID, for example: + +```python +print(sum(ord(char) for char in "stride-internal-1")) +``` + +However, you can pick any number as your domain ID. +::: + +:::tip +The fee for each transfer is calculated by: + += `protocol_fee + (default_gas_usage * gas_price * exchange_rate / 10000000000)` + +So in our config, it will be: `1 + [(1000 * 10000 * 100000) / 10000000000] = 101uwasm` +::: + +#### Inside the cw-hyperlane directory, install the Hyperlane cw-cli: + +```bash +yarn install +``` + +#### Upload and deploy the contracts on our localwasm rollup: + +```bash +# This command will make one file. +# - context with artifacts (default path: {cw-hyperlane-root}/context/localwasm.json) +yarn cw-hpl upload remote v0.0.6-rc8 -n localwasm + +# This command will output two results. +# - context + deployment (default path: {cw-hyperlane-root}/context/localwasm.json) +# - Hyperlane agent-config (default path: {cw-hyperlane-root}/context/localwasm.config.json) +yarn cw-hpl deploy -n localwasm +``` + +#### Update the config.yaml for the stride deployment + + + + +```bash +wget -O config.yaml https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/hyperlane-config-2.yaml +``` + +#### Deploy the contracts on the Stride testnet: + + + +```bash +# Stride has permissioned CosmWasm, meaning only certain addresses can upload contracts. +# The Hyperlane contracts have already been uploaded, so all that's left is to instantiate them. +# This command will initialize the config for stride-testnet-1 with the code IDs of the Hyperlane contracts. +wget -O context/stride-internal-1.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/stride-internal-1.json + +# This command will output two results. +# - context + deployment (default path: {cw-hyperlane-root}/context/stride-internal-1.json) +# - Hyperlane agent-config (default path: {cw-hyperlane-root}/context/stride-internal-1.config.json) +yarn cw-hpl deploy -n stride-internal-1 +``` + +### Deploy the validators and relayer + +#### Setup the relayer config: + +```bash +wget -O example/hyperlane/relayer.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/relayer.json +``` + +#### Setup the validator config on the Stride side: + +```bash +wget -O example/hyperlane/validator.strideinternal1.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/validator.strideinternal1.json +``` + +#### Setup the validator config on the localwasm rollup side: + +```bash +wget -O example/hyperlane/validator.localwasm.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/validator.localwasm.json +``` + +#### Prepare the validators and relayer config: + + + +```bash +# Create agent-config.docker.json by merging localwasm.config.json and stride-internal-1.config.json +# We also have to put quotes around the gasPrice amount to be compliant with the agent version, +# and we need to change the hostname to localwasm so it can be recognized from within docker +jq -s '.[0] * .[1]' context/{localwasm,stride-internal-1}.config.json | \ + jq '.chains |= with_entries(.value.gasPrice.amount |= tostring)' | \ + jq '.chains.strideinternal1.index.chunk |= 5' | \ + perl -pe 's/127.0.0.1/localwasm/' > \ + example/hyperlane/agent-config.docker.json +``` + +#### Run the relayer and validators: + +```bash +docker compose -f example/docker-compose.yml up -d validator-localwasm validator-strideinternal1 relayer +``` + +### Deploy the warp routes + +#### Deploy a warp contract with TIA as collateral on Stride + +```bash +wget -O example/warp/utia-stride.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/utia-stride.json + +yarn cw-hpl warp create ./example/warp/utia-stride.json -n stride-internal-1 +``` + +The output should look like: + +``` +[DEBUG] [contract] deploying hpl_warp_native +[ INFO] [contract] deployed hpl_warp_native at stride1... +``` + +#### Deploy a warp contract on the rollup with bride TIA from Stride + + + +```bash +wget -O example/warp/utia-localwasm.json https://raw.githubusercontent.com/Stride-Labs/Rollkit-docs/hyperlane-v2/guides/assets/hyperlane-use-tia-for-gas/utia-localwasm.json + +yarn cw-hpl warp create ./example/warp/utia-localwasm.json -n localwasm +``` + +The output should look like: + +``` +[DEBUG] [contract] deploying hpl_warp_native +[ INFO] [contract] deployed hpl_warp_native at wasm1... +``` + +:::tip +When TIA is bridged to the rollup, it uses tokenfactory under the hood to mint TIA that belongs to the warp contract. +The denom will be of the form: `factory/{warp-contract-address}/utia` +::: + +#### Link the localwasm route to the stride route + +```bash +yarn cw-hpl warp link \ + --asset-type native \ + --asset-id TIA.stride-localwasm \ + --target-domain 963 \ + --warp-address $(jq -r '.deployments.warp.native[0].hexed' context/localwasm.json) \ + -n stride-internal-1 +``` + +#### Link the stride route to the localwasm route + +```bash +yarn cw-hpl warp link \ + --asset-type native \ + --asset-id TIA.stride-localwasm \ + --target-domain 1651 \ + --warp-address $(jq -r '.deployments.warp.native[0].hexed' context/stride-internal-1.json) \ + -n localwasm +``` + +### Transfer TIA from Celestia through Stride to localwasm + +Build the celestia binary + +```bash +git clone https://github.com/celestiaorg/celestia-app.git ../celestia-appd +cd ../celestia-appd +make install + +cd - # return to previous directory +``` + +Add your account + +```bash +celestia-appd config chain-id mocha-4 +celestia-appd config node https://celestia-testnet-rpc.polkachu.com:443 +celestia-appd config keyring-backend test + +echo "join always addict position jungle jeans bus govern crack huge photo purse famous live velvet virtual weekend hire cricket media dignity wait load mercy" | \ + celestia-appd keys add my-key --recover # celestia133xh839fjn9wxzg6vhc0370lcem8939zc3uexj +``` + +Fund you account with the [Celestia Mocha Testnet Faucet](https://docs.celestia.org/nodes/mocha-testnet#mocha-testnet-faucet). + +Transfer TIA from Celestia through Stride to the localwasm rollup: + +```bash +warp_contract_address=$(jq -r '.deployments.warp.native[0].address' context/stride-internal-1.json) +recipient=$(yarn cw-hpl wallet convert-cosmos-to-eth -n localwasm $(wasmd keys show my-key -a) | perl -pe 's/0x0x//g') + +forward_msg='{"transfer_remote":{"dest_domain":963,"recipient":"'"$recipient"'","amount":"10000"}}' +funds='[{"amount":1,"denom":"ibc/1A7653323C1A9E267FF7BEBF40B3EEA8065E8F069F47F2493ABC3E0B621BF793"}]' +memo='{"wasm":{"contract":"'"$warp_contract_address"'","msg":'"$forward_msg"',"funds":'"$funds"'}}' + +celestia-appd tx ibc-transfer transfer transfer channel-78 $warp_contract_address 1utia --from my-key -y --fees 420utia --memo "$memo" +``` + +:::tip +Stride has IBC middleware installed that automatically forwards and routes transfers directly to the rollup, therefore we only need to sign one transaction on Celestia! + +See the `memo` field in the above command to see how we can encode a message for the wasm contract and send it along with the funds. +::: + +Confirm the tokens landed in the wasm account with: + +```bash +wasmd q bank balances $(wasmd keys show my-key -a) +``` + +### Update localwasm to use Hyperlane bridged TIA as a gas token + +Update the `restart-wasmd.sh` script to include the new minimum gas prices: + +```bash +warp_contract_address="$(jq -r '.deployments.warp.native[0].address' context/localwasm.json)" +localwasm_container_id="$(docker compose -f example/docker-compose.yml ps | awk '$1~/^localwasm$/{print $1}')" + +docker exec "$localwasm_container_id" perl -i -pe "s;--minimum-gas-prices=0.025uwasm;--minimum-gas-prices=0.025uwasm,0.025factory/$warp_contract_address/utia;" restart-wasmd.sh +``` + +Restart the wasmd container: + +```bash +docker compose -f example/docker-compose.yml restart "$localwasm_container_id" +``` + +### Send a transaction on the localwasm using TIA to pay for gas + +```bash +wasmd tx bank send my-key wasm133xh839fjn9wxzg6vhc0370lcem8939zr8uu45 1uwasm -y --gas auto --gas-adjustment 1.5 --gas-prices "0.025factory/$warp_contract_address/utia" +``` + +## 🎉 + +Congratulations! You've built a local rollup that uses Hyperlane bridged TIA as the gas token! + +## Resources + +- [Deploying Hyperlane with Osmosis Testnet](https://github.com/many-things/cw-hyperlane/blob/main/DEPLOYMENT.md) +- [Hyperlane docs: Deploy Hyperlane](https://docs.hyperlane.xyz/docs/deploy-hyperlane) diff --git a/guides/use-tia-for-gas.md b/guides/use-tia-for-gas.md index 02ac03b92..6947c0648 100644 --- a/guides/use-tia-for-gas.md +++ b/guides/use-tia-for-gas.md @@ -4,6 +4,16 @@ description: Build a sovereign rollup using Rollkit CLI and a local DA network, # How to use IBC token (TIA) as gas token in your rollup +:::warning Disclaimer +This initial version of IBC has high trust assumptions where receiving chains +only verify the signature of the single rollup node. For use in production, it's recommended to wait for trust-minimized IBC support which includes state proofs and conditional clients. + +Learn more about how conditional clients work in [ibc-go issue 5112](https://github.com/cosmos/ibc-go/issues/5112) +and a tracking issue for state proofs in [rollkit issue 1632](https://github.com/rollkit/rollkit/issues/1632). + +For now, it is strongly recommended using Hyperlane instead of IBC. Check out [GM world rollup with Hyperlane](https://rollkit.dev/guides/hyperlane). +::: + ## 🌞 Introduction {#introduction} This tutorial will guide you through building a sovereign `gm-world` rollup using Rollkit, with TIA as the gas token. Unlike the [quick start guide](https://rollkit.dev/tutorials/quick-start), which uses a native rollup token for gas, this tutorial demonstrates how to integrate an IBC-enabled token, TIA, as the gas token within the rollup, providing a deeper exploration of sovereign rollup development. @@ -124,30 +134,10 @@ Note that we specified the gas token to be IBC TIA. We still haven't made an IBC Now you should see the logs of the running node: ```bash -12:21PM INF starting node with ABCI CometBFT in-process module=server -12:21PM INF starting node with Rollkit in-process module=server -12:21PM INF service start impl=multiAppConn module=proxy msg="Starting multiAppConn service" -12:21PM INF service start connection=query impl=localClient module=abci-client msg="Starting localClient service" -12:21PM INF service start connection=snapshot impl=localClient module=abci-client msg="Starting localClient service" -12:21PM INF service start connection=mempool impl=localClient module=abci-client msg="Starting localClient service" -12:21PM INF service start connection=consensus impl=localClient module=abci-client msg="Starting localClient service" -12:21PM INF service start impl=EventBus module=events msg="Starting EventBus service" -12:21PM INF service start impl=PubSub module=pubsub msg="Starting PubSub service" -12:21PM INF Using default mempool ttl MempoolTTL=25 module=BlockManager -12:21PM INF service start impl=IndexerService module=txindex msg="Starting IndexerService service" -12:21PM INF service start impl=RPC module=server msg="Starting RPC service" -12:21PM INF service start impl=Node module=server msg="Starting Node service" -12:21PM INF starting P2P client module=server -12:21PM INF serving HTTP listen address=127.0.0.1:26657 module=server -12:21PM INF listening on address=/ip4/127.0.0.1/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p -12:21PM INF listening on address=/ip4/163.172.162.109/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p -12:21PM INF no seed nodes - only listening for connections module=p2p -12:21PM INF working in aggregator mode block time=1000 module=server -12:21PM INF Creating and publishing block height=22 module=BlockManager -12:21PM INF starting gRPC server... address=127.0.0.1:9290 module=grpc-server -12:21PM INF finalized block block_app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager num_txs_res=0 num_val_updates=0 -12:21PM INF executed block app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager -12:21PM INF indexed block events height=22 module=txindex +... +12:21PM INF finalized block block_app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=1 module=BlockManager num_txs_res=0 num_val_updates=0 +12:21PM INF executed block app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=1 module=BlockManager +12:21PM INF indexed block events height=1 module=txindex ... ``` @@ -214,7 +204,7 @@ chains: account-prefix: celestia keyring-backend: test gas-adjustment: 1.5 - gas-prices: 0.15utia + gas-prices: 0.25utia min-gas-amount: 0 max-gas-amount: 0 debug: false @@ -332,6 +322,6 @@ TX_HASH=$(rollkit tx bank send "$ACCOUNT_ON_ROLLUP" "$ACCOUNT_ON_ROLLUP" 1stake rollkit q tx "$TX_HASH" --output json | jq .code # => 0 ``` -## 🎉 Next steps +## 🎉 Congratulations! You've built a local rollup that posts to a local DA network and uses TIA as the gas token! diff --git a/tutorials/cosmwasm.md b/tutorials/cosmwasm.md index ff644808d..430072326 100644 --- a/tutorials/cosmwasm.md +++ b/tutorials/cosmwasm.md @@ -1,9 +1,6 @@ # 🗞️ CosmWasm rollup -CosmWasm is a smart contracting platform built for the Cosmos -ecosystem by making use of [WebAssembly](https://webassembly.org) (Wasm) -to build smart contracts for Cosmos-SDK. In this tutorial, we will be -exploring how to integrate CosmWasm with local DA layer using Rollkit. +CosmWasm is a smart contracting platform built for the Cosmos ecosystem by making use of [WebAssembly](https://webassembly.org) (Wasm) to build smart contracts for Cosmos-SDK. In this tutorial, we will be exploring how to integrate CosmWasm with local DA layer using Rollkit.