Skip to content

Instantly share code, notes, and snippets.

@jgryffindor
Forked from fmorency/osmo-ibc-lp.md
Created July 8, 2025 14:50
Show Gist options
  • Select an option

  • Save jgryffindor/c130c766ca9d1307b359a8ff76067aa6 to your computer and use it in GitHub Desktop.

Select an option

Save jgryffindor/c130c766ca9d1307b359a8ff76067aa6 to your computer and use it in GitHub Desktop.

Revisions

  1. @fmorency fmorency created this gist Jun 4, 2024.
    395 changes: 395 additions & 0 deletions osmo-ibc-lp.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,395 @@
    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
    ```shell
    $ 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
    ```
    1. Configure Hermes
    ```shell
    $ mkdir ~/.hermes
    $ touch ~/.hermes/config.toml
    ```

    Copy the following content in `~/.hermes/config.toml`
    ```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`.
    1. Add keys to Hermes
    ```shell
    # 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
    ```
    1. 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.
    ```shell
    $ 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
    ```
    1. Start Hermes
    ```shell
    $ 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"} }
    ```
    1. Create a new Hermes connection and channel
    ```shell
    $ hermes create channel --a-chain osmo-test-5 --b-chain [MANIFEST_CHAIN_ID] --a-port transfer --b-port transfer --new-client-connection --yes
    ```
    1. Verify setup
    ```shell
    # 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
    ```
    1. Transfer some tokens from osmosis to manifest
    ```shell
    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
    ```
    1. Verify tokens were transfered
    ```shell
    # 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
    ```shell
    $ 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!
    1. Transfer `umfx` to Osmosis
    ```shell
    $ 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
    ```
    1. Verify tokens were transfered
    ```shell
    # 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.
    1. Create the `lp.json` file with the following liquidity pool confituration
    ```json
    {
    "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.
    1. Create the liquidity pool
    ```shell
    # 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`.
    1. Query the liquidity pool
    ```shell
    $ 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.