Skip to content

Instantly share code, notes, and snippets.

@fmorency
Created June 4, 2024 14:54
Show Gist options
  • Save fmorency/fdbe8e8373626fe592e0c78dd8dee103 to your computer and use it in GitHub Desktop.
Save fmorency/fdbe8e8373626fe592e0c78dd8dee103 to your computer and use it in GitHub Desktop.
Osmosis Testnet IBC + LP

This document provides instructions on how to create IBC connection from the manifest chain to Osmosis Testnet 5 as well as how to create a Liquidity Pool.

Requirements

  • Manifest manifestd binary
  • Osmosis osmosisd binary
  • Manifest node with public endpoints
  • Manifest relayer account funded with umfx
  • Osmosis relayer account funded with uosmo
  • Hermes relayer binary
  1. Install Hermes v1.9.0

    $ wget https://github.com/informalsystems/hermes/releases/download/v1.9.0/hermes-v1.9.0-x86_64-unknown-linux-gnu.tar.gz
    $ tar zxvf https://github.com/informalsystems/hermes/releases/download/v1.9.0/hermes-v1.9.0-x86_64-unknown-linux-gnu.tar.gz
    $ sudo mv hermes /usr/local/bin
    $ hermes version
    hermes 1.9.0+a026d66
  2. Configure Hermes

    $ mkdir ~/.hermes
    $ touch ~/.hermes/config.toml

    Copy the following content in ~/.hermes/config.toml

    [global]
    log_level = 'info'
    
    [mode]
    [mode.clients]
    enabled = true
    refresh = true
    misbehaviour = true
    
    [mode.connections]
    enabled = true
    
    [mode.channels]
    enabled = true
    
    [mode.packets]
    enabled = true
    clear_interval = 100
    clear_on_start = true
    tx_confirmation = false
    auto_register_counterparty_payee = false
    
    [rest]
    enabled = false
    host = '127.0.0.1'
    port = 3000
    
    [telemetry]
    enabled = false
    host = '127.0.0.1'
    port = 3001
    
    [telemetry.buckets]
    
    [tracing_server]
    enabled = false
    port = 5555
    
    [[chains]]
    id = 'osmo-test-5'
    ccv_consumer_chain = false
    rpc_addr = 'https://rpc.osmotest5.osmosis.zone'
    grpc_addr = 'https://grpc.osmotest5.osmosis.zone'
    event_source = { mode = 'push', url = 'ws://rpc.osmotest5.osmosis.zone/websocket', batch_delay = '500ms' }
    rpc_timeout = '20s'
    trusted_node = false
    account_prefix = 'osmo'
    key_name = 'keyosmosis'
    address_type = { derivation = 'cosmos' }
    store_prefix = 'ibc'
    default_gas = 100000
    max_gas = 4000000
    gas_price = { price = 0.0026, denom = 'uosmo' }  # Osmosis Tesnet sane default gas price
    gas_multiplier = 1.6
    dynamic_gas_price = { enabled = false, multiplier = 1.6, max = 0.6 }
    max_msg_num = 30
    max_tx_size = 2097152
    query_packets_chunk_size = 50
    clock_drift = '5s'
    max_block_time = '30s'
    trusting_period = '4days'
    client_refresh_rate = '1/3'
    trust_threshold = '2/3'
    memo_prefix = ''
    
    [[chains]]
    id = '[MANIFEST_CHAIN_ID]'  # The ID used in the example is `manifest-test-1`
    ccv_consumer_chain = false
    rpc_addr = '[MANIFEST_RPC_ENDPOINT]'
    grpc_addr = '[MANIFEST_gRPC_ENDPOINT]'
    event_source = { mode = 'push', url = 'ws://[MANIFEST_RPC_ENDPOINT]/websocket', batch_delay = '500ms' }
    rpc_timeout = '20s'
    trusted_node = false
    account_prefix = 'manifest'
    key_name = 'keymanifest'
    address_type = { derivation = 'cosmos' }
    store_prefix = 'ibc'
    default_gas = 100000
    max_gas = 4000000
    gas_price = { price = 0.0011, denom = 'umfx' }  # [MANIFEST_GAS_PRICE].
    gas_multiplier = 1.6
    dynamic_gas_price = { enabled = false, multiplier = 1.6, max = 0.6 }
    max_msg_num = 30
    max_tx_size = 2097152
    query_packets_chunk_size = 50
    clock_drift = '5s'
    max_block_time = '30s'
    trusting_period = '14days'
    client_refresh_rate = '1/3'
    trust_threshold = '2/3'
    memo_prefix = ''

    where [MANIFEST_CHAIN_ID] is the chain ID of the Manifest network, [MANIFEST_RPC_ENDPOINT] is the network RPC endpoint, [MANIFEST_gRPC_ENDPOINT] is the network gRPC endpoint and [MANIFEST_GAS_PRICE] is the network gas price, e.g., 0.0011.

  3. Add keys to Hermes

    # Add the Manifest relaying account key
    # The `--key-name` must match the `key_name` entry from the `config.toml`
    # `[MANIFEST_CHAIN_ID]` is the chain ID of the Manifest network
    # The `manifest-icb` contains the mnemonic words of the key
    hermes keys add --key-name keymanifest --chain [MANIFEST_CHAIN_ID] --mnemonic-file manifest-ibc
    
    # Add the Osmosis relaying account key
    # The `--key-name` must match the `key_name` entry from the `config.toml`
    # The `osmosis-icb` contains the mnemonic words of the key
    hermes keys add --key-name keyosmosis --chain osmo-test-5 --mnemonic-file osmosis-ibc 
  4. Run Hermes health-check. Disregard the Osmosis Testnet WARNING. Note that Hermes will also print a warning if you set your network gas price to 0.0. Disregard if this was intended.

    $ hermes health-check
    INFO ThreadId(01) using default configuration from '/home/debian/.hermes/config.toml'
    INFO ThreadId(01) running Hermes v1.9.0+a026d66
    INFO ThreadId(01) health_check{chain=osmo-test-5}: performing health check...
    WARN ThreadId(05) health_check{chain=osmo-test-5}: health check failed for chain 'osmo-test-5'
    WARN ThreadId(05) health_check{chain=osmo-test-5}: reason: transaction indexing for chain 'osmo-test-5' is disabled (`node_info.other.tx_index` is off)
    WARN ThreadId(05) health_check{chain=osmo-test-5}: some Hermes features may not work in this mode!
    WARN ThreadId(01) health_check{chain=osmo-test-5}: chain is not healthy
    INFO ThreadId(01) health_check{chain=manifest-test-1}: performing health check...
    INFO ThreadId(01) health_check{chain=manifest-test-1}: chain is healthy
  5. Start Hermes

    $ hermes start
    INFO ThreadId(01) using default configuration from '/home/debian/.hermes/config.toml'
    INFO ThreadId(01) running Hermes v1.9.0+a026d66
    INFO ThreadId(01) telemetry: telemetry disabled
    INFO ThreadId(01) rest: REST server disabled
    WARN ThreadId(06) health_check{chain=osmo-test-5}: health check failed for chain 'osmo-test-5'
    WARN ThreadId(06) health_check{chain=osmo-test-5}: reason: transaction indexing for chain 'osmo-test-5' is disabled (`node_info.other.tx_index` is off)
    WARN ThreadId(06) health_check{chain=osmo-test-5}: some Hermes features may not work in this mode!
    WARN ThreadId(01) health_check{chain=osmo-test-5}: chain is not healthy: transaction indexing for chain 'osmo-test-5' is disabled (`node_info.other.tx_index` is off)
    INFO ThreadId(01) health_check{chain=manifest-test-1}: chain is healthy
    INFO ThreadId(01) scan.chain{chain=osmo-test-5}: scanning chain...
    INFO ThreadId(01) scan.chain{chain=osmo-test-5}: scanning chain for all clients, connections and channels
    INFO ThreadId(01) scan.chain{chain=osmo-test-5}: scanning all clients...
    # DISREGARD THE FOLLOWING ERROR, IT WILL STILL WORK
    ERROR ThreadId(01) spawn: failed to spawn worker for a chain, reason: query: gRPC call `query_clients` failed with status: status: Internal, message: "protocol error: received message with invalid compression flag: 60 (valid flags are 0 and 1) while receiving response with status: 504 Gateway Timeout", details: [], metadata: MetadataMap { headers: {"server": "nginx", "date": "Tue, 04 Jun 2024 13:51:16 GMT", "content-type": "text/html; charset=utf-8", "content-length": "160"} }
  6. Create a new Hermes connection and channel

    $ hermes create channel --a-chain osmo-test-5 --b-chain [MANIFEST_CHAIN_ID] --a-port transfer --b-port transfer --new-client-connection --yes
  7. Verify setup

    # Query the Manifest client status
    $ hermes query clients --host-chain [MANIFEST_CHAIN_ID]
    SUCCESS [
        ClientChain {
            client_id: ClientId(
                "07-tendermint-0",
            ),
            chain_id: ChainId {
                id: "osmo-test-5",
                version: 5,
            },
        },
    ]
    
    # `07-tendermint-0` is the client ID on the manifest side
    
    # Query the Manifest connection status
    $ hermes query connections --chain [MANIFEST_CHAIN_ID]
    SUCCESS [
        ConnectionId(
            "connection-0",
        ),
        ConnectionId(
            "connection-localhost",
        ),
    ]
    
    # `connection-0` is the connection ID on the manifest side
    
    $ hermes query connection end --chain [MANIFEST_CHAIN_ID] --connection connection-0
    SUCCESS ConnectionEnd {
        state: Open,
        client_id: ClientId(
            "07-tendermint-0",
        ),
        counterparty: Counterparty {
            client_id: ClientId(
                "07-tendermint-3571",
            ),
            connection_id: Some(
                ConnectionId(
                    "connection-3136",
                ),
            ),
            prefix: ibc,
        },
        versions: [
            Version {
                identifier: "1",
                features: [
                    "ORDER_ORDERED",
                    "ORDER_UNORDERED",
                ],
            },
        ],
        delay_period: 0ns,
    }
    
    # `07-tendermint-3571` is the client ID on the osmosis side
    # `connection-3136` is the connection ID on the osmosis side
    
    $ hermes query channels --chain [MANIFEST_CHAIN_ID]
    SUCCESS [
        PortChannelId {
            channel_id: ChannelId(
                "channel-0",
            ),
            port_id: PortId(
                "transfer",
            ),
        },
    ]
    
    # `channel-0` is the channel ID on the manifest side
    
    $ hermes query channel end --chain [MANIFEST_CHAIN_ID] --port transfer --channel channel-0
    SUCCESS ChannelEnd {
        state: Open(
            NotUpgrading,
        ),
        ordering: Unordered,
        remote: Counterparty {
            port_id: PortId(
                "transfer",
            ),
            channel_id: Some(
                ChannelId(
                    "channel-8012",
                ),
            ),
        },
        connection_hops: [
            ConnectionId(
                "connection-0",
            ),
        ],
        version: Version(
            "ics20-1",
        ),
        upgrade_sequence: 0,
    }
    
    # `channel-8012` is the channel ID on the osmosis side

    At this point we have a working 2-way IBC!

    Let's recap the client/connection/channel information. You will need those for the next steps.

    Manifest client ID: 07-tendermint-0
    Osmosis client ID: 07-tendermint-3571
    Manifest connection ID: connection-0
    Osmosis connection ID: connection-3136
    Manifest channel ID: channel-0
    Osmosis channel ID: channel-8012
    
  8. Transfer some tokens from osmosis to manifest

    hermes tx ft-transfer --dst-chain manifest-test-1 --src-chain osmo-test-5 --src-port transfer --src-channel channel-8012 --amount 2 --denom uosmo --timeout-height-offset 1000
  9. Verify tokens were transfered

    # Retrieve the [MANIFEST_ADDRESS]
    $ hermes keys list --chain [MANIFEST_CHAIN_ID]
    SUCCESS 
    - keymanifest (manifest13a9kcn6...mmn7ukncg3cll723zz) # The `manifest1...` string is the [MANIFEST_ADDRESS]
    
    # Check the MANIFEST_ADDRESS balance
    $ manifestd q bank balances [MANIFEST_ADDRESS]
    balances:
    - amount: "2"
      denom: ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518
    - amount: "98"
      denom: umfx
    pagination:
      total: "2"

    where ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518 is the IBC identifier corresponding to uosmo, as showed by

    $ manifestd q ibc-transfer denom-trace ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518
    denom_trace:
        base_denom: uosmo
        path: transfer/channel-0

    We now have uosmo tokens on the Manifest chain!

  10. Transfer umfx to Osmosis

    $ hermes tx ft-transfer --dst-chain osmo-test-5 --src-chain manifest-test-1 --src-port transfer --src-channel channel-0 --amount 2 --denom umfx --timeout-height-offset 1000
  11. Verify tokens were transfered

    # Retrieve the [OSMOSIS_ADDRESS]
    $ hermes keys list --chain osmo-test-5
    SUCCESS 
    - keyosmosis (osmo1jtjvlzcq...p6uf7pwa9nua523) # The `osmo1...` string is the [OSMOSIS_ADDRESS]
    
    # Check the OSMOSIS_ADDRESS balance
    $ osmosisd q bank balances [OSMOSIS_ADDRESS] --node https://rpc.osmotest5.osmosis.zone:443
    balances:
    - amount: "2"
      denom: ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D
    - amount: "49988442"
      denom: uosmo
    pagination:
      next_key: null
      total: "0"

    where ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D is the IBC identifier corresponding to umfx. Use https://www.mintscan.io/osmosis-testnet/ and search for your osmo1... address on the Osmosis Testnet to view the transaction detail.

  12. Create the lp.json file with the following liquidity pool confituration

    {
        "weights": "1ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D,1uosmo",
        "initial-deposit": "1ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D,1uosmo",
        "swap-fee": "0.01",
        "future-governor": "168h"
    }

    where ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D is the IBC identifier corresponding to umfx. This configuration means that 1umfx == 1uosmo.

    NOTE: One will need to configure the proper weight on the mainnet following the umfx token launch price. NOTE: The swap fee is also TBD.

  13. Create the liquidity pool

    # The creator of the LP, here `osmoibc`, will need `uosmo` funds for the pool creation
    $ osmosisd tx gamm create-pool --pool-file lp.json --node https://rpc.osmotest5.osmosis.zone:443 --from osmoibc --fees 5000uosmo --chain-id osmo-test-5 --gas 2000000

    You can retrieve the pool ID using https://www.mintscan.io/osmosis-testnet/. Search for the pool creator address and find the Create Balance Pool transaction from the transaction list. Click on it and then click on Event Logs. Expand the [23] Pool Created box and you should see the Pool Id.

  14. Query the liquidity pool

    $ osmosisd q gamm pool [POOL_ID] --node https://rpc.osmotest5.osmosis.zone:443
    pool:
      '@type': /osmosis.gamm.v1beta1.Pool
      address: osmo13jlfrqhv3kuexf8trdhamnastzf4vz580c2m4j8n6cvppvsnnn5scqn27d
      future_pool_governor: 168h
      id: "479"
      pool_assets:
      - token:
          amount: "1"
          denom: ibc/CEE22D005E967405D7AF1B5E3658B11C75FF240A21F335DD868C6E240330B43D
        weight: "1073741824"
      - token:
          amount: "1"
          denom: uosmo
        weight: "1073741824"
      pool_params:
        exit_fee: "0.000000000000000000"
        smooth_weight_change_params: null
        swap_fee: "0.010000000000000000"
      total_shares:
        amount: "100000000000000000000"
        denom: gamm/pool/479
      total_weight: "2147483648"

    where [POOL_ID] is the ID of the liquidity pool.

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