NAV
Python Golang

Change Log

2025-11-10

2025-09-24

2025-07-29

2025-04-21

2025-02-17

2024-08-06

2024-07-30

2024-03-08

2024-01-25

2024-01-02

2023-09-06

2023-08-28

Introduction

Welcome to Injective's documentation!

Here you can find a comprehensive overview of our protocol, as well as tutorials, guides and general resources for developers and API traders.

If you would like to ask any questions or be a part of our community, please join our Discord Group or Telegram Group. We have a dedicated channel in our Discord group for questions related to the API.

Clients

Python Client

Dependencies

Ubuntu

sudo apt install python3.X-dev autoconf automake build-essential libffi-dev libtool pkg-config

Fedora

sudo dnf install python3-devel autoconf automake gcc gcc-c++ libffi-devel libtool make pkgconfig

macOS

brew install autoconf automake libtool

Installation

Install injective-py from PyPI using pip.

pip install injective-py

Reference

InjectiveLabs/sdk-python

Choose Exchange V1 or Exchange V2 queries

The Injective Python SDK provides two different clients for interacting with the exchange:

Example - Exchange V1 Client

from injective.async_client import AsyncClient
from injective.network import Network

async def main():
    # Initialize client with mainnet
    client = AsyncClient(network=Network.mainnet())
    # Or use testnet
    # client = AsyncClient(network=Network.testnet())
    # Use V1 exchange queries here
  1. Exchange V1 Client (async_client module):
    • Use this client if you need to interact with the original Injective Exchange API
    • Import using: from injective.async_client import AsyncClient
    • Suitable for applications that need to maintain compatibility with the original exchange interface

Example - Exchange V2 Client

from injective.async_client_v2 import AsyncClient
from injective.network import Network

async def main():
    # Initialize client with mainnet
    client = AsyncClient(network=Network.mainnet())
    # Or use testnet
    # client = AsyncClient(network=Network.testnet())
    # Use V2 exchange queries here
  1. Exchange V2 Client (async_client_v2 module):
    • Use this client for the latest exchange features and improvements
    • Import using: from injective.async_client_v2 import AsyncClient
    • Recommended for new applications and when you need access to the latest exchange features

Both clients provide similar interfaces but with different underlying implementations. Choose V2 for new projects unless you have specific requirements for V1 compatibility.

Market Format Differences:

Exchange Endpoint Format Differences:

Golang Client

1. Create your own client repo and go.mod file

go mod init foo

2. Import SDK into go.mod

require ( github.com/InjectiveLabs/sdk-go v1.58.0 )

Consult the sdk-go repository to find the latest release and replace the version in your go.mod file. Version v1.39.4 is only an example and must be replaced with the newest release

3. Download the package

Download the package using go mod download

go mod download github.com/InjectiveLabs/sdk-go

Choose Exchange V1 or Exchange V2 queries

The SDK provides two different clients for interacting with the Injective Exchange:

Example - ChainClient

// For Exchange V1
client := chainclient.NewChainClient(...)

// For Exchange V2
clientV2 := chainclient.NewChainClientV2(...)

Markets Assistant

Example - Markets Assistant

// For Exchange V1 markets
marketsAssistant, err := chain.NewMarketsAssistant(ctx, client)  // ChainClient instance
if err != nil {
    // Handle error
}

// For Exchange V2 markets
marketsAssistantV2, err := chain.NewHumanReadableMarketsAssistant(ctx, clientV2)  // ChainClientV2 instance
if err != nil {
    // Handle error
}

The SDK provides a Markets Assistant to help you interact with markets in both V1 and V2. Here's how to create instances for each version

The Markets Assistant provides helper methods to:

Make sure to use the correct version of the Markets Assistant that matches your ChainClient version to ensure compatibility. The V1 assistant (NewMarketsAssistant) will only work with V1 markets, while the V2 assistant (NewHumanReadableMarketsAssistant) provides access to V2 markets and their features.

Format Differences

There are important format differences between V1 and V2 endpoints:

This format difference is one of the key improvements in V2, making it easier to work with market data without manual conversion.

Markets and Tokens information

Since version 1.49 the SDK is able also to get the markets and tokens information directly from the chain data (through the Indexer process). The benefit of this approach is that it is not necessary to update the SDK version when a new market is created in the chain or a new token is added.

Example - Get markets and tokens from Indexer (ExchangeClient)

package main

import (
    "context"
    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/InjectiveLabs/sdk-go/client/core"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    "os"

    "github.com/InjectiveLabs/sdk-go/client/common"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint, "/websocket")
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketsAssistant, err := core.NewMarketsAssistantUsingExchangeClient(ctx, exchangeClient)
    if err != nil {
        panic(err)
    }
}




















































Example - MarketsAssistant with all tokens

package main

import (
    "context"
    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/InjectiveLabs/sdk-go/client/core"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    "os"

    "github.com/InjectiveLabs/sdk-go/client/common"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint, "/websocket")
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketsAssistant, err := core.NewMarketsAssistantWithAllTokens(ctx, exchangeClient, chainClient)
    if err != nil {
        panic(err)
    }
}

By default the MarketsAssistant will only initialize the tokens that are part of an active market. In order to let it use any of the tokens available in the chain, the user has to create the MarketsAssistant instance using the function NewMarketsAssistantWithAllTokens.

The MarketsAssistant instance can be used with the following ChainClient functions:

Reference

InjectiveLabs/sdk-go.

Typescript Client

Installation

Install the @injectivelabs/sdk-ts npm package using yarn

yarn add @injectivelabs/sdk-ts

Reference

To see Typescript examples please check the Typescript SDK documentation page listed above

For other languages

Currently Injective provides SDKs only for Go, Python and TypeScript. To interact with the nodes using a different language please connect directly using the gRPC proto objects. The compiled proto files for C++, C# and Rust can be found in InjectiveLabs/injective-proto

Overview

Injective is a DeFi focused layer-1 blockchain built for the next generation of decentralized derivatives exchanges. The Injective Chain is a Tendermint-based IBC-compatible blockchain which supports a decentralized orderbook-based DEX protocol and a trustless ERC-20 token bridge to the Ethereum blockchain.

It is the first decentralized exchange focused layer-1 blockchain for perpetual swaps, futures, and spot trading that unlocks the full potential of decentralized derivatives and borderless DeFi. Every component of the protocol has been built to be fully trustless, censorship-resistant, publicly verifiable, and front-running resistant.

By providing the unrestricted and unprecedented ability to express diverse views in decentralized financial markets, we strive to empower individuals with the ability to more efficiently allocate capital in our society.

Architecture Overview

Injective enables traders to create and trade on arbitrary spot and derivative markets. The entire process includes on-chain limit orderbook management, on-chain trade execution, on-chain order matching, on-chain transaction settlement, and on-chain trading incentive distribution through the logic codified by the Injective Chain's exchange module.

Architecturally there are two main services that traders should concern themselves with:

  1. The Injective Chain node (the Chain API)
  2. The Injective Exchange API

The trading lifecycle is as follows:

  1. First, traders cryptographically sign a transaction containing one or more order messages (e.g. MsgBatchCreateDerivativeLimitOrders, MsgCreateSpotMarketOrder, MsgCancelDerivativeLimitOrder, etc. ).
  2. Then the transaction is broadcasted to an Injective Chain node.
  3. The transaction is then added to the mempool and becomes included in a block. More details on this process can be found here.
  4. The handler for each respective message is run. During handler execution, order cancel and liquidation messages are processed immediately, whereas order creation messages are added to a queue.
  5. At the end of the block, the batch auction process for order matching begins.
    • First, the queued market orders are executed against the resting orderbook (which does NOT include the new orders from the current block) and are cleared at a uniform clearing price.
    • Second, the queued limit orders are matched against each other and the resting orderbook to result in an uncrossed orderbook. Limit orders created in that block are cleared at a uniform clearing price while resting limit orders created in previous blocks are cleared at an equal or better price than their limit order price.
  6. The funds are settled accordingly, with positions being created for derivative trades and assets being swapped for spot trades.
  7. Events containing the trade and settlement information are emitted by the Chain.
  8. The Injective Exchange API backend indexes the events and pushes updates to all subscribed traders.

Key Differences To CEX

To summarize the sequence of state changes on the Injective Chain:

  1. Mempool: A queue of pending transactions.
  2. BeginBlocker: Code that is executed at the beginning of every block. We use it for certain maintenance tasks (details can be found in the exchange module documentation).
  3. Handler: Code that is executed when a transaction is included in a block.
  4. EndBlocker: Code that is executed at the end of every block. We use it to match orders, calculate changes in funds, and update positions.

Comparison to CEX

Centralized Exchange (CEX) Decentralized Exchange (DEX)
Exchange Gateway Injective Chain Handler
Exchange Matching Engine Injective Chain EndBlocker
Exchange Trade Report Injective Chain EndBlocker
Co-location Injective Node (Decentralized Validators)

Frequent Batch Auction (FBA)

The goal is to further prevent any Front-Running in a decentralized setting. Most DEX's suffer from this as all information is public and traders can collude with miners or pay high gas fees enabling them to front-run any trades. We mitigate this by combining fast block times with a Frequent Batch Auction:

In any given block:

  1. Calculate one uniform clearing price for all market orders and execute them. For an example for the market order matching in FBA fashion, look here.
  2. Limit orders are combined with the resting orderbook and orders are matched as long as there is still negative spread. The limit orders are all matched at one uniform clearing price. For an example for the limit order matching in FBA fashion, look here.

Trading Fees and Gas

If you are a trader on existing centralized exchanges, you will be familiar with the concept of trading fees. Traders are charged a fee for each successful trade. However, for a DEX, there are additional gas costs that must be paid to the network. And luckily, the gas fee from trading on Injective is very minimal.

Mark Price Margin Requirement

Quantity = 2 BTC, InitialMarginRatio = 0.05
MarkPrice = $45,000, EntryPrice = $43,000

Margin ≥ 2 * 0.05 * $45,000 = $4,500

MarginLong ≥ max(2 * (0.05 * $45,000 - ($45,000 - $43,000)), $4,500)
MarginLong ≥ max($500, $4,500) = $4,500

MarginShort ≥ max(2 * (0.05 * $45,000 - ($43,000 - $45,000)), $4,500)
MarginShort ≥ max($8,500, $4,500) = $8,500

So in this case if the trader wanted to create a short position with
an entry price which essentially starts at a loss of $2,000 as
unrealized PNL, he would need to post at a minimum $8,500 as margin,
rather than the usual required $4,500.

You might be familiar with margin requirements on Centralized Exchanges. When creating a new position, it must fulfill the following requirement:

For example in a market with maximally 20x leverage, your initial margin must be at least 0.05 of the order's notional (entryPrice * quantity). On Injective additionally the margin must also fulfill the following mark price requirement:

where PNL is the expected profit and loss of the position if it was closed at the MarkPrice.

Liquidations

Long Position:
Quantity = 1 BTC, MaintenanceMarginRatio = 0.05
EntryPrice = $50,000, Margin = $5,000

Now the MarkPrice drops down to $47,300, which is below the liquidation price of $47,368.42 (when margin = $2,368.42, maintenance ratio ≈ .04999998).

The position is auto-closed via reduce-only order:

Sell order:
Quantity = 1 BTC, Price = $0, Margin = $0

Assuming it gets matched with a clearing price of 47,100:

Liquidation Payout = Position Margin + PNL = $5,000 - $2,900 = $2,100
Liquidator Profit = $2,100 * 0.5 = $1,050
Insurance Fund Profit = $2,100 * 0.5 = $1,050

When your position falls below the maintenance margin ratio, the position can and likely will be liquidated by anyone running the liquidator bot. You will loose your entire position and all funds remaining in the position. On-chain, a reduce-only market order of the same size as the position is automatically created. The market order will have a worst price defined as Infinity or 0, implying it will be matched at whatever prices are available in the order book.

One key difference is that the payout from executing the reduce-only market order will not go towards the position owner. Instead, half of the remaining funds are transferred to the liquidator bot and the other half is transferred to the insurance fund.

If the payout in the position was negative, i.e., the position's negative PNL was greater than its margin, then the insurance fund will cover the missing funds.

Note: liquidations are executed immediately in a block before any other order matching occurs.

Fee Discounts

Fee discounts are enabled by looking at the past trailing 30 day window. As long as you meet both conditions for a tier (volume traded AND staked amount), you will receive the respective discounts.

Funding Rate

The hourly funding rate on perpetual markets determines the percentage that traders on one side have to pay to the other side each hour. If the rate is positive, longs pay shorts. If the rate is negative, shorts pay longs. The further trade prices deviate from the mark price within the hour, the higher the funding rate will be up to a maximum of 0.0625% (1.5% per day).

Closing a Position

Suppose you have an open position:

- Direction = Long
- Margin = $5,000
- EntryPrice = $50,000
- Quantity = 0.5 BTC

You create a new vanilla order for

- Direction = Sell
- Margin = $10,000
- Price = $35,000
- Quantity = 0.75 BTC

which is fully matched. First, the position is fully closed:

- OrderMarginUsedForClosing = OrderMargin * CloseQuantity / OrderQuantity
- OrderMarginUsedForClosing = $10,000 * 0.5 / 0.75 = $6,667

The proportional closing order margin is then used for the payout:

- Payout = PNL + PositionMargin + OrderMarginUsedForClosing
- Payout = ($35,000-$50,000) * 0.5 + $5,000 + $6,667 = $4,167

And a new position is opened in the opposite direction:

- Direction = Short
- Margin = $3,333
- Price = $35,000
- Quantity = 0.25 BTC

There are two ways to close a position:

Closing via Reduce-Only Order

When you close a position via a reduce-only order, no additional margin is used from the order. All reduce-only orders have a margin of zero. In addition, reduce-only orders are only used to close positions, not to open new ones.

Closing via Vanilla Order

You can also close a position via vanilla orders. When a sell vanilla order is getting matched while you have an open Long position, the position will be closed at the price of the sell order. Depending on the size of the order and position, the position may be either

  1. partially closed
  2. fully closed
  3. or fully closed with subsequent opening of a new position in the opposite direction.

Note that how the margin inside the order is used depends on which of the three scenarios you are in. If you close a position via vanilla order, the margin is only used to cover PNL payouts, not to go into the position. If the order subsequently opens a new position in the opposite direction (scenario 3), the remaining proportional margin will go towards the new position.

Trading Rewards

Assume you have a trading rewards campaign with 100 INJ as rewards:

Reward Tokens: 100 INJ
Trader Reward Points = 100
Total Reward Points = 1,000

Trader Rewards = Trader Reward Points / Total Reward Points * Reward Tokens
Trader Rewards = 100 / 1,000 * 100 INJ = 10 INJ

During a given campaign, the exchange will record each trader's cumulative trading reward points obtained from trading fees (with boosts applied, if applicable) from all eligible markets. At the end of each campaign each trader will receive a pro-rata percentage of the trading rewards pool based off their trading rewards points from that campaign epoch. Those rewards will be automatically deposited into the trader's respective wallets, it's not necessary to manually withdraw them.

Reduce-Only Order Precedence

Imagine a trader has the following position:

And the following SELL orders:

Buy Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.1 BTC Reduce-only
$65,400 0.1 BTC Vanilla
$64,500 0.3 BTC Vanilla
$63,500 0.1 BTC Reduce-only

This has some implications when placing new orders.

Upon placing a reduce-only order:

We check if any reduce-only orders would be invalid after executing all of the trader's other limit sell orders that have better prices in the same direction.

In our example, consider a new reduce-only order of 0.4 BTC at $64,600.

Sell Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.1 BTC Reduce-only
$65,400 0.1 BTC Vanilla
$64,600 0.4 BTC Reduce-only
$64,500 0.3 BTC Vanilla
$63,500 0.1 BTC Reduce-only

This is perfectly valid and no further action is required. If the buy price hit $65,500 and all limit sell orders less than or equal to that price were filled, then the long position would be closed. If the price hit $66,500 and the vanilla sell order was filled, then the trader would open a 0.2 BTC short position. But what if the reduce-only order was for 0.5 BTC instead?

Sell Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.1 BTC Reduce-only
$65,400 0.1 BTC Vanilla
$64,600 0.5 BTC Reduce-only
$64,500 0.3 BTC Vanilla
$63,500 0.1 BTC Reduce-only

If the orders are getting matched, once the last vanilla order of 0.1 BTC at $65,400 is filled, the position will have been reduced to 1 BTC - 0.1 BTC - 0.3 BTC - 0.5 BTC - 0.1 BTC = 0 BTC. The next reduce-only order of 0.1 BTC at $65,500 will thus be invalid.

To prevent that, we automatically cancel all reduce-only orders at a price where the cumulative sum of orders up to and including the reduce-only order would add up to more than the trader’s current long amount. Another way to think about it: we find the reduce-only order with the highest price such that all orders (vanilla and reduce-only) including and below that price add up in quantity to less than the long quantity. All reduce-only orders above that price will be canceled so that no reduce-only orders exist when the position is closed or short. The same concept applies to reduce-only orders on short positions, but we look for the lowest price instead of the highest on buy orders so that no reduce-only orders exist when the position is closed or long.

Upon placing a vanilla limit order:

We check if any reduce-only limit orders would be invalidated if all the orders up to and including the new vanilla limit order were filled.

In our example, consider a new vanilla order of 0.4 BTC at $64,600.

Sell Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.1 BTC Reduce-only
$65,400 0.1 BTC Vanilla
$64,600 0.4 BTC Vanilla
$64,500 0.3 BTC Vanilla
$63,500 0.1 BTC Reduce-only

Again this perfectly valid and no further action is required because all order quantities up to the highest priced reduce-only order add up to ≤ the long position quantity. But what if the order was for 0.5 BTC instead?

Sell Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.1 BTC Reduce-only
$65,400 0.1 BTC Vanilla
$64,600 0.5 BTC Vanilla
$64,500 0.3 BTC Vanilla
$63,500 0.1 BTC Reduce-only

If the orders are getting matched, once the last reduce-only order of $65,500 is reached, the position will have been reduced to 1 BTC - 0.1 BTC - 0.3 BTC - 0.5 BTC - 0.1 BTC = 0 BTC. A reduce-only order of 0.1 BTC after that will thus be invalid.

To prevent this, we automatically cancel the existing 0.1 BTC reduce-only order. In other words, new vanilla limit orders can invalidate and auto-cancel existing reduce-only limit orders if the reduce-only order becomes invalid at its price.

Rate Limits

The public mainnet and testnet nodes have a request rate limit associated to the requester IP address. The limits are:

Each endpoint's section in this document clarifies which group the endpoint belongs to. When the limit is reached the server will respond sending an error response with code 429.

Order types

Gas estimation

Interactions with the Injective Chain that involve processing will incur gas consumption. The gas required for any action is related to the interactions with the chain store, and thus, the amount of gas is not deterministic. Users sending messages to the chain in transactions must estimate the gas required. There are two primary methods for determining the gas required for a transaction:

The InjectiveLabs team is developing a new functionality to make the gas requirement for certain Exchange module messages fixed, thereby making gas calculation deterministic. The fixed gas values, which will be implemented, can already serve as a reliable approximation for manually calculating the gas requirement for a transaction.

Fixed gas requirement

The following table lists message types with a fixed gas requirement. Any message not mentioned will continue to have a non-deterministic gas requirement based on chain store interactions.

Message type Gas units
MsgCreateDerivativeLimitOrderGas 120000
MsgCreateDerivativeLimitPostOnlyOrderGas 140000
MsgCreateDerivativeMarketOrderGas 105000
MsgCancelDerivativeOrderGas 70000
MsgCreateSpotLimitOrderGas 100000
MsgCreateSpotLimitPostOnlyOrderGas 120000
MsgCreateSpotMarketOrderGas 50000
MsgCancelSpotOrderGas 65000
MsgCreateBinaryOptionsLimitOrderGas 120000
MsgCreateBinaryOptionsLimitPostOnlyOrderGas 140000
MsgCreateBinaryOptionsMarketOrderGas 105000
MsgCancelBinaryOptionsOrderGas 70000
MsgDepositGas 70000
MsgWithdrawGas 70000
MsgSubaccountTransferGas 70000
MsgExternalTransferGas 70000
MsgIncreasePositionMarginGas 70000
MsgDecreasePositionMarginGas 70000

For the MsgBatchUpdateOrders the gas requirement will also be fixed. The gas requirement for each order action will match the individual order message actions as specified in the table. This applies similarly to the following batch messages:

Market and Limit Order Examples

Adding a Spot Market Buy Order

→ The account's available balance is decremented by 5,000 USDT + Taker Fee = 5,005 USDT.

Upon matching with a resting sell order with price of 4 USDT the new account balances are calculated as:

Adding a Spot Market Sell Order

→ The account's available balance is decremented by 1,000 INJ.

Upon matching with a resting sell order with price of 4 USDT the new account balances are calculated as:

Adding a Spot Limit Buy Order

→ The account's available balance is decremented by 5,000 USDT + Taker Fee = 5,005 USDT.

After the order is submitted:

Adding a Spot Limit Sell Order

→ The account's available balance is decremented by 1,000 INJ.

After the order is submitted:

Derivative Market Order Payouts

The payouts for derivative market orders work the same way as for derivative limit orders, with the one difference being they are cancelled if not immediately matched. See spot market and derivative limit orders as reference.

Adding a Derivative Limit Buy Order

→ The account's available balance is decremented by Margin + Taker Fee = 1000 + 5000 * 0.001 = 1005 USDT.

After creation:

If Unmatched, the order becomes a resting limit order (maker) and we refund the taker fee on vanilla orders (reduce-only orders don't pay upfront fees):

If Matched:

Assuming:

Would result in:

1. Closing existing position with proportional order margin for closing:

2. Opening new position in opposite direction:

3. Refunding margin difference from order price vs. clearing price:

4. Refunding fee difference from order price vs. clearing price:

Market Order Matching

Existing Orderbook

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
$64,3600.5 BTC
PriceQuantity
$64,2100.1 BTC
$64,2050.4 BTC
$64,2000.2 BTC

New Orders

Resulting Orderbook

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
PriceQuantity
$64,2050.2 BTC
$64,2000.2 BTC

Market Buys: Matching the highest priced market buy order first for 0.4 BTC. Now for the second market buy order only 0.1 BTC is left at matchable price, meaning the other 0.1 BTC in the order will be cancelled. Both orders will be matched with the single resting limit order at a price of 64,360 for a total quantity of 0.5 BTC.

Market Sells: Matching the first two market sell orders for at a matching price of (64,210*0.1 + 64,205*0.2) / 0.3 = 64,206.67 for a total quantity of 0.3 BTC. The resting limit orders are both matched at their specified price points of 64,210 and 64,205. Since the last market sell order of 69,000 cannot be fulfilled, it is cancelled.

Limit Order Matching

Existing Orderbook

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
$64,2500.5 BTC
PriceQuantity
$64,2100.1 BTC
$64,2050.3 BTC
$64,2000.2 BTC

New Orders

Sells Buys
PriceQuantity
$64,2200.4 BTC
$64,1800.2 BTC
PriceQuantity
$64,3700.4 BTC
$64,3600.2 BTC

Matching Orders

All new orders are incorporated into the existing orderbook. In our case this results in a negative spread:

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
$64,2500.5 BTC
$64,2200.4 BTC
$64,1800.2 BTC
PriceQuantity
$64,3700.4 BTC
$64,3600.1 BTC
$64,2100.1 BTC
$64,2050.3 BTC
$64,2000.2 BTC

As long as negative spread exists, orders are matched against each other. The first buy order is fully matched:

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
$64,2500.4 BTC
$64,2200.2 BTC
PriceQuantity
$64,3600.1 BTC
$64,2100.1 BTC
$64,2050.3 BTC
$64,2000.2 BTC

Now the second buy order can still be fully matched:

Sells Buys
PriceQuantity
$64,3900.3 BTC
$64,3700.2 BTC
$64,2500.4 BTC
$64,2200.1 BTC
PriceQuantity
$64,2100.1 BTC
$64,2050.3 BTC
$64,2000.2 BTC

This is the end of the matching, since no more negative spread exists (64,220 > 62,210).

All orders will be matched with a uniform clearing price within the range of the last sell order price and the last buy order price.

Step 1: Check if clearing price range is out of bounds regarding the resting orderbook mid price.

Step 2: Check if clearing price range is out of bounds regarding the mark price.

Step 3: Set clearing price = mid price or mark price for spot or perpetual markets, respectively, or in the case where these prices are out of bounds, use last buy or last sell price.

Resources

Here you can find a comprehensive overview of the exchange ecosystem on Injective, guides and general resources for developers and API traders.

Coin denoms and market IDs for testnet and mainnet can be found on the Injective testnet explorer and mainnet explorer under the Markets tab and Assets tab.

Explorer

A Web interface that allows you to search for information on the Injective Chain

Explorer Mainnet

Explorer Testnet

Faucet

A web-based service that provides free tokens to users on testnet and allows them to experiment on the Injective Chain.

Faucet

Status

Monitor the uptime of all public services.

Testnet Status

Mainnet Status

Message Broadcaster

In the examples included in this documentation you will see all the steps required to interact with the chain, from deriving a public key from a private key, creating messages to query the chain or creating orders, to creating and broadcasting transactions to the chain. Before going to the examples of all the possible actions it is important to state that you can avoid implementing yourself all the steps to create and configure correctly a transaction. If you are not interested in defining all the low level aspects you can use the component called MsgBroadcasterWithPk. To use the broadcaster you just need to create an instance of MsgBroadcasterWithPk, and once all the messages to be included in the transaction have been created, use the broadcast method, passing the messages as a parameter. The broadcaster will take care of: - Calculate the gas fee to pay for the transaction - Create the transaction and configure it - Sign the transaction - Broadcast it to the chain

Broadcaster for standard account

Calculate gas fee simulating the transaction

Example - Calculate gas fee simulating the transaction:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    spot_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3"),
            quantity=Decimal("55"),
            order_type="BUY",
            cid=(str(uuid.uuid4())),
        ),
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("300"),
            quantity=Decimal("55"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    msg = composer.msg_batch_update_orders(
        sender=address.to_acc_bech32(),
        spot_orders_to_create=spot_orders_to_create,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

For the broadcaster to calculate the gas fee running the simulation, create an instance of MsgBroadcasterWithPk with the message new_using_simulation.

This is the most common broadcaster configuration. Unless you are using grantee accounts (delegated accounts with authz) you should use this one.




















































Calculate gas fee without simulation

Example - Calculate gas fee without simulation:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()
    await client.sync_timeout_height()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    spot_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3"),
            quantity=Decimal("55"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("300"),
            quantity=Decimal("55"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    msg = composer.msg_batch_update_orders(
        sender=address.to_acc_bech32(),
        spot_orders_to_create=spot_orders_to_create,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

For the broadcaster to calculate the gas fee based on the messages included without running the simulation, create an instance of MsgBroadcasterWithPk with the message new_without_simulation.



Broadcaster for grantee account

This is the required broadcaster configuration when operating with grantee accounts. The broadcaster will take care of creating the MsgExec message, so that the user keeps passing the same messages to the broadcast method that are passed when using the standard broadcaster with non-grantee accounts.

Calculate gas fee simulating the transaction

Example - Calculate gas fee simulating the transaction:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import Address, PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_GRANTEE_PRIVATE_KEY")
    granter_inj_address = os.getenv("INJECTIVE_GRANTER_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_for_grantee_account_using_simulation(
        network=network,
        grantee_private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # prepare tx msg
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    granter_address = Address.from_acc_bech32(granter_inj_address)
    granter_subaccount_id = granter_address.get_subaccount_id(index=0)

    msg = composer.msg_create_spot_limit_order(
        market_id=market_id,
        sender=granter_inj_address,
        subaccount_id=granter_subaccount_id,
        fee_recipient=address.to_acc_bech32(),
        price=Decimal("7.523"),
        quantity=Decimal("0.01"),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

For the broadcaster to calculate the gas fee running the simulation, create an instance of MsgBroadcasterWithPk with the message new_for_grantee_account_using_simulation.














































Calculate gas fee without simulation

Example - Calculate gas fee without simulation:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import Address, PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_GRANTEE_PRIVATE_KEY")
    granter_inj_address = os.getenv("INJECTIVE_GRANTER_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    # load account
    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_for_grantee_account_without_simulation(
        network=network,
        grantee_private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # prepare tx msg
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    granter_address = Address.from_acc_bech32(granter_inj_address)
    granter_subaccount_id = granter_address.get_subaccount_id(index=0)

    msg = composer.msg_create_spot_limit_order(
        market_id=market_id,
        sender=granter_inj_address,
        subaccount_id=granter_subaccount_id,
        fee_recipient=address.to_acc_bech32(),
        price=Decimal("7.523"),
        quantity=Decimal("0.01"),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

For the broadcaster to calculate the gas fee based on the messages included without running the simulation, create an instance of MsgBroadcasterWithPk with the message new_for_grantee_account_without_simulation.



Fine-tunning message based gas fee estimation

As mentioned before the gas estimation without using simulation is implemented by using fixed values as gas cost for certain messages and actions. Since the real gas cost can differ at some point from the estimator calculations, the Python SDK allows the developer to fine-tune certain gas cost values in order to improve the gas cost estimation. In the next tables you can find the global values used for gas estimation calculations, that can be modified in your application:

Gas limit estimation based on gas heuristics

This is the estimator implemented with the class GasHeuristicsGasLimitEstimator.

Module Global Variable Description
pyinjective.core.gas_heuristics_gas_limit_estimator SPOT_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one spot limit order
pyinjective.core.gas_heuristics_gas_limit_estimator SPOT_MARKET_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one spot market order
pyinjective.core.gas_heuristics_gas_limit_estimator POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one post only spot limit order
pyinjective.core.gas_heuristics_gas_limit_estimator DERIVATIVE_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one derivative order
pyinjective.core.gas_heuristics_gas_limit_estimator DERIVATIVE_MARKET_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one derivative market order
pyinjective.core.gas_heuristics_gas_limit_estimator POST_ONLY_DERIVATIVE_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one post only derivative limit order
pyinjective.core.gas_heuristics_gas_limit_estimator BINARY_OPTIONS_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one binary options order
pyinjective.core.gas_heuristics_gas_limit_estimator BINARY_OPTIONS_MARKET_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one binary options market order
pyinjective.core.gas_heuristics_gas_limit_estimator POST_ONLY_BINARY_OPTIONS_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one post only binary options limit order
pyinjective.core.gas_heuristics_gas_limit_estimator SPOT_ORDER_CANCELATION_GAS_LIMIT The gas cost associated to the cancellation of one spot order
pyinjective.core.gas_heuristics_gas_limit_estimator DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT The gas cost associated to the cancellation of one derivative order
pyinjective.core.gas_heuristics_gas_limit_estimator BINARY_OPTIONS_ORDER_CANCELATION_GAS_LIMIT The gas cost associated to the cancellation of one binary options order
pyinjective.core.gas_heuristics_gas_limit_estimator DEPOSIT_GAS_LIMIT The gas cost associated to a deposit into a subaccount
pyinjective.core.gas_heuristics_gas_limit_estimator WITHDRAW_GAS_LIMIT The gas cost associated to a withdrawal from a subaccount
pyinjective.core.gas_heuristics_gas_limit_estimator SUBACCOUNT_TRANSFER_GAS_LIMIT The gas cost associated to a funds transfer between subaccounts of the same address
pyinjective.core.gas_heuristics_gas_limit_estimator EXTERNAL_TRANSFER_GAS_LIMIT The gas cost associated to a funds transfer to a subaccount from a different address
pyinjective.core.gas_heuristics_gas_limit_estimator INCREASE_POSITION_MARGIN_TRANSFER_GAS_LIMIT The gas cost associated to increasing a position's margin
pyinjective.core.gas_heuristics_gas_limit_estimator DECREASE_POSITION_MARGIN_TRANSFER_GAS_LIMIT The gas cost associated to decreasing a position's margin
Module Class Global Variable Description
pyinjective.core.broadcaster.py MessageBasedTransactionFeeCalculator TRANSACTION_GAS_LIMIT The gas cost associated to the TX processing
pyinjective.core.gas_heuristics_gas_limit_estimator GasHeuristicsGasLimitEstimator GENERAL_MESSAGE_GAS_LIMIT Generic base gas cost for any message
pyinjective.core.gas_heuristics_gas_limit_estimator BatchUpdateOrdersGasLimitEstimator AVERAGE_CANCEL_ALL_AFFECTED_ORDERS This global represents the expected number of orders to be cancelled when executing a "cancel all orders for a market" action
pyinjective.core.gas_heuristics_gas_limit_estimator ExecGasLimitEstimator DEFAULT_GAS_LIMIT Estimation of the general gas amount required for a MsgExec (for the general message processing)

Gas limit estimation based on chain statistics

This is the estimator implemented with the class GasLimitEstimator, and it is the original implementation for gas estimation without simulations. It has been replaced now by the GasHeuristicsGasLimitEstimator, but the user can still use it.

Module Global Variable Description
pyinjective.core.gas_limit_estimator SPOT_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one spot order
pyinjective.core.gas_limit_estimator DERIVATIVE_ORDER_CREATION_GAS_LIMIT The gas cost associated to the creation of one derivative order
pyinjective.core.gas_limit_estimator SPOT_ORDER_CANCELATION_GAS_LIMIT The gas cost associated to the cancellation of one spot order
pyinjective.core.gas_limit_estimator DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT The gas cost associated to the cancellation of one derivative order
pyinjective.core.gas_limit_estimator SPOT_POST_ONLY_ORDER_MULTIPLIER Multiplier to increase the gas cost for post only spot orders (in addition to the normal spot order cost)
pyinjective.core.gas_limit_estimator DERIVATIVE_POST_ONLY_ORDER_MULTIPLIER Multiplier to increase the gas cost for post only derivative orders (in addition to the normal derivative order cost)
Class Global Variable Description
MessageBasedTransactionFeeCalculator TRANSACTION_GAS_LIMIT The gas cost associated to the TX processing
GasLimitEstimator GENERAL_MESSAGE_GAS_LIMIT Generic base gas cost for any message
GasLimitEstimator BASIC_REFERENCE_GAS_LIMIT Base gas cost for messages not related to orders. Each type of message will calculate its cost multiplying this reference cost by a multiplier
DefaultGasLimitEstimator DEFAULT_GAS_LIMIT The gas cost for all messages for which there is no especial estimator implemented
BatchUpdateOrdersGasLimitEstimator CANCEL_ALL_SPOT_MARKET_GAS_LIMIT This is an estimation of the gas cost per spot order cancel when cancelling all orders for a spot market
BatchUpdateOrdersGasLimitEstimator CANCEL_ALL_DERIVATIVE_MARKET_GAS_LIMIT This is an estimation of the gas cost per derivative order cancel when cancelling all orders for a derivative market
BatchUpdateOrdersGasLimitEstimator MESSAGE_GAS_LIMIT Estimation of the general gas amount required for a MsgBatchUpdateOrders (not for particular actions, but for the general message processing)
BatchUpdateOrdersGasLimitEstimator AVERAGE_CANCEL_ALL_AFFECTED_ORDERS This global represents the expected number of orders to be cancelled when executing a "cancel all orders for a market" action
ExecGasLimitEstimator DEFAULT_GAS_LIMIT Estimation of the general gas amount required for a MsgExec (for the general message processing)
GenericExchangeGasLimitEstimator BASIC_REFERENCE_GAS_LIMIT Base gas cost for messages not related to orders. Each type of message will calculate its cost multiplying this reference cost by a multiplier

Indexer API

The Indexer API is read-only whereas the Chain API is write and also includes a limited set of API requests to read data. The Chain API reads query the blockchain state from the node directly as opposed to the Indexer API which reconstructs state from events emitted by chain.

On a high-level the end-user trading applications and Injective Products use the Indexer API to read data and the Chain API to write data to the blockchain. Even though it’s possible to develop trading applications using the Chain API only, the Indexer API includes more methods, streaming support, gRPC, and also allows you to fetch historical data (the Chain API queries the blockchain state which doesn’t include historical records).

- InjectiveAccountsRPC

InjectiveAccountsRPC defines the gRPC API of the Exchange Accounts provider.

SubaccountsList

Get a list of subaccounts for a specific address.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt"
    subacc_list = await client.fetch_subaccounts_list(account_address)
    print(json.dumps(subacc_list, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    accountAddress := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    res, err := exchangeClient.GetSubaccountsList(ctx, accountAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
account_addressstringAccount address, the subaccounts ownerYes

Response Parameters

Response Example:

{
   "subaccounts":[
      "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
      "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000002",
      "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000"
   ]
}
{
 "subaccounts": [
  "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
  "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000002"
 ]
}
ParameterTypeDescription
subaccountsstring array

SubaccountHistory

Get the subaccount's transfer history.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denom = "inj"
    transfer_types = ["withdraw", "deposit"]
    skip = 1
    limit = 15
    end_time = 1665118340224
    pagination = PaginationOption(skip=skip, limit=limit, end_time=end_time)
    subacc_history = await client.fetch_subaccount_history(
        subaccount_id=subaccount,
        denom=denom,
        transfer_types=transfer_types,
        pagination=pagination,
    )
    print(json.dumps(subacc_history, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    accountPB "github.com/InjectiveLabs/sdk-go/exchange/accounts_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    denom := "inj"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    transferTypes := []string{"deposit"}
    skip := uint64(0)
    limit := int32(10)

    req := accountPB.SubaccountHistoryRequest{
        Denom:         denom,
        SubaccountId:  subaccountId,
        TransferTypes: transferTypes,
        Skip:          skip,
        Limit:         limit,
    }

    res, err := exchangeClient.GetSubaccountHistory(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the history fromYes
denomstringFilter history by denomYes
transfer_typesstring arrayFilter history by transfer typeYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes
end_timeint64Upper bound of account transfer history's executedAtYes

Response Parameters

Response Example:

{
   "transfers":[
      {
         "transferType":"deposit",
         "srcAccountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "dstSubaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "amount":{
            "denom":"inj",
            "amount":"2000000000000000000"
         },
         "executedAt":"1665117493543",
         "srcSubaccountId":"",
         "dstAccountAddress":""
      },
      {
         "transferType":"deposit",
         "srcAccountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "dstSubaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "amount":{
            "denom":"inj",
            "amount":"15000000000000000000"
         },
         "executedAt":"1660313668990",
         "srcSubaccountId":"",
         "dstAccountAddress":""
      }
   ],
   "paging":{
      "total":"3",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}

{
 "transfers": [
  {
   "transfer_type": "deposit",
   "src_account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "dst_subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "amount": {
    "denom": "inj",
    "amount": "50000000000000000000"
   },
   "executed_at": 1651492257605
  },
  {
   "transfer_type": "deposit",
   "src_account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "dst_subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "amount": {
    "denom": "inj",
    "amount": "1000000000000000000"
   },
   "executed_at": 1652453978939
  }
 ],
 "paging": [
  {
   "total": 3
  }
 ]
}
ParameterTypeDescription
transfersSubaccountBalanceTransfer arrayList of subaccount transfers
pagingPaging


SubaccountBalanceTransfer

ParameterTypeDescription
transfer_typestringType of the subaccount balance transfer
src_subaccount_idstringSubaccount ID of the sending side
src_account_addressstringAccount address of the sending side
dst_subaccount_idstringSubaccount ID of the receiving side
dst_account_addressstringAccount address of the receiving side
amountCosmosCoinCoin amount of the transfer
executed_atint64Timestamp of the transfer in UNIX millis


CosmosCoin

ParameterTypeDescription
denomstringCoin denominator
amountstringCoin amount (big int)


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

SubaccountBalance

Get the balance of a subaccount for a specific denom.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denom = "inj"
    balance = await client.fetch_subaccount_balance(subaccount_id=subaccount_id, denom=denom)
    print(json.dumps(balance, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("mainnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denom := "inj"
    res, err := exchangeClient.GetSubaccountBalance(ctx, subaccountId, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
denomstringSpecify denom to get balanceYes

Response Parameters

Response Example:

{
   "balance":{
      "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
      "accountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
      "denom":"inj",
      "deposit":{
         "totalBalance":"0",
         "availableBalance":"0"
      }
   }
}
{
 "balance": {
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "denom": "inj",
  "deposit": {
   "total_balance": "1492235700000000000000",
   "available_balance": "1492235700000000000000"
  }
 }
}
ParameterTypeDescription
balanceSubaccountBalanceSubaccount balance


SubaccountBalance

ParameterTypeDescription
subaccount_idstringRelated subaccount ID
account_addressstringAccount address, owner of this subaccount
denomstringCoin denom on the chain.
depositSubaccountDeposit


SubaccountDeposit

ParameterTypeDescription
total_balancestring
available_balancestring
total_balance_usdstring
available_balance_usdstring

SubaccountBalancesList

List the subaccount's balances for all denoms.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denoms = ["inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"]
    subacc_balances_list = await client.fetch_subaccount_balances_list(subaccount_id=subaccount, denoms=denoms)
    print(json.dumps(subacc_balances_list, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    res, err := exchangeClient.GetSubaccountBalancesList(ctx, subaccountId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
denomsstring arrayFilter balances by denoms. If not set, the balances of all the denoms for the subaccount are provided.Yes

Response Parameters

Response Example:

{
   "balances":[
      {
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "accountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "deposit":{
            "totalBalance":"131721505.337958346262317217",
            "availableBalance":"0.337958346262317217"
         }
      },
      {
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "accountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "denom":"inj",
         "deposit":{
            "totalBalance":"0",
            "availableBalance":"0"
         }
      }
   ]
}
{
 "balances": [
  {
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "deposit": {
    "total_balance": "200501904612800.13082016560359584",
    "available_balance": "200358014975479.130820165603595295"
   }
  },
  {
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "denom": "inj",
   "deposit": {
    "total_balance": "53790000010000000003",
    "available_balance": "52790000010000000003"
   }
  },
  {
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "denom": "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9",
   "deposit": {
    "total_balance": "1000000",
    "available_balance": "1000000"
   }
  }
 ]
}
ParameterTypeDescription
balancesSubaccountBalance arrayList of subaccount balances


SubaccountBalance

ParameterTypeDescription
subaccount_idstringRelated subaccount ID
account_addressstringAccount address, owner of this subaccount
denomstringCoin denom on the chain.
depositSubaccountDeposit


SubaccountDeposit

ParameterTypeDescription
total_balancestring
available_balancestring
total_balance_usdstring
available_balance_usdstring

SubaccountOrderSummary

Get a summary of the subaccount's active/unfilled orders.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    order_direction = "buy"
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subacc_order_summary = await client.fetch_subaccount_order_summary(
        subaccount_id=subaccount, order_direction=order_direction, market_id=market_id
    )
    print(json.dumps(subacc_order_summary, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    accountPB "github.com/InjectiveLabs/sdk-go/exchange/accounts_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    orderDirection := "buy"

    req := accountPB.SubaccountOrderSummaryRequest{
        MarketId:       marketId,
        SubaccountId:   subaccountId,
        OrderDirection: orderDirection,
    }

    res, err := exchangeClient.GetSubaccountOrderSummary(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("spot orders:", res.SpotOrdersTotal)
    fmt.Println("derivative orders:", res.DerivativeOrdersTotal)
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the summary fromYes
market_idstringMarketId is limiting order summary to specific market onlyYes
order_directionstringFilter by direction of the ordersYes

Response Parameters

Response Example:

{
   "derivativeOrdersTotal":"1",
   "spotOrdersTotal":"0"
}
spot orders: 1
derivative orders: 7
ParameterTypeDescription
spot_orders_totalint64Total count of subaccount's spot orders in given market and direction
derivative_orders_totalint64Total count of subaccount's derivative orders in given market and direction

StreamSubaccountBalance

Stream the subaccount's balance for all denoms.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def balance_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to balance updates ({exception})")


def stream_closed_processor():
    print("The balance updates stream has been closed")


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"
    denoms = ["inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"]
    task = asyncio.get_event_loop().create_task(
        client.listen_subaccount_balance_updates(
            subaccount_id=subaccount_id,
            callback=balance_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            denoms=denoms,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    subaccountId := "0x1b99514e320ae0087be7f87b1e3057853c43b799000000000000000000000000"
    stream, err := exchangeClient.StreamSubaccountBalance(ctx, subaccountId)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
denomsstring arrayFilter balances by denoms. If not set, the balances of all the denoms for the subaccount are provided.Yes

Response Parameters

Streaming Response Example:

{
  "balance": {
    "subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
    "accountAddress": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "deposit": {
      "totalBalance": "200493439765890.695319283887814576",
      "availableBalance": "200493414240390.695319283887814031"
    }
  },
  "timestamp": 1654234765000
}
{
  "balance": {
    "subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
    "accountAddress": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "deposit": {
      "totalBalance": "200493847328858.695319283887814576",
      "availableBalance": "200493821803358.695319283887814031"
    }
  },
  "timestamp": 1654234804000
}
{
 "balance": {
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "deposit": {
   "total_balance": "200503979400874.28368413692326264",
   "available_balance": "200360046875708.283684136923262095"
  }
 },
 "timestamp": 1653037703000
}{
 "balance": {
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "deposit": {
   "total_balance": "200503560511302.28368413692326264",
   "available_balance": "200359627986136.283684136923262095"
  }
 },
 "timestamp": 1653037744000
}
ParameterTypeDescription
balanceSubaccountBalanceSubaccount balance
timestampint64Operation timestamp in UNIX millis.


SubaccountBalance

ParameterTypeDescription
subaccount_idstringRelated subaccount ID
account_addressstringAccount address, owner of this subaccount
denomstringCoin denom on the chain.
depositSubaccountDeposit


SubaccountDeposit

ParameterTypeDescription
total_balancestring
available_balancestring
total_balance_usdstring
available_balance_usdstring

OrderStates

Get orders with an order hash. This request will return market orders and limit orders in all states [booked, partial_filled, filled, canceled]. For filled and canceled orders, there is a TTL of 3 minutes. Should your order be filled or canceled you will still be able to fetch it for 3 minutes.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    spot_order_hashes = [
        "0xce0d9b701f77cd6ddfda5dd3a4fe7b2d53ba83e5d6c054fb2e9e886200b7b7bb",
        "0x2e2245b5431638d76c6e0cc6268970418a1b1b7df60a8e94b8cf37eae6105542",
    ]
    derivative_order_hashes = [
        "0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50",
        "0xbb1f036001378cecb5fff1cc69303919985b5bf058c32f37d5aaf9b804c07a06",
    ]
    orders = await client.fetch_order_states(
        spot_order_hashes=spot_order_hashes, derivative_order_hashes=derivative_order_hashes
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    accountPB "github.com/InjectiveLabs/sdk-go/exchange/accounts_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    spotOrderHashes := []string{"0x0b156df549747187210ca5381f0291f179d76d613d0bae1a3c4fd2e3c0504b7c"}
    derivativeOrderHashes := []string{"0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50"}

    req := accountPB.OrderStatesRequest{
        SpotOrderHashes:       spotOrderHashes,
        DerivativeOrderHashes: derivativeOrderHashes,
    }

    res, err := exchangeClient.GetOrderStates(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
spot_order_hashesstring arrayYes
derivative_order_hashesstring arrayYes

Response Parameters

Response Example:

{
  "spotOrderStates": [
    {
      "orderHash": "0xb7b556d6eab10c4c185a660be44757a8a6715fb16db39708f2f76d9ce5ae8617",
      "subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
      "marketId": "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa",
      "orderType": "limit",
      "orderSide": "buy",
      "state": "booked",
      "quantityFilled": "0",
      "quantityRemaining": "1000000",
      "createdAt": 1654080262300,
      "updatedAt": 1654080262300
    }
  ],
  "derivativeOrderStates": [
    {
      "orderHash": "0x4228f9a56a5bb50de4ceadc64df694c77e7752d58b71a7c557a27ec10e1a094e",
      "subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
      "marketId": "0x1c79dac019f73e4060494ab1b4fcba734350656d6fc4d474f6a238c13c6f9ced",
      "orderType": "limit",
      "orderSide": "buy",
      "state": "booked",
      "quantityFilled": "0",
      "quantityRemaining": "1",
      "createdAt": 1654235059957,
      "updatedAt": 1654235059957
    }
  ]
}
{
 "spot_order_states": [
  {
   "order_hash": "0xb7b556d6eab10c4c185a660be44757a8a6715fb16db39708f2f76d9ce5ae8617",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa",
   "order_type": "limit",
   "order_side": "buy",
   "state": "booked",
   "quantity_filled": "0",
   "quantity_remaining": "1000000",
   "created_at": 1654080262300,
   "updated_at": 1654080262300
  }
 ],
 "derivative_order_states": [
  {
   "order_hash": "0x4228f9a56a5bb50de4ceadc64df694c77e7752d58b71a7c557a27ec10e1a094e",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0x1c79dac019f73e4060494ab1b4fcba734350656d6fc4d474f6a238c13c6f9ced",
   "order_type": "limit",
   "order_side": "buy",
   "state": "booked",
   "quantity_filled": "0",
   "quantity_remaining": "1",
   "created_at": 1654235059957,
   "updated_at": 1654235059957
  }
 ]
}
ParameterTypeDescription
spot_order_statesOrderStateRecord arrayList of the spot order state records
derivative_order_statesOrderStateRecord arrayList of the derivative order state records


OrderStateRecord

ParameterTypeDescription
order_hashstringHash of the order
subaccount_idstringThe subaccountId that this order belongs to
market_idstringThe Market ID of the order
order_typestringThe type of the order
order_sidestringThe side of the order
statestringThe state (status) of the order
quantity_filledstringThe filled quantity of the order
quantity_remainingstringThe filled quantity of the order
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
pricestringOrder prices
marginstringMargin for derivative order

Portfolio

Get an overview of your portfolio.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    portfolio = await client.fetch_portfolio(account_address=account_address)
    print(json.dumps(portfolio, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    accountAddress := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    res, err := exchangeClient.GetPortfolio(ctx, accountAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
account_addressstringAccount addressYes

Response Parameters

Response Example:

{
   "portfolio":{
      "portfolioValue":"6229.040631548905238875",
      "availableBalance":"92.4500010811984646",
      "lockedBalance":"13218.3573583009093604",
      "unrealizedPnl":"-7081.766727833202586125",
      "subaccounts":[
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000002",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000006",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000008",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000009",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f971347490200000061746f6d2d75736474",
            "availableBalance":"0.00000066622556",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "availableBalance":"0.0000003382963046",
            "lockedBalance":"13218.3573583009093604",
            "unrealizedPnl":"-7081.766727833202586125"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f971347490200000000696e6a2d75736474",
            "availableBalance":"0.0000000766766",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000001",
            "availableBalance":"92.45",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000003",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000007",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000004",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         },
         {
            "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000005",
            "availableBalance":"0",
            "lockedBalance":"0",
            "unrealizedPnl":"0"
         }
      ]
   }
}
{
 "portfolio": {
  "portfolio_value": "16961.63886335580191347385",
  "available_balance": "10127.8309908372442029",
  "locked_balance": "8192.6038127728038576",
  "unrealized_pnl": "-1358.79594025424614702615",
  "subaccounts": [
   {
    "subaccount_id": "0x792bb0b9001d71a8efcb3c026ba4e34608a68a8c000000000000000000000000",
    "available_balance": "10127.8309908372442029",
    "locked_balance": "8192.6038127728038576",
    "unrealized_pnl": "-1358.79594025424614702615"
   }
  ]
 }
}
ParameterTypeDescription
portfolioAccountPortfolioThe portfolio of this account


AccountPortfolio

ParameterTypeDescription
portfolio_valuestringThe account's portfolio value in USD.
available_balancestringThe account's available balance value in USD.
locked_balancestringThe account's locked balance value in USD.
unrealized_pnlstringThe account's total unrealized PnL value in USD.
subaccountsSubaccountPortfolio arrayList of all subaccounts' portfolio


SubaccountPortfolio

ParameterTypeDescription
subaccount_idstringThe ID of this subaccount
available_balancestringThe subaccount's available balance value in USD.
locked_balancestringThe subaccount's locked balance value in USD.
unrealized_pnlstringThe subaccount's total unrealized PnL value in USD.

Rewards

Get the rewards for Trade & Earn, the request will fetch all addresses for the latest epoch (-1) by default.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    epoch = -1
    rewards = await client.fetch_rewards(account_address=account_address, epoch=epoch)
    print(json.dumps(rewards, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    accountPB "github.com/InjectiveLabs/sdk-go/exchange/accounts_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    accountAddress := "inj1rwv4zn3jptsqs7l8lpa3uvzhs57y8duemete9e"
    epoch := int64(1)

    req := accountPB.RewardsRequest{
        Epoch:          epoch,
        AccountAddress: accountAddress,
    }

    res, err := exchangeClient.GetRewards(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
epochint64The distribution epoch sequence number. -1 for latest.Yes
account_addressstringAccount address for the rewards distributionYes

Response Parameters

Response Example:

{
   "rewards":[
      {
         "accountAddress":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "rewards":[
            {
               "denom":"inj",
               "amount":"11169382212463849"
            }
         ],
         "distributedAt":"1672218001897"
      }
   ]
}
{
 "rewards": [
  {
   "account_address": "inj1rwv4zn3jptsqs7l8lpa3uvzhs57y8duemete9e",
   "rewards": [
    {
     "denom": "inj",
     "amount": "755104058929571177652"
    }
   ],
   "distributed_at": 1642582800716
  }
 ]
}
ParameterTypeDescription
rewardsReward arrayThe trading rewards distributed


Reward

ParameterTypeDescription
account_addressstringAccount address
rewardsCoin arrayReward coins distributed
distributed_atint64Rewards distribution timestamp in UNIX millis.


Coin

ParameterTypeDescription
denomstringDenom of the coin
amountstring
usd_valuestring

- InjectiveSpotExchangeRPC

InjectiveSpotExchangeRPC defines the gRPC API of the Spot Exchange provider.

Market

Get details of a single spot market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    market = await client.fetch_spot_market(market_id=market_id)
    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    res, err := exchangeClient.GetSpotMarket(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market we want to fetchYes

Response Parameters

Response Example:

{
   "market":{
      "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
      "marketStatus":"active",
      "ticker":"INJ/USDT",
      "baseDenom":"inj",
      "baseTokenMeta":{
         "name":"Injective Protocol",
         "address":"0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
         "symbol":"INJ",
         "logo":"https://static.alchemyapi.io/images/assets/7226.png",
         "decimals":18,
         "updatedAt":"1683119359318"
      },
      "quoteDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
      "quoteTokenMeta":{
         "name":"Testnet Tether USDT",
         "address":"0x0000000000000000000000000000000000000000",
         "symbol":"USDT",
         "logo":"https://static.alchemyapi.io/images/assets/825.png",
         "decimals":6,
         "updatedAt":"1683119359320"
      },
      "makerFeeRate":"-0.0001",
      "takerFeeRate":"0.001",
      "serviceProviderFee":"0.4",
      "minPriceTickSize":"0.000000000000001",
      "minQuantityTickSize":"1000000000000000",
      "minNotional": "1000000"
   }
}
{
 "market": {
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "market_status": "active",
  "ticker": "INJ/USDT",
  "base_denom": "inj",
  "base_token_meta": {
   "name": "Injective Protocol",
   "address": "0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
   "symbol": "INJ",
   "logo": "https://static.alchemyapi.io/images/assets/7226.png",
   "decimals": 18,
   "updated_at": 1650978921934
  },
  "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "maker_fee_rate": "0.001",
  "taker_fee_rate": "0.002",
  "service_provider_fee": "0.4",
  "min_price_tick_size": "0.000000000000001",
  "min_quantity_tick_size": "1000000000000000",
  "min_notional": "1000000"
 }
}
ParameterTypeDescription
marketSpotMarketInfoInfo about particular spot market


SpotMarketInfo

ParameterTypeDescription
market_idstringSpotMarket ID is keccak265(baseDenom || quoteDenom)
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset.
base_token_metaTokenMetaToken metadata for base asset
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
min_notionalstringMinimum notional value for the market


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

Markets

Get a list of spot markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_status = "active"
    base_denom = "inj"
    quote_denom = "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    market = await client.fetch_spot_markets(
        market_statuses=[market_status], base_denom=base_denom, quote_denom=quote_denom
    )
    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketStatus := "active"
    quoteDenom := "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7"

    req := spotExchangePB.MarketsRequest{
        MarketStatus: marketStatus,
        QuoteDenom:   quoteDenom,
    }

    res, err := exchangeClient.GetSpotMarkets(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_statusstringFilter by market statusYes
base_denomstringFilter by the Coin denomination of the base currencyYes
quote_denomstringFilter by the Coin denomination of the quote currencyYes
market_statusesstring arrayYes

Response Parameters

Response Example:

{
   "markets":[
      {
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "marketStatus":"active",
         "ticker":"INJ/USDT",
         "baseDenom":"inj",
         "baseTokenMeta":{
            "name":"Injective Protocol",
            "address":"0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
            "symbol":"INJ",
            "logo":"https://static.alchemyapi.io/images/assets/7226.png",
            "decimals":18,
            "updatedAt":"1683119359318"
         },
         "quoteDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "quoteTokenMeta":{
            "name":"Testnet Tether USDT",
            "address":"0x0000000000000000000000000000000000000000",
            "symbol":"USDT",
            "logo":"https://static.alchemyapi.io/images/assets/825.png",
            "decimals":6,
            "updatedAt":"1683119359320"
         },
         "makerFeeRate":"-0.0001",
         "takerFeeRate":"0.001",
         "serviceProviderFee":"0.4",
         "minPriceTickSize":"0.000000000000001",
         "minQuantityTickSize":"1000000000000000",
         "minNotional":"1000000"
      }
   ]
}
{
 "markets": [
  {
   "market_id": "0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b",
   "market_status": "active",
   "ticker": "AAVE/USDT",
   "base_denom": "peggy0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
   "base_token_meta": {
    "name": "Aave",
    "address": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
    "symbol": "AAVE",
    "logo": "https://static.alchemyapi.io/images/assets/7278.png",
    "decimals": 18,
    "updated_at": 1650978921846
   },
   "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "maker_fee_rate": "0.001",
   "taker_fee_rate": "0.002",
   "service_provider_fee": "0.4",
   "min_price_tick_size": "0.000000000000001",
   "min_quantity_tick_size": "1000000000000000"
  },
  {
   "market_id": "0xe8bf0467208c24209c1cf0fd64833fa43eb6e8035869f9d043dbff815ab76d01",
   "market_status": "active",
   "ticker": "UNI/USDT",
   "base_denom": "peggy0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
   "base_token_meta": {
    "name": "Uniswap",
    "address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
    "symbol": "UNI",
    "logo": "https://static.alchemyapi.io/images/assets/7083.png",
    "decimals": 18,
    "updated_at": 1650978922133
   },
   "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "maker_fee_rate": "0.001",
   "taker_fee_rate": "0.002",
   "service_provider_fee": "0.4",
   "min_price_tick_size": "0.000000000000001",
   "min_quantity_tick_size": "1000000000000000",
   "min_notional": "1000000"
  }
 ]
}
ParameterTypeDescription
marketsSpotMarketInfo arraySpot Markets list


SpotMarketInfo

ParameterTypeDescription
market_idstringSpotMarket ID is keccak265(baseDenom || quoteDenom)
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset.
base_token_metaTokenMetaToken metadata for base asset
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
min_notionalstringMinimum notional value for the market


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

StreamMarkets

Stream live updates of spot markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def market_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to spot markets updates ({exception})")


def stream_closed_processor():
    print("The spot markets updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.mainnet()
    client = IndexerClient(network)

    task = asyncio.get_event_loop().create_task(
        client.listen_spot_markets_updates(
            callback=market_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}
    stream, err := exchangeClient.StreamSpotMarket(ctx, marketIds)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for updates streaming, empty means 'ALL' spot marketsYes

Response Parameters

Streaming Response Example:

{
   "market":{
      "marketId":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
      "marketStatus":"active",
      "ticker":"INJ/USDT",
      "baseDenom":"inj",
      "baseTokenMeta":{
         "name":"Injective Protocol",
         "address":"0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
         "symbol":"INJ",
         "logo":"https://static.alchemyapi.io/images/assets/7226.png",
         "decimals":18,
         "updatedAt":1632535055751
      },
      "quoteDenom":"peggy0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
      "quoteTokenMeta":{
         "name":"Tether",
         "address":"0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
         "symbol":"USDT",
         "logo":"https://static.alchemyapi.io/images/assets/825.png",
         "decimals":6,
         "updatedAt":1632535055759
      },
      "makerFeeRate":"0.001",
      "takerFeeRate":"0.002",
      "serviceProviderRate":"0.4",
      "minPriceTickSize":"0.000000000000001",
      "minQuantityTickSize":"1000000000000000",
      "minNotional":"0"
   },
   "operationType":"update",
   "timestamp":1632535055790
}
{
  "market": {
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "market_status": "active",
  "ticker": "INJ/USDT",
  "base_denom": "inj",
  "base_token_meta": {
    "name": "Injective Protocol",
    "address": "0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
    "symbol": "INJ",
    "logo": "https://static.alchemyapi.io/images/assets/7226.png",
    "decimals": 18,
    "updated_at": 1632535055751
  },
  "quote_denom": "peggy0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
  "quote_token_meta": {
    "name": "Tether",
    "address": "0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
    "symbol": "USDT",
    "logo": "https://static.alchemyapi.io/images/assets/825.png",
    "decimals": 6,
    "updated_at": 1632535055759
  },
  "maker_fee_rate": "0.001",
  "taker_fee_rate": "0.002",
  "service_provider_fee": "0.4",
  "min_price_tick_size": "0.000000000000001",
  "min_quantity_tick_size": "1000000000000000",
  "min_notional": "0",
},
  "operation_type": "update",
  "timestamp": 1632535055790
}
ParameterTypeDescription
marketSpotMarketInfoInfo about particular spot market
operation_typestringUpdate type
timestampint64Operation timestamp in UNIX millis.


SpotMarketInfo

ParameterTypeDescription
market_idstringSpotMarket ID is keccak265(baseDenom || quoteDenom)
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset.
base_token_metaTokenMetaToken metadata for base asset
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
min_notionalstringMinimum notional value for the market


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

OrdersHistory

List history of orders (all states) for a spot market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"]
    subaccount_id = "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000"
    skip = 10
    limit = 3
    order_types = ["buy_po"]
    pagination = PaginationOption(skip=skip, limit=limit)
    orders = await client.fetch_spot_orders_history(
        subaccount_id=subaccount_id,
        market_ids=market_ids,
        order_types=order_types,
        pagination=pagination,
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)
    orderTypes := []string{"buy_po"}

    req := spotExchangePB.OrdersHistoryRequest{
        SubaccountId: subaccountId,
        MarketId:     marketId,
        Skip:         skip,
        Limit:        limit,
        OrderTypes:   orderTypes,
    }

    res, err := exchangeClient.GetHistoricalSpotOrders(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes
order_typesstring arrayfilter by order typesYes
directionstringorder side filterYes
start_timeint64Search for orders which createdAt >= startTime, time in millisecondYes
end_timeint64Search for orders which createdAt <= endTime, time in millisecondYes
statestringFilter by order stateYes
execution_typesstring arrayYes
market_idsstring arrayYes
trade_idstringTradeId of the order we want to fetchYes
active_markets_onlyboolReturn only orders for active marketsYes
cidstringClient order IDYes

Response Parameters

Response Example:

{
   "orders":[
      {
         "orderHash":"0x4e6629ce45597a3dc3941c5382cc7bc542d52fbcc6b03c4fd604c94a9bec0cc1",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"0.000000000000001",
         "triggerPrice":"0",
         "quantity":"1000000000000000",
         "filledQuantity":"1000000000000000",
         "state":"filled",
         "createdAt":"1668264339149",
         "updatedAt":"1682667017745",
         "direction":"buy",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "cid":""
      },
      {
         "orderHash":"0x347de654c8484fe36473c3569382ff27d25e95c660fd055163b7193607867a8b",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"0.000000000000001",
         "triggerPrice":"0",
         "quantity":"1000000000000000",
         "filledQuantity":"1000000000000000",
         "state":"filled",
         "createdAt":"1668264339149",
         "updatedAt":"1682667017745",
         "direction":"buy",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "cid":""
      },
      {
         "orderHash":"0x2141d52714f5c9328170cc674de8ecf876463b1999bea4124d1de595152b718f",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"0.000000000000001",
         "triggerPrice":"0",
         "quantity":"1000000000000000",
         "filledQuantity":"1000000000000000",
         "state":"filled",
         "createdAt":"1668264339149",
         "updatedAt":"1682667017745",
         "direction":"buy",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "cid":""
      }
   ],
   "paging":{
      "total":"1000",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "orders": [
  {
   "order_hash": "0x47a3858df766691a6124255a959ac17c79588fa36e52bed6d8aea2d927bb6a60",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000007789",
   "trigger_price": "0",
   "quantity": "12000000000000000000",
   "filled_quantity": "12000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x4a0f7bec21c2861ec390510f461ab94a6e4425453e113ba41d67c5e79a45538b",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000007692",
   "trigger_price": "0",
   "quantity": "14000000000000000000",
   "filled_quantity": "14000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x447b593a3c1683b64bd6ac4e60aa6ff22078951312eb3bfacf0b8b163eb015e4",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000005787",
   "trigger_price": "0",
   "quantity": "18000000000000000000",
   "filled_quantity": "18000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x77d1c86d0b04b3347ace0f4a7f708adbb160d54701891d0c212a8c28bb10f77f",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000005457",
   "trigger_price": "0",
   "quantity": "8000000000000000000",
   "filled_quantity": "8000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x76899c13fa3e591b1e2cbadfc2c84db5a7f4f97e42cee2451a6a90d04b100642",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000007134",
   "trigger_price": "0",
   "quantity": "4000000000000000000",
   "filled_quantity": "4000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0xf353711353a98ac3aceee62a4d7fed30e0c65cf38adfa898c455be5e5c671445",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000006138",
   "trigger_price": "0",
   "quantity": "2000000000000000000",
   "filled_quantity": "2000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0xb599db2124630b350e0ca2ea3453ece84e7721334e1009b451fa21d072a6cf8f",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000005667",
   "trigger_price": "0",
   "quantity": "22000000000000000000",
   "filled_quantity": "22000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x1c28300cfebfef73c26e32d396162e45089e34a5ba0c627cc8b6e3fb1d9861ad",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000006263",
   "trigger_price": "0",
   "quantity": "20000000000000000000",
   "filled_quantity": "20000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x7a2b9753c94c67f5e79e2f9dcd8af8a619d55d2f9ba1a134a22c5ef154b76e7f",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000007683",
   "trigger_price": "0",
   "quantity": "16000000000000000000",
   "filled_quantity": "16000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  },
  {
   "order_hash": "0x4984a08abefd29ba6bc914b11182251e18c0235842916955a4ffdc8ff149d188",
   "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy_po",
   "price": "0.000000000007668",
   "trigger_price": "0",
   "quantity": "6000000000000000000",
   "filled_quantity": "6000000000000000000",
   "state": "filled",
   "created_at": 1681812187591,
   "updated_at": 1681886620984,
   "direction": "buy"
  }
 ],
 "paging": {
  "total": 1000
 }
}

ParameterTypeDescription
ordersSpotOrderHistory arrayList of history spot orders
pagingPaging


SpotOrderHistory

ParameterTypeDescription
order_hashstringHash of the order
market_idstringSpot Market ID is keccak265(baseDenom + quoteDenom)
is_activeboolactive state of the order
subaccount_idstringThe subaccountId that this order belongs to
execution_typestringThe execution type
order_typestringThe side of the order
pricestringPrice of the order
trigger_pricestringTrigger price
quantitystringQuantity of the order
filled_quantitystringFilled amount
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
directionstringOrder direction (order side)
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamOrdersHistory

Stream order updates for spot markets. If no parameters are given, updates to all subaccounts in all spot markets will be streamed.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def order_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to spot orders history updates ({exception})")


def stream_closed_processor():
    print("The spot orders history updates stream has been closed")


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    order_direction = "buy"

    task = asyncio.get_event_loop().create_task(
        client.listen_spot_orders_history_updates(
            callback=order_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            market_id=market_id,
            direction=order_direction,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    direction := "buy"

    req := spotExchangePB.StreamOrdersHistoryRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Direction:    direction,
    }
    stream, err := exchangeClient.StreamHistoricalSpotOrders(ctx, &req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
order_typesstring arrayfilter by order typesYes
directionstringorder side filterYes
statestringFilter by order stateYes
execution_typesstring arrayYes

Response Parameters

Streaming Response Example:

{
   "order":{
      "orderHash":"0xff6a1ce6339911bb6f0765e17e70144ae62834e65e551e910018203d62bc6d12",
      "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
      "subaccountId":"0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000004",
      "executionType":"limit",
      "orderType":"buy_po",
      "price":"0.000000000019028",
      "triggerPrice":"0",
      "quantity":"67129093000000000000000",
      "filledQuantity":"0",
      "state":"canceled",
      "createdAt":"1702044186286",
      "updatedAt":"1702044188683",
      "direction":"buy",
      "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
      "isActive":false,
      "cid":""
   },
   "operationType":"update",
   "timestamp":"1702044191000"
}
{
 "order": {
  "order_hash": "0xf8a90ee4cfb4c938035b791d3b3561e8991803793b4b5590164b2ecbfa247f3d",
  "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
  "subaccount_id": "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000004",
  "execution_type": "limit",
  "order_type": "buy_po",
  "price": "0.000000000007438",
  "trigger_price": "0",
  "quantity": "76848283000000000000000",
  "filled_quantity": "0",
  "state": "canceled",
  "created_at": 1696621893030,
  "updated_at": 1696621895445,
  "direction": "buy"
 },
 "operation_type": "update",
 "timestamp": 1696621898000
}{
 "order": {
  "order_hash": "0xfd6bf489944cb181ee94057b80ffdfc113a17d48d0455c8d10e4deadf341bdfd",
  "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
  "subaccount_id": "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000004",
  "execution_type": "limit",
  "order_type": "buy_po",
  "price": "0.000000000007478",
  "trigger_price": "0",
  "quantity": "76437220000000000000000",
  "filled_quantity": "0",
  "state": "canceled",
  "created_at": 1696621893030,
  "updated_at": 1696621895445,
  "direction": "buy"
 },
 "operation_type": "update",
 "timestamp": 1696621898000
}
ParameterTypeDescription
orderSpotOrderHistoryUpdated order
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.


SpotOrderHistory

ParameterTypeDescription
order_hashstringHash of the order
market_idstringSpot Market ID is keccak265(baseDenom + quoteDenom)
is_activeboolactive state of the order
subaccount_idstringThe subaccountId that this order belongs to
execution_typestringThe execution type
order_typestringThe side of the order
pricestringPrice of the order
trigger_pricestringTrigger price
quantitystringQuantity of the order
filled_quantitystringFilled amount
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
directionstringOrder direction (order side)
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID

TradesV2

Get trade history for a spot market. The default request returns all spot trades from all markets.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"]
    execution_side = "taker"
    direction = "buy"
    subaccount_ids = ["0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"]
    execution_types = ["limitMatchNewOrder", "market"]
    orders = await client.fetch_spot_trades(
        market_ids=market_ids,
        subaccount_ids=subaccount_ids,
        execution_side=execution_side,
        direction=direction,
        execution_types=execution_types,
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"

    req := spotExchangePB.TradesV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }

    res, err := exchangeClient.GetSpotTradesV2(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market's orderbook we want to fetchYes
execution_sidestringFilter by execution side of the tradeYes
directionstringFilter by direction the tradeYes
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
skipuint64Skip will skip the first n item from the item resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
start_timeint64The starting timestamp in UNIX milliseconds that the trades must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the trades must be equal or younger thanYes
market_idsstring arrayMarketIds of the markets of which we want to get tradesYes
subaccount_idsstring arraySubaccount ids of traders we want to get tradesYes
execution_typesstring arrayYes
trade_idstringFilter by the tradeId of the tradeYes
account_addressstringAccount addressYes
cidstringClient order IDYes
fee_recipientstringFee recipient addressYes

Response Parameters

Response Example:

{
   "trades":[
      {
         "orderHash":"0x952bb14a7a377697d724c60d6077ef3dfe894c98f854970fab187247be832b6f",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b",
         "tradeExecutionType":"limitMatchRestingOrder",
         "tradeDirection":"buy",
         "price":{
            "price":"0.00000000001",
            "quantity":"1000000000000000000",
            "timestamp":"1701961116630"
         },
         "fee":"-600",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_0",
         "executionSide":"maker",
         "cid":"96866b8b-02dd-4288-97d3-e5254e4888b3"
      },
      {
         "orderHash":"0x85a824c31f59cf68235b48666c4821334813f2b80db937f02d192f1e3fc74368",
         "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
         "marketId":"0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b",
         "tradeExecutionType":"limitMatchNewOrder",
         "tradeDirection":"sell",
         "price":{
            "price":"0.00000000001",
            "quantity":"1000000000000000000",
            "timestamp":"1701961116630"
         },
         "fee":"10000",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_1",
         "executionSide":"taker",
         "cid":"spot_AAVE/USDT"
      },
      {
         "orderHash":"0xffabb2d12a745d79eb12c7ef0eb59c729aaa4387a141f858153c8b8f58168b2e",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
         "tradeExecutionType":"limitMatchRestingOrder",
         "tradeDirection":"buy",
         "price":{
            "price":"0.00000000001",
            "quantity":"2000000000000000000",
            "timestamp":"1701960607140"
         },
         "fee":"-2400",
         "executedAt":"1701960607140",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"646_0",
         "executionSide":"maker",
         "cid":"ec581735-f801-4bf3-9101-282b301bf5cd"
      },
      {
         "orderHash":"0xa19e24eef9877ec4980b8d259c1d21fa1dafcd50691e6f853e84af74fb23c05c",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
         "tradeExecutionType":"limitMatchNewOrder",
         "tradeDirection":"sell",
         "price":{
            "price":"0.00000000001",
            "quantity":"2000000000000000000",
            "timestamp":"1701960607140"
         },
         "fee":"40000",
         "executedAt":"1701960607140",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "tradeId":"646_1",
         "executionSide":"taker",
         "cid":""
      },
      {
         "orderHash":"0xffabb2d12a745d79eb12c7ef0eb59c729aaa4387a141f858153c8b8f58168b2e",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
         "tradeExecutionType":"limitMatchRestingOrder",
         "tradeDirection":"buy",
         "price":{
            "price":"0.00000000001",
            "quantity":"8000000000000000000",
            "timestamp":"1701960594997"
         },
         "fee":"-9600",
         "executedAt":"1701960594997",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"630_0",
         "executionSide":"maker",
         "cid":"ec581735-f801-4bf3-9101-282b301bf5cd"
      },
      {
         "orderHash":"0x87b786072190a2f38e9057987be7bdcb4e2274a6c16fdb9670e5c2ded765140f",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
         "tradeExecutionType":"limitMatchNewOrder",
         "tradeDirection":"sell",
         "price":{
            "price":"0.00000000001",
            "quantity":"8000000000000000000",
            "timestamp":"1701960594997"
         },
         "fee":"160000",
         "executedAt":"1701960594997",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "tradeId":"630_1",
         "executionSide":"taker",
         "cid":""
      }
   ],
   "paging":{
      "total":"6",
      "from":1,
      "to":6,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}

{
 "trades": [
  {
   "order_hash": "0xffabb2d12a745d79eb12c7ef0eb59c729aaa4387a141f858153c8b8f58168b2e",
   "subaccount_id": "0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitMatchRestingOrder",
   "trade_direction": "buy",
   "price": {
    "price": "0.00000000001",
    "quantity": "2000000000000000000",
    "timestamp": 1701960607140
   },
   "fee": "-2400",
   "executed_at": 1701960607140,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "646_0",
   "execution_side": "maker",
   "cid": "ec581735-f801-4bf3-9101-282b301bf5cd"
  },
  {
   "order_hash": "0xa19e24eef9877ec4980b8d259c1d21fa1dafcd50691e6f853e84af74fb23c05c",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitMatchNewOrder",
   "trade_direction": "sell",
   "price": {
    "price": "0.00000000001",
    "quantity": "2000000000000000000",
    "timestamp": 1701960607140
   },
   "fee": "40000",
   "executed_at": 1701960607140,
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
   "trade_id": "646_1",
   "execution_side": "taker"
  },
  {
   "order_hash": "0xffabb2d12a745d79eb12c7ef0eb59c729aaa4387a141f858153c8b8f58168b2e",
   "subaccount_id": "0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitMatchRestingOrder",
   "trade_direction": "buy",
   "price": {
    "price": "0.00000000001",
    "quantity": "8000000000000000000",
    "timestamp": 1701960594997
   },
   "fee": "-9600",
   "executed_at": 1701960594997,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "630_0",
   "execution_side": "maker",
   "cid": "ec581735-f801-4bf3-9101-282b301bf5cd"
  },
  {
   "order_hash": "0x87b786072190a2f38e9057987be7bdcb4e2274a6c16fdb9670e5c2ded765140f",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitMatchNewOrder",
   "trade_direction": "sell",
   "price": {
    "price": "0.00000000001",
    "quantity": "8000000000000000000",
    "timestamp": 1701960594997
   },
   "fee": "160000",
   "executed_at": 1701960594997,
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
   "trade_id": "630_1",
   "execution_side": "taker"
  }
 ],
 "paging": {
  "total": 4,
  "from": 1,
  "to": 4
 }
}

ParameterTypeDescription
tradesSpotTrade arrayTrades of a Spot Market
pagingPagingPaging indicates pages response is on


SpotTrade

ParameterTypeDescription
order_hashstringMaker order hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
trade_directionstringThe direction the trade
pricePriceLevelPrice level at which trade has been executed
feestringThe fee associated with the trade (quote asset denom)
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamTradesV2

Stream newly executed trades of spot markets. The default request streams trades from all spot markets.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def trade_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to spot trades updates ({exception})")


def stream_closed_processor():
    print("The spot trades updates stream has been closed")


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = [
        "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0",
    ]
    execution_side = "maker"
    direction = "sell"
    subaccount_id = "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"
    execution_types = ["limitMatchRestingOrder"]

    task = asyncio.get_event_loop().create_task(
        client.listen_spot_trades_updates(
            callback=trade_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            market_ids=market_ids,
            subaccount_ids=[subaccount_id],
            execution_side=execution_side,
            direction=direction,
            execution_types=execution_types,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"

    req := spotExchangePB.StreamTradesV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }
    stream, err := exchangeClient.StreamSpotTradesV2(ctx, &req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market's orderbook we want to fetchYes
execution_sidestringFilter by execution side of the tradeYes
directionstringFilter by direction the tradeYes
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
skipuint64Skip will skip the first n item from the item resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
start_timeint64The starting timestamp in UNIX milliseconds that the trades must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the trades must be equal or younger thanYes
market_idsstring arrayMarketIds of the markets of which we want to get tradesYes
subaccount_idsstring arraySubaccount ids of traders we want to get tradesYes
execution_typesstring arrayYes
trade_idstringFilter by the tradeId of the tradeYes
account_addressstringAccount addressYes
cidstringClient order IDYes
fee_recipientstringFee recipient addressYes

Response Parameters

Streaming Response Example:

{
   "trade":{
      "orderHash":"0xa7f4a7d85136d97108d271caadd93bf697ff965790e0e1558617b953cced4adc",
      "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
      "marketId":"0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b",
      "tradeExecutionType":"limitMatchNewOrder",
      "tradeDirection":"sell",
      "price":{
         "price":"0.00000000001",
         "quantity":"1000000000000000000",
         "timestamp":"1701978102242"
      },
      "fee":"10000",
      "executedAt":"1701978102242",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"22868_1",
      "executionSide":"taker",
      "cid":"96866b8b-02dd-4288-97d3-e5254e4999d4"
   },
   "operationType":"insert",
   "timestamp":"1701978103000"
}
{
   "trade":{
      "orderHash":"0x952bb14a7a377697d724c60d6077ef3dfe894c98f854970fab187247be832b6f",
      "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
      "marketId":"0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b",
      "tradeExecutionType":"limitMatchRestingOrder",
      "tradeDirection":"buy",
      "price":{
         "price":"0.00000000001",
         "quantity":"1000000000000000000",
         "timestamp":"1701978102242"
      },
      "fee":"-600",
      "executedAt":"1701978102242",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"22868_0",
      "executionSide":"maker",
      "cid":"96866b8b-02dd-4288-97d3-e5254e4888b3"
   },
   "operationType":"insert",
   "timestamp":"1701978103000"
}
{
 "trade": {
  "order_hash": "0x88e34872af0147f57c8c5a093c3a6a8a97358615bccf975b4a06dfb5162daeaf",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "market",
  "trade_direction": "sell",
  "price": {
   "price": "0.000000000001654",
   "quantity": "1000000000000000000",
   "timestamp": 1653042087046
  },
  "fee": "3308",
  "executed_at": 1653042087046,
  "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8"
 },
 "operation_type": "insert",
 "timestamp": 1653042089000
}{
 "trade": {
  "order_hash": "0xb5d651a01faa90ec53b0fa34f00f3ecdfe169f9fc35be8114ee113eea9257c30",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "market",
  "trade_direction": "sell",
  "price": {
   "price": "0.000000000001654",
   "quantity": "2000000000000000000",
   "timestamp": 1653042093023
  },
  "fee": "6616",
  "executed_at": 1653042093023,
  "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8"
 },
 "operation_type": "insert",
 "timestamp": 1653042098000
}
ParameterTypeDescription
tradeSpotTradeNew spot market trade
operation_typestringExecuted trades update type
timestampint64Operation timestamp in UNIX millis.


SpotTrade

ParameterTypeDescription
order_hashstringMaker order hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
trade_directionstringThe direction the trade
pricePriceLevelPrice level at which trade has been executed
feestringThe fee associated with the trade (quote asset denom)
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.

OrderbooksV2

Get an orderbook snapshot for one or more spot markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = [
        "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0",
    ]
    depth = 1
    orderbooks = await client.fetch_spot_orderbooks_v2(market_ids=market_ids, depth=depth)
    print(json.dumps(orderbooks, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}
    depth := int32(10)
    res, err := exchangeClient.GetSpotOrderbooksV2(ctx, marketIds, depth)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idsstring arrayMarketIds of the marketsYes
depthint32Depth of the orderbookYes

Response Parameters

Response Example:

{
   "orderbooks":[
      {
         "marketId":"0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0",
         "orderbook":{
            "sells":[
               {
                  "price":"0.000000000005",
                  "quantity":"27767884000000000000000",
                  "timestamp":"1694702425539"
               },
               {
                  "price":"0.0000000000045",
                  "quantity":"3519999000000000000000000",
                  "timestamp":"1694424758707"
               }
            ],
            "timestamp":"-62135596800000",
            "buys":[

            ],
            "sequence":"0"
         }
      },
      {
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "orderbook":{
            "buys":[
               {
                  "price":"0.000000000073489",
                  "quantity":"129000000000000000",
                  "timestamp":"1702042963690"
               },
               {
                  "price":"0.000000000064261",
                  "quantity":"1292000000000000000",
                  "timestamp":"1702039612697"
               }
            ],
            "sells":[
               {
                  "price":"0.000000000085",
                  "quantity":"6693248000000000000000",
                  "timestamp":"1702044317059"
               },
               {
                  "price":"0.000000000085768",
                  "quantity":"581000000000000000",
                  "timestamp":"1701944786578"
               }
            ],
            "sequence":"6916386",
            "timestamp":"1702044336800"
         }
      }
   ]
}

ParameterTypeDescription
orderbooksSingleSpotLimitOrderbookV2 array


SingleSpotLimitOrderbookV2

ParameterTypeDescription
market_idstringmarket's ID
orderbookSpotLimitOrderbookV2Orderbook of the market


SpotLimitOrderbookV2

ParameterTypeDescription
buysPriceLevel arrayArray of price levels for buys
sellsPriceLevel arrayArray of price levels for sells
sequenceuint64market orderbook sequence
timestampint64Last update timestamp in UNIX millis.
heightint64Block height at which the orderbook was last updated.


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.

StreamOrderbookV2

Stream orderbook snapshot updates for one or more spot markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def orderbook_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to spot orderbook snapshots ({exception})")


def stream_closed_processor():
    print("The spot orderbook snapshots stream has been closed")


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = [
        "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0",
    ]

    task = asyncio.get_event_loop().create_task(
        client.listen_spot_orderbook_snapshots(
            market_ids=market_ids,
            callback=orderbook_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("devnet-1", "")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}
    stream, err := exchangeClient.StreamSpotOrderbookV2(ctx, marketIds)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            fmt.Println(res.MarketId, res.Orderbook, len(res.Orderbook.Sells), len(res.Orderbook.Buys))
        }
    }
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for orderbook streaming, empty means 'ALL' spot marketsYes

Response Parameters

Streaming Response Example:

{
   "orderbook":{
      "buys":[
         {
            "price":"0.000000000073489",
            "quantity":"129000000000000000",
            "timestamp":"1702042963690"
         },
         {
            "price":"0.000000000064261",
            "quantity":"1292000000000000000",
            "timestamp":"1702039612697"
         }
      ],
      "sells":[
         {
            "price":"0.000000000085",
            "quantity":"6681507000000000000000",
            "timestamp":"1702044411262"
         },
         {
            "price":"0.000000000085768",
            "quantity":"581000000000000000",
            "timestamp":"1701944786578"
         }
      ],
      "sequence":"6916434",
      "timestamp":"1702044439698"
   },
   "operationType":"update",
   "timestamp":"1702044441000",
   "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
}

ParameterTypeDescription
orderbookSpotLimitOrderbookV2Orderbook of a Spot Market
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.
market_idstringMarketId of the market's orderbook


SpotLimitOrderbookV2

ParameterTypeDescription
buysPriceLevel arrayArray of price levels for buys
sellsPriceLevel arrayArray of price levels for sells
sequenceuint64market orderbook sequence
timestampint64Last update timestamp in UNIX millis.
heightint64Block height at which the orderbook was last updated.


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.


StreamOrderbookUpdate

Stream incremental orderbook updates for one or more spot markets. This stream should be started prior to obtaining orderbook snapshots so that no incremental updates are omitted between obtaining a snapshot and starting the update stream.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from decimal import Decimal
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to spot orderbook updates ({exception})")


def stream_closed_processor():
    print("The spot orderbook updates stream has been closed")


class PriceLevel:
    def __init__(self, price: Decimal, quantity: Decimal, timestamp: int):
        self.price = price
        self.quantity = quantity
        self.timestamp = timestamp

    def __str__(self) -> str:
        return "price: {} | quantity: {} | timestamp: {}".format(self.price, self.quantity, self.timestamp)


class Orderbook:
    def __init__(self, market_id: str):
        self.market_id = market_id
        self.sequence = -1
        self.levels = {"buys": {}, "sells": {}}


async def load_orderbook_snapshot(client: IndexerClient, orderbook: Orderbook):
    # load the snapshot
    res = await client.fetch_spot_orderbooks_v2(market_ids=[orderbook.market_id], depth=0)
    for snapshot in res["orderbooks"]:
        if snapshot["marketId"] != orderbook.market_id:
            raise Exception("unexpected snapshot")

        orderbook.sequence = int(snapshot["orderbook"]["sequence"])

        for buy in snapshot["orderbook"]["buys"]:
            orderbook.levels["buys"][buy["price"]] = PriceLevel(
                price=Decimal(buy["price"]),
                quantity=Decimal(buy["quantity"]),
                timestamp=int(buy["timestamp"]),
            )
        for sell in snapshot["orderbook"]["sells"]:
            orderbook.levels["sells"][sell["price"]] = PriceLevel(
                price=Decimal(sell["price"]),
                quantity=Decimal(sell["quantity"]),
                timestamp=int(sell["timestamp"]),
            )


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)

    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    orderbook = Orderbook(market_id=market_id)
    updates_queue = asyncio.Queue()
    tasks = []

    async def queue_event(event: Dict[str, Any]):
        await updates_queue.put(event)

    # start getting price levels updates
    task = asyncio.get_event_loop().create_task(
        client.listen_spot_orderbook_updates(
            market_ids=[market_id],
            callback=queue_event,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )
    tasks.append(task)

    # load the snapshot once we are already receiving updates, so we don't miss any
    await load_orderbook_snapshot(client=client, orderbook=orderbook)

    task = asyncio.get_event_loop().create_task(
        apply_orderbook_update(orderbook=orderbook, updates_queue=updates_queue)
    )
    tasks.append(task)

    await asyncio.sleep(delay=60)
    for task in tasks:
        task.cancel()


async def apply_orderbook_update(orderbook: Orderbook, updates_queue: asyncio.Queue):
    while True:
        updates = await updates_queue.get()
        update = updates["orderbookLevelUpdates"]

        # discard updates older than the snapshot
        if int(update["sequence"]) <= orderbook.sequence:
            return

        print(" * * * * * * * * * * * * * * * * * * *")

        # ensure we have not missed any update
        if int(update["sequence"]) > (orderbook.sequence + 1):
            raise Exception(
                "missing orderbook update events from stream, must restart: {} vs {}".format(
                    update["sequence"], (orderbook.sequence + 1)
                )
            )

        print("updating orderbook with updates at sequence {}".format(update["sequence"]))

        # update orderbook
        orderbook.sequence = int(update["sequence"])
        for direction, levels in {"buys": update["buys"], "sells": update["sells"]}.items():
            for level in levels:
                if level["isActive"]:
                    # upsert level
                    orderbook.levels[direction][level["price"]] = PriceLevel(
                        price=Decimal(level["price"]), quantity=Decimal(level["quantity"]), timestamp=level["timestamp"]
                    )
                else:
                    if level["price"] in orderbook.levels[direction]:
                        del orderbook.levels[direction][level["price"]]

        # sort the level numerically
        buys = sorted(orderbook.levels["buys"].values(), key=lambda x: x.price, reverse=True)
        sells = sorted(orderbook.levels["sells"].values(), key=lambda x: x.price, reverse=True)

        # lowest sell price should be higher than the highest buy price
        if len(buys) > 0 and len(sells) > 0:
            highest_buy = buys[0].price
            lowest_sell = sells[-1].price
            print("Max buy: {} - Min sell: {}".format(highest_buy, lowest_sell))
            if highest_buy >= lowest_sell:
                raise Exception("crossed orderbook, must restart")

        # for the example, print the list of buys and sells orders.
        print("sells")
        for k in sells:
            print(k)
        print("=========")
        print("buys")
        for k in buys:
            print(k)
        print("====================================")


if __name__ == "__main__":
    asyncio.run(main())
package main

import (
    "context"
    "fmt"
    "io"
    "os"
    "sort"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
    "github.com/shopspring/decimal"
)

type MapOrderbook struct {
    Sequence uint64
    Levels   map[bool]map[string]*spotExchangePB.PriceLevel
}

func main() {
    network := common.LoadNetwork("devnet-1", "")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        fmt.Println(err)
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}
    stream, err := exchangeClient.StreamSpotOrderbookUpdate(ctx, marketIds)
    if err != nil {
        fmt.Println(err)
        panic(err)
    }

    updatesCh := make(chan *spotExchangePB.OrderbookLevelUpdates, 100000)
    receiving := make(chan struct{})
    var receivingClosed bool

    // stream orderbook price levels
    go func() {
        for {
            select {
            case <-ctx.Done():
                return
            default:
                res, err := stream.Recv()
                if err == io.EOF {
                    fmt.Println("change stream needs to be restarted")
                    os.Exit(0)
                }
                if err != nil {
                    panic(err) // rester on errors
                }
                u := res.OrderbookLevelUpdates
                if !receivingClosed {
                    fmt.Println("receiving updates from stream")
                    close(receiving)
                    receivingClosed = true
                }
                updatesCh <- u
            }
        }
    }()

    // ensure we are receiving updates before getting the orderbook snapshot,
    // we will skip past updates later.
    fmt.Println("waiting for streaming updates")
    <-receiving

    // prepare orderbooks map
    orderbooks := map[string]*MapOrderbook{}
    depth := int32(0)
    res, err := exchangeClient.GetSpotOrderbooksV2(ctx, marketIds, depth)
    if err != nil {
        panic(err)
    }
    for _, ob := range res.Orderbooks {
        // init inner maps not ready
        _, ok := orderbooks[ob.MarketId]
        if !ok {
            orderbook := &MapOrderbook{
                Sequence: ob.Orderbook.Sequence,
                Levels:   map[bool]map[string]*spotExchangePB.PriceLevel{},
            }
            orderbook.Levels[true] = map[string]*spotExchangePB.PriceLevel{}
            orderbook.Levels[false] = map[string]*spotExchangePB.PriceLevel{}
            orderbooks[ob.MarketId] = orderbook
        }

        for _, level := range ob.Orderbook.Buys {
            orderbooks[ob.MarketId].Levels[true][level.Price] = level
        }
        for _, level := range ob.Orderbook.Sells {
            orderbooks[ob.MarketId].Levels[false][level.Price] = level
        }
    }

    // continuously consume level updates and maintain orderbook
    skippedPastEvents := false
    for {
        updates := <-updatesCh

        // validate orderbook
        orderbook, ok := orderbooks[updates.MarketId]
        if !ok {
            fmt.Println("updates channel closed, must restart")
            return // closed
        }

        // skip if update sequence <= orderbook sequence until it's ready to consume
        if !skippedPastEvents {
            if orderbook.Sequence >= updates.Sequence {
                continue
            }
            skippedPastEvents = true
        }

        // panic if update sequence > orderbook sequence + 1
        if updates.Sequence > orderbook.Sequence+1 {
            fmt.Printf("skipping levels: update sequence %d vs orderbook sequence %d\n", updates.Sequence, orderbook.Sequence)
            panic("missing orderbook update events from stream, must restart")
        }

        // update orderbook map
        orderbook.Sequence = updates.Sequence
        for isBuy, update := range map[bool][]*spotExchangePB.PriceLevelUpdate{
            true:  updates.Buys,
            false: updates.Sells,
        } {
            for _, level := range update {
                if level.IsActive {
                    // upsert
                    orderbook.Levels[isBuy][level.Price] = &spotExchangePB.PriceLevel{
                        Price:     level.Price,
                        Quantity:  level.Quantity,
                        Timestamp: level.Timestamp,
                    }
                } else {
                    // remove inactive level
                    delete(orderbook.Levels[isBuy], level.Price)
                }
            }
        }

        // construct orderbook arrays
        sells, buys := maintainOrderbook(orderbook.Levels)
        fmt.Println("after", orderbook.Sequence, len(sells), len(buys))

        if len(sells) > 0 && len(buys) > 0 {
            // assert orderbook
            topBuyPrice := decimal.RequireFromString(buys[0].Price)
            lowestSellPrice := decimal.RequireFromString(sells[0].Price)
            if topBuyPrice.GreaterThanOrEqual(lowestSellPrice) {
                panic(fmt.Errorf("crossed orderbook, must restart: buy %s >= %s sell", topBuyPrice, lowestSellPrice))
            }
        }

        res, _ = exchangeClient.GetSpotOrderbooksV2(ctx, marketIds, depth)
        fmt.Println("query", res.Orderbooks[0].Orderbook.Sequence, len(res.Orderbooks[0].Orderbook.Sells), len(res.Orderbooks[0].Orderbook.Buys))

        // print orderbook
        fmt.Println(" [SELLS] ========")
        for _, s := range sells {
            fmt.Println(s)
        }
        fmt.Println(" [BUYS] ========")
        for _, b := range buys {
            fmt.Println(b)
        }
        fmt.Println("=======================================================")
    }
}

func maintainOrderbook(orderbook map[bool]map[string]*spotExchangePB.PriceLevel) (buys, sells []*spotExchangePB.PriceLevel) {
    for _, v := range orderbook[false] {
        sells = append(sells, v)
    }
    for _, v := range orderbook[true] {
        buys = append(buys, v)
    }

    sort.Slice(sells, func(i, j int) bool {
        return decimal.RequireFromString(sells[i].Price).LessThan(decimal.RequireFromString(sells[j].Price))
    })

    sort.Slice(buys, func(i, j int) bool {
        return decimal.RequireFromString(buys[i].Price).GreaterThan(decimal.RequireFromString(buys[j].Price))
    })

    return sells, buys
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for orderbook streaming, empty means 'ALL' spot marketsYes

Response Parameters

Streaming Response Example:

 * * * * * * * * * * * * * * * * * * *
updating orderbook with updates at sequence 724
Max buy: 7.523E-12 - Min sell: 7.525E-12
sells
price: 8E-12 | quantity: 10000000000000000 | timestamp: 1675904636889
price: 7.526E-12 | quantity: 50000000000000000 | timestamp: 1676089482358
price: 7.525E-12 | quantity: 10000000000000000 | timestamp: 1676015247335
=========
buys
price: 7.523E-12 | quantity: 30000000000000000 | timestamp: 1676616192052
price: 7E-12 | quantity: 1000000000000000000 | timestamp: 1675904400063
price: 1E-12 | quantity: 10000000000000000 | timestamp: 1675882430039
price: 1E-15 | quantity: 17983000000000000000 | timestamp: 1675880932648
====================================
 * * * * * * * * * * * * * * * * * * *
updating orderbook with updates at sequence 725
Max buy: 7.523E-12 - Min sell: 7.525E-12
sells
price: 8E-12 | quantity: 10000000000000000 | timestamp: 1675904636889
price: 7.526E-12 | quantity: 50000000000000000 | timestamp: 1676089482358
price: 7.525E-12 | quantity: 10000000000000000 | timestamp: 1676015247335
=========
buys
price: 7.523E-12 | quantity: 40000000000000000 | timestamp: 1676616222476
price: 7E-12 | quantity: 1000000000000000000 | timestamp: 1675904400063
price: 1E-12 | quantity: 10000000000000000 | timestamp: 1675882430039
price: 1E-15 | quantity: 17983000000000000000 | timestamp: 1675880932648
====================================

ParameterTypeDescription
orderbook_level_updatesOrderbookLevelUpdatesOrderbook level updates of a Spot Market
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.
market_idstringMarketId of the market's orderbook


OrderbookLevelUpdates

ParameterTypeDescription
market_idstringmarket's ID
sequenceuint64orderbook update sequence
buysPriceLevelUpdate arraybuy levels
sellsPriceLevelUpdate arraysell levels
updated_atint64updates timestamp


PriceLevelUpdate

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
is_activeboolPrice level status.
timestampint64Price level last updated timestamp in UNIX millis.

SubaccountOrdersList

Get orders of a subaccount.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    skip = 10
    limit = 10
    pagination = PaginationOption(skip=skip, limit=limit)
    orders = await client.fetch_spot_subaccount_orders_list(
        subaccount_id=subaccount_id, market_id=market_id, pagination=pagination
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccountId := "0x0b46e339708ea4d87bd2fcc61614e109ac374bbe000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)

    req := spotExchangePB.SubaccountOrdersListRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Skip:         skip,
        Limit:        limit,
    }

    res, err := exchangeClient.GetSubaccountSpotOrdersList(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes

Response Parameters

Response Example:

{
   "orders":[
      {
         "orderHash":"0x3414f6f1a37a864166b19930680eb62a99798b5e406c2d14ed1ee66ab9958503",
         "orderSide":"buy",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "price":"0.000000000003",
         "quantity":"55000000000000000000",
         "unfilledQuantity":"55000000000000000000",
         "triggerPrice":"0",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "state":"booked",
         "createdAt":"1701808096494",
         "updatedAt":"1701808096494",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "cid":"670c52ec-f68f-456c-8aeb-e271071a43ac"
      },
      {
         "orderHash":"0xb7b6d54d1e01e1eb0005e34e08a96b715b557eeee7c5f3a439636f98ddd66b91",
         "orderSide":"buy",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "price":"0.000000000003",
         "quantity":"55000000000000000000",
         "unfilledQuantity":"55000000000000000000",
         "triggerPrice":"0",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "state":"booked",
         "createdAt":"1701808058512",
         "updatedAt":"1701808058512",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "cid":"bba97476-e7f4-4313-874b-7ef115daccb4"
      }
   ],
   "paging":{
      "total":"53",
      "from":1,
      "to":2,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "orders": [
  {
   "order_hash": "0x5e970df47eb5a65a5f907e3a2912067dde416eca8609c838e08c0dbebfbefaa5",
   "order_side": "sell",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "price": "0.000000000005",
   "quantity": "1000000000000000000",
   "unfilled_quantity": "1000000000000000000",
   "trigger_price": "0",
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
   "state": "booked",
   "created_at": 1652809317404,
   "updated_at": 1652809317404
  },
  {
   "order_hash": "0x318418b546563a75c11dc656ee0fb41608e2893b0de859cf2b9e2d65996b6f9c",
   "order_side": "buy",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "price": "0.000000000001",
   "quantity": "1000000000000000000",
   "unfilled_quantity": "1000000000000000000",
   "trigger_price": "0",
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
   "state": "booked",
   "created_at": 1652809253308,
   "updated_at": 1652809253308
  }
 ]
}
ParameterTypeDescription
ordersSpotLimitOrder array
pagingPaging


SpotLimitOrder

ParameterTypeDescription
order_hashstringHash of the order
order_sidestringThe side of the order
market_idstringSpot Market ID is keccak265(baseDenom + quoteDenom)
subaccount_idstringThe subaccountId that this order belongs to
pricestringPrice of the order
quantitystringQuantity of the order
unfilled_quantitystringThe amount of the quantity remaining unfilled
trigger_pricestringTrigger price is the trigger price used by stop/take orders. 0 if the trigger price is not set.
fee_recipientstringFee recipient address
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

SubaccountTradesList

Get trades of a subaccount.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    execution_type = "market"
    direction = "buy"
    skip = 2
    limit = 3
    pagination = PaginationOption(skip=skip, limit=limit)
    trades = await client.fetch_spot_subaccount_trades_list(
        subaccount_id=subaccount_id,
        market_id=market_id,
        execution_type=execution_type,
        direction=direction,
        pagination=pagination,
    )
    print(json.dumps(trades, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    spotExchangePB "github.com/InjectiveLabs/sdk-go/exchange/spot_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)

    req := spotExchangePB.SubaccountTradesListRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Skip:         skip,
        Limit:        limit,
    }

    res, err := exchangeClient.GetSubaccountSpotTradesList(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
market_idstringFilter trades by market IDYes
execution_typestringFilter by execution type of tradesYes
directionstringFilter by direction tradesYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes

Response Parameters

Response Example:

{
   "trades":[
      {
         "orderHash":"0x6dfd01151a5b3cfb3a61777335f0d8d324a479b9006fd9642f52b402aec53d4f",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "tradeExecutionType":"market",
         "tradeDirection":"buy",
         "price":{
            "price":"0.000000000015589",
            "quantity":"1000000000000000",
            "timestamp":"1700675201676"
         },
         "fee":"10.9123",
         "executedAt":"1700675201676",
         "feeRecipient":"inj1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3t5qxqh",
         "tradeId":"18740619_240_0",
         "executionSide":"taker",
         "cid":""
      },
      {
         "orderHash":"0x6a6cd0afb038322b67a88cd827e2800483e3571c5e82663df37a33770fa0a8d1",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "tradeExecutionType":"market",
         "tradeDirection":"buy",
         "price":{
            "price":"0.000000000015742",
            "quantity":"1000000000000000",
            "timestamp":"1700232025894"
         },
         "fee":"11.0194",
         "executedAt":"1700232025894",
         "feeRecipient":"inj1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3t5qxqh",
         "tradeId":"18529043_240_0",
         "executionSide":"taker",
         "cid":""
      },
      {
         "orderHash":"0xa3049ebaa97ac3755c09bd53ea30e86b98aef40bf037cb9d91dedfc1fd4b7735",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "tradeExecutionType":"limitMatchNewOrder",
         "tradeDirection":"buy",
         "price":{
            "price":"0.000000000015874",
            "quantity":"21000000000000000000",
            "timestamp":"1700221121919"
         },
         "fee":"233347.8",
         "executedAt":"1700221121919",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "tradeId":"18523837_243_0",
         "executionSide":"taker",
         "cid":""
      }
   ]
}
{
 "trades": [
  {
   "order_hash": "0xbf5cf18a5e73c61d465a60ca550c5fbe0ed37b9ca0a49f7bd1de012e983fe55e",
   "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitFill",
   "trade_direction": "sell",
   "price": {
    "price": "0.000000000002305",
    "quantity": "1000000000000000000",
    "timestamp": 1652809734211
   },
   "fee": "2305",
   "executed_at": 1652809734211,
   "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
  },
  {
   "order_hash": "0xfd474dc696dc291bca8ca1b371653994fd846a303c08d26ccc17a7b60939d256",
   "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
   "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
   "trade_execution_type": "limitFill",
   "trade_direction": "sell",
   "price": {
    "price": "0.000000000002318",
    "quantity": "4000000000000000000",
    "timestamp": 1652773190338
   },
   "fee": "9272",
   "executed_at": 1652773190338,
   "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
  }
 ]
}

ParameterTypeDescription
tradesSpotTrade arrayList of spot market trades


SpotTrade

ParameterTypeDescription
order_hashstringMaker order hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
trade_directionstringThe direction the trade
pricePriceLevelPrice level at which trade has been executed
feestringThe fee associated with the trade (quote asset denom)
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.

- InjectiveDerivativeExchangeRPC

InjectiveDerivativeExchangeRPC defines the gRPC API of the Derivative Exchange provider.

Market

Get details of a single derivative market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    market = await client.fetch_derivative_market(market_id=market_id)
    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    res, err := exchangeClient.GetDerivativeMarket(ctx, marketId)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market we want to fetchYes

Response Parameters

Response Example:

{
   "market":{
      "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
      "marketStatus":"active",
      "ticker":"INJ/USDT PERP",
      "oracleBase":"0x2d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b3",
      "oracleQuote":"0x1fc18861232290221461220bd4e2acd1dcdfbc89c84092c93c18bdc7756c1588",
      "oracleType":"pyth",
      "oracleScaleFactor":6,
      "initialMarginRatio":"0.05",
      "maintenanceMarginRatio":"0.02",
      "quoteDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
      "quoteTokenMeta":{
         "name":"Testnet Tether USDT",
         "address":"0x0000000000000000000000000000000000000000",
         "symbol":"USDT",
         "logo":"https://static.alchemyapi.io/images/assets/825.png",
         "decimals":6,
         "updatedAt":"1698247516758"
      },
      "makerFeeRate":"-0.0001",
      "takerFeeRate":"0.001",
      "serviceProviderFee":"0.4",
      "isPerpetual":true,
      "minPriceTickSize":"100",
      "minQuantityTickSize":"0.0001",
      "perpetualMarketInfo":{
         "hourlyFundingRateCap":"0.000625",
         "hourlyInterestRate":"0.00000416666",
         "nextFundingTimestamp":"1701990000",
         "fundingInterval":"3600"
      },
      "perpetualMarketFunding":{
         "cumulativeFunding":"-156010.283874921534910863",
         "cumulativePrice":"566.477789213654772072",
         "lastTimestamp":"1701906508"
      },
      "min_notional":"1000000"
   }
}
{
 "market": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "market_status": "active",
  "ticker": "BTC/USDT PERP",
  "oracle_base": "BTC",
  "oracle_quote": "USDT",
  "oracle_type": "bandibc",
  "oracle_scale_factor": 6,
  "initial_margin_ratio": "0.095",
  "maintenance_margin_ratio": "0.05",
  "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "quote_token_meta": {
   "name": "Tether",
   "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "symbol": "USDT",
   "logo": "https://static.alchemyapi.io/images/assets/825.png",
   "decimals": 6,
   "updated_at": 1650978923435
  },
  "maker_fee_rate": "0.0005",
  "taker_fee_rate": "0.0012",
  "service_provider_fee": "0.4",
  "is_perpetual": true,
  "min_price_tick_size": "100000",
  "min_quantity_tick_size": "0.0001",
  "perpetual_market_info": {
   "hourly_funding_rate_cap": "0.000625",
   "hourly_interest_rate": "0.00000416666",
   "next_funding_timestamp": 1652864400,
   "funding_interval": 3600
  },
  "perpetual_market_funding": {
   "cumulative_funding": "7246105747.050586213851272386",
   "cumulative_price": "31.114148427047982579",
   "last_timestamp": 1652793510
  },
  "min_notional": "1000000"
 }
}
ParameterTypeDescription
marketDerivativeMarketInfoInfo about particular derivative market

DerivativeMarketInfo

ParameterTypeDescription
market_idstringDerivativeMarket ID is crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote))) for perpetual markets and crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote + strconv.Itoa(int(expiry))))) for expiry futures markets
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typestringOracle Type
oracle_scale_factoruint32OracleScaleFactor
initial_margin_ratiostringDefines the initial margin ratio of a derivative market
maintenance_margin_ratiostringDefines the maintenance margin ratio of a derivative market
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
is_perpetualboolTrue if the market is a perpetual swap market
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
perpetual_market_infoPerpetualMarketInfo
perpetual_market_fundingPerpetualMarketFunding
expiry_futures_market_infoExpiryFuturesMarketInfo
min_notionalstringMinimum notional value for the order
reduce_margin_ratiostringDefines the reduce margin ratio of a derivative market
open_notional_capOpenNotionalCapThe open notional cap of the market, if any


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.


PerpetualMarketInfo

ParameterTypeDescription
hourly_funding_rate_capstringDefines the default maximum absolute value of the hourly funding rate of the perpetual market.
hourly_interest_ratestringDefines the hourly interest rate of the perpetual market.
next_funding_timestampint64Defines the next funding timestamp in seconds of a perpetual market in UNIX seconds.
funding_intervalint64Defines the funding interval in seconds of a perpetual market in seconds.


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingstringDefines the cumulative funding of a perpetual market.
cumulative_pricestringDefines defines the cumulative price for the current hour up to the last timestamp.
last_timestampint64Defines the last funding timestamp in seconds of a perpetual market in UNIX seconds.
last_funding_ratestringDefines the last funding rate of a perpetual market.


ExpiryFuturesMarketInfo

ParameterTypeDescription
expiration_timestampint64Defines the expiration time for a time expiry futures market in UNIX seconds.
settlement_pricestringDefines the settlement price for a time expiry futures market.


Markets

Get a list of one or more derivative markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_statuses = ["active"]
    quote_denom = "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    market = await client.fetch_derivative_markets(market_statuses=market_statuses, quote_denom=quote_denom)
    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("mainnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketStatus := "active"
    quoteDenom := "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7"

    req := derivativeExchangePB.MarketsRequest{
        MarketStatus: marketStatus,
        QuoteDenom:   quoteDenom,
    }

    res, err := exchangeClient.GetDerivativeMarkets(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_statusstringFilter by market statusYes
quote_denomstringFilter by the Coin denomination of the quote currencyYes
market_statusesstring arrayYes

Response Parameters

Response Example:

[
  {
    "marketId": "0x1c79dac019f73e4060494ab1b4fcba734350656d6fc4d474f6a238c13c6f9ced",
    "marketStatus": "active",
    "ticker": "BNB/USDT PERP",
    "oracleBase": "BNB",
    "oracleQuote": "USDT",
    "oracleType": "bandibc",
    "oracleScaleFactor": 6,
    "initialMarginRatio": "0.095",
    "maintenanceMarginRatio": "0.05",
    "quoteDenom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "quoteTokenMeta": {
      "name": "Tether",
      "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "symbol": "USDT",
      "logo": "https://static.alchemyapi.io/images/assets/825.png",
      "decimals": 6,
      "updatedAt": 1650978923353
    },
    "makerFeeRate": "0.0005",
    "takerFeeRate": "0.0012",
    "serviceProviderFee": "0.4",
    "isPerpetual": true,
    "minPriceTickSize": "10000",
    "minQuantityTickSize": "0.01",
    "perpetualMarketInfo": {
      "hourlyFundingRateCap": "0.000625",
      "hourlyInterestRate": "0.00000416666",
      "nextFundingTimestamp": 1654246800,
      "fundingInterval": 3600
    },
    "perpetualMarketFunding": {
      "cumulativeFunding": "56890491.178246679699729639",
      "cumulativePrice": "7.082760891515203314",
      "lastTimestamp": 1654245985
    },
    "min_notional": "1000000",
  },
  {
    "marketId": "0x00030df39180df04a873cb4aadc50d4135640af5c858ab637dbd4d31b147478c",
    "marketStatus": "active",
    "ticker": "Frontrunner Futures: Expires 5.21.2023",
    "oracleBase": "FRNT",
    "oracleQuote": "USDT",
    "oracleType": "pricefeed",
    "oracleScaleFactor": 6,
    "initialMarginRatio": "0.999999999999999999",
    "maintenanceMarginRatio": "0.1",
    "quoteDenom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "quoteTokenMeta": {
      "name": "Tether",
      "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "symbol": "USDT",
      "logo": "https://static.alchemyapi.io/images/assets/825.png",
      "decimals": 6,
      "updatedAt": 1653064108501
    },
    "makerFeeRate": "0.005",
    "takerFeeRate": "0.012",
    "serviceProviderFee": "0.4",
    "isPerpetual": false,
    "minPriceTickSize": "0.000000000000001",
    "minQuantityTickSize": "0.0001",
    "expiryFuturesMarketInfo": {
      "expirationTimestamp": 1684600043,
      "settlementPrice": "0"
    },
    "min_notional": "0"
  }
]
{
 "markets": [
  {
   "market_id": "0x1c79dac019f73e4060494ab1b4fcba734350656d6fc4d474f6a238c13c6f9ced",
   "market_status": "active",
   "ticker": "BNB/USDT PERP",
   "oracle_base": "BNB",
   "oracle_quote": "USDT",
   "oracle_type": "bandibc",
   "oracle_scale_factor": 6,
   "initial_margin_ratio": "0.095",
   "maintenance_margin_ratio": "0.05",
   "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "quote_token_meta": {
    "name": "Tether",
    "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "symbol": "USDT",
    "logo": "https://static.alchemyapi.io/images/assets/825.png",
    "decimals": 6,
    "updated_at": 1650978923353
   },
   "maker_fee_rate": "0.0005",
   "taker_fee_rate": "0.0012",
   "service_provider_fee": "0.4",
   "is_perpetual": true,
   "min_price_tick_size": "10000",
   "min_quantity_tick_size": "0.01",
   "perpetual_market_info": {
    "hourly_funding_rate_cap": "0.000625",
    "hourly_interest_rate": "0.00000416666",
    "next_funding_timestamp": 1652864400,
    "funding_interval": 3600
   },
   "perpetual_market_funding": {
    "cumulative_funding": "48248742.484852568471323698",
    "cumulative_price": "5.691379282523162906",
    "last_timestamp": 1652775374
   },
   "min_notional": "1000000"
  },
  {
   "market_id": "0xfb5f14852bd01af901291dd2aa65e997b3a831f957124a7fe7aa40d218ff71ae",
   "market_status": "active",
   "ticker": "XAG/USDT PERP",
   "oracle_base": "XAG",
   "oracle_quote": "USDT",
   "oracle_type": "bandibc",
   "oracle_scale_factor": 6,
   "initial_margin_ratio": "0.8",
   "maintenance_margin_ratio": "0.4",
   "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "quote_token_meta": {
    "name": "Tether",
    "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "symbol": "USDT",
    "logo": "https://static.alchemyapi.io/images/assets/825.png",
    "decimals": 6,
    "updated_at": 1650978923534
   },
   "maker_fee_rate": "0.003",
   "taker_fee_rate": "0.005",
   "service_provider_fee": "0.4",
   "is_perpetual": true,
   "min_price_tick_size": "10000",
   "min_quantity_tick_size": "0.01",
   "perpetual_market_info": {
    "hourly_funding_rate_cap": "0.000625",
    "hourly_interest_rate": "0.00000416666",
    "next_funding_timestamp": 1652864400,
    "funding_interval": 3600
   },
   "perpetual_market_funding": {
    "cumulative_funding": "1099659.417190990913058692",
    "cumulative_price": "-4.427475055338306767",
    "last_timestamp": 1652775322
   },
   "min_notional": "0",
  }
 ]
}
ParameterTypeDescription
marketsDerivativeMarketInfo arrayDerivative Markets list


DerivativeMarketInfo

ParameterTypeDescription
market_idstringDerivativeMarket ID is crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote))) for perpetual markets and crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote + strconv.Itoa(int(expiry))))) for expiry futures markets
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typestringOracle Type
oracle_scale_factoruint32OracleScaleFactor
initial_margin_ratiostringDefines the initial margin ratio of a derivative market
maintenance_margin_ratiostringDefines the maintenance margin ratio of a derivative market
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
is_perpetualboolTrue if the market is a perpetual swap market
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
perpetual_market_infoPerpetualMarketInfo
perpetual_market_fundingPerpetualMarketFunding
expiry_futures_market_infoExpiryFuturesMarketInfo
min_notionalstringMinimum notional value for the order
reduce_margin_ratiostringDefines the reduce margin ratio of a derivative market
open_notional_capOpenNotionalCapThe open notional cap of the market, if any


PerpetualMarketInfo

ParameterTypeDescription
hourly_funding_rate_capstringDefines the default maximum absolute value of the hourly funding rate of the perpetual market.
hourly_interest_ratestringDefines the hourly interest rate of the perpetual market.
next_funding_timestampint64Defines the next funding timestamp in seconds of a perpetual market in UNIX seconds.
funding_intervalint64Defines the funding interval in seconds of a perpetual market in seconds.


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingstringDefines the cumulative funding of a perpetual market.
cumulative_pricestringDefines defines the cumulative price for the current hour up to the last timestamp.
last_timestampint64Defines the last funding timestamp in seconds of a perpetual market in UNIX seconds.
last_funding_ratestringDefines the last funding rate of a perpetual market.


ExpiryFuturesMarketInfo

ParameterTypeDescription
expiration_timestampint64Defines the expiration time for a time expiry futures market in UNIX seconds.
settlement_pricestringDefines the settlement price for a time expiry futures market.


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

StreamMarkets

Stream live updates of derivative markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def market_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative markets updates ({exception})")


def stream_closed_processor():
    print("The derivative markets updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)

    task = asyncio.get_event_loop().create_task(
        client.listen_derivative_market_updates(
            callback=market_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}
    stream, err := exchangeClient.StreamDerivativeMarket(ctx, marketIds)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for updates streaming, empty means 'ALL' derivative marketsYes

Response Parameters

Streaming Response Example:

{
  "market": {
    "marketId": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
    "marketStatus": "active",
    "ticker": "BTC/USDT PERP",
    "oracleBase": "BTC",
    "oracleQuote": "USDT",
    "oracleType": "bandibc",
    "oracleScaleFactor": 6,
    "initialMarginRatio": "0.095",
    "maintenanceMarginRatio": "0.05",
    "quoteDenom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "quoteTokenMeta": {
      "name": "Tether",
      "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "symbol": "USDT",
      "logo": "https://static.alchemyapi.io/images/assets/825.png",
      "decimals": 6,
      "updatedAt": 1650978923435
    },
    "makerFeeRate": "0.0005",
    "takerFeeRate": "0.0012",
    "serviceProviderFee": "0.4",
    "isPerpetual": true,
    "minPriceTickSize": "100000",
    "minQuantityTickSize": "0.0001",
    "perpetualMarketInfo": {
      "hourlyFundingRateCap": "0.000625",
      "hourlyInterestRate": "0.00000416666",
      "nextFundingTimestamp": 1654246800,
      "fundingInterval": 3600
    },
    "perpetualMarketFunding": {
      "cumulativeFunding": "8239865636.851083559033030036",
      "cumulativePrice": "7.15770685160786651",
      "lastTimestamp": 1654246073
    },
    "min_notional": "1000000"
  },
  "operationType": "update",
  "timestamp": 1654246076000
}
{
 "market": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "market_status": "active",
  "ticker": "BTC/USDT PERP",
  "oracle_base": "BTC",
  "oracle_quote": "USDT",
  "oracle_type": "bandibc",
  "oracle_scale_factor": 6,
  "initial_margin_ratio": "0.095",
  "maintenance_margin_ratio": "0.05",
  "quote_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "quote_token_meta": {
   "name": "Tether",
   "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
   "symbol": "USDT",
   "logo": "https://static.alchemyapi.io/images/assets/825.png",
   "decimals": 6,
   "updated_at": 1650978923435
  },
  "maker_fee_rate": "0.0005",
  "taker_fee_rate": "0.0012",
  "service_provider_fee": "0.4",
  "is_perpetual": true,
  "min_price_tick_size": "100000",
  "min_quantity_tick_size": "0.0001",
  "perpetual_market_info": {
   "hourly_funding_rate_cap": "0.000625",
   "hourly_interest_rate": "0.00000416666",
   "next_funding_timestamp": 1653040800,
   "funding_interval": 3600
  },
  "perpetual_market_funding": {
   "cumulative_funding": "7356035675.459202347630388315",
   "cumulative_price": "3.723976370878870887",
   "last_timestamp": 1653038971
  },
  "min_notional": "0"
 },
 "operation_type": "update",
 "timestamp": 1653038974000
}
ParameterTypeDescription
marketDerivativeMarketInfoInfo about particular derivative market
operation_typestringUpdate type
timestampint64Operation timestamp in UNIX millis.


DerivativeMarketInfo

ParameterTypeDescription
market_idstringDerivativeMarket ID is crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote))) for perpetual markets and crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleBase + oracleQuote + strconv.Itoa(int(expiry))))) for expiry futures markets
market_statusstringThe status of the market
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typestringOracle Type
oracle_scale_factoruint32OracleScaleFactor
initial_margin_ratiostringDefines the initial margin ratio of a derivative market
maintenance_margin_ratiostringDefines the maintenance margin ratio of a derivative market
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
is_perpetualboolTrue if the market is a perpetual swap market
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
perpetual_market_infoPerpetualMarketInfo
perpetual_market_fundingPerpetualMarketFunding
expiry_futures_market_infoExpiryFuturesMarketInfo
min_notionalstringMinimum notional value for the order
reduce_margin_ratiostringDefines the reduce margin ratio of a derivative market
open_notional_capOpenNotionalCapThe open notional cap of the market, if any


PerpetualMarketInfo

ParameterTypeDescription
hourly_funding_rate_capstringDefines the default maximum absolute value of the hourly funding rate of the perpetual market.
hourly_interest_ratestringDefines the hourly interest rate of the perpetual market.
next_funding_timestampint64Defines the next funding timestamp in seconds of a perpetual market in UNIX seconds.
funding_intervalint64Defines the funding interval in seconds of a perpetual market in seconds.


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingstringDefines the cumulative funding of a perpetual market.
cumulative_pricestringDefines defines the cumulative price for the current hour up to the last timestamp.
last_timestampint64Defines the last funding timestamp in seconds of a perpetual market in UNIX seconds.
last_funding_ratestringDefines the last funding rate of a perpetual market.


ExpiryFuturesMarketInfo

ParameterTypeDescription
expiration_timestampint64Defines the expiration time for a time expiry futures market in UNIX seconds.
settlement_pricestringDefines the settlement price for a time expiry futures market.


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

OrdersHistory

Lists historical orders posted from a subaccount

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    subaccount_id = "0x295639d56c987f0e24d21bb167872b3542a6e05a000000000000000000000000"
    is_conditional = "false"
    skip = 10
    limit = 3
    pagination = PaginationOption(skip=skip, limit=limit)
    orders = await client.fetch_derivative_orders_history(
        subaccount_id=subaccount_id,
        market_ids=market_ids,
        is_conditional=is_conditional,
        pagination=pagination,
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)
    isConditional := "false"

    req := derivativeExchangePB.OrdersHistoryRequest{
        SubaccountId:  subaccountId,
        MarketId:      marketId,
        Skip:          skip,
        Limit:         limit,
        IsConditional: isConditional,
    }

    res, err := exchangeClient.GetHistoricalDerivativeOrders(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes
order_typesstring arrayfilter by order typesYes
directionstringorder side filterYes
start_timeint64Search for orders which createdAt >= startTime, time in millisecondYes
end_timeint64Search for orders which createdAt <= endTime, time in millisecondYes
is_conditionalstringOnly search for conditional/non-conditional ordersYes
order_typestringfilter by order typeYes
statestringFilter by order stateYes
execution_typesstring arrayYes
market_idsstring arrayYes
trade_idstringTradeId of the order we want to fetchYes
active_markets_onlyboolReturn only orders for active marketsYes
cidstringClient order IDYes

Response Parameters

Response Example:

{
   "orders":[
      {
         "orderHash":"0x3c98f1e38781ce8780f8f5ffe3a78cf3dbfa4d96f54d774a4847f46e9e89d6dc",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000005",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"13097700",
         "triggerPrice":"0",
         "quantity":"110660.5284",
         "filledQuantity":"0",
         "state":"canceled",
         "createdAt":"1701995288222",
         "updatedAt":"1702002966962",
         "direction":"buy",
         "margin":"724699201412.34",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "isReduceOnly":false,
         "isConditional":false,
         "triggerAt":"0",
         "placedOrderHash":"",
         "cid":""
      },
      {
         "orderHash":"0xc7c34746158b1e21bbdfa8edce0876fa00810f7b6f2236c302945c8e6b9eeb38",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000005",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"13064100",
         "triggerPrice":"0",
         "quantity":"110945.1399",
         "filledQuantity":"0",
         "state":"canceled",
         "createdAt":"1701995288222",
         "updatedAt":"1702002966962",
         "direction":"buy",
         "margin":"724699201083.795",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "isReduceOnly":false,
         "isConditional":false,
         "triggerAt":"0",
         "placedOrderHash":"",
         "cid":""
      },
      {
         "orderHash":"0x4478897d21c94df929c7d12c33d71973027ced1899ff253199b6e46124e680c1",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000005",
         "executionType":"limit",
         "orderType":"buy_po",
         "price":"13030500",
         "triggerPrice":"0",
         "quantity":"111231.2193",
         "filledQuantity":"0",
         "state":"canceled",
         "createdAt":"1701995288222",
         "updatedAt":"1702002966962",
         "direction":"buy",
         "margin":"724699201544.325",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isActive":false,
         "isReduceOnly":false,
         "isConditional":false,
         "triggerAt":"0",
         "placedOrderHash":"",
         "cid":""
      }
   ],
   "paging":{
      "total":"1000",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "orders": [
  {
   "order_hash": "0x17da6aa0ba9c192da6c9d5a043b4c36a91af5117636cb1f6e69654fc6cfc1bee",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "market",
   "order_type": "sell",
   "price": "6494113.703056872037914692",
   "trigger_price": "0",
   "quantity": "2110",
   "filled_quantity": "2110",
   "state": "filled",
   "created_at": 1692857306725,
   "updated_at": 1692857306725,
   "direction": "sell",
   "margin": "0"
  },
  {
   "order_hash": "0xeac94983c5e1a47885e5959af073c475e4ec6ec343c1e1d441af1ba65f8aa5ee",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "limit",
   "order_type": "buy",
   "price": "8111100",
   "trigger_price": "0",
   "quantity": "10",
   "filled_quantity": "10",
   "state": "filled",
   "created_at": 1688738648747,
   "updated_at": 1688738648747,
   "direction": "buy",
   "margin": "82614000"
  },
  {
   "order_hash": "0x41a5c6f8c8c8ff3f37e443617dda589f46f1678ef1a22e2ab2b6ca54e0788210",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "market",
   "order_type": "buy",
   "price": "8261400",
   "trigger_price": "0",
   "quantity": "100",
   "filled_quantity": "100",
   "state": "filled",
   "created_at": 1688591280030,
   "updated_at": 1688591280030,
   "direction": "buy",
   "margin": "274917218.543"
  },
  {
   "order_hash": "0x2f667629cd06ac9fd6e54aa2544ad63cd43efc29418d0e1e12df9ba783c9a7ab",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "market",
   "order_type": "buy",
   "price": "7166668.98546",
   "trigger_price": "0",
   "quantity": "2000",
   "filled_quantity": "2000",
   "state": "filled",
   "created_at": 1687507605674,
   "updated_at": 1687507605674,
   "direction": "buy",
   "margin": "4814400000"
  },
  {
   "order_hash": "0x4c42bca7b65f18bf96e75be03a53f73854da15e8030c38e63d1531307f8cd40c",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "market",
   "order_type": "sell",
   "price": "7123287.02926",
   "trigger_price": "0",
   "quantity": "1000",
   "filled_quantity": "1000",
   "state": "filled",
   "created_at": 1687507547684,
   "updated_at": 1687507547684,
   "direction": "sell",
   "margin": "0"
  },
  {
   "order_hash": "0x70c66ce3e92aa616d3dbdbcd565c37a3d42b2b5a0951a8bebe9ddaca9852d547",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "execution_type": "market",
   "order_type": "buy",
   "price": "7162504.91532",
   "trigger_price": "0",
   "quantity": "1000",
   "filled_quantity": "1000",
   "state": "filled",
   "created_at": 1687507348068,
   "updated_at": 1687507348068,
   "direction": "buy",
   "margin": "7212200000"
  }
 ],
 "paging": {
  "total": 6
 }
}

ParameterTypeDescription
ordersDerivativeOrderHistory arrayList of historical derivative orders
pagingPaging


DerivativeOrderHistory

ParameterTypeDescription
order_hashstringHash of the order
market_idstringSpot Market ID is keccak265(baseDenom + quoteDenom)
is_activeboolactive state of the order
subaccount_idstringThe subaccountId that this order belongs to
execution_typestringThe execution type
order_typestringThe side of the order
pricestringPrice of the order
trigger_pricestringTrigger price
quantitystringQuantity of the order
filled_quantitystringFilled amount
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
is_reduce_onlyboolTrue if an order is reduce only
directionstringOrder direction (order side)
is_conditionalboolTrue if this is conditional order, otherwise false
trigger_atuint64Trigger timestamp in unix milli
placed_order_hashstringOrder hash placed when this triggers
marginstringOrder's margin
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamOrdersHistory

Stream order updates of a derivative market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def order_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative orders history updates ({exception})")


def stream_closed_processor():
    print("The derivative orders history updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    task = asyncio.get_event_loop().create_task(
        client.listen_derivative_orders_history_updates(
            callback=order_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            market_id=market_id,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    direction := "buy"

    req := derivativeExchangePB.StreamOrdersHistoryRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Direction:    direction,
    }
    stream, err := exchangeClient.StreamHistoricalDerivativeOrders(ctx, &req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
order_typesstring arrayfilter by order typesYes
directionstringorder side filterYes
statestringFilter by order stateYes
execution_typesstring arrayYes

Response Parameters

Streaming Response Example:

{
   "order":{
      "order_hash":"0x4aeb72ac2ae5811126a0c384e05ce68745316add0e705c39e73f68c76431515e",
      "market_id":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
      "is_active":true,
      "subaccount_id":"0x7619f89a2172c6705aac7482f3adbf0601ea140e000000000000000000000000",
      "execution_type":"limit",
      "order_type":"sell_po",
      "price":"27953000000",
      "trigger_price":"0",
      "quantity":"0.0344",
      "filled_quantity":"0",
      "state":"booked",
      "created_at":1696617269292,
      "updated_at":1696617269292,
      "direction":"sell",
      "margin":"320527734"
   },
   "operation_type":"insert",
   "timestamp":1696617272000
}
{
   "order":{
      "order_hash":"0x24d82da3530ce5d2d392c9563d29b79c3a25e058dd6d79e0d8f651703256eb78",
      "market_id":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
      "subaccount_id":"0x6590d14d9e9c1d964f8c83bddc8a092f4a2d1284000000000000000000000000",
      "execution_type":"limit",
      "order_type":"buy_po",
      "price":"27912000000",
      "trigger_price":"0",
      "quantity":"0.0344",
      "filled_quantity":"0",
      "state":"canceled",
      "created_at":1696617207873,
      "updated_at":1696617269292,
      "direction":"buy",
      "margin":"320057600"
   },
   "operation_type":"update",
   "timestamp":1696617272000
}
{
   "order":{
      "order_hash":"0x4aeb72ac2ae5811126a0c384e05ce68745316add0e705c39e73f68c76431515e",
      "market_id":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
      "is_active":true,
      "subaccount_id":"0x7619f89a2172c6705aac7482f3adbf0601ea140e000000000000000000000000",
      "execution_type":"limit",
      "order_type":"sell_po",
      "price":"27953000000",
      "trigger_price":"0",
      "quantity":"0.0344",
      "filled_quantity":"0",
      "state":"booked",
      "created_at":1696617269292,
      "updated_at":1696617269292,
      "direction":"sell",
      "margin":"320527734"
   },
   "operation_type":"insert",
   "timestamp":1696617272000
}
{
   "order":{
      "order_hash":"0x24d82da3530ce5d2d392c9563d29b79c3a25e058dd6d79e0d8f651703256eb78",
      "market_id":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
      "subaccount_id":"0x6590d14d9e9c1d964f8c83bddc8a092f4a2d1284000000000000000000000000",
      "execution_type":"limit",
      "order_type":"buy_po",
      "price":"27912000000",
      "trigger_price":"0",
      "quantity":"0.0344",
      "filled_quantity":"0",
      "state":"canceled",
      "created_at":1696617207873,
      "updated_at":1696617269292,
      "direction":"buy",
      "margin":"320057600"
   },
   "operation_type":"update",
   "timestamp":1696617272000
}
ParameterTypeDescription
orderDerivativeOrderHistoryUpdated order
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.


DerivativeOrderHistory

ParameterTypeDescription
order_hashstringHash of the order
market_idstringSpot Market ID is keccak265(baseDenom + quoteDenom)
is_activeboolactive state of the order
subaccount_idstringThe subaccountId that this order belongs to
execution_typestringThe execution type
order_typestringThe side of the order
pricestringPrice of the order
trigger_pricestringTrigger price
quantitystringQuantity of the order
filled_quantitystringFilled amount
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
is_reduce_onlyboolTrue if an order is reduce only
directionstringOrder direction (order side)
is_conditionalboolTrue if this is conditional order, otherwise false
trigger_atuint64Trigger timestamp in unix milli
placed_order_hashstringOrder hash placed when this triggers
marginstringOrder's margin
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID

TradesV2

Get trades of a derivative market. The difference between Trades and TradesV2 is that the latter returns a trade_id compatible witht the one used for trade events in chain stream.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    subaccount_ids = ["0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"]
    skip = 0
    limit = 4
    pagination = PaginationOption(skip=skip, limit=limit)
    trades = await client.fetch_derivative_trades(
        market_ids=market_ids, subaccount_ids=subaccount_ids, pagination=pagination
    )
    print(json.dumps(trades, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"

    req := derivativeExchangePB.TradesV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }

    res, err := exchangeClient.GetDerivativeTradesV2(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market's orderbook we want to fetchYes
execution_sidestringFilter by execution side of the tradeYes
directionstringFilter by direction the tradeYes
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
start_timeint64The starting timestamp in UNIX milliseconds that the trades must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the trades must be equal or younger thanYes
market_idsstring arrayMarketIds of the markets of which we want to get tradesYes
subaccount_idsstring arraySubaccount ids of traders we want to get trades. Use this field for fetching trades from multiple subaccountsYes
execution_typesstring arrayYes
trade_idstringFilter by the tradeId of the tradeYes
account_addressstringAccount addressYes
cidstringClient order IDYes
fee_recipientstringFilter by fee recipientYes

Response Parameters

Response Example:

{
   "trades":[
      {
         "orderHash":"0xc246b6a43d826667047f752a76e508511d0aa4f73aba1c3b95527037ccbcb50c",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
         "tradeExecutionType":"limitMatchRestingOrder",
         "positionDelta":{
            "tradeDirection":"buy",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"-60000",
         "executedAt":"1701978102242",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"22868_2",
         "executionSide":"maker",
         "cid":"49fb387d-aad3-4f03-85c5-e6c06c5ea685",
         "isLiquidation":false
      },
      {
         "orderHash":"0x836e778ae11cee6cd31619ca7329121419471be7ea1bd2fafbae3a8d411a04c7",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
         "tradeExecutionType":"limitMatchRestingOrder",
         "positionDelta":{
            "tradeDirection":"buy",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"-600",
         "executedAt":"1701978102242",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"22868_4",
         "executionSide":"maker",
         "cid":"9a74f3ce-ea31-491e-9e64-e48541a8f7fd",
         "isLiquidation":false
      },
      {
         "orderHash":"0x404577bc40896028733f7740d4efc6f6695fb9194f43dd545fb8923cbb01efd6",
         "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
         "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
         "tradeExecutionType":"limitMatchNewOrder",
         "positionDelta":{
            "tradeDirection":"sell",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"5000000",
         "executedAt":"1701978102242",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"22868_3",
         "executionSide":"taker",
         "cid":"derivative_ATOM/USDT",
         "isLiquidation":false
      },
      {
         "orderHash":"0x3fde93ceabc67a13372c237f5271784c0bbe97801ef12e883cfbde4c13e16300",
         "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
         "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
         "tradeExecutionType":"limitMatchNewOrder",
         "positionDelta":{
            "tradeDirection":"sell",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"9000000"
         },
         "payout":"0",
         "fee":"10000",
         "executedAt":"1701978102242",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"22868_5",
         "executionSide":"taker",
         "cid":"derivative_INJ/USDT",
         "isLiquidation":false
      },
      {
         "orderHash":"0xc246b6a43d826667047f752a76e508511d0aa4f73aba1c3b95527037ccbcb50c",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
         "tradeExecutionType":"limitMatchRestingOrder",
         "positionDelta":{
            "tradeDirection":"buy",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"-60000",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_2",
         "executionSide":"maker",
         "cid":"49fb387d-aad3-4f03-85c5-e6c06c5ea685",
         "isLiquidation":false
      },
      {
         "orderHash":"0x836e778ae11cee6cd31619ca7329121419471be7ea1bd2fafbae3a8d411a04c7",
         "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
         "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
         "tradeExecutionType":"limitMatchRestingOrder",
         "positionDelta":{
            "tradeDirection":"buy",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"-600",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_4",
         "executionSide":"maker",
         "cid":"9a74f3ce-ea31-491e-9e64-e48541a8f7fd",
         "isLiquidation":false
      },
      {
         "orderHash":"0xf6ae77b0a1e267b7f0b8618f3f226c39ba702a09fb3bdb650b0c28197d36d91d",
         "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
         "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
         "tradeExecutionType":"limitMatchNewOrder",
         "positionDelta":{
            "tradeDirection":"sell",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"10000000"
         },
         "payout":"0",
         "fee":"5000000",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_3",
         "executionSide":"taker",
         "cid":"49fb387d-aad3-4f03-85c5-e6c06c5ea685",
         "isLiquidation":false
      },
      {
         "orderHash":"0x01ba4dd3b30bc946a31f5fe1aba9918e95d3dc8cf31a6c4b2d793068eae529e8",
         "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
         "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
         "tradeExecutionType":"limitMatchNewOrder",
         "positionDelta":{
            "tradeDirection":"sell",
            "executionPrice":"10000000",
            "executionQuantity":"1",
            "executionMargin":"9000000"
         },
         "payout":"0",
         "fee":"10000",
         "executedAt":"1701961116630",
         "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
         "tradeId":"1321_5",
         "executionSide":"taker",
         "cid":"9a74f3ce-ea31-491e-9e64-e48541a8f7fd",
         "isLiquidation":false
      }
   ],
   "paging":{
      "total":"8",
      "from":1,
      "to":8,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "trades": [
  {
   "order_hash": "0x836e778ae11cee6cd31619ca7329121419471be7ea1bd2fafbae3a8d411a04c7",
   "subaccount_id": "0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
   "market_id": "0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
   "trade_execution_type": "limitMatchRestingOrder",
   "position_delta": {
    "trade_direction": "buy",
    "execution_price": "10000000",
    "execution_quantity": "1",
    "execution_margin": "10000000"
   },
   "payout": "0",
   "fee": "-600",
   "executed_at": 1701978102242,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "22868_4",
   "execution_side": "maker",
   "cid": "9a74f3ce-ea31-491e-9e64-e48541a8f7fd"
  },
  {
   "order_hash": "0x3fde93ceabc67a13372c237f5271784c0bbe97801ef12e883cfbde4c13e16300",
   "subaccount_id": "0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
   "market_id": "0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
   "trade_execution_type": "limitMatchNewOrder",
   "position_delta": {
    "trade_direction": "sell",
    "execution_price": "10000000",
    "execution_quantity": "1",
    "execution_margin": "9000000"
   },
   "payout": "0",
   "fee": "10000",
   "executed_at": 1701978102242,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "22868_5",
   "execution_side": "taker",
   "cid": "9a74f3ce-ea31-491e-9e64-e48541a8f7fd"
  },
  {
   "order_hash": "0x836e778ae11cee6cd31619ca7329121419471be7ea1bd2fafbae3a8d411a04c7",
   "subaccount_id": "0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
   "market_id": "0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
   "trade_execution_type": "limitMatchRestingOrder",
   "position_delta": {
    "trade_direction": "buy",
    "execution_price": "10000000",
    "execution_quantity": "1",
    "execution_margin": "10000000"
   },
   "payout": "0",
   "fee": "-600",
   "executed_at": 1701961116630,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "1321_4",
   "execution_side": "maker",
   "cid": "9a74f3ce-ea31-491e-9e64-e48541a8f7fd"
  },
  {
   "order_hash": "0x01ba4dd3b30bc946a31f5fe1aba9918e95d3dc8cf31a6c4b2d793068eae529e8",
   "subaccount_id": "0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
   "market_id": "0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
   "trade_execution_type": "limitMatchNewOrder",
   "position_delta": {
    "trade_direction": "sell",
    "execution_price": "10000000",
    "execution_quantity": "1",
    "execution_margin": "9000000"
   },
   "payout": "0",
   "fee": "10000",
   "executed_at": 1701961116630,
   "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "trade_id": "1321_5",
   "execution_side": "taker",
   "cid": "9a74f3ce-ea31-491e-9e64-e48541a8f7fd"
  }
 ],
 "paging": {
  "total": 4,
  "from": 1,
  "to": 4
 }
}

ParameterTypeDescription
tradesDerivativeTrade arrayTrades of a Derivative Market
pagingPaging


DerivativeTrade

ParameterTypeDescription
order_hashstringOrder hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
is_liquidationboolTrue if the trade is a liquidation
position_deltaPositionDeltaPosition Delta from the trade
payoutstringThe payout associated with the trade
feestringThe fee associated with the trade
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID
pnlstringProfit and loss of the trade


PositionDelta

ParameterTypeDescription
trade_directionstringThe direction the trade
execution_pricestringExecution Price of the trade.
execution_quantitystringExecution Quantity of the trade.
execution_marginstringExecution Margin of the trade.


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamTradesV2

Stream newly executed trades of a derivative market. The default request streams trades from all derivative markets. The difference between StreamTrades and StreamTradesV2 is that the latter returns a trade_id compatible witht the one used for trade events in chain stream.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def market_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative trades updates ({exception})")


def stream_closed_processor():
    print("The derivative trades updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = [
        "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        "0x70bc8d7feab38b23d5fdfb12b9c3726e400c265edbcbf449b6c80c31d63d3a02",
    ]
    subaccount_ids = ["0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"]

    task = asyncio.get_event_loop().create_task(
        client.listen_derivative_trades_updates(
            callback=market_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            market_ids=market_ids,
            subaccount_ids=subaccount_ids,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"

    req := derivativeExchangePB.StreamTradesV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }
    stream, err := exchangeClient.StreamDerivativeV2Trades(ctx, &req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the market's orderbook we want to fetchYes
execution_sidestringFilter by execution side of the tradeYes
directionstringFilter by direction the tradeYes
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
start_timeint64The starting timestamp in UNIX milliseconds that the trades must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the trades must be equal or younger thanYes
market_idsstring arrayMarketIds of the markets of which we want to get tradesYes
subaccount_idsstring arraySubaccount ids of traders we want to get trades. Use this field for fetching trades from multiple subaccountsYes
execution_typesstring arrayYes
trade_idstringFilter by the tradeId of the tradeYes
account_addressstringAccount addressYes
cidstringClient order IDYes
fee_recipientstringFilter by fee recipientYes

Response Parameters

Streaming Response Example:

{
   "trade":{
      "orderHash":"0x01e6b3df831734c88c84522f9834b3656b3afde6891ac671742dd269be776510",
      "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
      "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
      "tradeExecutionType":"limitMatchNewOrder",
      "positionDelta":{
         "tradeDirection":"sell",
         "executionPrice":"10000000",
         "executionQuantity":"1",
         "executionMargin":"10000000"
      },
      "payout":"0",
      "fee":"5000000",
      "executedAt":"1701979920875",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"25116_3",
      "executionSide":"taker",
      "cid":"derivative_ATOM/USDT",
      "isLiquidation":false
   },
   "operationType":"insert",
   "timestamp":"1701979922000"
}
{
   "trade":{
      "orderHash":"0xc246b6a43d826667047f752a76e508511d0aa4f73aba1c3b95527037ccbcb50c",
      "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
      "marketId":"0x56d0c0293c4415e2d48fc2c8503a56a0c7389247396a2ef9b0a48c01f0646705",
      "tradeExecutionType":"limitMatchRestingOrder",
      "positionDelta":{
         "tradeDirection":"buy",
         "executionPrice":"10000000",
         "executionQuantity":"1",
         "executionMargin":"10000000"
      },
      "payout":"0",
      "fee":"-60000",
      "executedAt":"1701979920875",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"25116_2",
      "executionSide":"maker",
      "cid":"49fb387d-aad3-4f03-85c5-e6c06c5ea685",
      "isLiquidation":false
   },
   "operationType":"insert",
   "timestamp":"1701979922000"
}
{
   "trade":{
      "orderHash":"0xa0446c80b66dd6ab75b32e51e4e04929ae92df9fa7a64fe2d21ed9be536bb6d5",
      "subaccountId":"0x3db1f84431dfe4df617f9eb2d04edf432beb9826000000000000000000000000",
      "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
      "tradeExecutionType":"limitMatchNewOrder",
      "positionDelta":{
         "tradeDirection":"sell",
         "executionPrice":"10000000",
         "executionQuantity":"1",
         "executionMargin":"9000000"
      },
      "payout":"0",
      "fee":"10000",
      "executedAt":"1701979920875",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"25116_5",
      "executionSide":"taker",
      "cid":"derivative_INJ/USDT",
      "isLiquidation":false
   },
   "operationType":"insert",
   "timestamp":"1701979922000"
}
{
   "trade":{
      "orderHash":"0x836e778ae11cee6cd31619ca7329121419471be7ea1bd2fafbae3a8d411a04c7",
      "subaccountId":"0x101411266c6e2b610b4a0324d2bfb2ef0ca6e1dd000000000000000000000000",
      "marketId":"0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4",
      "tradeExecutionType":"limitMatchRestingOrder",
      "positionDelta":{
         "tradeDirection":"buy",
         "executionPrice":"10000000",
         "executionQuantity":"1",
         "executionMargin":"10000000"
      },
      "payout":"0",
      "fee":"-600",
      "executedAt":"1701979920875",
      "feeRecipient":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "tradeId":"25116_4",
      "executionSide":"maker",
      "cid":"9a74f3ce-ea31-491e-9e64-e48541a8f7fd",
      "isLiquidation":false
   },
   "operationType":"insert",
   "timestamp":"1701979922000"
}
{
 "trade": {
  "order_hash": "0x0403d2e51d73aa1cb46004b16d76279afece9ad14e3784eb93aa6370de466f81",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchRestingOrder",
  "position_delta": {
   "trade_direction": "sell",
   "execution_price": "40249100000",
   "execution_quantity": "0.06",
   "execution_margin": "2388462000"
  },
  "payout": "0",
  "fee": "1207473",
  "executed_at": 1653040243183,
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
 },
 "operation_type": "insert",
 "timestamp": 1653040246000
}{
 "trade": {
  "order_hash": "0x728d69975e4057d1801f1a7031d0ccf7242abacbf73320da55abab677efc2a7e",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchRestingOrder",
  "position_delta": {
   "trade_direction": "sell",
   "execution_price": "40249100000",
   "execution_quantity": "0.02",
   "execution_margin": "779300000"
  },
  "payout": "0",
  "fee": "402491",
  "executed_at": 1653040243183,
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
 },
 "operation_type": "insert",
 "timestamp": 1653040246000
}
ParameterTypeDescription
tradeDerivativeTradeNew derivative market trade
operation_typestringExecuted trades update type
timestampint64Operation timestamp in UNIX millis.


DerivativeTrade

ParameterTypeDescription
order_hashstringOrder hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
is_liquidationboolTrue if the trade is a liquidation
position_deltaPositionDeltaPosition Delta from the trade
payoutstringThe payout associated with the trade
feestringThe fee associated with the trade
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID
pnlstringProfit and loss of the trade


PositionDelta

ParameterTypeDescription
trade_directionstringThe direction the trade
execution_pricestringExecution Price of the trade.
execution_quantitystringExecution Quantity of the trade.
execution_marginstringExecution Margin of the trade.

Positions

Get the positions of a market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = [
        "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        "0xd97d0da6f6c11710ef06315971250e4e9aed4b7d4cd02059c9477ec8cf243782",
    ]
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    direction = "short"
    subaccount_total_positions = False
    skip = 4
    limit = 4
    pagination = PaginationOption(skip=skip, limit=limit)
    positions = await client.fetch_derivative_positions_v2(
        market_ids=market_ids,
        subaccount_id=subaccount_id,
        direction=direction,
        subaccount_total_positions=subaccount_total_positions,
        pagination=pagination,
    )
    print(json.dumps(positions, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)

    req := derivativeExchangePB.PositionsV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Skip:         skip,
        Limit:        limit,
    }

    res, err := exchangeClient.GetDerivativePositionsV2(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the positions fromYes
market_idstringMarketId of the position we want to fetch. Use this field for fetching from single marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes
start_timeint64The starting timestamp in UNIX milliseconds that the trades must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the trades must be equal or younger thanYes
market_idsstring arrayMarketIds of the markets we want to filter. Use this field for fetching from multiple marketsYes
directionstringfilter by direction of the positionYes
subaccount_total_positionsboolset to True to return subaccount total positionsYes
account_addressstringfilter by account addressYes

Response Parameters

Response Example:

{
   "positions":[
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0000007c60fab7a70c2ae0ebe437f3726b05e7eb000000000000000000000000",
         "direction":"short",
         "quantity":"0.087829315829932072",
         "entryPrice":"26453271.813315285838444221",
         "margin":"1156906.224974",
         "liquidationPrice":"38848511.946759",
         "markPrice":"35561999.99",
         "updatedAt":"1703793600379"
      },
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0000040f1111c5c3d2037940658ee770bb37e0a2000000000000000000000000",
         "direction":"long",
         "quantity":"0.000068500966722584",
         "entryPrice":"12293600",
         "margin":"440.389918",
         "liquidationPrice":"5984327.380009",
         "markPrice":"35561999.99",
         "updatedAt":"1703793600379"
      },
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x00509ed903475672121d6a1fb2c646eef4da6c44000000000000000000000000",
         "direction":"short",
         "quantity":"0.022151816236313182",
         "entryPrice":"15980281.340438795311756833",
         "margin":"172782.601001",
         "liquidationPrice":"23313932.022168",
         "markPrice":"35561999.99",
         "updatedAt":"1703793600379"
      },
   ],
   "paging":{
      "total":"1166",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "positions": [
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0000007c60fab7a70c2ae0ebe437f3726b05e7eb000000000000000000000000",
   "direction": "short",
   "quantity": "0.087829315829932072",
   "entry_price": "26453271.813315285838444221",
   "margin": "1156893.718782",
   "liquidation_price": "38848372.346758",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0000040f1111c5c3d2037940658ee770bb37e0a2000000000000000000000000",
   "direction": "long",
   "quantity": "0.000068500966722584",
   "entry_price": "12293600",
   "margin": "440.399672",
   "liquidation_price": "5984182.081895",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00509ed903475672121d6a1fb2c646eef4da6c44000000000000000000000000",
   "direction": "short",
   "quantity": "0.022151816236313182",
   "entry_price": "15980281.340438795311756833",
   "margin": "172779.44676",
   "liquidation_price": "23313792.422186",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00606da8ef76ca9c36616fa576d1c053bb0f7eb2000000000000000000000000",
   "direction": "short",
   "quantity": "0.041121486263975195",
   "entry_price": "15980281.340438795311756842",
   "margin": "320624.783065",
   "liquidation_price": "23311073.361647",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00cd2929594559000670af009e2f5ef15fefa6cf000000000000000000000000",
   "direction": "long",
   "quantity": "0.000050211853307914",
   "entry_price": "12293600",
   "margin": "322.774915",
   "liquidation_price": "5985039.457698",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00cf63fab44e827a4fb12142d6e0d8e82099701a000000000000000000000000",
   "direction": "long",
   "quantity": "0.000058171926973086",
   "entry_price": "12293600",
   "margin": "374.127106",
   "liquidation_price": "5981833.667338",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x010d36443f440708892e79dcbb6c1350c4c76662000000000000000000000000",
   "direction": "long",
   "quantity": "0.00008708028566368",
   "entry_price": "12293600",
   "margin": "559.983294",
   "liquidation_price": "5982596.709155",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0154fc01caf0e4c82b7ea6c9be719c260e940ef3000000000000000000000000",
   "direction": "short",
   "quantity": "0.005684726095134712",
   "entry_price": "19468749.344033524349659551",
   "margin": "54688.034814",
   "liquidation_price": "28518548.958621",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0198b3d3691bcc1718dcda4277bb27c68fd19a6f000000000000000000000000",
   "direction": "short",
   "quantity": "1.950155851194068459",
   "entry_price": "34111005.753742189227540816",
   "margin": "33194528.351493",
   "liquidation_price": "50129882.732098",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x021a86b9858f6e4150a724d444e94d10cb75c1b1000000000000000000000000",
   "direction": "short",
   "quantity": "0.077749303393590607",
   "entry_price": "15980281.340438795311756851",
   "margin": "605813.214778",
   "liquidation_price": "23306040.184987",
   "mark_price": "35294291.44",
   "updated_at": 1703790001819
  }
 ],
 "paging": {
  "total": 1153
 }
}
ParameterTypeDescription
positionsDerivativePositionV2 array
pagingPaging


DerivativePosition

ParameterTypeDescription
tickerstringTicker of the derivative market
market_idstringDerivative Market ID
subaccount_idstringThe subaccountId that the position belongs to
directionstringDirection of the position
quantitystringQuantity of the position
entry_pricestringPrice of the position
marginstringMargin of the position
liquidation_pricestringLiquidationPrice of the position
mark_pricestringMarkPrice of the position
updated_atint64Position updated timestamp in UNIX millis.
denomstringMarket quote denom
funding_laststringLast funding fees since position opened
funding_sumstringNet funding fees since position opened


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamPositions

Stream position updates for a specific market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def positions_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative positions updates ({exception})")


def stream_closed_processor():
    print("The derivative positions updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    market_ids = ["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    subaccount_ids = ["0xea98e3aa091a6676194df40ac089e40ab4604bf9000000000000000000000000"]

    task = asyncio.get_event_loop().create_task(
        client.listen_derivative_positions_v2_updates(
            callback=positions_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            market_ids=market_ids,
            subaccount_ids=subaccount_ids,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"

    req := derivativeExchangePB.StreamPositionsV2Request{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }
    stream, err := exchangeClient.StreamDerivativePositionsV2(ctx, &req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the positions fromYes
market_idstringBackward compat single market ID of position we want to streamYes
market_idsstring arrayList of market IDs of the positions we want to streamYes
subaccount_idsstring arraySubaccount ids of traders we want to get positionsYes
account_addressstringfilter by account addressYes

Response Parameters

Streaming Response Example:

{
  "position": {
    "ticker": "BTC/USDT PERP",
    "marketId": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
    "subaccountId": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
    "direction": "short",
    "quantity": "1.6321",
    "entryPrice": "40555935751.758890674529114982",
    "margin": "65283896141.678537523412631302",
    "liquidationPrice": "76719878206.648298",
    "markPrice": "40128736026.4094317665",
    "aggregateReduceOnlyQuantity": "0"
  },
  "timestamp": 1654246646000
}
{
  "position": {
    "ticker": "BTC/USDT PERP",
    "marketId": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
    "subaccountId": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
    "direction": "short",
    "quantity": "1.6321",
    "entryPrice": "40489113688.030524225816723708",
    "margin": "65069810777.851918748331744252",
    "liquidationPrice": "76531312698.56045",
    "markPrice": "40128736026.4094317665",
    "aggregateReduceOnlyQuantity": "0"
  },
  "timestamp": 1654246687000
}
{
 "position": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "direction": "short",
  "quantity": "0.4499",
  "entry_price": "40187334829.308997167725462798",
  "margin": "17648170480.844939276952101173",
  "liquidation_price": "75632579558.528471",
  "mark_price": "40128736026.4094317665",
  "aggregate_reduce_only_quantity": "0"
 },
 "timestamp": 1653039418000
}{
 "position": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "direction": "short",
  "quantity": "0.4499",
  "entry_price": "40415133266.89312760388339505",
  "margin": "17780087110.130349528796488556",
  "liquidation_price": "76128781140.582706",
  "mark_price": "40128736026.4094317665",
  "aggregate_reduce_only_quantity": "0"
 },
 "timestamp": 1653039464000
}{
 "position": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "direction": "short",
  "quantity": "0.4499",
  "entry_price": "40306914705.252255649316986606",
  "margin": "17654816331.908168110936068341",
  "liquidation_price": "75760533574.235878",
  "mark_price": "40128736026.4094317665",
  "aggregate_reduce_only_quantity": "0"
 },
 "timestamp": 1653039501000
}
ParameterTypeDescription
positionDerivativePositionV2Updated derivative Position
timestampint64Operation timestamp in UNIX millis.


DerivativePositionV2

ParameterTypeDescription
tickerstringTicker of the derivative market
market_idstringDerivative Market ID
subaccount_idstringThe subaccountId that the position belongs to
directionstringDirection of the position
quantitystringQuantity of the position
entry_pricestringPrice of the position
marginstringMargin of the position
liquidation_pricestringLiquidationPrice of the position
mark_pricestringMarkPrice of the position
updated_atint64Position updated timestamp in UNIX millis.
denomstringMarket quote denom
funding_laststringLast funding fees since position opened
funding_sumstringNet funding fees since position opened

LiquidablePositions

Gets all the liquidable positions

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    skip = 10
    limit = 3
    pagination = PaginationOption(skip=skip, limit=limit)
    positions = await client.fetch_derivative_liquidable_positions(
        market_id=market_id,
        pagination=pagination,
    )
    print(json.dumps(positions, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    //marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    skip := uint64(0)
    limit := int32(10)

    req := derivativeExchangePB.LiquidablePositionsRequest{
        //MarketId: marketId,
        Skip:  skip,
        Limit: limit,
    }

    res, err := exchangeClient.GetDerivativeLiquidablePositions(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarket ID to filter orders for specific marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes

Response Parameters

Streaming Response Example:

{
   "positions":[
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0a5d67f3616a9e7b53c301b508e9384c6321be47000000000000000000000000",
         "direction":"short",
         "quantity":"0.00966730135521481",
         "entryPrice":"15980281.340438795311756819",
         "margin":"75611.273514",
         "liquidationPrice":"23334925.188149",
         "markPrice":"39291123.99",
         "aggregateReduceOnlyQuantity":"0",
         "updatedAt":"1705525203015",
         "createdAt":"-62135596800000"
      },
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0c812012cf492aa422fb888e172fbd6e19df517b000000000000000000000000",
         "direction":"short",
         "quantity":"0.066327809378915175",
         "entryPrice":"16031762.538045163086357667",
         "margin":"520412.029703",
         "liquidationPrice":"23409630.791347",
         "markPrice":"39291123.99",
         "aggregateReduceOnlyQuantity":"0",
         "updatedAt":"1705525203015",
         "createdAt":"-62135596800000"
      },
      {
         "ticker":"INJ/USDT PERP",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0d750ad3404b6f23579706e44111e8dd774fd1fa000000000000000000000000",
         "direction":"short",
         "quantity":"0.000080602003464734",
         "entryPrice":"16031762.53804516308635803",
         "margin":"632.408209",
         "liquidationPrice":"23409630.592378",
         "markPrice":"39291123.99",
         "aggregateReduceOnlyQuantity":"0",
         "updatedAt":"1705525203015",
         "createdAt":"-62135596800000"
      }
   ]
}
{
 "positions": [
  {
   "ticker": "SOL/USDT PERP",
   "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
   "subaccount_id": "0x0ddbe7ea40134ae14ed6a5d104d8783c80663edb000000000000000000000000",
   "direction": "short",
   "quantity": "135965",
   "entry_price": "24074541.242231456624866694",
   "margin": "922840147876.471312471775929175",
   "liquidation_price": "29392264.1007154944460271",
   "mark_price": "102769181.99",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "SOL/USDT PERP",
   "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
   "subaccount_id": "0x16aef18dbaa341952f1af1795cb49960f68dfee3000000000000000000000000",
   "direction": "short",
   "quantity": "34.99",
   "entry_price": "25000000",
   "margin": "963925977.452838924992513061",
   "liquidation_price": "50046298.3288514793340278",
   "mark_price": "102769181.99",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "SOL/USDT PERP",
   "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "direction": "short",
   "quantity": "160",
   "entry_price": "24375243.283322806982741737",
   "margin": "3774845657.765183864053125849",
   "liquidation_price": "45683836.8041478153648322",
   "mark_price": "102769181.99",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "SOL/USDT PERP",
   "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
   "subaccount_id": "0xce4c01573f2a5f4db5d184b666ecfccb9313cc65000000000000000000000000",
   "direction": "short",
   "quantity": "8",
   "entry_price": "17700000",
   "margin": "141673770.450618846533455704",
   "liquidation_price": "33723067.9107879579206495",
   "mark_price": "102769181.99",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0000007c60fab7a70c2ae0ebe437f3726b05e7eb000000000000000000000000",
   "direction": "short",
   "quantity": "0.087829315829932072",
   "entry_price": "26453271.813315285838444221",
   "margin": "1154483.475338511428917818",
   "liquidation_price": "38821468.0751518485185464",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00509ed903475672121d6a1fb2c646eef4da6c44000000000000000000000000",
   "direction": "short",
   "quantity": "0.022151816236313182",
   "entry_price": "15980281.340438795311756833",
   "margin": "172410.019375666543049786",
   "liquidation_price": "23297442.3538099336017081",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x00606da8ef76ca9c36616fa576d1c053bb0f7eb2000000000000000000000000",
   "direction": "short",
   "quantity": "0.041121486263975195",
   "entry_price": "15980281.340438795311756842",
   "margin": "320053.045217395063737578",
   "liquidation_price": "23297442.3538099336017082",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x0154fc01caf0e4c82b7ea6c9be719c260e940ef3000000000000000000000000",
   "direction": "short",
   "quantity": "0.005684726095134712",
   "entry_price": "19468749.344033524349659551",
   "margin": "54563.593706555517738922",
   "liquidation_price": "28497087.7512237107551938",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x021a86b9858f6e4150a724d444e94d10cb75c1b1000000000000000000000000",
   "direction": "short",
   "quantity": "0.077749303393590607",
   "entry_price": "15980281.340438795311756851",
   "margin": "605131.369885566651321656",
   "liquidation_price": "23297442.3538099336017081",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  },
  {
   "ticker": "INJ/USDT PERP",
   "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
   "subaccount_id": "0x03ca8d57285836857dddf42cbb896448015246e7000000000000000000000000",
   "direction": "short",
   "quantity": "3.933956815705317214",
   "entry_price": "20294270.597312410912417203",
   "margin": "39442957.950528509629919537",
   "liquidation_price": "29726031.3451969744796065",
   "mark_price": "40421744.55",
   "aggregate_reduce_only_quantity": "0",
   "updated_at": 1703361600801,
   "created_at": -62135596800000
  }
 ]
}

ParameterTypeDescription
positionsDerivativePosition arrayList of derivative positions


DerivativePosition

ParameterTypeDescription
tickerstringTicker of the derivative market
market_idstringDerivative Market ID
subaccount_idstringThe subaccountId that the position belongs to
directionstringDirection of the position
quantitystringQuantity of the position
entry_pricestringPrice of the position
marginstringMargin of the position
liquidation_pricestringLiquidationPrice of the position
mark_pricestringMarkPrice of the position
aggregate_reduce_only_quantitystringAggregate Quantity of the Reduce Only orders associated with the position
updated_atint64Position updated timestamp in UNIX millis.
created_atint64Position created timestamp in UNIX millis.
funding_laststringLast funding fees since position opened
funding_sumstringNet funding fees since position opened

OrderbooksV2

Get an orderbook snapshot for one or more derivative markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    market_ids = [
        "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff",
    ]
    depth = 1
    orderbooks = await client.fetch_derivative_orderbooks_v2(market_ids=market_ids, depth=depth)
    print(json.dumps(orderbooks, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}
    depth := int32(10)
    res, err := exchangeClient.GetDerivativeOrderbooksV2(ctx, marketIds, depth)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idsstring arrayMarketIds of the marketsYes
depthint32Depth of the orderbookYes

Response Parameters

Response Example:

{
   "orderbooks":[
      {
         "marketId":"0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff",
         "orderbook":{
            "sequence":"4099",
            "timestamp":"1681978300931",
            "buys":[

            ],
            "sells":[

            ]
         }
      },
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "orderbook":{
            "buys":[
               {
                  "price":"13400000",
                  "quantity":"683.3032",
                  "timestamp":"1702002966962"
               },
               {
                  "price":"13366500",
                  "quantity":"108438.1403",
                  "timestamp":"1702002966962"
               }
            ],
            "sells":[
               {
                  "price":"18390200",
                  "quantity":"78815.8042",
                  "timestamp":"1702002966962"
               }
            ],
            "sequence":"1919116",
            "timestamp":"1702003451726"
         }
      }
   ]
}
{
 "orderbooks": [
  {
   "market_id": "0x2e94326a421c3f66c15a3b663c7b1ab7fb6a5298b3a57759ecf07f0036793fc9",
   "orderbook": {
    "buys": [
     {
      "price": "25100000000",
      "quantity": "0.46",
      "timestamp": 1701558751779
     },
     {
      "price": "25000000000",
      "quantity": "99.51",
      "timestamp": 1702216325243
     },
     {
      "price": "24192180000",
      "quantity": "0.05",
      "timestamp": 1681812143213
     },
     {
      "price": "24000180000",
      "quantity": "3",
      "timestamp": 1681811751044
     },
     {
      "price": "21295940000",
      "quantity": "1",
      "timestamp": 1681811119316
     },
     {
      "price": "20160150000",
      "quantity": "1",
      "timestamp": 1681812143213
     },
     {
      "price": "20000000000",
      "quantity": "200",
      "timestamp": 1699699685300
     },
     {
      "price": "19894890000",
      "quantity": "1",
      "timestamp": 1681811751044
     },
     {
      "price": "19764860000",
      "quantity": "4",
      "timestamp": 1681810803871
     },
     {
      "price": "18900140000",
      "quantity": "3",
      "timestamp": 1681812143213
     },
     {
      "price": "18439160000",
      "quantity": "10",
      "timestamp": 1681812143213
     },
     {
      "price": "15000000000",
      "quantity": "400",
      "timestamp": 1699699705568
     },
     {
      "price": "10000000000",
      "quantity": "1000",
      "timestamp": 1699699744160
     }
    ],
    "sells": [
     {
      "price": "50501180000",
      "quantity": "4",
      "timestamp": 1681811955314
     },
     {
      "price": "50198770000",
      "quantity": "2.48",
      "timestamp": 1681811955314
     }
    ],
    "timestamp": -62135596800000
   }
  }
 ]
}

ParameterTypeDescription
orderbooksSingleDerivativeLimitOrderbookV2 array

SingleDerivativeLimitOrderbookV2

ParameterTypeDescription
market_idstringmarket's ID
orderbookDerivativeLimitOrderbookV2Orderbook of the market


DerivativeLimitOrderbookV2

ParameterTypeDescription
buysPriceLevel arrayArray of price levels for buys
sellsPriceLevel arrayArray of price levels for sells
sequenceuint64market orderbook sequence
timestampint64Last update timestamp in UNIX millis.
heightint64Block height at which the orderbook was last updated.


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.


StreamOrderbookV2

Stream orderbook snapshot updates for one or more derivative markets

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def orderbook_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative orderbook snapshots ({exception})")


def stream_closed_processor():
    print("The derivative orderbook snapshots stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]

    task = asyncio.get_event_loop().create_task(
        client.listen_derivative_orderbook_snapshots(
            market_ids=market_ids,
            callback=orderbook_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("devnet-1", "")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}
    stream, err := exchangeClient.StreamDerivativeOrderbookV2(ctx, marketIds)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            fmt.Println(res.MarketId, len(res.Orderbook.Sells), len(res.Orderbook.Buys))
        }
    }
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for orderbook streaming, empty means 'ALL' derivative marketsYes

Response Parameters

Streaming Response Example:

{
   "orderbook":{
      "buys":[
         {
            "price":"13400000",
            "quantity":"683.3032",
            "timestamp":"1702002966962"
         },
         ...
      ],
      "sells":[
         {
            "price":"18390200",
            "quantity":"78815.8042",
            "timestamp":"1702002966962"
         },
         ...
      ],
      "sequence":"1919121",
      "timestamp":"1702003627697"
   },
   "operationType":"update",
   "timestamp":"1702003629000",
   "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
}

ParameterTypeDescription
orderbookDerivativeLimitOrderbookV2Orderbook of a Derivative Market
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.
market_idstringMarketId of the market's orderbook


DerivativeLimitOrderbookV2

ParameterTypeDescription
buysPriceLevel arrayArray of price levels for buys
sellsPriceLevel arrayArray of price levels for sells
sequenceuint64market orderbook sequence
timestampint64Last update timestamp in UNIX millis.
heightint64Block height at which the orderbook was last updated.


PriceLevel

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
timestampint64Price level last updated timestamp in UNIX millis.

StreamOrderbookUpdate

Stream incremental orderbook updates for one or more derivative markets. This stream should be started prior to obtaining orderbook snapshots so that no incremental updates are omitted between obtaining a snapshot and starting the update stream.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from decimal import Decimal
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to derivative orderbook updates ({exception})")


def stream_closed_processor():
    print("The derivative orderbook updates stream has been closed")


class PriceLevel:
    def __init__(self, price: Decimal, quantity: Decimal, timestamp: int):
        self.price = price
        self.quantity = quantity
        self.timestamp = timestamp

    def __str__(self) -> str:
        return "price: {} | quantity: {} | timestamp: {}".format(self.price, self.quantity, self.timestamp)


class Orderbook:
    def __init__(self, market_id: str):
        self.market_id = market_id
        self.sequence = -1
        self.levels = {"buys": {}, "sells": {}}


async def load_orderbook_snapshot(client: IndexerClient, orderbook: Orderbook):
    # load the snapshot
    res = await client.fetch_derivative_orderbooks_v2(market_ids=[orderbook.market_id], depth=1)
    for snapshot in res["orderbooks"]:
        if snapshot["marketId"] != orderbook.market_id:
            raise Exception("unexpected snapshot")

        orderbook.sequence = int(snapshot["orderbook"]["sequence"])

        for buy in snapshot["orderbook"]["buys"]:
            orderbook.levels["buys"][buy["price"]] = PriceLevel(
                price=Decimal(buy["price"]),
                quantity=Decimal(buy["quantity"]),
                timestamp=int(buy["timestamp"]),
            )
        for sell in snapshot["orderbook"]["sells"]:
            orderbook.levels["sells"][sell["price"]] = PriceLevel(
                price=Decimal(sell["price"]),
                quantity=Decimal(sell["quantity"]),
                timestamp=int(sell["timestamp"]),
            )


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    indexer_client = IndexerClient(network)

    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    orderbook = Orderbook(market_id=market_id)
    updates_queue = asyncio.Queue()
    tasks = []

    async def queue_event(event: Dict[str, Any]):
        await updates_queue.put(event)

    # start getting price levels updates
    task = asyncio.get_event_loop().create_task(
        indexer_client.listen_derivative_orderbook_updates(
            market_ids=[market_id],
            callback=queue_event,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )
    tasks.append(task)

    # load the snapshot once we are already receiving updates, so we don't miss any
    await load_orderbook_snapshot(client=indexer_client, orderbook=orderbook)

    task = asyncio.get_event_loop().create_task(
        apply_orderbook_update(orderbook=orderbook, updates_queue=updates_queue)
    )
    tasks.append(task)

    await asyncio.sleep(delay=60)
    for task in tasks:
        task.cancel()


async def apply_orderbook_update(orderbook: Orderbook, updates_queue: asyncio.Queue):
    while True:
        updates = await updates_queue.get()
        update = updates["orderbookLevelUpdates"]

        # discard updates older than the snapshot
        if int(update["sequence"]) <= orderbook.sequence:
            return

        print(" * * * * * * * * * * * * * * * * * * *")

        # ensure we have not missed any update
        if int(update["sequence"]) > (orderbook.sequence + 1):
            raise Exception(
                "missing orderbook update events from stream, must restart: {} vs {}".format(
                    update["sequence"], (orderbook.sequence + 1)
                )
            )

        print("updating orderbook with updates at sequence {}".format(update["sequence"]))

        # update orderbook
        orderbook.sequence = int(update["sequence"])
        for direction, levels in {"buys": update["buys"], "sells": update["sells"]}.items():
            for level in levels:
                if level["isActive"]:
                    # upsert level
                    orderbook.levels[direction][level["price"]] = PriceLevel(
                        price=Decimal(level["price"]), quantity=Decimal(level["quantity"]), timestamp=level["timestamp"]
                    )
                else:
                    if level["price"] in orderbook.levels[direction]:
                        del orderbook.levels[direction][level["price"]]

        # sort the level numerically
        buys = sorted(orderbook.levels["buys"].values(), key=lambda x: x.price, reverse=True)
        sells = sorted(orderbook.levels["sells"].values(), key=lambda x: x.price, reverse=True)

        # lowest sell price should be higher than the highest buy price
        if len(buys) > 0 and len(sells) > 0:
            highest_buy = buys[0].price
            lowest_sell = sells[-1].price
            print("Max buy: {} - Min sell: {}".format(highest_buy, lowest_sell))
            if highest_buy >= lowest_sell:
                raise Exception("crossed orderbook, must restart")

        # for the example, print the list of buys and sells orders.
        print("sells")
        for k in sells:
            print(k)
        print("=========")
        print("buys")
        for k in buys:
            print(k)
        print("====================================")


if __name__ == "__main__":
    asyncio.run(main())
package main

import (
    "context"
    "fmt"
    "sort"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
    "github.com/shopspring/decimal"
)

type MapOrderbook struct {
    Sequence uint64
    Levels   map[bool]map[string]*derivativeExchangePB.PriceLevel
}

func main() {
    network := common.LoadNetwork("devnet-1", "")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        fmt.Println(err)
        panic(err)
    }

    ctx := context.Background()
    marketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}
    stream, err := exchangeClient.StreamDerivativeOrderbookUpdate(ctx, marketIds)
    if err != nil {
        fmt.Println(err)
        panic(err)
    }

    updatesCh := make(chan *derivativeExchangePB.OrderbookLevelUpdates, 100000)
    receiving := make(chan struct{})
    var receivingClosed bool

    // stream orderbook price levels
    go func() {
        defer close(updatesCh)
        for {
            select {
            case <-ctx.Done():
                return
            default:
                res, err := stream.Recv()
                if err != nil {
                    fmt.Println(err)
                    return
                }
                u := res.OrderbookLevelUpdates
                if !receivingClosed {
                    fmt.Println("receiving updates from stream")
                    close(receiving)
                    receivingClosed = true
                }
                updatesCh <- u
            }
        }
    }()

    // ensure we are receiving updates before getting orderbook
    fmt.Println("waiting for streaming updates")
    <-receiving

    // prepare orderbooks map
    orderbooks := map[string]*MapOrderbook{}
    depth := int32(0)
    res, err := exchangeClient.GetDerivativeOrderbooksV2(ctx, marketIds, depth)
    if err != nil {
        panic(err)
    }
    for _, ob := range res.Orderbooks {
        // init inner maps not ready
        _, ok := orderbooks[ob.MarketId]
        if !ok {
            orderbook := &MapOrderbook{
                Sequence: ob.Orderbook.Sequence,
                Levels:   make(map[bool]map[string]*derivativeExchangePB.PriceLevel),
            }
            orderbook.Levels[true] = make(map[string]*derivativeExchangePB.PriceLevel)
            orderbook.Levels[false] = make(map[string]*derivativeExchangePB.PriceLevel)
            orderbooks[ob.MarketId] = orderbook
        }

        for _, level := range ob.Orderbook.Buys {
            orderbooks[ob.MarketId].Levels[true][level.Price] = level
        }
        for _, level := range ob.Orderbook.Sells {
            orderbooks[ob.MarketId].Levels[false][level.Price] = level
        }
    }

    // continuously consume level updates and maintain orderbook
    skippedPastEvents := false
    for {
        updates, ok := <-updatesCh
        if !ok {
            fmt.Println("updates channel closed, must restart")
            return // closed
        }

        // validate orderbook
        orderbook, ok := orderbooks[updates.MarketId]
        if !ok {
            panic("level update doesn't belong to any orderbooks")
        }

        // skip if update sequence <= orderbook sequence until it's ready to consume
        if !skippedPastEvents {
            if orderbook.Sequence >= updates.Sequence {
                continue
            }
            skippedPastEvents = true
        }

        // panic if update sequence > orderbook sequence + 1
        if updates.Sequence > orderbook.Sequence+1 {
            fmt.Printf("skipping levels: update sequence %d vs orderbook sequence %d\n", updates.Sequence, orderbook.Sequence)
            panic("missing orderbook update events from stream, must restart")
        }

        // update orderbook map
        orderbook.Sequence = updates.Sequence
        for isBuy, update := range map[bool][]*derivativeExchangePB.PriceLevelUpdate{
            true:  updates.Buys,
            false: updates.Sells,
        } {
            for _, level := range update {
                if level.IsActive {
                    // upsert
                    orderbook.Levels[isBuy][level.Price] = &derivativeExchangePB.PriceLevel{
                        Price:     level.Price,
                        Quantity:  level.Quantity,
                        Timestamp: level.Timestamp,
                    }
                } else {
                    // remove inactive level
                    delete(orderbook.Levels[isBuy], level.Price)
                }
            }
        }

        // construct orderbook arrays
        sells, buys := maintainOrderbook(orderbook.Levels)
        fmt.Println("after", orderbook.Sequence, len(sells), len(buys))

        if len(sells) > 0 && len(buys) > 0 {
            // assert orderbook
            topBuyPrice := decimal.RequireFromString(buys[0].Price)
            lowestSellPrice := decimal.RequireFromString(sells[0].Price)
            if topBuyPrice.GreaterThanOrEqual(lowestSellPrice) {
                panic(fmt.Errorf("crossed orderbook, must restart: buy %s >= %s sell", topBuyPrice, lowestSellPrice))
            }
        }

        res, _ = exchangeClient.GetDerivativeOrderbooksV2(ctx, marketIds, depth)
        fmt.Println("query", res.Orderbooks[0].Orderbook.Sequence, len(res.Orderbooks[0].Orderbook.Sells), len(res.Orderbooks[0].Orderbook.Buys))

        // print orderbook
        fmt.Println(" [SELLS] ========")
        for _, s := range sells {
            fmt.Println(s)
        }
        fmt.Println(" [BUYS] ========")
        for _, b := range buys {
            fmt.Println(b)
        }
        fmt.Println("=======================================================")
    }
}

func maintainOrderbook(orderbook map[bool]map[string]*derivativeExchangePB.PriceLevel) (buys, sells []*derivativeExchangePB.PriceLevel) {
    for _, v := range orderbook[false] {
        sells = append(sells, v)
    }
    for _, v := range orderbook[true] {
        buys = append(buys, v)
    }

    sort.Slice(sells, func(i, j int) bool {
        return decimal.RequireFromString(sells[i].Price).LessThan(decimal.RequireFromString(sells[j].Price))
    })
    sort.Slice(buys, func(i, j int) bool {
        return decimal.RequireFromString(buys[i].Price).GreaterThan(decimal.RequireFromString(buys[j].Price))
    })

    return sells, buys
}
ParameterTypeDescriptionRequired
market_idsstring arrayList of market IDs for orderbook streaming, empty means 'ALL' derivative marketsYes

Response Parameters

Streaming Response Example:

* * * * * * * * * * * * * * * * * * *
updating orderbook with updates at sequence 589
Max buy: 10000000000 - Min sell: 50000000000
sells
price: 101000000000 | quantity: 0.0007 | timestamp: 1675291761230
price: 100000000000 | quantity: 0.0037 | timestamp: 1675291786816
price: 70000000000 | quantity: 0.0001 | timestamp: 1671787246665
price: 65111000000 | quantity: 0.0449 | timestamp: 1675291786816
price: 50000000000 | quantity: 0.1 | timestamp: 1676326399734
=========
buys
price: 10000000000 | quantity: 0.0004 | timestamp: 1676622014694
price: 5000000000 | quantity: 0.0097 | timestamp: 1676383776468
price: 1000000000 | quantity: 0.0013 | timestamp: 1676622213616
====================================
* * * * * * * * * * * * * * * * * * *
updating orderbook with updates at sequence 590
Max buy: 10000000000 - Min sell: 50000000000
sells
price: 101000000000 | quantity: 0.0007 | timestamp: 1675291761230
price: 100000000000 | quantity: 0.0037 | timestamp: 1675291786816
price: 70000000000 | quantity: 0.0001 | timestamp: 1671787246665
price: 65111000000 | quantity: 0.0449 | timestamp: 1675291786816
price: 50000000000 | quantity: 0.1 | timestamp: 1676326399734
=========
buys
price: 10000000000 | quantity: 0.0004 | timestamp: 1676622014694
price: 5000000000 | quantity: 0.0097 | timestamp: 1676383776468
price: 1000000000 | quantity: 0.0014 | timestamp: 1676622220695
====================================

ParameterTypeDescription
orderbook_level_updatesOrderbookLevelUpdatesOrderbook level updates of a Derivative Market
operation_typestringOrder update type
timestampint64Operation timestamp in UNIX millis.
market_idstringMarketId of the market's orderbook


OrderbookLevelUpdates

ParameterTypeDescription
market_idstringmarket's ID
sequenceuint64orderbook update sequence
buysPriceLevelUpdate arraybuy levels
sellsPriceLevelUpdate arraysell levels
updated_atint64updates timestamp


PriceLevelUpdate

ParameterTypeDescription
pricestringPrice number of the price level.
quantitystringQuantity of the price level.
is_activeboolPrice level status.
timestampint64Price level last updated timestamp in UNIX millis.

SubaccountOrdersList

Get the derivative orders of a specific subaccount.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    skip = 1
    limit = 2
    pagination = PaginationOption(skip=skip, limit=limit)
    orders = await client.fetch_derivative_subaccount_orders_list(
        subaccount_id=subaccount_id, market_id=market_id, pagination=pagination
    )
    print(json.dumps(orders, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)

    req := derivativeExchangePB.SubaccountOrdersListRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Skip:         skip,
        Limit:        limit,
    }

    res, err := exchangeClient.GetSubaccountDerivativeOrdersList(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringsubaccount ID to filter orders for specific subaccountYes
market_idstringMarket ID to filter orders for specific marketYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes

Response Parameters

Response Example:

{
   "orders":[
      {
         "orderHash":"0x0a3db65baf5d253b10e6f42e606a95503f72e920176b94e31ee802acde53ec84",
         "orderSide":"buy",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "margin":"10107500",
         "price":"10107500",
         "quantity":"1",
         "unfilledQuantity":"1",
         "triggerPrice":"0",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "state":"booked",
         "createdAt":"1699794939298",
         "updatedAt":"1699794939298",
         "orderType":"buy",
         "txHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
         "isReduceOnly":false,
         "orderNumber":"0",
         "isConditional":false,
         "triggerAt":"0",
         "placedOrderHash":"",
         "executionType":"",
         "cid":""
      }
   ],
   "paging":{
      "total":"2",
      "from":2,
      "to":2,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "orders": [
  {
   "order_hash": "0x8af0b619d31acda68d04b8a14e1488eee3c28792ded6fbb7393a489a4a8dbb58",
   "order_side": "buy",
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "margin": "36000000000",
   "price": "36000000000",
   "quantity": "1",
   "unfilled_quantity": "1",
   "trigger_price": "0",
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
   "state": "booked",
   "created_at": 1652792829016,
   "updated_at": 1652792829016
  },
  {
   "order_hash": "0x457aadf92c40e5b2c4c7e6c3176872e72f36e11e7d4e718222b94a08a35ab071",
   "order_side": "buy",
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "margin": "155000000",
   "price": "31000000000",
   "quantity": "0.01",
   "unfilled_quantity": "0.01",
   "trigger_price": "0",
   "fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "state": "booked",
   "created_at": 1652701438661,
   "updated_at": 1652701438661
  }
 ]
}
ParameterTypeDescription
ordersDerivativeLimitOrder arrayList of derivative orders
pagingPaging


DerivativeLimitOrder

ParameterTypeDescription
order_hashstringHash of the order
order_sidestringThe side of the order
market_idstringDerivative Market ID
subaccount_idstringThe subaccountId that this order belongs to
is_reduce_onlyboolTrue if the order is a reduce-only order
marginstringMargin of the order
pricestringPrice of the order
quantitystringQuantity of the order
unfilled_quantitystringThe amount of the quantity remaining unfilled
trigger_pricestringTrigger price is the trigger price used by stop/take orders
fee_recipientstringFee recipient address
statestringOrder state
created_atint64Order committed timestamp in UNIX millis.
updated_atint64Order updated timestamp in UNIX millis.
order_numberint64Order number of subaccount
order_typestringOrder type
is_conditionalboolOrder type
trigger_atuint64Trigger timestamp, only exists for conditional orders
placed_order_hashstringOrderHash of order that is triggered by this conditional order
execution_typestringExecution type of conditional order
tx_hashstringTransaction Hash where order is created. Not all orders have this field
cidstringCustom client order ID


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

SubaccountTradesList

Get the derivative trades for a specific subaccount.

IP rate limit group: indexer

*Trade execution types

  1. "market" for market orders
  2. "limitFill" for a resting limit order getting filled by a market order
  3. "limitMatchRestingOrder" for a resting limit order getting matched with another new limit order
  4. "limitMatchNewOrder" for a new limit order getting matched immediately

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    execution_type = "market"
    direction = "sell"
    skip = 10
    limit = 2
    pagination = PaginationOption(skip=skip, limit=limit)
    trades = await client.fetch_derivative_subaccount_trades_list(
        subaccount_id=subaccount_id,
        market_id=market_id,
        execution_type=execution_type,
        direction=direction,
        pagination=pagination,
    )
    print(json.dumps(trades, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    skip := uint64(0)
    limit := int32(10)

    req := derivativeExchangePB.SubaccountTradesListRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
        Skip:         skip,
        Limit:        limit,
    }

    res, err := exchangeClient.GetSubaccountDerivativeTradesList(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the trades fromYes
market_idstringFilter trades by market IDYes
execution_typestringFilter by execution type of tradesYes
directionstringFilter by direction tradesYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returnedYes

Response Parameters

Response Example:

{
   "trades":[
      {
         "orderHash":"0x19da3923ce9141a9cfdb644d4ac72e0650e0e938c244ca9a55d100011fedc25e",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "tradeExecutionType":"market",
         "positionDelta":{
            "tradeDirection":"sell",
            "executionPrice":"16945600",
            "executionQuantity":"4",
            "executionMargin":"67443600"
         },
         "payout":"0",
         "fee":"47447.68",
         "executedAt":"1699795360671",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "tradeId":"18321280_201_0",
         "executionSide":"taker",
         "isLiquidation":false,
         "cid":""
      },
      {
         "orderHash":"0xe9c8a307d353d09f11f616c9b3ee7be890512ceca9da7d8e3a62411607afc9af",
         "subaccountId":"0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "tradeExecutionType":"limitFill",
         "positionDelta":{
            "tradeDirection":"buy",
            "executionPrice":"16945600",
            "executionQuantity":"4",
            "executionMargin":"67782400"
         },
         "payout":"68143885.714285714285714287",
         "fee":"-4066.944",
         "executedAt":"1699795360671",
         "feeRecipient":"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
         "tradeId":"18321280_202_0",
         "executionSide":"maker",
         "isLiquidation":false,
         "cid":""
      }
   ]
}
{
 "trades": [
  {
   "order_hash": "0xb131b0a095a8e72ad2fe0897001dbf6277f7ee9b8da868a9eedf9814e181da82",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "trade_execution_type": "market",
   "position_delta": {
    "trade_direction": "buy",
    "execution_price": "42710340000",
    "execution_quantity": "0.15",
    "execution_margin": "0"
   },
   "payout": "1105814219.16406340684465003",
   "fee": "7687861.2",
   "executed_at": 1652793510591,
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8"
  },
  {
   "order_hash": "0xa049d9b5950b5a4a3a1560503ab22e191ad3f03d211629359cbdc844e8a05d91",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "trade_execution_type": "market",
   "position_delta": {
    "trade_direction": "sell",
    "execution_price": "38221371000",
    "execution_quantity": "1",
    "execution_margin": "37732000000"
   },
   "payout": "0",
   "fee": "45865645.2",
   "executed_at": 1651491831613,
   "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8"
  }
 ]
}

ParameterTypeDescription
tradesDerivativeTrade arrayList of derivative market trades


DerivativeTrade

ParameterTypeDescription
order_hashstringOrder hash.
subaccount_idstringThe subaccountId that executed the trade
market_idstringThe ID of the market that this trade is in
trade_execution_typestringThe execution type of the trade
is_liquidationboolTrue if the trade is a liquidation
position_deltaPositionDeltaPosition Delta from the trade
payoutstringThe payout associated with the trade
feestringThe fee associated with the trade
executed_atint64Timestamp of trade execution in UNIX millis
fee_recipientstringFee recipient address
trade_idstringA unique string that helps differentiate between trades
execution_sidestringTrade's execution side, marker/taker
cidstringCustom client order ID
pnlstringProfit and loss of the trade


PositionDelta

ParameterTypeDescription
trade_directionstringThe direction the trade
execution_pricestringExecution Price of the trade.
execution_quantitystringExecution Quantity of the trade.
execution_marginstringExecution Margin of the trade.

FundingPayments

Get the funding payments for a subaccount.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_ids = ["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    skip = 0
    limit = 3
    end_time = 1676426400125
    pagination = PaginationOption(skip=skip, limit=limit, end_time=end_time)
    funding_payments = await client.fetch_funding_payments(
        market_ids=market_ids, subaccount_id=subaccount_id, pagination=pagination
    )
    print(json.dumps(funding_payments, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccountId := "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"

    req := derivativeExchangePB.FundingPaymentsRequest{
        MarketId:     marketId,
        SubaccountId: subaccountId,
    }

    res, err := exchangeClient.GetDerivativeFundingPayments(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
subaccount_idstringSubaccountId of the trader we want to get the positions fromYes
market_idstringMarketIds of the funding payment we want to fetch. Using this for only one market id. This field is prioritizedYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
end_timeint64Upper bound of funding payment updatedAtYes
market_idsstring arrayFilter by market ids. Using this field for fetching funding payments from multiple market idsYes

Response Parameters

Response Example:

{
   "payments":[
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x00509ed903475672121d6a1fb2c646eef4da6c44000000000000000000000000",
         "amount":"1.628605",
         "timestamp":"1702000801389"
      },
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0000040f1111c5c3d2037940658ee770bb37e0a2000000000000000000000000",
         "amount":"-0.005036",
         "timestamp":"1702000801389"
      },
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "subaccountId":"0x0000007c60fab7a70c2ae0ebe437f3726b05e7eb000000000000000000000000",
         "amount":"-0.006378",
         "timestamp":"1702000801389"
      }
   ],
   "paging":{
      "total":"1000",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "payments": [
  {
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "amount": "9904406.085347",
   "timestamp": 1652511601035
  },
  {
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "amount": "5811676.298013",
   "timestamp": 1652508000824
  },
  {
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
   "amount": "6834858.744846",
   "timestamp": 1652504401219
  }
 ]
}

ParameterTypeDescription
paymentsFundingPayment arrayList of funding payments
pagingPaging


FundingPayment

ParameterTypeDescription
market_idstringDerivative Market ID
subaccount_idstringThe subaccountId that the position belongs to
amountstringAmount of the funding payment
timestampint64Timestamp of funding payment in UNIX millis


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

FundingRates

Get the historical funding rates for a specific market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    skip = 0
    limit = 3
    end_time = 1675717201465
    pagination = PaginationOption(skip=skip, limit=limit, end_time=end_time)
    funding_rates = await client.fetch_funding_rates(market_id=market_id, pagination=pagination)
    print(json.dumps(funding_rates, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    derivativeExchangePB "github.com/InjectiveLabs/sdk-go/exchange/derivative_exchange_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"

    req := derivativeExchangePB.FundingRatesRequest{
        MarketId: marketId,
    }

    res, err := exchangeClient.GetDerivativeFundingRates(ctx, &req)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringMarketId of the position we want to fetchYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes
end_timeint64Upper bound of funding timestampYes

Response Parameters

Response Example:

{
   "fundingRates":[
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "rate":"0.000004",
         "timestamp":"1702000801389"
      },
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "rate":"0.000004",
         "timestamp":"1701997200816"
      },
      {
         "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
         "rate":"0.000004",
         "timestamp":"1701993600737"
      }
   ],
   "paging":{
      "total":"5571",
      "from":0,
      "to":0,
      "countBySubaccount":"0",
      "next":[

      ]
   }
}
{
 "funding_rates": [
  {
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "rate": "0.000142",
   "timestamp": 1652508000824
  },
  {
   "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
   "rate": "0.000167",
   "timestamp": 1652504401219
  }
 ]
}
ParameterTypeDescription
funding_ratesFundingRate arrayList of funding rates
pagingPaging


FundingRate

ParameterTypeDescription
market_idstringDerivative Market ID
ratestringValue of the funding rate
timestampint64Timestamp of funding rate in UNIX millis


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

BinaryOptionsMarket

Get details of a single binary options market.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_id = "0x175513943b8677368d138e57bcd6bef53170a0da192e7eaa8c2cd4509b54f8db"
    market = await client.fetch_binary_options_market(market_id=market_id)
    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
market_idstringMarketId of the market we want to fetchYes

Response Parameters

Response Example:

{
  "market": {
    "marketId": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
    "marketStatus": "active",
    "ticker": "INJ/USDT BO",
    "oracleSymbol": "inj",
    "oracleProvider": "BANDIBC",
    "oracleType": "provider",
    "oracleScaleFactor": 6,
    "expirationTimestamp": "2343242423",
    "settlementTimestamp": "2342342323",
    "quoteDenom": "USDT",
    "quoteTokenMeta": {
      "name": "Tether",
      "address": '0xdAC17F958D2ee523a2206206994597C13D831ec7',
      "symbol": "USDT",
      "logo": "https://static.alchemyapi.io/images/assets/7278.png",
      "decimals": 18;
      "updatedAt": "1650978921846"
    },
    "makerFeeRate": "0.001",
    "takerFeeRate": "0.002",
    "serviceProviderFee": "0.4",
    "minPriceTickSize": "0.000000000000001",
    "minQuantityTickSize": "1000000000000000",
    "settlementPrice": "1",
    "min_notional": "0"
  }
}

ParameterTypeDescription
marketBinaryOptionsMarketInfoInfo about particular derivative market


BinaryOptionsMarketInfo

ParameterTypeDescription
market_idstringBinary Options Market ID is crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleSymbol + oracleProvider)))
market_statusstringThe status of the market
tickerstringA name of the binary options market.
oracle_symbolstringOracle symbol
oracle_providerstringOracle provider
oracle_typestringOracle Type
oracle_scale_factoruint32OracleScaleFactor
expiration_timestampint64Defines the expiration time for the market in UNIX seconds.
settlement_timestampint64Defines the settlement time for the market in UNIX seconds.
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
settlement_pricestringDefines the settlement price of the market
min_notionalstringDefines the minimum notional value for the market


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

BinaryOptionsMarkets

Get a list of binary options markets.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    market_status = "active"
    quote_denom = "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7"
    market = await client.fetch_binary_options_markets(market_status=market_status, quote_denom=quote_denom)

    print(json.dumps(market, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
market_statusstringFilter by market statusYes
quote_denomstringFilter by the Coin denomination of the quote currencyYes
skipuint64Skip will skip the first n item from the resultYes
limitint32Limit is used to specify the maximum number of items to be returned.Yes

Response Parameters

Response Example:

{
   "markets":[
      {
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "marketStatus":"active",
         "ticker":"INJ/USDT BO",
         "oracleSymbol":"inj",
         "oracleProvider":"BANDIBC",
         "oracleType":"provider",
         "oracleScaleFactor":6,
         "expirationTimestamp":"2343242423",
         "settlementTimestamp":"2342342323",
         "quoteDenom":"USDT",
         "quoteTokenMeta":{
            "name":"Tether",
            "address":"0xdAC17F958D2ee523a2206206994597C13D831ec7",
            "symbol":"USDT",
            "logo":"https://static.alchemyapi.io/images/assets/7278.png",
            "decimals":18;"updatedAt":"1650978921846"
         },
         "makerFeeRate":"0.001",
         "takerFeeRate":"0.002",
         "serviceProviderFee":"0.4",
         "minPriceTickSize":"0.000000000000001",
         "minQuantityTickSize":"1000000000000000",
         "settlementPrice":"1",
         "min_notional":"0",
      }
   ],
   "paging":{
      "total":"5"
      "from":"1"
      "to":"3"
      "countBySubaccount":"4"
   }
}

ParameterTypeDescription
marketsBinaryOptionsMarketInfo arrayBinary Options Markets list
pagingPaging


BinaryOptionsMarketInfo

ParameterTypeDescription
market_idstringBinary Options Market ID is crypto.Keccak256Hash([]byte((oracleType.String() + ticker + quoteDenom + oracleSymbol + oracleProvider)))
market_statusstringThe status of the market
tickerstringA name of the binary options market.
oracle_symbolstringOracle symbol
oracle_providerstringOracle provider
oracle_typestringOracle Type
oracle_scale_factoruint32OracleScaleFactor
expiration_timestampint64Defines the expiration time for the market in UNIX seconds.
settlement_timestampint64Defines the settlement time for the market in UNIX seconds.
quote_denomstringCoin denom used for the quote asset.
quote_token_metaTokenMetaToken metadata for quote asset
maker_fee_ratestringDefines the fee percentage makers pay when trading (in quote asset)
taker_fee_ratestringDefines the fee percentage takers pay when trading (in quote asset)
service_provider_feestringPercentage of the transaction fee shared with the service provider
min_price_tick_sizestringDefines the minimum required tick size for the order's price
min_quantity_tick_sizestringDefines the minimum required tick size for the order's quantity
settlement_pricestringDefines the settlement price of the market
min_notionalstringDefines the minimum notional value for the market


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

- InjectiveOracleRPC

InjectiveOracleRPC defines the gRPC API of the Exchange Oracle provider.

OracleList

Get a list of all oracles.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    oracle_list = await client.fetch_oracle_list()
    print(json.dumps(oracle_list, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("mainnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    res, err := exchangeClient.GetOracleList(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

Response Parameters

Response Example:

{
   "oracles":[
      {
         "symbol":"BTC",
         "oracleType":"bandibc",
         "price":"16835.93",
         "baseSymbol":"",
         "quoteSymbol":""
      },
      {
         "symbol":"ETH",
         "oracleType":"bandibc",
         "price":"1251.335",
         "baseSymbol":"",
         "quoteSymbol":""
      },
      {
         "symbol":"INJ",
         "oracleType":"bandibc",
         "price":"1.368087992",
         "baseSymbol":"",
         "quoteSymbol":""
      },
      {
         "symbol":"USDT",
         "oracleType":"bandibc",
         "price":"0.999785552",
         "baseSymbol":"",
         "quoteSymbol":""
      },
      {
         "symbol":"FRNT/USDT",
         "baseSymbol":"FRNT",
         "quoteSymbol":"USDT",
         "oracleType":"pricefeed",
         "price":"0.5"
      },
      {
         "symbol":"0xb327d9cf0ecd793a175fa70ac8d2dc109d4462758e556962c4a87b02ec4f3f15",
         "baseSymbol":"0xb327d9cf0ecd793a175fa70ac8d2dc109d4462758e556962c4a87b02ec4f3f15",
         "quoteSymbol":"0xb327d9cf0ecd793a175fa70ac8d2dc109d4462758e556962c4a87b02ec4f3f15",
         "oracleType":"pyth",
         "price":"7.33638432"
      },
      {
         "symbol":"0xecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a",
         "baseSymbol":"0xecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a",
         "quoteSymbol":"0xecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a",
         "oracleType":"pyth",
         "price":"225.28704062"
      }
   ]
}
{
 "oracles": [
  {
   "symbol": "ANC",
   "oracle_type": "bandibc",
   "price": "2.212642692"
  },
  {
   "symbol": "ATOM",
   "oracle_type": "bandibc",
   "price": "24.706861402"
  },
  {
   "symbol": "ZRX",
   "oracle_type": "coinbase",
   "price": "0.9797"
  }
 ]
}
ParameterTypeDescription
oraclesOracle array


Oracle

ParameterTypeDescription
symbolstringThe symbol of the oracle asset.
base_symbolstringOracle base currency
quote_symbolstringOracle quote currency
oracle_typestringOracle Type
pricestringThe price of the oracle asset

Price

Get the oracle price of an asset.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market = (await client.all_derivative_markets())[
        "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    ]

    base_symbol = market.oracle_base
    quote_symbol = market.oracle_quote
    oracle_type = market.oracle_type

    oracle_prices = await client.fetch_oracle_price(
        base_symbol=base_symbol,
        quote_symbol=quote_symbol,
        oracle_type=oracle_type,
    )
    print(json.dumps(oracle_prices, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/core"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    ctx := context.Background()
    marketsAssistant, err := chainclient.NewHumanReadableMarketsAssistant(ctx, chainClient)
    if err != nil {
        panic(err)
    }

    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    market := marketsAssistant.AllDerivativeMarkets()["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    derivativeMarket, ok := market.(core.DerivativeMarketV2)
    if !ok {
        panic("market is not a derivative market")
    }

    baseSymbol := derivativeMarket.OracleBase
    quoteSymbol := derivativeMarket.OracleQuote
    oracleType := derivativeMarket.OracleType
    oracleScaleFactor := uint32(0)
    res, err := exchangeClient.GetPrice(ctx, baseSymbol, quoteSymbol, oracleType, oracleScaleFactor)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
base_symbolstringOracle base currencyYes
quote_symbolstringOracle quote currencyYes
oracle_typestringOracle TypeYes
oracle_scale_factoruint32OracleScaleFactorYes

Response Parameters

Response Example:

{ "price": '1.368087992' }
{
 "price": "40128736026.4094317665"
}
ParameterTypeDescription
pricestringThe price of the oracle asset

StreamPrices

Stream new price changes for a specified oracle. If no oracles are provided, all price changes are streamed.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def price_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to oracle prices updates ({exception})")


def stream_closed_processor():
    print("The oracle prices updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    market = (await client.all_derivative_markets())[
        "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    ]

    base_symbol = market.oracle_base
    quote_symbol = market.oracle_quote
    oracle_type = market.oracle_type.lower()

    task = asyncio.get_event_loop().create_task(
        client.listen_oracle_prices_updates(
            callback=price_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            base_symbol=base_symbol,
            quote_symbol=quote_symbol,
            oracle_type=oracle_type,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "strings"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/core"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    ctx := context.Background()
    marketsAssistant, err := chainclient.NewHumanReadableMarketsAssistant(ctx, chainClient)
    if err != nil {
        panic(err)
    }

    market := marketsAssistant.AllDerivativeMarkets()["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"]
    derivativeMarket, ok := market.(core.DerivativeMarketV2)
    if !ok {
        panic("market is not a derivative market")
    }

    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    baseSymbol := derivativeMarket.OracleBase
    quoteSymbol := derivativeMarket.OracleQuote
    oracleType := strings.ToLower(derivativeMarket.OracleType)

    stream, err := exchangeClient.StreamPrices(ctx, baseSymbol, quoteSymbol, oracleType)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
base_symbolstringOracle base currencyYes
quote_symbolstringOracle quote currencyYes
oracle_typestringOracle TypeYes

Response Parameters

Streaming Response Example:

{
   "price":"1.3683814386627584",
   "timestamp":"1702043286264"
}
{
 "price": "40128.7360264094317665",
 "timestamp": 1653038843915
}
ParameterTypeDescription
pricestringThe price of the oracle asset
timestampint64Operation timestamp in UNIX millis.

- InjectiveInsuranceRPC

InjectiveInsuranceRPC defines the gRPC API of the Insurance Exchange provider.

InsuranceFunds

List all the insurance funds.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    insurance_funds = await client.fetch_insurance_funds()
    print(json.dumps(insurance_funds, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    insurancePB "github.com/InjectiveLabs/sdk-go/exchange/insurance_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := insurancePB.FundsRequest{}

    res, err := exchangeClient.GetInsuranceFunds(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

Response Parameters

Response Example:

{
   "funds":[
      {
         "marketTicker":"BTC/USDT PERP",
         "marketId":"0x90e662193fa29a3a7e6c07be4407c94833e762d9ee82136a2cc712d6b87d7de3",
         "depositDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "poolTokenDenom":"share1",
         "redemptionNoticePeriodDuration":"1209600",
         "balance":"3825059708",
         "totalShare":"1000000000000000000",
         "oracleBase":"BTC",
         "oracleQuote":"USDT",
         "oracleType":"bandibc",
         "expiry":"0"
      },
      {
         "marketTicker":"ETH/USDT PERP",
         "marketId":"0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff",
         "depositDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "poolTokenDenom":"share2",
         "redemptionNoticePeriodDuration":"1209600",
         "balance":"723501080000",
         "totalShare":"7235010800000000000",
         "oracleBase":"ETH",
         "oracleQuote":"USDT",
         "oracleType":"bandibc",
         "expiry":"0"
      }
   ]
}
{
 "funds": [
  {
   "market_ticker": "OSMO/UST PERP",
   "market_id": "0x8c7fd5e6a7f49d840512a43d95389a78e60ebaf0cde1af86b26a785eb23b3be5",
   "deposit_denom": "ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C",
   "pool_token_denom": "share19",
   "redemption_notice_period_duration": 1209600,
   "balance": "1000000",
   "total_share": "1000000000000000000",
   "oracle_base": "OSMO",
   "oracle_quote": "UST",
   "oracle_type": "bandibc"
  }
 ]
}
ParameterTypeDescription
fundsInsuranceFund array


InsuranceFund

ParameterTypeDescription
market_tickerstringTicker of the derivative market.
market_idstringDerivative Market ID
deposit_denomstringCoin denom used for the underwriting of the insurance fund.
pool_token_denomstringPool token denom
redemption_notice_period_durationint64Redemption notice period duration in seconds.
balancestring
total_sharestring
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typestringOracle Type
expiryint64Defines the expiry, if any
deposit_token_metaTokenMetaToken metadata for the deposit asset


TokenMeta

ParameterTypeDescription
namestringToken full name
addressstringToken contract address (native or not)
symbolstringToken symbol short name
logostringURL to the logo image
decimalsint32Token decimals
updated_atint64Token metadata fetched timestamp in UNIX millis.

Redemptions

Get a list of redemptions. If no parameters are provided, redemptions for all pools and addresses will be returned.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    redeemer = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    redemption_denom = "share4"
    status = "disbursed"
    insurance_redemptions = await client.fetch_redemptions(address=redeemer, denom=redemption_denom, status=status)
    print(json.dumps(insurance_redemptions, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    insurancePB "github.com/InjectiveLabs/sdk-go/exchange/insurance_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := insurancePB.RedemptionsRequest{}

    res, err := exchangeClient.GetRedemptions(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
redeemerstringAccount address of the redemption ownerYes
redemption_denomstringDenom of the insurance pool token.Yes
statusstringStatus of the redemption. Either pending or disbursed.Yes

Response Parameters

Response Example:

{
   "redemptionSchedules":[
      {
         "redemptionId":"1",
         "status":"disbursed",
         "redeemer":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "claimableRedemptionTime":"1674798129093000",
         "redemptionAmount":"500000000000000000",
         "redemptionDenom":"share4",
         "requestedAt":"1673588529093000",
         "disbursedAmount":"5000000",
         "disbursedDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "disbursedAt":"1674798130965000"
      },
      {
         "redemptionId":"2",
         "status":"disbursed",
         "redeemer":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "claimableRedemptionTime":"1674798342397000",
         "redemptionAmount":"2000000000000000000",
         "redemptionDenom":"share4",
         "requestedAt":"1673588742397000",
         "disbursedAmount":"20000000",
         "disbursedDenom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "disbursedAt":"1674798343097000"
      }
   ]
}
{
 "redemption_schedules": [
  {
   "redemption_id": 1,
   "status": "pending",
   "redeemer": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "claimable_redemption_time": 1654247935923000,
   "redemption_amount": "1000000000000000000",
   "redemption_denom": "share19",
   "requested_at": 1653038335923000
  }
 ]
}
ParameterTypeDescription
redemption_schedulesRedemptionSchedule array


RedemptionSchedule

ParameterTypeDescription
redemption_iduint64Redemption ID.
statusstringStatus of the redemption. Either pending or disbursed.
redeemerstringAccount address of the redemption owner
claimable_redemption_timeint64Claimable redemption time in seconds
redemption_amountstringAmount of pool tokens being redeemed.
redemption_denomstringPool token denom being redeemed.
requested_atint64Redemption request time in unix milliseconds.
disbursed_amountstringAmount of quote tokens disbursed
disbursed_denomstringDenom of the quote tokens disbursed
disbursed_atint64Redemption disbursement time in unix milliseconds.

- InjectiveAuctionRPC

InjectiveAuctionRPC defines the gRPC API of the Auction provider.

Auction

Get the details of a specific auction.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    bid_round = 31
    auction = await client.fetch_auction(round=bid_round)
    print(json.dumps(auction, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    round := int64(35)
    res, err := exchangeClient.GetAuction(ctx, round)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
roundint64The auction round number. -1 for latest.Yes

Response Parameters

Response Example:

{
   "auction":{
      "winner":"inj1uyk56r3xdcf60jwrmn7p9rgla9dc4gam56ajrq",
      "basket":[
         {
            "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "amount":"2322098"
         }
      ],
      "winningBidAmount":"2000000000000000000",
      "round":"31",
      "endTimestamp":"1676013187000",
      "updatedAt":"1677075140258"
   },
   "bids":[
      {
         "bidder":"inj1pdxq82m20fzkjn2th2mm5jp7t5ex6j6klf9cs5",
         "amount":"1000000000000000000",
         "timestamp":"1675426622603"
      },
      {
         "bidder":"inj1tu9xwxms5dvz3782tjal0fy5rput78p3k5sfv6",
         "amount":"1010000000000000000",
         "timestamp":"1675427580363"
      },
      {
         "bidder":"inj1sdkt803zwq2tpej0k2a0z58hwyrnerzfsxj356",
         "amount":"1030000000000000000",
         "timestamp":"1675482275821"
      },
      {
         "bidder":"inj1uyk56r3xdcf60jwrmn7p9rgla9dc4gam56ajrq",
         "amount":"2000000000000000000",
         "timestamp":"1675595586380"
      }
   ]
}
{
 "auction": {
  "basket": [
   {
    "denom": "ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C",
    "amount": "20541163349"
   },
   {
    "denom": "peggy0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "amount": "3736040925000000"
   },
   {
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "amount": "383119139180"
   }
  ],
  "round": 13534,
  "end_timestamp": 1650635285000,
  "updated_at": 1650978958302
 }
}
ParameterTypeDescription
auctionAuctionThe auction
bidsBid arrayBids of the auction


Auction

ParameterTypeDescription
winnerstringAccount address of the auction winner
basketCoin arrayCoins in the basket
winning_bid_amountstring
rounduint64
end_timestampint64Auction end timestamp in UNIX millis.
updated_atint64UpdatedAt timestamp in UNIX millis.
contractAuctionContract


Bid

ParameterTypeDescription
bidderstringAccount address of the bidder
amountstring
timestampint64Bid timestamp in UNIX millis.


Coin

ParameterTypeDescription
denomstringDenom of the coin
amountstring
usd_valuestring

Auctions

Get the details of previous auctions.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    auctions = await client.fetch_auctions()
    print(json.dumps(auctions, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    res, err := exchangeClient.GetAuctions(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

No parameters

Response Parameters

Response Example:

{
   "auctions":[
      {
         "basket":[
            {
               "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
               "amount":"188940000"
            }
         ],
         "round":"1",
         "endTimestamp":"1657869187000",
         "updatedAt":"1658131202118",
         "winner":"",
         "winningBidAmount":""
      },
      {
         "basket":[
            {
               "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
               "amount":"219025410"
            }
         ],
         "round":"2",
         "endTimestamp":"1658473987000",
         "updatedAt":"1658134858904",
         "winner":"",
         "winningBidAmount":""
      },
      ...
      {
         "winner":"inj1rk9fguz9zjwtqm3t6e9fzp7n9dd7jfhaw9dcc4",
         "basket":[
            {
               "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
               "amount":"1066722260002"
            }
         ],
         "winningBidAmount":"3007530000000000000000",
         "round":"73",
         "endTimestamp":"1701414787000",
         "updatedAt":"1700809987278"
      },
      {
         "basket":[
            {
               "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
               "amount":"1137356301548"
            },
            {
               "denom":"peggy0xf9152067989BDc8783fF586624124C05A529A5D1",
               "amount":"128519416"
            }
         ],
         "round":"74",
         "endTimestamp":"1702019587000",
         "updatedAt":"1701414788278",
         "winner":"",
         "winningBidAmount":""
      }
   ]
}
{
 "auctions": [
  {
   "basket": [
    {
     "denom": "ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C",
     "amount": "20541163349"
    },
    {
     "denom": "peggy0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
     "amount": "3736040925000000"
    },
    {
     "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
     "amount": "383119139180"
    }
   ],
   "round": 13435,
   "end_timestamp": 1650575885000,
   "updated_at": 1650978931464
  },
  {
   "basket": [
    {
     "denom": "ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C",
     "amount": "20541163349"
    },
    {
     "denom": "peggy0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
     "amount": "3736040925000000"
    },
    {
     "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
     "amount": "383119139180"
    }
   ],
   "round": 13436,
   "end_timestamp": 1650576485000,
   "updated_at": 1650978931847
  }
 ]
}
ParameterTypeDescription
auctionsAuction arrayThe historical auctions


ParameterTypeDescription
winnerstringAccount address of the auction winner
basketCoin arrayCoins in the basket
winning_bid_amountstring
rounduint64
end_timestampint64Auction end timestamp in UNIX millis.
updated_atint64UpdatedAt timestamp in UNIX millis.
contractAuctionContract


Coin

ParameterTypeDescription
denomstringDenom of the coin
amountstring
usd_valuestring

InjBurntEndpoint

Returns the total amount of INJ burnt in auctions.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main():
    # Select network: testnet, mainnet, or local
    network = Network.testnet()
    client = IndexerClient(network)

    try:
        # Fetch INJ burnt amount
        inj_burnt_response = await client.fetch_inj_burnt()
        print("INJ Burnt Endpoint Response:")
        print(json.dumps(inj_burnt_response, indent=2))

    except Exception as e:
        print(f"Error fetching INJ burnt amount: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchange.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Fetch INJ burnt details
    injBurntResponse, err := exchangeClient.FetchInjBurnt(ctx)
    if err != nil {
        fmt.Printf("Failed to fetch INJ burnt details: %v\n", err)
        return
    }

    // Print JSON representation of the response
    jsonResponse, err := json.MarshalIndent(injBurntResponse, "", "  ")
    if err != nil {
        fmt.Printf("Failed to marshal response to JSON: %v\n", err)
        return
    }

    fmt.Println("INJ Burnt Details:")
    fmt.Println(string(jsonResponse))
}

No parameters

Response Parameters

Response Example:

{
  "total_inj_burnt": "15336250729"
}
ParameterTypeDescription
total_inj_burntstring

StreamBids

Stream live updates for auction bids.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def bid_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to bids updates ({exception})")


def stream_closed_processor():
    print("The bids updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)

    task = asyncio.get_event_loop().create_task(
        client.listen_bids_updates(
            callback=bid_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    stream, err := exchangeClient.StreamBids(ctx)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}

No parameters

Response Parameters

Response Example:

{
  "bidder": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "bidAmount": "1000000000000000000",
  "round": 19532,
  "timestamp": 1654233511715
}
{
  "bidder": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "bidAmount": "3000000000000000000",
  "round": 19532,
  "timestamp": 1654233530633
}
{
 "bidder": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
 "bid_amount": "1000000000000000000",
 "round": 17539,
 "timestamp": 1653038036697
}{
 "bidder": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
 "bid_amount": "2000000000000000000",
 "round": 17539,
 "timestamp": 1653038046359
}
ParameterTypeDescription
bidderstringAccount address of the bidder
bid_amountstring
rounduint64
timestampint64Operation timestamp in UNIX millis.

- InjectiveExplorerRPC

InjectiveExplorerRPC defines the gRPC API of the Explorer provider.

GetTxByHash

Get the details for a specific transaction.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.composer_v2 import Composer
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    composer = Composer(network=network)

    tx_hash = "0F3EBEC1882E1EEAC5B7BDD836E976250F1CD072B79485877CEACCB92ACDDF52"
    transaction_response = await client.fetch_tx_by_tx_hash(tx_hash=tx_hash)
    print("Transaction response:")
    print(f"{json.dumps(transaction_response, indent=2)}\n")

    transaction_messages = composer.unpack_transaction_messages(transaction_data=transaction_response["data"])
    print("Transaction messages:")
    print(f"{json.dumps(transaction_messages, indent=2)}\n")
    first_message = transaction_messages[0]
    print("First message:")
    print(f"{json.dumps(first_message, indent=2)}\n")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("mainnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    hash := "E5DCF04CC670A0567F58683409F7DAFC49754278DAAD507FE6EB40DFBFD71830"
    res, err := explorerClient.GetTxByTxHash(ctx, hash)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
hashstringtransaction hashYes
is_evm_hashboolSet to true if the provided hash may be an EVM tx hashYes

Response Parameters

Response Example:

{
   "s":"ok",
   "data":{
      "blockNumber":"5024371",
      "blockTimestamp":"2022-11-14 13:16:18.946 +0000 UTC",
      "hash":"0x0f3ebec1882e1eeac5b7bdd836e976250f1cd072b79485877ceaccb92acddf52",
      "data":"CoQBCjwvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnQ3JlYXRlQmluYXJ5T3B0aW9uc0xpbWl0T3JkZXISRApCMHhmMWQ5MWZiNWI5MGRjYjU3MzczODVlNGIyZDUxMWY3YWZjMmE0MGRkMDNiZWRkMjdjYmM4Nzc3MmIwZjZlMzgy",
      "gasWanted":"123364",
      "gasUsed":"120511",
      "gasFee":{
         "amount":[
            {
               "denom":"inj",
               "amount":"61682000000000"
            }
         ],
         "gasLimit":"123364",
         "payer":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
         "granter":""
      },
      "txType":"injective",
      "messages":"W3sidHlwZSI6Ii9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dDcmVhdGVCaW5hcnlPcHRpb25zTGltaXRPcmRlciIsInZhbHVlIjp7Im9yZGVyIjp7Im9yZGVyX3R5cGUiOiJTRUxMIiwibWFyZ2luIjoiOTk5OTk5NDAwMDAuMDAwMDAwMDAwMDAwMDAwMDAwIiwidHJpZ2dlcl9wcmljZSI6IjAuMDAwMDAwMDAwMDAwMDAwMDAwIiwibWFya2V0X2lkIjoiMHhjMGM5ODU4MWJhZjkzNzQwZTBkNTdhYWUyZTM2YWVjMjYyODUyMzQxYTY4MTgxYzkzODhjOWZiYmU3NTY3ZmYxIiwib3JkZXJfaW5mbyI6eyJmZWVfcmVjaXBpZW50IjoiaW5qMTc0bWV3YzNoYzk2dDdjbmdlcDU0NWVqdTlrc2RjZnZ4NmQzanFxIiwicHJpY2UiOiI1MzAwMDAuMDAwMDAwMDAwMDAwMDAwMDAwIiwicXVhbnRpdHkiOiIxMDAwMDAuMDAwMDAwMDAwMDAwMDAwMDAwIiwic3ViYWNjb3VudF9pZCI6IjB4ZjU3Nzk3NjIzN2MxNzRiZjYyNjhjODY5NWE2NjVjMmRhMGRjMjU4NjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMSJ9fSwic2VuZGVyIjoiaW5qMTc0bWV3YzNoYzk2dDdjbmdlcDU0NWVqdTlrc2RjZnZ4NmQzanFxIn19XQ==",
      "signatures":[
         {
            "pubkey":"injvalcons174mewc3hc96t7cngep545eju9ksdcfvxechtd9",
            "address":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
            "sequence":"283962",
            "signature":"pqXQlPRK8aMEZg2GyW0aotlYcz82iX+FDYNtgkq/9P1e59QYcdyGT/DNV4INLQVXkMwNHUcbKti0dEurzQT6Tw=="
         }
      ],
      "txNumber":"635946",
      "blockUnixTimestamp":"1668431778946",
      "logs":"W3siZXZlbnRzIjpbeyJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dDcmVhdGVCaW5hcnlPcHRpb25zTGltaXRPcmRlciJ9XSwidHlwZSI6Im1lc3NhZ2UifV19XQ==",
      "id":"",
      "code":0,
      "info":"",
      "codespace":"",
      "events":[

      ],
      "memo":"",
      "errorLog":"",
      "claimIds":[

      ]
   },
   "errmsg":""
}

[
   {
      "type":"/injective.exchange.v1beta1.MsgCreateBinaryOptionsLimitOrder",
      "value":{
         "sender":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
         "order":{
            "marketId":"0xc0c98581baf93740e0d57aae2e36aec262852341a68181c9388c9fbbe7567ff1",
            "orderInfo":{
               "subaccountId":"0xf577976237c174bf6268c8695a665c2da0dc2586000000000000000000000001",
               "feeRecipient":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
               "price":"530000.000000000000000000",
               "quantity":"100000.000000000000000000",
               "cid":""
            },
            "orderType":"SELL",
            "margin":"99999940000.000000000000000000",
            "triggerPrice":"0.000000000000000000"
         }
      }
   }
]

{
   "type":"/injective.exchange.v1beta1.MsgCreateBinaryOptionsLimitOrder",
   "value":{
      "sender":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
      "order":{
         "marketId":"0xc0c98581baf93740e0d57aae2e36aec262852341a68181c9388c9fbbe7567ff1",
         "orderInfo":{
            "subaccountId":"0xf577976237c174bf6268c8695a665c2da0dc2586000000000000000000000001",
            "feeRecipient":"inj174mewc3hc96t7cngep545eju9ksdcfvx6d3jqq",
            "price":"530000.000000000000000000",
            "quantity":"100000.000000000000000000",
            "cid":""
         },
         "orderType":"SELL",
         "margin":"99999940000.000000000000000000",
         "triggerPrice":"0.000000000000000000"
      }
   }
}
{
 "block_number": 4362066,
 "block_timestamp": "2022-04-25 09:27:48.303 +0000 UTC",
 "hash": "0x4893b36b1b2d7a0a94973cda1a6eaabf32c43e9c51b629bbdee6a46891c8a63c",
 "data": "CnsKMy9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dDcmVhdGVTcG90TGltaXRPcmRlchJECkIweDIzNGU3YTAzMzlmOTUzZGEyNDMxMTFlOTlhNDg2NTZiOGI5ODM5NGY3ZGJiNTNkZTNlY2QwYWZmMGQ0NTI4ZmI=",
 "gas_wanted": 121770,
 "gas_used": 115359,
 "gas_fee": {
  "amount": [
   {
    "denom": "inj",
    "amount": "60885000000000"
   }
  ],
  "gas_limit": 121770,
  "payer": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
 },
 "tx_type": "injective",
 "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateSpotLimitOrder\",\"value\":{\"order\":{\"market_id\":\"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0\",\"order_info\":{\"fee_recipient\":\"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r\",\"price\":\"0.000000000007523000\",\"quantity\":\"10000000000000000.000000000000000000\",\"subaccount_id\":\"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000\"},\"order_type\":\"BUY_PO\",\"trigger_price\":\"0.000000000000000000\"},\"sender\":\"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r\"}}]",
 "signatures": [
  {
   "pubkey": "injvalcons1hkhdaj2a2clmq5jq6mspsggqs32vynpkflpeux",
   "address": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
   "sequence": 1114,
   "signature": "Ylj8HMq6g0iwSEtMVm8xKwP6m2p9w2H/K/AeKlIeBzltKONBP2oPkdWYcQKkGimbozlxIZm4AYi3x0JGwNps+g=="
  }
 ]
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataTxDetailData


TxDetailData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codeuint32
databyte array
infostring
gas_wantedint64
gas_usedint64
gas_feeGasFee
codespacestring
eventsEvent array
tx_typestring
messagesbyte array
signaturesSignature array
memostring
tx_numberuint64
block_unix_timestampuint64Block timestamp in unix milli
error_logstringTransaction log indicating errors
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim


GasFee

ParameterTypeDescription
amountCosmosCoin array
gas_limituint64
payerstring
granterstring


Event

ParameterTypeDescription
typestring
attributesmap[string]string


Signature

ParameterTypeDescription
pubkeystring
addressstring
sequenceuint64
signaturestring


CosmosCoin

ParameterTypeDescription
denomstringCoin denominator
amountstringCoin amount (big int)

AccountTxs

Get the details for a specific transaction.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.composer_v2 import Composer
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    composer = Composer(network=network)

    address = "inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex"
    message_type = "cosmos.bank.v1beta1.MsgSend"
    limit = 2
    pagination = PaginationOption(limit=limit)
    transactions_response = await client.fetch_account_txs(
        address=address,
        message_type=message_type,
        pagination=pagination,
    )
    print("Transactions response:")
    print(f"{json.dumps(transactions_response, indent=2)}\n")
    first_transaction_messages = composer.unpack_transaction_messages(transaction_data=transactions_response["data"][0])
    print("First transaction messages:")
    print(f"{json.dumps(first_transaction_messages, indent=2)}\n")
    first_message = first_transaction_messages[0]
    print("First message:")
    print(f"{json.dumps(first_message, indent=2)}\n")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    address := "inj1akxycslq8cjt0uffw4rjmfm3echchptu52a2dq"
    after := uint64(14112176)

    req := explorerPB.GetAccountTxsRequest{
        After:   after,
        Address: address,
    }

    ctx := context.Background()
    res, err := explorerClient.GetAccountTxs(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringAddress of accountYes
typestringComma-separated list of msg typesYes
start_timeint64The starting timestamp in UNIX milliseconds that the txs must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the txs must be equal or younger thanYes
per_pageint32Yes
tokenstringPagination tokenYes

Response Parameters

Response Example:

{
   "paging":{
      "total":"5000",
      "from":221428,
      "to":221429,
      "countBySubaccount":"0",
      "next":[

      ]
   },
   "data":[
      {
         "blockNumber":"18138926",
         "blockTimestamp":"2023-11-07 23:19:55.371 +0000 UTC",
         "hash":"0x3790ade2bea6c8605851ec89fa968adf2a2037a5ecac11ca95e99260508a3b7e",
         "data":"EiYKJC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmRSZXNwb25zZQ==",
         "gasWanted":"400000",
         "gasUsed":"93696",
         "gasFee":{
            "amount":[
               {
                  "denom":"inj",
                  "amount":"200000000000000"
               }
            ],
            "gasLimit":"400000",
            "payer":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
            "granter":""
         },
         "txType":"injective-web3",
         "messages":"W3sidHlwZSI6Ii9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQiLCJ2YWx1ZSI6eyJmcm9tX2FkZHJlc3MiOiJpbmoxcGhkNzA2anF6ZDl3em5razVoZ3Nma3JjOGpxeHYwa21sajBrZXgiLCJ0b19hZGRyZXNzIjoiaW5qMWQ2cXg4M25oeDNhM2d4N2U2NTR4NHN1OGh1cjVzODN1ODRoMnhjIiwiYW1vdW50IjpbeyJkZW5vbSI6ImZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3dldGgiLCJhbW91bnQiOiIxMDAwMDAwMDAwMDAwMDAwMDAifV19fV0=",
         "signatures":[
            {
               "pubkey":"02c33c539e2aea9f97137e8168f6e22f57b829876823fa04b878a2b7c2010465d9",
               "address":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
               "sequence":"223460",
               "signature":"gFXPJ5QENzq9SUHshE8g++aRLIlRCRVcOsYq+EOr3T4QgAAs5bVHf8NhugBjJP9B+AfQjQNNneHXPF9dEp4Uehs="
            }
         ],
         "txNumber":"221429",
         "blockUnixTimestamp":"1699399195371",
         "logs":"W3sibXNnX2luZGV4IjowLCJldmVudHMiOlt7InR5cGUiOiJtZXNzYWdlIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiYWN0aW9uIiwidmFsdWUiOiIvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kIn0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFwaGQ3MDZqcXpkOXd6bmtrNWhnc2ZrcmM4anF4djBrbWxqMGtleCJ9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJiYW5rIn1dfSx7InR5cGUiOiJjb2luX3NwZW50IiwiYXR0cmlidXRlcyI6W3sia2V5Ijoic3BlbmRlciIsInZhbHVlIjoiaW5qMXBoZDcwNmpxemQ5d3pua2s1aGdzZmtyYzhqcXh2MGttbGowa2V4In0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjEwMDAwMDAwMDAwMDAwMDAwMGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3dldGgifV19LHsidHlwZSI6ImNvaW5fcmVjZWl2ZWQiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJyZWNlaXZlciIsInZhbHVlIjoiaW5qMWQ2cXg4M25oeDNhM2d4N2U2NTR4NHN1OGh1cjVzODN1ODRoMnhjIn0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjEwMDAwMDAwMDAwMDAwMDAwMGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3dldGgifV19LHsidHlwZSI6InRyYW5zZmVyIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjaXBpZW50IiwidmFsdWUiOiJpbmoxZDZxeDgzbmh4M2EzZ3g3ZTY1NHg0c3U4aHVyNXM4M3U4NGgyeGMifSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMXBoZDcwNmpxemQ5d3pua2s1aGdzZmtyYzhqcXh2MGttbGowa2V4In0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjEwMDAwMDAwMDAwMDAwMDAwMGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3dldGgifV19LHsidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFwaGQ3MDZqcXpkOXd6bmtrNWhnc2ZrcmM4anF4djBrbWxqMGtleCJ9XX1dfV0=",
         "id":"",
         "code":0,
         "info":"",
         "codespace":"",
         "events":[

         ],
         "memo":"",
         "errorLog":"",
         "claimIds":[

         ]
      },
      {
         "blockNumber":"18138918",
         "blockTimestamp":"2023-11-07 23:19:38.275 +0000 UTC",
         "hash":"0xd1f313b090b8698223086c081f71d9590716b83390ae18bc7e6b84b9eb7c7500",
         "data":"EiYKJC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmRSZXNwb25zZQ==",
         "gasWanted":"400000",
         "gasUsed":"93775",
         "gasFee":{
            "amount":[
               {
                  "denom":"inj",
                  "amount":"200000000000000"
               }
            ],
            "gasLimit":"400000",
            "payer":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
            "granter":""
         },
         "txType":"injective-web3",
         "messages":"W3sidHlwZSI6Ii9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQiLCJ2YWx1ZSI6eyJmcm9tX2FkZHJlc3MiOiJpbmoxcGhkNzA2anF6ZDl3em5razVoZ3Nma3JjOGpxeHYwa21sajBrZXgiLCJ0b19hZGRyZXNzIjoiaW5qMWQ2cXg4M25oeDNhM2d4N2U2NTR4NHN1OGh1cjVzODN1ODRoMnhjIiwiYW1vdW50IjpbeyJkZW5vbSI6ImZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2F0b20iLCJhbW91bnQiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIn1dfX1d",
         "signatures":[
            {
               "pubkey":"02c33c539e2aea9f97137e8168f6e22f57b829876823fa04b878a2b7c2010465d9",
               "address":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
               "sequence":"223459",
               "signature":"3Xunour/wXJksgpgkAXC55UwSbUYYt1jpA2zgsMNbHpGucHhSJad13i+HtCXUQY5APABaKKgRC+KAD9UvlPV0Rs="
            }
         ],
         "txNumber":"221428",
         "blockUnixTimestamp":"1699399178275",
         "logs":"W3sibXNnX2luZGV4IjowLCJldmVudHMiOlt7InR5cGUiOiJtZXNzYWdlIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiYWN0aW9uIiwidmFsdWUiOiIvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kIn0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFwaGQ3MDZqcXpkOXd6bmtrNWhnc2ZrcmM4anF4djBrbWxqMGtleCJ9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJiYW5rIn1dfSx7InR5cGUiOiJjb2luX3NwZW50IiwiYXR0cmlidXRlcyI6W3sia2V5Ijoic3BlbmRlciIsInZhbHVlIjoiaW5qMXBoZDcwNmpxemQ5d3pua2s1aGdzZmtyYzhqcXh2MGttbGowa2V4In0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjEwMDAwMDAwMDAwMDAwMDAwMDBmYWN0b3J5L2luajE3dnl0ZHdxY3pxejcyajY1c2F1a3Bscmt0ZDRneWZtZTVhZ2Y2Yy9hdG9tIn1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFkNnF4ODNuaHgzYTNneDdlNjU0eDRzdThodXI1czgzdTg0aDJ4YyJ9LHsia2V5IjoiYW1vdW50IiwidmFsdWUiOiIxMDAwMDAwMDAwMDAwMDAwMDAwZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYXRvbSJ9XX0seyJ0eXBlIjoidHJhbnNmZXIiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJyZWNpcGllbnQiLCJ2YWx1ZSI6ImluajFkNnF4ODNuaHgzYTNneDdlNjU0eDRzdThodXI1czgzdTg0aDJ4YyJ9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxcGhkNzA2anF6ZDl3em5razVoZ3Nma3JjOGpxeHYwa21sajBrZXgifSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMTAwMDAwMDAwMDAwMDAwMDAwMGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2F0b20ifV19LHsidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFwaGQ3MDZqcXpkOXd6bmtrNWhnc2ZrcmM4anF4djBrbWxqMGtleCJ9XX1dfV0=",
         "id":"",
         "code":0,
         "info":"",
         "codespace":"",
         "events":[

         ],
         "memo":"",
         "errorLog":"",
         "claimIds":[

         ]
      }
   ]
}

[
   {
      "type":"/cosmos.bank.v1beta1.MsgSend",
      "value":{
         "fromAddress":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
         "toAddress":"inj1d6qx83nhx3a3gx7e654x4su8hur5s83u84h2xc",
         "amount":[
            {
               "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
               "amount":"100000000000000000"
            }
         ]
      }
   }
]

{
   "type":"/cosmos.bank.v1beta1.MsgSend",
   "value":{
      "fromAddress":"inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex",
      "toAddress":"inj1d6qx83nhx3a3gx7e654x4su8hur5s83u84h2xc",
      "amount":[
         {
            "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
            "amount":"100000000000000000"
         }
      ]
   }
}
{
 "paging": {
  "total": 100000,
  "from": 5968747,
  "to": 5968675
 },
 "data": [
  {
   "block_number": 5968747,
   "block_timestamp": "2022-05-30 16:01:23.09 +0000 UTC",
   "hash": "0x1d5e86c296c70aa2c97b0d31d83a84fb5b7296ccc2e9887868c17a0c1c7a458f",
   "data": "CoEBCjkvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnQ3JlYXRlRGVyaXZhdGl2ZUxpbWl0T3JkZXISRApCMHhmYjEwMDdmYTZiODlmOWQwZDgyODU1MWZmOThhZDRkOTgxYWZkNWQ2NzUzYzljMmU1YTNiNWZiZjYyM2YxMjgw",
   "gas_wanted": 200000,
   "gas_used": 122413,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "100000000000000"
     }
    ],
    "gas_limit": 200000,
    "payer": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf"
   },
   "tx_type": "injective-web3",
   "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder\",\"value\":{\"order\":{\"margin\":\"2000000.000000000000000000\",\"market_id\":\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\",\"order_info\":{\"fee_recipient\":\"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8\",\"price\":\"1000000.000000000000000000\",\"quantity\":\"2.000000000000000000\",\"subaccount_id\":\"0x056510d87f3c88ff7127aae3f5406b8d68908739000000000000000000000000\"},\"order_type\":\"BUY\",\"trigger_price\":\"0.000000000000000000\"},\"sender\":\"inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf\"}}]",
   "signatures": [
    {
     "pubkey": "injvalcons1q4j3pkrl8jy07uf84t3l2srt345fppee8gwf4v",
     "address": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf",
     "sequence": 2,
     "signature": "kUm97awCT/j5RrHR3pIUvU/pOp+qYC2RnYm3tyPpdLdwFIXAFHCzX94htDc0LQxFKT7by08VCOyifTpZJJ9UaRs="
    }
   ]
  },
  {
   "block_number": 5968725,
   "block_timestamp": "2022-05-30 16:00:40.386 +0000 UTC",
   "hash": "0x8d8a0995b99c7641f8e0cc0c7e779325a4c4f5c3a738d1878ee2970c9f7e6f36",
   "data": "CoEBCjkvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnQ3JlYXRlRGVyaXZhdGl2ZUxpbWl0T3JkZXISRApCMHgxZDE4Yzc4ZGYwMTAzZTg4NGZmZjdiZGU5OGIyMjgxNDQ3NDFmODA5NWE2NDY2OGZlNzc2MTEwNmQ1NDNkYWI1",
   "gas_wanted": 200000,
   "gas_used": 122263,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "100000000000000"
     }
    ],
    "gas_limit": 200000,
    "payer": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf"
   },
   "tx_type": "injective-web3",
   "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder\",\"value\":{\"order\":{\"margin\":\"3000000.000000000000000000\",\"market_id\":\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\",\"order_info\":{\"fee_recipient\":\"inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8\",\"price\":\"3000000.000000000000000000\",\"quantity\":\"1.000000000000000000\",\"subaccount_id\":\"0x056510d87f3c88ff7127aae3f5406b8d68908739000000000000000000000000\"},\"order_type\":\"BUY\",\"trigger_price\":\"0.000000000000000000\"},\"sender\":\"inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf\"}}]",
   "signatures": [
    {
     "pubkey": "injvalcons1q4j3pkrl8jy07uf84t3l2srt345fppee8gwf4v",
     "address": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf",
     "sequence": 1,
     "signature": "2iFB8tsuNHcSdvYufaL/8JJ0J0D6JOwbjzRJwJueHlpgkfRbWrXU3mBYqkP324U8scBs7jNP2Wa/90KUVi1BLRw="
    }
   ]
  },
  {
   "block_number": 5968715,
   "block_timestamp": "2022-05-30 16:00:19.878 +0000 UTC",
   "hash": "0x1d584573d1df6135bb13238943b805c30c075bca9068f6fe756ba433e36bb978",
   "data": "CigKJi9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dEZXBvc2l0",
   "gas_wanted": 200000,
   "gas_used": 119686,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "100000000000000"
     }
    ],
    "gas_limit": 200000,
    "payer": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf"
   },
   "tx_type": "injective-web3",
   "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgDeposit\",\"value\":{\"amount\":{\"amount\":\"2000000000\",\"denom\":\"peggy0xdAC17F958D2ee523a2206206994597C13D831ec7\"},\"sender\":\"inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf\",\"subaccount_id\":\"0x056510d87f3c88ff7127aae3f5406b8d68908739000000000000000000000000\"}}]",
   "signatures": [
    {
     "pubkey": "injvalcons1q4j3pkrl8jy07uf84t3l2srt345fppee8gwf4v",
     "address": "inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf",
     "signature": "QYBDtZd3hc5/blM3DEk2MU64DsexOVQxMhDjbC+m5W4S1VM18DxbqN4fWfyr756jQNDAiAxAugXIaBgyDykfkRw="
    }
   ]
  },
  {
   "block_number": 5968675,
   "block_timestamp": "2022-05-30 15:59:00.706 +0000 UTC",
   "hash": "0x5f420c9e78f81e33614943834ae3913273b09b3e4b9ae6661bca0b695d6d2fde",
   "data": "Ch4KHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQKHgocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZA==",
   "gas_wanted": 400000,
   "gas_used": 126714,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "200000000000000"
     }
    ],
    "gas_limit": 400000,
    "payer": "inj1pmau7c2ll72l0p58vdchzd39dvacfln50n7e9r"
   },
   "tx_type": "injective-web3",
   "messages": "[{\"type\":\"/cosmos.bank.v1beta1.MsgSend\",\"value\":{\"amount\":[{\"amount\":\"10000000000000000000\",\"denom\":\"inj\"}],\"from_address\":\"inj1pmau7c2ll72l0p58vdchzd39dvacfln50n7e9r\",\"to_address\":\"inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf\"}},{\"type\":\"/cosmos.bank.v1beta1.MsgSend\",\"value\":{\"amount\":[{\"amount\":\"10000000000\",\"denom\":\"peggy0xdAC17F958D2ee523a2206206994597C13D831ec7\"}],\"from_address\":\"inj1pmau7c2ll72l0p58vdchzd39dvacfln50n7e9r\",\"to_address\":\"inj1q4j3pkrl8jy07uf84t3l2srt345fppeeyagscf\"}}]",
   "signatures": [
    {
     "pubkey": "injvalcons1pmau7c2ll72l0p58vdchzd39dvacfln5vxcqgx",
     "address": "inj1pmau7c2ll72l0p58vdchzd39dvacfln50n7e9r",
     "sequence": 49,
     "signature": "4gw7HI6wT/+yuCs0TeB+qh63puimW7MSGnVOmX/ywKggKIgjRIXAzJHlT8c7graA0dXXxJX1Hn5yjuMDsBHQChw="
    }
   ]
  }
 ]
}
ParameterTypeDescription
pagingCursor
dataTxDetailData array


TxDetailData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codeuint32
databyte array
infostring
gas_wantedint64
gas_usedint64
gas_feeGasFee
codespacestring
eventsEvent array
tx_typestring
messagesbyte array
signaturesSignature array
memostring
tx_numberuint64
block_unix_timestampuint64Block timestamp in unix milli
error_logstringTransaction log indicating errors
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim


GasFee

ParameterTypeDescription
amountCosmosCoin array
gas_limituint64
payerstring
granterstring


Signatures

ParameterTypeDescription
pubkeystring
addressstring
sequenceuint64
signaturestring


CosmosCoin

ParameterTypeDescription
denomstringCoin denominator
amountstringCoin amount (big int)


Cursor

ParameterTypeDescription
nextstring arrayarray of tokens to navigate to the next pages

Blocks

Get data for blocks.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    limit = 2
    pagination = PaginationOption(limit=limit)
    blocks = await client.fetch_blocks(pagination=pagination)
    print(json.dumps(blocks, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("mainnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    res, err := explorerClient.GetBlocks(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
beforeuint64Yes
afteruint64Yes
limitint32Yes
fromuint64Unix timestamp (UTC) in millisecondsYes
touint64Unix timestamp (UTC) in millisecondsYes

Response Parameters

Response Example:

{
   "paging":{
      "total":"19388338",
      "from":19388337,
      "to":19388338,
      "countBySubaccount":"0",
      "next":[

      ]
   },
   "data":[
      {
         "height":"19388338",
         "proposer":"injvalcons1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a",
         "moniker":"InjectiveNode2",
         "blockHash":"0x349ba348107a78e27a21aa86f7b6a7eab3cda33067872234eef5e6967fa0964c",
         "parentHash":"0x3cdbdc7eee0767651785b5ac978af2fe2162caab8596da651c3c6403284902d7",
         "timestamp":"2023-12-08 12:35:08.059 +0000 UTC",
         "numPreCommits":"0",
         "numTxs":"0",
         "txs":[

         ]
      },
      {
         "height":"19388337",
         "proposer":"injvalcons1e0rj6fuy9yn5fwm9x4vw69xyuv7kzjm8rvw5r3",
         "moniker":"InjectiveNode3",
         "blockHash":"0x275aaa7206b6272b50a7d697d2ed432a2ab51aca3bcf3a0da3009521a29b1e07",
         "parentHash":"0x44b8faece543cba46e1391e918b4f397e99461092c178149185275fff30d40bc",
         "numTxs":"1",
         "timestamp":"2023-12-08 12:35:06.749 +0000 UTC",
         "numPreCommits":"0",
         "txs":[

         ]
      }
   ]
}
{
 "paging": {
  "from": 6002843,
  "to": 6002844
 },
 "data": [
  {
   "height": 6002844,
   "proposer": "injvalcons1qmrj7lnzraref92lzuhrv6m7sxey248fzxmfnf",
   "moniker": "InjectiveNode3",
   "block_hash": "0x138f577b66db53405fd2e642223d563558dd5af85cae0c7f6bb4d5fbfa53c310",
   "parent_hash": "0x4012fcb077810c5e5d70ad2a1fbb5874dd66c194f243800db2c02b6ffcac0f4d",
   "timestamp": "2022-05-31 10:27:13.325 +0000 UTC"
  },
  {
   "height": 6002843,
   "proposer": "injvalcons1uq5z4v9jhxr3a3k5k94nxa6l8hzzqs5fcstvaa",
   "moniker": "InjectiveNode1",
   "block_hash": "0x5b04a48a7d757585af7acd28f97cd75a377e6b5e8dd807322a2b74f467a292a6",
   "parent_hash": "0x82e4d22cf5ed64aa9bce69bcb9933295d0730a3dbfafdc3f0970949934435d70",
   "timestamp": "2022-05-31 10:27:11.395 +0000 UTC"
  }
 ]
}
ParameterTypeDescription
pagingPaging
dataBlockInfo array


BlockInfo

ParameterTypeDescription
heightuint64
proposerstring
monikerstring
block_hashstring
parent_hashstring
num_pre_commitsint64
num_txsint64
txsTxDataRPC array
timestampstring
block_unix_timestampuint64Block timestamp in unix milli


TxDataRPC

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codespacestring
messagesstring
tx_numberuint64
error_logstringTransaction log indicating errors
codeuint32
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

Block

Get detailed data for a single block.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    block_height = "5825046"
    block = await client.fetch_block(block_id=block_height)
    print(json.dumps(block, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    blockHeight := "5825046"
    res, err := explorerClient.GetBlock(ctx, blockHeight)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
idstringYes

Response Parameters

Response Example:

{
   "s":"ok",
   "data":{
      "height":"5825046",
      "proposer":"injvalcons1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a",
      "moniker":"InjectiveNode2",
      "blockHash":"0x5982527aa7bc62d663256d505ab396e699954e46ada71a11de2a75f6e514d073",
      "parentHash":"0x439caaef7ed0c6d9c2bdd7ffcd8c7303a4eb6a7c33d7db189f85f9b3a496fbc6",
      "numTxs":"2",
      "txs":[
         {
            "blockNumber":"5825046",
            "blockTimestamp":"2022-12-11 22:06:49.182 +0000 UTC",
            "hash":"0xbe8c8ca9a41196adf59b88fe9efd78e7532e04169152e779be3dc14ba7c360d9",
            "messages":"bnVsbA==",
            "txNumber":"994979",
            "txMsgTypes":"WyIvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnQ3JlYXRlQmluYXJ5T3B0aW9uc0xpbWl0T3JkZXIiXQ==",
            "id":"",
            "codespace":"",
            "errorLog":"",
            "code":0,
            "logs":"",
            "claimIds":[

            ]
         },
         {
            "blockNumber":"5825046",
            "blockTimestamp":"2022-12-11 22:06:49.182 +0000 UTC",
            "hash":"0xe46713fbedc907278b6bd22165946d8673169c1a0360383e5e31abf219290c6a",
            "messages":"bnVsbA==",
            "txNumber":"994978",
            "txMsgTypes":"WyIvaWJjLmNvcmUuY2xpZW50LnYxLk1zZ1VwZGF0ZUNsaWVudCIsIi9pYmMuY29yZS5jaGFubmVsLnYxLk1zZ1JlY3ZQYWNrZXQiXQ==",
            "id":"",
            "codespace":"",
            "errorLog":"",
            "code":0,
            "logs":"",
            "claimIds":[

            ]
         }
      ],
      "timestamp":"2022-12-11 22:06:49.182 +0000 UTC",
      "numPreCommits":"0",
      "totalTxs":"0"
   },
   "errmsg":""
}
{
 "height": 5825046,
 "proposer": "injvalcons1qmrj7lnzraref92lzuhrv6m7sxey248fzxmfnf",
 "moniker": "InjectiveNode3",
 "block_hash": "0x06453296122c4db605b68aac9e2848ea778b8fb2cdbdeb77281515722a1457cf",
 "parent_hash": "0x14cba82aa61d5ee2ddcecf8e1f0a7f0286c5ac1fe3f8c3dafa1729121152793d",
 "timestamp": "2022-05-27 10:21:51.168 +0000 UTC"
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataBlockDetailInfo


BlockDetailInfo

ParameterTypeDescription
heightuint64
proposerstring
monikerstring
block_hashstring
parent_hashstring
num_pre_commitsint64
num_txsint64
total_txsint64
txsTxData array
timestampstring
block_unix_timestampuint64Block timestamp in unix milli


TxData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codespacestring
messagesbyte array
tx_numberuint64
error_logstringTransaction log indicating errors
codeuint32
tx_msg_typesbyte array
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim
signaturesSignature array
block_unix_timestampuint64Block timestamp in unix milli
ethereum_tx_hash_hexstring

Txs

Get the transactions.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    limit = 2
    pagination = PaginationOption(limit=limit)
    txs = await client.fetch_txs(pagination=pagination)
    print(json.dumps(txs, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    before := uint64(7158400)

    req := explorerPB.GetTxsRequest{
        Before: before,
    }

    res, err := explorerClient.GetTxs(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
beforeuint64Yes
afteruint64Yes
limitint32Yes
skipuint64Yes
typestringYes
modulestringYes
from_numberint64Yes
to_numberint64Yes
start_timeint64The starting timestamp in UNIX milliseconds that the txs must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the txs must be equal or younger thanYes
statusstringThe status of the txs to be returnedYes

Response Parameters

Response Example:

{
   "paging":{
      "total":"17748338",
      "from":17748337,
      "to":17748338,
      "countBySubaccount":"0",
      "next":[

      ]
   },
   "data":[
      {
         "blockNumber":"19388410",
         "blockTimestamp":"2023-12-08 12:37:42.632 +0000 UTC",
         "hash":"0xe9e2bd81acb24a6d04ab3eb50e5188858a63b8ec05b694c8731b2be8dc34b2d0",
         "messages":"W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFmdXc4OTMyNmQ0NzlrbjR2aGd6dnRhYWY3bTJoeDltZ25nZnFhMyIsImNvbnRyYWN0IjoiaW5qMTNnOWhwbnRjdHpnaGU5Mjkzc2xlMjhxNGU0ZTVtMGdzM2hwcDBoIiwibXNnIjp7InBvc3RfZGF0YSI6eyJkYXRhIjoiQ3RFREN2MEJDZ0lJQ3hETjhTd1lscHpNcXdZaUlPMFUvUTdFSFF1VEVUSHoxcmhtK0g3MUdJdkhsTXRwRUhOVlZQTDZHbUpHS2lCdDlWcmszekdtdGI0UVY2Z3hiVmlvOUJlT3VzenRmWUhtSUlOYzRxbTFyeklnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQTZJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVFpQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZJVW44bHVMWERzaHVYd2FBcm8wcjllYUNocCtRSmFJQThyemk3UXFtRng1eW8rR2tOKzk3RjIvRUZZNEVRVGVGQjdYSTFKWTg0TFlndHZjSFJwWHpFM016Z3RNUkpDQ2tBVWNraTd4K2dBMUlyNlpINnNWTWRDSWVndU9Cdm5ONVFoZVpYbU9FTWhyZG54eHl6bXpLbks0cEVuRUFFSEgvMTVnZE1HQXRIZ3BiV0N3VGtYSG5vT0dvb0JDa01LRkovSmJpMXc3SWJsOEdnSzZOSy9YbWdvYWZrQ0VpSUtJTlprU09wWUtNbldoNytFamlQWDJ5eG52d1VIRVlrdXROSjV4bU5qTmRyVEdJQ0FtcWJxcitNQkVrTUtGSi9KYmkxdzdJYmw4R2dLNk5LL1htZ29hZmtDRWlJS0lOWmtTT3BZS01uV2g3K0VqaVBYMnl4bnZ3VUhFWWt1dE5KNXhtTmpOZHJUR0lDQW1xYnFyK01CRWdBPSJ9fSwiZnVuZHMiOltdfX1d",
         "txNumber":"17748338",
         "txMsgTypes":"WyIvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QiXQ==",
         "logs":"W3sibXNnX2luZGV4IjowLCJldmVudHMiOlt7InR5cGUiOiJtZXNzYWdlIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiYWN0aW9uIiwidmFsdWUiOiIvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QifSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMWZ1dzg5MzI2ZDQ3OWtuNHZoZ3p2dGFhZjdtMmh4OW1nbmdmcWEzIn0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc20ifV19LHsidHlwZSI6ImV4ZWN1dGUiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJfY29udHJhY3RfYWRkcmVzcyIsInZhbHVlIjoiaW5qMTNnOWhwbnRjdHpnaGU5Mjkzc2xlMjhxNGU0ZTVtMGdzM2hwcDBoIn1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajEzZzlocG50Y3R6Z2hlOTI5M3NsZTI4cTRlNGU1bTBnczNocHAwaCJ9LHsia2V5IjoibWV0aG9kIiwidmFsdWUiOiJwb3N0ZGF0YSJ9XX1dfV0=",
         "id":"",
         "codespace":"",
         "errorLog":"",
         "code":0,
         "claimIds":[

         ]
      },
      {
         "blockNumber":"19388408",
         "blockTimestamp":"2023-12-08 12:37:38.713 +0000 UTC",
         "hash":"0xd9197814915db8cfcc38743d1680764530da238304899723f5b37b49500304d3",
         "messages":"W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFkZWVqYzY2dmhjcWVuNXFqdTJlZGxjOHdqczN4OTJzaHYza2F0cyIsImNvbnRyYWN0IjoiaW5qMThybGZscDM3MzVoMjVqbWp4OTdkMjJjNzJzeGsyNjBhbWRqeGx1IiwibXNnIjp7InVwZGF0ZV9wcmljZV9mZWVkcyI6eyJkYXRhIjpbIlVFNUJWUUVBQUFBQW9BRUFBQUFBQVFDK3FzR3JqcjdzeXVmS3l3VDN6dllvcXRyVzc3cXZlSFFIbDl3V3hhU3RMRVJaS1liS2Q2UE45clNReW5OU1ZkbGVIdkRJaWh2d2lrYnhCY2o2bkxSb0FXVnpEaEVBQUFBQUFCcmhBZnJ0ckZoUjR5dWJJN1g1UVJxTUs2eEtyajdVM1h1QkhkR25McVNxY1FBQUFBQUNhNVRJQVVGVlYxWUFBQUFBQUFiYjlqUUFBQ2NRNmRhVWViTjRsM25SWmtyZlZVayt6Z0poQ3VrT0FGVUEvbVVQQTJmVXArK1lGYVdUNmhYVFpaUHdaRHFxOEJTYnNFdm1lcmhSM3MwQUFBQUJ0TXJCaHdBQUFBQUFNdFZtLy8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUJzU2Q5cUFBQUFBQUFPNEpiQ21Gbzh0UGlWbTl5WkFkVUxNUUROZzRVNmV1ZXhHMklqdVlia1VTdlo2ZWhIbStQTlpXNXIxSTZFeHFURGFZNWJTREtpSWYyZHZBRWN6NXAwcEdTTEJzQm0yRHhZZVFKTkRXaTZ5U3VFTXp1MGViL0M4SHR6NjJwbkZDd00vUEFzcVFXM3UxRC9GUDAwcDBMRldKL1FSQjRMQ1pnK09Bb09DM2FTODFBUElqajU0TkpEdm9aMC9vTU5ucTlhdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFIOEdJWVNNaWtDSVVZU0lMMU9LczBkemZ2SW5JUUpMSlBCaTl4M1ZzRllnQUFBQUFCZllLTndBQUFBQUFBRlloLy8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFCZllYY3dBQUFBQUFBR05wQ24wRnd6c1lTem54aEtYc2JhQWhDd2phYTVhTHU4bVhKL2xtQWlJV050d2lnc1BWd09KN0hKb0VZWkpXb0ZxTTVoRVZvdmtDWWF5NG5jMFFqK2N3WkJHWmdGbmlYTGdEVjU3dEZHeE0rWWFMTkE5YWpTV2lLb0sxemVxUjN2TGpLMkIxSVgweHYwQVVTL0FVWURIYmREcDFYRzJyM1dveExzZlV4QVgrMnJ0UEVYN0syWEZkNFlHSUpvc21laXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUErY0FYSzZFTitrMFpDSTJVOWI5aDA3Vk5XOWRJT2pJcW1DNFRjKzZPb3hzQUFBUDVhSU9ib1FBQUFBQmF1WVlwLy8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBUDBZWjdLWUFBQUFBQlBSM1dlQ2dOdE94cWZPdFZOTXNwdm1NT0NZclB4MnBOSkpxVVJvdVYzalZKejdjNXY3QktTeVNxVWJtOVVUUkFOcHkrc05abnE1NVprUUVuaExTU20wckZIeXNZV0s4Rm13NVN4TFJjQUlUNXRQTnpaam5wWGR1aDJPK20vVmcwdG5RL1kxTXJ4N29sRC9GUDAwcDBMRldKL1FSQjRMQ1pnK09Bb09DM2FTODFBUElqajU0TkpEdm9aMC9vTU5ucTlhdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFOL1FOS0pnVm5vOHVVcms4dDQ5SHpEZ3BveDVTV3JsMXhKekZ4ZGtYWTNnQUFBQUFCdm5jR0FBQUFBQUFBT0lvLy8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFCdkZFWlFBQUFBQUFBUGxKQ21GaEpCK0ZMMlJka3Q0RzVNd1VZNTE4anlMQ0xEMUZTaGNUSnV0V1hSUjEwaEJFVit1N0RkNThUV1FncnlPQXpsMnQyaE1IM1dpbXFNNkZGOVkwbytGblh1K3dCcnE5ZXhWelpIRU1UcTJvM3doZjJ5bVY0aVZhbDhnNzI5MjdONGlRQkl4QnRJVDhuVkRxUERuQ3RJcVVlUEY1alpydTBPM2RZeVpxUjQwT2RGK3VtVkplUnNnZ0FEV0FlaXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFNS0dSV1BXbFRBcmZqN2RXQmljMFB5S2h2SVVyaWRWcjRhek54ZHY1YlE0QUFBQUFBQjcwMkFBQUFBQUFBQUJ6Ly8vLy9RQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFBQjczV0FBQUFBQUFBQUI5Q3ZNTTI2VVlPVlBBRVBnZmMwOU0zYkthcklVdEhqVDhidU5HQms4MTQrQ1VQOGZMTjR3Vkd5dkJETzQzNC9GbnF3MENqNUhTZisrbmdhSTFLUlUvMVZaSnN5MFE2TER0eFpuRnpMK1NqVXlyd3RmV3J1V1ZkQnJBVDFFMDFYdmtnL094QlpKQnRJVDhuVkRxUERuQ3RJcVVlUEY1alpydTBPM2RZeVpxUjQwT2RGK3VtVkplUnNnZ0FEV0FlaXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUF3YkVuYWZaak41alVXdC9XSy94d0VVZzVJeTRwU2JBZnM5UDVKOUpnWVZRQUFBQUFBQUdsT3dBQUFBQUFBQUFLLy8vLyt3QUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFBQUdsTVFBQUFBQUFBQUFLQ2lnRHd3eUo5TDRjaFNBSzZnRVZsckxkaUVQdmJhQ1owd09WUGpHNEpSeEpwMHBBY1BnbFo3YnVFQXdDd2tvN1JDVUxHRElPQ0k5aWg4ZlA4eTNzcnI0ekp6UkYycmI0MXZlM3pYeU9iRXJNVEZ1UGkvRmhtR3M5Mlh5NEV4eXZleVRrY056Mnc3OHFRMTIrckN6R0F3ejdwTjNNbnJyUVRQR0tGUnVjUU5FekF1WjBOaXVaUjd4dk8xdC9hdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFNaHVrMWdqNmRicDIxdGM5cW5GYXZMM3JuYm9DSlg4Rm9iV1JlTFNmV1pzQUFBQUFBQ1JIWndBQUFBQUFBQUp4Ly8vLyt3QUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFBQ1JTZndBQUFBQUFBQUgwQ3VXM0tTaW95T0dIQ0FCK3Nsc2ZKWldESWVtN0pmNlVueElLd3hRMWkrNzUwQ1lPTFFpbEJ5SnRHR3VqVGllbzlubXo4dVJsSkx1b3hEVm11eFUvMVZaSnN5MFE2TER0eFpuRnpMK1NqVXlyd3RmV3J1V1ZkQnJBVDFFMDFYdmtnL094QlpKQnRJVDhuVkRxUERuQ3RJcVVlUEY1alpydTBPM2RZeVpxUjQwT2RGK3VtVkplUnNnZ0FEV0FlaXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFJS2s0OVV0bzhmTHZHT29ES1BiZEIwZjQ2aEZJYlNLd0llZzZrQXZvbDNZQUFBQUFBQUl6blFBQUFBQUFBQUFJLy8vLy9RQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFBQUl6L1FBQUFBQUFBQUFJQ2hwOEhiS1JRdnRrWUJKdzMxR1lPdjJPTUFURXU4bVhKL2xtQWlJV050d2lnc1BWd09KN0hKb0VZWkpXb0ZxTTVoRVZvdmtDWWF5NG5jMFFqK2N3WkJHWmdGbmlYTGdEVjU3dEZHeE0rWWFMTkE5YWpTV2lLb0sxemVxUjN2TGpLMkIxSVgweHYwQVVTL0FVWURIYmREcDFYRzJyM1dveExzZlV4QVgrMnJ0UEVYN0syWEZkNFlHSUpvc21laXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUF2TDNDZFZ2WFNpQmwrZE1vUEN1S3k5aVk1SE85dVFwblpMUGIxR2ZGYnMwQUFBQUFBQUhyUUFBQUFBQUFBQUFLLy8vLyt3QUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFBQUhyVFFBQUFBQUFBQUFKQ3BySEprTUViNFk1R1EwQ0R5bktnZkxyODBYNzRXOGM3dG1FWGE3RG43WHk0SjlSeVZiYngyWElBQWRBSzRnTVlCTWNLVTNmZ0VUdEE5L0U1S1kvTWRLVERFNVhvS25ULzdaYkxZUGdxd3F1aEQ4WFNRVEVxZU1JYm9hUWRkblVMTVkzd2hiMnc3OHFRMTIrckN6R0F3ejdwTjNNbnJyUVRQR0tGUnVjUU5FekF1WjBOaXVaUjd4dk8xdC9hdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUF5b0M2YmNNdUNOQnZHcWlHQVI3dEhYZkhlK25yZGh6QkRYSzMwS0w5VjZZQUFBQTNFZDZLc2dBQUFBQUZlOGp5Ly8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQTNBN29GWUFBQUFBQUZjbnJyQ2p3UmZsTzI3N1JXaTkxaXBEMEhIbWFzL3M0WWVEME5YNlo3Qnk3cDVhV1UzOC84ZEFsNVZFTUVsM2djeC96Mjl2ditDL2tjd05zSnlYTVFHY1Z5Z1JvOUdRcXp0cFl6MmxpRVBzcFhOR0F3dkhhekRvVkJIWHhMQ2dBT1VrWTVwUGYvc3QxQURuekVwd0hvYTlVQ29DZGhGbE5TN0d3NVhmR0tGUnVjUU5FekF1WjBOaXVaUjd4dk8xdC9hdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFZU0p0T2I3cUdkTTA4WHd2Njg0bjRTWkcyRVoxa2s2N0Fybk5ycWFISitNQUFBQUFQUkNMYXdBQUFBQUFDT3I4Ly8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFQR01hYmdBQUFBQUFDY0xZQ3I0dEhHVk9sNkh0dnpwVFlTMGNjaTdLTk5FYmxWRXlJU1lMTVpSemxhOEI2VnhOQ3FKbHZYUExZM0p3ckw4RG1NS2czNXJMVk14TWF4TE5EdkZOOHBTK2VzRjZrKy96SVc3WkxKY2l1MzE0N1NpcmpSbm42MHhhRlJYVkZWVVJycWlML1U0ZXlDTXIrWTdvRndFQ3RzS0F6OTdWNzQ4QlB6QnVtd3Fkc2d1Rnl1Q3ZJWldGTzNaVWlEMXp1dE1XYjBpYW9zK2o5SmVLeDhZRTZvQnVFRWlrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFMWk1WcUk4d0dmanZxSTMrbkE4SVEzRXRvTHJJRkVZZUozTS9hNFByVWJNQUFBQUFkT2pNaXdBQUFBQUFKUDRCLy8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFjNlN1L0FBQUFBQUFJdXIzQ2hsMVJhT3BEV2k2S1VCbkozS1kwUUJ5WE5hdVlsNXV5YWpsQ0IwNlVxS29YM2h4VUFhbmdmWi83Wk1vWDlvdStEc2x5MW9hWkV3Z1ZqcVAvS3ZVeUh2QzhEcElDVU16aTNxakRab0c0ZjNoclJrQ1NjZmtiWGFybXNpOGZOVi9RUHJYN3U0eHYwQVVTL0FVWURIYmREcDFYRzJyM1dveExzZlV4QVgrMnJ0UEVYN0syWEZkNFlHSUpvc21laXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUE3WUx2djYzZ0VJUC9xUFpHWk1ocTg1S0N5ZkNFaDNCbXJuSzJOZWQzR1BBQUFBQUFBQUE4V2dBQUFBQUFBQUJDLy8vLzlnQUFBQUJsY3c0UEFBQUFBR1Z6RGc0QUFBQUFBQUE4RkFBQUFBQUFBQUE2Q2lNOHhBaUtQUzByN2xOQnFGUVdvQUIySHN5cDArTm9vcmxKT3hJZzlMYmJOZEdMNHZUUzNZaTF6TUczOGVjSk1NM05zL1Q3OEkvS1JDajBUc3c1dWlZNlpncDROSmROMnJjSXBxekNsNVZNVkNnYUxBVHVienR3blNReDI5UDdBWU80T2RCbVhtSkF5TWg5YytwT01vWnY0dFo3ZEt3dnB5M2FTODFBUElqajU0TkpEdm9aMC9vTU5ucTlhdE5qV2dQWUhvaERDNUpZaWtzM3ZCM1MrMzNwK0daM1VVcC8yK3pKTjVCUVBTQTJQbFpCZXpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxa0FGVUFRZk5pV1hIS0x0SW1QbmhYUCtYT0krRTlKVmp0UHk1SHF3K0UrNTU2NXlJQUFBQUFCZlhnL3dBQUFBQUFBSFV0Ly8vLytBQUFBQUJsY3c0UkFBQUFBR1Z6RGc4QUFBQUFCZlhsakFBQUFBQUFBR3NYQ2tYVS94MUtZdEczb2VvUzVuQUlOV0tyUlBDc1R0NmVodjcxNXBSS25VZzJTTWNqbEVWdU91aklJUm5nZFpXSjlGVi9FV2hBMjdmaGZrT1pEeTZqQzUxTzlYT3cwTTByc0VlYUtWNzQ0NWFGM3doZjJ5bVY0aVZhbDhnNzI5MjdONGlRQkl4QnRJVDhuVkRxUERuQ3RJcVVlUEY1alpydTBPM2RZeVpxUjQwT2RGK3VtVkplUnNnZ0FEV0FlaXIxSThBZ3owUlp6c2JMZlo1ZHdwWWs1bStrRUVFN0l3SHllYXI0UTlub2orLzI0OVVBZmpuMEFseG8yM1IvcjQ3bCt4czJ2YnNXajFxayJdfX0sImZ1bmRzIjpbeyJkZW5vbSI6ImluaiIsImFtb3VudCI6IjE0In1dfX1d",
         "txNumber":"17748337",
         "txMsgTypes":"WyIvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QiXQ==",
         "logs":"W3sibXNnX2luZGV4IjowLCJldmVudHMiOlt7InR5cGUiOiJtZXNzYWdlIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiYWN0aW9uIiwidmFsdWUiOiIvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QifSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMWRlZWpjNjZ2aGNxZW41cWp1MmVkbGM4d2pzM3g5MnNodjNrYXRzIn0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc20ifV19LHsidHlwZSI6ImNvaW5fc3BlbnQiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJzcGVuZGVyIiwidmFsdWUiOiJpbmoxZGVlamM2NnZoY3FlbjVxanUyZWRsYzh3anMzeDkyc2h2M2thdHMifSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMTRpbmoifV19LHsidHlwZSI6ImNvaW5fcmVjZWl2ZWQiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJyZWNlaXZlciIsInZhbHVlIjoiaW5qMThybGZscDM3MzVoMjVqbWp4OTdkMjJjNzJzeGsyNjBhbWRqeGx1In0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjE0aW5qIn1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMThybGZscDM3MzVoMjVqbWp4OTdkMjJjNzJzeGsyNjBhbWRqeGx1In0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFkZWVqYzY2dmhjcWVuNXFqdTJlZGxjOHdqczN4OTJzaHYza2F0cyJ9LHsia2V5IjoiYW1vdW50IiwidmFsdWUiOiIxNGluaiJ9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxOHJsZmxwMzczNWgyNWptang5N2QyMmM3MnN4azI2MGFtZGp4bHUifV19LHsidHlwZSI6Indhc20iLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJfY29udHJhY3RfYWRkcmVzcyIsInZhbHVlIjoiaW5qMThybGZscDM3MzVoMjVqbWp4OTdkMjJjNzJzeGsyNjBhbWRqeGx1In0seyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6InVwZGF0ZV9wcmljZV9mZWVkcyJ9LHsia2V5IjoibnVtX2F0dGVzdGF0aW9ucyIsInZhbHVlIjoiMTQifSx7ImtleSI6Im51bV91cGRhdGVkIiwidmFsdWUiOiIxNCJ9XX0seyJ0eXBlIjoiaW5qZWN0aXZlLm9yYWNsZS52MWJldGExLkV2ZW50U2V0UHl0aFByaWNlcyIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InByaWNlcyIsInZhbHVlIjoiW3tcInByaWNlX2lkXCI6XCIweGZlNjUwZjAzNjdkNGE3ZWY5ODE1YTU5M2VhMTVkMzY1OTNmMDY0M2FhYWYwMTQ5YmIwNGJlNjdhYjg1MWRlY2RcIixcImVtYV9wcmljZVwiOlwiNzIuNjcxMjI2MDAwMDAwMDAwMDAwXCIsXCJlbWFfY29uZlwiOlwiMC4wMzg5OTk5NTAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjAuMDMzMzE0MzAwMDAwMDAwMDAwXCIsXCJwdWJsaXNoX3RpbWVcIjpcIjE3MDIwMzkwNTdcIixcInByaWNlX3N0YXRlXCI6e1wicHJpY2VcIjpcIjczLjI4MTUzOTkxMDAwMDAwMDAwMFwiLFwiY3VtdWxhdGl2ZV9wcmljZVwiOlwiNTk1NjAyMjQ3LjEzNjEzNTY0MDAwMDAwMDAwMFwiLFwidGltZXN0YW1wXCI6XCIxNzAyMDM5MDU4XCJ9fSx7XCJwcmljZV9pZFwiOlwiMHgxZmMxODg2MTIzMjI5MDIyMTQ2MTIyMGJkNGUyYWNkMWRjZGZiYzg5Yzg0MDkyYzkzYzE4YmRjNzc1NmMxNTg4XCIsXCJlbWFfcHJpY2VcIjpcIjEuMDAwMTM5MzkwMDAwMDAwMDAwXCIsXCJlbWFfY29uZlwiOlwiMC4wMDAyNTQ0OTAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjAuMDAwMjIwNDkwMDAwMDAwMDAwXCIsXCJwdWJsaXNoX3RpbWVcIjpcIjE3MDIwMzkwNTdcIixcInByaWNlX3N0YXRlXCI6e1wicHJpY2VcIjpcIjEuMDAwMTA1NTEwMDAwMDAwMDAwXCIsXCJjdW11bGF0aXZlX3ByaWNlXCI6XCIyMzIyNzc5Ni40NzU2MjQ3MzAwMDAwMDAwMDBcIixcInRpbWVzdGFtcFwiOlwiMTcwMjAzOTA1OFwifX0se1wicHJpY2VfaWRcIjpcIjB4ZjljMDE3MmJhMTBkZmE0ZDE5MDg4ZDk0ZjViZjYxZDNiNTRkNWJkNzQ4M2EzMjJhOTgyZTEzNzNlZThlYTMxYlwiLFwiZW1hX3ByaWNlXCI6XCI0MzQ4MS40NDcwMDAwMDAwMDAwMDAwMDBcIixcImVtYV9jb25mXCI6XCIxMy4zMDA4MzIzMDAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjE1LjIyMTA3OTQ1MDAwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU3XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCI0MzY5Ny4zNTE5NTU1MzAwMDAwMDAwMDBcIixcImN1bXVsYXRpdmVfcHJpY2VcIjpcIjY4MzMwNjY2NjY4NC45NjIwNDczMjAwMDAwMDAwMDBcIixcInRpbWVzdGFtcFwiOlwiMTcwMjAzOTA1OFwifX0se1wicHJpY2VfaWRcIjpcIjB4MzdmNDBkMjg5ODE1OWU4ZjJlNTJiOTNjYjc4ZjQ3Y2MzODI5YTMxZTUyNWFiOTc1YzQ5Y2M1YzVkOTE3NjM3OFwiLFwiZW1hX3ByaWNlXCI6XCIxLjE2NDc0OTgxMDAwMDAwMDAwMFwiLFwiZW1hX2NvbmZcIjpcIjAuMDAwNjM4MTcwMDAwMDAwMDAwXCIsXCJjb25mXCI6XCIwLjAwMDU3ODk2MDAwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU3XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCIxLjE3MDM4MTA0MDAwMDAwMDAwMFwiLFwiY3VtdWxhdGl2ZV9wcmljZVwiOlwiMjQxNzYzMTkuNDE3NDMwMDgwMDAwMDAwMDAwXCIsXCJ0aW1lc3RhbXBcIjpcIjE3MDIwMzkwNThcIn19LHtcInByaWNlX2lkXCI6XCIweDMwYTE5MTU4ZjVhNTRjMGFkZjhmYjc1NjA2MjczNDNmMjJhMWJjODUyYjg5ZDU2YmUxYWNjZGM1ZGJmOTZkMGVcIixcImVtYV9wcmljZVwiOlwiMjAyOS40MDAwMDAwMDAwMDAwMDAwMDBcIixcImVtYV9jb25mXCI6XCIwLjEyNTAwMDAwMDAwMDAwMDAwMFwiLFwiY29uZlwiOlwiMC4xMTUwMDAwMDAwMDAwMDAwMDBcIixcInB1Ymxpc2hfdGltZVwiOlwiMTcwMjAzOTA1N1wiLFwicHJpY2Vfc3RhdGVcIjp7XCJwcmljZVwiOlwiMjAyOC43NjAwMDAwMDAwMDAwMDAwMDBcIixcImN1bXVsYXRpdmVfcHJpY2VcIjpcIjQzNzQ1MDU5NjM4LjQyMDAwMDAwMDAwMDAwMDAwMFwiLFwidGltZXN0YW1wXCI6XCIxNzAyMDM5MDU4XCJ9fSx7XCJwcmljZV9pZFwiOlwiMHhjMWIxMjc2OWY2NjMzNzk4ZDQ1YWRmZDYyYmZjNzAxMTQ4MzkyMzJlMjk0OWIwMWZiM2QzZjkyN2QyNjA2MTU0XCIsXCJlbWFfcHJpY2VcIjpcIjEuMDc4MjUwMDAwMDAwMDAwMDAwXCIsXCJlbWFfY29uZlwiOlwiMC4wMDAxMDAwMDAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjAuMDAwMTAwMDAwMDAwMDAwMDAwXCIsXCJwdWJsaXNoX3RpbWVcIjpcIjE3MDIwMzkwNTdcIixcInByaWNlX3N0YXRlXCI6e1wicHJpY2VcIjpcIjEuMDc4MzUwMDAwMDAwMDAwMDAwXCIsXCJjdW11bGF0aXZlX3ByaWNlXCI6XCIyNDIzNzczMS4wNzEwMTAwMDAwMDAwMDAwMDBcIixcInRpbWVzdGFtcFwiOlwiMTcwMjAzOTA1OFwifX0se1wicHJpY2VfaWRcIjpcIjB4MzIxYmE0ZDYwOGZhNzViYTc2ZDZkNzNkYWE3MTVhYmNiZGViOWRiYTAyMjU3ZjA1YTFiNTkxNzhiNDlmNTk5YlwiLFwiZW1hX3ByaWNlXCI6XCIyMy44MDQxNTAwMDAwMDAwMDAwMDBcIixcImVtYV9jb25mXCI6XCIwLjAwNTAwMDAwMDAwMDAwMDAwMFwiLFwiY29uZlwiOlwiMC4wMDYyNTAwMDAwMDAwMDAwMDBcIixcInB1Ymxpc2hfdGltZVwiOlwiMTcwMjAzOTA1N1wiLFwicHJpY2Vfc3RhdGVcIjp7XCJwcmljZVwiOlwiMjMuNzc1NzUwMDAwMDAwMDAwMDAwXCIsXCJjdW11bGF0aXZlX3ByaWNlXCI6XCI1MjkwNjUwMTUuNTE0ODEwMDAwMDAwMDAwMDAwXCIsXCJ0aW1lc3RhbXBcIjpcIjE3MDIwMzkwNThcIn19LHtcInByaWNlX2lkXCI6XCIweDIwYTkzOGY1NGI2OGYxZjJlZjE4ZWEwMzI4ZjZkZDA3NDdmOGVhMTE0ODZkMjJiMDIxZTgzYTkwMGJlODk3NzZcIixcImVtYV9wcmljZVwiOlwiMTQ0LjM4MTAwMDAwMDAwMDAwMDAwMFwiLFwiZW1hX2NvbmZcIjpcIjAuMDA4MDAwMDAwMDAwMDAwMDAwXCIsXCJjb25mXCI6XCIwLjAwODAwMDAwMDAwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU3XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCIxNDQuMjg1MDAwMDAwMDAwMDAwMDAwXCIsXCJjdW11bGF0aXZlX3ByaWNlXCI6XCIzMTQ4MTY5NTYzLjY5MjAwMDAwMDAwMDAwMDAwMFwiLFwidGltZXN0YW1wXCI6XCIxNzAyMDM5MDU4XCJ9fSx7XCJwcmljZV9pZFwiOlwiMHhiY2JkYzI3NTViZDc0YTIwNjVmOWQzMjgzYzJiOGFjYmQ4OThlNDczYmRiOTBhNjc2NGIzZGJkNDY3YzU2ZWNkXCIsXCJlbWFfcHJpY2VcIjpcIjEuMjU3NzMwMDAwMDAwMDAwMDAwXCIsXCJlbWFfY29uZlwiOlwiMC4wMDAwOTAwMDAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjAuMDAwMTAwMDAwMDAwMDAwMDAwXCIsXCJwdWJsaXNoX3RpbWVcIjpcIjE3MDIwMzkwNTdcIixcInByaWNlX3N0YXRlXCI6e1wicHJpY2VcIjpcIjEuMjU3NjAwMDAwMDAwMDAwMDAwXCIsXCJjdW11bGF0aXZlX3ByaWNlXCI6XCIyNzk5MTIyNS43NTQ3MDAwMDAwMDAwMDAwMDBcIixcInRpbWVzdGFtcFwiOlwiMTcwMjAzOTA1OFwifX0se1wicHJpY2VfaWRcIjpcIjB4Y2E4MGJhNmRjMzJlMDhkMDZmMWFhODg2MDExZWVkMWQ3N2M3N2JlOWViNzYxY2MxMGQ3MmI3ZDBhMmZkNTdhNlwiLFwiZW1hX3ByaWNlXCI6XCIyMzYyLjg1NzI0MDAwMDAwMDAwMDAwMFwiLFwiZW1hX2NvbmZcIjpcIjAuOTEzODg2NTEwMDAwMDAwMDAwXCIsXCJjb25mXCI6XCIwLjkxOTk4NDUwMDAwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU3XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCIyMzY1LjIyOTk4NDUwMDAwMDAwMDAwMFwiLFwiY3VtdWxhdGl2ZV9wcmljZVwiOlwiNDE3OTY4MDExMjEuNzk4MDYyMjEwMDAwMDAwMDAwXCIsXCJ0aW1lc3RhbXBcIjpcIjE3MDIwMzkwNThcIn19LHtcInByaWNlX2lkXCI6XCIweDYxMjI2ZDM5YmVlYTE5ZDMzNGYxN2MyZmViY2UyN2UxMjY0NmQ4NDY3NTkyNGViYjAyYjljZGFlYTY4NzI3ZTNcIixcImVtYV9wcmljZVwiOlwiMTAuMTMxMjc3OTAwMDAwMDAwMDAwXCIsXCJlbWFfY29uZlwiOlwiMC4wMDYzOTcwNDAwMDAwMDAwMDBcIixcImNvbmZcIjpcIjAuMDA1ODQ0NDQwMDAwMDAwMDAwXCIsXCJwdWJsaXNoX3RpbWVcIjpcIjE3MDIwMzkwNTdcIixcInByaWNlX3N0YXRlXCI6e1wicHJpY2VcIjpcIjEwLjI0NDk0NDQzMDAwMDAwMDAwMFwiLFwiY3VtdWxhdGl2ZV9wcmljZVwiOlwiMjEzODk1OTI4Ljc1Nzk5NTcyMDAwMDAwMDAwMFwiLFwidGltZXN0YW1wXCI6XCIxNzAyMDM5MDU4XCJ9fSx7XCJwcmljZV9pZFwiOlwiMHgyZDkzMTVhODhmMzAxOWY4ZWZhODhkZmU5YzBmMDg0MzcxMmRhMGJhYzgxNDQ2MWUyNzczM2Y2YjgzZWI1MWIzXCIsXCJlbWFfcHJpY2VcIjpcIjE5LjQwMTcyNTQwMDAwMDAwMDAwMFwiLFwiZW1hX2NvbmZcIjpcIjAuMDIyODgzNzUwMDAwMDAwMDAwXCIsXCJjb25mXCI6XCIwLjAyNDI0MzIxMDAwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU3XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCIxOS42MTQxMzc3MTAwMDAwMDAwMDBcIixcImN1bXVsYXRpdmVfcHJpY2VcIjpcIjE5Njk2NjI1Ni4xNTc4MjA0ODAwMDAwMDAwMDBcIixcInRpbWVzdGFtcFwiOlwiMTcwMjAzOTA1OFwifX0se1wicHJpY2VfaWRcIjpcIjB4ZWQ4MmVmYmZhZGUwMTA4M2ZmYThmNjQ2NjRjODZhZjM5MjgyYzlmMDg0ODc3MDY2YWU3MmI2MzVlNzc3MThmMFwiLFwiZW1hX3ByaWNlXCI6XCIwLjAwMDAwMTUzODAwMDAwMDAwMFwiLFwiZW1hX2NvbmZcIjpcIjAuMDAwMDAwMDA1ODAwMDAwMDAwXCIsXCJjb25mXCI6XCIwLjAwMDAwMDAwNjYwMDAwMDAwMFwiLFwicHVibGlzaF90aW1lXCI6XCIxNzAyMDM5MDU1XCIsXCJwcmljZV9zdGF0ZVwiOntcInByaWNlXCI6XCIwLjAwMDAwMTU0NTAwMDAwMDAwMFwiLFwiY3VtdWxhdGl2ZV9wcmljZVwiOlwiMjAuOTYzNzUwNDQyMjAwMDAwMDAwXCIsXCJ0aW1lc3RhbXBcIjpcIjE3MDIwMzkwNThcIn19LHtcInByaWNlX2lkXCI6XCIweDQxZjM2MjU5NzFjYTJlZDIyNjNlNzg1NzNmZTVjZTIzZTEzZDI1NThlZDNmMmU0N2FiMGY4NGZiOWU3YWU3MjJcIixcImVtYV9wcmljZVwiOlwiMS4wMDAwMTE2NDAwMDAwMDAwMDBcIixcImVtYV9jb25mXCI6XCIwLjAwMDI3NDE1MDAwMDAwMDAwMFwiLFwiY29uZlwiOlwiMC4wMDAyOTk5NzAwMDAwMDAwMDBcIixcInB1Ymxpc2hfdGltZVwiOlwiMTcwMjAzOTA1N1wiLFwicHJpY2Vfc3RhdGVcIjp7XCJwcmljZVwiOlwiMC45OTk5OTk5OTAwMDAwMDAwMDBcIixcImN1bXVsYXRpdmVfcHJpY2VcIjpcIjIzMjIyMDc2Ljg1MzYxNTM4MDAwMDAwMDAwMFwiLFwidGltZXN0YW1wXCI6XCIxNzAyMDM5MDU4XCJ9fV0ifV19XX1d",
         "id":"",
         "codespace":"",
         "errorLog":"",
         "code":0,
         "claimIds":[

         ]
      }
   ]
}
}
{
 "paging": {
  "total": 100000,
  "from": 6007200,
  "to": 6001687
 },
 "data": [
  {
   "block_number": 6007200,
   "block_timestamp": "2022-05-31 12:48:34.886 +0000 UTC",
   "hash": "0xaaf6e69819ade1b9bdc128ec84d35a0d928c46082007522f1ac80b999f62adfd",
   "data": "CjQKMi9pbmplY3RpdmUub3JhY2xlLnYxYmV0YTEuTXNnUmVsYXlDb2luYmFzZU1lc3NhZ2Vz",
   "gas_wanted": 784680,
   "gas_used": 538379,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "392340000000000"
     }
    ],
    "gas_limit": 784680,
    "payer": "inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8"
   },
   "tx_type": "injective",
   "messages": "[{\"type\":\"/injective.oracle.v1beta1.MsgRelayCoinbaseMessages\",\"value\":{\"messages\":[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1rce1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCVEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHT/28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANFVEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf0IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANYVFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpX2mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPQRQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANEQUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACk3wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANSRVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaOoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANaUlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGHVEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCQVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh82gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANLTkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwiJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARMSU5LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPA/6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARDT01QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXleAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANVTkkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWcIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUlQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv2/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANTTlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"],\"sender\":\"inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8\",\"signatures\":[\"zCWD1dTt0tIGMPwd/8ff81HrG6nloxk6EVb1r7SOgO+c3NDRFoTqRGbQ4PwuDYAXzrTIznkiax808YeqbltB+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"/kefMAblMcZEff6jiTRbYl0nmhSGVkCGeKBznKhQ5sldNytKBgWV7WQxGS9vbRXk/PSOgt6wHJ7ZRxdHw3LogwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"FdnISEwJs5jBx4PQFO4snJLjc7KSZ46hWzeruHnqFcoMN9ojanwnk/vKO13rKVqUWZb7l4Oak9hWJ/rYXLi86wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"0dWYExhIsaEL2/7xD1z2tPFbmxtXE9SRnOF/FCLsvMkenMopwQxK82oe+qK2Ts2pXVE7oFO6IyMQWCLIeVIcrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"+UhX91gBZchuBZ21gdg6toGJEU4egivkRT5lEoh+AReN7ClIDhEKvKp/nVhEa5+zzIXY/5KCWOcGZlJ/Pfx8zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"e1ho1uftysZdxNIg+701zAanvZxtEjSnfXynDWW7x6Wo79/mBs+KUpHzUfhlYxp8mgoOZbGCp3k5l83/4lhYwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"n8MD/MYj6B4u0YMiGrJOYdlQ3U6tfbOxBRptWgr6x/aLj2eKbcE5gmg6gGVas9WBvjquKAhQR8U5MhYkLbqYbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"txgWSFuq4x8o44kvl4I1GCryAa6gUzPTWAKWLxfp6HtzIWVoFDsiz1dFDngfaIBPo+lmvak1lEBES+I9Ai2O6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"BrWea8Hrzn6hd2rEZ6MYMcxUw7+a3xomj554oY4okaW8YaDFHl+Qjx83rYN/hV++I016oofLLpSQ7Un/t2gGVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"A8Ls0YNqqj8DHofRIhkpG+KgM1qitVYyx72/8qPhi9kymmzEnWNaAnsNqBvBGvXka1e5u9bCFTmdx3lHpVe3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"QCnXDJR/47TZ9OJ0jEUxdPgp2tvbJvNUMkupmY0qE6rbrdMbbihu0oRn8q3TAzfELimrj3HuXqmi4dHjCfulVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"oE3BN/deGTEqyXcfx+jmTjzp3uY9YPo3x8m678U6zKPTkE3eR1tnQ5tmwOOfejm7h5XzFWpnSdFylVKLBNqU1wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"+QU+45qb2cZL3jtmCtmXpUl1kROnRF0f4XiQ5sU+liRoqY/LKJDfKoy/ufqmApjGzYNuB6ccmKS2fLduARDZ0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\"]}}]",
   "signatures": [
    {
     "pubkey": "injvalcons128jwakuw3wrq6ye7m4p64wrzc5rfl8tvdh7raz",
     "address": "inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8",
     "sequence": 54715,
     "signature": "DDzBCEVmF9uNCt0kH9BSBcWYNs/D4ePWAPil/JU8FaMInn5ENSGNZ2qzPQPtnPxl63Z6pIMkeGFlxIlZo4COuAE="
    }
   ]
  },
  {
   "block_number": 6007111,
   "block_timestamp": "2022-05-31 12:45:41.945 +0000 UTC",
   "hash": "0x57d2c0dd087206f9772efdb6901b66c604d75c023d89a5c9614893e6157d1df1",
   "data": "CjQKMi9pbmplY3RpdmUub3JhY2xlLnYxYmV0YTEuTXNnUmVsYXlDb2luYmFzZU1lc3NhZ2Vz",
   "gas_wanted": 710127,
   "gas_used": 488677,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "355063500000000"
     }
    ],
    "gas_limit": 710127,
    "payer": "inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8"
   },
   "tx_type": "injective",
   "messages": "[{\"type\":\"/injective.oracle.v1beta1.MsgRelayCoinbaseMessages\",\"value\":{\"messages\":[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1oqt4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCVEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHTk7UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANFVEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfqXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANYVFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpX2mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPQRQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANEQUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClLSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANSRVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaNIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANaUlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGFSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCQVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhyTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANLTkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARMSU5LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO84PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARDT01QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXW0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANVTkkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWDIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUlQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpYNkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnByaWNlcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANTTlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"],\"sender\":\"inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8\",\"signatures\":[\"YL231HABMdVXctipqLhc638wBgdTFpwOZAdAgPgefAjXC8Vvl65gXzw9cNRJOY0kA4vCt0g8FiF9YqdOw1jnbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"kGtm079wAMRGGjJPT/WuLvd4M5LNTcjkIoTDI8SW6j6wwFhUYblYscAvJsqdtNxKzUB/s93g48nbfYbV+HRlrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"LXYjHiXRC5HTKlylmfF+diCBzrAOY74yrKPNNqnN8RS+d+TKT/hx8CLGQt3QuLxlWnNg7BwucO+/TfhMauyp0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"0dWYExhIsaEL2/7xD1z2tPFbmxtXE9SRnOF/FCLsvMkenMopwQxK82oe+qK2Ts2pXVE7oFO6IyMQWCLIeVIcrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"kkHcQL/fE+b4cXcTpxwL6gCiEHSx6vFapLVJ6pD+VQ5fv+FUZDj20fgMhigsA3cKa0TRhqB4VW/yeBeYeo+dtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"NgCe7fZDDgiHYKzTQGCmRvcCBO6hAtK+Lray3inBoJ2U5X102+9+hrW0843QToBG1LYHZ9kQ81DzkMNe6lKmLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"RGiVY4JdjfVmXcIu5qcwhFwTTDl/Vi8etEMA3wGCisPqmG5x1/ibcTBqwu+bRftdaS1tR1EndDW+wsVvyJ27tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"wvgniA1t3o6E/2t9OsqWKZq9vDlmOD8KR8/m3rjUnupQpv1fQ/b84T/FsFRezSZrfD1FUGUJZU4OpI90cvsN1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"/Eks8pFIMrD64hlAwpNVmns4AwCVgsjty7ckBiKrau6ZPtmm7JyW0PcaAuvHtT+y2NE0F6I9h2fPzOIi+VCXLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"Ielef8mF/3IUz3VMl1uvbcgqs1i4jvgHPviwF5S6gkFDSa/YfPUp022c9+Q3pW7tidxaqWQbbayOUI9XrFBoNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"1EDj3Pq/bh07CAE7EYReXiZgMH/tEFkar112JmsK83tWaCBuw6iRvZ43GqMvmnn5vU66axYg58UdxAcrkexfRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\",\"V1yoJNEvPhwT6BQ3HlpZsEaJgy/SHrb9cfMi9gg3GpbfkDvDx0qhrgkMPyd/YSCk+0Vpfyc9p15GbM4KfjwPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc\",\"iUoHMZwEx1gIjM8p8fejb6YAwMw+xzDshdnlr9mdosrP6qDjxOXqzcX644Nk8J2qG5Jd3QPgrSfbYP5fz9CggQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb\"]}}]",
   "signatures": [
    {
     "pubkey": "injvalcons128jwakuw3wrq6ye7m4p64wrzc5rfl8tvdh7raz",
     "address": "inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8",
     "sequence": 54714,
     "signature": "HetA8jXHA1wsAF4HhO5DkQL+qZNkYnZP6IRlYANqz+ZByTFXbJ9suv1qZFMtHxANMkThjsNHfoNR3FyLCH+z9AA="
    }
   ]
  }
 ]
}
ParameterTypeDescription
pagingPaging
dataTxData array


TxData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codespacestring
messagesbyte array
tx_numberuint64
error_logstringTransaction log indicating errors
codeuint32
tx_msg_typesbyte array
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim
signaturesSignature array
block_unix_timestampuint64Block timestamp in unix milli
ethereum_tx_hash_hexstring


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

StreamTxs

Stream transactions.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def tx_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to txs updates ({exception})")


def stream_closed_processor():
    print("The txs updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)

    task = asyncio.get_event_loop().create_task(
        client.listen_txs_updates(
            callback=tx_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    stream, err := explorerClient.StreamTxs(ctx)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}

No parameters

Response Parameters

Response Example:

{
   "blockNumber":"19388455",
   "blockTimestamp":"2023-12-08 12:39:19.596 +0000 UTC",
   "hash":"0xf4f17301c06df63160b60a071985fc0e0093a53e4027a2086fc51b0a46b6b43c",
   "messages":"[{\"type\":\"/cosmos.authz.v1beta1.MsgExec\",\"value\":{\"grantee\":\"inj12shqy72r0apr4d9ft9x6z59t5yfjj4jv9n79l6\",\"msgs\":[{\"@type\":\"/injective.exchange.v1beta1.MsgBatchUpdateOrders\",\"sender\":\"inj15uad884tqeq9r76x3fvktmjge2r6kek55c2zpa\",\"subaccount_id\":\"\",\"spot_market_ids_to_cancel_all\":[],\"derivative_market_ids_to_cancel_all\":[],\"spot_orders_to_cancel\":[],\"derivative_orders_to_cancel\":[],\"spot_orders_to_create\":[],\"derivative_orders_to_create\":[{\"market_id\":\"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6\",\"order_info\":{\"subaccount_id\":\"0xa73ad39eab064051fb468a5965ee48ca87ab66d4000000000000000000000004\",\"fee_recipient\":\"inj15uad884tqeq9r76x3fvktmjge2r6kek55c2zpa\",\"price\":\"18495900.000000000000000000\",\"quantity\":\"60.000000000000000000\",\"cid\":\"HBOTSIJUT60bfedf775353d7bf700310e7cd\"},\"order_type\":\"SELL\",\"margin\":\"0.000000000000000000\",\"trigger_price\":\"0.000000000000000000\"}],\"binary_options_orders_to_cancel\":[],\"binary_options_market_ids_to_cancel_all\":[],\"binary_options_orders_to_create\":[]}]}}]",
   "txNumber":"17748407",
   "id":"",
   "codespace":"",
   "errorLog":"",
   "code":0,
   "claimIds":[

   ]
}
{
 "block_number": 6129344,
 "block_timestamp": "2022-06-03 06:48:33.883 +0000 UTC",
 "hash": "0x8cbfc9c361abea5b59c95ed8096cd55d9b41af68e0fd81fab049f9e9aaace206",
 "data": "CnwKNC9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dDcmVhdGVTcG90TWFya2V0T3JkZXISRApCMHgzNGVjMGEyNTQzYWM5NmZlZmM2NWE0ZmQyMDUyOWE5MWQ4MzRiYzgwMzEwMzQ3M2FhYTlmYWY2YWMyMjVmYzNm",
 "gas_wanted": 129946,
 "gas_used": 101840,
 "gas_fee": {
  "amount": [
   {
    "denom": "inj",
    "amount": "64973000000000"
   }
  ],
  "gas_limit": 129946,
  "payer": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
 },
 "tx_type": "injective",
 "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateSpotMarketOrder\",\"value\":{\"order\":{\"market_id\":\"0x8b1a4d3e8f6b559e30e40922ee3662dd78edf7042330d4d620d188699d1a9715\",\"order_info\":{\"fee_recipient\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\",\"price\":\"0.984400000000000000\",\"quantity\":\"23000000.000000000000000000\",\"subaccount_id\":\"0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000\"},\"order_type\":\"BUY\",\"trigger_price\":null},\"sender\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\"}}]",
 "signatures": [
  {
   "pubkey": "injvalcons1cml96vmptgw99syqrrz8az79xer2pcgpvgp7ex",
   "address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
   "sequence": 2087458,
   "signature": "UWKbIKeR4a2Ws1zE5vno5Q71WLIiUzB4dGhJzLuUtLQWV09PcP/a40L0nzw0hnMEhSqJUeDk9oj0PVr6c0ZMZQE="
  }
 ]
}{
 "block_number": 6129345,
 "block_timestamp": "2022-06-03 06:48:35.803 +0000 UTC",
 "hash": "0x13177ab51add513cfae7586886954c6bc818c18d8523a4c29475d66114917cb3",
 "data": "CnwKNC9pbmplY3RpdmUuZXhjaGFuZ2UudjFiZXRhMS5Nc2dDcmVhdGVTcG90TWFya2V0T3JkZXISRApCMHhmY2MyNmRjYzc0OTQwMWRjZTA0NmNkM2M5M2QwNzczMzZkOGI1MDhiYTk0N2MxMzA4MjlhMzllNThjYzA1YzI2",
 "gas_wanted": 130489,
 "gas_used": 102202,
 "gas_fee": {
  "amount": [
   {
    "denom": "inj",
    "amount": "65244500000000"
   }
  ],
  "gas_limit": 130489,
  "payer": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
 },
 "tx_type": "injective",
 "messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateSpotMarketOrder\",\"value\":{\"order\":{\"market_id\":\"0xbe9d4a0a768c7e8efb6740be76af955928f93c247e0b3a1a106184c6cf3216a7\",\"order_info\":{\"fee_recipient\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\",\"price\":\"0.000000000071480000\",\"quantity\":\"240000000000000000000.000000000000000000\",\"subaccount_id\":\"0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000\"},\"order_type\":\"BUY\",\"trigger_price\":null},\"sender\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\"}}]",
 "signatures": [
  {
   "pubkey": "injvalcons1cml96vmptgw99syqrrz8az79xer2pcgpvgp7ex",
   "address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
   "sequence": 2087459,
   "signature": "yXQON133B3lJlVNkFwf0pvZof6GCoeKoIhMkKHe3sndfgf2aWs4DwlOVlbEZTY4X++x+PU6sZNngHACiuGqPmAE="
  }
 ]
}
ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codespacestring
messagesstring
tx_numberuint64
error_logstringTransaction log indicating errors
codeuint32
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim

StreamBlocks

Stream blocks.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def block_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to blocks updates ({exception})")


def stream_closed_processor():
    print("The blocks updates stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)

    task = asyncio.get_event_loop().create_task(
        client.listen_blocks_updates(
            callback=block_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    stream, err := explorerClient.StreamBlocks(ctx)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}

No parameters

Response Parameters

Response Example:

{
   "height":"19388498",
   "proposer":"injvalcons1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a",
   "moniker":"InjectiveNode2",
   "blockHash":"0xf12fd7ce5a00a4bab5028f6b6e94e014d31074b8f4a45d03731ab640533c71b7",
   "parentHash":"0x601b7b2c202e8142535b1a76ec095a05e91c2507cbb462d59c0fd251fd769255",
   "numTxs":"2",
   "timestamp":"2023-12-08 12:40:51.641 +0000 UTC",
   "numPreCommits":"0",
   "txs":[

   ]
}
{
   "height":"19388499",
   "proposer":"injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz",
   "moniker":"InjectiveNode0",
   "blockHash":"0x36bc946dba7fd81ea9b8dac4a70ca20ff4bc8e59b6ed2005e397d6ab0d3655d7",
   "parentHash":"0xf37f966ec5d8275c74f25fbb3c39e7f58b30ca36dff5592cde44dd251b943fd8",
   "numTxs":"3",
   "timestamp":"2023-12-08 12:40:53.945 +0000 UTC",
   "numPreCommits":"0",
   "txs":[

   ]
}
{
   "height":"19388500",
   "proposer":"injvalcons18x63wcw5hjxlf535lgn4qy20yer7mm0qedu0la",
   "moniker":"InjectiveNode1",
   "blockHash":"0x1da9e10a726da84a5f7b53e25a598165a5ac44b573b7a3a7a1044242f9de2c83",
   "parentHash":"0xad1f884d19fac8c6abc8b1e896e34a84583c49dc3ff66070c477a5af71bf54a2",
   "numTxs":"2",
   "timestamp":"2023-12-08 12:40:56.463 +0000 UTC",
   "numPreCommits":"0",
   "txs":[

   ]
}
{
 "height": 6009287,
 "proposer": "injvalcons1aju53n6la4xzemws8gqnvr9v8hsjdea706jq7f",
 "moniker": "InjectiveNode2",
 "block_hash": "0x9ad53714c72b66d4c347814a0b14975160cda0f22e48df1e59cf1f4e9c083526",
 "parent_hash": "0x3a8aa6a5f7b9c3647442a0a7f43586c30b66b216ff3e29c373e9b02cbb81f51b",
 "timestamp": "2022-05-31 13:56:17.644 +0000 UTC"
}{
 "height": 6009288,
 "proposer": "injvalcons1qmrj7lnzraref92lzuhrv6m7sxey248fzxmfnf",
 "moniker": "InjectiveNode3",
 "block_hash": "0x1869065635c1b726d973ea154c49736dbcf3159975b4ef6236a85128ee0ad69a",
 "parent_hash": "0xb9054fd1f6ca37ba8d2507636685ceb548a6dc224c4658f6ec4e118ef803a6e8",
 "timestamp": "2022-05-31 13:56:19.657 +0000 UTC"
}
ParameterTypeDescription
heightuint64
proposerstring
monikerstring
block_hashstring
parent_hashstring
num_pre_commitsint64
num_txsint64
txsTxDataRPC array
timestampstring
block_unix_timestampuint64Block timestamp in unix milli


TxDataRPC

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codespacestring
messagesstring
tx_numberuint64
error_logstringTransaction log indicating errors
codeuint32
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim

PeggyDeposits

Get info on peggy deposits. By default, deposits for all senders and receivers will be fetched.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    receiver = "inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex"
    peggy_deposits = await client.fetch_peggy_deposit_txs(receiver=receiver)
    print(json.dumps(peggy_deposits, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    receiver := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"

    req := explorerPB.GetPeggyDepositTxsRequest{
        Receiver: receiver,
    }

    res, err := explorerClient.GetPeggyDeposits(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
senderstringSender address of deposit requestYes
receiverstringAddress of receiveer upon depositYes
limitint32Yes
skipuint64Yes

Response Parameters

Response Example:

{
   "field":[
      {
         "sender":"0x197E6c3f19951eA0bA90Ddf465bcC79790cDD12d",
         "receiver":"inj1r9lxc0cej502pw5smh6xt0x8j7gvm5fdrj6xhk",
         "eventNonce":"624",
         "eventHeight":"10122722",
         "amount":"500000000000000000",
         "denom":"0xAD1794307245443B3Cb55d88e79EEE4d8a548C03",
         "orchestratorAddress":"inj1c8rpu79mr70hqsgzutdd6rhvzhej9vntm6fqku",
         "state":"Completed",
         "claimType":1,
         "txHashes":[
            "0x028a43ad2089cad45a8855143508f7381787d7f17cc19e3cda1bc2300c1d043f"
         ],
         "createdAt":"2023-11-28 16:55:54.841 +0000 UTC",
         "updatedAt":"2023-11-28 16:56:07.944 +0000 UTC"
      },
      {
         "sender":"0x197E6c3f19951eA0bA90Ddf465bcC79790cDD12d",
         "receiver":"inj1r9lxc0cej502pw5smh6xt0x8j7gvm5fdrj6xhk",
         "eventNonce":"622",
         "eventHeight":"10094898",
         "amount":"550000000000000000",
         "denom":"0xAD1794307245443B3Cb55d88e79EEE4d8a548C03",
         "orchestratorAddress":"inj1c8rpu79mr70hqsgzutdd6rhvzhej9vntm6fqku",
         "state":"Completed",
         "claimType":1,
         "txHashes":[
            "0xa528a522ce00b0f44add4a634ec92417c483fc045aa6b3f1cfceb685cdcf13a7"
         ],
         "createdAt":"2023-11-23 18:09:52.228 +0000 UTC",
         "updatedAt":"2023-11-23 18:10:31.294 +0000 UTC"
      }
   ]
}
{
 "field": [
  {
   "sender": "0xbdAEdEc95d563Fb05240d6e01821008454c24C36",
   "receiver": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "event_nonce": 201,
   "event_height": 31544480,
   "amount": "1000000000000000000",
   "denom": "0x36B3D7ACe7201E28040eFf30e815290D7b37ffaD",
   "orchestrator_address": "inj1ultw9r29l8nxy5u6thcgusjn95vsy2caecl0ps",
   "state": "Completed",
   "claim_type": 1,
   "tx_hashes": [
    "0x8de1bf0f32966d2edf09378bc0e1d292f8ae34c45ae0b37a847867753a4b37a6"
   ],
   "created_at": "2022-06-01 07:25:47.077 +0000 UTC",
   "updated_at": "2022-06-01 07:32:01.671 +0000 UTC"
  },
  {
   "sender": "0xbdAEdEc95d563Fb05240d6e01821008454c24C36",
   "receiver": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "event_nonce": 200,
   "event_height": 31396037,
   "amount": "1000000000000000000",
   "denom": "0x36B3D7ACe7201E28040eFf30e815290D7b37ffaD",
   "orchestrator_address": "inj1ultw9r29l8nxy5u6thcgusjn95vsy2caecl0ps",
   "state": "Completed",
   "claim_type": 1,
   "tx_hashes": [
    "0x377c52c94f8cab6e91d4b56a5e65710c1452acc4b10bc26d111ceeab9e30a67f"
   ],
   "created_at": "2022-06-01 07:17:52.285 +0000 UTC",
   "updated_at": "2022-06-01 07:31:57.848 +0000 UTC"
  },
  {
   "sender": "0xAF79152AC5dF276D9A8e1E2E22822f9713474902",
   "receiver": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "event_nonce": 2,
   "event_height": 29335363,
   "amount": "50000000000000000000",
   "denom": "0xA3a9029B8120e2F09B194Df4A249A24dB461E573",
   "orchestrator_address": "inj1hs9q5xuvzunl77uv0mf0amsfa79uzhsrzak00a",
   "state": "InjectiveConfirming",
   "tx_hashes": [
    "0x97d223982ffef0a0550d75c8dfdb8fd661b8be28744d3f5b23cb8c1b328d1b3b"
   ],
   "created_at": "2022-05-18 21:03:34.991 +0000 UTC",
   "updated_at": "0001-01-01 00:00:00 +0000 UTC"
  }
 ]
}
ParameterTypeDescription
fieldPeggyDepositTx array


PeggyDepositTx

ParameterTypeDescription
senderstringSender address of deposit request
receiverstringAddress of receiveer upon deposit
event_nonceuint64The event nonce of WithdrawalClaim event emitted by Ethereum chain upon deposit
event_heightuint64The block height of WithdrawalClaim event emitted by Ethereum chain upon deposit
amountstringAmount of tokens being deposited
denomstringDenom of tokens being deposited
orchestrator_addressstringorchestratorAddress who created batch request
statestring
claim_typeint32The claimType will be DepoistClaim for Deposits
tx_hashesstring array
created_atstring
updated_atstring

PeggyWithdrawals

Get info on peggy withdrawals.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    sender = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    limit = 2
    pagination = PaginationOption(limit=limit)
    peggy_deposits = await client.fetch_peggy_withdrawal_txs(sender=sender, pagination=pagination)
    print(json.dumps(peggy_deposits, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    sender := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"

    req := explorerPB.GetPeggyWithdrawalTxsRequest{
        Sender: sender,
    }

    res, err := explorerClient.GetPeggyWithdrawals(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
senderstringSender address of withdrawal requestYes
receiverstringAddress of receiveer upon withdrawalYes
limitint32Yes
skipuint64Yes

Response Parameters

Response Example:

{
   "field":[
      {
         "sender":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "receiver":"0xAF79152AC5dF276D9A8e1E2E22822f9713474902",
         "amount":"1424956871765382404",
         "denom":"inj",
         "bridgeFee":"575043128234617596",
         "outgoingTxId":"1136",
         "batchTimeout":"10125614",
         "batchNonce":"1600",
         "orchestratorAddress":"inj1c8rpu79mr70hqsgzutdd6rhvzhej9vntm6fqku",
         "state":"Cancelled",
         "txHashes":[
            "0x0d9a7e280898b4452a4cd283c0447ea36d9f09f223d9812f64bbd694851dec8c",
            "0x9a456aa20d613c2cd646cbfff0b77c49e746757c24352e967578cd6e86ad62e1",
            "0x6ad03f12df86ead8efe52b1aecc35a4527c548283a901c71d6ca731a5bcf0a71",
            "0x8cb343b8ec48de5b30c9825156e29ab649570f15a8d1b4a4c850d736d99a670e",
            "0x9830d597d9ef2e60fa0c161cb0f39528e3d589c52bf365bf6971369025ce55ee",
            "0xa955975323aac3a3ad52adc45379a6ce19ec4d91f661265521a55139b2a6ad8d",
            "0x15dfa29c3f0e888b808b488c02f4596bbd6d30d566ddcf12fb80f658e6e2bc50",
            "0x016df0af7326ea14160f8f6d233578c9dfdecc9568b5b464deb80584ea00d652",
            "0xcf07704ba6ddf1ee4cdda30c594098ec7d4826fffc4a32891f76d1f632de5f61",
            "0xc6198363885fda70ec365020a99df9ba9b0a6dc880d7b83e956e7441c1cd8824",
            "0x25081d4593dc0f31c7e7465d2fbdb4f68289cd64b47968f532038085f9013ace",
            "0x684b59d4cd779d1333b9f2cfa5db1a28ed5ba6a9be3b96fa63aa0cf6577ade0e"
         ],
         "createdAt":"2023-11-09 07:37:31.258 +0000 UTC",
         "updatedAt":"2023-11-28 16:59:17.646 +0000 UTC",
         "eventNonce":"0",
         "eventHeight":"0",
         "claimType":0
      },
      {
         "sender":"inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
         "receiver":"0xAF79152AC5dF276D9A8e1E2E22822f9713474902",
         "amount":"19254843517138599106",
         "denom":"inj",
         "bridgeFee":"745156482861400894",
         "outgoingTxId":"912",
         "batchTimeout":"10125613",
         "batchNonce":"1598",
         "orchestratorAddress":"inj1qu62yv9xutqgeqms7gzvdnay5j5lph2j2e4q5h",
         "state":"Cancelled",
         "txHashes":[
            "0x1fc11c1db466716ad08237ec13128dead7a5edc2324a2d10eede9c45fd1789bc",
            "0x747b809a56f1e2f9065378df6f46a9e2d725f04ccf505608756aa41a73551235",
            "0x06db2f347054b394a70326314c04c2421757960a5b23724ec40cd84cc27ce44c",
            "0x3c36a54a326ad9eb37ccfb2b8d8db72f3d2b5bdbc8d3693bf202ce98b315bdd8",
            "0x7a2df716dae67e1fe9acbb336beda22882e92dc60836d19396305f9f03d34530",
            "0xe31b3b5cabdae870a4c93d15cadfa6ac173e7d60ee2f021f4a047d4523bf7481",
            "0x9d8d67e82d9f54477ca31e339643fc18b655fb24a9ebaa122400f49c5737df5e",
            "0xa9039fee3b119f27fb0e733d8cfe2f9e96af51802a6a4088af3a5cabb1fb6de8",
            "0x77d86350929b7cf6f4fe0094365bb71e9dc36a3e089a6af961cf05a153b54ade",
            "0x3846355740bcfa46d7ac9092e9065df0a7f232f2736ac05a09fff69ee32314f2",
            "0x86771d5fef383f8e256196d50ab62843aba63f3d23d3190f99cb882bcdaa45c9",
            "0x27c712e45ec0458c9a39cf031d3d5de2d1ba1ef8833528062508a1ef0a02e64b",
            "0x534fe5777662f31d098f6a5da2a73efc553a8fa81010da319162b7673062a90c",
            "0xaafcd570b535ecc063573a94e9dd58dfcfcb0f30853945aa79e64fccc5907688",
            "0x58258c46c3a674051e8c74c75ebe234942f85dacbeaba57c95ead9fa41b6d3a8",
            "0xa434119dd2e647db048cfad61f3b97feef6008c38e68d7c574a6153b41dd49fe"
         ],
         "createdAt":"2023-10-27 16:18:16.23 +0000 UTC",
         "updatedAt":"2023-11-28 16:59:04.777 +0000 UTC",
         "eventNonce":"0",
         "eventHeight":"0",
         "claimType":0
      }
   ]
}
{
 "field": [
  {
   "sender": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "receiver": "0xAF79152AC5dF276D9A8e1E2E22822f9713474902",
   "amount": "5000000000000000000",
   "denom": "inj",
   "bridge_fee": "2000000000000000000",
   "outgoing_tx_id": 113,
   "state": "InjectiveConfirming",
   "tx_hashes": [
    "0x391ab87558318bd7ff2ccb9d68ed309ad073fa64c8395a493d6c347ff572af38"
   ],
   "created_at": "2022-05-13 16:14:16.912 +0000 UTC",
   "updated_at": "0001-01-01 00:00:00 +0000 UTC"
  },
  {
   "sender": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
   "receiver": "0xAF79152AC5dF276D9A8e1E2E22822f9713474902",
   "amount": "23000000000000000000",
   "denom": "inj",
   "bridge_fee": "3546099290780142080",
   "outgoing_tx_id": 110,
   "state": "InjectiveConfirming",
   "tx_hashes": [
    "0x088975b8a12119944a254f0e4d7659df4c2b9c85c2c110305393f83be4f7f6ed"
   ],
   "created_at": "2022-05-11 10:32:20.19 +0000 UTC",
   "updated_at": "0001-01-01 00:00:00 +0000 UTC"
  }
 ]
}
ParameterTypeDescription
fieldPeggyWithdrawalTx array


PeggyWithdrawalTx

ParameterTypeDescription
senderstringSender address of withdrawal request
receiverstringAddress of receiveer upon withdrawal
amountstringAmount of tokens being withdrawan
denomstringDenom of tokens being withdrawan
bridge_feestringThe bridge fee paid by sender for withdrawal
outgoing_tx_iduint64A auto incremented unique ID representing the withdrawal request
batch_timeoutuint64The timestamp after which Batch request will be discarded if not processed already
batch_nonceuint64A auto incremented unique ID representing the Withdrawal Batches
orchestrator_addressstringorchestratorAddress who created batch request
event_nonceuint64The event nonce of WithdrawalClaim event emitted by Ethereum chain upon batch withdrawal
event_heightuint64The block height of WithdrawalClaim event emitted by Ethereum chain upon batch withdrawal
statestring
claim_typeint32The claimType will be WithdrawalClaim for Batch Withdrawals
tx_hashesstring array
created_atstring
updated_atstring

IBCTransfers

Get data on IBC transfers.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network=network)
    sender = "inj1cll5cv3ezgal30gagkhnq2um6zf6qrmhw4r6c8"
    receiver = "cosmos1usr9g5a4s2qrwl63sdjtrs2qd4a7huh622pg82"
    src_channel = "channel-2"
    src_port = "transfer"
    destination_channel = "channel-30"
    dest_port = "transfer"
    limit = 1
    skip = 10
    pagination = PaginationOption(limit=limit, skip=skip)
    ibc_transfers = await client.fetch_ibc_transfer_txs(
        sender=sender,
        receiver=receiver,
        src_channel=src_channel,
        src_port=src_port,
        dest_channel=destination_channel,
        dest_port=dest_port,
        pagination=pagination,
    )
    print(json.dumps(ibc_transfers, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    receiver := "inj1ddcp5ftqmntudn4m6heg2adud6hn58urnwlmkh"

    req := explorerPB.GetIBCTransferTxsRequest{
        Receiver: receiver,
    }

    res, err := explorerClient.GetIBCTransfers(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
senderstringYes
receiverstringYes
src_channelstringYes
src_portstringYes
dest_channelstringYes
dest_portstringYes
limitint32Yes
skipuint64Yes

Response Parameters

Response Example:

{
   "field":[
      {
         "sender":"inj14nendtsz0c40n7xtzwkjmdc8dkuz835jdydxhn",
         "receiver":"nois1mvuupgre7pjx3k5tm5729frkn9nvju6pgsxawc47pgamctypdzlsm7hg90",
         "sourcePort":"transfer",
         "sourceChannel":"channel-74",
         "destinationPort":"transfer",
         "destinationChannel":"channel-33",
         "amount":"1000000",
         "denom":"transfer/channel-74/unois",
         "timeoutHeight":"0-0",
         "timeoutTimestamp":"1702124625185146392",
         "packetSequence":"20509",
         "dataHex":"N2IyMjYxNmQ2Zjc1NmU3NDIyM2EyMjMxMzAzMDMwMzAzMDMwMjIyYzIyNjQ2NTZlNmY2ZDIyM2EyMjc0NzI2MTZlNzM2NjY1NzIyZjYzNjg2MTZlNmU2NTZjMmQzNzM0MmY3NTZlNmY2OTczMjIyYzIyNzI2NTYzNjU2OTc2NjU3MjIyM2EyMjZlNmY2OTczMzE2ZDc2NzU3NTcwNjc3MjY1Mzc3MDZhNzgzMzZiMzU3NDZkMzUzNzMyMzk2NjcyNmI2ZTM5NmU3NjZhNzUzNjcwNjc3Mzc4NjE3NzYzMzQzNzcwNjc2MTZkNjM3NDc5NzA2NDdhNmM3MzZkMzc2ODY3MzkzMDIyMmMyMjczNjU2ZTY0NjU3MjIyM2EyMjY5NmU2YTMxMzQ2ZTY1NmU2NDc0NzM3YTMwNjMzNDMwNmUzNzc4NzQ3YTc3NmI2YTZkNjQ2MzM4NjQ2Yjc1N2EzODMzMzU2YTY0Nzk2NDc4Njg2ZTIyN2Q=",
         "state":"Completed",
         "txHashes":[
            "0x3bf678143df5202cb9646e3d449978d385aff8d7b7e8cd5b1e1442163816d609",
            "0x5abaf2ac5afd669c5cf5b8e22eceb211f6a334510dc58a5766d66848eede9407"
         ],
         "createdAt":"2023-12-08 12:23:45.185 +0000 UTC",
         "updatedAt":"2023-12-08 12:23:58.769 +0000 UTC"
      }
   ]
}
{
 "field": [
  {
   "sender": "terra1nrgj0e5l98y07zuenvnpa76x8e5dmm4cdkppws",
   "receiver": "inj1ddcp5ftqmntudn4m6heg2adud6hn58urnwlmkh",
   "source_port": "transfer",
   "source_channel": "channel-17",
   "destination_port": "transfer",
   "destination_channel": "channel-4",
   "amount": "10000000000",
   "denom": "uusd",
   "timeout_height": "5-7072846",
   "timeout_timestamp": 1648784773000000000,
   "packet_sequence": 1892,
   "data_hex": "N2IyMjYxNmQ2Zjc1NmU3NDIyM2EyMjMxMzAzMDMwMzAzMDMwMzAzMDMwMzAyMjJjMjI2NDY1NmU2ZjZkMjIzYTIyNzU3NTczNjQyMjJjMjI3MjY1NjM2NTY5NzY2NTcyMjIzYTIyNjk2ZTZhMzE2NDY0NjM3MDM1NjY3NDcxNmQ2ZTc0NzU2NDZlMzQ2ZDM2Njg2NTY3MzI2MTY0NzU2NDM2Njg2ZTM1Mzg3NTcyNmU3NzZjNmQ2YjY4MjIyYzIyNzM2NTZlNjQ2NTcyMjIzYTIyNzQ2NTcyNzI2MTMxNmU3MjY3NmEzMDY1MzU2YzM5Mzg3OTMwMzc3YTc1NjU2ZTc2NmU3MDYxMzczNjc4Mzg2NTM1NjQ2ZDZkMzQ2MzY0NmI3MDcwNzc3MzIyN2Q=",
   "state": "Completed",
   "tx_hashes": [
    "0xf52d55dd6b68d78d137d4e5526a450d74689d3cba7f69640acd41b68ee26cd15"
   ],
   "created_at": "2022-04-01 03:45:39.338 +0000 UTC",
   "updated_at": "2022-04-01 03:45:39.338 +0000 UTC"
  },
  {
   "sender": "terra1nrgj0e5l98y07zuenvnpa76x8e5dmm4cdkppws",
   "receiver": "inj1ddcp5ftqmntudn4m6heg2adud6hn58urnwlmkh",
   "source_port": "transfer",
   "source_channel": "channel-17",
   "destination_port": "transfer",
   "destination_channel": "channel-4",
   "amount": "200000000",
   "denom": "uluna",
   "timeout_height": "5-6753065",
   "timeout_timestamp": 1646665141000000000,
   "packet_sequence": 1516,
   "data_hex": "N2IyMjYxNmQ2Zjc1NmU3NDIyM2EyMjMyMzAzMDMwMzAzMDMwMzAzMDIyMmMyMjY0NjU2ZTZmNmQyMjNhMjI3NTZjNzU2ZTYxMjIyYzIyNzI2NTYzNjU2OTc2NjU3MjIyM2EyMjY5NmU2YTMxNjQ2NDYzNzAzNTY2NzQ3MTZkNmU3NDc1NjQ2ZTM0NmQzNjY4NjU2NzMyNjE2NDc1NjQzNjY4NmUzNTM4NzU3MjZlNzc2YzZkNmI2ODIyMmMyMjczNjU2ZTY0NjU3MjIyM2EyMjc0NjU3MjcyNjEzMTZlNzI2NzZhMzA2NTM1NmMzOTM4NzkzMDM3N2E3NTY1NmU3NjZlNzA2MTM3MzY3ODM4NjUzNTY0NmQ2ZDM0NjM2NDZiNzA3MDc3NzMyMjdk",
   "state": "Completed",
   "tx_hashes": [
    "0xe5782979f08f7f939b6ed6f4687b70542295ef91f3de84a3e10c4044230f8474"
   ],
   "created_at": "2022-03-07 14:58:31.905 +0000 UTC",
   "updated_at": "2022-03-07 14:58:31.905 +0000 UTC"
  }
 ]
}
ParameterTypeDescription
fieldIBCTransferTx array


IBCTransferTx

ParameterTypeDescription
senderstringthe sender address
receiverstringthe recipient address on the destination chain
source_portstringthe port on which the packet will be sent
source_channelstringthe channel by which the packet will be sent
destination_portstringidentifies the port on the receiving chain
destination_channelstringidentifies the channel end on the receiving chain
amountstringtransfer amount
denomstringtransafer denom
timeout_heightstringTimeout height relative to the current block height. The timeout is disabled when set to 0
timeout_timestampuint64Timeout timestamp (in nanoseconds) relative to the current block timestamp
packet_sequenceuint64number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number
data_hexbyte array
statestring
tx_hashesstring arrayit's injective chain tx hash array
created_atstring
updated_atstring

GetWasmCodes

List all cosmwasm code on injective chain. Results are paginated.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # network: Network = Network.testnet()
    network = Network.testnet()
    client = IndexerClient(network=network)

    pagination = PaginationOption(
        limit=10,
        from_number=1000,
        to_number=2000,
    )

    wasm_codes = await client.fetch_wasm_codes(
        pagination=pagination,
    )
    print("Wasm codes:")
    print(json.dumps(wasm_codes, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := explorerPB.GetWasmCodesRequest{
        Limit: 10,
    }

    res, err := explorerClient.GetWasmCodes(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
limitint32Yes
from_numberint64Yes
to_numberint64Yes

Response Parameters

Response Example:

{
 "paging": {
  "total": 501,
  "from": 497,
  "to": 501
 },
 "data": [
  {
   "code_id": 501,
   "tx_hash": "0x6f218f72f68b3c90e578c1b1fad735f8016fc9b3618664ceb301234f2725d218",
   "checksum": {
    "algorithm": "sha256",
    "hash": "0x4f6e56bbbe7ebec55f7e9d49c4a6e534f57ba3402c0282c1c3ec1aac83753ccf"
   },
   "created_at": 1677495117914,
   "permission": {
    "access_type": 3
   },
   "creator": "inj13dyu3ukelncq95s7dqhg6crqvjursramcazkka",
   "code_number": 515
  },
  {
   "code_id": 500,
   "tx_hash": "0x9a8035a3cd85651b7266f813f3dd909772a7cec5ca0b4f9266832d50c85921b8",
   "checksum": {
    "algorithm": "sha256",
    "hash": "0xdcaa8a03707966ebfedbb927f755fabf9e7f095663f4b9f45a5b437a8276ea0f"
   },
   "created_at": 1677495084552,
   "permission": {
    "access_type": 3
   },
   "creator": "inj13dyu3ukelncq95s7dqhg6crqvjursramcazkka",
   "code_number": 514
  },
  {
   "code_id": 499,
   "tx_hash": "0x3809b1b61e218144c4f50e0a61b6ae89f8942cbe7cadfe67e23127c70949a3f1",
   "checksum": {
    "algorithm": "sha256",
    "hash": "0xdbef810fdc577f4e983620b16eccafdf359e924af0752a13820bf679b260ffe1"
   },
   "created_at": 1677495060759,
   "permission": {
    "access_type": 3
   },
   "creator": "inj13dyu3ukelncq95s7dqhg6crqvjursramcazkka",
   "code_number": 513
  },
  {
   "code_id": 498,
   "tx_hash": "0x9c5a44981506fe7658fa38b2bd63ddd20717842433ce75eba60cb2d7ca548b54",
   "checksum": {
    "algorithm": "sha256",
    "hash": "0xe17581873943e1fe3671bfca9a3360398be10a28245fc0d5c55403f64808019c"
   },
   "created_at": 1677495034788,
   "permission": {
    "access_type": 3
   },
   "creator": "inj13dyu3ukelncq95s7dqhg6crqvjursramcazkka",
   "code_number": 512
  },
  {
   "code_id": 497,
   "tx_hash": "0xeaa3d642a049d0b09920bacf7989a2371ecf43ec20bb5d6dbb3b54326cec63e7",
   "checksum": {
    "algorithm": "sha256",
    "hash": "0x1a1278f43c03e9ed12ba9c1995bae8ea1554cf67a38e9eedd97e9cd61a3e411d"
   },
   "created_at": 1677495006505,
   "permission": {
    "access_type": 3
   },
   "creator": "inj13dyu3ukelncq95s7dqhg6crqvjursramcazkka",
   "code_number": 511
  }
 ]
}
ParameterTypeDescription
pagingPaging
dataWasmCode array


WasmCode

ParameterTypeDescription
code_iduint64ID of stored wasmcode, sorted in descending order
tx_hashstringTx hash of store code transaction
checksumChecksumChecksum of the cosmwasm code
created_atuint64Block time when the code is stored, in millisecond
contract_typestringContract type of the wasm code
versionstringversion string of the wasm code
permissionContractPermissiondescribe instantiate permission
code_schemastringcode schema preview
code_viewstringcode repo preview, may contain schema folder
instantiatesuint64count number of contract instantiation from this code
creatorstringcreator of this code
code_numberint64monotonic order of the code stored
proposal_idint64id of the proposal that store this code


Checksum

ParameterTypeDescription
algorithmstringAlgorithm of hash function
hashstringHash if apply algorithm to the cosmwasm bytecode


ContractPermission

ParameterTypeDescription
access_typeint32Access type of instantiation
addressstringAccount address


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

GetWasmCodeByID

Get cosmwasm code by its code ID

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network=network)

    code_id = 2008

    wasm_code = await client.fetch_wasm_code_by_id(
        code_id=code_id,
    )
    print("Wasm code:")
    print(json.dumps(wasm_code, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := explorerPB.GetWasmCodeByIDRequest{
        CodeId: 10,
    }

    res, err := explorerClient.GetWasmCodeByID(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
code_idint64Code ID of the codeYes

Response Parameters

Response Example:

{
 "code_id": 10,
 "tx_hash": "0x476b1988ba0ea020a337b92f46afefde8af2ac9e72934a1b9882673b3926388c",
 "checksum": {
  "algorithm": "sha256",
  "hash": "0xdba30bcea6d5997c00a7922b475e42f172e72b8ef6ad522c09bc1868bc6caff4"
 },
 "created_at": 1658305428842,
 "instantiates": 4,
 "creator": "inj10hpqmlskky8azz5qca20xau2ppf3x23jsh9k8r",
 "code_number": 10
}
ParameterTypeDescription
code_iduint64ID of stored wasmcode, sorted in descending order
tx_hashstringTx hash of store code transaction
checksumChecksumChecksum of the cosmwasm code
created_atuint64Block time when the code is stored, in millisecond
contract_typestringContract type of the wasm code
versionstringversion string of the wasm code
permissionContractPermissiondescribe instantiate permission
code_schemastringcode schema preview
code_viewstringcode repo preview, may contain schema folder
instantiatesuint64count number of contract instantiation from this code
creatorstringcreator of this code
code_numberint64monotonic order of the code stored
proposal_idint64id of the proposal that store this code


Checksum

ParameterTypeDescription
algorithmstringAlgorithm of hash function
hashstringHash if apply algorithm to the cosmwasm bytecode


ContractPermission

ParameterTypeDescription
access_typeint32Access type of instantiation
addressstringAccount address

GetWasmContracts

Get cosmwasm instantiated contracts on injective-chain. Results are paginated.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network=network)

    pagination = PaginationOption(
        limit=10,
        from_number=1000,
        to_number=2000,
    )

    wasm_contracts = await client.fetch_wasm_contracts(
        assets_only=True,
        pagination=pagination,
    )
    print("Wasm contracts:")
    print(json.dumps(wasm_contracts, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := explorerPB.GetWasmContractsRequest{}

    res, err := explorerClient.GetWasmContracts(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
limitint32Yes
code_idint64Yes
from_numberint64Yes
to_numberint64Yes
assets_onlyboolYes
skipint64Yes
labelstringLabel of the contractYes
tokenstringToken name or symbol to filter byYes
lookupstringText to lookup byYes

Response Parameters

Response Example:

{
 "paging": {
  "total": 529,
  "from": 1,
  "to": 5
 },
 "data": [
  {
   "label": "Instantiation",
   "address": "inj138nnvqqx4t49n6u8r7d8g6h2ek3kpztk3s4svy",
   "tx_hash": "0xdc1c7dc4bb47710b22894def0c4fa12d2d86d9d3d6e3ed3a348d83e9052ea7c2",
   "creator": "inj1rhsl5eld5qg7qe2w2nretw6s6xnwdpaju3rp5j",
   "instantiated_at": 1677520960574,
   "init_message": "{\"app_components\":[],\"name\":\"First Aoo\",\"primitive_contract\":\"inj1hsrl44l3gm5p52r26nx89g9tpptacuy755y6yd\"}",
   "last_executed_at": 1677520960574,
   "code_id": 481,
   "admin": "inj1rhsl5eld5qg7qe2w2nretw6s6xnwdpaju3rp5j",
   "contract_number": 529,
   "version": "0.1.0",
   "type": "crates.io:andromeda-app-contract"
  },
  {
   "label": "CounterTestInstance",
   "address": "inj1xd48d9fs7rmh9rhf36fj69mw8yxplnq66m3gxq",
   "tx_hash": "0x05f44c2dd194a41a7e4606d350d85bd49cf59597dbb63681eaf97e51416a2df2",
   "creator": "inj1kpps36y8c5qm9axr5w3v3ukqtth99pq40ga84e",
   "executes": 1,
   "instantiated_at": 1677252138256,
   "init_message": "{\"count\":99}",
   "last_executed_at": 1677255965387,
   "code_id": 476,
   "contract_number": 528,
   "version": "0.1.0",
   "type": "crates.io:cw-counter"
  },
  {
   "label": "Wormhole Wrapped CW20",
   "address": "inj1m4g54lg2mhhm7a4h3ms5xlyecafhe4macgsuen",
   "tx_hash": "0xce9b5b713da1b1b0e48d1b5451769ba80ca905145a90c704d01221986083c2d8",
   "creator": "inj1q0e70vhrv063eah90mu97sazhywmeegp7myvnh",
   "instantiated_at": 1677179269211,
   "init_message": "{\"name\":\"QAT\",\"symbol\":\"QAT\",\"asset_chain\":2,\"asset_address\":\"AAAAAAAAAAAAAAAAGQLhj+sSNNANiA8frKXI106FAek=\",\"decimals\":8,\"mint\":null,\"init_hook\":{\"msg\":\"eyJyZWdpc3Rlcl9hc3NldF9ob29rIjp7ImNoYWluIjoyLCJ0b2tlbl9hZGRyZXNzIjp7ImJ5dGVzIjpbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMjUsMiwyMjUsMTQzLDIzNSwxOCw1MiwyMDgsMTMsMTM2LDE1LDMxLDE3MiwxNjUsMjAwLDIxNSw3OCwxMzMsMSwyMzNdfX19\",\"contract_addr\":\"inj1q0e70vhrv063eah90mu97sazhywmeegp7myvnh\"}}",
   "last_executed_at": 1677179269211,
   "code_id": 14,
   "admin": "inj1q0e70vhrv063eah90mu97sazhywmeegp7myvnh",
   "contract_number": 527,
   "version": "0.1.0",
   "type": "crates.io:cw20-base",
   "cw20_metadata": {
    "token_info": {
     "name": "QAT (Wormhole)",
     "symbol": "QAT",
     "decimals": 8,
     "total_supply": "0"
    }
   }
  },
  {
   "label": "xAccount Registry",
   "address": "inj1s4alfevl7u84v7c3klh2flv6fw95s3q08eje53",
   "tx_hash": "0xad817a8a4fcef1c36f8c5535b5598a4bc2ddc069f8a60634438dae90a242efed",
   "creator": "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
   "instantiated_at": 1677176719385,
   "init_message": "{\"wormhole_id_here\":19,\"wormhole_core_contract\":\"inj1xx3aupmgv3ce537c0yce8zzd3sz567syuyedpg\",\"factory_code_id\":474,\"x_account_code_id\":475,\"vm_id_here\":1}",
   "last_executed_at": 1677176719385,
   "code_id": 473,
   "admin": "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
   "contract_number": 526
  },
  {
   "label": "xAccount Deployer",
   "address": "inj1a0s058avjct43t7cwn7rfvmxt2p37v29xladv8",
   "tx_hash": "0xad817a8a4fcef1c36f8c5535b5598a4bc2ddc069f8a60634438dae90a242efed",
   "creator": "inj1s4alfevl7u84v7c3klh2flv6fw95s3q08eje53",
   "instantiated_at": 1677176719385,
   "init_message": "{\"x_account_registry\":\"inj1s4alfevl7u84v7c3klh2flv6fw95s3q08eje53\",\"commanders\":[{\"wormhole_id\":19,\"address_byte_length\":20,\"address\":\"AAAAAAAAAAAAAAAAQjjjD/fOAVOq8xb1O7rhomqGArc=\"}]}",
   "last_executed_at": 1677176719385,
   "code_id": 475,
   "admin": "inj1gguwxrlhecq482hnzm6nhwhp5f4gvq4hmxpn7p",
   "contract_number": 525
  }
 ]
}
ParameterTypeDescription
pagingPaging
dataWasmContract array


WasmContract

ParameterTypeDescription
labelstringGeneral name of the contract
addressstringAddress of the contract
tx_hashstringhash of the instantiate transaction
creatorstringAddress of the contract creator
executesuint64Number of times call to execute contract
instantiated_atuint64Block timestamp that contract was instantiated, in millisecond
init_messagestringinit message when this contract was instantiated
last_executed_atuint64Block timestamp that contract was called, in millisecond
fundsContractFund arrayContract funds
code_iduint64Code id of the contract
adminstringAdmin of the contract
current_migrate_messagestringLatest migrate message of the contract
contract_numberint64Monotonic contract number in database
versionstringContract version string
typestringContract type
cw20_metadataCw20Metadata
proposal_idint64id of the proposal that instantiate this contract


ContractFund

ParameterTypeDescription
denomstringDenominator
amountstringAmount of denom


Cw20Metadata

ParameterTypeDescription
token_infoCw20TokenInfo
marketing_infoCw20MarketingInfo


Cw20TokenInfo

ParameterTypeDescription
namestringGeneral name of the token
symbolstringSymbol of then token
decimalsint64Decimal places of token
total_supplystringToken's total supply


Cw20MarketingInfo

ParameterTypeDescription
projectstringProject information
descriptionstringToken's description
logostringlogo (url/embedded)
marketingbyte arrayA random field for additional marketing info


Paging

ParameterTypeDescription
totalint64total number of txs saved in database
fromint32can be either block height or index num
toint32can be either block height or index num
count_by_subaccountint64count entries by subaccount, serving some places on helix
nextstring arrayarray of tokens to navigate to the next pages

GetWasmContractByAddress

Get cosmwasm contract by its address

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network=network)

    address = "inj1yhz4e7df95908jhs9erl87vdzjkdsc24q7afjf"

    wasm_contract = await client.fetch_wasm_contract_by_address(address=address)
    print("Wasm contract:")
    print(json.dumps(wasm_contract, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := explorerPB.GetWasmContractByAddressRequest{
        ContractAddress: "inj1ru9nhdjtjtz8u8wrwxmcl9zsns4fh2838yr5ga",
    }
    res, err := explorerClient.GetWasmContractByAddress(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
contract_addressstringContract addressYes

Response Parameters

Response Example:

{
 "label": "xAccount Registry",
 "address": "inj1ru9nhdjtjtz8u8wrwxmcl9zsns4fh2838yr5ga",
 "tx_hash": "0x7dbc4177ef6253b6cfb33c0345e023eec3a6603aa615fa836271d2f3743e33fb",
 "creator": "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
 "executes": 6,
 "instantiated_at": 1676450262441,
 "init_message": "{\"wormhole_id_here\":19,\"wormhole_core_contract\":\"inj1xx3aupmgv3ce537c0yce8zzd3sz567syuyedpg\",\"factory_code_id\":422,\"x_account_code_id\":421,\"vm_id_here\":1}",
 "last_executed_at": 1676464935254,
 "code_id": 420,
 "admin": "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
 "contract_number": 430
}
ParameterTypeDescription
labelstringGeneral name of the contract
addressstringAddress of the contract
tx_hashstringhash of the instantiate transaction
creatorstringAddress of the contract creator
executesuint64Number of times call to execute contract
instantiated_atuint64Block timestamp that contract was instantiated, in millisecond
init_messagestringinit message when this contract was instantiated
last_executed_atuint64Block timestamp that contract was called, in millisecond
fundsContractFund arrayContract funds
code_iduint64Code id of the contract
adminstringAdmin of the contract
current_migrate_messagestringLatest migrate message of the contract
contract_numberint64Monotonic contract number in database
versionstringContract version string
typestringContract type
cw20_metadataCw20Metadata
proposal_idint64id of the proposal that instantiate this contract


ContractFund

ParameterTypeDescription
denomstringDenominator
amountstringAmount of denom


Cw20Metadata

ParameterTypeDescription
token_infoCw20TokenInfo
marketing_infoCw20MarketingInfo


Cw20TokenInfo

ParameterTypeDescription
namestringGeneral name of the token
symbolstringSymbol of then token
decimalsint64Decimal places of token
total_supplystringToken's total supply


Cw20MarketingInfo

ParameterTypeDescription
projectstringProject information
descriptionstringToken's description
logostringlogo (url/embedded)
marketingbyte arrayA random field for additional marketing info

GetCw20Balance

Get CW20 balances of an injective account across all instantiated CW20 contracts

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network=network)

    address = "inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex"

    balance = await client.fetch_cw20_balance(address=address)
    print("Cw20 balance:")
    print(json.dumps(balance, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"

    "github.com/InjectiveLabs/sdk-go/client/common"
    explorerclient "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    explorerClient, err := explorerclient.NewExplorerClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := explorerPB.GetCw20BalanceRequest{
        Address: "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
    }
    res, err := explorerClient.GetCW20Balance(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringaddress to list balance ofYes
limitint32Yes

Response Parameters

Response Example:

{
 "field": [
  {
   "contract_address": "inj1v6p2u2pgk9qdcf3ussudszjetqwjaj6l89ce0k",
   "account": "inj1dc6rrxhfjaxexzdcrec5w3ryl4jn6x5t7t9j3z",
   "balance": "10000000000000000",
   "updated_at": 1666153787458,
   "cw20_metadata": {
    "token_info": {
     "name": "test coin",
     "symbol": "TEST",
     "decimals": 6,
     "total_supply": "10000000000000000"
    },
    "marketing_info": {
     "marketing": "bnVsbA=="
    }
   }
  }
 ]
}
ParameterTypeDescription
fieldWasmCw20Balance array


WasmCw20Balance

ParameterTypeDescription
contract_addressstringAddress of CW20 contract
accountstringAccount address
balancestringAccount balance
updated_atint64update timestamp in milisecond
cw20_metadataCw20Metadata


Cw20Metadata

ParameterTypeDescription
token_infoCw20TokenInfo
marketing_infoCw20MarketingInfo


Cw20TokenInfo

ParameterTypeDescription
namestringGeneral name of the token
symbolstringSymbol of then token
decimalsint64Decimal places of token
total_supplystringToken's total supply


Cw20MarketingInfo

ParameterTypeDescription
projectstringProject information
descriptionstringToken's description
logostringlogo (url/embedded)
marketingbyte arrayA random field for additional marketing info

GetContractTxs

Returns contract-related transactions

IP rate limit group: indexer

Request Parameters

Request Example:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Example contract address (replace with an actual contract address)
    contractAddress := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"

    req := &explorerPB.GetContractTxsRequest{
        Address: contractAddress,
        Limit:   10, // Fetch 10 transactions
    }

    response, err := explorerClient.FetchContractTxs(ctx, req)
    if err != nil {
        log.Panicf("Failed to fetch contract transactions: %v", err)
    }

    fmt.Println("Total Contract Transactions:", len(response.Data))
    for _, tx := range response.Data {
        fmt.Printf("Tx Hash: %s, Block: %d\n", tx.Hash, tx.BlockNumber)
    }

    fmt.Printf("\n\n")
    fmt.Println("Full response:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringAddress of contractYes
limitint32Yes
skipuint64Yes
from_numberint64Yes
to_numberint64Yes

Response Parameters

Response Example:

{{
 "paging": {
  "total": 97,
  "from": 1,
  "to": 10
 },
 "data": [
  {
   "block_number": 58822729,
   "block_timestamp": "2025-01-09 10:36:21.96 +0000 UTC",
   "hash": "0x470de892246c7fa143dfa0475484316f4053b84b905a78dd2a07838231926cf9",
   "data": "EjYKNC9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0UmVzcG9uc2U=",
   "gas_wanted": 369732,
   "gas_used": 275791,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59157120000000"
     }
    ],
    "gas_limit": 369732,
    "payer": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwidmFsdWUiOnsic2VuZGVyIjoiaW5qMWhraGRhajJhMmNsbXE1anE2bXNwc2dncXMzMnZ5bnBrMjI4cTNyIiwiY29udHJhY3QiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJtc2ciOiJ7XCJpbmNyZW1lbnRcIjoge319IiwiZnVuZHMiOiI2OWZhY3RvcnkvaW5qMWhkdnk2dGw4OWxscXkzemU4bHY2bXo1cWg2NnN4OWVubjBqeGc2L2luajEybmdldngwNDV6cHZhY3VzOXM2YW5yMjU4Z2t3cG10aG56ODBlOSw0MjBwZWdneTB4NDRDMjFhZkFhRjIwYzI3MEVCYkY1OTE0Q2ZjM2I1MDIyMTczRkVCNywxcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUifX1d",
   "signatures": [
    {
     "pubkey": "035ddc4d5642b9383e2f087b2ee88b7207f6286ebc9f310e9df1406eccc2c31813",
     "address": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
     "sequence": 22307,
     "signature": "8mOLGcjvgD3jjO1UTYzj+G9oIPsHMWvBJJN3r7thFQgyvbinvrmqDxOtpKiwPenffoKOhIwvYcPHF/CbqcrgBwE="
    }
   ],
   "tx_number": 42879897,
   "block_unix_timestamp": 1736418981960,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc214IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjY5ZmFjdG9yeS9pbmoxaGR2eTZ0bDg5bGxxeTN6ZThsdjZtejVxaDY2c3g5ZW5uMGp4ZzYvaW5qMTJuZ2V2eDA0NXpwdmFjdXM5czZhbnIyNThna3dwbXRobno4MGU5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjQyMHBlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9yZWNlaXZlZCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2VpdmVyIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjFwZWdneTB4ODdhQjNCNEM4NjYxZTA3RDYzNzIzNjEyMTFCOTZlZDREYzM2QjFCNSIsImluZGV4Ijp0cnVlfSx7ImtleSI6Im1zZ19pbmRleCIsInZhbHVlIjoiMCIsImluZGV4Ijp0cnVlfV19LHsidHlwZSI6InRyYW5zZmVyIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjaXBpZW50IiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 58816984,
   "block_timestamp": "2025-01-09 09:36:16.039 +0000 UTC",
   "hash": "0xc49b5b9c5f55e3cd0307a8a5c52585a6c4892ce8e35673dcefa2161fea0f7dd4",
   "data": "EjYKNC9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0UmVzcG9uc2U=",
   "gas_wanted": 369732,
   "gas_used": 275728,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59157120000000"
     }
    ],
    "gas_limit": 369732,
    "payer": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwidmFsdWUiOnsic2VuZGVyIjoiaW5qMWhraGRhajJhMmNsbXE1anE2bXNwc2dncXMzMnZ5bnBrMjI4cTNyIiwiY29udHJhY3QiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJtc2ciOiJ7XCJpbmNyZW1lbnRcIjoge319IiwiZnVuZHMiOiI2OWZhY3RvcnkvaW5qMWhkdnk2dGw4OWxscXkzemU4bHY2bXo1cWg2NnN4OWVubjBqeGc2L2luajEybmdldngwNDV6cHZhY3VzOXM2YW5yMjU4Z2t3cG10aG56ODBlOSw0MjBwZWdneTB4NDRDMjFhZkFhRjIwYzI3MEVCYkY1OTE0Q2ZjM2I1MDIyMTczRkVCNywxcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUifX1d",
   "signatures": [
    {
     "pubkey": "035ddc4d5642b9383e2f087b2ee88b7207f6286ebc9f310e9df1406eccc2c31813",
     "address": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
     "sequence": 22306,
     "signature": "/64SGXeQufnbq4S6l3gaYW8p+3QjAiC0JGTGCoXXrHoTgE09gUCwp1is5prUJbSt+yegNFEcQUs5HZFVRmpf/gA="
    }
   ],
   "tx_number": 42877669,
   "block_unix_timestamp": 1736415376039,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc214IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjY5ZmFjdG9yeS9pbmoxaGR2eTZ0bDg5bGxxeTN6ZThsdjZtejVxaDY2c3g5ZW5uMGp4ZzYvaW5qMTJuZ2V2eDA0NXpwdmFjdXM5czZhbnIyNThna3dwbXRobno4MGU5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjQyMHBlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9yZWNlaXZlZCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2VpdmVyIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjFwZWdneTB4ODdhQjNCNEM4NjYxZTA3RDYzNzIzNjEyMTFCOTZlZDREYzM2QjFCNSIsImluZGV4Ijp0cnVlfSx7ImtleSI6Im1zZ19pbmRleCIsInZhbHVlIjoiMCIsImluZGV4Ijp0cnVlfV19LHsidHlwZSI6InRyYW5zZmVyIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjaXBpZW50IiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 55217772,
   "block_timestamp": "2024-12-11 18:47:34.588 +0000 UTC",
   "hash": "0xf77982a04ad2350313a2b9407e4e8f2bbc08a505af27244f88775ea511f8940d",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 147091,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e30sImFzZGYiOnt9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "sequence": 2,
     "signature": "glgairiArdzkAYGw96KOIzHaYs/s62ZoqWIDiv62OEt8y9nU90lgIUPdiY52ASqZT2fbRBzcRsJM8ugkN7lJ/wE="
    }
   ],
   "tx_number": 41247484,
   "block_unix_timestamp": 1733942854588,
   "error_log": "failed to execute message; message index: 0: Error parsing into type cw_counter::msg::ExecuteMsg: Expected this character to start a JSON value.: execute wasm contract failed"
  },
  {
   "block_number": 55215328,
   "block_timestamp": "2024-12-11 18:19:08.542 +0000 UTC",
   "hash": "0xd9ca6b185c270624945e71c50bc93ce018c135490e095ae792abcce8718ed4d7",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 2000000,
   "gas_used": 152998,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "sequence": 1,
     "signature": "0dIkouKEhe3DJgEL/6LkJ/6zokK7u7yo1ab5zatKGogGSXFnkN4R6VIdcZH+nfwQL22wHINMtuVXaKx3ztBRvgE="
    }
   ],
   "tx_number": 41246188,
   "block_unix_timestamp": 1733941148542,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMTh0ZzV2Y3Y0ZXBucHV1ZXJqbHFjNDhscDg4OHl0ajhmcW1lNzg2IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 55215254,
   "block_timestamp": "2024-12-11 18:18:18.307 +0000 UTC",
   "hash": "0x4ac5f09ea7c8469d7cd82fd85e0a5e72c5b9d4af4383f8c9c5b80ae40203dde0",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 161846,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e30sImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "signature": "QpwwzQX7OPJUPRqJxmUCu/e7GMUyfn7FaF6k3EqzsUdg529x20tgo9Lmuw2KQCtAN8FCCsdUPIr2kajVGPWx7wE="
    }
   ],
   "tx_number": 41246155,
   "block_unix_timestamp": 1733941098307,
   "error_log": "failed to execute message; message index: 0: Error parsing into type cw_counter::msg::ExecuteMsg: Expected this character to start a JSON value.: execute wasm contract failed"
  },
  {
   "block_number": 51412834,
   "block_timestamp": "2024-11-12 01:41:02.012 +0000 UTC",
   "hash": "0xfd8d73363512856e462995d3733f5047fd033077fee6bf90bf10f6b1cdb035f9",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 371647,
   "gas_used": 153013,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59463520000000"
     }
    ],
    "gas_limit": 371647,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 128,
     "signature": "AxRUotq9abi9gJsE2oORD/rwWpc2NjtVuYfdb0ZDLH08gh9Vox8RcAGD2a587DGqODV08G+n+fhzk4CM/0xUdw=="
    }
   ],
   "tx_number": 39702063,
   "block_unix_timestamp": 1731375662012,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMXQ3a2ZnZXl3a2Y4a2F0NHh5ajNqZHM0a3E4ZnVldzZ4ZmpzdXl5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 51403866,
   "block_timestamp": "2024-11-12 00:00:00.788 +0000 UTC",
   "hash": "0x468be957643b74582caf8e1991aea490f68522910655f68417741f7306d50014",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 371619,
   "gas_used": 152982,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59459040000000"
     }
    ],
    "gas_limit": 371619,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 127,
     "signature": "/II5Vf7y+5msOSjdPo7wcFlfIMAXUwn64+Q2EkxsN1ROD0VyT36Xbj69vTmtnVbBjM59MKzBlgw5g1/1IWlr5A=="
    }
   ],
   "tx_number": 39698366,
   "block_unix_timestamp": 1731369600788,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMXQ3a2ZnZXl3a2Y4a2F0NHh5ajNqZHM0a3E4ZnVldzZ4ZmpzdXl5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 51403569,
   "block_timestamp": "2024-11-11 23:56:40.421 +0000 UTC",
   "hash": "0xf034d70005d204d671d2525b9b2c324c54d64d1dd923972deaa4d4d9aef44caf",
   "code": 11,
   "gas_wanted": 146589,
   "gas_used": 146703,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "23454240000000"
     }
    ],
    "gas_limit": 146589,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "codespace": "sdk",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 126,
     "signature": "k2kI8ITLgSKXw2yPUTFD59u9hUFlfvY/Gqwuj7hH1ORYZPFLps+0tPcdX2GMOjexJ24Yjge33j9aAoWYWtzPOw=="
    }
   ],
   "tx_number": 39698239,
   "block_unix_timestamp": 1731369400421,
   "error_log": "out of gas in location: Loading CosmWasm module: execute; gasWanted: 146589, gasUsed: 146703: out of gas"
  },
  {
   "block_number": 51042475,
   "block_timestamp": "2024-11-08 20:41:58.386 +0000 UTC",
   "hash": "0x1faa6345544cfcd4313a7091bb8f8a163cd51d5ebc055cbd60049ec30ff9d43c",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 148186,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFkM3V4Mzd0Zm16eXduejhwcGd2YzNwZ3pzcDhuMmxyZW16ZTRjNiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7InJlc2V0Ijp7ImNvdW50Ijo5OTl9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "03fd6dc7984102f0dacb47ee68d61693df33b71f9bffe10e64b91a59b30db2855c",
     "address": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6",
     "sequence": 5,
     "signature": "c8cDNKZikjjR4zvNSo3SAQmEufFLfnvkeY2zIbqIhNIqRawFsLb7Gu2NeudwcIZyPspUgkh2AOA07FeGabrWEAE="
    }
   ],
   "tx_number": 39614138,
   "block_unix_timestamp": 1731098518386,
   "error_log": "failed to execute message; message index: 0: Unauthorized: execute wasm contract failed"
  },
  {
   "block_number": 51042428,
   "block_timestamp": "2024-11-08 20:41:16.699 +0000 UTC",
   "hash": "0xc8b4b4f21f621ce844ac0a2429adfde253a9f26fc376b5f2f87524d9da0c8f8c",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 148186,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFkM3V4Mzd0Zm16eXduejhwcGd2YzNwZ3pzcDhuMmxyZW16ZTRjNiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7InJlc2V0Ijp7ImNvdW50Ijo5OTl9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "03fd6dc7984102f0dacb47ee68d61693df33b71f9bffe10e64b91a59b30db2855c",
     "address": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6",
     "sequence": 4,
     "signature": "xKCf4kJajA39c7EWkAxuB8H1+x39JmuoQIyHWsgg1ygL0N+CrQMrR1leqeczhmsXQtSbs1/R+v1csQqLa183HwA="
    }
   ],
   "tx_number": 39614128,
   "block_unix_timestamp": 1731098476699,
   "error_log": "failed to execute message; message index: 0: Unauthorized: execute wasm contract failed"
  }
 ]
}
ParameterTypeDescription
pagingPaging
dataTxDetailData array


Paging

ParameterTypeDescription
pagingPaging
dataTxDetailData array


TxDetailData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codeuint32
databyte array
infostring
gas_wantedint64
gas_usedint64
gas_feeGasFee
codespacestring
eventsEvent array
tx_typestring
messagesbyte array
signaturesSignature array
memostring
tx_numberuint64
block_unix_timestampuint64Block timestamp in unix milli
error_logstringTransaction log indicating errors
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim


GasFee

ParameterTypeDescription
amountCosmosCoin array
gas_limituint64
payerstring
granterstring


Event

ParameterTypeDescription
typestring
attributesmap[string]string


Signature

ParameterTypeDescription
pubkeystring
addressstring
sequenceuint64
signaturestring


CosmosCoin

ParameterTypeDescription
denomstringCoin denominator
amountstringCoin amount (big int)

GetContractTxsV2

Returns contract-related transactions

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import time

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # Select network: local, testnet, mainnet, or custom
    network = Network.testnet()

    # Initialize client
    client = IndexerClient(network=network)

    try:
        # Example parameters for fetching contract transactions
        address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"  # Replace with actual contract address

        # Optional pagination and filtering parameters
        pagination = PaginationOption(
            limit=10,
            start_time=int((time.time() - 100) * 1000),
            end_time=int(time.time() * 1000),
        )

        # Fetch contract transactions V2
        response = await client.fetch_contract_txs_v2(address=address, height=60_000_000, pagination=pagination)

        # Print the results
        print("Contract Transactions V2:")
        print("Total Transactions:", len(response["data"]))

        for tx in response["data"]:
            print("\nTransaction Details:")
            print("ID:", tx["id"])
            print("Block Number:", tx["blockNumber"])
            print("Timestamp:", tx["blockTimestamp"])
            print("Hash:", tx["hash"])
            print("Tx Number:", tx["txNumber"])

    except Exception as e:
        print(f"Error occurred: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Example contract address (replace with an actual contract address)
    contractAddress := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"

    req := &explorerPB.GetContractTxsV2Request{
        Address: contractAddress,
        PerPage: 10, // Fetch 10 transactions
    }

    response, err := explorerClient.FetchContractTxsV2(ctx, req)
    if err != nil {
        log.Panicf("Failed to fetch contract transactions V2: %v", err)
    }

    fmt.Println("Total Contract Transactions:", len(response.Data))
    for _, tx := range response.Data {
        fmt.Printf("Tx Hash: %s, Block: %d\n", tx.Hash, tx.BlockNumber)
    }

    fmt.Printf("\n\n")
    fmt.Println("Full response:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringAddress of contractYes
heightuint64Height of the blockYes
fromint64Unix timestamp (UTC) in millisecondsYes
toint64Unix timestamp (UTC) in millisecondsYes
per_pageint32Yes
tokenstringPagination tokenYes
statusstringThe status of the txs to be returnedYes

Response Parameters

Response Example:

{
 "next": [
  "eyJpIjoiNjcyZTc2ZjRiZTEzMWVmMzBmNWE0NzI1IiwidCI6IjAwMDEtMDEtMDFUMDA6MDA6MDBaIn0=",
  "eyJpIjoiNjYwZWRhZWRlZTU2MGJiMWM5Mjk5M2Q3IiwidCI6IjAwMDEtMDEtMDFUMDA6MDA6MDBaIn0=",
  "eyJpIjoiNjU5NmMxNzA5NmY0Nzk3ZTk2ZDA2ZDdhIiwidCI6IjAwMDEtMDEtMDFUMDA6MDA6MDBaIn0=",
  "eyJpIjoiNjU4NWNkYTk5NmY0Nzk3ZTk2YWMyMTkwIiwidCI6IjAwMDEtMDEtMDFUMDA6MDA6MDBaIn0=",
  "eyJpIjoiNjU0ZDQ5OWVmZTM4MWY3NWM1Y2FlYmIyIiwidCI6IjAwMDEtMDEtMDFUMDA6MDA6MDBaIn0="
 ],
 "data": [
  {
   "block_number": 58822729,
   "block_timestamp": "2025-01-09 10:36:21.96 +0000 UTC",
   "hash": "0x470de892246c7fa143dfa0475484316f4053b84b905a78dd2a07838231926cf9",
   "data": "EjYKNC9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0UmVzcG9uc2U=",
   "gas_wanted": 369732,
   "gas_used": 275791,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59157120000000"
     }
    ],
    "gas_limit": 369732,
    "payer": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwidmFsdWUiOnsic2VuZGVyIjoiaW5qMWhraGRhajJhMmNsbXE1anE2bXNwc2dncXMzMnZ5bnBrMjI4cTNyIiwiY29udHJhY3QiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJtc2ciOiJ7XCJpbmNyZW1lbnRcIjoge319IiwiZnVuZHMiOiI2OWZhY3RvcnkvaW5qMWhkdnk2dGw4OWxscXkzemU4bHY2bXo1cWg2NnN4OWVubjBqeGc2L2luajEybmdldngwNDV6cHZhY3VzOXM2YW5yMjU4Z2t3cG10aG56ODBlOSw0MjBwZWdneTB4NDRDMjFhZkFhRjIwYzI3MEVCYkY1OTE0Q2ZjM2I1MDIyMTczRkVCNywxcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUifX1d",
   "signatures": [
    {
     "pubkey": "035ddc4d5642b9383e2f087b2ee88b7207f6286ebc9f310e9df1406eccc2c31813",
     "address": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
     "sequence": 22307,
     "signature": "8mOLGcjvgD3jjO1UTYzj+G9oIPsHMWvBJJN3r7thFQgyvbinvrmqDxOtpKiwPenffoKOhIwvYcPHF/CbqcrgBwE="
    }
   ],
   "tx_number": 42879897,
   "block_unix_timestamp": 1736418981960,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc214IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjY5ZmFjdG9yeS9pbmoxaGR2eTZ0bDg5bGxxeTN6ZThsdjZtejVxaDY2c3g5ZW5uMGp4ZzYvaW5qMTJuZ2V2eDA0NXpwdmFjdXM5czZhbnIyNThna3dwbXRobno4MGU5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjQyMHBlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9yZWNlaXZlZCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2VpdmVyIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjFwZWdneTB4ODdhQjNCNEM4NjYxZTA3RDYzNzIzNjEyMTFCOTZlZDREYzM2QjFCNSIsImluZGV4Ijp0cnVlfSx7ImtleSI6Im1zZ19pbmRleCIsInZhbHVlIjoiMCIsImluZGV4Ijp0cnVlfV19LHsidHlwZSI6InRyYW5zZmVyIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjaXBpZW50IiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 58816984,
   "block_timestamp": "2025-01-09 09:36:16.039 +0000 UTC",
   "hash": "0xc49b5b9c5f55e3cd0307a8a5c52585a6c4892ce8e35673dcefa2161fea0f7dd4",
   "data": "EjYKNC9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0UmVzcG9uc2U=",
   "gas_wanted": 369732,
   "gas_used": 275728,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59157120000000"
     }
    ],
    "gas_limit": 369732,
    "payer": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwidmFsdWUiOnsic2VuZGVyIjoiaW5qMWhraGRhajJhMmNsbXE1anE2bXNwc2dncXMzMnZ5bnBrMjI4cTNyIiwiY29udHJhY3QiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJtc2ciOiJ7XCJpbmNyZW1lbnRcIjoge319IiwiZnVuZHMiOiI2OWZhY3RvcnkvaW5qMWhkdnk2dGw4OWxscXkzemU4bHY2bXo1cWg2NnN4OWVubjBqeGc2L2luajEybmdldngwNDV6cHZhY3VzOXM2YW5yMjU4Z2t3cG10aG56ODBlOSw0MjBwZWdneTB4NDRDMjFhZkFhRjIwYzI3MEVCYkY1OTE0Q2ZjM2I1MDIyMTczRkVCNywxcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUifX1d",
   "signatures": [
    {
     "pubkey": "035ddc4d5642b9383e2f087b2ee88b7207f6286ebc9f310e9df1406eccc2c31813",
     "address": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
     "sequence": 22306,
     "signature": "/64SGXeQufnbq4S6l3gaYW8p+3QjAiC0JGTGCoXXrHoTgE09gUCwp1is5prUJbSt+yegNFEcQUs5HZFVRmpf/gA="
    }
   ],
   "tx_number": 42877669,
   "block_unix_timestamp": 1736415376039,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9pbmplY3RpdmUud2FzbXgudjEuTXNnRXhlY3V0ZUNvbnRyYWN0Q29tcGF0IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtb2R1bGUiLCJ2YWx1ZSI6Indhc214IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNjlmYWN0b3J5L2luajFoZHZ5NnRsODlsbHF5M3plOGx2Nm16NXFoNjZzeDllbm4wanhnNi9pbmoxMm5nZXZ4MDQ1enB2YWN1czlzNmFucjI1OGdrd3BtdGhuejgwZTkiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjY5ZmFjdG9yeS9pbmoxaGR2eTZ0bDg5bGxxeTN6ZThsdjZtejVxaDY2c3g5ZW5uMGp4ZzYvaW5qMTJuZ2V2eDA0NXpwdmFjdXM5czZhbnIyNThna3dwbXRobno4MGU5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJjb2luX3JlY2VpdmVkIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjZWl2ZXIiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiNDIwcGVnZ3kweDQ0QzIxYWZBYUYyMGMyNzBFQmJGNTkxNENmYzNiNTAyMjE3M0ZFQjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ0cmFuc2ZlciIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2lwaWVudCIsInZhbHVlIjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwiaW5kZXgiOnRydWV9LHsia2V5Ijoic2VuZGVyIiwidmFsdWUiOiJpbmoxaGtoZGFqMmEyY2xtcTVqcTZtc3BzZ2dxczMydnlucGsyMjhxM3IiLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjQyMHBlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9zcGVudCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InNwZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiY29pbl9yZWNlaXZlZCIsImF0dHJpYnV0ZXMiOlt7ImtleSI6InJlY2VpdmVyIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJhbW91bnQiLCJ2YWx1ZSI6IjFwZWdneTB4ODdhQjNCNEM4NjYxZTA3RDYzNzIzNjEyMTFCOTZlZDREYzM2QjFCNSIsImluZGV4Ijp0cnVlfSx7ImtleSI6Im1zZ19pbmRleCIsInZhbHVlIjoiMCIsImluZGV4Ijp0cnVlfV19LHsidHlwZSI6InRyYW5zZmVyIiwiYXR0cmlidXRlcyI6W3sia2V5IjoicmVjaXBpZW50IiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJzZW5kZXIiLCJ2YWx1ZSI6ImluajFoa2hkYWoyYTJjbG1xNWpxNm1zcHNnZ3FzMzJ2eW5wazIyOHEzciIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFtb3VudCIsInZhbHVlIjoiMXBlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 55217772,
   "block_timestamp": "2024-12-11 18:47:34.588 +0000 UTC",
   "hash": "0xf77982a04ad2350313a2b9407e4e8f2bbc08a505af27244f88775ea511f8940d",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 147091,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e30sImFzZGYiOnt9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "sequence": 2,
     "signature": "glgairiArdzkAYGw96KOIzHaYs/s62ZoqWIDiv62OEt8y9nU90lgIUPdiY52ASqZT2fbRBzcRsJM8ugkN7lJ/wE="
    }
   ],
   "tx_number": 41247484,
   "block_unix_timestamp": 1733942854588,
   "error_log": "failed to execute message; message index: 0: Error parsing into type cw_counter::msg::ExecuteMsg: Expected this character to start a JSON value.: execute wasm contract failed"
  },
  {
   "block_number": 55215328,
   "block_timestamp": "2024-12-11 18:19:08.542 +0000 UTC",
   "hash": "0xd9ca6b185c270624945e71c50bc93ce018c135490e095ae792abcce8718ed4d7",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 2000000,
   "gas_used": 152998,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "sequence": 1,
     "signature": "0dIkouKEhe3DJgEL/6LkJ/6zokK7u7yo1ab5zatKGogGSXFnkN4R6VIdcZH+nfwQL22wHINMtuVXaKx3ztBRvgE="
    }
   ],
   "tx_number": 41246188,
   "block_unix_timestamp": 1733941148542,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMTh0ZzV2Y3Y0ZXBucHV1ZXJqbHFjNDhscDg4OHl0ajhmcW1lNzg2IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 55215254,
   "block_timestamp": "2024-12-11 18:18:18.307 +0000 UTC",
   "hash": "0x4ac5f09ea7c8469d7cd82fd85e0a5e72c5b9d4af4383f8c9c5b80ae40203dde0",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 161846,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajE4dGc1dmN2NGVwbnB1dWVyamxxYzQ4bHA4ODh5dGo4ZnFtZTc4NiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e30sImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "0232104c09ec53c81f4a99fa2e8af82b46014b2d62249c0417ca06a314db847269",
     "address": "inj18tg5vcv4epnpuuerjlqc48lp888ytj8fqme786",
     "signature": "QpwwzQX7OPJUPRqJxmUCu/e7GMUyfn7FaF6k3EqzsUdg529x20tgo9Lmuw2KQCtAN8FCCsdUPIr2kajVGPWx7wE="
    }
   ],
   "tx_number": 41246155,
   "block_unix_timestamp": 1733941098307,
   "error_log": "failed to execute message; message index: 0: Error parsing into type cw_counter::msg::ExecuteMsg: Expected this character to start a JSON value.: execute wasm contract failed"
  },
  {
   "block_number": 51412834,
   "block_timestamp": "2024-11-12 01:41:02.012 +0000 UTC",
   "hash": "0xfd8d73363512856e462995d3733f5047fd033077fee6bf90bf10f6b1cdb035f9",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 371647,
   "gas_used": 153013,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59463520000000"
     }
    ],
    "gas_limit": 371647,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 128,
     "signature": "AxRUotq9abi9gJsE2oORD/rwWpc2NjtVuYfdb0ZDLH08gh9Vox8RcAGD2a587DGqODV08G+n+fhzk4CM/0xUdw=="
    }
   ],
   "tx_number": 39702063,
   "block_unix_timestamp": 1731375662012,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMXQ3a2ZnZXl3a2Y4a2F0NHh5ajNqZHM0a3E4ZnVldzZ4ZmpzdXl5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 51403866,
   "block_timestamp": "2024-11-12 00:00:00.788 +0000 UTC",
   "hash": "0x468be957643b74582caf8e1991aea490f68522910655f68417741f7306d50014",
   "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl",
   "gas_wanted": 371619,
   "gas_used": 152982,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "59459040000000"
     }
    ],
    "gas_limit": 371619,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 127,
     "signature": "/II5Vf7y+5msOSjdPo7wcFlfIMAXUwn64+Q2EkxsN1ROD0VyT36Xbj69vTmtnVbBjM59MKzBlgw5g1/1IWlr5A=="
    }
   ],
   "tx_number": 39698366,
   "block_unix_timestamp": 1731369600788,
   "logs": "W3sibXNnX2luZGV4IjoiMCIsImV2ZW50cyI6W3sidHlwZSI6Im1lc3NhZ2UiLCJhdHRyaWJ1dGVzIjpbeyJrZXkiOiJhY3Rpb24iLCJ2YWx1ZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsImluZGV4Ijp0cnVlfSx7ImtleSI6InNlbmRlciIsInZhbHVlIjoiaW5qMXQ3a2ZnZXl3a2Y4a2F0NHh5ajNqZHM0a3E4ZnVldzZ4ZmpzdXl5IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibW9kdWxlIiwidmFsdWUiOiJ3YXNtIiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX0seyJ0eXBlIjoiZXhlY3V0ZSIsImF0dHJpYnV0ZXMiOlt7ImtleSI6Il9jb250cmFjdF9hZGRyZXNzIiwidmFsdWUiOiJpbmoxYWR5M3M3d2hxMzBsNGZ4OHNqM3g2bXV2NW14NGRmZGxjcHY4bjciLCJpbmRleCI6dHJ1ZX0seyJrZXkiOiJtc2dfaW5kZXgiLCJ2YWx1ZSI6IjAiLCJpbmRleCI6dHJ1ZX1dfSx7InR5cGUiOiJ3YXNtIiwiYXR0cmlidXRlcyI6W3sia2V5IjoiX2NvbnRyYWN0X2FkZHJlc3MiLCJ2YWx1ZSI6ImluajFhZHkzczd3aHEzMGw0Zng4c2ozeDZtdXY1bXg0ZGZkbGNwdjhuNyIsImluZGV4Ijp0cnVlfSx7ImtleSI6ImFjdGlvbiIsInZhbHVlIjoiaW5jcmVtZW50IiwiaW5kZXgiOnRydWV9LHsia2V5IjoibXNnX2luZGV4IiwidmFsdWUiOiIwIiwiaW5kZXgiOnRydWV9XX1dfV0="
  },
  {
   "block_number": 51403569,
   "block_timestamp": "2024-11-11 23:56:40.421 +0000 UTC",
   "hash": "0xf034d70005d204d671d2525b9b2c324c54d64d1dd923972deaa4d4d9aef44caf",
   "code": 11,
   "gas_wanted": 146589,
   "gas_used": 146703,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "23454240000000"
     }
    ],
    "gas_limit": 146589,
    "payer": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy"
   },
   "codespace": "sdk",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajF0N2tmZ2V5d2tmOGthdDR4eWozamRzNGtxOGZ1ZXc2eGZqc3V5eSIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7ImluY3JlbWVudCI6e319LCJmdW5kcyI6W119fV0=",
   "signatures": [
    {
     "pubkey": "030b3b7ca00851ca255c18f7b47c5670793c4f022e9d286a080d322ba7dc11d019",
     "address": "inj1t7kfgeywkf8kat4xyj3jds4kq8fuew6xfjsuyy",
     "sequence": 126,
     "signature": "k2kI8ITLgSKXw2yPUTFD59u9hUFlfvY/Gqwuj7hH1ORYZPFLps+0tPcdX2GMOjexJ24Yjge33j9aAoWYWtzPOw=="
    }
   ],
   "tx_number": 39698239,
   "block_unix_timestamp": 1731369400421,
   "error_log": "out of gas in location: Loading CosmWasm module: execute; gasWanted: 146589, gasUsed: 146703: out of gas"
  },
  {
   "block_number": 51042475,
   "block_timestamp": "2024-11-08 20:41:58.386 +0000 UTC",
   "hash": "0x1faa6345544cfcd4313a7091bb8f8a163cd51d5ebc055cbd60049ec30ff9d43c",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 148186,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFkM3V4Mzd0Zm16eXduejhwcGd2YzNwZ3pzcDhuMmxyZW16ZTRjNiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7InJlc2V0Ijp7ImNvdW50Ijo5OTl9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "03fd6dc7984102f0dacb47ee68d61693df33b71f9bffe10e64b91a59b30db2855c",
     "address": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6",
     "sequence": 5,
     "signature": "c8cDNKZikjjR4zvNSo3SAQmEufFLfnvkeY2zIbqIhNIqRawFsLb7Gu2NeudwcIZyPspUgkh2AOA07FeGabrWEAE="
    }
   ],
   "tx_number": 39614138,
   "block_unix_timestamp": 1731098518386,
   "error_log": "failed to execute message; message index: 0: Unauthorized: execute wasm contract failed"
  },
  {
   "block_number": 51042428,
   "block_timestamp": "2024-11-08 20:41:16.699 +0000 UTC",
   "hash": "0xc8b4b4f21f621ce844ac0a2429adfde253a9f26fc376b5f2f87524d9da0c8f8c",
   "code": 5,
   "gas_wanted": 2000000,
   "gas_used": 148186,
   "gas_fee": {
    "amount": [
     {
      "denom": "inj",
      "amount": "1000000000000000"
     }
    ],
    "gas_limit": 2000000,
    "payer": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6"
   },
   "codespace": "wasm",
   "tx_type": "injective",
   "messages": "W3sidHlwZSI6Ii9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdCIsInZhbHVlIjp7InNlbmRlciI6ImluajFkM3V4Mzd0Zm16eXduejhwcGd2YzNwZ3pzcDhuMmxyZW16ZTRjNiIsImNvbnRyYWN0IjoiaW5qMWFkeTNzN3docTMwbDRmeDhzajN4Nm11djVteDRkZmRsY3B2OG43IiwibXNnIjp7InJlc2V0Ijp7ImNvdW50Ijo5OTl9fSwiZnVuZHMiOltdfX1d",
   "signatures": [
    {
     "pubkey": "03fd6dc7984102f0dacb47ee68d61693df33b71f9bffe10e64b91a59b30db2855c",
     "address": "inj1d3ux37tfmzywnz8ppgvc3pgzsp8n2lremze4c6",
     "sequence": 4,
     "signature": "xKCf4kJajA39c7EWkAxuB8H1+x39JmuoQIyHWsgg1ygL0N+CrQMrR1leqeczhmsXQtSbs1/R+v1csQqLa183HwA="
    }
   ],
   "tx_number": 39614128,
   "block_unix_timestamp": 1731098476699,
   "error_log": "failed to execute message; message index: 0: Unauthorized: execute wasm contract failed"
  }
 ]
}
ParameterTypeDescription
pagingCursor
dataTxDetailData array


TxDetailData

ParameterTypeDescription
idstring
block_numberuint64
block_timestampstring
hashstring
codeuint32
databyte array
infostring
gas_wantedint64
gas_usedint64
gas_feeGasFee
codespacestring
eventsEvent array
tx_typestring
messagesbyte array
signaturesSignature array
memostring
tx_numberuint64
block_unix_timestampuint64Block timestamp in unix milli
error_logstringTransaction log indicating errors
logsbyte arraytransaction event logs
claim_idsint64 arraypeggy bridge claim id, non-zero if tx contains MsgDepositClaim


GasFee

ParameterTypeDescription
amountCosmosCoin array
gas_limituint64
payerstring
granterstring


Event

ParameterTypeDescription
typestring
attributesmap[string]string


Signature

ParameterTypeDescription
pubkeystring
addressstring
sequenceuint64
signaturestring


CosmosCoin

ParameterTypeDescription
denomstringCoin denominator
amountstringCoin amount (big int)

GetValidators

Returns validators on the active chain

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main():
    # Select network: choose between testnet, mainnet, or local
    network = Network.testnet()
    client = IndexerClient(network=network)

    try:
        # Fetch validators
        validators = await client.fetch_validators()

        # Print validators
        print("Validators:")
        print(json.dumps(validators, indent=2))

    except Exception as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    response, err := explorerClient.FetchValidators(ctx)
    if err != nil {
        log.Panicf("Failed to fetch validators: %v", err)
    }

    fmt.Println("Full response:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}

No parameters

Response Parameters

Response Example:

{
 "s": "ok",
 "data": [
  {
   "moniker": "InjectiveNode0",
   "operator_address": "injvaloper156t3yxd4udv0h9gwagfcmwnmm3quy0nph7tyh5",
   "consensus_address": "injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz",
   "status": 3,
   "tokens": "199839467422092227833043922278058",
   "delegator_shares": "200079520832392518666156120803312.278592914008001140",
   "description": {
    "moniker": "InjectiveNode0"
   },
   "unbonding_height": 29124205,
   "unbonding_time": "2024-05-28 05:54:07.916 +0000 UTC",
   "commission_rate": "0.100000000000000000",
   "commission_max_rate": "1.000000000000000000",
   "commission_max_change_rate": "1.000000000000000000",
   "commission_update_time": "2022-07-05 00:43:31.747 +0000 UTC",
   "proposed": 14637446,
   "signed": 34790558,
   "timestamp": "2025-01-24 17:43:23.333 +0000 UTC",
   "slashing_events": [
    {
     "block_number": 29124205,
     "block_timestamp": "2024-05-07 05:54:07.916 +0000 UTC",
     "power": 199859454142830,
     "reason": "missing_signature",
     "jailed": "injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz"
    }
   ],
   "uptime_percentage": 100
  },
  {
   "moniker": "InjectiveNode3",
   "operator_address": "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe",
   "consensus_address": "injvalcons156wnzfr0kul2ftuqwz6339fafv9a3jnr03v25d",
   "jailed": true,
   "status": 1,
   "tokens": "2552165711097612775707760",
   "delegator_shares": "2557277708668587635912948.746178338091196081",
   "description": {
    "moniker": "InjectiveNode3"
   },
   "unbonding_height": 13904543,
   "unbonding_time": "2023-08-13 08:49:31.706 +0000 UTC",
   "commission_rate": "1.000000000000000000",
   "commission_max_rate": "1.000000000000000000",
   "commission_max_change_rate": "1.000000000000000000",
   "commission_update_time": "2022-07-05 03:07:17.931 +0000 UTC",
   "proposed": 2722044,
   "signed": 7101559,
   "timestamp": "2025-01-24 17:43:23.333 +0000 UTC"
  }
 ]
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataValidator array


Validator

ParameterTypeDescription
idstring
monikerstring
operator_addressstring
consensus_addressstring
jailedbool
statusint32
tokensstring
delegator_sharesstring
descriptionValidatorDescription
unbonding_heightint64
unbonding_timestring
commission_ratestring
commission_max_ratestring
commission_max_change_ratestring
commission_update_timestring
proposeduint64
signeduint64
misseduint64
timestampstring
uptimesValidatorUptime array
slashing_eventsSlashingEvent array
uptime_percentagefloat64uptime percentage base on latest 10k block
image_urlstringURL of the validator logo


ValidatorDescription

ParameterTypeDescription
monikerstring
identitystring
websitestring
security_contactstring
detailsstring
image_urlstring


ValidatorUptime

ParameterTypeDescription
block_numberuint64
statusstring

GetValidator

Returns validator information on the active chain

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main():
    # Select network: choose between testnet, mainnet, or local
    network = Network.testnet()
    client = IndexerClient(network=network)

    address = "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe"

    try:
        # Fetch validator
        validator = await client.fetch_validator(address=address)

        # Print validators
        print("Validator:")
        print(json.dumps(validator, indent=2))

    except Exception as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Example validator address (replace with an actual validator address)
    validatorAddress := "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe"

    response, err := explorerClient.FetchValidator(ctx, validatorAddress)
    if err != nil {
        log.Panicf("Failed to fetch validator: %v", err)
    }

    fmt.Println("Validator:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringYes

Response Parameters

Response Example:

{
 "s": "ok",
 "data": {
  "moniker": "InjectiveNode3",
  "operator_address": "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe",
  "consensus_address": "injvalcons156wnzfr0kul2ftuqwz6339fafv9a3jnr03v25d",
  "jailed": true,
  "status": 1,
  "tokens": "2552165711097612775707760",
  "delegator_shares": "2557277708668587635912948.746178338091196081",
  "description": {
   "moniker": "InjectiveNode3"
  },
  "unbonding_height": 13904543,
  "unbonding_time": "2023-08-13 08:49:31.706 +0000 UTC",
  "commission_rate": "1.000000000000000000",
  "commission_max_rate": "1.000000000000000000",
  "commission_max_change_rate": "1.000000000000000000",
  "commission_update_time": "2022-07-05 03:07:17.931 +0000 UTC",
  "proposed": 2722044,
  "signed": 7101559,
  "timestamp": "2025-01-24 18:06:40.345 +0000 UTC"
 }
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataValidator


Validator

ParameterTypeDescription
idstring
monikerstring
operator_addressstring
consensus_addressstring
jailedbool
statusint32
tokensstring
delegator_sharesstring
descriptionValidatorDescription
unbonding_heightint64
unbonding_timestring
commission_ratestring
commission_max_ratestring
commission_max_change_ratestring
commission_update_timestring
proposeduint64
signeduint64
misseduint64
timestampstring
uptimesValidatorUptime array
slashing_eventsSlashingEvent array
uptime_percentagefloat64uptime percentage base on latest 10k block
image_urlstringURL of the validator logo


ValidatorDescription

ParameterTypeDescription
monikerstring
identitystring
websitestring
security_contactstring
detailsstring
image_urlstring


ValidatorUptime

ParameterTypeDescription
block_numberuint64
statusstring

GetValidatorUptime

Returns validator uptime information on the active chain

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main():
    # Select network: choose between testnet, mainnet, or local
    network = Network.testnet()
    client = IndexerClient(network=network)

    address = "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe"

    try:
        # Fetch validator uptime
        uptime = await client.fetch_validator_uptime(address=address)

        # Print uptime
        print("Validator uptime:")
        print(json.dumps(uptime, indent=2))

    except Exception as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Example validator address (replace with an actual validator address)
    validatorAddress := "injvaloper1kk523rsm9pey740cx4plalp40009ncs0wrchfe"

    response, err := explorerClient.FetchValidatorUptime(ctx, validatorAddress)
    if err != nil {
        log.Panicf("Failed to fetch validator uptime: %v", err)
    }

    fmt.Println("Validator uptime:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
addressstringYes

Response Parameters

Response Example:

{
 "s": "ok",
 "data": [
  {
   "block_number": 60715775,
   "status": "missed"
  },
  {
   "block_number": 60715774,
   "status": "missed"
  },
  {
   "block_number": 60715773,
   "status": "missed"
  },
  {
   "block_number": 60715772,
   "status": "missed"
  },
  {
   "block_number": 60715771,
   "status": "missed"
  },
  {
   "block_number": 60715770,
   "status": "missed"
  },
  {
   "block_number": 60715769,
   "status": "missed"
  },
  {
   "block_number": 60715768,
   "status": "missed"
  },
  {
   "block_number": 60715767,
   "status": "missed"
  },
  {
   "block_number": 60715766,
   "status": "missed"
  },
  {
   "block_number": 60715765,
   "status": "missed"
  },
  {
   "block_number": 60715764,
   "status": "missed"
  },
  {
   "block_number": 60715763,
   "status": "missed"
  },
  {
   "block_number": 60715762,
   "status": "missed"
  },
  {
   "block_number": 60715761,
   "status": "missed"
  },
  {
   "block_number": 60715760,
   "status": "missed"
  },
  {
   "block_number": 60715759,
   "status": "missed"
  },
  {
   "block_number": 60715758,
   "status": "missed"
  },
  {
   "block_number": 60715757,
   "status": "missed"
  },
  {
   "block_number": 60715756,
   "status": "missed"
  },
  {
   "block_number": 60715755,
   "status": "missed"
  },
  {
   "block_number": 60715754,
   "status": "missed"
  },
  {
   "block_number": 60715753,
   "status": "missed"
  },
  {
   "block_number": 60715752,
   "status": "missed"
  },
  {
   "block_number": 60715751,
   "status": "missed"
  },
  {
   "block_number": 60715750,
   "status": "missed"
  },
  {
   "block_number": 60715749,
   "status": "missed"
  },
  {
   "block_number": 60715748,
   "status": "missed"
  },
  {
   "block_number": 60715747,
   "status": "missed"
  },
  {
   "block_number": 60715746,
   "status": "missed"
  },
  {
   "block_number": 60715745,
   "status": "missed"
  },
  {
   "block_number": 60715744,
   "status": "missed"
  },
  {
   "block_number": 60715743,
   "status": "missed"
  },
  {
   "block_number": 60715742,
   "status": "missed"
  },
  {
   "block_number": 60715741,
   "status": "missed"
  },
  {
   "block_number": 60715740,
   "status": "missed"
  },
  {
   "block_number": 60715739,
   "status": "missed"
  },
  {
   "block_number": 60715738,
   "status": "missed"
  },
  {
   "block_number": 60715737,
   "status": "missed"
  },
  {
   "block_number": 60715736,
   "status": "missed"
  },
  {
   "block_number": 60715735,
   "status": "missed"
  },
  {
   "block_number": 60715734,
   "status": "missed"
  },
  {
   "block_number": 60715733,
   "status": "missed"
  },
  {
   "block_number": 60715732,
   "status": "missed"
  },
  {
   "block_number": 60715731,
   "status": "missed"
  },
  {
   "block_number": 60715730,
   "status": "missed"
  },
  {
   "block_number": 60715729,
   "status": "missed"
  },
  {
   "block_number": 60715728,
   "status": "missed"
  },
  {
   "block_number": 60715727,
   "status": "missed"
  },
  {
   "block_number": 60715726,
   "status": "missed"
  },
  {
   "block_number": 60715725,
   "status": "missed"
  },
  {
   "block_number": 60715724,
   "status": "missed"
  },
  {
   "block_number": 60715723,
   "status": "missed"
  },
  {
   "block_number": 60715722,
   "status": "missed"
  },
  {
   "block_number": 60715721,
   "status": "missed"
  },
  {
   "block_number": 60715720,
   "status": "missed"
  },
  {
   "block_number": 60715719,
   "status": "missed"
  },
  {
   "block_number": 60715718,
   "status": "missed"
  },
  {
   "block_number": 60715717,
   "status": "missed"
  },
  {
   "block_number": 60715716,
   "status": "missed"
  },
  {
   "block_number": 60715715,
   "status": "missed"
  },
  {
   "block_number": 60715714,
   "status": "missed"
  },
  {
   "block_number": 60715713,
   "status": "missed"
  },
  {
   "block_number": 60715712,
   "status": "missed"
  },
  {
   "block_number": 60715711,
   "status": "missed"
  },
  {
   "block_number": 60715710,
   "status": "missed"
  },
  {
   "block_number": 60715709,
   "status": "missed"
  },
  {
   "block_number": 60715708,
   "status": "missed"
  },
  {
   "block_number": 60715707,
   "status": "missed"
  },
  {
   "block_number": 60715706,
   "status": "missed"
  },
  {
   "block_number": 60715705,
   "status": "missed"
  },
  {
   "block_number": 60715704,
   "status": "missed"
  },
  {
   "block_number": 60715703,
   "status": "missed"
  },
  {
   "block_number": 60715702,
   "status": "missed"
  },
  {
   "block_number": 60715701,
   "status": "missed"
  },
  {
   "block_number": 60715700,
   "status": "missed"
  },
  {
   "block_number": 60715699,
   "status": "missed"
  },
  {
   "block_number": 60715698,
   "status": "missed"
  },
  {
   "block_number": 60715697,
   "status": "missed"
  },
  {
   "block_number": 60715696,
   "status": "missed"
  },
  {
   "block_number": 60715695,
   "status": "missed"
  },
  {
   "block_number": 60715694,
   "status": "missed"
  },
  {
   "block_number": 60715693,
   "status": "missed"
  },
  {
   "block_number": 60715692,
   "status": "missed"
  },
  {
   "block_number": 60715691,
   "status": "missed"
  },
  {
   "block_number": 60715690,
   "status": "missed"
  },
  {
   "block_number": 60715689,
   "status": "missed"
  },
  {
   "block_number": 60715688,
   "status": "missed"
  },
  {
   "block_number": 60715687,
   "status": "missed"
  },
  {
   "block_number": 60715686,
   "status": "missed"
  },
  {
   "block_number": 60715685,
   "status": "missed"
  },
  {
   "block_number": 60715684,
   "status": "missed"
  },
  {
   "block_number": 60715683,
   "status": "missed"
  },
  {
   "block_number": 60715682,
   "status": "missed"
  },
  {
   "block_number": 60715681,
   "status": "missed"
  },
  {
   "block_number": 60715680,
   "status": "missed"
  },
  {
   "block_number": 60715679,
   "status": "missed"
  },
  {
   "block_number": 60715678,
   "status": "missed"
  },
  {
   "block_number": 60715677,
   "status": "missed"
  },
  {
   "block_number": 60715676,
   "status": "missed"
  }
 ]
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataValidatorUptime array


ValidatorUptime

ParameterTypeDescription
block_numberuint64
statusstring

Relayers

Request relayers infos by marketIDs. If no ids are provided, all market with associated relayers are returned

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main():
    # Select network: choose between testnet, mainnet, or local
    network = Network.testnet()
    client = IndexerClient(network=network)

    try:
        # Fetch relayers
        relayers = await client.fetch_relayers()

        # Print relayers
        print("Relayers:")
        print(json.dumps(relayers, indent=2))

    except Exception as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Pass an empty list of market IDs
    var marketIds []string

    response, err := explorerClient.FetchRelayers(ctx, marketIds)
    if err != nil {
        log.Panicf("Failed to fetch relayers: %v", err)
    }

    fmt.Println("Relayers:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_i_dsstring arraySpecify multiple marketIDs to search.Yes

Response Parameters

Response Example:


ParameterTypeDescription
fieldRelayerMarkets array


RelayerMarkets

ParameterTypeDescription
market_idstringMarket ID of the market
relayersRelayer arrayRelayers list for specified market


Relayer

ParameterTypeDescription
namestringRelayer identifier
ctastringCall to action. A link to the relayer

GetBankTransfers

Returns bank transfers

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import logging

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network=network)

    pagination = PaginationOption(limit=5)
    senders = ["inj17xpfvakm2amg962yls6f84z3kell8c5l6s5ye9"]

    bank_transfers = await client.fetch_bank_transfers(senders=senders, pagination=pagination)
    print("Bank transfers:")
    print(json.dumps(bank_transfers, indent=2))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    "github.com/InjectiveLabs/sdk-go/client/explorer"
    explorerPB "github.com/InjectiveLabs/sdk-go/exchange/explorer_rpc/pb"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    explorerClient, err := explorer.NewExplorerClient(network)
    if err != nil {
        log.Fatalf("Failed to create explorer client: %v", err)
    }
    defer explorerClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    defer cancel()

    req := &explorerPB.GetBankTransfersRequest{
        Senders: []string{"inj17xpfvakm2amg962yls6f84z3kell8c5l6s5ye9"},
        Limit:   5, // Limit number of transfers
    }

    response, err := explorerClient.FetchBankTransfers(ctx, req)
    if err != nil {
        log.Panicf("Failed to fetch bank transfers: %v", err)
    }

    fmt.Println("Bank transfers:")
    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
sendersstring arrayTransfer sender addressYes
recipientsstring arrayTransfer recipient addressYes
is_community_pool_relatedboolReturns transfers with the community pool address as either sender or recipientYes
limitint32Yes
skipuint64Yes
start_timeint64The starting timestamp in UNIX milliseconds that the transfers must be equal or older thanYes
end_timeint64The ending timestamp in UNIX milliseconds that the transfers must be equal or younger thanYes
addressstring arrayTransfers where either the sender or the recipient is one of the addressesYes
per_pageint32Yes
tokenstringYes

Response Parameters

Response Example:


ParameterTypeDescription
pagingPaging
dataBankTransfer array


BankTransfer

ParameterTypeDescription
senderstring
recipientstring
amountsCoin arrayAmounts transferred
block_numberuint64
block_timestampstring


Coin

ParameterTypeDescription
denomstringDenom of the coin
amountstring
usd_valuestring

- InjectiveMetaRPC

InjectiveMetaRPC defines the gRPC API of the Exchange Meta provider.

Ping

Get the server health.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    resp = await client.fetch_ping()
    print(json.dumps(resp, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    metaPB "github.com/InjectiveLabs/sdk-go/exchange/meta_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := metaPB.PingRequest{}

    res, err := exchangeClient.Ping(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

Response Example:

Health OK?
Health OK?{}

Version

Get the server version.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    resp = await client.fetch_version()
    print(json.dumps(resp, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    metaPB "github.com/InjectiveLabs/sdk-go/exchange/meta_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := metaPB.VersionRequest{}

    res, err := exchangeClient.GetVersion(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

Response Parameters

Response Example:

{
   "version":"v1.12.46-rc1",
   "build":{
      "BuildDate":"20231110-0736",
      "GitCommit":"2b326fe",
      "GoVersion":"go1.20.5",
      "GoArch":"amd64"
   }
}
{
 "version": "dev",
 "build": {
  "BuildDate": "20220426-0810",
  "GitCommit": "4f3bc09",
  "GoArch": "amd64",
  "GoVersion": "go1.17.3"
 }
}
ParameterTypeDescription
versionstringinjective-exchange code version.
buildmap[string]stringAdditional build meta info.

Info

Get the server information.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json
import time

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    resp = await client.fetch_info()
    print("[!] Info:")
    print(json.dumps(resp, indent=2))
    latency = int(time.time() * 1000) - int(resp["timestamp"])
    print(f"Server Latency: {latency}ms")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
    metaPB "github.com/InjectiveLabs/sdk-go/exchange/meta_rpc/pb"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    req := metaPB.InfoRequest{}

    res, err := exchangeClient.GetInfo(ctx, &req)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
timestampint64Provide current system UNIX timestamp in millisYes

Response Parameters

Response Example:

{
   "timestamp":"1702040535291",
   "serverTime":"1702040536394",
   "version":"v1.12.46-guilds-rc5",
   "build":{
      "BuildDate":"20231113-1523",
      "GitCommit":"78a9ea2",
      "GoVersion":"go1.20.5",
      "GoArch":"amd64"
   },
   "region":""
}
ParameterTypeDescription
timestampint64The original timestamp value in millis.
server_timeint64UNIX time on the server in millis.
versionstringinjective-exchange code version.
buildmap[string]stringAdditional build meta info.
regionstringServer's location region

StreamKeepAlive

Subscribe to a stream and gracefully disconnect and connect to another sentry node if the primary becomes unavailable.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to keepalive updates ({exception})")


def stream_closed_processor():
    print("The keepalive stream has been closed")


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    tasks = []

    async def keepalive_event_processor(event: Dict[str, Any]):
        print("Server announce:", event)
        for task in tasks:
            task.cancel()
        print("Cancelled all tasks")

    market_task = asyncio.get_event_loop().create_task(get_markets(client))
    tasks.append(market_task)
    keepalive_task = asyncio.get_event_loop().create_task(
        client.listen_keepalive(
            callback=keepalive_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    try:
        await asyncio.gather(market_task, keepalive_task)
    except asyncio.CancelledError:
        print("main(): get_markets is cancelled now")


async def get_markets(client):
    async def print_market_updates(event: Dict[str, Any]):
        print(event)

    await client.listen_spot_markets_updates(
        callback=print_market_updates,
        on_end_callback=stream_closed_processor,
        on_status_callback=stream_error_processor,
    )


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    stream, err := exchangeClient.StreamKeepalive(ctx)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}

No parameters

Response Parameters

Response Example:

event: "shutdown",
timestamp: 1636236225847,

"Cancelled all tasks"
ParameterTypeDescription
timestampint64The original timestamp value in millis.
server_timeint64UNIX time on the server in millis.
versionstringinjective-exchange code version.
buildmap[string]stringAdditional build meta info.
regionstringServer's location region

- InjectivePortfolioRPC

InjectivePortfolioRPC defines the gRPC API of the Exchange Portfolio provider.

AccountPortfolio

Get details about an account's portfolio.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = IndexerClient(network)
    account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt"
    portfolio = await client.fetch_account_portfolio_balances(account_address=account_address, usd=False)
    print(json.dumps(portfolio, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // select network: local, testnet, mainnet
    network := common.LoadNetwork("devnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    accountAddress := "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt"
    res, err := exchangeClient.GetAccountPortfolioBalances(ctx, accountAddress, true)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
account_addressstringAccount addressYes
usdboolWhether to return USD values for the balancesYes

Response Parameters

Response Example:

{
   "portfolio":{
      "accountAddress":"inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt",
      "bankBalances":[
         {
            "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom",
            "amount":"10000000000"
         },
         {
            "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
            "amount":"10000000000"
         },
         {
            "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
            "amount":"5000000000"
         },
         {
            "denom":"inj",
            "amount":"9699395972014420000000"
         },
         {
            "denom":"peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
            "amount":"100000000000000000000"
         },
         {
            "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "amount":"18689670208"
         }
      ],
      "subaccounts":[
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
            "denom":"inj",
            "deposit":{
               "totalBalance":"11010001000000000000",
               "availableBalance":"11010001000000000000"
            }
         },
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
            "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "deposit":{
               "totalBalance":"298666021.6838251182660625",
               "availableBalance":"298666021.6838251182660625"
            }
         },
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000002",
            "denom":"inj",
            "deposit":{
               "totalBalance":"1000000000000",
               "availableBalance":"1000000000000"
            }
         },
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
            "denom":"inj",
            "deposit":{
               "totalBalance":"0.458458",
               "availableBalance":"0.458458"
            }
         },
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
            "denom":"peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
            "deposit":{
               "totalBalance":"0",
               "availableBalance":"0"
            }
         },
         {
            "subaccountId":"0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
            "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "deposit":{
               "totalBalance":"0.170858923182467801",
               "availableBalance":"0.170858923182467801"
            }
         }
      ]
   }
}
{
 "portfolio": {
  "account_address": "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt",
  "bank_balances": [
   {
    "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom",
    "amount": "10000000000"
   },
   {
    "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
    "amount": "10000000000"
   },
   {
    "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
    "amount": "5000000000"
   },
   {
    "denom": "inj",
    "amount": "9699395972014420000000"
   },
   {
    "denom": "peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
    "amount": "100000000000000000000"
   },
   {
    "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
    "amount": "18689670208"
   }
  ],
  "subaccounts": [
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
    "denom": "peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
    "deposit": {
     "total_balance": "0",
     "available_balance": "0"
    }
   },
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
    "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
    "deposit": {
     "total_balance": "0.170858923182467801",
     "available_balance": "0.170858923182467801"
    }
   },
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000000",
    "denom": "inj",
    "deposit": {
     "total_balance": "0.458458",
     "available_balance": "0.458458"
    }
   },
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
    "denom": "inj",
    "deposit": {
     "total_balance": "11010001000000000000",
     "available_balance": "11010001000000000000"
    }
   },
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
    "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
    "deposit": {
     "total_balance": "298666021.6838251182660625",
     "available_balance": "298666021.6838251182660625"
    }
   },
   {
    "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000002",
    "denom": "inj",
    "deposit": {
     "total_balance": "1000000000000",
     "available_balance": "1000000000000"
    }
   }
  ]
 }
}

ParameterTypeDescription
portfolioPortfolioBalancesThe portfolio balances of this account


PortfolioBalances

ParameterTypeDescription
account_addressstringThe account's portfolio address
bank_balancesCoin arrayAccount available bank balances
subaccountsSubaccountBalanceV2 arraySubaccounts list
total_usdstringUSD value of the portfolio


Coin

ParameterTypeDescription
denomstringDenom of the coin
amountstring
usd_valuestring


SubaccountBalanceV2

ParameterTypeDescription
subaccount_idstringRelated subaccount ID
denomstringCoin denom on the chain.
depositSubaccountDeposit


SubaccountDeposit

ParameterTypeDescription
total_balancestring
available_balancestring
total_balance_usdstring
available_balance_usdstring

StreamAccountPortfolio

Get continuous updates on account's portfolio.

IP rate limit group: indexer

Request Parameters

Request Example:

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.core.network import Network
from pyinjective.indexer_client import IndexerClient


async def account_portfolio_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to account portfolio updates ({exception})")


def stream_closed_processor():
    print("The account portfolio updates stream has been closed")


async def main() -> None:
    network = Network.testnet()
    client = IndexerClient(network)
    account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt"

    task = asyncio.get_event_loop().create_task(
        client.listen_account_portfolio_updates(
            account_address=account_address,
            callback=account_portfolio_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client/common"
    exchangeclient "github.com/InjectiveLabs/sdk-go/client/exchange"
)

func main() {
    // select network: local, testnet, mainnet
    network := common.LoadNetwork("testnet", "lb")
    exchangeClient, err := exchangeclient.NewExchangeClient(network)
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    stream, err := exchangeClient.StreamAccountPortfolio(ctx, "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt", "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001", "total_balances")
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
account_addressstringThe account's portfolio addressYes
subaccount_idstringRelated subaccount IDYes
typestringYes

Response Parameters

Response Example:

{
 "type": "total_balances",
 "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
 "amount": "302686408.8456",
 "subaccountId": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
 "timestamp": "342423423"
}
{
 "type": "total_balances",
 "denom": "inj",
 "amount": "11040001000000000000",
 "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001",
 "timestamp": "342432343"
}
{
 "type": "total_balances",
 "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
 "amount": "302686408.8456",
 "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"
}{
 "type": "total_balances",
 "denom": "inj",
 "amount": "11040001000000000000",
 "subaccount_id": "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001"
}
ParameterTypeDescription
typestringtype of portfolio entry
denomstringdenom of portfolio entry
amountstringamount of portfolio entry
subaccount_idstringsubaccount id of portfolio entry
timestampint64Operation timestamp in UNIX millis.

Chain API

The Indexer API is read-only whereas the Chain API is write and also includes a limited set of API requests to read data. The Chain API reads query the blockchain state from the node directly as opposed to the Indexer API which reconstructs state from events emitted by chain.

On a high-level the end-user trading applications and Injective Products use the Indexer API to read data and the Chain API to write data to the blockchain. Even though it’s possible to develop trading applications using the Chain API only, the Indexer API includes more methods, streaming support, gRPC and also allows you to fetch historical data as the Chain API queries the blockchain state which doesn’t include historical records.

- Account

Includes all messages related to accounts and transfers.

MsgDeposit

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare tx msg
    msg = composer.msg_deposit(sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=1, denom="inj")

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgDeposit{
        Sender:       senderAddress.String(),
        SubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        Amount: sdktypes.Coin{
            Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstring(Optional) the subaccount ID to deposit funds into. If empty, the coin will be deposited to the sender's default subaccount address.No
amounttypes.Cointhe amount of the deposit (in chain format)Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "49CA54DA708B5F58E401B661A8A6B590447AFCFCD192D95AE2DAFDBEB00DCD33"
raw_log: "[]"

gas wanted: 105793
gas fee: 0.0000528965 INJ
DEBU[0001] broadcastTx with nonce 3491                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5212649  fn=func1 src="client/chain/chain.go:619" txHash=8B3F45BB7247C0BFC916B4D9177601E512BBAEF8FA60E5B61D5CC815910D059F
DEBU[0002] nonce incremented to 3492                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  132099                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000660495 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgWithdraw

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)
    denom = "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"

    # prepare tx msg
    msg = composer.msg_withdraw(sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=1, denom=denom)

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgWithdraw{
        Sender:       senderAddress.String(),
        SubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        Amount: sdktypes.Coin{
            Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstringthe subaccount ID to withdraw funds fromYes
amounttypes.Cointhe amount of the withdrawal (in chain format)Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "30724652FB970C8C08B0179D134AC519795068885541B08C6BB0AE3E8F0E59CE"
raw_log: "[]"

gas wanted: 111105
gas fee: 0.0000555525 INJ
DEBU[0001] broadcastTx with nonce 3504                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5214520  fn=func1 src="client/chain/chain.go:619" txHash=B73529AE8EE92B931B5E52102DE67251B71B492421D718644A79ED826BD6B451
DEBU[0004] nonce incremented to 3505                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  129606                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000064803 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgSubaccountTransfer

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)
    dest_subaccount_id = address.get_subaccount_id(index=1)

    # prepare tx msg
    msg = composer.msg_subaccount_transfer(
        sender=address.to_acc_bech32(),
        source_subaccount_id=subaccount_id,
        destination_subaccount_id=dest_subaccount_id,
        amount=100,
        denom="inj",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgSubaccountTransfer{
        Sender:                  senderAddress.String(),
        SourceSubaccountId:      "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        DestinationSubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000001",
        Amount: sdktypes.Coin{
            Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
source_subaccount_idstringthe source subaccount IDYes
destination_subaccount_idstringthe destination subaccount IDYes
amounttypes.Cointhe amount to transfer (in chain format)Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "2E37F37501D025D09FADEB8A64DD47362292DE47D81514723BB061410409C956"
raw_log: "[]"

gas wanted: 97883
gas fee: 0.0000489415 INJ
DEBU[0001] broadcastTx with nonce 3506                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214566  fn=func1 src="client/chain/chain.go:619" txHash=11181E2B0ACD1B0358CA19D52EF05D191B24F4E91B7548E94F3B7AC5841ABD8F
DEBU[0003] nonce incremented to 3507                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  122103                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000610515 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgExternalTransfer

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)
    dest_subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"

    # prepare tx msg
    msg = composer.msg_external_transfer(
        sender=address.to_acc_bech32(),
        source_subaccount_id=subaccount_id,
        destination_subaccount_id=dest_subaccount_id,
        amount=100,
        denom="inj",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgExternalTransfer{
        Sender:                  senderAddress.String(),
        SourceSubaccountId:      "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        DestinationSubaccountId: "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
        Amount: sdktypes.Coin{
            Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
source_subaccount_idstringthe source subaccount IDYes
destination_subaccount_idstringthe destination subaccount IDYes
amounttypes.Cointhe amount to transfer (in chain format)Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "6790503C993094B50A7E0CBAD4B27E1ABFE24060509CB189DCC408A0AD99F894"
raw_log: "[]"

gas wanted: 99159
gas fee: 0.0000495795 INJ
DEBU[0002] broadcastTx with nonce 3658                   fn=func1 src="client/chain/chain.go:607"
DEBU[0005] msg batch committed successfully at height 6556107  fn=func1 src="client/chain/chain.go:628" txHash=BD185F427DD1987969605695779C48FD4BEECC7AEC9C51ED5E0BF1747A471F4E
DEBU[0005] nonce incremented to 3659                     fn=func1 src="client/chain/chain.go:632"
DEBU[0005] gas wanted:  122397                           fn=func1 src="client/chain/chain.go:633"
gas fee: 0.0000611985 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgSendToEth

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv
import requests

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare msg
    asset = "injective-protocol"
    coingecko_endpoint = f"https://api.coingecko.com/api/v3/simple/price?ids={asset}&vs_currencies=usd"
    token_price = requests.get(coingecko_endpoint).json()[asset]["usd"]
    minimum_bridge_fee_usd = 10
    bridge_fee = minimum_bridge_fee_usd / token_price
    token_decimals = 6
    chain_bridge_fee = int(Decimal(str(bridge_fee)) * Decimal(f"1e{token_decimals}"))

    # prepare tx msg
    msg = composer.msg_send_to_eth(
        sender=address.to_acc_bech32(),
        denom="inj",
        eth_dest="0xaf79152ac5df276d9a8e1e2e22822f9713474902",
        amount=23,
        bridge_fee=chain_bridge_fee,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    peggytypes "github.com/InjectiveLabs/sdk-go/chain/peggy/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    ethDest := "0xaf79152ac5df276d9a8e1e2e22822f9713474902"

    amount := sdktypes.Coin{
        Denom: "inj", Amount: math.NewInt(5000000000000000000), // 5 INJ
    }
    bridgeFee := sdktypes.Coin{
        Denom: "inj", Amount: math.NewInt(2000000000000000000), // 2 INJ
    }

    msg := peggytypes.MsgSendToEth{
        Sender:    senderAddress.String(),
        Amount:    amount,
        EthDest:   ethDest,
        BridgeFee: bridgeFee,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
eth_deststringThe Ethereum address to send the tokens toYes
amounttypes.CoinThe amount of tokens to sendYes
bridge_feetypes.CoinThe fee paid for the bridge, distinct from the fee paid to the chain to actually send this message in the first place. So a successful send has two layers of fees for the userYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "5529016817553230024B45B44ABEB0538DC0AF9EEE0DEAD467B91C85BCCCAC87"
raw_log: "[]"

gas wanted: 125732
gas fee: 0.000062866 INJ
DEBU[0001] broadcastTx with nonce 3515                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5215066  fn=func1 src="client/chain/chain.go:619" txHash=391AB87558318BD7FF2CCB9D68ED309AD073FA64C8395A493D6C347FF572AF38
DEBU[0004] nonce incremented to 3516                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  161907                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000809535 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

SendToInjective

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.core.network import Network
from pyinjective.sendtocosmos import Peggo


async def main() -> None:
    dotenv.load_dotenv()
    private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: testnet, mainnet
    network = Network.testnet()
    peggo_composer = Peggo(network=network.string())

    ethereum_endpoint = "https://eth-goerli.g.alchemy.com/v2/q-7JVv4mTfsNh1y_djKkKn3maRBGILLL"

    maxFeePerGas_Gwei = 4
    maxPriorityFeePerGas_Gwei = 4

    token_contract = "0xBe8d71D26525440A03311cc7fa372262c5354A3c"
    receiver = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    amount = 1

    data = (
        '{"@type": "/injective.exchange.v1beta1.MsgDeposit",'
        '"sender": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",'
        '"subaccountId": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",'
        '"amount": {"denom": "inj","amount": "1000000000000000000"}}'
    )

    with open("../pyinjective/Peggo_ABI.json") as pego_file:
        peggo_data = pego_file.read()
    peggo_abi = json.loads(peggo_data)

    peggo_composer.sendToInjective(
        ethereum_endpoint=ethereum_endpoint,
        private_key=private_key,
        token_contract=token_contract,
        receiver=receiver,
        amount=amount,
        maxFeePerGas=maxFeePerGas_Gwei,
        maxPriorityFeePerGas=maxPriorityFeePerGas_Gwei,
        data=data,
        peggo_abi=peggo_abi,
    )


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
ethereum_endpointStringThe ethereum endpoint, you can get one from providers like Infura and AlchemyYes
private_keyStringPrivate key of the account to be used to sign the transactionYes
token_contractStringThe token contract, you can find the contract for the token you want to transfer on etherscanYes
receiverStringThe Injective Chain address to receive the fundsYes
amountFloatThe amount to transferYes
maxFeePerGasIntegerThe maxFeePerGas in GweiYes
maxPriorityFeePerGasIntegerThe maxPriorityFeePerGas in GweiYes
peggo_abiStringPeggo contract ABIYes
dataStringThe body of the message to send to Injective chain to do the depositYes
decimalsIntegerNumber of decimals in Injective chain of the token being transferred (default: 18)No

Response Parameters

Response Example:

Transferred 1 0x36b3d7ace7201e28040eff30e815290d7b37ffad from 0xbdAEdEc95d563Fb05240d6e01821008454c24C36 to inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku

Transaction hash: 0xb538abc7c2f893a2fe24c7a8ea606ff48d980a754499f1bec89b862c2bcb9ea7

GetTx

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.devnet()
    client = AsyncClient(network)
    tx_hash = "EA598BB5297341636DD62D378DEB87ECE6F95AFB4F45966AA6A53D36EF022DA5"
    tx_logs = await client.fetch_tx(hash=tx_hash)
    print(tx_logs)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"
    "os"
    "time"

    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/InjectiveLabs/sdk-go/client/common"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("mainnet", "lb")
    tmRPC, err := rpchttp.New(network.TmEndpoint)

    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    timeOutCtx, cancelFn := context.WithTimeout(ctx, 30*time.Second)
    defer cancelFn()

    resp, err := chainClient.GetTx(timeOutCtx, "A2B2B971C690AE7977451D24D6F450AECE6BCCB271E91E32C2563342DDA5254B")
    if err != nil {
        panic(err)
    }

    fmt.Println(resp.TxResponse)
}
ParameterTypeDescriptionRequired
hashstringhash is the tx hash to query, encoded as a hex string.Yes

Response Example:

{
   "tx":{
      "body":{
         "messages":[
            "OrderedDict("[
               "(""@type",
               "/cosmos.authz.v1beta1.MsgExec"")",
               "(""grantee",
               "inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"")",
               "(""msgs",
               [
                  "OrderedDict("[
                     "(""@type",
                     "/injective.exchange.v1beta1.MsgCreateSpotMarketOrder"")",
                     "(""sender",
                     "inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"")",
                     "(""order",
                     {
                        "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
                        "orderInfo":{
                           "subaccountId":"0x6561b5033700b734c54df4084240395889d23492000000000000000000000000",
                           "feeRecipient":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                           "price":"10194000",
                           "quantity":"175000000000000000000000000000000000",
                           "cid":""
                        },
                        "orderType":"SELL",
                        "triggerPrice":"0"
                     }")"
                  ]")"
               ]")"
            ]")"
         ],
         "timeoutHeight":"17518637",
         "memo":"",
         "extensionOptions":[

         ],
         "nonCriticalExtensionOptions":[

         ]
      },
      "authInfo":{
         "signerInfos":[
            {
               "publicKey":"OrderedDict("[
                  "(""@type",
                  "/injective.crypto.v1beta1.ethsecp256k1.PubKey"")",
                  "(""key",
                  "AmHqvENFf9E5s9vQFLQbcbHv4OIKTEWXVO4f7PZS9YOz"")"
               ]")",
               "modeInfo":{
                  "single":{
                     "mode":"SIGN_MODE_DIRECT"
                  }
               },
               "sequence":"211255"
            }
         ],
         "fee":{
            "amount":[
               {
                  "denom":"inj",
                  "amount":"52378500000000"
               }
            ],
            "gasLimit":"104757",
            "payer":"",
            "granter":""
         }
      },
      "signatures":[
         "Hn4Ugl50quZLQv/btmpWGMDr4F4RX5eeaGMIbc5VzC06a0sH3yRLvcNPyAcODcVjMQ1jbIRM01SYkvu2By+xJw=="
      ]
   },
   "txResponse":{
      "height":"17518608",
      "txhash":"D265527E3171C47D01D7EC9B839A95F8F794D4E683F26F5564025961C96EFDDA",
      "data":"126F0A252F636F736D6F732E617574687A2E763162657461312E4D736745786563526573706F6E736512460A440A42307834316630316536623266646433623463303631663834323235666165653033333536646238643137656265373631356661393232663132363861666434316136",
      "rawLog":"[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.authz.v1beta1.MsgExec\"},{\"key\":\"sender\",\"value\":\"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7\"},{\"key\":\"module\",\"value\":\"authz\"}]},{\"type\":\"coin_spent\",\"attributes\":[{\"key\":\"spender\",\"value\":\"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7\"},{\"key\":\"amount\",\"value\":\"175000000000000000inj\"},{\"key\":\"authz_msg_index\",\"value\":\"0\"}]},{\"type\":\"coin_received\",\"attributes\":[{\"key\":\"receiver\",\"value\":\"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk\"},{\"key\":\"amount\",\"value\":\"175000000000000000inj\"},{\"key\":\"authz_msg_index\",\"value\":\"0\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk\"},{\"key\":\"sender\",\"value\":\"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7\"},{\"key\":\"amount\",\"value\":\"175000000000000000inj\"},{\"key\":\"authz_msg_index\",\"value\":\"0\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7\"},{\"key\":\"authz_msg_index\",\"value\":\"0\"}]}]}]",
      "logs":[
         {
            "events":[
               {
                  "type":"message",
                  "attributes":[
                     {
                        "key":"action",
                        "value":"/cosmos.authz.v1beta1.MsgExec"
                     },
                     {
                        "key":"sender",
                        "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"
                     },
                     {
                        "key":"module",
                        "value":"authz"
                     }
                  ]
               },
               {
                  "type":"coin_spent",
                  "attributes":[
                     {
                        "key":"spender",
                        "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"
                     },
                     {
                        "key":"amount",
                        "value":"175000000000000000inj"
                     },
                     {
                        "key":"authz_msg_index",
                        "value":"0"
                     }
                  ]
               },
               {
                  "type":"coin_received",
                  "attributes":[
                     {
                        "key":"receiver",
                        "value":"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk"
                     },
                     {
                        "key":"amount",
                        "value":"175000000000000000inj"
                     },
                     {
                        "key":"authz_msg_index",
                        "value":"0"
                     }
                  ]
               },
               {
                  "type":"transfer",
                  "attributes":[
                     {
                        "key":"recipient",
                        "value":"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk"
                     },
                     {
                        "key":"sender",
                        "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"
                     },
                     {
                        "key":"amount",
                        "value":"175000000000000000inj"
                     },
                     {
                        "key":"authz_msg_index",
                        "value":"0"
                     }
                  ]
               },
               {
                  "type":"message",
                  "attributes":[
                     {
                        "key":"sender",
                        "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"
                     },
                     {
                        "key":"authz_msg_index",
                        "value":"0"
                     }
                  ]
               }
            ],
            "msgIndex":0,
            "log":""
         }
      ],
      "gasWanted":"104757",
      "gasUsed":"102564",
      "tx":"OrderedDict("[
         "(""@type",
         "/cosmos.tx.v1beta1.Tx"")",
         "(""body",
         {
            "messages":[
               "OrderedDict("[
                  "(""@type",
                  "/cosmos.authz.v1beta1.MsgExec"")",
                  "(""grantee",
                  "inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"")",
                  "(""msgs",
                  [
                     "OrderedDict("[
                        "(""@type",
                        "/injective.exchange.v1beta1.MsgCreateSpotMarketOrder"")",
                        "(""sender",
                        "inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7"")",
                        "(""order",
                        {
                           "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
                           "orderInfo":{
                              "subaccountId":"0x6561b5033700b734c54df4084240395889d23492000000000000000000000000",
                              "feeRecipient":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                              "price":"10194000",
                              "quantity":"175000000000000000000000000000000000",
                              "cid":""
                           },
                           "orderType":"SELL",
                           "triggerPrice":"0"
                        }")"
                     ]")"
                  ]")"
               ]")"
            ],
            "timeoutHeight":"17518637",
            "memo":"",
            "extensionOptions":[

            ],
            "nonCriticalExtensionOptions":[

            ]
         }")",
         "(""authInfo",
         {
            "signerInfos":[
               {
                  "publicKey":"OrderedDict("[
                     "(""@type",
                     "/injective.crypto.v1beta1.ethsecp256k1.PubKey"")",
                     "(""key",
                     "AmHqvENFf9E5s9vQFLQbcbHv4OIKTEWXVO4f7PZS9YOz"")"
                  ]")",
                  "modeInfo":{
                     "single":{
                        "mode":"SIGN_MODE_DIRECT"
                     }
                  },
                  "sequence":"211255"
               }
            ],
            "fee":{
               "amount":[
                  {
                     "denom":"inj",
                     "amount":"52378500000000"
                  }
               ],
               "gasLimit":"104757",
               "payer":"",
               "granter":""
            }
         }")",
         "(""signatures",
         [
            "Hn4Ugl50quZLQv/btmpWGMDr4F4RX5eeaGMIbc5VzC06a0sH3yRLvcNPyAcODcVjMQ1jbIRM01SYkvu2By+xJw=="
         ]")"
      ]")",
      "timestamp":"2023-10-23T18:48:19Z",
      "events":[
         {
            "type":"coin_spent",
            "attributes":[
               {
                  "key":"spender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"52378500000000inj",
                  "index":true
               }
            ]
         },
         {
            "type":"coin_received",
            "attributes":[
               {
                  "key":"receiver",
                  "value":"inj17xpfvakm2amg962yls6f84z3kell8c5l6s5ye9",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"52378500000000inj",
                  "index":true
               }
            ]
         },
         {
            "type":"transfer",
            "attributes":[
               {
                  "key":"recipient",
                  "value":"inj17xpfvakm2amg962yls6f84z3kell8c5l6s5ye9",
                  "index":true
               },
               {
                  "key":"sender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"52378500000000inj",
                  "index":true
               }
            ]
         },
         {
            "type":"message",
            "attributes":[
               {
                  "key":"sender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               }
            ]
         },
         {
            "type":"tx",
            "attributes":[
               {
                  "key":"fee",
                  "value":"52378500000000inj",
                  "index":true
               },
               {
                  "key":"fee_payer",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               }
            ]
         },
         {
            "type":"tx",
            "attributes":[
               {
                  "key":"acc_seq",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7/211255",
                  "index":true
               }
            ]
         },
         {
            "type":"tx",
            "attributes":[
               {
                  "key":"signature",
                  "value":"Hn4Ugl50quZLQv/btmpWGMDr4F4RX5eeaGMIbc5VzC06a0sH3yRLvcNPyAcODcVjMQ1jbIRM01SYkvu2By+xJw==",
                  "index":true
               }
            ]
         },
         {
            "type":"message",
            "attributes":[
               {
                  "key":"action",
                  "value":"/cosmos.authz.v1beta1.MsgExec",
                  "index":true
               },
               {
                  "key":"sender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"module",
                  "value":"authz",
                  "index":true
               }
            ]
         },
         {
            "type":"coin_spent",
            "attributes":[
               {
                  "key":"spender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"175000000000000000inj",
                  "index":true
               },
               {
                  "key":"authz_msg_index",
                  "value":"0",
                  "index":true
               }
            ]
         },
         {
            "type":"coin_received",
            "attributes":[
               {
                  "key":"receiver",
                  "value":"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"175000000000000000inj",
                  "index":true
               },
               {
                  "key":"authz_msg_index",
                  "value":"0",
                  "index":true
               }
            ]
         },
         {
            "type":"transfer",
            "attributes":[
               {
                  "key":"recipient",
                  "value":"inj14vnmw2wee3xtrsqfvpcqg35jg9v7j2vdpzx0kk",
                  "index":true
               },
               {
                  "key":"sender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"amount",
                  "value":"175000000000000000inj",
                  "index":true
               },
               {
                  "key":"authz_msg_index",
                  "value":"0",
                  "index":true
               }
            ]
         },
         {
            "type":"message",
            "attributes":[
               {
                  "key":"sender",
                  "value":"inj1v4sm2qehqzmnf32d7syyyspetzyaydyj4r4yv7",
                  "index":true
               },
               {
                  "key":"authz_msg_index",
                  "value":"0",
                  "index":true
               }
            ]
         }
      ],
      "codespace":"",
      "code":0,
      "info":""
   }
}
code: 0
codespace: ""
data: 0AC1010A302F696E6A6563746976652E65786368616E67652E763162657461312E4D736742617463685570646174654F7264657273128C011202010122423078396638313937363932323364333439646462313738333335303831396437396235373736323363623361613163633462346534326361643638666264393462362242307834656239333035636565663365616264663762653734313338343931633966373738663439613131613164643733613930623761666366323731353263633935
events:
- attributes:
  - index: true
    key: YWNjX3NlcQ==
    value: aW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13LzEwODczMTIy
  type: tx
- attributes:
  - index: true
    key: c2lnbmF0dXJl
    value: eWtDcmVOVjdEaHF1Z1k5d2gvc25EWFF4VUtibC9ZK3h3Nmw5d3ZhU28zcExSYU9rVlR2b3VuaERmRy9ZYzl0SEplYVd6L1d2am1OekU2MmFJNHBrSHdFPQ==
  type: tx
- attributes:
  - index: true
    key: c3BlbmRlcg==
    value: aW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13
  - index: true
    key: YW1vdW50
    value: MzY5ODAxMDAwMDAwMDAwaW5q
  type: coin_spent
- attributes:
  - index: true
    key: cmVjZWl2ZXI=
    value: aW5qMTd4cGZ2YWttMmFtZzk2MnlsczZmODR6M2tlbGw4YzVsNnM1eWU5
  - index: true
    key: YW1vdW50
    value: MzY5ODAxMDAwMDAwMDAwaW5q
  type: coin_received
- attributes:
  - index: true
    key: cmVjaXBpZW50
    value: aW5qMTd4cGZ2YWttMmFtZzk2MnlsczZmODR6M2tlbGw4YzVsNnM1eWU5
  - index: true
    key: c2VuZGVy
    value: aW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13
  - index: true
    key: YW1vdW50
    value: MzY5ODAxMDAwMDAwMDAwaW5q
  type: transfer
- attributes:
  - index: true
    key: c2VuZGVy
    value: aW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13
  type: message
- attributes:
  - index: true
    key: ZmVl
    value: MzY5ODAxMDAwMDAwMDAwaW5q
  - index: true
    key: ZmVlX3BheWVy
    value: aW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13
  type: tx
- attributes:
  - index: true
    key: YWN0aW9u
    value: L2luamVjdGl2ZS5leGNoYW5nZS52MWJldGExLk1zZ0JhdGNoVXBkYXRlT3JkZXJz
  type: message
- attributes:
  - index: true
    key: aXNMaW1pdENhbmNlbA==
    value: dHJ1ZQ==
  - index: true
    key: bGltaXRfb3JkZXI=
    value: eyJvcmRlcl9pbmZvIjp7InN1YmFjY291bnRfaWQiOiIweGVjMmIyMWFmYTczZDA1MTE0ZTNlZWE4NTEzNThiODZiNTY3NjkwNWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiLCJmZWVfcmVjaXBpZW50IjoiaW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13IiwicHJpY2UiOiI3NzM1MDAwLjAwMDAwMDAwMDAwMDAwMDAwMCIsInF1YW50aXR5IjoiNjQ2LjU2OTAwMDAwMDAwMDAwMDAwMCJ9LCJvcmRlcl90eXBlIjoiU0VMTF9QTyIsIm1hcmdpbiI6IjAuMDAwMDAwMDAwMDAwMDAwMDAwIiwiZmlsbGFibGUiOiI2NDYuNTY5MDAwMDAwMDAwMDAwMDAwIiwidHJpZ2dlcl9wcmljZSI6bnVsbCwib3JkZXJfaGFzaCI6ImhTZUNBOEU1a0krdmEzZUdLMnhWUGJxSlZybzNSUzlPRkJCVHhxMXhtVDg9In0=
  - index: true
    key: bWFya2V0X2lk
    value: IjB4OWI5OTgwMTY3ZWNjMzY0NWZmMWE1NTE3ODg2NjUyZDk0YTA4MjVlNTRhNzdkMjA1N2NiYmUzZWJlZTAxNTk2MyI=
  - index: true
    key: bWFya2V0X29yZGVyX2NhbmNlbA==
    value: bnVsbA==
  type: injective.exchange.v1beta1.EventCancelDerivativeOrder
- attributes:
  - index: true
    key: aXNMaW1pdENhbmNlbA==
    value: dHJ1ZQ==
  - index: true
    key: bGltaXRfb3JkZXI=
    value: eyJvcmRlcl9pbmZvIjp7InN1YmFjY291bnRfaWQiOiIweGVjMmIyMWFmYTczZDA1MTE0ZTNlZWE4NTEzNThiODZiNTY3NjkwNWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEiLCJmZWVfcmVjaXBpZW50IjoiaW5qMWFzNGpydGE4ODV6M3puMzdhMnozeGs5Y2RkdDhkeXptZnZ3ZW13IiwicHJpY2UiOiI3NjY0MDAwLjAwMDAwMDAwMDAwMDAwMDAwMCIsInF1YW50aXR5IjoiNjQ2LjU2OTAwMDAwMDAwMDAwMDAwMCJ9LCJvcmRlcl90eXBlIjoiQlVZX1BPIiwibWFyZ2luIjoiOTkxMDYwOTYzLjIwMDAwMDAwMDAwMDAwMDAwMCIsImZpbGxhYmxlIjoiNjQ2LjU2OTAwMDAwMDAwMDAwMDAwMCIsInRyaWdnZXJfcHJpY2UiOm51bGwsIm9yZGVyX2hhc2giOiJnYllhaEVIdFhLY0J3RkgvazU4ZmxQdVZlUWRzcGlabjA5NWZia3E0a0dNPSJ9
  - index: true
    key: bWFya2V0X2lk
    value: IjB4OWI5OTgwMTY3ZWNjMzY0NWZmMWE1NTE3ODg2NjUyZDk0YTA4MjVlNTRhNzdkMjA1N2NiYmUzZWJlZTAxNTk2MyI=
  - index: true
    key: bWFya2V0X29yZGVyX2NhbmNlbA==
    value: bnVsbA==
  type: injective.exchange.v1beta1.EventCancelDerivativeOrder
- attributes:
  - index: true
    key: YnV5X29yZGVycw==
    value: W10=
  - index: true
    key: bWFya2V0X2lk
    value: IjB4OWI5OTgwMTY3ZWNjMzY0NWZmMWE1NTE3ODg2NjUyZDk0YTA4MjVlNTRhNzdkMjA1N2NiYmUzZWJlZTAxNTk2MyI=
  - index: true
    key: c2VsbF9vcmRlcnM=
    value: W3sib3JkZXJfaW5mbyI6eyJzdWJhY2NvdW50X2lkIjoiMHhlYzJiMjFhZmE3M2QwNTExNGUzZWVhODUxMzU4Yjg2YjU2NzY5MDViMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxIiwiZmVlX3JlY2lwaWVudCI6ImluajFhczRqcnRhODg1ejN6bjM3YTJ6M3hrOWNkZHQ4ZHl6bWZ2d2VtdyIsInByaWNlIjoiNzczNzAwMC4wMDAwMDAwMDAwMDAwMDAwMDAiLCJxdWFudGl0eSI6IjY0Ni4zMzcwMDAwMDAwMDAwMDAwMDAifSwib3JkZXJfdHlwZSI6IlNFTExfUE8iLCJtYXJnaW4iOiIwLjAwMDAwMDAwMDAwMDAwMDAwMCIsImZpbGxhYmxlIjoiNjQ2LjMzNzAwMDAwMDAwMDAwMDAwMCIsInRyaWdnZXJfcHJpY2UiOm51bGwsIm9yZGVyX2hhc2giOiJuNEdYYVNJOU5KM2JGNE0xQ0JuWG0xZDJJOHM2b2N4TFRrTEsxbys5bExZPSJ9XQ==
  type: injective.exchange.v1beta1.EventNewDerivativeOrders
- attributes:
  - index: true
    key: YnV5X29yZGVycw==
    value: W3sib3JkZXJfaW5mbyI6eyJzdWJhY2NvdW50X2lkIjoiMHhlYzJiMjFhZmE3M2QwNTExNGUzZWVhODUxMzU4Yjg2YjU2NzY5MDViMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxIiwiZmVlX3JlY2lwaWVudCI6ImluajFhczRqcnRhODg1ejN6bjM3YTJ6M3hrOWNkZHQ4ZHl6bWZ2d2VtdyIsInByaWNlIjoiNzY2NjAwMC4wMDAwMDAwMDAwMDAwMDAwMDAiLCJxdWFudGl0eSI6IjY0Ni4zMzcwMDAwMDAwMDAwMDAwMDAifSwib3JkZXJfdHlwZSI6IkJVWV9QTyIsIm1hcmdpbiI6Ijk5MDk2Mzg4OC40MDAwMDAwMDAwMDAwMDAwMDAiLCJmaWxsYWJsZSI6IjY0Ni4zMzcwMDAwMDAwMDAwMDAwMDAiLCJ0cmlnZ2VyX3ByaWNlIjpudWxsLCJvcmRlcl9oYXNoIjoiVHJrd1hPN3o2cjMzdm5RVGhKSEo5M2owbWhHaDNYT3BDM3I4OG5GU3pKVT0ifV0=
  - index: true
    key: bWFya2V0X2lk
    value: IjB4OWI5OTgwMTY3ZWNjMzY0NWZmMWE1NTE3ODg2NjUyZDk0YTA4MjVlNTRhNzdkMjA1N2NiYmUzZWJlZTAxNTk2MyI=
  - index: true
    key: c2VsbF9vcmRlcnM=
    value: W10=
  type: injective.exchange.v1beta1.EventNewDerivativeOrders
gas_used: "261983"
gas_wanted: "369801"
height: "32442284"
info: ""
logs:
- events:
  - attributes:
    - key: isLimitCancel
      value: "true"
    - key: limit_order
      value: '{"order_info":{"subaccount_id":"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001","fee_recipient":"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw","price":"7735000.000000000000000000","quantity":"646.569000000000000000"},"order_type":"SELL_PO","margin":"0.000000000000000000","fillable":"646.569000000000000000","trigger_price":null,"order_hash":"hSeCA8E5kI+va3eGK2xVPbqJVro3RS9OFBBTxq1xmT8="}'
    - key: market_id
      value: '"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963"'
    - key: market_order_cancel
      value: "null"
    - key: isLimitCancel
      value: "true"
    - key: limit_order
      value: '{"order_info":{"subaccount_id":"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001","fee_recipient":"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw","price":"7664000.000000000000000000","quantity":"646.569000000000000000"},"order_type":"BUY_PO","margin":"991060963.200000000000000000","fillable":"646.569000000000000000","trigger_price":null,"order_hash":"gbYahEHtXKcBwFH/k58flPuVeQdspiZn095fbkq4kGM="}'
    - key: market_id
      value: '"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963"'
    - key: market_order_cancel
      value: "null"
    type: injective.exchange.v1beta1.EventCancelDerivativeOrder
  - attributes:
    - key: buy_orders
      value: '[]'
    - key: market_id
      value: '"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963"'
    - key: sell_orders
      value: '[{"order_info":{"subaccount_id":"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001","fee_recipient":"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw","price":"7737000.000000000000000000","quantity":"646.337000000000000000"},"order_type":"SELL_PO","margin":"0.000000000000000000","fillable":"646.337000000000000000","trigger_price":null,"order_hash":"n4GXaSI9NJ3bF4M1CBnXm1d2I8s6ocxLTkLK1o+9lLY="}]'
    - key: buy_orders
      value: '[{"order_info":{"subaccount_id":"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001","fee_recipient":"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw","price":"7666000.000000000000000000","quantity":"646.337000000000000000"},"order_type":"BUY_PO","margin":"990963888.400000000000000000","fillable":"646.337000000000000000","trigger_price":null,"order_hash":"TrkwXO7z6r33vnQThJHJ93j0mhGh3XOpC3r88nFSzJU="}]'
    - key: market_id
      value: '"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963"'
    - key: sell_orders
      value: '[]'
    type: injective.exchange.v1beta1.EventNewDerivativeOrders
  - attributes:
    - key: action
      value: /injective.exchange.v1beta1.MsgBatchUpdateOrders
    type: message
  log: ""
  msg_index: 0
raw_log: '[{"events":[{"type":"injective.exchange.v1beta1.EventCancelDerivativeOrder","attributes":[{"key":"isLimitCancel","value":"true"},{"key":"limit_order","value":"{\"order_info\":{\"subaccount_id\":\"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001\",\"fee_recipient\":\"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw\",\"price\":\"7735000.000000000000000000\",\"quantity\":\"646.569000000000000000\"},\"order_type\":\"SELL_PO\",\"margin\":\"0.000000000000000000\",\"fillable\":\"646.569000000000000000\",\"trigger_price\":null,\"order_hash\":\"hSeCA8E5kI+va3eGK2xVPbqJVro3RS9OFBBTxq1xmT8=\"}"},{"key":"market_id","value":"\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\""},{"key":"market_order_cancel","value":"null"},{"key":"isLimitCancel","value":"true"},{"key":"limit_order","value":"{\"order_info\":{\"subaccount_id\":\"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001\",\"fee_recipient\":\"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw\",\"price\":\"7664000.000000000000000000\",\"quantity\":\"646.569000000000000000\"},\"order_type\":\"BUY_PO\",\"margin\":\"991060963.200000000000000000\",\"fillable\":\"646.569000000000000000\",\"trigger_price\":null,\"order_hash\":\"gbYahEHtXKcBwFH/k58flPuVeQdspiZn095fbkq4kGM=\"}"},{"key":"market_id","value":"\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\""},{"key":"market_order_cancel","value":"null"}]},{"type":"injective.exchange.v1beta1.EventNewDerivativeOrders","attributes":[{"key":"buy_orders","value":"[]"},{"key":"market_id","value":"\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\""},{"key":"sell_orders","value":"[{\"order_info\":{\"subaccount_id\":\"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001\",\"fee_recipient\":\"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw\",\"price\":\"7737000.000000000000000000\",\"quantity\":\"646.337000000000000000\"},\"order_type\":\"SELL_PO\",\"margin\":\"0.000000000000000000\",\"fillable\":\"646.337000000000000000\",\"trigger_price\":null,\"order_hash\":\"n4GXaSI9NJ3bF4M1CBnXm1d2I8s6ocxLTkLK1o+9lLY=\"}]"},{"key":"buy_orders","value":"[{\"order_info\":{\"subaccount_id\":\"0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001\",\"fee_recipient\":\"inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw\",\"price\":\"7666000.000000000000000000\",\"quantity\":\"646.337000000000000000\"},\"order_type\":\"BUY_PO\",\"margin\":\"990963888.400000000000000000\",\"fillable\":\"646.337000000000000000\",\"trigger_price\":null,\"order_hash\":\"TrkwXO7z6r33vnQThJHJ93j0mhGh3XOpC3r88nFSzJU=\"}]"},{"key":"market_id","value":"\"0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963\""},{"key":"sell_orders","value":"[]"}]},{"type":"message","attributes":[{"key":"action","value":"/injective.exchange.v1beta1.MsgBatchUpdateOrders"}]}]}]'
timestamp: "2023-05-02T03:04:55Z"
tx:
  '@type': /cosmos.tx.v1beta1.Tx
  auth_info:
    fee:
      amount:
      - amount: "369801000000000"
        denom: inj
      gas_limit: "369801"
      granter: ""
      payer: ""
    signer_infos:
    - mode_info:
        single:
          mode: SIGN_MODE_DIRECT
      public_key:
        '@type': /injective.crypto.v1beta1.ethsecp256k1.PubKey
        key: An8DQ7/twFqvUuJxd5rCIkl04BfQocYS2T/A2pnYbFOJ
      sequence: "10873122"
  body:
    extension_options: []
    memo: ""
    messages:
    - '@type': /injective.exchange.v1beta1.MsgBatchUpdateOrders
      binary_options_market_ids_to_cancel_all: []
      binary_options_orders_to_cancel: []
      binary_options_orders_to_create: []
      derivative_market_ids_to_cancel_all: []
      derivative_orders_to_cancel:
      - market_id: 0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963
        order_hash: 0x85278203c139908faf6b77862b6c553dba8956ba37452f4e141053c6ad71993f
        order_mask: 0
        subaccount_id: 0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001
      - market_id: 0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963
        order_hash: 0x81b61a8441ed5ca701c051ff939f1f94fb9579076ca62667d3de5f6e4ab89063
        order_mask: 0
        subaccount_id: 0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001
      derivative_orders_to_create:
      - margin: "0.000000000000000000"
        market_id: 0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963
        order_info:
          fee_recipient: inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw
          price: "7737000.000000000000000000"
          quantity: "646.337000000000000000"
          subaccount_id: 0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001
        order_type: SELL_PO
        trigger_price: null
      - margin: "990963888.400000000000000000"
        market_id: 0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963
        order_info:
          fee_recipient: inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw
          price: "7666000.000000000000000000"
          quantity: "646.337000000000000000"
          subaccount_id: 0xec2b21afa73d05114e3eea851358b86b5676905b000000000000000000000001
        order_type: BUY_PO
        trigger_price: null
      sender: inj1as4jrta885z3zn37a2z3xk9cddt8dyzmfvwemw
      spot_market_ids_to_cancel_all: []
      spot_orders_to_cancel: []
      spot_orders_to_create: []
      subaccount_id: ""
    non_critical_extension_options: []
    timeout_height: "0"
  signatures:
  - ykCreNV7DhqugY9wh/snDXQxUKbl/Y+xw6l9wvaSo3pLRaOkVTvounhDfG/Yc9tHJeaWz/WvjmNzE62aI4pkHwE=
txhash: A2B2B971C690AE7977451D24D6F450AECE6BCCB271E91E32C2563342DDA5254B
ParameterTypeDescription
txTxtx is the queried transaction.
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


Tx

ParameterTypeDescription
bodyTxBodybody is the processable content of the transaction
auth_infoAuthInfoauth_info is the authorization related content of the transaction, specifically signers, signer modes and fee
signatures][byte arraysignatures is a list of signatures that matches the length and order of AuthInfo's signer_infos to allow connecting signature meta information like public key and signing mode by position.


TxBody

ParameterTypeDescription
messagestypes.Any arraymessages is a list of messages to be executed. The required signers of those messages define the number and order of elements in AuthInfo's signer_infos and Tx's signatures. Each required signer address is added to the list only the first time it occurs. By convention, the first required signer (usually from the first message) is referred to as the primary signer and pays the fee for the whole transaction.
memostringmemo is any arbitrary note/comment to be added to the transaction. WARNING: in clients, any publicly exposed text should not be called memo, but should be called `note` instead (see https://github.com/cosmos/cosmos-sdk/issues/9122).
timeout_heightuint64timeout is the block height after which this transaction will not be processed by the chain
extension_optionstypes.Any arrayextension_options are arbitrary options that can be added by chains when the default options are not sufficient. If any of these are present and can't be handled, the transaction will be rejected
non_critical_extension_optionstypes.Any arrayextension_options are arbitrary options that can be added by chains when the default options are not sufficient. If any of these are present and can't be handled, they will be ignored


AuthInfo

ParameterTypeDescription
signer_infosSignerInfo arraysigner_infos defines the signing modes for the required signers. The number and order of elements must match the required signers from TxBody's messages. The first element is the primary signer and the one which pays the fee.
feeFeeFee is the fee and gas limit for the transaction. The first signer is the primary signer and the one which pays the fee. The fee can be calculated based on the cost of evaluating the body and doing signature verification of the signers. This can be estimated via simulation.
tipTipTip is the optional tip used for transactions fees paid in another denom. This field is ignored if the chain didn't enable tips, i.e. didn't add the `TipDecorator` in its posthandler. Since: cosmos-sdk 0.46


SignerInfo

ParameterTypeDescription
public_keytypes.Anypublic_key is the public key of the signer. It is optional for accounts that already exist in state. If unset, the verifier can use the required \ signer address for this position and lookup the public key.
mode_infoModeInfomode_info describes the signing mode of the signer and is a nested structure to support nested multisig pubkey's
sequenceuint64sequence is the sequence of the account, which describes the number of committed transactions signed by a given address. It is used to prevent replay attacks.


ModeInfo

ParameterTypeDescription
singleModeInfo_Single
multiModeInfo_Multi
modesigning.SignModemode is the signing mode of the single signer
bitarraytypes1.CompactBitArraybitarray specifies which keys within the multisig are signing
mode_infosModeInfo arraymode_infos is the corresponding modes of the signers of the multisig which could include nested multisig public keys


Fee

ParameterTypeDescription
amountgithub_com_cosmos_cosmos_sdk_types.Coinsamount is the amount of coins to be paid as a fee
gas_limituint64gas_limit is the maximum gas that can be used in transaction processing before an out of gas error occurs
payerstringif unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees. the payer must be a tx signer (and thus have signed this field in AuthInfo). setting this field does *not* change the ordering of required signers for the transaction.
granterstringif set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does not support fee grants, this will fail


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


Tip

ParameterTypeDescription
amountgithub_com_cosmos_cosmos_sdk_types.Coinsamount is the amount of the tip
tipperstringtipper is the address of the account paying for the tip


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

StreamEventOrderFail

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import base64
import json

import websockets

from pyinjective.core.network import Network


async def main() -> None:
    network = Network.mainnet()
    event_filter = (
        "tm.event='Tx' AND message.sender='inj1rwv4zn3jptsqs7l8lpa3uvzhs57y8duemete9e' "
        "AND message.action='/injective.exchange.v2.MsgBatchUpdateOrders' "
        "AND injective.exchange.v2.EventOrderFail.flags EXISTS"
    )
    query = json.dumps(
        {
            "jsonrpc": "2.0",
            "method": "subscribe",
            "id": "0",
            "params": {"query": event_filter},
        }
    )

    async with websockets.connect(network.tm_websocket_endpoint) as ws:
        await ws.send(query)
        while True:
            res = await ws.recv()
            res = json.loads(res)
            result = res["result"]
            if result == {}:
                continue

            failed_order_hashes = json.loads(result["events"]["injective.exchange.v2.EventOrderFail.hashes"][0])
            failed_order_codes = json.loads(result["events"]["injective.exchange.v2.EventOrderFail.flags"][0])

            dict = {}
            for i, order_hash in enumerate(failed_order_hashes):
                hash = "0x" + base64.b64decode(order_hash).hex()
                dict[hash] = failed_order_codes[i]

            print(dict)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("mainnet", "lb")

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        "",
        nil,
    )
    if err != nil {
        panic(err)
    }

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    failEventCh := make(chan map[string]uint, 10000)
    go chainClient.StreamEventOrderFail("inj1rwv4zn3jptsqs7l8lpa3uvzhs57y8duemete9e", failEventCh)
    for {
        e := <-failEventCh
        fmt.Println(e)
    }
}

Response Parameters

Response Example:

{'0x7d6d0d2118488dcaccd57193372e536881f34132241f01c1721ed6aedffec419': 36}
map[0x9db0f6e90d63b151ab0d64f0c6d83f747969f353d8c39a68cca65d046907e92a:59 0xdf7e05e66ab7a47e7a8a1751d4b9360fd80058cd5186162cee6fe124c57ece82:36]

- Auction

Includes the message for placing bids in auctions.

MsgBid

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    msg = composer.msg_bid(sender=address.to_acc_bech32(), round=16250, bid_amount=1)

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    auctiontypes "github.com/InjectiveLabs/sdk-go/chain/auction/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    round := uint64(9355)
    bidAmount := sdktypes.Coin{
        Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
    }

    msg := auctiontypes.MsgBid{
        Sender:    senderAddress.String(),
        Round:     round,
        BidAmount: bidAmount,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
bid_amounttypes.Coinamount of the bid in INJ tokensYes
rounduint64the current auction round being bid onYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "F18B1E6E39FAEA646F487C223DAE161482B1A12FC00C20D04A43826B8DD3E40F"
raw_log: "[]"

gas wanted: 105842
gas fee: 0.000052921 INJ
DEBU[0001] broadcastTx with nonce 3508                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214789  fn=func1 src="client/chain/chain.go:619" txHash=BD49BD58A263A92465A93FD0E10C5076DA8334A45A60E29A66C2E5961998AB5F
DEBU[0002] nonce incremented to 3509                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  152112                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000076056 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Authz

Includes all messages and queries related to the Authz module. Authz is an implementation of the Cosmos SDK module, that allows granting arbitrary privileges from one account (the granter) to another account (the grantee). Authorizations must be granted for a particular Msg service method one by one using an implementation of the Authorization interface.

MsgGrant

There are two types of authorization, Generic and Typed. Generic authorization will grant permissions to the grantee to execute exchange-related messages in all markets, typed authorization restricts the privileges to specified markets. Typed authorization is generally more safe since even if the grantee's key is compromised the attacker will only be able to send orders in specified markets - thus prevents them from launching bogus markets on-chain and executing orders on behalf of the granter.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")
    grantee_public_address = os.getenv("INJECTIVE_GRANTEE_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    # subaccount_id = address.get_subaccount_id(index=0)
    # market_ids = ["0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"]

    # prepare tx msg

    # GENERIC AUTHZ
    msg = composer.msg_grant_generic(
        granter=address.to_acc_bech32(),
        grantee=grantee_public_address,
        msg_type="/injective.exchange.v2.MsgCreateSpotLimitOrder",
        expire_in=31536000,  # 1 year
    )

    # TYPED AUTHZ
    # msg = composer.msg_grant_typed(
    #     granter = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
    #     grantee = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
    #     msg_type = "CreateSpotLimitOrderAuthz",
    #     expire_in=31536000, # 1 year
    #     subaccount_id=subaccount_id,
    #     market_ids=market_ids
    # )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    granter := senderAddress.String()
    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    expireIn := time.Now().AddDate(1, 0, 0) // years months days

    // GENERIC AUTHZ
    // msgtype := "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder"
    // msg := chainClient.BuildGenericAuthz(granter, grantee, msgtype, expireIn)

    // TYPED AUTHZ
    msg := chainClient.BuildExchangeAuthz(
        granter,
        grantee,
        chainclient.CreateSpotLimitOrderAuthz,
        chainClient.DefaultSubaccount(senderAddress).String(),
        []string{"0xe0dc13205fb8b23111d8555a6402681965223135d368eeeb964681f9ff12eb2a"},
        expireIn,
    )

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
granterstringYes
granteestringYes
grantGrantYes

Typed Authorization Messages

  1. CreateSpotLimitOrderAuthz

  2. CreateSpotMarketOrderAuthz

  3. BatchCreateSpotLimitOrdersAuthz

  4. CancelSpotOrderAuthz

  5. BatchCancelSpotOrdersAuthz

  6. CreateDerivativeLimitOrderAuthz

  7. CreateDerivativeMarketOrderAuthz

  8. BatchCreateDerivativeLimitOrdersAuthz

  9. CancelDerivativeOrderAuthz

  10. BatchCancelDerivativeOrdersAuthz

  11. BatchUpdateOrdersAuthz

Response Parameters

Response Example:

txhash: "ACD8E18DF357E28821B2931C4138971F805967485AE48FED2A808112F630D7E9"
raw_log: "[]"

gas wanted: 96103
gas fee: 0.0000480515 INJ
DEBU[0001] broadcastTx with nonce 3509                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214837  fn=func1 src="client/chain/chain.go:619" txHash=1F1FD519002B85C68CAE5593FDDB11FD749F918D5BBCA5F10E8AF6CFF0C5090A
DEBU[0003] nonce incremented to 3510                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  117873                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000589365 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgExec

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import Address, PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_GRANTEE_PRIVATE_KEY")
    granter_inj_address = os.getenv("INJECTIVE_GRANTER_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_for_grantee_account_using_gas_heuristics(
        network=network,
        grantee_private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    grantee = address.to_acc_bech32()

    granter_address = Address.from_acc_bech32(granter_inj_address)
    granter_subaccount_id = granter_address.get_subaccount_id(index=0)
    message = composer.msg_create_spot_limit_order(
        sender=granter_inj_address,
        market_id=market_id,
        subaccount_id=granter_subaccount_id,
        fee_recipient=grantee,
        price=Decimal("7.523"),
        quantity=Decimal("0.01"),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    sdk "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    authztypes "github.com/cosmos/cosmos-sdk/x/authz"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    granterAddress, _, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    txFactory := chainclient.NewTxFactory(clientCtx)
    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionTxFactory(&txFactory),
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    // note that we use grantee keyring to send the msg on behalf of granter here
    // sender, subaccount are from granter
    granter := granterAddress.String()
    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    defaultSubaccountID := chainClient.DefaultSubaccount(granterAddress)

    marketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"

    amount := decimal.NewFromFloat(2)
    price := decimal.NewFromFloat(22.55)
    order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY),
            Quantity:     amount,
            Price:        price,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
        },
    )

    // manually pack msg into Any type
    msg0 := exchangev2types.MsgCreateSpotLimitOrder{
        Sender: granter,
        Order:  *order,
    }
    msg0Bytes, _ := msg0.Marshal()
    msg0Any := &codectypes.Any{}
    msg0Any.TypeUrl = sdk.MsgTypeURL(&msg0)
    msg0Any.Value = msg0Bytes
    msg := authztypes.MsgExec{
        Grantee: grantee,
        Msgs:    []*codectypes.Any{msg0Any},
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
granteestringYes
msgstypes.Any arrayExecute Msg. The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg)) triple and validate it.No

Response Parameters

Response Example:

---Simulation Response---
[results: "\nB0x7bd1785363eb01c0c9e1642d71645f75d198e70419b303c9e48e39af3e428bcf"
]
---Transaction Response---
txhash: "D8F84A91C189430E2219DBA72BFA64FD567240EAEFFE4296202A1D31835E2EE1"
raw_log: "[]"

gas wanted: 107030
gas fee: 0.000053515 INJ
DEBU[0002] broadcastTx with nonce 1313                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5214956  fn=func1 src="client/chain/chain.go:619" txHash=6968428F68F3F1380D9A059C964F0C39C943EBBCCD758E8541270DC3B4037A02
DEBU[0004] nonce incremented to 1314                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  133972                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066986 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgRevoke

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")
    grantee_public_address = os.getenv("INJECTIVE_GRANTEE_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    msg = composer.msg_revoke(
        granter=address.to_acc_bech32(),
        grantee=grantee_public_address,
        msg_type="/injective.exchange.v2.MsgCreateSpotLimitOrder",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    authztypes "github.com/cosmos/cosmos-sdk/x/authz"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    msgType := "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder"

    msg := authztypes.MsgRevoke{
        Granter:    senderAddress.String(),
        Grantee:    grantee,
        MsgTypeUrl: msgType,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
granterstringYes
granteestringYes
msg_type_urlstringYes

Response Example:

txhash: "7E89656E1ED2E2A934B0A1D4DD1D4B228C15A50FDAEA0B97A67E9E27E1B22627"
raw_log: "[]"

gas wanted: 86490
gas fee: 0.000043245 INJ
DEBU[0001] broadcastTx with nonce 3511                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214972  fn=func1 src="client/chain/chain.go:619" txHash=CB15AC2B2722E5CFAA61234B3668043BA1333DAC728B875A77946EEE11FE48C2
DEBU[0003] nonce incremented to 3512                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  103153                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000515765 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

Grants

Get the details of an authorization between a granter and a grantee.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    granter = os.getenv("INJECTIVE_GRANTER_PUBLIC_ADDRESS")
    grantee = os.getenv("INJECTIVE_GRANTEE_PUBLIC_ADDRESS")

    network = Network.testnet()
    client = AsyncClient(network)
    msg_type_url = "/injective.exchange.v2.MsgCreateDerivativeLimitOrder"
    authorizations = await client.fetch_grants(granter=granter, grantee=grantee, msg_type_url=msg_type_url)
    print(json.dumps(authorizations, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    authztypes "github.com/cosmos/cosmos-sdk/x/authz"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    granter := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    msg_type_url := "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder"

    req := authztypes.QueryGrantsRequest{
        Granter:    granter,
        Grantee:    grantee,
        MsgTypeUrl: msg_type_url,
    }

    ctx := context.Background()

    res, err := chainClient.GetAuthzGrants(ctx, req)
    if err != nil {
        panic(err)
    }

    jsonResponse, err := clientCtx.Codec.MarshalJSON(res)
    if err != nil {
        panic(err)
    }

    fmt.Print(string(jsonResponse))
}
ParameterTypeDescriptionRequired
granterstringYes
granteestringYes
msg_type_urlstringOptional, msg_type_url, when set, will query only grants matching given msg type.No
paginationquery.PageRequestpagination defines an pagination for the request.No

Response Parameters

Response Example:

{
   "grants":[
      {
         "authorization":"OrderedDict("[
            "(""@type",
            "/cosmos.authz.v1beta1.GenericAuthorization"")",
            "(""msg",
            "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder"")"
         ]")",
         "expiration":"2024-12-07T02:26:01Z"
      }
   ]
}
ParameterTypeDescription
grantsGrant arrayauthorizations is a list of grants granted for grantee by granter.
paginationquery.PageResponsepagination defines an pagination for the response.


Grant

ParameterTypeDescription
authorizationtypes.Any
expirationtime.Timetime when the grant will expire and will be pruned. If null, then the grant doesn't have a time expiration (other conditions in `authorization` may apply to invalidate the grant)


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

- Bank

Bank module.

MsgSend

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    msg = composer.msg_send(
        from_address=address.to_acc_bech32(),
        to_address="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
        amount=100000000000000000,
        denom="inj",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    // prepare tx msg
    msg := banktypes.MsgSend{
        FromAddress: senderAddress.String(),
        ToAddress:   "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
        Amount: []sdktypes.Coin{{
            Denom: "inj", Amount: math.NewInt(1000000000000000000)}, // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
from_addressstringYes
to_addressstringYes
amountgithub_com_cosmos_cosmos_sdk_types.CoinsYes

Response Parameters

Response Example:

txhash: "52F3AF222FB064E7505FB14D79D703120EBDF8C945B7920F02FE2BB6666F1D50"
raw_log: "[]"

gas wanted: 97455
gas fee: 0.0000487275 INJ
DEBU[0001] broadcastTx with nonce 3490                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5212593  fn=func1 src="client/chain/chain.go:619" txHash=AD30AE73838AA342072DCC61897AA75548D613D032A3EC9BDD0A5A064C456002
DEBU[0004] nonce incremented to 3491                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  119871                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000599355 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgMultiSend

IP rate limit group: chain

Request Parameters

Request Example:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    // initialize grpc client

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    // prepare tx msg

    msg := banktypes.MsgMultiSend{
        Inputs: []banktypes.Input{
            {
                Address: senderAddress.String(),
                Coins: []sdktypes.Coin{{
                    Denom: "inj", Amount: math.NewInt(1000000000000000000)}, // 1 INJ
                },
            },
            {
                Address: senderAddress.String(),
                Coins: []sdktypes.Coin{{
                    Denom: "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5", Amount: math.NewInt(1000000)}, // 1 USDT
                },
            },
        },
        Outputs: []banktypes.Output{
            {
                Address: "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
                Coins: []sdktypes.Coin{{
                    Denom: "inj", Amount: math.NewInt(1000000000000000000)}, // 1 INJ
                },
            },
            {
                Address: "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
                Coins: []sdktypes.Coin{{
                    Denom: "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5", Amount: math.NewInt(1000000)}, // 1 USDT
                },
            },
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
inputsInput arrayInputs, despite being `repeated`, only allows one sender input. This is checked in MsgMultiSend's ValidateBasic.Yes
outputsOutput arrayYes


Input

ParameterTypeDescription
addressstring
coinsgithub_com_cosmos_cosmos_sdk_types.Coins


Output

ParameterTypeDescription
addressstring
coinsgithub_com_cosmos_cosmos_sdk_types.Coins

Response Example:


DEBU[0001] broadcastTx with nonce 30                     fn=func1 src="client/chain/chain.go:630"
DEBU[0003] msg batch committed successfully at height 1620903  fn=func1 src="client/chain/chain.go:651" txHash=643F2C0F7FC679609AFE87FC4F3B0F2E81769F75628375BD6F3D27D4C286B240
DEBU[0003] nonce incremented to 31                       fn=func1 src="client/chain/chain.go:655"
DEBU[0003] gas wanted:  152844                           fn=func1 src="client/chain/chain.go:656"
gas fee: 0.000076422 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

QueryAllBalances

Get the bank balance for all denoms.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
    all_bank_balances = await client.fetch_bank_balances(address=address)
    print(json.dumps(all_bank_balances, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    ctx := context.Background()

    res, err := chainClient.GetBankBalances(ctx, address)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address to query balances for.Yes
paginationquery.PageRequestpagination defines an optional pagination for the request.No
resolve_denomboolresolve_denom is the flag to resolve the denom into a human-readable form from the metadata. Since: cosmos-sdk 0.50Yes


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "balances":[
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom",
         "amount":"10000000000"
      },
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
         "amount":"10000000000"
      },
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
         "amount":"5000000000"
      },
      {
         "denom":"factory/inj1aetmaq5pswvfg6nhvgd4lt94qmg23ka3ljgxlm/SHURIKEN",
         "amount":"115700000"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/test",
         "amount":"1000000"
      },
      {
         "denom":"inj",
         "amount":"760662316753211286487"
      },
      {
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "amount":"9996297948"
      }
   ],
   "pagination":{
      "total":"7",
      "nextKey":""
   }
}
{
 "balances": [
  {
   "denom": "ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C",
   "amount": "829149863837"
  },
  {
   "denom": "inj",
   "amount": "51142210518226357537"
  },
  {
   "denom": "peggy0x36B3D7ACe7201E28040eFf30e815290D7b37ffaD",
   "amount": "4000000000000000000"
  },
  {
   "denom": "share26",
   "amount": "1000000000000000000"
  }
 ],
 "pagination": {
  "total": 4
 }
}
ParameterTypeDescription
balancesgithub_com_cosmos_cosmos_sdk_types.Coinsbalances is the balances of all the coins.
paginationquery.PageResponsepagination defines the pagination in the response.


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

QueryBalance

Get the bank balance for a specific denom.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
    denom = "inj"
    bank_balance = await client.fetch_bank_balance(address=address, denom=denom)
    print(json.dumps(bank_balance, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    denom := "inj"
    ctx := context.Background()

    res, err := chainClient.GetBankBalance(ctx, address, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address to query balances for.Yes
denomstringdenom is the coin denom to query balances for.Yes

Response Parameters

Response Example:

{
   "balance":{
      "denom":"inj",
      "amount":"760662316753211286487"
   }
}
{
 "balance": {
  "denom": "inj",
  "amount": "51142210518226357537"
 }
}
ParameterTypeDescription
balancetypes.Coinbalance is the balance of the coin.


Balance

ParameterTypeDescription
addressstringaddress is the address of the balance holder.
coinsgithub_com_cosmos_cosmos_sdk_types.Coinscoins defines the different coins this balance holds.

SpendableBalances

Get the bank spendable balances for a specific address.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
    spendable_balances = await client.fetch_spendable_balances(address=address)
    print(json.dumps(spendable_balances, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/cosmos/cosmos-sdk/types/query"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.GetBankSpendableBalances(ctx, address, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address to query spendable balances for.Yes
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "balances":[
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom",
         "amount":"10000000000"
      },
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
         "amount":"10000000000"
      },
      {
         "denom":"factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth",
         "amount":"5000000000"
      },
      {
         "denom":"factory/inj1aetmaq5pswvfg6nhvgd4lt94qmg23ka3ljgxlm/SHURIKEN",
         "amount":"109950000"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/AAA",
         "amount":"3000000000"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/ANK",
         "amount":"999989999000010"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/APE",
         "amount":"999999899000038"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/aaaa",
         "amount":"900000928000028"
      },
      {
         "denom":"factory/inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r/test",
         "amount":"1000000"
      },
      {
         "denom":"inj",
         "amount":"682717353413490977815"
      },
      {
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "amount":"9996297948"
      }
   ],
   "pagination":{
      "total":"11",
      "nextKey":""
   }
}
{
 "balances": [
  {
   "denom": "factory/inj17d34nrgnq5sj24qd6rk4jrnak628wfqxjx9uhz/lpinj1zd8zg8xeerlsrsfzxhpe3xgncrp0txetqye9cl",
   "amount": "2000000000000000000"
  },
  {
   "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/mitotest1",
   "amount": "249999999999999999998"
  },
  {
   "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/projx",
   "amount": "27877970000000000000"
  },
  {
   "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/stinj",
   "amount": "103927830000000000000"
  },
  {
   "denom": "factory/inj17q7ds0yh7hhtusff7gz8a5kx2uwxruttlxur96/lpinj1vd0mf8a39xwr9hav2g7e8lmur07utjrjv025kd",
   "amount": "29670048440098478542"
  },
  {
   "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/aave",
   "amount": "110000000000"
  },
  {
   "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom",
   "amount": "20672215991"
  },
  {
   "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/crv",
   "amount": "110000000000"
  },
  {
   "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/cvx",
   "amount": "110000000000"
  },
  {
   "denom": "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/shib",
   "amount": "110000000000"
  }
 ],
 "pagination": {
  "next_key": "ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdGlh"
 }
}

ParameterTypeDescription
balancesgithub_com_cosmos_cosmos_sdk_types.Coinsbalances is the spendable balances of all the coins.
paginationquery.PageResponsepagination defines the pagination in the response.


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

SpendableBalancesByDenom

Get the bank spendable balances for a specific address and denom.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
    denom = "inj"
    spendable_balances = await client.fetch_spendable_balances_by_denom(address=address, denom=denom)
    print(json.dumps(spendable_balances, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    denom := "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    ctx := context.Background()

    res, err := chainClient.GetBankSpendableBalancesByDenom(ctx, address, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address to query balances for.Yes
denomstringdenom is the coin denom to query balances for.Yes

Response Parameters

Response Example:

{
   "balance":{
      "denom":"inj",
      "amount":"682717353413490977815"
   }
}
{
 "balance": {
  "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
  "amount": "172767664766"
 }
}

ParameterTypeDescription
balancetypes.Coinbalance is the balance of the coin.


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

TotalSupply

Get the total supply for all tokens

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    total_supply = await client.fetch_total_supply(
        pagination=PaginationOption(limit=10),
    )
    print(json.dumps(total_supply, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/cosmos/cosmos-sdk/types/query"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.GetBankTotalSupply(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an optional pagination for the request. Since: cosmos-sdk 0.43No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "supply":[
      {
         "denom":"factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position",
         "amount":"64120252107"
      },
      {
         "denom":"factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position",
         "amount":"192927104"
      },
      {
         "denom":"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
         "amount":"1921200000000000000000"
      },
      {
         "denom":"factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position",
         "amount":"52973849072"
      },
      {
         "denom":"factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position",
         "amount":"777131899999"
      },
      {
         "denom":"factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position",
         "amount":"5556700000000000000"
      },
      {
         "denom":"factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position",
         "amount":"642300000000"
      },
      {
         "denom":"factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position",
         "amount":"725247250499"
      },
      {
         "denom":"factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position",
         "amount":"4067730000000000000000"
      },
      {
         "denom":"factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
         "amount":"761148481800"
      }
   ],
   "pagination":{
      "nextKey":"ZmFjdG9yeS9pbmoxMG52MjB4ZTR4MzI1c3E1NTdkZGNtc3lsYTd6YWo2cG5zc3JmdzkvcG9zaXRpb24=",
      "total":"0"
   }
}
{
 "supply": [
  {
   "denom": "factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position",
   "amount": "64120252107"
  },
  {
   "denom": "factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position",
   "amount": "192927104"
  },
  {
   "denom": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
   "amount": "1921200000000000000000"
  },
  {
   "denom": "factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position",
   "amount": "52973849072"
  },
  {
   "denom": "factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position",
   "amount": "777131899999"
  },
  {
   "denom": "factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position",
   "amount": "5556700000000000000"
  },
  {
   "denom": "factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position",
   "amount": "642300000000"
  },
  {
   "denom": "factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position",
   "amount": "725247250499"
  },
  {
   "denom": "factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position",
   "amount": "4067730000000000000000"
  },
  {
   "denom": "factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
   "amount": "761148481800"
  }
 ],
 "pagination": {
  "next_key": "ZmFjdG9yeS9pbmoxMG52MjB4ZTR4MzI1c3E1NTdkZGNtc3lsYTd6YWo2cG5zc3JmdzkvcG9zaXRpb24="
 }
}

ParameterTypeDescription
supplygithub_com_cosmos_cosmos_sdk_types.Coinssupply is the supply of the coins
paginationquery.PageResponsepagination defines the pagination in the response. Since: cosmos-sdk 0.43


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

SupplyOf

Queries the supply of a single token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    supply_of = await client.fetch_supply_of(denom="inj")
    print(json.dumps(supply_of, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denom := "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    ctx := context.Background()

    res, err := chainClient.GetBankSupplyOf(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomstringdenom is the coin denom to query balances for.Yes

Response Parameters

Response Example:

{'amount': {'denom': 'inj', 'amount': '926435158902805147647209906101604'}}
{
 "amount": {
  "denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
  "amount": "999999965050607001998"
 }
}

ParameterTypeDescription
amounttypes.Coinamount is the supply of the coin.


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

DenomMetadata

Queries the metadata of a single token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    denom = "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
    metadata = await client.fetch_denom_metadata(denom=denom)
    print(json.dumps(metadata, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denom := "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
    ctx := context.Background()

    res, err := chainClient.GetDenomMetadata(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomstringdenom is the coin denom to query the metadata for.Yes

Response Parameters

Response Example:

{
   "metadata":{
      "denomUnits":[
         {
            "denom":"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
            "exponent":0,
            "aliases":[

            ]
         }
      ],
      "base":"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
      "description":"",
      "display":"",
      "name":"",
      "symbol":"",
      "uri":"",
      "uriHash":""
   }
}
{
 "metadata": {
  "denom_units": [
   {
    "denom": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
   }
  ],
  "base": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
 }
}

ParameterTypeDescription
metadataMetadatametadata describes and provides all the client information for the requested token.


Metadata

ParameterTypeDescription
descriptionstring
denom_unitsDenomUnit arraydenom_units represents the list of DenomUnit's for a given coin
basestringbase represents the base denom (should be the DenomUnit with exponent = 0).
displaystringdisplay indicates the suggested denom that should be displayed in clients.
namestringname defines the name of the token (eg: Cosmos Atom) Since: cosmos-sdk 0.43
symbolstringsymbol is the token symbol usually shown on exchanges (eg: ATOM). This can be the same as the display. Since: cosmos-sdk 0.43
uristringURI to a document (on or off-chain) that contains additional information. Optional. Since: cosmos-sdk 0.46
uri_hashstringURIHash is a sha256 hash of a document pointed by URI. It's used to verify that the document didn't change. Optional. Since: cosmos-sdk 0.46
decimalsuint32Decimals represent the number of decimals use to represent token amount on chain Since: cosmos-sdk 0.50


DenomUnit

ParameterTypeDescription
denomstringdenom represents the string name of the given denom unit (e.g uatom).
exponentuint32exponent represents power of 10 exponent that one must raise the base_denom to in order to equal the given DenomUnit's denom 1 denom = 10^exponent base_denom (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with exponent = 6, thus: 1 atom = 10^6 uatom).
aliasesstring arrayaliases is a list of string aliases for the given denom

DenomsMetadata

Queries the metadata of all tokens

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    denoms = await client.fetch_denoms_metadata(
        pagination=PaginationOption(limit=10),
    )
    print(json.dumps(denoms, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/cosmos/cosmos-sdk/types/query"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.GetDenomsMetadata(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "metadatas":[
      {
         "denomUnits":[
            {
               "denom":"factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      },
      {
         "denomUnits":[
            {
               "denom":"factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
               "exponent":0,
               "aliases":[

               ]
            }
         ],
         "base":"factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
         "description":"",
         "display":"",
         "name":"",
         "symbol":"",
         "uri":"",
         "uriHash":""
      }
   ],
   "pagination":{
      "nextKey":"ZmFjdG9yeS9pbmoxMGptcDZzZ2g0Y2M2enQzZThndzA1d2F2dmVqZ3I1cHc2bThqNzUvYWs=",
      "total":"0"
   }
}
{
 "metadatas": [
  {
   "denom_units": [
    {
     "denom": "factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position"
    }
   ],
   "base": "factory/inj104y00apw6uu26gthl7cafztdy67hhmwksekdem/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position"
    }
   ],
   "base": "factory/inj106rseec0xmv5k06aaf8jsnr57ajw76rxa3gpwm/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
    }
   ],
   "base": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position"
    }
   ],
   "base": "factory/inj107skcseta3egagj822d3qdgusx7a7ua7sepmcf/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position"
    }
   ],
   "base": "factory/inj107srzqksjtdevlpw888vuyrnqmlpjuv64ytm85/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position"
    }
   ],
   "base": "factory/inj108t3mlej0dph8er6ca2lq5cs9pdgzva5mqsn5p/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position"
    }
   ],
   "base": "factory/inj109rcepnmg7ewjcc4my3448jm3h0yjdwcl6kmnl/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position"
    }
   ],
   "base": "factory/inj10ajd3f46mp755wmhgke8w4vcegfjndwfzymf82/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position"
    }
   ],
   "base": "factory/inj10fz2cj00ee80y76pdzg06dxfamat8nfpr9vl5s/position"
  },
  {
   "denom_units": [
    {
     "denom": "factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position"
    }
   ],
   "base": "factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position"
  }
 ],
 "pagination": {
  "next_key": "ZmFjdG9yeS9pbmoxMGptcDZzZ2g0Y2M2enQzZThndzA1d2F2dmVqZ3I1cHc2bThqNzUvYWs="
 }
}
ParameterTypeDescription
metadatasMetadata arraymetadata provides the client information for all the registered tokens.
paginationquery.PageResponsepagination defines the pagination in the response.


Metadata

ParameterTypeDescription
descriptionstring
denom_unitsDenomUnit arraydenom_units represents the list of DenomUnit's for a given coin
basestringbase represents the base denom (should be the DenomUnit with exponent = 0).
displaystringdisplay indicates the suggested denom that should be displayed in clients.
namestringname defines the name of the token (eg: Cosmos Atom) Since: cosmos-sdk 0.43
symbolstringsymbol is the token symbol usually shown on exchanges (eg: ATOM). This can be the same as the display. Since: cosmos-sdk 0.43
uristringURI to a document (on or off-chain) that contains additional information. Optional. Since: cosmos-sdk 0.46
uri_hashstringURIHash is a sha256 hash of a document pointed by URI. It's used to verify that the document didn't change. Optional. Since: cosmos-sdk 0.46
decimalsuint32Decimals represent the number of decimals use to represent token amount on chain Since: cosmos-sdk 0.50


DenomUnit

ParameterTypeDescription
denomstringdenom represents the string name of the given denom unit (e.g uatom).
exponentuint32exponent represents power of 10 exponent that one must raise the base_denom to in order to equal the given DenomUnit's denom 1 denom = 10^exponent base_denom (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with exponent = 6, thus: 1 atom = 10^6 uatom).
aliasesstring arrayaliases is a list of string aliases for the given denom


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

DenomsOwners

Queries for all account addresses that own a particular token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    denom = "inj"
    owners = await client.fetch_denom_owners(
        denom=denom,
        pagination=PaginationOption(limit=10),
    )
    print(json.dumps(owners, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/types/query"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denom := "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.GetDenomOwners(ctx, denom, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomstringdenom defines the coin denomination to query all account holders for.Yes
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "denomOwners":[
      {
         "address":"inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49",
         "balance":{
            "denom":"inj",
            "amount":"420000000000000010003"
         }
      },
      {
         "address":"inj1qqqqqqqpa95pcsnxa3927hlym6t8quhwlgkmqt",
         "balance":{
            "denom":"inj",
            "amount":"10000000000000000"
         }
      },
      {
         "address":"inj1qqqqqqzw4rg692t320252whr7gjp4k86lun8hp",
         "balance":{
            "denom":"inj",
            "amount":"143805431033925108"
         }
      },
      {
         "address":"inj1qqqqqqr0g47qlr6kqveans58w2raj25j095pad",
         "balance":{
            "denom":"inj",
            "amount":"199999568185205399700"
         }
      },
      {
         "address":"inj1qqqqqq4ze7h25mf9w8h8h02h807yj2fxzl27m8",
         "balance":{
            "denom":"inj",
            "amount":"10000"
         }
      },
      {
         "address":"inj1qqqqqqhn9sygdmn966q9n77mwmhk56vkkae2d3",
         "balance":{
            "denom":"inj",
            "amount":"260838118080821668174"
         }
      },
      {
         "address":"inj1qqqqqr5pwtzk2n8tswusllscjagw3w9k3dyceg",
         "balance":{
            "denom":"inj",
            "amount":"826945326095056784"
         }
      },
      {
         "address":"inj1qqqqqrk35e4y5r3aklpeelkkr9hkxq4k4y55c9",
         "balance":{
            "denom":"inj",
            "amount":"49800000000000000"
         }
      },
      {
         "address":"inj1qqqqqyyfzemqpsjjtrdzn5hzept7c95f8zyhmn",
         "balance":{
            "denom":"inj",
            "amount":"599500010155805818137328"
         }
      },
      {
         "address":"inj1qqqqqy2thegwe8473jk5u6th93uc488n4ltucm",
         "balance":{
            "denom":"inj",
            "amount":"40027858757349727870"
         }
      }
   ],
   "pagination":{
      "nextKey":"FAAAADLLRNDsOnihjI3alQcdNB0a",
      "total":"0"
   }
}
{
 "denom_owners": [
  {
   "address": "inj15e2qkdv5kf0w79f34t0c0w3j7arhxe4gy6juwf",
   "balance": {
    "denom": "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position",
    "amount": "1921200000000000000000"
   }
  }
 ],
 "pagination": {}
}
ParameterTypeDescription
denom_ownersDenomOwner array
paginationquery.PageResponsepagination defines the pagination in the response.


DenomOwner

ParameterTypeDescription
addressstringaddress defines the address that owns a particular denomination.
balancetypes.Coinbalance is the balance of the denominated coin for an account.


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

SendEnabled

This query only returns denominations that have specific SendEnabled settings. Any denomination that does not have a specific setting will use the default params.default_send_enabled, and will not be returned by this query.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    denom = "inj"
    enabled = await client.fetch_send_enabled(
        denoms=[denom],
        pagination=PaginationOption(limit=10),
    )
    print(json.dumps(enabled, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denoms := []string{"factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"}
    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.GetBankSendEnabled(ctx, denoms, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomsstring arraydenoms is the specific denoms you want look up. Leave empty to get all entries.Yes
paginationquery.PageRequestpagination defines an optional pagination for the request. This field is only read if the denoms field is empty.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

ParameterTypeDescription
send_enabledSendEnabled array
paginationquery.PageResponsepagination defines the pagination in the response. This field is only populated if the denoms field in the request is empty.


SendEnabled

ParameterTypeDescription
denomstring
enabledbool


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

- Chain Stream

Chain Stream is a gRPC service that allows clients to receive low-latency updates from the Injective Chain. This API is exposed directly from a dedicated server running on a chain node and provides the fastest way to receive events data (like trades, orders, balances, etc.). Under the hood, a stream message is computed by the chain node immediately after the event is emitted and is sent to the client via a gRPC stream once the block is committed.

Stream Request

Its possible to specify multiple filters to customize the stream. A filter can be specified with a list of values, generally MarketIds, SubaccountIds and Accounts address. A filter can also be omitted, in this case the stream will return all the events for the specified type. In addition each filter supports a * wildcard to match all possible values.

import asyncio
from typing import Any, Dict

from grpc import RpcError

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def chain_stream_event_processor(event: Dict[str, Any]):
    print(event)


def stream_error_processor(exception: RpcError):
    print(f"There was an error listening to chain stream updates ({exception})")


def stream_closed_processor():
    print("The chain stream updates stream has been closed")


async def main() -> None:
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    subaccount_id = "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000"

    inj_usdt_market = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    inj_usdt_perp_market = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    bank_balances_filter = composer.chain_stream_bank_balances_filter(
        accounts=["inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"]
    )
    subaccount_deposits_filter = composer.chain_stream_subaccount_deposits_filter(subaccount_ids=[subaccount_id])
    spot_trades_filter = composer.chain_stream_trades_filter(subaccount_ids=["*"], market_ids=[inj_usdt_market])
    derivative_trades_filter = composer.chain_stream_trades_filter(
        subaccount_ids=["*"], market_ids=[inj_usdt_perp_market]
    )
    spot_orders_filter = composer.chain_stream_orders_filter(
        subaccount_ids=[subaccount_id], market_ids=[inj_usdt_market]
    )
    derivative_orders_filter = composer.chain_stream_orders_filter(
        subaccount_ids=[subaccount_id], market_ids=[inj_usdt_perp_market]
    )
    spot_orderbooks_filter = composer.chain_stream_orderbooks_filter(market_ids=[inj_usdt_market])
    derivative_orderbooks_filter = composer.chain_stream_orderbooks_filter(market_ids=[inj_usdt_perp_market])
    positions_filter = composer.chain_stream_positions_filter(
        subaccount_ids=[subaccount_id], market_ids=[inj_usdt_perp_market]
    )
    oracle_price_filter = composer.chain_stream_oracle_price_filter(symbols=["INJ", "USDT"])
    order_failures_filter = composer.chain_stream_order_failures_filter(
        accounts=["inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"]
    )
    conditional_order_trigger_failures_filter = composer.chain_stream_conditional_order_trigger_failures_filter(
        subaccount_ids=[subaccount_id], market_ids=[inj_usdt_perp_market]
    )

    task = asyncio.get_event_loop().create_task(
        client.listen_chain_stream_updates(
            callback=chain_stream_event_processor,
            on_end_callback=stream_closed_processor,
            on_status_callback=stream_error_processor,
            bank_balances_filter=bank_balances_filter,
            subaccount_deposits_filter=subaccount_deposits_filter,
            spot_trades_filter=spot_trades_filter,
            derivative_trades_filter=derivative_trades_filter,
            spot_orders_filter=spot_orders_filter,
            derivative_orders_filter=derivative_orders_filter,
            spot_orderbooks_filter=spot_orderbooks_filter,
            derivative_orderbooks_filter=derivative_orderbooks_filter,
            positions_filter=positions_filter,
            oracle_price_filter=oracle_price_filter,
            order_failures_filter=order_failures_filter,
            conditional_order_trigger_failures_filter=conditional_order_trigger_failures_filter,
        )
    )

    await asyncio.sleep(delay=60)
    task.cancel()


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    chainstreamv2 "github.com/InjectiveLabs/sdk-go/chain/stream/types/v2"
    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        "",
        nil,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    subaccountId := "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000"

    injUsdtMarket := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    injUsdtPerpMarket := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    req := chainstreamv2.StreamRequest{
        BankBalancesFilter: &chainstreamv2.BankBalancesFilter{
            Accounts: []string{"*"},
        },
        SpotOrdersFilter: &chainstreamv2.OrdersFilter{
            MarketIds:     []string{injUsdtMarket},
            SubaccountIds: []string{subaccountId},
        },
        DerivativeOrdersFilter: &chainstreamv2.OrdersFilter{
            MarketIds:     []string{injUsdtPerpMarket},
            SubaccountIds: []string{subaccountId},
        },
        SpotTradesFilter: &chainstreamv2.TradesFilter{
            MarketIds:     []string{injUsdtMarket},
            SubaccountIds: []string{"*"},
        },
        SubaccountDepositsFilter: &chainstreamv2.SubaccountDepositsFilter{
            SubaccountIds: []string{subaccountId},
        },
        DerivativeOrderbooksFilter: &chainstreamv2.OrderbookFilter{
            MarketIds: []string{injUsdtPerpMarket},
        },
        SpotOrderbooksFilter: &chainstreamv2.OrderbookFilter{
            MarketIds: []string{injUsdtMarket},
        },
        PositionsFilter: &chainstreamv2.PositionsFilter{
            SubaccountIds: []string{subaccountId},
            MarketIds:     []string{injUsdtPerpMarket},
        },
        DerivativeTradesFilter: &chainstreamv2.TradesFilter{
            SubaccountIds: []string{"*"},
            MarketIds:     []string{injUsdtPerpMarket},
        },
        OraclePriceFilter: &chainstreamv2.OraclePriceFilter{
            Symbol: []string{"INJ", "USDT"},
        },
        OrderFailuresFilter: &chainstreamv2.OrderFailuresFilter{
            Accounts: []string{"*"},
        },
        ConditionalOrderTriggerFailuresFilter: &chainstreamv2.ConditionalOrderTriggerFailuresFilter{
            SubaccountIds: []string{subaccountId},
            MarketIds:     []string{injUsdtPerpMarket},
        },
    }

    ctx := context.Background()

    stream, err := chainClient.ChainStreamV2(ctx, req)
    if err != nil {
        panic(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                panic(err)
            }
            str, _ := json.MarshalIndent(res, "", "\t")
            fmt.Print(string(str))
        }
    }
}
ParameterTypeDescriptionRequired
bank_balances_filterBankBalancesFilterfilter for bank balances eventsNo
subaccount_deposits_filterSubaccountDepositsFilterfilter for subaccount deposits eventsNo
spot_trades_filterTradesFilterfilter for spot trades eventsNo
derivative_trades_filterTradesFilterfilter for derivative trades eventsNo
spot_orders_filterOrdersFilterfilter for spot orders eventsNo
derivative_orders_filterOrdersFilterfilter for derivative orders eventsNo
spot_orderbooks_filterOrderbookFilterfilter for spot orderbooks eventsNo
derivative_orderbooks_filterOrderbookFilterfilter for derivative orderbooks eventsNo
positions_filterPositionsFilterfilter for positions eventsNo
oracle_price_filterOraclePriceFilterfilter for oracle prices eventsNo
order_failures_filterOrderFailuresFilterfilter for order failures eventsNo
conditional_order_trigger_failures_filterConditionalOrderTriggerFailuresFilterfilter for conditional order trigger failures eventsNo


BankBalancesFilter

ParameterTypeDescription
accountsstring arraylist of account addresses to filter by


SubaccountDepositsFilter

ParameterTypeDescription
subaccount_idsstring arraylist of subaccount IDs to filter by


TradesFilter

ParameterTypeDescription
subaccount_idsstring arraylist of subaccount IDs to filter by
market_idsstring arraylist of market IDs to filter by


OrdersFilter

ParameterTypeDescription
subaccount_idsstring arraylist of subaccount IDs to filter by
market_idsstring arraylist of market IDs to filter by


OrderbookFilter

ParameterTypeDescription
market_idsstring arraylist of market IDs to filter by


PositionsFilter

ParameterTypeDescription
subaccount_idsstring arraylist of subaccount IDs to filter by
market_idsstring arraylist of market IDs to filter by


OraclePriceFilter

ParameterTypeDescription
symbolstring arraylist of symbols to filter by


OrderFailuresFilter

ParameterTypeDescription
accountsstring arraylist of account addresses to filter by


ConditionalOrderTriggerFailuresFilter

ParameterTypeDescription
subaccount_idsstring arraylist of subaccount IDs to filter by
market_idsstring arraylist of market IDs to filter by

StreamResponse

The stream response is a stream of events that are sent to the client. Each message contains a list of events that are filtered by the request parameters and it's identified by the block height.

ParameterTypeDescription
block_heightuint64the block height
block_timeint64the block time
bank_balancesBankBalance arraylist of bank balances updates
subaccount_depositsSubaccountDeposits arraylist of subaccount deposits updates
spot_tradesSpotTrade arraylist of spot trades updates
derivative_tradesDerivativeTrade arraylist of derivative trades updates
spot_ordersSpotOrderUpdate arraylist of spot orders updates
derivative_ordersDerivativeOrderUpdate arraylist of derivative orders updates
spot_orderbook_updatesOrderbookUpdate arraylist of spot orderbook updates
derivative_orderbook_updatesOrderbookUpdate arraylist of derivative orderbook updates
positionsPosition arraylist of positions updates
oracle_pricesOraclePrice arraylist of oracle prices updates
gas_pricestringthe current gas price when the block was processed (in chain format)
order_failuresOrderFailureUpdate arraylist of order failures updates
conditional_order_trigger_failuresConditionalOrderTriggerFailureUpdate arraylist of conditional order trigger failures updates


BankBalance

ParameterTypeDescription
accountstringthe account address
balancesgithub_com_cosmos_cosmos_sdk_types.Coinslist of account balances


SubaccountDeposits

ParameterTypeDescription
denomstring
depositv2.Deposit


SpotTrade

ParameterTypeDescription
market_idstringthe market ID
is_buyboolwhether the trade is a buy or sell
executionTypestringthe execution type
quantitycosmossdk_io_math.LegacyDecthe quantity of the trade (in human readable format)
pricecosmossdk_io_math.LegacyDecthe price of the trade (in human readable format)
subaccount_idstringthe subaccount ID that executed the trade
feecosmossdk_io_math.LegacyDecthe fee of the trade (in human readable format)
order_hashstringthe order hash
fee_recipient_addressstringthe fee recipient address
cidstringthe client order ID
trade_idstringthe trade ID


DerivativeTrade

ParameterTypeDescription
market_idstringthe market ID
is_buyboolwhether the trade is a buy or sell
executionTypestringthe execution type
subaccount_idstringthe subaccount ID
position_deltav2.PositionDeltathe position delta of the trade (in human readable format)
payoutcosmossdk_io_math.LegacyDecthe payout of the trade (in human readable format)
feecosmossdk_io_math.LegacyDecthe fee of the trade (in human readable format)
order_hashstringthe order hash
fee_recipient_addressstringthe fee recipient address
cidstringthe client order ID
trade_idstringthe trade ID


SpotOrderUpdate

ParameterTypeDescription
statusOrderUpdateStatusthe status of the order
order_hashstringthe order hash
cidstringthe client order ID
orderSpotOrderthe order details


DerivativeOrderUpdate

ParameterTypeDescription
statusOrderUpdateStatusthe status of the order
order_hashstringthe order hash
cidstringthe client order ID
orderDerivativeOrderthe order details


OrderbookUpdate

ParameterTypeDescription
sequint64the sequence number of the orderbook update
orderbookOrderbookthe orderbook details


Position

ParameterTypeDescription
market_idstringthe market ID
subaccount_idstringthe subaccount ID
isLongboolwhether the position is long or short
quantitycosmossdk_io_math.LegacyDecthe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecthe entry price of the position (in human readable format)
margincosmossdk_io_math.LegacyDecthe margin of the position (in human readable format)
cumulative_funding_entrycosmossdk_io_math.LegacyDecthe cumulative funding entry of the position (in human readable format)


OraclePrice

ParameterTypeDescription
symbolstringthe symbol of the oracle price
pricecosmossdk_io_math.LegacyDecthe updated price
typestringthe oracle type


OrderFailureUpdate

ParameterTypeDescription
accountstringthe account address
order_hashstringthe order hash
cidstringthe client order ID
error_codeuint32the error code


ConditionalOrderTriggerFailureUpdate

ParameterTypeDescription
market_idstringthe market ID
subaccount_idstringthe subaccount ID
mark_pricecosmossdk_io_math.LegacyDecthe mark price
order_hashstringthe order hash
cidstringthe client order ID
error_descriptionstringthe error code


OrderUpdateStatus

CodeName
0Unspecified
1Booked
2Matched
3Cancelled


SpotOrder

ParameterTypeDescription
market_idstringthe market ID
orderv2.SpotLimitOrderthe order details


DerivativeOrder

ParameterTypeDescription
market_idstringthe market ID
orderv2.DerivativeLimitOrderthe order details
is_marketboolwhether the order is a market order


SpotLimitOrder

ParameterTypeDescription
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders
order_hashbyte arrayorder hash
expiration_blockint64expiration block is the block number at which the order will expire


DerivativeLimitOrder

ParameterTypeDescription
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders
order_hashbyte array
expiration_blockint64expiration block is the block number at which the order will expire


Orderbook

ParameterTypeDescription
market_idstringthe market ID
buy_levelsv2.Level arraylist of buy levels
sell_levelsv2.Level arraylist of sell levels


Level

ParameterTypeDescription
pcosmossdk_io_math.LegacyDecprice (in human readable format)
qcosmossdk_io_math.LegacyDecquantity (in human readable format)

- Chain Exchange

Includes all the messages and queries related to exchange accounts, orders and trades

SubaccountDeposits

Retrieves a subaccount's deposits

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    deposits = await client.fetch_subaccount_deposits(subaccount_id=subaccount_id)
    print(json.dumps(deposits, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    subaccountId := chainClient.Subaccount(senderAddress, 0)
    ctx := context.Background()

    res, err := chainClient.FetchSubaccountDeposits(ctx, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
subaccountSubaccountthe subaccount detailsNo


Subaccount

ParameterTypeDescription
traderstringthe subaccount's trader address
subaccount_nonceuint32the subaccount's nonce number

Response Parameters

Response Example:

{
   "deposits":{
      "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/demo":{
         "availableBalance":"0",
         "totalBalance":"0"
      },
      "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/stinj":{
         "availableBalance":"0",
         "totalBalance":"0"
      },
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-3":{
         "availableBalance":"0",
         "totalBalance":"0"
      },
      "inj":{
         "availableBalance":"0",
         "totalBalance":"22458000000000000000000000000000000000"
      },
      "peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7":{
         "availableBalance":"0",
         "totalBalance":"0"
      },
      "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5":{
         "availableBalance":"342932031115126491",
         "totalBalance":"324904824830342932031115126449"
      },
      "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom":{
         "availableBalance":"0",
         "totalBalance":"0"
      }
   }
}
ParameterTypeDescription
depositsmap[string]Deposit


Deposit

ParameterTypeDescription
available_balancecosmossdk_io_math.LegacyDecthe available balance (in chain format)
total_balancecosmossdk_io_math.LegacyDecthe total balance (in chain format)

SubaccountDeposit

Retrieves a subaccount's deposit

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    deposit = await client.fetch_subaccount_deposit(subaccount_id=subaccount_id, denom="inj")
    print(json.dumps(deposit, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    subaccountId := chainClient.Subaccount(senderAddress, 0)
    denom := "inj"
    ctx := context.Background()

    res, err := chainClient.FetchSubaccountDeposit(ctx, subaccountId.Hex(), denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
denomstringthe token denomYes

Response Parameters

Response Example:

{
   "deposits":{
      "availableBalance":"0",
      "totalBalance":"22458000000000000000000000000000000000"
   }
}
ParameterTypeDescription
depositsDeposit


Deposit

ParameterTypeDescription
available_balancecosmossdk_io_math.LegacyDecthe available balance (in chain format)
total_balancecosmossdk_io_math.LegacyDecthe total balance (in chain format)

ExchangeBalances

Retrieves the balances for all accounts registered in the exchange module

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    # initialize grpc client
    client = AsyncClient(network)

    balances = await client.fetch_exchange_balances()
    print(json.dumps(balances, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchExchangeBalances(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "balances":{
      "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
      "deposits":{
         "availableBalance":"0",
         "totalBalance":"0"
      },
      "subaccountId":"0x0000000001e9681c4266ec4aaf5fe4de967072ee000000000000000000000000"
   }
}
ParameterTypeDescription
balancesBalance array


Balance

ParameterTypeDescription
subaccount_idstringthe subaccount ID
denomstringthe denom of the balance
depositsDepositthe token deposits details


Deposit

ParameterTypeDescription
available_balancecosmossdk_io_math.LegacyDecthe available balance (in chain format)
total_balancecosmossdk_io_math.LegacyDecthe total balance (in chain format)

AggregateVolume

Retrieves the aggregate volumes for the specified account or subaccount

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    subaccount_id = address.get_subaccount_id(index=0)

    volume = await client.fetch_aggregate_volume(account=address.to_acc_bech32())
    print(json.dumps(volume, indent=2))

    volume = await client.fetch_aggregate_volume(account=subaccount_id)
    print(json.dumps(volume, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchAggregateVolume(ctx, senderAddress.String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

    res, err = chainClient.FetchAggregateVolume(ctx, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ = json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountstringcan either be an address or a subaccountYes

Response Parameters

Response Example:

{
    "aggregate_volumes": [
        {
            "market_id": "0x0033118e7cf665369d4208ea03c88549f151c1303f43442413679c8c407cc0d3",
            "volume": {
                "maker_volume": "0.000000000000000000",
                "taker_volume": "517.964166944195530000"
            }
        },
        {
            "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            "volume": {
                "maker_volume": "6920720.332267000000000000",
                "taker_volume": "8251230.030349665999999981"
            }
        },
        {
            "market_id": "0x0f03542809143c7e5d3c22f56bc6e51eb2c8bab5009161b58f6f468432dfa196",
            "volume": {
                "maker_volume": "19883.294699000000000000",
                "taker_volume": "27665.175938000000000000"
            }
        }
    ]
}
ParameterTypeDescription
aggregate_volumesMarketVolume arrayif an address is specified, then the aggregate_volumes will aggregate the volumes across all subaccounts for the address


MarketVolume

ParameterTypeDescription
market_idstringthe market ID
volumeVolumeRecordthe market volume


VolumeRecord

ParameterTypeDescription
maker_volumecosmossdk_io_math.LegacyDecthe market's maker volume (in human readable format)
taker_volumecosmossdk_io_math.LegacyDecthe market's taker volume (in human readable format)

AggregateVolumes

Retrieves the aggregate volumes for specified accounts

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    volume = await client.fetch_aggregate_volumes(
        accounts=[address.to_acc_bech32()],
        market_ids=["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"],
    )
    print(json.dumps(volume, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    accounts := []string{senderAddress.String()}
    marketIds := []string{"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"}

    res, err := chainClient.FetchAggregateVolumes(ctx, accounts, marketIds)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountsstring arrayYes
market_idsstring arrayYes

Response Parameters

Response Example:

{
    "aggregate_account_volumes": [
        {
            "account": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
            "market_volumes": [
                {
                    "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
                    "volume": {
                        "maker_volume": "6920720.332267000000000000",
                        "taker_volume": "8251230.030349665999999981"
                    }
                }
            ]
        }
    ],
    "aggregate_market_volumes": [
        {
            "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            "volume": {
                "maker_volume": "5265332551.630613000000000000",
                "taker_volume": "5268011997.041324344999998038"
            }
        }
    ]
}
ParameterTypeDescription
aggregate_account_volumesAggregateAccountVolumeRecord arraythe aggregate volume records for the accounts specified
aggregate_market_volumesMarketVolume arraythe aggregate volumes for the markets specified


AggregateAccountVolumeRecord

ParameterTypeDescription
accountstringaccount the volume belongs to
market_volumesMarketVolume arraythe aggregate volumes for each market


MarketVolume

ParameterTypeDescription
market_idstringthe market ID
volumeVolumeRecordthe market volume


VolumeRecord

ParameterTypeDescription
maker_volumecosmossdk_io_math.LegacyDecthe market's maker volume (in human readable format)
taker_volumecosmossdk_io_math.LegacyDecthe market's taker volume (in human readable format)

AggregateMarketVolume

Retrieves the aggregate volume for the specified market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    volume = await client.fetch_aggregate_market_volume(market_id=market_id)
    print(json.dumps(volume, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchAggregateMarketVolume(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:

{
    "volume": {
        "maker_volume": "5265332551.630613000000000000",
        "taker_volume": "5268011997.041324344999998038"
    }
}
ParameterTypeDescription
volumeVolumeRecord


VolumeRecord

ParameterTypeDescription
maker_volumecosmossdk_io_math.LegacyDecthe market's maker volume (in human readable format)
taker_volumecosmossdk_io_math.LegacyDecthe market's taker volume (in human readable format)

AggregateMarketVolumes

Retrieves the aggregate market volumes for specified markets

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    volume = await client.fetch_aggregate_market_volumes(
        market_ids=["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"],
    )
    print(volume)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketIds := []string{"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"}

    res, err := chainClient.FetchAggregateMarketVolumes(ctx, marketIds)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idsstring arrayYes

Response Parameters

Response Example:

{
    "volumes": [
        {
            "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            "volume": {
                "maker_volume": "5265332551.630613000000000000",
                "taker_volume": "5268011997.041324344999998038"
            }
        }
    ]
}
ParameterTypeDescription
volumesMarketVolume arraythe aggregate volumes for the entire market


MarketVolume

ParameterTypeDescription
market_idstringthe market ID
volumeVolumeRecordthe market volume


VolumeRecord

ParameterTypeDescription
maker_volumecosmossdk_io_math.LegacyDecthe market's maker volume (in human readable format)
taker_volumecosmossdk_io_math.LegacyDecthe market's taker volume (in human readable format)

AuctionExchangeTransferDenomDecimal

Retrieves the number of decimals used for a denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    deposits = await client.fetch_auction_exchange_transfer_denom_decimal(
        denom="peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    )
    print(deposits)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"

    res, err := chainClient.FetchAuctionExchangeTransferDenomDecimal(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomstringYes

Response Parameters

Response Example:

{
   "decimal":"6"
}
ParameterTypeDescription
decimaluint64

AuctionExchangeTransferDenomDecimals

Retrieves the denom decimals for multiple denoms

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    deposits = await client.fetch_auction_exchange_transfer_denom_decimals(
        denoms=["inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"]
    )
    print(deposits)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denoms := []string{"inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"}

    res, err := chainClient.FetchAuctionExchangeTransferDenomDecimals(ctx, denoms)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomsstring arraydenoms can be empty to query all denom decimalsYes

Response Parameters

Response Example:

{
   "denomDecimals":[
      {
         "denom":"inj",
         "decimals":"0"
      },
      {
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "decimals":"6"
      }
   ]
}
ParameterTypeDescription
denom_decimalsDenomDecimals array


DenomDecimals

ParameterTypeDescription
denomstringthe denom of the token
decimalsuint64the decimals of the token

SubaccountOrders

Retrieves subaccount's orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_subaccount_orders(
        subaccount_id=subaccount_id,
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainSubaccountOrders(ctx, subaccountId.Hex(), marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
market_idstringthe market IDYes

Response Parameters

Response Example:

{
   "buyOrders":[

   ],
   "sellOrders":[

   ]
}
ParameterTypeDescription
buy_ordersSubaccountOrderData array
sell_ordersSubaccountOrderData array


SubaccountOrderData

ParameterTypeDescription
orderSubaccountOrder
order_hashbyte array


SubaccountOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order
quantitycosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable
isReduceOnlybool
cidstring

SubaccountTradeNonce

Retrieves a subaccount's trade nonce

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    nonce = await client.fetch_subaccount_trade_nonce(
        subaccount_id=subaccount_id,
    )
    print(nonce)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchSubaccountTradeNonce(ctx, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes

Response Parameters

Response Example:

{
   "nonce":30226
}
ParameterTypeDescription
nonceuint32

SubaccountOrderMetadata

Retrieves subaccount's order metadata

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    metadata = await client.fetch_subaccount_order_metadata(
        subaccount_id=subaccount_id,
    )
    print(metadata)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchSubaccountOrderMetadata(ctx, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes

Response Parameters

Response Example:

{
   "metadata":[
      {
         "metadata":{
            "aggregateReduceOnlyQuantity":"0",
            "aggregateVanillaQuantity":"0",
            "vanillaLimitOrderCount":0,
            "reduceOnlyLimitOrderCount":0,
            "vanillaConditionalOrderCount":0,
            "reduceOnlyConditionalOrderCount":0
         },
         "marketId":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
         "isBuy":true
      },
      {
         "metadata":{
            "aggregateReduceOnlyQuantity":"0",
            "aggregateVanillaQuantity":"0",
            "vanillaLimitOrderCount":0,
            "reduceOnlyLimitOrderCount":0,
            "vanillaConditionalOrderCount":0,
            "reduceOnlyConditionalOrderCount":0
         },
         "marketId":"0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
         "isBuy":false
      }
   ]
}
ParameterTypeDescription
metadataSubaccountOrderbookMetadataWithMarket array


SubaccountOrderbookMetadataWithMarket

ParameterTypeDescription
metadataSubaccountOrderbookMetadatathe subaccount orderbook details
market_idstringthe market ID
isBuybooltrue if the orderbook is for a buy orders


SubaccountOrderbookMetadata

ParameterTypeDescription
vanilla_limit_order_countuint32The number of vanilla limit orders
reduce_only_limit_order_countuint32The number of reduce-only limit orders
aggregate_reduce_only_quantitycosmossdk_io_math.LegacyDecThe aggregate quantity of the subaccount's reduce-only limit orders (in human readable format)
aggregate_vanilla_quantitycosmossdk_io_math.LegacyDecThe aggregate quantity of the subaccount's vanilla limit orders (in human readable format)
vanilla_conditional_order_countuint32The number of vanilla conditional orders
reduce_only_conditional_order_countuint32The number of reduce-only conditional orders

TradeRewardPoints

Retrieves the account and total trade rewards points

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    points = await client.fetch_trade_reward_points(
        accounts=[address.to_acc_bech32()],
    )
    print(points)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    accounts := []string{senderAddress.String()}

    res, err := chainClient.FetchTradeRewardPoints(ctx, accounts)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountsstring arrayYes
pending_pool_timestampint64Yes

Response Parameters

Response Example:

{
   "accountTradeRewardPoints":[
      "0"
   ]
}
ParameterTypeDescription
account_trade_reward_pointscosmossdk_io_math.LegacyDec array

PendingTradeRewardPoints

Retrieves the pending account and total trade rewards points

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    points = await client.fetch_pending_trade_reward_points(
        accounts=[address.to_acc_bech32()],
    )
    print(points)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    accounts := []string{senderAddress.String()}

    res, err := chainClient.FetchPendingTradeRewardPoints(ctx, accounts)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountsstring arrayYes
pending_pool_timestampint64Yes

Response Parameters

Response Example:

{
   "accountTradeRewardPoints":[
      "0"
   ]
}
ParameterTypeDescription
account_trade_reward_pointscosmossdk_io_math.LegacyDec array

TradeRewardCampaign

Retrieves the trade reward campaign

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    campaign = await client.fetch_trade_reward_campaign()
    print(campaign)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchTradeRewardCampaign(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "totalTradeRewardPoints":"22845565536709999999999999999855",
   "tradingRewardPoolCampaignSchedule":[

   ],
   "pendingTradingRewardPoolCampaignSchedule":[

   ],
   "pendingTotalTradeRewardPoints":[

   ]
}
ParameterTypeDescription
trading_reward_campaign_infoTradingRewardCampaignInfo
trading_reward_pool_campaign_scheduleCampaignRewardPool array
total_trade_reward_pointscosmossdk_io_math.LegacyDec
pending_trading_reward_pool_campaign_scheduleCampaignRewardPool array
pending_total_trade_reward_pointscosmossdk_io_math.LegacyDec array


TradingRewardCampaignInfo

ParameterTypeDescription
campaign_duration_secondsint64number of seconds of the duration of each campaign
quote_denomsstring arraythe trading fee quote denoms which will be counted for the rewards
trading_reward_boost_infoTradingRewardCampaignBoostInfothe optional boost info for markets
disqualified_market_idsstring arraythe marketIDs which are disqualified from being rewarded


CampaignRewardPool

ParameterTypeDescription
start_timestampint64the campaign start timestamp in seconds
max_campaign_rewardsgithub_com_cosmos_cosmos_sdk_types.Coinsmax_campaign_rewards are the maximum reward amounts to be disbursed at the end of the campaign


TradingRewardCampaignBoostInfo

ParameterTypeDescription
boosted_spot_market_idsstring array
spot_market_multipliersPointsMultiplier array
boosted_derivative_market_idsstring array
derivative_market_multipliersPointsMultiplier array


PointsMultiplier

ParameterTypeDescription
maker_points_multipliercosmossdk_io_math.LegacyDec
taker_points_multipliercosmossdk_io_math.LegacyDec

FeeDiscountAccountInfo

Retrieves the account's fee discount info

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    fee_discount = await client.fetch_fee_discount_account_info(
        account=address.to_acc_bech32(),
    )
    print(fee_discount)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchFeeDiscountAccountInfo(ctx, senderAddress.String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountstringYes

Response Parameters

Response Example:

{
    "account_info": {
        "maker_discount_rate": "0.000000000000000000",
        "taker_discount_rate": "0.000000000000000000",
        "staked_amount": "999397551050222369770",
        "volume": "33.861597433912020000"
    },
    "account_ttl": {
        "ttl_timestamp": 1750204196
    }
}
ParameterTypeDescription
tier_leveluint64
account_infoFeeDiscountTierInfo
account_ttlFeeDiscountTierTTL


FeeDiscountTierInfo

ParameterTypeDescription
maker_discount_ratecosmossdk_io_math.LegacyDecthe maker discount rate
taker_discount_ratecosmossdk_io_math.LegacyDecthe taker discount rate
staked_amountcosmossdk_io_math.Intthe staked amount required to qualify for the discount (in chain format)
volumecosmossdk_io_math.LegacyDecthe volume required to qualify for the discount (in human readable format)


FeeDiscountTierTTL

ParameterTypeDescription
tieruint64the tier number
ttl_timestampint64the TTL timestamp in seconds

FeeDiscountSchedule

Retrieves the fee discount schedule

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    schedule = await client.fetch_fee_discount_schedule()
    print(schedule)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchFeeDiscountSchedule(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "feeDiscountSchedule":{
      "bucketCount":"28",
      "bucketDuration":"86400",
      "quoteDenoms":[
         "peggy0xf9152067989BDc8783fF586624124C05A529A5D1",
         "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
      ],
      "tierInfos":[
         {
            "makerDiscountRate":"75000000000000000",
            "takerDiscountRate":"75000000000000000",
            "stakedAmount":"25000000000000000000",
            "volume":"50000000000000000000000000"
         },
         {
            "makerDiscountRate":"125000000000000000",
            "takerDiscountRate":"125000000000000000",
            "stakedAmount":"100000000000000000000",
            "volume":"100000000000000000000000000"
         },
         {
            "makerDiscountRate":"200000000000000000",
            "takerDiscountRate":"200000000000000000",
            "stakedAmount":"250000000000000000000",
            "volume":"200000000000000000000000000"
         },
         {
            "makerDiscountRate":"300000000000000000",
            "takerDiscountRate":"300000000000000000",
            "stakedAmount":"750000000000000000000",
            "volume":"500000000000000000000000000"
         },
         {
            "makerDiscountRate":"400000000000000000",
            "takerDiscountRate":"400000000000000000",
            "stakedAmount":"2000000000000000000000",
            "volume":"1500000000000000000000000000"
         },
         {
            "makerDiscountRate":"500000000000000000",
            "takerDiscountRate":"500000000000000000",
            "stakedAmount":"5000000000000000000000",
            "volume":"3500000000000000000000000000"
         },
         {
            "makerDiscountRate":"600000000000000000",
            "takerDiscountRate":"600000000000000000",
            "stakedAmount":"12500000000000000000000",
            "volume":"8000000000000000000000000000"
         },
         {
            "makerDiscountRate":"700000000000000000",
            "takerDiscountRate":"700000000000000000",
            "stakedAmount":"30000000000000000000000",
            "volume":"20000000000000000000000000000"
         },
         {
            "makerDiscountRate":"800000000000000000",
            "takerDiscountRate":"800000000000000000",
            "stakedAmount":"750000000000000000000000",
            "volume":"30000000000000000000000000000"
         }
      ],
      "disqualifiedMarketIds":[
         "0x8b1a4d3e8f6b559e30e40922ee3662dd78edf7042330d4d620d188699d1a9715"
      ]
   }
}
ParameterTypeDescription
fee_discount_scheduleFeeDiscountSchedule


FeeDiscountSchedule

ParameterTypeDescription
bucket_countuint64the bucket number
bucket_durationint64the bucket duration in seconds
quote_denomsstring arraythe trading fee quote denoms which will be counted for the fee paid contribution
tier_infosFeeDiscountTierInfo arraythe fee discount tiers
disqualified_market_idsstring arraythe marketIDs which are disqualified from contributing to the fee paid amount


FeeDiscountTierInfo

ParameterTypeDescription
maker_discount_ratecosmossdk_io_math.LegacyDecthe maker discount rate
taker_discount_ratecosmossdk_io_math.LegacyDecthe taker discount rate
staked_amountcosmossdk_io_math.Intthe staked amount required to qualify for the discount (in chain format)
volumecosmossdk_io_math.LegacyDecthe volume required to qualify for the discount (in human readable format)

BalanceMismatches

Retrieves mismatches between available vs. total balance

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    mismatches = await client.fetch_balance_mismatches(dust_factor=1)
    print(mismatches)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchBalanceMismatches(ctx, 1)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
dust_factorint64Yes

Response Parameters

Response Example:

{
   "balanceMismatches":[
      {
         "subaccountId":"0x05fa91c2776ac40473285b75e3d795870b94e5e2000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"870155637577815628",
         "total":"870155637577800218",
         "balanceHold":"0",
         "expectedTotal":"870155637577815628",
         "difference":"15410"
      },
      {
         "subaccountId":"0x0ec17dde18a517442b7d580f53d8dc705af13ea8000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"933130554975740524",
         "total":"933130554975739895",
         "balanceHold":"0",
         "expectedTotal":"933130554975740524",
         "difference":"629"
      },
      {
         "subaccountId":"0x16aef18dbaa341952f1af1795cb49960f68dfee3000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"761588657963815176",
         "total":"75225000761588657963815176",
         "balanceHold":"0",
         "expectedTotal":"761588657963815176",
         "difference":"-75225000000000000000000000"
      },
      {
         "subaccountId":"0x2968698c6b9ed6d44b667a0b1f312a3b5d94ded7000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"219272509577750671",
         "total":"79887563548606272509577750670",
         "balanceHold":"79887563548387000000000000000",
         "expectedTotal":"79887563548606272509577750671",
         "difference":"1"
      },
      {
         "subaccountId":"0x48237ce2f2d88aebef5eec7b7a228e4b13fd6eb5000000000000000000000002",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"4207036229489676145196048627",
         "total":"4207036229489676145196048624",
         "balanceHold":"0",
         "expectedTotal":"4207036229489676145196048627",
         "difference":"3"
      },
      {
         "subaccountId":"0x643de64bde8ae72b8f0acfe88abd444df6b723fd000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"436283710291691073",
         "total":"436283710291693025",
         "balanceHold":"0",
         "expectedTotal":"436283710291691073",
         "difference":"-1952"
      },
      {
         "subaccountId":"0x6590d14d9e9c1d964f8c83bddc8a092f4a2d1284000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"546950183781755834",
         "total":"546950183781756580",
         "balanceHold":"0",
         "expectedTotal":"546950183781755834",
         "difference":"-746"
      },
      {
         "subaccountId":"0x7619f89a2172c6705aac7482f3adbf0601ea140e000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"42406272780554925",
         "total":"42406272780556044",
         "balanceHold":"0",
         "expectedTotal":"42406272780554925",
         "difference":"-1119"
      },
      {
         "subaccountId":"0x8efbdeee271d02e1931a015233b4c1e84631a8f1000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"703396215678687048",
         "total":"703396215678689667",
         "balanceHold":"0",
         "expectedTotal":"703396215678687048",
         "difference":"-2619"
      },
      {
         "subaccountId":"0xbb4afcb3b0e2a95d91f0eaaf9acefefa00d70a6e000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"893202463407432010",
         "total":"893202463407432298",
         "balanceHold":"0",
         "expectedTotal":"893202463407432010",
         "difference":"-288"
      },
      {
         "subaccountId":"0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"342932031115126491",
         "total":"324904900060342932031115126449",
         "balanceHold":"324904900060000000000000000000",
         "expectedTotal":"324904900060342932031115126491",
         "difference":"42"
      },
      {
         "subaccountId":"0xc877ce74d053ada17c0c41d1203b19b44ac4d790000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"770209411929225026",
         "total":"770209411929224682",
         "balanceHold":"0",
         "expectedTotal":"770209411929225026",
         "difference":"344"
      },
      {
         "subaccountId":"0xfc48d223d93b6da8817ae50deb15c98babaa67ae000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"841670909697500242",
         "total":"841670909697500243",
         "balanceHold":"0",
         "expectedTotal":"841670909697500242",
         "difference":"-1"
      }
   ]
}
ParameterTypeDescription
balance_mismatchesBalanceMismatch array


BalanceMismatch

ParameterTypeDescription
subaccountIdstringthe subaccount ID
denomstringthe denom of the balance
availablecosmossdk_io_math.LegacyDecthe available balance
totalcosmossdk_io_math.LegacyDecthe total balance
balance_holdcosmossdk_io_math.LegacyDecthe balance hold
expected_totalcosmossdk_io_math.LegacyDecthe expected total balance
differencecosmossdk_io_math.LegacyDecthe difference between the total balance and the expected total balance

BalanceWithBalanceHolds

Retrieves available and total balances with balance holds

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    balance = await client.fetch_balance_with_balance_holds()
    print(balance)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchBalanceWithBalanceHolds(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "balanceWithBalanceHolds":[
      {
         "subaccountId":"0x0000000001e9681c4266ec4aaf5fe4de967072ee000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"0",
         "total":"0",
         "balanceHold":"0"
      },
      {
         "subaccountId":"0x00000002f32c0886ee65d68059fbdb76ef6a6996000000000000000000000000",
         "denom":"peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
         "available":"361169802053915059",
         "total":"361169802053915059",
         "balanceHold":"0"
      }
   ]
}
ParameterTypeDescription
balance_with_balance_holdsBalanceWithMarginHold array


BalanceWithMarginHold

ParameterTypeDescription
subaccountIdstringthe subaccount ID
denomstringthe denom of the balance
availablecosmossdk_io_math.LegacyDecthe available balance
totalcosmossdk_io_math.LegacyDecthe total balance
balance_holdcosmossdk_io_math.LegacyDecthe balance on hold

FeeDiscountTierStatistics

Retrieves fee discount tier stats

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    statistics = await client.fetch_fee_discount_tier_statistics()
    print(statistics)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchFeeDiscountTierStatistics(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "statistics":[
      {
         "count":"104",
         "tier":"0"
      },
      {
         "tier":"1",
         "count":"0"
      },
      {
         "tier":"2",
         "count":"1"
      },
      {
         "tier":"3",
         "count":"1"
      },
      {
         "tier":"4",
         "count":"0"
      },
      {
         "tier":"5",
         "count":"0"
      },
      {
         "tier":"6",
         "count":"0"
      },
      {
         "tier":"7",
         "count":"0"
      },
      {
         "tier":"8",
         "count":"0"
      }
   ]
}
ParameterTypeDescription
statisticsTierStatistic array


TierStatistic

ParameterTypeDescription
tieruint64
countuint64

MitoVaultInfos

Retrieves market making pool info

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    infos = await client.fetch_mito_vault_infos()
    print(infos)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchMitoVaultInfos(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "masterAddresses":[
      "inj1qg5ega6dykkxc307y25pecuufrjkxkag6xhp6y"
   ],
   "spotAddresses":[
      "inj1wddvh8vnn6rmyhp59qvr5jmpu3nllkgsyzr4m6"
   ],
   "derivativeAddresses":[

   ],
   "cw20Addresses":[

   ]
}
ParameterTypeDescription
master_addressesstring arraylist of master addresses
derivative_addressesstring arraylist of derivative addresses
spot_addressesstring arraylist of spot addresses
cw20_addressesstring arraylist of cw20 addresses

QueryMarketIDFromVault

Returns the market ID for a given vault subaccount ID

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_id = await client.fetch_market_id_from_vault(vault_address="inj1qg5ega6dykkxc307y25pecuufrjkxkag6xhp6y")
    print(market_id)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    vaultAddress := "inj1qg5ega6dykkxc307y25pecuufrjkxkag6xhp6y"

    res, err := chainClient.FetchMarketIDFromVault(ctx, vaultAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
vault_addressstringYes

Response Parameters

Response Example:


ParameterTypeDescription
market_idstring

HistoricalTradeRecords

Retrieves historical trade records for a given market ID

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    records = await client.fetch_historical_trade_records(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    )
    print(records)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchHistoricalTradeRecords(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:

{
   "tradeRecords":[
      {
         "marketId":"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
         "latestTradeRecords":[
            {
               "timestamp":"1709641326",
               "price":"42249000",
               "quantity":"15368000000000000000000000000000000000"
            },
            {
               "timestamp":"1709641446",
               "price":"42080000",
               "quantity":"15415000000000000000000000000000000000"
            }
         ]
      }
   ]
}
ParameterTypeDescription
trade_recordsTradeRecords array


TradeRecords

ParameterTypeDescription
market_idstring
latest_trade_recordsTradeRecord array


TradeRecord

ParameterTypeDescription
timestampint64the timestamp of the trade
pricecosmossdk_io_math.LegacyDecthe price of the trade (in human readable format)
quantitycosmossdk_io_math.LegacyDecthe quantity of the trade (in human readable format)

IsOptedOutOfRewards

Retrieves if the account is opted out of rewards

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    is_opted_out = await client.fetch_is_opted_out_of_rewards(
        account=address.to_acc_bech32(),
    )
    print(is_opted_out)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchIsOptedOutOfRewards(ctx, senderAddress.String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
accountstringYes

Response Parameters

Response Example:

{
   "isOptedOut":true
}
ParameterTypeDescription
is_opted_outbool

OptedOutOfRewardsAccounts

Retrieves all accounts opted out of rewards

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    opted_out = await client.fetch_opted_out_of_rewards_accounts()
    print(opted_out)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchOptedOutOfRewardsAccounts(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "accounts":[
      "inj1qqqqpgj4strcnlgzsaae2tey7dhk6enu8fc5zd",
      "inj1fwpyx9k4x5yzm63wmrpg4ekngmv2qjd0yddqaq",
      "inj1tz65vxc7a4acf6gd3fhq23mrquvjhgrtwwr7fz",
      "inj1wefqjmt5xkn7t769kl4kay2ncvx7we0nnephl2",
      "inj1n47c74gv6jwnzzsmqhd7h5msdnx2gncpjk4yh4",
      "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
      "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt"
   ]
}
ParameterTypeDescription
accountsstring array

MarketVolatility

Computes the volatility for spot and derivative markets trading history

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    trade_grouping_sec = 10
    max_age = 0
    include_raw_history = True
    include_metadata = True
    volatility = await client.fetch_market_volatility(
        market_id=market_id,
        trade_grouping_sec=trade_grouping_sec,
        max_age=max_age,
        include_raw_history=include_raw_history,
        include_metadata=include_metadata,
    )
    print(json.dumps(volatility, indent=4))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    tradeHistoryOptions := exchangev2types.TradeHistoryOptions{
        TradeGroupingSec:  10,
        MaxAge:            0,
        IncludeRawHistory: true,
        IncludeMetadata:   true,
    }

    res, err := chainClient.FetchMarketVolatility(ctx, marketId, &tradeHistoryOptions)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringthe market ID to query volatility forYes
trade_history_optionsTradeHistoryOptionsthe trade history optionsNo


TradeHistoryOptions

ParameterTypeDescription
trade_grouping_secuint64TradeGroupingSec of 0 means use the chain's default grouping
max_ageuint64MaxAge restricts the trade records oldest age in seconds from the current block time to consider. A value of 0 means use all the records present on the chain.
include_raw_historyboolIf IncludeRawHistory is true, the raw underlying data used for the computation is included in the response
include_metadataboolIf IncludeMetadata is true, metadata on the computation is included in the response

Response Parameters

Response Example:

{
  "volatility": "0.000000000000000000",
  "history_metadata": {
    "group_count": 1,
    "records_sample_size": 1,
    "mean": "10.500000000000000000",
    "twap": "0.000000000000000000",
    "first_timestamp": "1750251696",
    "last_timestamp": "1750251696",
    "min_price": "10.500000000000000000",
    "max_price": "10.500000000000000000",
    "median_price": "10.500000000000000000"
  },
  "raw_history": [
    {
      "timestamp": "1750251696",
      "price": "10.500000000000000000",
      "quantity": "0.788000000000000000"
    }
  ]
}
ParameterTypeDescription
volatilitycosmossdk_io_math.LegacyDec
history_metadatatypes.MetadataStatistics
raw_historyTradeRecord array


MetadataStatistics

ParameterTypeDescription
group_countuint32GroupCount refers to the number of groups used. Equals RecordsSampleSize if no grouping is used
records_sample_sizeuint32RecordsSampleSize refers to the total number of records used.
meancosmossdk_io_math.LegacyDecMean refers to the arithmetic mean For trades, the mean is the VWAP computed over the grouped trade records ∑ (price * quantity) / ∑ quantity For oracle prices, the mean is computed over the price records ∑ (price) / prices_count
twapcosmossdk_io_math.LegacyDecTWAP refers to the time-weighted average price which equals ∑ (price_i * ∆t_i) / ∑ ∆t_i where ∆t_i = t_i - t_{i-1}
first_timestampint64FirstTimestamp is the timestamp of the oldest record considered
last_timestampint64LastTimestamp is the timestamp of the youngest record considered
min_pricecosmossdk_io_math.LegacyDecMinPrice refers to the smallest individual raw price considered
max_pricecosmossdk_io_math.LegacyDecMaxPrice refers to the largest individual raw price considered
median_pricecosmossdk_io_math.LegacyDecMedianPrice refers to the median individual raw price considered


TradeRecord

ParameterTypeDescription
timestampint64the timestamp of the trade
pricecosmossdk_io_math.LegacyDecthe price of the trade (in human readable format)
quantitycosmossdk_io_math.LegacyDecthe quantity of the trade (in human readable format)

MarketAtomicExecutionFeeMultiplier

Retrieves the atomic execution fee multiplier

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    multiplier = await client.fetch_market_atomic_execution_fee_multiplier(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(multiplier)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchMarketAtomicExecutionFeeMultiplier(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:

{
  "multiplier": "2.000000000000000000"
}
ParameterTypeDescription
multipliercosmossdk_io_math.LegacyDec

ActiveStakeGrant

Retrieves the active stake grant for a grantee

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    grantee_public_address = os.getenv("INJECTIVE_GRANTEE_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    active_grant = await client.fetch_active_stake_grant(
        grantee=grantee_public_address,
    )
    print(active_grant)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    res, err := chainClient.FetchActiveStakeGrant(ctx, grantee)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
granteestringYes

Response Parameters

Response Example:

{
    "grant": {
        "granter": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
        "amount": "1000000000000000000"
    },
    "effective_grant": {
        "granter": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
        "net_granted_stake": "1000000000000000000",
        "is_valid": true
    }
}
ParameterTypeDescription
grantActiveGrant
effective_grantEffectiveGrant


ActiveGrant

ParameterTypeDescription
granterstring
amountcosmossdk_io_math.Int


EffectiveGrant

ParameterTypeDescription
granterstring
net_granted_stakecosmossdk_io_math.Int
is_validbool

GrantAuthorization

Retrieves the grant authorization amount for a granter and grantee

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")
    grantee_public_address = os.getenv("INJECTIVE_GRANTEE_PUBLIC_ADDRESS")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    active_grant = await client.fetch_grant_authorization(
        granter=address.to_acc_bech32(),
        grantee=grantee_public_address,
    )
    print(active_grant)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    granter := senderAddress.String()
    grantee := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    res, err := chainClient.FetchGrantAuthorization(ctx, granter, grantee)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
granterstringYes
granteestringYes

Response Parameters

Response Example:

{
    "grant": {
        "granter": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
        "amount": "1000000000000000000"
    },
    "effective_grant": {
        "granter": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
        "net_granted_stake": "1000000000000000000",
        "is_valid": true
    }
}
ParameterTypeDescription
amountcosmossdk_io_math.Int

GrantAuthorizations

Retrieves the grant authorization amount for a granter and grantee

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    active_grant = await client.fetch_grant_authorizations(
        granter=address.to_acc_bech32(),
    )
    print(json.dumps(active_grant, indent=4))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    granter := senderAddress.String()

    res, err := chainClient.FetchGrantAuthorizations(ctx, granter)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
granterstringYes

Response Parameters

Response Example:

{
    "totalGrantAmount": "0",
    "grants": []
}
ParameterTypeDescription
total_grant_amountcosmossdk_io_math.Int
grantsGrantAuthorization array

MarketBalance

Retrieves a derivative or binary options market's balance

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    """
    Demonstrate fetching market balances using AsyncClient.
    """
    # Select network: choose between Network.mainnet(), Network.testnet(), or Network.devnet()
    network = Network.testnet()

    # Initialize the Async Client
    client = AsyncClient(network)

    try:
        # Fetch market balances
        market_balance = await client.fetch_market_balance(
            market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
        )
        print("Market Balance:")
        print(json.dumps(market_balance, indent=4))

    except Exception as ex:
        print(f"Error occurred: {ex}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    res, err := chainClient.FetchMarketBalance(context.Background(), marketId)
    if err != nil {
        log.Fatalf("Failed to fetch market balance: %v", err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
market_idstringmarket idYes

Response Parameters

Response Example:

{
    "balance": {
        "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        "balance": "0.000000000000000000"
    }
}
ParameterTypeDescription
balanceMarketBalance


MarketBalance

ParameterTypeDescription
market_idstringthe market ID
balancecosmossdk_io_math.LegacyDecthe current balance of the market

MarketBalances

Retrieves all derivative or binary options market balances

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    """
    Demonstrate fetching market balances using AsyncClient.
    """
    # Select network: choose between Network.mainnet(), Network.testnet(), or Network.devnet()
    network = Network.testnet()

    # Initialize the Async Client
    client = AsyncClient(network)

    try:
        # Fetch market balances
        market_balances = await client.fetch_market_balances()
        print("Market Balances:")
        print(json.dumps(market_balances, indent=4))

    except Exception as ex:
        print(f"Error occurred: {ex}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    res, err := chainClient.FetchMarketBalances(context.Background())
    if err != nil {
        log.Fatalf("Failed to fetch market balances: %v", err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

No parameters

Response Parameters

Response Example:

{
    "balances": [
        {
            "market_id": "0x0f03542809143c7e5d3c22f56bc6e51eb2c8bab5009161b58f6f468432dfa196",
            "balance": "12786056074.839985155385737295"
        },
        {
            "market_id": "0x14f82598b92674598af196770a45e1b808a4ef3aa86eb9ca09aff1aeab33ac46",
            "balance": "110430504.838630944276932996"
        },
        {
            "market_id": "0x155576f660b3b6116c1ab7a42fbf58a95adf11b3061f88f81bc8df228e7ac934",
            "balance": "192395910452.616033854134359847"
        },
        {
            "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            "balance": "6016868951759.776358953610638498"
        },
        {
            "market_id": "0x2e94326a421c3f66c15a3b663c7b1ab7fb6a5298b3a57759ecf07f0036793fc9",
            "balance": "1862621465555.345621229678183898"
        },
        {
            "market_id": "0x70bc8d7feab38b23d5fdfb12b9c3726e400c265edbcbf449b6c80c31d63d3a02",
            "balance": "1081846808163.026104388432379730"
        },
        {
            "market_id": "0x820bad0e0cbee65bb0eea5a99c78720c97b7b2217c47dcc0e0875e1ebb35e546",
            "balance": "19250932183.917771878838020931"
        },
        {
            "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
            "balance": "1776259936686.725194400658361835"
        },
        {
            "market_id": "0xb6fd8f78b97238eb67146e9b097c131e94730c10170cbcafa82ea2fd14ff62c7",
            "balance": "24106730968097.988978884697599456"
        },
        {
            "market_id": "0xba9c96a1a9cc226cfe6bd9bca3a433e396569d1955393f38f2ee728cfda7ec58",
            "balance": "106677202502.228300901587097267"
        },
        {
            "market_id": "0xc90e8ea048b8fe5c3174d4d0386191765db699d2bf83d0cbaf07e15462115a15",
            "balance": "268624705972.943347626458922724"
        },
        {
            "market_id": "0xd97d0da6f6c11710ef06315971250e4e9aed4b7d4cd02059c9477ec8cf243782",
            "balance": "76355383629.090552557946079821"
        },
        {
            "market_id": "0xdfbb038abf614c59decdaaa02c0446bbebcd16327bd4e9d0350a1e3b691a38ef",
            "balance": "5328333.333333333386944360"
        },
        {
            "market_id": "0xe185b08a7ccd830a94060edd5e457d30f429aa6f0757f75a8b93aa611780cfac",
            "balance": "11381866569024.341225836858561702"
        },
        {
            "market_id": "0xf97a740538e10845e0c3db9ea94c6eaf8a570aeebe3e3511e2e387501a40e4bb",
            "balance": "16051013781.249043673289183236"
        }
    ]
}
ParameterTypeDescription
balancesMarketBalance array


MarketBalance

ParameterTypeDescription
market_idstringthe market ID
balancecosmossdk_io_math.LegacyDecthe current balance of the market

DenomMinNotional

Retrieves the min notional for a denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    """
    Demonstrate fetching denom min notional using AsyncClient.
    """
    # Select network: choose between Network.mainnet(), Network.testnet(), or Network.devnet()
    network = Network.testnet()

    # Initialize the Async Client
    client = AsyncClient(network)

    try:
        # Example denom
        denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

        # Fetch market balance
        min_notional = await client.fetch_denom_min_notional(denom=denom)
        print("Min Notional:")
        print(min_notional)

    except Exception as ex:
        print(f"Error occurred: {ex}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denom := "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"

    res, err := chainClient.FetchDenomMinNotional(context.Background(), denom)
    if err != nil {
        log.Fatalf("Failed to fetch denom min notional for %s: %v", denom, err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringYes

Response Parameters

Response Example:

{
  "amount": "1.000000000000000000"
}
ParameterTypeDescription
amountcosmossdk_io_math.LegacyDecthe minimum notional amount for the denom (in human readable format)

DenomMinNotionals

Retrieves the min notionals for all denoms

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    """
    Demonstrate fetching denom min notionals using AsyncClient.
    """
    # Select network: choose between Network.mainnet(), Network.testnet(), or Network.devnet()
    network = Network.testnet()

    # Initialize the Async Client
    client = AsyncClient(network)

    try:
        # Fetch market balance
        min_notionals = await client.fetch_denom_min_notionals()
        print("Min Notionals:")
        print(min_notionals)

    except Exception as ex:
        print(f"Error occurred: {ex}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    res, err := chainClient.FetchDenomMinNotionals(context.Background())
    if err != nil {
        log.Fatalf("Failed to fetch denoms min notionals: %v", err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}

No parameters

Response Parameters

Response Example:

{
    "denom_min_notionals": [
        {
            "denom": "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9",
            "min_notional": "1.000000000000000000"
        },
        {
            "denom": "inj",
            "min_notional": "0.010000000000000000"
        },
        {
            "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
            "min_notional": "1.000000000000000000"
        }
    ]
}
ParameterTypeDescription
denom_min_notionalsDenomMinNotional array


DenomMinNotional

ParameterTypeDescription
denomstringthe denom of the token
min_notionalcosmossdk_io_math.LegacyDecthe minimum notional value for the token (in human readable format)

OpenInterest

Retrieves a market's open interest

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    """
    Demonstrate fetching denom min notionals using AsyncClient.
    """
    # Select network: choose between Network.mainnet(), Network.testnet(), or Network.devnet()
    network = Network.testnet()

    # Initialize the Async Client
    client = AsyncClient(network)

    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    open_interest = await client.fetch_open_interest(market_id=market_id)
    print(json.dumps(open_interest, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchOpenInterest(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringmarket idYes

Response Parameters

Response Example:

{
    "amount": {
        "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        "balance": "1020516.638732418776111164"
    }
}
ParameterTypeDescription
amountOpenInterest

MsgRewardsOptOut

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    msg = composer.msg_rewards_opt_out(sender=address.to_acc_bech32())

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgRewardsOptOut{
        Sender: senderAddress.String(),
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgAuthorizeStakeGrants

Message to grant stakes to grantees.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    grant_authorization = composer.create_grant_authorization(
        grantee="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
        amount=Decimal("1"),
    )
    message = composer.msg_authorize_stake_grants(sender=address.to_acc_bech32(), grants=[grant_authorization])

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    grantAuthorization := &exchangev2types.GrantAuthorization{
        Grantee: "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
        Amount:  math.NewIntWithDecimal(1, 18),
    }

    msg := &exchangev2types.MsgAuthorizeStakeGrants{
        Sender: senderAddress.String(),
        Grants: []*exchangev2types.GrantAuthorization{grantAuthorization},
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringInjective address of the stake granterYes
grantsGrantAuthorization arraylist of stake grants to authorize (mandatory)Yes


GrantAuthorization

ParameterTypeDescription
granteestringthe grantee address
amountcosmossdk_io_math.Intthe amount of stake granted (INJ in chain format)

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgActivateStakeGrant

Message for grantees to claim stake grants.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_activate_stake_grant(
        sender=address.to_acc_bech32(), granter="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := &exchangev2types.MsgActivateStakeGrant{
        Sender:  senderAddress.String(),
        Granter: "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringInjective address of the stake granteeYes
granterstringInjective address of the stake granterYes


GrantAuthorization

ParameterTypeDescription
granteestringthe grantee address
amountcosmossdk_io_math.Intthe amount of stake granted (INJ in chain format)

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Chain Exchange for Derivatives

Includes all messages related to derivative markets.

L3DerivativeOrderBook

Get the level 3 aggregated order book for a derivative market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    orderbook = await client.fetch_l3_derivative_orderbook(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(orderbook)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchL3DerivativeOrderbook(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringmarket idYes

Response Parameters

Response Example:

ParameterTypeDescription
BidsTrimmedLimitOrder array
AsksTrimmedLimitOrder array
sequint64the current orderbook sequence number


TrimmedLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
order_hashstringthe order hash
subaccount_idstringthe subaccount ID

DerivativeMidPriceAndTOB

Retrieves a derivative market's mid-price

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    prices = await client.fetch_derivative_mid_price_and_tob(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(prices)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchDerivativeMidPriceAndTOB(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes

Response Parameters

Response Example:

{
    "midPrice": "19.49495",
    "bestBuyPrice": "19.2929",
    "bestSellPrice": "19.697"
}
ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market

DerivativeOrderbook

Retrieves a derivative market's orderbook by marketID

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    pagination = PaginationOption(limit=2)

    orderbook = await client.fetch_chain_derivative_orderbook(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        pagination=pagination,
    )
    print(orderbook)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "cosmossdk.io/math"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    limit := uint64(2)
    limitCumulativeNotional := math.LegacyDec{}

    res, err := chainClient.FetchChainDerivativeOrderbook(ctx, marketId, limit, limitCumulativeNotional)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
limituint64Yes
limit_cumulative_notionalcosmossdk_io_math.LegacyDecNo

Response Parameters

Response Example:

{
    "buysPriceLevel": [
        {
            "p": "19.2929",
            "q": "0.0333"
        },
        {
            "p": "19.1837",
            "q": "0.029"
        }
    ],
    "sellsPriceLevel": [
        {
            "p": "19.697",
            "q": "0.0333"
        },
        {
            "p": "19.899",
            "q": "0.0333"
        }
    ]
}
ParameterTypeDescription
buys_price_levelLevel array
sells_price_levelLevel array
sequint64the current orderbook sequence number


Level

ParameterTypeDescription
pcosmossdk_io_math.LegacyDecprice (in human readable format)
qcosmossdk_io_math.LegacyDecquantity (in human readable format)

TraderDerivativeOrders

Retrieves a trader's derivative orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_trader_derivative_orders(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        subaccount_id=subaccount_id,
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainTraderDerivativeOrders(ctx, marketId, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes

Response Parameters

Response Example:

{
   "orders":[

   ]
}
ParameterTypeDescription
ordersTrimmedDerivativeLimitOrder array


TrimmedDerivativeLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
margincosmossdk_io_math.LegacyDecmargin of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

AccountAddressDerivativeOrders

Retrieves all account address' derivative orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    orders = await client.fetch_chain_account_address_derivative_orders(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        account_address=address.to_acc_bech32(),
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainAccountAddressDerivativeOrders(ctx, marketId, senderAddress.String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
account_addressstringAccount address of the traderYes

Response Parameters

Response Example:

{
   "orders":[

   ]
}
ParameterTypeDescription
ordersTrimmedDerivativeLimitOrder array


TrimmedDerivativeLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
margincosmossdk_io_math.LegacyDecmargin of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

DerivativeOrdersByHashes

Retrieves a trader's derivative orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_derivative_orders_by_hashes(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        subaccount_id=subaccount_id,
        order_hashes=["0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"],
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := chainClient.Subaccount(senderAddress, 0)
    orderHashes := []string{"0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"}

    res, err := chainClient.FetchChainDerivativeOrdersByHashes(ctx, marketId, subaccountId.Hex(), orderHashes)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes
order_hashesstring arraythe order hashesYes

Response Parameters

Response Example:

{
   "orders":[

   ]
}
ParameterTypeDescription
ordersTrimmedDerivativeLimitOrder array


TrimmedDerivativeLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
margincosmossdk_io_math.LegacyDecmargin of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

TraderDerivativeTransientOrders

Retrieves a trader's transient derivative orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_trader_derivative_transient_orders(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        subaccount_id=subaccount_id,
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainTraderDerivativeTransientOrders(ctx, marketId, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes

Response Parameters

Response Example:

{
   "orders":[

   ]
}
ParameterTypeDescription
ordersTrimmedDerivativeLimitOrder array


TrimmedDerivativeLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
margincosmossdk_io_math.LegacyDecmargin of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

DerivativeMarkets

Retrieves a list of derivative markets

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    derivative_markets = await client.fetch_chain_derivative_markets(
        status="Active",
        market_ids=["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"],
    )
    print(derivative_markets)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    status := "Active"
    marketIds := []string{"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"}
    withMidPriceAndTob := true

    res, err := chainClient.FetchChainDerivativeMarkets(ctx, status, marketIds, withMidPriceAndTob)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
statusstringStatus of the market, for convenience it is set to string - not enumYes
market_idsstring arrayFilter by market IDsYes
with_mid_price_and_tobboolFlag to return the markets mid price and top of the book buy and sell orders.Yes

Response Parameters

Response Example:

{
    "markets": [
        {
            "market": {
                "ticker": "INJ/USDT PERP",
                "oracle_base": "0x2d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b3",
                "oracle_quote": "0x1fc18861232290221461220bd4e2acd1dcdfbc89c84092c93c18bdc7756c1588",
                "oracle_type": 9,
                "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
                "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
                "initial_margin_ratio": "0.083333000000000000",
                "maintenance_margin_ratio": "0.060000000000000000",
                "maker_fee_rate": "-0.000100000000000000",
                "taker_fee_rate": "0.000500000000000000",
                "relayer_fee_share_rate": "0.400000000000000000",
                "isPerpetual": true,
                "status": 1,
                "min_price_tick_size": "0.000100000000000000",
                "min_quantity_tick_size": "0.000100000000000000",
                "min_notional": "0.000000000001000000",
                "quote_decimals": 6,
                "reduce_margin_ratio": "0.249999000000000000"
            },
            "Info": {
                "perpetual_info": {
                    "market_info": {
                        "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
                        "hourly_funding_rate_cap": "0.000625000000000000",
                        "hourly_interest_rate": "0.000004166660000000",
                        "next_funding_timestamp": 1748962800,
                        "funding_interval": 3600
                    },
                    "funding_info": {
                        "cumulative_funding": "0.142734053117809236",
                        "cumulative_price": "0.000000000000000000",
                        "last_timestamp": 1748959200
                    }
                }
            },
            "mark_price": "12.864774536812149196",
            "mid_price_and_tob": {
                "mid_price": "19.494950000000000000",
                "best_buy_price": "19.292900000000000000",
                "best_sell_price": "19.697000000000000000"
            }
        }
    ]
}
ParameterTypeDescription
marketsFullDerivativeMarket array


FullDerivativeMarket

ParameterTypeDescription
marketDerivativeMarketderivative market details
mark_pricecosmossdk_io_math.LegacyDecmark price (in human readable format)
mid_price_and_tobMidPriceAndTOBmid_price_and_tob defines the mid price for this market and the best ask and bid orders


DerivativeMarket

ParameterTypeDescription
tickerstringTicker for the derivative contract.
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typetypes.OracleTypeOracle type
oracle_scale_factoruint32Scale factor for oracle prices.
quote_denomstringAddress of the quote currency denomination for the derivative contract
market_idstringUnique market ID.
initial_margin_ratiocosmossdk_io_math.LegacyDecinitial_margin_ratio defines the initial margin ratio of a derivative market
maintenance_margin_ratiocosmossdk_io_math.LegacyDecmaintenance_margin_ratio defines the maintenance margin ratio of a derivative market
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the maker fee rate of a derivative market
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the taker fee rate of a derivative market
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
isPerpetualbooltrue if the market is a perpetual market. false if the market is an expiry futures market
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price and margin required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
quote_decimalsuint32quote token decimals
reduce_margin_ratiocosmossdk_io_math.LegacyDecreduce_margin_ratio defines the ratio of the margin that is reduced
open_notional_capOpenNotionalCapopen_notional_cap defines the maximum open notional for the market


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec


PerpetualMarketState

ParameterTypeDescription
market_infoPerpetualMarketInfo
funding_infoPerpetualMarketFunding


PerpetualMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
hourly_funding_rate_capcosmossdk_io_math.LegacyDechourly_funding_rate_cap defines the maximum absolute value of the hourly funding rate
hourly_interest_ratecosmossdk_io_math.LegacyDechourly_interest_rate defines the hourly interest rate
next_funding_timestampint64next_funding_timestamp defines the next funding timestamp in seconds of a perpetual market
funding_intervalint64funding_interval defines the next funding interval in seconds of a perpetual market.


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingcosmossdk_io_math.LegacyDeccumulative_funding defines the cumulative funding of a perpetual market.
cumulative_pricecosmossdk_io_math.LegacyDeccumulative_price defines the running time-integral of the perp premium ((VWAP - mark_price) / mark_price) i.e., sum(premium * seconds) used to compute the interval’s average premium for funding
last_timestampint64the last funding timestamp in seconds


ExpiryFuturesMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
expiration_timestampint64expiration_timestamp defines the expiration time for a time expiry futures market.
twap_start_timestampint64expiration_twap_start_timestamp defines the start time of the TWAP calculation window
expiration_twap_start_price_cumulativecosmossdk_io_math.LegacyDecexpiration_twap_start_price_cumulative defines the cumulative price for the start of the TWAP window (in human readable format)
settlement_pricecosmossdk_io_math.LegacyDecsettlement_price defines the settlement price for a time expiry futures market (in human readable format)


MidPriceAndTOB

ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market (in human readable format)
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market (in human readable format)
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market (in human readable format)


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

DerivativeMarket

Retrieves a derivative market by ticker

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    derivative_market = await client.fetch_chain_derivative_market(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(derivative_market)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainDerivativeMarket(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes

Response Parameters

Response Example:

{
    "market": {
        "market": {
            "ticker": "INJ/USDT PERP",
            "oracle_base": "0x2d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b3",
            "oracle_quote": "0x1fc18861232290221461220bd4e2acd1dcdfbc89c84092c93c18bdc7756c1588",
            "oracle_type": 9,
            "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            "initial_margin_ratio": "0.083333000000000000",
            "maintenance_margin_ratio": "0.060000000000000000",
            "maker_fee_rate": "-0.000100000000000000",
            "taker_fee_rate": "0.000500000000000000",
            "relayer_fee_share_rate": "0.400000000000000000",
            "isPerpetual": true,
            "status": 1,
            "min_price_tick_size": "0.000100000000000000",
            "min_quantity_tick_size": "0.000100000000000000",
            "min_notional": "0.000000000001000000",
            "quote_decimals": 6,
            "reduce_margin_ratio": "0.249999000000000000"
        },
        "Info": {
            "perpetual_info": {
                "market_info": {
                    "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
                    "hourly_funding_rate_cap": "0.000625000000000000",
                    "hourly_interest_rate": "0.000004166660000000",
                    "next_funding_timestamp": 1748962800,
                    "funding_interval": 3600
                },
                "funding_info": {
                    "cumulative_funding": "0.142734053117809236",
                    "cumulative_price": "0.000000000000000000",
                    "last_timestamp": 1748959200
                }
            }
        },
        "mark_price": "12.824150042260121341"
    }
}
ParameterTypeDescription
marketFullDerivativeMarket


FullDerivativeMarket

ParameterTypeDescription
marketDerivativeMarketderivative market details
mark_pricecosmossdk_io_math.LegacyDecmark price (in human readable format)
mid_price_and_tobMidPriceAndTOBmid_price_and_tob defines the mid price for this market and the best ask and bid orders


DerivativeMarket

ParameterTypeDescription
tickerstringTicker for the derivative contract.
oracle_basestringOracle base currency
oracle_quotestringOracle quote currency
oracle_typetypes.OracleTypeOracle type
oracle_scale_factoruint32Scale factor for oracle prices.
quote_denomstringAddress of the quote currency denomination for the derivative contract
market_idstringUnique market ID.
initial_margin_ratiocosmossdk_io_math.LegacyDecinitial_margin_ratio defines the initial margin ratio of a derivative market
maintenance_margin_ratiocosmossdk_io_math.LegacyDecmaintenance_margin_ratio defines the maintenance margin ratio of a derivative market
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the maker fee rate of a derivative market
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the taker fee rate of a derivative market
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
isPerpetualbooltrue if the market is a perpetual market. false if the market is an expiry futures market
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price and margin required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
quote_decimalsuint32quote token decimals
reduce_margin_ratiocosmossdk_io_math.LegacyDecreduce_margin_ratio defines the ratio of the margin that is reduced
open_notional_capOpenNotionalCapopen_notional_cap defines the maximum open notional for the market


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


PerpetualMarketState

ParameterTypeDescription
market_infoPerpetualMarketInfo
funding_infoPerpetualMarketFunding


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec


PerpetualMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
hourly_funding_rate_capcosmossdk_io_math.LegacyDechourly_funding_rate_cap defines the maximum absolute value of the hourly funding rate
hourly_interest_ratecosmossdk_io_math.LegacyDechourly_interest_rate defines the hourly interest rate
next_funding_timestampint64next_funding_timestamp defines the next funding timestamp in seconds of a perpetual market
funding_intervalint64funding_interval defines the next funding interval in seconds of a perpetual market.


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingcosmossdk_io_math.LegacyDeccumulative_funding defines the cumulative funding of a perpetual market.
cumulative_pricecosmossdk_io_math.LegacyDeccumulative_price defines the running time-integral of the perp premium ((VWAP - mark_price) / mark_price) i.e., sum(premium * seconds) used to compute the interval’s average premium for funding
last_timestampint64the last funding timestamp in seconds


ExpiryFuturesMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
expiration_timestampint64expiration_timestamp defines the expiration time for a time expiry futures market.
twap_start_timestampint64expiration_twap_start_timestamp defines the start time of the TWAP calculation window
expiration_twap_start_price_cumulativecosmossdk_io_math.LegacyDecexpiration_twap_start_price_cumulative defines the cumulative price for the start of the TWAP window (in human readable format)
settlement_pricecosmossdk_io_math.LegacyDecsettlement_price defines the settlement price for a time expiry futures market (in human readable format)


MidPriceAndTOB

ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market (in human readable format)
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market (in human readable format)
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market (in human readable format)


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

DerivativeMarketAddress

Retrieves a derivative market's corresponding address for fees that contribute to the market's insurance fund

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    address = await client.fetch_derivative_market_address(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(address)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchDerivativeMarketAddress(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes

Response Parameters

Response Example:

{
    "address": "inj1zlh5sqevkfphtwnu9cul8p89vseme2eqt0snn9",
    "subaccount_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20000000000000000000000000"
}
ParameterTypeDescription
addressstringaddress for the market
subaccount_idstringsubaccountID for the market

Positions

Retrieves the entire exchange module's positions

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    positions = await client.fetch_chain_positions()
    print(positions)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchChainPositions(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "state":[
        {
            "subaccount_id": "0x90b61ab108ad861a68a763eb7fd9868737678ed5000000000000000000000000",
            "market_id": "0x0f03542809143c7e5d3c22f56bc6e51eb2c8bab5009161b58f6f468432dfa196",
            "position": {
                "isLong": true,
                "quantity": "0.000100000000000000",
                "entry_price": "32.256800000000000000",
                "margin": "0.004249000000000000",
                "cumulative_funding_entry": "1.271877043435469720"
            }
        },
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0x0f03542809143c7e5d3c22f56bc6e51eb2c8bab5009161b58f6f468432dfa196",
            "position": {
                "isLong": true,
                "quantity": "258.750000000000000000",
                "entry_price": "24.100496718773416725",
                "margin": "6777.476791762608353694",
                "cumulative_funding_entry": "0.050154448152800501"
            }
        }
   ]
}
ParameterTypeDescription
stateDerivativePosition array


DerivativePosition

ParameterTypeDescription
subaccount_idstringthe subaccount ID
market_idstringthe market ID
positionPositionthe position details


Position

ParameterTypeDescription
isLongboolTrue if the position is long. False if the position is short.
quantitycosmossdk_io_math.LegacyDecThe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecThe entry price of the position (in human readable format)
margincosmossdk_io_math.LegacyDecThe margin of the position (in human readable format)
cumulative_funding_entrycosmossdk_io_math.LegacyDecThe cumulative funding

PositionsInMarket

Retrieves all positions in market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    positions = await client.fetch_chain_positions_in_market(market_id=market_id)
    print(json.dumps(positions, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainPositionsInMarket(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
market_idstringthe market IDYes

Response Parameters

Response Example:

{
    "state": [
        {
            "subaccount_id": "0x0000007c60fab7a70c2ae0ebe437f3726b05e7eb000000000000000000000000",
            "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            "position": {
                "quantity": "0.087829315829932072",
                "entry_price": "26.453271813315285838",
                "margin": "1.156098565040366061",
                "cumulative_funding_entry": "-0.259896600932507160"
            }
        },
        {
            "subaccount_id": "0x0000040f1111c5c3d2037940658ee770bb37e0a2000000000000000000000000",
            "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            "position": {
                "isLong": true,
                "quantity": "0.000068500966722584",
                "entry_price": "12.293600000000000000",
                "margin": "0.000422337168093583",
                "cumulative_funding_entry": "0.001394965993845972"
            }
        }
    ]
}
ParameterTypeDescription
statePosition


Position

ParameterTypeDescription
isLongboolTrue if the position is long. False if the position is short.
quantitycosmossdk_io_math.LegacyDecThe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecThe entry price of the position (in human readable format)
margincosmossdk_io_math.LegacyDecThe margin of the position (in human readable format)
cumulative_funding_entrycosmossdk_io_math.LegacyDecThe cumulative funding

SubaccountPositions

Retrieves subaccount's positions

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    positions = await client.fetch_chain_subaccount_positions(
        subaccount_id=subaccount_id,
    )
    print(positions)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainSubaccountPositions(ctx, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes

Response Parameters

Response Example:

{
    "state": [
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0x0f03542809143c7e5d3c22f56bc6e51eb2c8bab5009161b58f6f468432dfa196",
            "position": {
                "isLong": true,
                "quantity": "258.750000000000000000",
                "entry_price": "24.100496718773416725",
                "margin": "6777.476791762608353694",
                "cumulative_funding_entry": "0.050154448152800501"
            }
        },
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0x155576f660b3b6116c1ab7a42fbf58a95adf11b3061f88f81bc8df228e7ac934",
            "position": {
                "quantity": "0.000000642507772481",
                "entry_price": "2126.366900000000000000",
                "margin": "0.000698771862410178",
                "cumulative_funding_entry": "68.937815618854366506"
            }
        },
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            "position": {
                "isLong": true,
                "quantity": "4001.268237974374735585",
                "entry_price": "38.219387300439508994",
                "margin": "149511.194761579584705663",
                "cumulative_funding_entry": "1.164901749616683959"
            }
        },
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0x95698a9d8ba11660f44d7001d8c6fb191552ece5d9141a05c5d9128711cdc2e0",
            "position": {
                "quantity": "160.000000000000000000",
                "entry_price": "24.375243283322806983",
                "margin": "3762.387088377671867635",
                "cumulative_funding_entry": "0.741360126674168716"
            }
        },
        {
            "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
            "market_id": "0xf97a740538e10845e0c3db9ea94c6eaf8a570aeebe3e3511e2e387501a40e4bb",
            "position": {
                "isLong": true,
                "quantity": "110.000000000000000000",
                "entry_price": "22.516556291390728477",
                "margin": "2476.912251655629139073",
                "cumulative_funding_entry": "0.000000000000000000"
            }
        }
    ]
}
ParameterTypeDescription
stateDerivativePosition array


DerivativePosition

ParameterTypeDescription
subaccount_idstringthe subaccount ID
market_idstringthe market ID
positionPositionthe position details


Position

ParameterTypeDescription
isLongboolTrue if the position is long. False if the position is short.
quantitycosmossdk_io_math.LegacyDecThe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecThe entry price of the position (in human readable format)
margincosmossdk_io_math.LegacyDecThe margin of the position (in human readable format)
cumulative_funding_entrycosmossdk_io_math.LegacyDecThe cumulative funding

SubaccountPositionInMarket

Retrieves subaccount's position in market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    position = await client.fetch_chain_subaccount_position_in_market(
        subaccount_id=subaccount_id,
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(position)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainSubaccountPositionInMarket(ctx, subaccountId.Hex(), marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
market_idstringthe market IDYes

Response Parameters

Response Example:

{
    "state": {
        "isLong": true,
        "quantity": "4001.268237974374735585",
        "entry_price": "38.219387300439508994",
        "margin": "149511.194761579584705663",
        "cumulative_funding_entry": "1.164901749616683959"
    }
}
ParameterTypeDescription
statePosition


Position

ParameterTypeDescription
isLongboolTrue if the position is long. False if the position is short.
quantitycosmossdk_io_math.LegacyDecThe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecThe entry price of the position (in human readable format)
margincosmossdk_io_math.LegacyDecThe margin of the position (in human readable format)
cumulative_funding_entrycosmossdk_io_math.LegacyDecThe cumulative funding

SubaccountEffectivePositionInMarket

Retrieves subaccount's position in market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    position = await client.fetch_chain_subaccount_effective_position_in_market(
        subaccount_id=subaccount_id,
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(position)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    subaccountId := chainClient.Subaccount(senderAddress, 0)
    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainSubaccountEffectivePositionInMarket(ctx, subaccountId.Hex(), marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
market_idstringthe market IDYes

Response Parameters

Response Example:

{
    "state": {
        "is_long": true,
        "quantity": "4001.268237974374735585",
        "entry_price": "38.219387300439508994",
        "effective_margin": "52225.903642794329315064"
    }
}
ParameterTypeDescription
stateEffectivePosition


EffectivePosition

ParameterTypeDescription
is_longboolwhether the position is long or short
quantitycosmossdk_io_math.LegacyDecthe quantity of the position (in human readable format)
entry_pricecosmossdk_io_math.LegacyDecthe entry price of the position (in human readable format)
effective_margincosmossdk_io_math.LegacyDecthe effective margin of the position (in human readable format)

PerpetualMarketInfo

Retrieves perpetual market's info

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_info = await client.fetch_chain_perpetual_market_info(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(market_info)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainPerpetualMarketInfo(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:

{
   "info":{
      "marketId":"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
      "hourlyFundingRateCap":"625000000000000",
      "hourlyInterestRate":"4166660000000",
      "nextFundingTimestamp":"1709560800",
      "fundingInterval":"3600"
   }
}
ParameterTypeDescription
infoPerpetualMarketInfo


PerpetualMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
hourly_funding_rate_capcosmossdk_io_math.LegacyDechourly_funding_rate_cap defines the maximum absolute value of the hourly funding rate
hourly_interest_ratecosmossdk_io_math.LegacyDechourly_interest_rate defines the hourly interest rate
next_funding_timestampint64next_funding_timestamp defines the next funding timestamp in seconds of a perpetual market
funding_intervalint64funding_interval defines the next funding interval in seconds of a perpetual market.

ExpiryFuturesMarketInfo

Retrieves expiry market's info

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    market_info = await client.fetch_chain_expiry_futures_market_info(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(market_info)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainExpiryFuturesMarketInfo(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:


ParameterTypeDescription
infoExpiryFuturesMarketInfo


ExpiryFuturesMarketInfo

ParameterTypeDescription
market_idstringmarket ID.
expiration_timestampint64expiration_timestamp defines the expiration time for a time expiry futures market.
twap_start_timestampint64expiration_twap_start_timestamp defines the start time of the TWAP calculation window
expiration_twap_start_price_cumulativecosmossdk_io_math.LegacyDecexpiration_twap_start_price_cumulative defines the cumulative price for the start of the TWAP window (in human readable format)
settlement_pricecosmossdk_io_math.LegacyDecsettlement_price defines the settlement price for a time expiry futures market (in human readable format)

PerpetualMarketFunding

Retrieves perpetual market funding

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    funding = await client.fetch_chain_perpetual_market_funding(
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(funding)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    res, err := chainClient.FetchChainPerpetualMarketFunding(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringYes

Response Parameters

Response Example:

{
   "state":{
      "cumulativeFunding":"-43868182364823854683390",
      "cumulativePrice":"0",
      "lastTimestamp":"1709557200"
   }
}
ParameterTypeDescription
statePerpetualMarketFunding


PerpetualMarketFunding

ParameterTypeDescription
cumulative_fundingcosmossdk_io_math.LegacyDeccumulative_funding defines the cumulative funding of a perpetual market.
cumulative_pricecosmossdk_io_math.LegacyDeccumulative_price defines the running time-integral of the perp premium ((VWAP - mark_price) / mark_price) i.e., sum(premium * seconds) used to compute the interval’s average premium for funding
last_timestampint64the last funding timestamp in seconds

TraderDerivativeConditionalOrders

Retrieves a trader's derivative conditional orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_trader_derivative_conditional_orders(
        subaccount_id=subaccount_id,
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchTraderDerivativeConditionalOrders(ctx, subaccountId.Hex(), marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
subaccount_idstringthe subaccount IDYes
market_idstringthe market IDYes

Response Parameters

Response Example:

{
   "orders":[

   ]
}
ParameterTypeDescription
ordersTrimmedDerivativeConditionalOrder array


TrimmedDerivativeConditionalOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
margincosmossdk_io_math.LegacyDecmargin of the order (in human readable format)
triggerPricecosmossdk_io_math.LegacyDecprice to trigger the order (in human readable format)
isBuybooltrue if the order is a buy
isLimitbooltrue if the order is a limit order
order_hashstringthe order hash
cidstringthe client ID

MsgInstantPerpetualMarketLaunch

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_instant_perpetual_market_launch_v2(
        sender=address.to_acc_bech32(),
        ticker="INJ/USDC PERP",
        quote_denom="factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        oracle_base="INJ",
        oracle_quote="USDC",
        oracle_scale_factor=0,
        oracle_type="Band",
        maker_fee_rate=Decimal("-0.0001"),
        taker_fee_rate=Decimal("0.001"),
        initial_margin_ratio=Decimal("0.33"),
        maintenance_margin_ratio=Decimal("0.095"),
        reduce_margin_ratio=Decimal("3"),
        min_price_tick_size=Decimal("0.001"),
        min_quantity_tick_size=Decimal("0.01"),
        min_notional=Decimal("1"),
        open_notional_cap=composer.uncapped_open_notional_cap(),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    oracletypes "github.com/InjectiveLabs/sdk-go/chain/oracle/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.01")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.001")

    msg := &exchangev2types.MsgInstantPerpetualMarketLaunch{
        Sender:                 senderAddress.String(),
        Ticker:                 "INJ/USDC PERP",
        QuoteDenom:             "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        OracleBase:             "INJ",
        OracleQuote:            "USDC",
        OracleScaleFactor:      0,
        OracleType:             oracletypes.OracleType_Band,
        MakerFeeRate:           math.LegacyMustNewDecFromStr("-0.0001"),
        TakerFeeRate:           math.LegacyMustNewDecFromStr("0.001"),
        InitialMarginRatio:     math.LegacyMustNewDecFromStr("0.33"),
        MaintenanceMarginRatio: math.LegacyMustNewDecFromStr("0.095"),
        ReduceMarginRatio:      math.LegacyMustNewDecFromStr("0.3"),
        MinPriceTickSize:       minPriceTickSize,
        MinQuantityTickSize:    minQuantityTickSize,
        OpenNotionalCap: exchangev2types.OpenNotionalCap{
            Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)
    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
tickerstringTicker for the derivative market.Yes
quote_denomstringtype of coin to use as the base currencyYes
oracle_basestringOracle base currencyYes
oracle_quotestringOracle quote currencyYes
oracle_scale_factoruint32Scale factor for oracle prices.Yes
oracle_typetypes1.OracleTypeOracle typeYes
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the trade fee rate for makers on the perpetual marketYes
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the trade fee rate for takers on the perpetual marketYes
initial_margin_ratiocosmossdk_io_math.LegacyDecinitial_margin_ratio defines the initial margin ratio for the perpetual marketYes
maintenance_margin_ratiocosmossdk_io_math.LegacyDecmaintenance_margin_ratio defines the maintenance margin ratio for the perpetual marketYes
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size of the order's price and margin (in human readable format)Yes
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the order's quantity (in human readable format)Yes
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)Yes
reduce_margin_ratiocosmossdk_io_math.LegacyDecreduce_margin_ratio defines the ratio of the margin that is reducedYes
open_notional_capOpenNotionalCapopen_notional_cap defines the cap on the open notionalYes


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgInstantExpiryFuturesMarketLaunch

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_instant_expiry_futures_market_launch_v2(
        sender=address.to_acc_bech32(),
        ticker="INJ/USDC FUT",
        quote_denom="factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        oracle_base="INJ",
        oracle_quote="USDC",
        oracle_scale_factor=0,
        oracle_type="Band",
        expiry=2000000000,
        maker_fee_rate=Decimal("-0.0001"),
        taker_fee_rate=Decimal("0.001"),
        initial_margin_ratio=Decimal("0.33"),
        maintenance_margin_ratio=Decimal("0.095"),
        min_price_tick_size=Decimal("0.001"),
        min_quantity_tick_size=Decimal("0.01"),
        min_notional=Decimal("1"),
        open_notional_cap=composer.uncapped_open_notional_cap(),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    oracletypes "github.com/InjectiveLabs/sdk-go/chain/oracle/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.01")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.001")

    msg := &exchangev2types.MsgInstantExpiryFuturesMarketLaunch{
        Sender:                 senderAddress.String(),
        Ticker:                 "INJ/USDC FUT",
        QuoteDenom:             "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        OracleBase:             "INJ",
        OracleQuote:            "USDC",
        OracleScaleFactor:      0,
        OracleType:             oracletypes.OracleType_Band,
        Expiry:                 2000000000,
        MakerFeeRate:           math.LegacyMustNewDecFromStr("-0.0001"),
        TakerFeeRate:           math.LegacyMustNewDecFromStr("0.001"),
        InitialMarginRatio:     math.LegacyMustNewDecFromStr("0.33"),
        MaintenanceMarginRatio: math.LegacyMustNewDecFromStr("0.095"),
        ReduceMarginRatio:      math.LegacyMustNewDecFromStr("0.3"),
        MinPriceTickSize:       minPriceTickSize,
        MinQuantityTickSize:    minQuantityTickSize,
        OpenNotionalCap: exchangev2types.OpenNotionalCap{
            Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
tickerstringTicker for the derivative market.Yes
quote_denomstringtype of coin to use as the quote currencyYes
oracle_basestringOracle base currencyYes
oracle_quotestringOracle quote currencyYes
oracle_typetypes1.OracleTypeOracle typeYes
oracle_scale_factoruint32Scale factor for oracle prices.Yes
expiryint64Expiration time of the marketYes
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the trade fee rate for makers on the expiry futures marketYes
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the trade fee rate for takers on the expiry futures marketYes
initial_margin_ratiocosmossdk_io_math.LegacyDecinitial_margin_ratio defines the initial margin ratio for the derivative marketYes
maintenance_margin_ratiocosmossdk_io_math.LegacyDecmaintenance_margin_ratio defines the maintenance margin ratio for the derivative marketYes
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size of the order's price and marginYes
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the order's quantityYes
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the marketYes
reduce_margin_ratiocosmossdk_io_math.LegacyDecreduce_margin_ratio defines the ratio of the margin that is reducedYes
open_notional_capOpenNotionalCapopen_notional_cap defines the cap on the open notionalYes


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateDerivativeLimitOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.msg_create_derivative_limit_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal(50000),
        quantity=Decimal(0.1),
        margin=composer.calculate_margin(
            quantity=Decimal(0.1), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False
        ),
        order_type="SELL",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    amount := decimal.NewFromFloat(0.001)
    price := decimal.RequireFromString("31000") //31,000
    leverage := decimal.RequireFromString("2.5")

    order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     amount,
            Price:        price,
            Leverage:     leverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
            IsReduceOnly: true,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgCreateDerivativeLimitOrder{
        Sender: senderAddress.String(),
        Order:  *order,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderDerivativeOrderthe order detailsYes


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0x224e7312eb28955507142e9f761c5ba90165e05688583bffe9281dbe8f3e3083"
]
---Transaction Response---
txhash: "34138C7F4EB05EEBFC7AD81CE187BE13BF12348CB7973388007BE7505F257B14"
raw_log: "[]"

gas wanted: 124365
gas fee: 0.0000621825 INJ
simulated order hash 0x25233ede1fee09310d549241647edcf94cf5378749593b55c27148a80ce655c1
DEBU[0001] broadcastTx with nonce 3495                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5213085  fn=func1 src="client/chain/chain.go:619" txHash=47644A4BD75A97BF4B0D436821F564976C60C272DD25F966DA88216C2229A32A
DEBU[0003] nonce incremented to 3496                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  171439                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000857195 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateDerivativeMarketOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.msg_create_derivative_market_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal(50000),
        quantity=Decimal(0.1),
        margin=composer.calculate_margin(
            quantity=Decimal(0.1), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False
        ),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    amount := decimal.NewFromFloat(0.01)
    price := decimal.RequireFromString("33000") //33,000
    leverage := decimal.RequireFromString("2.5")

    order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_SELL), //BUY SELL
            Quantity:     amount,
            Price:        price,
            Leverage:     leverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
            IsReduceOnly: true,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgCreateDerivativeMarketOrder{
        Sender: senderAddress.String(),
        Order:  *order,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderDerivativeOrderthe order detailsYes


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0xcd0e33273d3a5688ef35cf3d857bd37df4a6b7a0698fdc46d77bbaeb79ffbbe4"
]
---Transaction Response---
txhash: "A4B30567DE6AB33F076858B6ED99BE757C084A2A217CEC98054DCEA5B8A0875D"
raw_log: "[]"

gas wanted: 110924
gas fee: 0.000055462 INJ
simulated order hash 0x2df7d24f919f833138b50f0b01ac200ec2e7bdc679fb144d152487fc23d6cfd0
DEBU[0001] broadcastTx with nonce 3496                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5213175  fn=func1 src="client/chain/chain.go:619" txHash=613A5264D460E9AA34ADD89987994A15A9AE5BF62BA8FFD53E3AA490F5AE0A6E
DEBU[0003] nonce incremented to 3497                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  139962                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000069981 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCancelDerivativeOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    order_hash = "0x667ee6f37f6d06bf473f4e1434e92ac98ff43c785405e2a511a0843daeca2de9"

    # prepare tx msg
    msg = composer.msg_cancel_derivative_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        order_hash=order_hash,
        is_buy=True,
        is_market_order=False,
        is_conditional=False,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgCancelDerivativeOrder{
        Sender:       senderAddress.String(),
        MarketId:     "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
        SubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        OrderHash:    "0x8cf97e586c0d84cd7864ccc8916b886557120d84fc97a21ae193b67882835ec5",
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
market_idstringthe market IDYes
subaccount_idstringthe subaccount IDYes
order_hashstringthe order hash (optional)No
order_maskint32the order mask (bitwise combination of OrderMask enum values) (optional)No
cidstringthe client order ID (optional)No


OrderMask

CodeName
0UNUSED
1ANY
2REGULAR
4CONDITIONAL
8DIRECTION_BUY_OR_HIGHER
16DIRECTION_SELL_OR_LOWER
32TYPE_MARKET
64TYPE_LIMIT

Response Parameters

Response Example:

---Simulation Response---
[success: true
success: false
]
---Transaction Response---
txhash: "862F4ABD2A75BD15B9BCEDB914653743F11CDB19583FB9018EB5A78B8D4ED264"
raw_log: "[]"

gas wanted: 118158
gas fee: 0.000059079 INJ
DEBU[0001] broadcastTx with nonce 3497                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5213261  fn=func1 src="client/chain/chain.go:619" txHash=71016DBB5723031C8DBF6B05A498DE5390BC91FE226E23E3F70497B584E6EB3B
DEBU[0003] nonce incremented to 3498                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  141373                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000706865 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgBatchUpdateOrders

MsgBatchUpdateOrders allows for the atomic cancellation and creation of spot and derivative limit orders, along with a new order cancellation mode. Upon execution, order cancellations (if any) occur first, followed by order creations (if any).

Users can cancel all limit orders in a given spot or derivative market for a given subaccountID by specifying the associated marketID in the SpotMarketIdsToCancelAll and DerivativeMarketIdsToCancelAll. Users can also cancel individual limit orders in SpotOrdersToCancel or DerivativeOrdersToCancel, but must ensure that marketIDs in these individual order cancellations are not already provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll.

Further note that if no marketIDs are provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll, then the SubaccountID in the Msg should be left empty.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    derivative_market_id_create = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    derivative_market_id_cancel = "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff"
    derivative_market_id_cancel_2 = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_cancel = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    spot_market_id_cancel_2 = "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0"

    derivative_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel,
            subaccount_id=subaccount_id,
            order_hash="0x48690013c382d5dbaff9989db04629a16a5818d7524e027d517ccc89fd068103",
        ),
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5",
        ),
    ]

    spot_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel,
            subaccount_id=subaccount_id,
            cid="0e5c3ad5-2cc4-4a2a-bbe5-b12697739163",
        ),
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2",
        ),
    ]

    derivative_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25000),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(50000),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_market_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25100),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25100), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3"),
            quantity=Decimal("55"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("300"),
            quantity=Decimal("55"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_market_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3.5"),
            quantity=Decimal("1"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    msg = composer.msg_batch_update_orders(
        sender=address.to_acc_bech32(),
        derivative_orders_to_create=derivative_orders_to_create,
        spot_orders_to_create=spot_orders_to_create,
        derivative_orders_to_cancel=derivative_orders_to_cancel,
        spot_orders_to_cancel=spot_orders_to_cancel,
        spot_market_orders_to_create=spot_market_orders_to_create,
        derivative_market_orders_to_create=derivative_market_orders_to_create,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    smarketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"
    samount := decimal.NewFromFloat(2)
    sprice := decimal.NewFromFloat(22.5)
    smarketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}

    spot_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     samount,
            Price:        sprice,
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    spot_market_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.1),
            Price:        decimal.NewFromFloat(22),
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    dmarketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    damount := decimal.NewFromFloat(0.01)
    dprice := decimal.RequireFromString("31000") //31,000
    dleverage := decimal.RequireFromString("2")
    dmarketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}

    derivative_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     damount,
            Price:        dprice,
            Leverage:     dleverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    derivative_market_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.01),
            Price:        decimal.RequireFromString("33000"),
            Leverage:     decimal.RequireFromString("2"),
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgBatchUpdateOrders{
        Sender:                         senderAddress.String(),
        SubaccountId:                   defaultSubaccountID.Hex(),
        SpotOrdersToCreate:             []*exchangev2types.SpotOrder{spot_order},
        DerivativeOrdersToCreate:       []*exchangev2types.DerivativeOrder{derivative_order},
        SpotMarketIdsToCancelAll:       smarketIds,
        DerivativeMarketIdsToCancelAll: dmarketIds,
        SpotMarketOrdersToCreate:       []*exchangev2types.SpotOrder{spot_market_order},
        DerivativeMarketOrdersToCreate: []*exchangev2types.DerivativeOrder{derivative_market_order},
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstringsubaccount_id only used for the spot_market_ids_to_cancel_all and derivative_market_ids_to_cancel_all (optional)No
spot_market_ids_to_cancel_allstring arraythe market IDs to cancel all spot orders for (optional)No
derivative_market_ids_to_cancel_allstring arraythe market IDs to cancel all derivative orders for (optional)No
spot_orders_to_cancelOrderData arraythe spot orders to cancelNo
derivative_orders_to_cancelOrderData arraythe derivative orders to cancelNo
spot_orders_to_createSpotOrder arraythe spot orders to createNo
derivative_orders_to_createDerivativeOrder arraythe derivative orders to createNo
binary_options_orders_to_cancelOrderData arraythe binary options orders to cancelNo
binary_options_market_ids_to_cancel_allstring arraythe market IDs to cancel all binary options orders for (optional)No
binary_options_orders_to_createDerivativeOrder arraythe binary options orders to createNo
spot_market_orders_to_createSpotOrder arraythe spot market orders to createNo
derivative_market_orders_to_createDerivativeOrder arraythe derivative market orders to createNo
binary_options_market_orders_to_createDerivativeOrder arraythe binary options market orders to createNo


OrderData

ParameterTypeDescription
market_idstringthe market ID
subaccount_idstringthe subaccount ID
order_hashstringthe order hash (optional - either the order_hash or the cid should be provided)
order_maskint32the order mask (bitwise combination of OrderMask enum values)
cidstringthe client order ID (optional - either the order_hash or the cid should be provided)


SpotOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderMask

CodeName
0UNUSED
1ANY
2REGULAR
4CONDITIONAL
8DIRECTION_BUY_OR_HIGHER
16DIRECTION_SELL_OR_LOWER
32TYPE_MARKET
64TYPE_LIMIT


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[spot_cancel_success: false
spot_cancel_success: false
derivative_cancel_success: false
derivative_cancel_success: false
spot_order_hashes: "0x3f5b5de6ec72b250c58e0a83408dbc1990cee369999036e3469e19b80fa9002e"
spot_order_hashes: "0x7d8580354e120b038967a180f73bc3aba0f49db9b6d2cb5c4cec85e8cab3e218"
derivative_order_hashes: "0x920a4ea4144c46d1e1084ca5807e4f5608639ce00f97139d5b44e628d487e15e"
derivative_order_hashes: "0x11d75d0c2ce8a07f352523be2e3456212c623397d0fc1a2f688b97a15c04372c"
]
---Transaction Response---
txhash: "4E29226884DCA22E127471588F39E0BB03D314E1AA27ECD810D24C4078D52DED"
raw_log: "[]"

gas wanted: 271213
gas fee: 0.0001356065 INJ
simulated spot order hashes [0xd9f30c7e700202615c2775d630b9fb276572d883fa480b6394abbddcb79c8109]
simulated derivative order hashes [0xb2bea3b15c204699a9ee945ca49650001560518d1e54266adac580aa061fedd4]
DEBU[0001] broadcastTx with nonce 3507                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214679  fn=func1 src="client/chain/chain.go:619" txHash=CF53E0B31B9E28E0D6D8F763ECEC2D91E38481321EA24AC86F6A8774C658AF44
DEBU[0003] nonce incremented to 3508                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  659092                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000329546 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgLiquidatePosition

This message is sent to the chain when a particular position has reached the liquidation price, to liquidate that position.

To detect the liquidable positions please use the Indexer endpoint called LiquidablePositions

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    cid = str(uuid.uuid4())

    order = composer.derivative_order(
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal(39.01),  # This should be the liquidation price
        quantity=Decimal(0.147),
        margin=composer.calculate_margin(
            quantity=Decimal(0.147), price=Decimal(39.01), leverage=Decimal(1), is_reduce_only=False
        ),
        order_type="SELL",
        cid=cid,
    )

    # prepare tx msg
    msg = composer.msg_liquidate_position(
        sender=address.to_acc_bech32(),
        subaccount_id="0x156df4d5bc8e7dd9191433e54bd6a11eeb390921000000000000000000000000",
        market_id=market_id,
        order=order,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    amount := decimal.NewFromFloat(0.147)
    price := decimal.RequireFromString("39.01")
    leverage := decimal.RequireFromString("1")

    order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_SELL),
            Quantity:     amount,
            Price:        price,
            Leverage:     leverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
            Cid:          uuid.NewString(),
        },
    )

    msg := &exchangev2types.MsgLiquidatePosition{
        Sender:       senderAddress.String(),
        SubaccountId: "0x156df4d5bc8e7dd9191433e54bd6a11eeb390921000000000000000000000000",
        MarketId:     marketId,
        Order:        order,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstringthe subaccount ID the position belongs toYes
market_idstringthe position's market IDYes
orderDerivativeOrderoptional order to provide for liquidationNo


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgIncreasePositionMargin

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    # prepare tx msg
    msg = composer.msg_increase_position_margin(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        source_subaccount_id=subaccount_id,
        destination_subaccount_id=subaccount_id,
        amount=Decimal(2),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgIncreasePositionMargin{
        Sender:                  senderAddress.String(),
        MarketId:                "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
        SourceSubaccountId:      "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        DestinationSubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        Amount:                  math.LegacyMustNewDecFromStr("100000000"), //100 USDT
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
source_subaccount_idstringthe subaccount ID sending the fundsYes
destination_subaccount_idstringthe subaccount ID the position belongs toYes
market_idstringthe market IDYes
amountcosmossdk_io_math.LegacyDecamount defines the amount of margin to add to the position (in human readable format)Yes

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgDecreasePositionMargin

Message to reduce the margin assigned to a particular position

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"

    # prepare tx msg
    msg = composer.msg_decrease_position_margin(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        source_subaccount_id=subaccount_id,
        destination_subaccount_id=subaccount_id,
        amount=Decimal(2),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    msg := &exchangev2types.MsgDecreasePositionMargin{
        Sender:                  senderAddress.String(),
        MarketId:                "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        SourceSubaccountId:      defaultSubaccountID.String(),
        DestinationSubaccountId: defaultSubaccountID.String(),
        Amount:                  math.LegacyMustNewDecFromStr("100000000"), //100 USDT
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
source_subaccount_idstringthe subaccount ID the position belongs toYes
destination_subaccount_idstringthe destination subaccount IDYes
market_idstringthe market IDYes
amountcosmossdk_io_math.LegacyDecamount defines the amount of margin to withdraw from the position (in human readable format)Yes

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgUpdateDerivativeMarket

Modifies certain market fields. It can only be sent by the market's admin.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_update_derivative_market(
        admin=address.to_acc_bech32(),
        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        new_ticker="INJ/USDT PERP 2",
        new_min_price_tick_size=Decimal("1"),
        new_min_quantity_tick_size=Decimal("1"),
        new_min_notional=Decimal("2"),
        new_initial_margin_ratio=Decimal("0.40"),
        new_maintenance_margin_ratio=Decimal("0.085"),
        new_reduce_margin_ratio=Decimal("3.5"),
        new_open_notional_cap=composer.uncapped_open_notional_cap(),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.1")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.1")
    minNotional := math.LegacyMustNewDecFromStr("2")

    msg := &exchangev2types.MsgUpdateDerivativeMarket{
        Admin:                     senderAddress.String(),
        MarketId:                  "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
        NewTicker:                 "INJ/USDT PERP 2",
        NewMinPriceTickSize:       minPriceTickSize,
        NewMinQuantityTickSize:    minQuantityTickSize,
        NewMinNotional:            minNotional,
        NewInitialMarginRatio:     math.LegacyMustNewDecFromStr("0.4"),
        NewMaintenanceMarginRatio: math.LegacyMustNewDecFromStr("0.085"),
        NewReduceMarginRatio:      math.LegacyMustNewDecFromStr("0.3"),
        NewOpenNotionalCap: exchangev2types.OpenNotionalCap{
            Cap: &exchangev2types.OpenNotionalCap_Capped{
                Capped: &exchangev2types.OpenNotionalCapCapped{
                    Value: math.LegacyMustNewDecFromStr("1000"),
                },
            },
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
adminstringcurrent admin address of the associated marketYes
market_idstringid of the market to be updatedYes
new_tickerstring(optional) updated value for tickerNo
new_min_price_tick_sizecosmossdk_io_math.LegacyDec(optional) updated value for min_price_tick_size (in human readable format)No
new_min_quantity_tick_sizecosmossdk_io_math.LegacyDec(optional) updated value min_quantity_tick_size (in human readable format)No
new_min_notionalcosmossdk_io_math.LegacyDec(optional) updated min notional (in human readable format)No
new_initial_margin_ratiocosmossdk_io_math.LegacyDec(optional) updated value for initial_margin_ratioNo
new_maintenance_margin_ratiocosmossdk_io_math.LegacyDec(optional) updated value for maintenance_margin_ratioNo
new_reduce_margin_ratiocosmossdk_io_math.LegacyDec(optional) updated value for reduce_margin_ratioNo
new_open_notional_capOpenNotionalCap(optional) updated value for open_notional_capNo


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

LocalOrderHashComputation

This function computes order hashes locally for SpotOrder and DerivativeOrder. For more information, see the note below.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.constant import GAS_FEE_BUFFER_AMOUNT
from pyinjective.core.network import Network
from pyinjective.orderhash import OrderHashManager
from pyinjective.transaction import Transaction
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())
    subaccount_id = address.get_subaccount_id(index=0)
    subaccount_id_2 = address.get_subaccount_id(index=1)

    order_hash_manager = OrderHashManager(address=address, network=network, subaccount_indexes=[0, 1, 2, 7])

    # prepare trade info
    spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    deriv_market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    spot_orders = [
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("0.524"),
            quantity=Decimal("0.01"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("27.92"),
            quantity=Decimal("0.01"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_orders = [
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(10500),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(10500), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(65111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(65111), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders)

    deriv_msg = composer.msg_batch_create_derivative_limit_orders(
        sender=address.to_acc_bech32(), orders=derivative_orders
    )

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=0
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 1
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=0
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 2
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

    spot_orders = [
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal("1.524"),
            quantity=Decimal("0.01"),
            order_type="BUY_PO",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal("27.92"),
            quantity=Decimal("0.01"),
            order_type="SELL_PO",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_orders = [
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal(25111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal("1.5"), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal(65111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders)

    deriv_msg = composer.msg_batch_create_derivative_limit_orders(
        sender=address.to_acc_bech32(), orders=derivative_orders
    )

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=1
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 3
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )
    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    // prepare tx msg
    defaultSubaccountID := chainClient.Subaccount(senderAddress, 1)

    spotOrder := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY),
            Quantity:     decimal.NewFromFloat(2),
            Price:        decimal.NewFromFloat(22.55),
            FeeRecipient: senderAddress.String(),
            MarketId:     "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            Cid:          uuid.NewString(),
        },
    )

    derivativeOrder := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY),
            Quantity:     decimal.NewFromFloat(2),
            Price:        decimal.RequireFromString("31"),
            Leverage:     decimal.RequireFromString("2.5"),
            FeeRecipient: senderAddress.String(),
            MarketId:     "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgBatchCreateSpotLimitOrders{
        Sender: senderAddress.String(),
        Orders: []exchangev2types.SpotOrder{*spotOrder},
    }

    msg1 := exchangev2types.MsgBatchCreateDerivativeLimitOrders{
        Sender: senderAddress.String(),
        Orders: []exchangev2types.DerivativeOrder{*derivativeOrder},
    }

    // compute local order hashes
    orderHashes, err := chainClient.ComputeOrderHashes(msg.Orders, msg1.Orders, defaultSubaccountID)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("computed spot order hashes: ", orderHashes.Spot)
    fmt.Println("computed derivative order hashes: ", orderHashes.Derivative)

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg, &msg1)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}

Response Parameters

Response Example:

computed spot order hashes ['0xa2d59cca00bade680a552f02deeb43464df21c73649191d64c6436313b311cba', '0xab78219e6c494373262a310d73660198c7a4c91196c0f6bb8808c81d8fb54a11']
computed derivative order hashes ['0x38d432c011f4a62c6b109615718b26332e7400a86f5e6f44e74a8833b7eed992', '0x66a921d83e6931513df9076c91a920e5e943837e2b836ad370b5cf53a1ed742c']
txhash: "604757CD9024FFF2DDCFEED6FC070E435AC09A829DB2E81AD4AD65B33E987A8B"
raw_log: "[]"

gas wanted: 196604
gas fee: 0.000098302 INJ
computed spot order hashes:  [0x0103ca50d0d033e6b8528acf28a3beb3fd8bac20949fc1ba60a2da06c53ad94f]
computed derivative order hashes:  [0x15334a7a0f1c2f98b9369f79b9a62a1f357d3e63b46a8895a4cec0ca375ddbbb 0xc26c8f74f56eade275e518f73597dd8954041bfbae3951ed4d7efeb0d060edbd]
DEBU[0001] broadcastTx with nonce 3488                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5212331  fn=func1 src="client/chain/chain.go:619" txHash=19D8D81BB1DF59889E00EAA600A01079BA719F00A4A43CCC1B56580A1BBD6455
DEBU[0003] nonce incremented to 3489                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  271044                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000135522 INJ

Note on LocalOrderHashComputation for HFTs/API Traders

LocalOrderHashComputation returns a locally computed transaction hash for spot and derivative orders, which is useful when the user needs the transaction hash faster than orders can be streamed through StreamOrdersHistory (there is extra latency since the order must be included by a block, and the block must be indexed by the Indexer). While the hash can also be obtained through transaction simulation, the process adds a layer of latency and can only be used for one transaction per block (simulation relies on a nonce based on the state machine which does not change until the transaction is included in a block).

On Injective, subaccount nonces are used to calculate order hashes. The subaccount nonce is incremented with each order so that order hashes remain unique.

For strategies employing high frequency trading, order hashes should be calculated locally before transactions are broadcasted. This is possible as long as the subaccount nonce is cached/tracked locally instead of queried from the chain. Similarly, the account sequence (like nonce on Ethereum) should be cached if more than one transaction per block is desired. The LocalOrderHashComputation implementation can be found here. Refer to the above API example for usage.

There are two caveats to be mindful of when taking this approach:

1. Gas must be manually calculated instead of fetched from simulation

  class GasLimitConstant:
      base = 65e3
      extra = 20e3
      derivative_order = 45e3
      derivative_cancel = 55e3

2. In the event a transaction fails, the account sequence and subaccount nonce must both be refreshed

  res = await self.client.broadcast_tx_sync_mode(tx_raw_bytes)
  if res.code == 32:
      await client.fetch_account(address.to_acc_bech32())

- Chain Exchange for Spot

Includes all messages related to spot markets.

L3SpotOrderBook

Get the level 3 aggregated order book for a spot market

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    orderbook = await client.fetch_l3_spot_orderbook(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
    )
    print(orderbook)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchL3SpotOrderbook(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringmarket idYes

Response Parameters

Response Example:

ParameterTypeDescription
BidsTrimmedLimitOrder array
AsksTrimmedLimitOrder array
sequint64the current orderbook sequence number


TrimmedLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
order_hashstringthe order hash
subaccount_idstringthe subaccount ID

SpotMarkets

Retrieves a list of spot markets

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    spot_markets = await client.fetch_chain_spot_markets(
        status="Active",
        market_ids=["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"],
    )
    print(spot_markets)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    status := "Active"
    marketIds := []string{"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"}

    res, err := chainClient.FetchChainSpotMarkets(ctx, status, marketIds)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
statusstringStatus of the market, for convenience it is set to string - not enumYes
market_idsstring arrayFilter by market IDsYes

Response Parameters

Response Example:

{
    "markets": [
        {
            "ticker": "INJ/USDT",
            "base_denom": "inj",
            "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "maker_fee_rate": "-0.000100000000000000",
            "taker_fee_rate": "0.000500000000000000",
            "relayer_fee_share_rate": "0.400000000000000000",
            "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            "status": 1,
            "min_price_tick_size": "0.001000000000000000",
            "min_quantity_tick_size": "0.001000000000000000",
            "min_notional": "0.000000000001000000",
            "base_decimals": 18,
            "quote_decimals": 6
        }
    ]
}
ParameterTypeDescription
marketsSpotMarket array


SpotMarket

ParameterTypeDescription
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset
quote_denomstringCoin used for the quote asset
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the fee percentage makers pay when trading
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the fee percentage takers pay when trading
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
market_idstringUnique market ID.
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
base_decimalsuint32base token decimals
quote_decimalsuint32quote token decimals


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

SpotMarket

Retrieves a spot market by ticker

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    spot_market = await client.fetch_chain_spot_market(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
    )
    print(spot_market)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchChainSpotMarket(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes

Response Parameters

Response Example:

{
    "market": {
        "ticker": "INJ/USDT",
        "base_denom": "inj",
        "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
        "maker_fee_rate": "-0.000100000000000000",
        "taker_fee_rate": "0.000500000000000000",
        "relayer_fee_share_rate": "0.400000000000000000",
        "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        "status": 1,
        "min_price_tick_size": "0.001000000000000000",
        "min_quantity_tick_size": "0.001000000000000000",
        "min_notional": "0.000000000001000000",
        "base_decimals": 18,
        "quote_decimals": 6
    }
}
ParameterTypeDescription
marketSpotMarket


SpotMarket

ParameterTypeDescription
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset
quote_denomstringCoin used for the quote asset
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the fee percentage makers pay when trading
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the fee percentage takers pay when trading
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
market_idstringUnique market ID.
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
base_decimalsuint32base token decimals
quote_decimalsuint32quote token decimals


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

FullSpotMarkets

Retrieves a list of spot markets with extra information

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    spot_markets = await client.fetch_chain_full_spot_markets(
        status="Active",
        market_ids=["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"],
        with_mid_price_and_tob=True,
    )
    print(spot_markets)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    status := "Active"
    marketIds := []string{"0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"}
    withMidPriceAndTob := true

    res, err := chainClient.FetchChainFullSpotMarkets(ctx, status, marketIds, withMidPriceAndTob)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
statusstringStatus of the market, for convenience it is set to string - not enumYes
market_idsstring arrayFilter by market IDsYes
with_mid_price_and_tobboolFlag to return the markets mid price and top of the book buy and sell orders.Yes

Response Parameters

Response Example:

{
    "markets": [
        {
            "market": {
                "ticker": "INJ/USDT",
                "base_denom": "inj",
                "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
                "maker_fee_rate": "-0.000100000000000000",
                "taker_fee_rate": "0.000500000000000000",
                "relayer_fee_share_rate": "0.400000000000000000",
                "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
                "status": 1,
                "min_price_tick_size": "0.001000000000000000",
                "min_quantity_tick_size": "0.001000000000000000",
                "min_notional": "0.000000000001000000",
                "base_decimals": 18,
                "quote_decimals": 6
            },
            "mid_price_and_tob": {
                "mid_price": "29.433500000000000000",
                "best_buy_price": "29.414000000000000000",
                "best_sell_price": "29.453000000000000000"
            }
        }
    ]
}
ParameterTypeDescription
marketsFullSpotMarket array


FullSpotMarket

ParameterTypeDescription
marketSpotMarketspot market details
mid_price_and_tobMidPriceAndTOBmid_price_and_tob defines the mid price for this market and the best ask and bid orders


SpotMarket

ParameterTypeDescription
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset
quote_denomstringCoin used for the quote asset
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the fee percentage makers pay when trading
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the fee percentage takers pay when trading
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
market_idstringUnique market ID.
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
base_decimalsuint32base token decimals
quote_decimalsuint32quote token decimals


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


MidPriceAndTOB

ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market (in human readable format)
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market (in human readable format)
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market (in human readable format)


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

FullSpotMarket

Retrieves a spot market with extra information

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    spot_market = await client.fetch_chain_full_spot_market(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        with_mid_price_and_tob=True,
    )
    print(spot_market)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    withMidPriceAndTob := true

    res, err := chainClient.FetchChainFullSpotMarket(ctx, marketId, withMidPriceAndTob)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
with_mid_price_and_tobboolFlag to return the markets mid price and top of the book buy and sell orders.Yes

Response Parameters

Response Example:

{
    "market": {
        "market": {
            "ticker": "INJ/USDT",
            "base_denom": "inj",
            "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "maker_fee_rate": "-0.000100000000000000",
            "taker_fee_rate": "0.000500000000000000",
            "relayer_fee_share_rate": "0.400000000000000000",
            "market_id": "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            "status": 1,
            "min_price_tick_size": "0.001000000000000000",
            "min_quantity_tick_size": "0.001000000000000000",
            "min_notional": "0.000000000001000000",
            "base_decimals": 18,
            "quote_decimals": 6
        },
        "mid_price_and_tob": {
            "mid_price": "29.433500000000000000",
            "best_buy_price": "29.414000000000000000",
            "best_sell_price": "29.453000000000000000"
        }
    }
}
ParameterTypeDescription
marketFullSpotMarket


FullSpotMarket

ParameterTypeDescription
marketSpotMarketspot market details
mid_price_and_tobMidPriceAndTOBmid_price_and_tob defines the mid price for this market and the best ask and bid orders


SpotMarket

ParameterTypeDescription
tickerstringA name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset.
base_denomstringCoin denom used for the base asset
quote_denomstringCoin used for the quote asset
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the fee percentage makers pay when trading
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the fee percentage takers pay when trading
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
market_idstringUnique market ID.
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
adminstringcurrent market admin
admin_permissionsuint32level of admin permissions
base_decimalsuint32base token decimals
quote_decimalsuint32quote token decimals


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired


MidPriceAndTOB

ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market (in human readable format)
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market (in human readable format)
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market (in human readable format)


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission

SpotOrderBook

Retrieves a spot market's orderbook by marketID

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    pagination = PaginationOption(limit=2)

    orderbook = await client.fetch_chain_spot_orderbook(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        order_side="Buy",
        pagination=pagination,
    )
    print(orderbook)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    v2 "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    limit := uint64(2)
    orderSide := v2.OrderSide_Buy
    limitCumulativeNotional := math.LegacyDec{}
    limitCumulativeQuantity := math.LegacyDec{}

    res, err := chainClient.FetchChainSpotOrderbook(ctx, marketId, limit, orderSide, limitCumulativeNotional, limitCumulativeQuantity)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
limituint64the maximum number of orderbook entries to return per side (optional)No
order_sideOrderSidethe order side to return the orderbook entries for (optional)No
limit_cumulative_notionalcosmossdk_io_math.LegacyDeclimits the number of entries to return per side based on the cumulative notional (in human readable format)No
limit_cumulative_quantitycosmossdk_io_math.LegacyDeclimits the number of entries to return per side based on the cumulative quantity (in human readable format)No


OrderSide

CodeName
0Side_Unspecified
1Buy
2Sell

Response Parameters

Response Example:

{
    "buysPriceLevel": [
        {
            "p": "29.414",
            "q": "27.651"
        },
        {
            "p": "29.394",
            "q": "27.714"
        }
    ],
    "sellsPriceLevel": []
}
ParameterTypeDescription
buys_price_levelLevel array
sells_price_levelLevel array
sequint64the current orderbook sequence number


Level

ParameterTypeDescription
pcosmossdk_io_math.LegacyDecprice (in human readable format)
qcosmossdk_io_math.LegacyDecquantity (in human readable format)

TraderSpotOrders

Retrieves a trader's spot orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_trader_spot_orders(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        subaccount_id=subaccount_id,
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainTraderSpotOrders(ctx, marketId, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes

Response Parameters

Response Example:

{
    "orders": [
        {
            "price": "21.000000000000000000",
            "quantity": "2.000000000000000000",
            "fillable": "2.000000000000000000",
            "isBuy": true,
            "order_hash": "0x4a547afd5fbe957223afdce1eef3a11a3e09be114310323b510dcc79dc18aca7"
        }
    ]
}
ParameterTypeDescription
ordersTrimmedSpotLimitOrder array


TrimmedSpotLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

AccountAddressSpotOrders

Retrieves all account address spot orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    orders = await client.fetch_chain_account_address_spot_orders(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        account_address=address.to_acc_bech32(),
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchChainAccountAddressSpotOrders(ctx, marketId, senderAddress.String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
account_addressstringAccount address of the traderYes

Response Parameters

Response Example:

{
    "orders": [
        {
            "price": "21.000000000000000000",
            "quantity": "2.000000000000000000",
            "fillable": "2.000000000000000000",
            "isBuy": true,
            "order_hash": "0x4a547afd5fbe957223afdce1eef3a11a3e09be114310323b510dcc79dc18aca7"
        }
    ]
}
ParameterTypeDescription
ordersTrimmedSpotLimitOrder array


TrimmedSpotLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

SpotOrdersByHashes

Retrieves spot orders corresponding to specified order hashes for a given subaccount ID and market ID

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_spot_orders_by_hashes(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        subaccount_id=subaccount_id,
        order_hashes=["0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"],
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := chainClient.Subaccount(senderAddress, 0)
    orderHashes := []string{"0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"}

    res, err := chainClient.FetchChainSpotOrdersByHashes(ctx, marketId, subaccountId.Hex(), orderHashes)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes
order_hashesstring arraythe order hashesYes

Response Parameters

Response Example:

{
    "orders": [
        {
            "price": "21.000000000000000000",
            "quantity": "2.000000000000000000",
            "fillable": "2.000000000000000000",
            "isBuy": true,
            "order_hash": "0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"
        }
    ]
}
ParameterTypeDescription
ordersTrimmedSpotLimitOrder array


TrimmedSpotLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

TraderSpotTransientOrders

Retrieves a trader's transient spot orders

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    subaccount_id = address.get_subaccount_id(index=0)

    orders = await client.fetch_chain_trader_spot_transient_orders(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
        subaccount_id=subaccount_id,
    )
    print(orders)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    subaccountId := chainClient.Subaccount(senderAddress, 0)

    res, err := chainClient.FetchChainTraderSpotTransientOrders(ctx, marketId, subaccountId.Hex())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes
subaccount_idstringSubaccountID of the traderYes

Response Parameters

Response Example:

{
    "orders": [
        {
            "price": "21.000000000000000000",
            "quantity": "2.000000000000000000",
            "fillable": "2.000000000000000000",
            "isBuy": true,
            "order_hash": "0x57a01cd26f1e2080860af3264e865d7c9c034a701e30946d01c1dc7a303cf2c1"
        }
    ]
}
ParameterTypeDescription
ordersTrimmedSpotLimitOrder array


TrimmedSpotLimitOrder

ParameterTypeDescription
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
fillablecosmossdk_io_math.LegacyDecthe amount of the quantity remaining fillable (in human readable format)
isBuybooltrue if the order is a buy
order_hashstringthe order hash (optional)
cidstringthe client order ID (optional)

SpotMidPriceAndTOB

Retrieves a spot market's mid-price

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    prices = await client.fetch_spot_mid_price_and_tob(
        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
    )
    print(prices)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    res, err := chainClient.FetchSpotMidPriceAndTOB(ctx, marketId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
market_idstringMarket ID for the marketYes

Response Parameters

Response Example:

{
    "midPrice": "29.4335",
    "bestBuyPrice": "29.414",
    "bestSellPrice": "29.453"
}
ParameterTypeDescription
mid_pricecosmossdk_io_math.LegacyDecmid price of the market (in human readable format)
best_buy_pricecosmossdk_io_math.LegacyDecbest buy price of the market (in human readable format)
best_sell_pricecosmossdk_io_math.LegacyDecbest sell price of the market

MsgInstantSpotMarketLaunch

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_instant_spot_market_launch(
        sender=address.to_acc_bech32(),
        ticker="INJ/USDC",
        base_denom="inj",
        quote_denom="factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        min_price_tick_size=Decimal("0.001"),
        min_quantity_tick_size=Decimal("0.01"),
        min_notional=Decimal("1"),
        base_decimals=18,
        quote_decimals=6,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.01")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.001")
    minNotional := math.LegacyMustNewDecFromStr("1")

    msg := &exchangev2types.MsgInstantSpotMarketLaunch{
        Sender:              senderAddress.String(),
        Ticker:              "INJ/USDC",
        BaseDenom:           "inj",
        QuoteDenom:          "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc",
        MinPriceTickSize:    minPriceTickSize,
        MinQuantityTickSize: minQuantityTickSize,
        MinNotional:         minNotional,
        BaseDecimals:        18,
        QuoteDecimals:       6,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
tickerstringTicker for the spot market.Yes
base_denomstringtype of coin to use as the base currencyYes
quote_denomstringtype of coin to use as the quote currencyYes
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size of the order's price (in human readable format)Yes
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the order's quantity (in human readable format)Yes
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)Yes
base_decimalsuint32base token decimalsYes
quote_decimalsuint32quote token decimalsYes

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateSpotLimitOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    cid = str(uuid.uuid4())

    # prepare tx msg
    msg = composer.msg_create_spot_limit_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal("7.523"),
        quantity=Decimal("0.01"),
        order_type="BUY",
        cid=cid,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    amount := decimal.NewFromFloat(2)
    price := decimal.NewFromFloat(22.55)

    order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     amount,
            Price:        price,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgCreateSpotLimitOrder{
        Sender: senderAddress.String(),
        Order:  *order,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderSpotOrderthe order detailsYes


SpotOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0xee49d8060469fd6824d65a0f7099b02fe23fcb7302dd21800905cf0cd285bd82"
]
---Transaction Response---
txhash: "C56626C351E66EBAF085E84DF6422E84043DD6A1B81316367FE3976D762000FE"
raw_log: "[]"

gas wanted: 104011
gas fee: 0.0000520055 INJ
simulated order hash:  0x73d8e846abdfffd3d42ff2c190a650829a5af52b3337287319b4f2c54eb7ce80
DEBU[0001] broadcastTx with nonce 3492                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5212740  fn=func1 src="client/chain/chain.go:619" txHash=B62F7CC6DE3297EC4376C239AF93DB33193A89FA99FAC27C9E25AD5579B9BAD7
DEBU[0003] nonce incremented to 3493                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  129912                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000064956 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateSpotMarketOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.msg_create_spot_market_order(
        market_id=market_id,
        sender=address.to_acc_bech32(),
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal("10.522"),
        quantity=Decimal("0.01"),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"
    amount := decimal.NewFromFloat(0.1)
    price := decimal.NewFromFloat(22)

    order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_SELL), //BUY SELL
            Quantity:     amount,
            Price:        price,
            FeeRecipient: senderAddress.String(),
            MarketId:     marketId,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgCreateSpotMarketOrder{
        Sender: senderAddress.String(),
        Order:  *order,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderSpotOrderthe order detailsYes


SpotOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0x7c6552c5f5ffd3adc2cb5fe9f2bc1eed4741952f698c84e9dc73c6f45b6af8b4"
]
---Transaction Response---
txhash: "9BBD3666A052FA11AF572F4D788C3C7D8B44F60CF0F0375EE40B84DA2408114A"
raw_log: "[]"

gas wanted: 104352
gas fee: 0.000052176 INJ
simulated order hash 0xfa9038ef2e59035a8f3368438aa4533fce90d8bbd3bee6c37e4cc06e8d1d0e6a
DEBU[0001] broadcastTx with nonce 3493                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5212834  fn=func1 src="client/chain/chain.go:619" txHash=14ABC252192D7286429730F9A29AB1BA67608B5EA7ACD7AD4D8F174C9B3852B3
DEBU[0004] nonce incremented to 3494                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  130596                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000065298 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCancelSpotOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    order_hash = "0x52888d397d5ae821869c8acde5823dfd8018802d2ef642d3aa639e5308173fcf"

    # prepare tx msg
    msg = composer.msg_cancel_spot_order(
        sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, order_hash=order_hash
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := exchangev2types.MsgCancelSpotOrder{
        Sender:       senderAddress.String(),
        MarketId:     "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
        SubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        OrderHash:    "0xc1dd07efb7cf3a90c3d09da958fa22d96a5787eba3dbec56b63902c482accbd4",
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
market_idstringthe market IDYes
subaccount_idstringthe subaccount IDYes
order_hashstringthe order hash (optional)No
cidstringthe client order ID (optional)No

Response Parameters

Response Example:

txhash: "3ABF365B8D90D44749AFF74FC510D792581202F98ABB406219B72E71315A64D4"
raw_log: "[]"

gas wanted: 102720
gas fee: 0.00005136 INJ
DEBU[0001] broadcastTx with nonce 3494                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5212920  fn=func1 src="client/chain/chain.go:619" txHash=14C2CB0592C5E950587D2041E97E337452A28F2A11220CC3E66624E5BAA73245
DEBU[0002] nonce incremented to 3495                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  127363                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000636815 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgBatchUpdateOrders

MsgBatchUpdateOrders allows for the atomic cancellation and creation of spot and derivative limit orders, along with a new order cancellation mode. Upon execution, order cancellations (if any) occur first, followed by order creations (if any).

Users can cancel all limit orders in a given spot or derivative market for a given subaccountID by specifying the associated marketID in the SpotMarketIdsToCancelAll and DerivativeMarketIdsToCancelAll. Users can also cancel individual limit orders in SpotOrdersToCancel or DerivativeOrdersToCancel, but must ensure that marketIDs in these individual order cancellations are not already provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll.

Further note that if no marketIDs are provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll, then the SubaccountID in the Msg should be left empty.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    derivative_market_id_create = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    derivative_market_id_cancel = "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff"
    derivative_market_id_cancel_2 = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_cancel = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    spot_market_id_cancel_2 = "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0"

    derivative_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel,
            subaccount_id=subaccount_id,
            order_hash="0x48690013c382d5dbaff9989db04629a16a5818d7524e027d517ccc89fd068103",
        ),
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5",
        ),
    ]

    spot_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel,
            subaccount_id=subaccount_id,
            cid="0e5c3ad5-2cc4-4a2a-bbe5-b12697739163",
        ),
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2",
        ),
    ]

    derivative_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25000),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(50000),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_market_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25100),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25100), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3"),
            quantity=Decimal("55"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("300"),
            quantity=Decimal("55"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_market_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3.5"),
            quantity=Decimal("1"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    msg = composer.msg_batch_update_orders(
        sender=address.to_acc_bech32(),
        derivative_orders_to_create=derivative_orders_to_create,
        spot_orders_to_create=spot_orders_to_create,
        derivative_orders_to_cancel=derivative_orders_to_cancel,
        spot_orders_to_cancel=spot_orders_to_cancel,
        spot_market_orders_to_create=spot_market_orders_to_create,
        derivative_market_orders_to_create=derivative_market_orders_to_create,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    smarketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"
    samount := decimal.NewFromFloat(2)
    sprice := decimal.NewFromFloat(22.5)
    smarketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}

    spot_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     samount,
            Price:        sprice,
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    spot_market_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.1),
            Price:        decimal.NewFromFloat(22),
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    dmarketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    damount := decimal.NewFromFloat(0.01)
    dprice := decimal.RequireFromString("31000") //31,000
    dleverage := decimal.RequireFromString("2")
    dmarketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}

    derivative_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     damount,
            Price:        dprice,
            Leverage:     dleverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    derivative_market_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.01),
            Price:        decimal.RequireFromString("33000"),
            Leverage:     decimal.RequireFromString("2"),
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgBatchUpdateOrders{
        Sender:                         senderAddress.String(),
        SubaccountId:                   defaultSubaccountID.Hex(),
        SpotOrdersToCreate:             []*exchangev2types.SpotOrder{spot_order},
        DerivativeOrdersToCreate:       []*exchangev2types.DerivativeOrder{derivative_order},
        SpotMarketIdsToCancelAll:       smarketIds,
        DerivativeMarketIdsToCancelAll: dmarketIds,
        SpotMarketOrdersToCreate:       []*exchangev2types.SpotOrder{spot_market_order},
        DerivativeMarketOrdersToCreate: []*exchangev2types.DerivativeOrder{derivative_market_order},
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstringsubaccount_id only used for the spot_market_ids_to_cancel_all and derivative_market_ids_to_cancel_all (optional)No
spot_market_ids_to_cancel_allstring arraythe market IDs to cancel all spot orders for (optional)No
derivative_market_ids_to_cancel_allstring arraythe market IDs to cancel all derivative orders for (optional)No
spot_orders_to_cancelOrderData arraythe spot orders to cancelNo
derivative_orders_to_cancelOrderData arraythe derivative orders to cancelNo
spot_orders_to_createSpotOrder arraythe spot orders to createNo
derivative_orders_to_createDerivativeOrder arraythe derivative orders to createNo
binary_options_orders_to_cancelOrderData arraythe binary options orders to cancelNo
binary_options_market_ids_to_cancel_allstring arraythe market IDs to cancel all binary options orders for (optional)No
binary_options_orders_to_createDerivativeOrder arraythe binary options orders to createNo
spot_market_orders_to_createSpotOrder arraythe spot market orders to createNo
derivative_market_orders_to_createDerivativeOrder arraythe derivative market orders to createNo
binary_options_market_orders_to_createDerivativeOrder arraythe binary options market orders to createNo


OrderData

ParameterTypeDescription
market_idstringthe market ID
subaccount_idstringthe subaccount ID
order_hashstringthe order hash (optional - either the order_hash or the cid should be provided)
order_maskint32the order mask (bitwise combination of OrderMask enum values)
cidstringthe client order ID (optional - either the order_hash or the cid should be provided)


SpotOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderMask

CodeName
0UNUSED
1ANY
2REGULAR
4CONDITIONAL
8DIRECTION_BUY_OR_HIGHER
16DIRECTION_SELL_OR_LOWER
32TYPE_MARKET
64TYPE_LIMIT


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[spot_cancel_success: false
spot_cancel_success: false
derivative_cancel_success: false
derivative_cancel_success: false
spot_order_hashes: "0x3f5b5de6ec72b250c58e0a83408dbc1990cee369999036e3469e19b80fa9002e"
spot_order_hashes: "0x7d8580354e120b038967a180f73bc3aba0f49db9b6d2cb5c4cec85e8cab3e218"
derivative_order_hashes: "0x920a4ea4144c46d1e1084ca5807e4f5608639ce00f97139d5b44e628d487e15e"
derivative_order_hashes: "0x11d75d0c2ce8a07f352523be2e3456212c623397d0fc1a2f688b97a15c04372c"
]
---Transaction Response---
txhash: "4E29226884DCA22E127471588F39E0BB03D314E1AA27ECD810D24C4078D52DED"
raw_log: "[]"

gas wanted: 271213
gas fee: 0.0001356065 INJ
simulated spot order hashes [0xd9f30c7e700202615c2775d630b9fb276572d883fa480b6394abbddcb79c8109]
simulated derivative order hashes [0xb2bea3b15c204699a9ee945ca49650001560518d1e54266adac580aa061fedd4]
DEBU[0001] broadcastTx with nonce 3507                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214679  fn=func1 src="client/chain/chain.go:619" txHash=CF53E0B31B9E28E0D6D8F763ECEC2D91E38481321EA24AC86F6A8774C658AF44
DEBU[0003] nonce incremented to 3508                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  659092                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000329546 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgUpdateSpotMarket

Modifies certain market fields. It can only be sent by the market's admin.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    message = composer.msg_update_spot_market(
        admin=address.to_acc_bech32(),
        market_id="0x215970bfdea5c94d8e964a759d3ce6eae1d113900129cc8428267db5ccdb3d1a",
        new_ticker="INJ/USDC 2",
        new_min_price_tick_size=Decimal("0.01"),
        new_min_quantity_tick_size=Decimal("0.01"),
        new_min_notional=Decimal("2"),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.01")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.01")
    minNotional := math.LegacyMustNewDecFromStr("2")

    msg := &exchangev2types.MsgUpdateSpotMarket{
        Admin:                  senderAddress.String(),
        MarketId:               "0x215970bfdea5c94d8e964a759d3ce6eae1d113900129cc8428267db5ccdb3d1a",
        NewTicker:              "INJ/USDC 2",
        NewMinPriceTickSize:    minPriceTickSize,
        NewMinQuantityTickSize: minQuantityTickSize,
        NewMinNotional:         minNotional,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
adminstringcurrent admin address of the associated marketYes
market_idstringid of the market to be updatedYes
new_tickerstring(optional) updated ticker valueNo
new_min_price_tick_sizecosmossdk_io_math.LegacyDec(optional) updated min price tick size value (in human readable format)No
new_min_quantity_tick_sizecosmossdk_io_math.LegacyDec(optional) updated min quantity tick size value (in human readable format)No
new_min_notionalcosmossdk_io_math.LegacyDec(optional) updated min notional (in human readable format)No

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

LocalOrderHashComputation

This function computes order hashes locally for SpotOrder and DerivativeOrder. For more information, see the note below.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.constant import GAS_FEE_BUFFER_AMOUNT
from pyinjective.core.network import Network
from pyinjective.orderhash import OrderHashManager
from pyinjective.transaction import Transaction
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())
    subaccount_id = address.get_subaccount_id(index=0)
    subaccount_id_2 = address.get_subaccount_id(index=1)

    order_hash_manager = OrderHashManager(address=address, network=network, subaccount_indexes=[0, 1, 2, 7])

    # prepare trade info
    spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    deriv_market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    spot_orders = [
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("0.524"),
            quantity=Decimal("0.01"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("27.92"),
            quantity=Decimal("0.01"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_orders = [
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(10500),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(10500), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(65111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(65111), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders)

    deriv_msg = composer.msg_batch_create_derivative_limit_orders(
        sender=address.to_acc_bech32(), orders=derivative_orders
    )

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=0
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 1
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=0
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 2
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

    spot_orders = [
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal("1.524"),
            quantity=Decimal("0.01"),
            order_type="BUY_PO",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal("27.92"),
            quantity=Decimal("0.01"),
            order_type="SELL_PO",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_orders = [
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal(25111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal("1.5"), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id_2,
            fee_recipient=fee_recipient,
            price=Decimal(65111),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal(2), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders)

    deriv_msg = composer.msg_batch_create_derivative_limit_orders(
        sender=address.to_acc_bech32(), orders=derivative_orders
    )

    # compute order hashes
    order_hashes = order_hash_manager.compute_order_hashes(
        spot_orders=spot_orders, derivative_orders=derivative_orders, subaccount_index=1
    )

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build tx 3
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    base_gas = 85000
    gas_limit = base_gas + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
    fee = [
        composer.coin(
            amount=gas_price * gas_limit,
            denom=network.fee_denom,
        )
    ]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(json.dumps(res, indent=2))
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )
    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    // prepare tx msg
    defaultSubaccountID := chainClient.Subaccount(senderAddress, 1)

    spotOrder := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY),
            Quantity:     decimal.NewFromFloat(2),
            Price:        decimal.NewFromFloat(22.55),
            FeeRecipient: senderAddress.String(),
            MarketId:     "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
            Cid:          uuid.NewString(),
        },
    )

    derivativeOrder := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY),
            Quantity:     decimal.NewFromFloat(2),
            Price:        decimal.RequireFromString("31"),
            Leverage:     decimal.RequireFromString("2.5"),
            FeeRecipient: senderAddress.String(),
            MarketId:     "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgBatchCreateSpotLimitOrders{
        Sender: senderAddress.String(),
        Orders: []exchangev2types.SpotOrder{*spotOrder},
    }

    msg1 := exchangev2types.MsgBatchCreateDerivativeLimitOrders{
        Sender: senderAddress.String(),
        Orders: []exchangev2types.DerivativeOrder{*derivativeOrder},
    }

    // compute local order hashes
    orderHashes, err := chainClient.ComputeOrderHashes(msg.Orders, msg1.Orders, defaultSubaccountID)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("computed spot order hashes: ", orderHashes.Spot)
    fmt.Println("computed derivative order hashes: ", orderHashes.Derivative)

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg, &msg1)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}

Response Parameters

Response Example:

computed spot order hashes ['0xa2d59cca00bade680a552f02deeb43464df21c73649191d64c6436313b311cba', '0xab78219e6c494373262a310d73660198c7a4c91196c0f6bb8808c81d8fb54a11']
computed derivative order hashes ['0x38d432c011f4a62c6b109615718b26332e7400a86f5e6f44e74a8833b7eed992', '0x66a921d83e6931513df9076c91a920e5e943837e2b836ad370b5cf53a1ed742c']
txhash: "604757CD9024FFF2DDCFEED6FC070E435AC09A829DB2E81AD4AD65B33E987A8B"
raw_log: "[]"

gas wanted: 196604
gas fee: 0.000098302 INJ
computed spot order hashes:  [0x0103ca50d0d033e6b8528acf28a3beb3fd8bac20949fc1ba60a2da06c53ad94f]
computed derivative order hashes:  [0x15334a7a0f1c2f98b9369f79b9a62a1f357d3e63b46a8895a4cec0ca375ddbbb 0xc26c8f74f56eade275e518f73597dd8954041bfbae3951ed4d7efeb0d060edbd]
DEBU[0001] broadcastTx with nonce 3488                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5212331  fn=func1 src="client/chain/chain.go:619" txHash=19D8D81BB1DF59889E00EAA600A01079BA719F00A4A43CCC1B56580A1BBD6455
DEBU[0003] nonce incremented to 3489                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  271044                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000135522 INJ

Note on LocalOrderHashComputation for HFTs/API Traders

LocalOrderHashComputation returns a locally computed transaction hash for spot and derivative orders, which is useful when the user needs the transaction hash faster than orders can be streamed through StreamOrdersHistory (there is extra latency since the order must be included by a block, and the block must be indexed by the Indexer). While the hash can also be obtained through transaction simulation, the process adds a layer of latency and can only be used for one transaction per block (simulation relies on a nonce based on the state machine which does not change until the transaction is included in a block).

On Injective, subaccount nonces are used to calculate order hashes. The subaccount nonce is incremented with each order so that order hashes remain unique.

For strategies employing high frequency trading, order hashes should be calculated locally before transactions are broadcasted. This is possible as long as the subaccount nonce is cached/tracked locally instead of queried from the chain. Similarly, the account sequence (like nonce on Ethereum) should be cached if more than one transaction per block is desired. The LocalOrderHashComputation implementation can be found here. Refer to the above API example for usage.

There are two caveats to be mindful of when taking this approach:

1. Gas must be manually calculated instead of fetched from simulation

  class GasLimitConstant:
      base = 65e3
      extra = 20e3
      spot_order = 60e3
      spot_cancel = 40e3

2. In the event a transaction fails, the account sequence and subaccount nonce must both be refreshed

  res = await self.client.broadcast_tx_sync_mode(tx_raw_bytes)
  if res.code == 32:
      await client.fetch_account(address.to_acc_bech32())

- Chain Exchange for Binary Options

Includes all messages related to binary options.

BinaryOptionsMarkets

Retrieves binary options markets

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    markets = await client.fetch_chain_binary_options_markets(status="Active")
    print(markets)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    status := "Active"

    res, err := chainClient.FetchChainBinaryOptionsMarkets(ctx, status)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
statusstringStatus of the market, for convenience it is set to string - not enumYes

Response Parameters

Response Example:

{
    "markets": [
        {
            "ticker": "TIA/USDT PERP",
            "oracle_symbol": "TIA/USDT PERP",
            "oracle_provider": "Frontrunner",
            "oracle_type": 11,
            "expiration_timestamp": 17115165000022,
            "settlement_timestamp": 17115201000022,
            "admin": "inj1xyfrl7wrsczv7ah5tvvpcwnp3vlc3n9terc9d6",
            "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "market_id": "0x5cced3de7c6df18b87d94b18f4b2065f8efcac44c3abecf3f2ed489af8c0c15e",
            "maker_fee_rate": "0.000500000000000000",
            "taker_fee_rate": "0.001000000000000000",
            "relayer_fee_share_rate": "0.400000000000000000",
            "status": 1,
            "min_price_tick_size": "0.000000010000000000",
            "min_quantity_tick_size": "0.010000000000000000",
            "min_notional": "0.000000000000000000",
            "quote_decimals": 6
        },
        {
            "ticker": "INJ/USDT",
            "oracle_symbol": "INJ/USDT",
            "oracle_provider": "Frontrunner",
            "oracle_type": 11,
            "expiration_timestamp": 17116342000091,
            "settlement_timestamp": 17116378000091,
            "admin": "inj1xyfrl7wrsczv7ah5tvvpcwnp3vlc3n9terc9d6",
            "quote_denom": "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
            "market_id": "0xddd038d16922db1671a998285e387f016ad302a6643732fcac93dc42ac927e39",
            "maker_fee_rate": "0.000500000000000000",
            "taker_fee_rate": "0.001000000000000000",
            "relayer_fee_share_rate": "0.400000000000000000",
            "status": 1,
            "min_price_tick_size": "0.000000010000000000",
            "min_quantity_tick_size": "0.010000000000000000",
            "min_notional": "0.000000000000000000",
            "quote_decimals": 6
        }
    ]
}
ParameterTypeDescription
marketsBinaryOptionsMarket array


BinaryOptionsMarket

ParameterTypeDescription
tickerstringTicker for the derivative contract.
oracle_symbolstringOracle symbol
oracle_providerstringOracle Provider
oracle_typetypes.OracleTypeOracle type
oracle_scale_factoruint32Scale factor for oracle prices.
expiration_timestampint64expiration timestamp
settlement_timestampint64expiration timestamp
adminstringadmin of the market
quote_denomstringAddress of the quote currency denomination for the binary options contract
market_idstringUnique market ID.
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the maker fee rate of a binary options market
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the taker fee rate of a derivative market
relayer_fee_share_ratecosmossdk_io_math.LegacyDecrelayer_fee_share_rate defines the percentage of the transaction fee shared with the relayer in a derivative market
statusMarketStatusStatus of the market
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price and margin required for orders in the market (in human readable format)
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)
settlement_pricecosmossdk_io_math.LegacyDecsettlement_price defines the settlement price of the binary options market (in human readable format)
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)
admin_permissionsuint32level of admin permissions
quote_decimalsuint32quote token decimals
open_notional_capOpenNotionalCapopen_notional_cap defines the maximum open notional for the market


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


AdminPermission

CodeName
1Ticker Permission
2Min Price Tick Size Permission
4Min Quantity Tick Size Permission
8Min Notional Permission
16Initial Margin Ratio Permission
32Maintenance Margin Ratio Permission


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec

MsgInstantBinaryOptionsMarketLaunch

IP rate limit group: chain

Request Parameters

Request Example:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    oracletypes "github.com/InjectiveLabs/sdk-go/chain/oracle/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    minPriceTickSize := math.LegacyMustNewDecFromStr("0.01")
    minQuantityTickSize := math.LegacyMustNewDecFromStr("0.001")

    msg := &exchangev2types.MsgInstantBinaryOptionsMarketLaunch{
        Sender:              senderAddress.String(),
        Ticker:              "UFC-KHABIB-TKO-05/30/2023",
        OracleSymbol:        "UFC-KHABIB-TKO-05/30/2023",
        OracleProvider:      "UFC",
        OracleType:          oracletypes.OracleType_Provider,
        OracleScaleFactor:   0,
        MakerFeeRate:        math.LegacyMustNewDecFromStr("0.0005"),
        TakerFeeRate:        math.LegacyMustNewDecFromStr("0.0010"),
        ExpirationTimestamp: 1680730982,
        SettlementTimestamp: 1690730982,
        Admin:               senderAddress.String(),
        QuoteDenom:          "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
        MinPriceTickSize:    minPriceTickSize,
        MinQuantityTickSize: minQuantityTickSize,
        OpenNotionalCap: exchangev2types.OpenNotionalCap{
            Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
tickerstringTicker for the derivative contract.Yes
oracle_symbolstringOracle symbolYes
oracle_providerstringOracle ProviderYes
oracle_typetypes1.OracleTypeOracle typeYes
oracle_scale_factoruint32Scale factor for oracle prices.Yes
maker_fee_ratecosmossdk_io_math.LegacyDecmaker_fee_rate defines the trade fee rate for makers on the perpetual marketYes
taker_fee_ratecosmossdk_io_math.LegacyDectaker_fee_rate defines the trade fee rate for takers on the perpetual marketYes
expiration_timestampint64expiration timestampYes
settlement_timestampint64expiration timestampYes
adminstringadmin of the marketYes
quote_denomstringAddress of the quote currency denomination for the binary options contractYes
min_price_tick_sizecosmossdk_io_math.LegacyDecmin_price_tick_size defines the minimum tick size that the price and margin required for orders in the market (in human readable format)Yes
min_quantity_tick_sizecosmossdk_io_math.LegacyDecmin_quantity_tick_size defines the minimum tick size of the quantity required for orders in the market (in human readable format)Yes
min_notionalcosmossdk_io_math.LegacyDecmin_notional defines the minimum notional (in quote asset) required for orders in the market (in human readable format)Yes
open_notional_capOpenNotionalCapopen_notional_cap defines the cap on the open notionalYes


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork


OpenNotionalCap_Uncapped

ParameterTypeDescription
uncappedOpenNotionalCapUncapped


OpenNotionalCap_Capped

ParameterTypeDescription
cappedOpenNotionalCapCapped


OpenNotionalCapCapped

ParameterTypeDescription
valuecosmossdk_io_math.LegacyDec

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateBinaryOptionsLimitOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x767e1542fbc111e88901e223e625a4a8eb6d630c96884bbde672e8bc874075bb"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.msg_create_binary_options_limit_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal("0.5"),
        quantity=Decimal("1"),
        margin=Decimal("0.5"),
        order_type="BUY",
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderDerivativeOrderthe order detailsYes


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0xc1e1a8e81659360c3092043a000786f23fce5f3b8a355da32227c3e8eafb1fde"
]
---Transaction Response---
txhash: "7955AE8D7EA90E85F07E776372369E92952A0A86DC9BCBDBA3132447DB738282"
raw_log: "[]"

gas wanted: 121249
gas fee: 0.0000606245 INJ

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCreateBinaryOptionsMarketOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x00617e128fdc0c0423dd18a1ff454511af14c4db6bdd98005a99cdf8fdbf74e9"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.msg_create_binary_options_market_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=Decimal("0.5"),
        quantity=Decimal(1),
        margin=composer.calculate_margin(
            quantity=Decimal(1), price=Decimal("0.5"), leverage=Decimal(1), is_reduce_only=False
        ),
        cid=str(uuid.uuid4()),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
orderDerivativeOrderthe order detailsYes


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[order_hash: "0x1d4ebeaa75bb6a5232ef20cf9ff10eedc470be8f716fb4b3a57780fb1247b4dc"
]
---Transaction Response---
txhash: "FE91A0828F1900FB9FD202BF872B66580A89E663062B3DF13874328A7F6CF797"
raw_log: "[]"

gas wanted: 107903
gas fee: 0.0000539515 INJ

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgCancelBinaryOptionsOrder

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x00617e128fdc0c0423dd18a1ff454511af14c4db6bdd98005a99cdf8fdbf74e9"
    order_hash = "a975fbd72b874bdbf5caf5e1e8e2653937f33ce6dd14d241c06c8b1f7b56be46"

    # prepare tx msg
    msg = composer.msg_cancel_binary_options_order(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        order_hash=order_hash,
        is_buy=True,
        is_market_order=False,
        is_conditional=False,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
market_idstringthe market IDYes
subaccount_idstringthe subaccount IDYes
order_hashstringthe order hash (optional)No
order_maskint32the order mask (bitwise combination of OrderMask enum values) (optional)No
cidstringthe client order ID (optional)No


OrderMask

CodeName
0UNUSED
1ANY
2REGULAR
4CONDITIONAL
8DIRECTION_BUY_OR_HIGHER
16DIRECTION_SELL_OR_LOWER
32TYPE_MARKET
64TYPE_LIMIT

Response Parameters

Response Example:

---Transaction Response---
txhash: "4B85368A96A67BB9B6DABB8B730A824051E0E4C9243F5970DF1512B98FCF2D67"
raw_log: "[]"

gas wanted: 111303
gas fee: 0.0000556515 INJ

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgAdminUpdateBinaryOptionsMarket

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare trade info
    market_id = "0xfafec40a7b93331c1fc89c23f66d11fbb48f38dfdd78f7f4fc4031fad90f6896"
    status = "Demolished"
    settlement_price = Decimal(1)
    expiration_timestamp = 1685460582
    settlement_timestamp = 1690730982

    # prepare tx msg
    msg = composer.msg_admin_update_binary_options_market(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        settlement_price=settlement_price,
        expiration_timestamp=expiration_timestamp,
        settlement_timestamp=settlement_timestamp,
        status=status,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
market_idstringThe market IDYes
settlement_pricecosmossdk_io_math.LegacyDecnew price at which market will be settledNo
expiration_timestampint64expiration timestampYes
settlement_timestampint64expiration timestampYes
statusMarketStatusStatus of the marketYes


MarketStatus

CodeName
0Unspecified
1Active
2Paused
3Demolished
4Expired

Response Parameters

Response Example:

---Transaction Response---
txhash: "4B85368A96A67BB9B6DABB8B730A824051E0E4C9243F5970DF1512B98FCF2D67"
raw_log: "[]"

gas wanted: 111303
gas fee: 0.0000556515 INJ

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgBatchUpdateOrders

MsgBatchUpdateOrders allows for the atomic cancellation and creation of spot and derivative limit orders, along with a new order cancellation mode. Upon execution, order cancellations (if any) occur first, followed by order creations (if any).

Users can cancel all limit orders in a given spot or derivative market for a given subaccountID by specifying the associated marketID in the SpotMarketIdsToCancelAll and DerivativeMarketIdsToCancelAll. Users can also cancel individual limit orders in SpotOrdersToCancel or DerivativeOrdersToCancel, but must ensure that marketIDs in these individual order cancellations are not already provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll.

Further note that if no marketIDs are provided in the SpotMarketIdsToCancelAll or DerivativeMarketIdsToCancelAll, then the SubaccountID in the Msg should be left empty.

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
import uuid
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    derivative_market_id_create = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"

    derivative_market_id_cancel = "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff"
    derivative_market_id_cancel_2 = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
    spot_market_id_cancel = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
    spot_market_id_cancel_2 = "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0"

    derivative_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel,
            subaccount_id=subaccount_id,
            order_hash="0x48690013c382d5dbaff9989db04629a16a5818d7524e027d517ccc89fd068103",
        ),
        composer.create_order_data_without_mask(
            market_id=derivative_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5",
        ),
    ]

    spot_orders_to_cancel = [
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel,
            subaccount_id=subaccount_id,
            cid="0e5c3ad5-2cc4-4a2a-bbe5-b12697739163",
        ),
        composer.create_order_data_without_mask(
            market_id=spot_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2",
        ),
    ]

    derivative_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25000),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(50000),
            quantity=Decimal(0.01),
            margin=composer.calculate_margin(
                quantity=Decimal(0.01), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    derivative_market_orders_to_create = [
        composer.derivative_order(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal(25100),
            quantity=Decimal(0.1),
            margin=composer.calculate_margin(
                quantity=Decimal(0.1), price=Decimal(25100), leverage=Decimal(1), is_reduce_only=False
            ),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3"),
            quantity=Decimal("55"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("300"),
            quantity=Decimal("55"),
            order_type="SELL",
            cid=str(uuid.uuid4()),
        ),
    ]

    spot_market_orders_to_create = [
        composer.spot_order(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=Decimal("3.5"),
            quantity=Decimal("1"),
            order_type="BUY",
            cid=str(uuid.uuid4()),
        ),
    ]

    # prepare tx msg
    msg = composer.msg_batch_update_orders(
        sender=address.to_acc_bech32(),
        derivative_orders_to_create=derivative_orders_to_create,
        spot_orders_to_create=spot_orders_to_create,
        derivative_orders_to_cancel=derivative_orders_to_cancel,
        spot_orders_to_cancel=spot_orders_to_cancel,
        spot_market_orders_to_create=spot_market_orders_to_create,
        derivative_market_orders_to_create=derivative_market_orders_to_create,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    "github.com/google/uuid"
    "github.com/shopspring/decimal"

    exchangev2types "github.com/InjectiveLabs/sdk-go/chain/exchange/types/v2"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    smarketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"
    samount := decimal.NewFromFloat(2)
    sprice := decimal.NewFromFloat(22.5)
    smarketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}

    spot_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     samount,
            Price:        sprice,
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    spot_market_order := chainClient.CreateSpotOrderV2(
        defaultSubaccountID,
        &chainclient.SpotOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.1),
            Price:        decimal.NewFromFloat(22),
            FeeRecipient: senderAddress.String(),
            MarketId:     smarketId,
            Cid:          uuid.NewString(),
        },
    )

    dmarketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    damount := decimal.NewFromFloat(0.01)
    dprice := decimal.RequireFromString("31000") //31,000
    dleverage := decimal.RequireFromString("2")
    dmarketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}

    derivative_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL BUY_PO SELL_PO
            Quantity:     damount,
            Price:        dprice,
            Leverage:     dleverage,
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    derivative_market_order := chainClient.CreateDerivativeOrderV2(
        defaultSubaccountID,
        &chainclient.DerivativeOrderData{
            OrderType:    int32(exchangev2types.OrderType_BUY), //BUY SELL
            Quantity:     decimal.NewFromFloat(0.01),
            Price:        decimal.RequireFromString("33000"),
            Leverage:     decimal.RequireFromString("2"),
            FeeRecipient: senderAddress.String(),
            MarketId:     dmarketId,
            IsReduceOnly: false,
            Cid:          uuid.NewString(),
        },
    )

    msg := exchangev2types.MsgBatchUpdateOrders{
        Sender:                         senderAddress.String(),
        SubaccountId:                   defaultSubaccountID.Hex(),
        SpotOrdersToCreate:             []*exchangev2types.SpotOrder{spot_order},
        DerivativeOrdersToCreate:       []*exchangev2types.DerivativeOrder{derivative_order},
        SpotMarketIdsToCancelAll:       smarketIds,
        DerivativeMarketIdsToCancelAll: dmarketIds,
        SpotMarketOrdersToCreate:       []*exchangev2types.SpotOrder{spot_market_order},
        DerivativeMarketOrdersToCreate: []*exchangev2types.DerivativeOrder{derivative_market_order},
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringthe sender's Injective addressYes
subaccount_idstringsubaccount_id only used for the spot_market_ids_to_cancel_all and derivative_market_ids_to_cancel_all (optional)No
spot_market_ids_to_cancel_allstring arraythe market IDs to cancel all spot orders for (optional)No
derivative_market_ids_to_cancel_allstring arraythe market IDs to cancel all derivative orders for (optional)No
spot_orders_to_cancelOrderData arraythe spot orders to cancelNo
derivative_orders_to_cancelOrderData arraythe derivative orders to cancelNo
spot_orders_to_createSpotOrder arraythe spot orders to createNo
derivative_orders_to_createDerivativeOrder arraythe derivative orders to createNo
binary_options_orders_to_cancelOrderData arraythe binary options orders to cancelNo
binary_options_market_ids_to_cancel_allstring arraythe market IDs to cancel all binary options orders for (optional)No
binary_options_orders_to_createDerivativeOrder arraythe binary options orders to createNo
spot_market_orders_to_createSpotOrder arraythe spot market orders to createNo
derivative_market_orders_to_createDerivativeOrder arraythe derivative market orders to createNo
binary_options_market_orders_to_createDerivativeOrder arraythe binary options market orders to createNo


OrderData

ParameterTypeDescription
market_idstringthe market ID
subaccount_idstringthe subaccount ID
order_hashstringthe order hash (optional - either the order_hash or the cid should be provided)
order_maskint32the order mask (bitwise combination of OrderMask enum values)
cidstringthe client order ID (optional - either the order_hash or the cid should be provided)


SpotOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


DerivativeOrder

ParameterTypeDescription
market_idstringmarket_id represents the unique ID of the market
order_infoOrderInfoorder_info contains the information of the order
order_typeOrderTypeorder types
margincosmossdk_io_math.LegacyDecmargin is the margin used by the limit order (in human readable format)
trigger_pricecosmossdk_io_math.LegacyDectrigger_price is the trigger price used by stop/take orders (in human readable format) (optional)
expiration_blockint64expiration block is the block number at which the order will expire


OrderMask

CodeName
0UNUSED
1ANY
2REGULAR
4CONDITIONAL
8DIRECTION_BUY_OR_HIGHER
16DIRECTION_SELL_OR_LOWER
32TYPE_MARKET
64TYPE_LIMIT


OrderInfo

ParameterTypeDescription
subaccount_idstringbytes32 subaccount ID that created the order
fee_recipientstringaddress fee_recipient address that will receive fees for the order
pricecosmossdk_io_math.LegacyDecprice of the order (in human readable format)
quantitycosmossdk_io_math.LegacyDecquantity of the order (in human readable format)
cidstringthe client order ID (optional)


OrderType

CodeName
0UNSPECIFIED
1BUY
2SELL
3STOP_BUY
4STOP_SELL
5TAKE_BUY
6TAKE_SELL
7BUY_PO
8SELL_PO
9BUY_ATOMIC
10SELL_ATOMIC

Response Parameters

Response Example:

---Simulation Response---
[spot_cancel_success: false
spot_cancel_success: false
derivative_cancel_success: false
derivative_cancel_success: false
spot_order_hashes: "0x3f5b5de6ec72b250c58e0a83408dbc1990cee369999036e3469e19b80fa9002e"
spot_order_hashes: "0x7d8580354e120b038967a180f73bc3aba0f49db9b6d2cb5c4cec85e8cab3e218"
derivative_order_hashes: "0x920a4ea4144c46d1e1084ca5807e4f5608639ce00f97139d5b44e628d487e15e"
derivative_order_hashes: "0x11d75d0c2ce8a07f352523be2e3456212c623397d0fc1a2f688b97a15c04372c"
]
---Transaction Response---
txhash: "4E29226884DCA22E127471588F39E0BB03D314E1AA27ECD810D24C4078D52DED"
raw_log: "[]"

gas wanted: 271213
gas fee: 0.0001356065 INJ
simulated spot order hashes [0xd9f30c7e700202615c2775d630b9fb276572d883fa480b6394abbddcb79c8109]
simulated derivative order hashes [0xb2bea3b15c204699a9ee945ca49650001560518d1e54266adac580aa061fedd4]
DEBU[0001] broadcastTx with nonce 3507                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5214679  fn=func1 src="client/chain/chain.go:619" txHash=CF53E0B31B9E28E0D6D8F763ECEC2D91E38481321EA24AC86F6A8774C658AF44
DEBU[0003] nonce incremented to 3508                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  659092                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000329546 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- ERC20

Includes all the messages and queries related to the tokens for the native EVM implementation.

AllTokenPairs

Defines a gRPC query method that returns the erc20 module's created token pairs

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    pairs = await client.fetch_erc20_all_token_pairs(
        pagination=PaginationOption(
            skip=0,
            limit=100,
        ),
    )
    print(json.dumps(pairs, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    pagination := query.PageRequest{Limit: 10}

    res, err := chainClient.FetchAllTokenPairs(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:


ParameterTypeDescription
token_pairsTokenPair array
paginationquery.PageResponsepagination defines the pagination in the response.


TokenPair

ParameterTypeDescription
bank_denomstring
erc20_addressstring

TokenPairByDenom

Defines a gRPC query method that returns the erc20 module's token pair associated with the provided bank denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    result = await client.fetch_erc20_token_pair_by_denom(bank_denom="usdt")
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchTokenPairByERC20Address(ctx, "usdt")
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
bank_denomstringYes

Response Parameters

Response Example:


ParameterTypeDescription
token_pairTokenPair


TokenPair

ParameterTypeDescription
bank_denomstring
erc20_addressstring

TokenPairByERC20Address

Defines a gRPC query method that returns the erc20 module's token pair associated with the provided erc20 contract address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    erc20_address = "0xdAC17F958D2ee523a2206206994597C13D831ec7"
    result = await client.fetch_erc20_token_pair_by_erc20_address(erc20_address=erc20_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    usdtERC20 := "0xdAC17F958D2ee523a2206206994597C13D831ec7"
    res, err := chainClient.FetchTokenPairByDenom(ctx, usdtERC20)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
erc20_addressstringYes

Response Parameters

Response Example:


ParameterTypeDescription
token_pairTokenPair


TokenPair

ParameterTypeDescription
bank_denomstring
erc20_addressstring

MsgCreateTokenPair

Creates a new ERC20 token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    usdt_denom = "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"
    usdt_erc20 = "0xdAC17F958D2ee523a2206206994597C13D831ec7"

    # prepare tx msg
    msg = composer.msg_create_token_pair(
        sender=address.to_acc_bech32(),
        bank_denom=usdt_denom,
        erc20_address=usdt_erc20,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    erc20types "github.com/InjectiveLabs/sdk-go/chain/erc20/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    usdtDenom := "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"
    usdtERC20 := "0xdAC17F958D2ee523a2206206994597C13D831ec7"

    msg := erc20types.MsgCreateTokenPair{
        Sender: senderAddress.String(),
        TokenPair: erc20types.TokenPair{
            BankDenom:    usdtDenom,
            Erc20Address: usdtERC20,
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
token_pairTokenPairYes


TokenPair

ParameterTypeDescription
bank_denomstring
erc20_addressstring

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgDeleteTokenPair

Deletes an ERC20 token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    usdt_denom = "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"

    # prepare tx msg
    msg = composer.msg_delete_token_pair(
        sender=address.to_acc_bech32(),
        bank_denom=usdt_denom,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    erc20types "github.com/InjectiveLabs/sdk-go/chain/erc20/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    usdtDenom := "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"

    msg := erc20types.MsgDeleteTokenPair{
        Sender:    senderAddress.String(),
        BankDenom: usdtDenom,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
bank_denomstringYes

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- EVM

Includes all the messages and queries related to the native EVM implementation.

Account

Queries an Ethereum account

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    erc20_address = "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    result = await client.fetch_evm_account(address=erc20_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    evmAddress := "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    res, err := chainClient.FetchEVMAccount(ctx, evmAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the ethereum hex address to query the account for.Yes

Response Parameters

Response Example:

{
    "balance": "0",
    "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
}
ParameterTypeDescription
balancestringbalance is the balance of the EVM denomination.
code_hashstringcode_hash is the hex-formatted code bytes from the EOA.
nonceuint64nonce is the account's sequence number.

CosmosAccount

Queries an Ethereum account's Cosmos Address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    erc20_address = "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    result = await client.fetch_evm_cosmos_account(address=erc20_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    evmAddress := "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    res, err := chainClient.FetchEVMCosmosAccount(ctx, evmAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the ethereum hex address to query the account for.Yes

Response Parameters

Response Example:

{
    "cosmos_address": "inj1ml2jj0vwx37luk0fpm74tv54dgf5893aq47asq"
}
ParameterTypeDescription
cosmos_addressstringcosmos_address is the cosmos address of the account.
sequenceuint64sequence is the account's sequence number.
account_numberuint64account_number is the account number

ValidatorAccount

Queries an Ethereum account's from a validator consensus Address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    cons_address = "injvalcons1h5u937etuat5hnr2s34yaaalfpkkscl5ndadqm"
    result = await client.fetch_evm_validator_account(cons_address=cons_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    consAddress := "injvalcons1h5u937etuat5hnr2s34yaaalfpkkscl5ndadqm"
    res, err := chainClient.FetchEVMValidatorAccount(ctx, consAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
cons_addressstringcons_address is the validator cons address to query the account for.Yes

Response Parameters

Response Example:


ParameterTypeDescription
account_addressstringaccount_address is the cosmos address of the account in bech32 format.
sequenceuint64sequence is the account's sequence number.
account_numberuint64account_number is the account number

Balance

Queries an Ethereum account's from a validator consensus Address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    erc20_address = "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    result = await client.fetch_evm_balance(address=erc20_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    evmAddress := "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    res, err := chainClient.FetchEVMBalance(ctx, evmAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the ethereum hex address to query the balance for.Yes

Response Parameters

Response Example:

{
    "balance": "0"
}
ParameterTypeDescription
balancestringbalance is the balance of the EVM denomination.

Storage

Queries the balance of all coins for a single account

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    erc20_address = "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    key = "key"
    result = await client.fetch_evm_storage(address=erc20_address, key=key)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    evmAddress := "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    key := "key"
    res, err := chainClient.FetchEVMStorage(ctx, evmAddress, &key)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the ethereum hex address to query the storage state for.Yes
keystringkey defines the key of the storage stateYes

Response Parameters

Response Example:

{
    "value": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
ParameterTypeDescription
valuestringvalue defines the storage state value hash associated with the given key.

Code

Queries the balance of all coins for a single account

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    evm_address = "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    result = await client.fetch_evm_code(address=evm_address)
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    evmAddress := "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d"
    res, err := chainClient.FetchEVMCode(ctx, evmAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the ethereum hex address to query the code for.Yes

Response Parameters

Response Example:


ParameterTypeDescription
codebyte arraycode represents the code bytes from an ethereum address.

BaseFee

Queries the base fee of the parent block of the current block, it's similar to feemarket module's method, but also checks london hardfork status

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    result = await client.fetch_evm_base_fee()
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchEVMBaseFee(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:


ParameterTypeDescription
base_feecosmossdk_io_math.Intbase_fee is the EIP1559 base fee

MsgCreateTokenPair

Creates a new ERC20 token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    usdt_denom = "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"
    usdt_erc20 = "0xdAC17F958D2ee523a2206206994597C13D831ec7"

    # prepare tx msg
    msg = composer.msg_create_token_pair(
        sender=address.to_acc_bech32(),
        bank_denom=usdt_denom,
        erc20_address=usdt_erc20,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    erc20types "github.com/InjectiveLabs/sdk-go/chain/erc20/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    usdtDenom := "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"
    usdtERC20 := "0xdAC17F958D2ee523a2206206994597C13D831ec7"

    msg := erc20types.MsgCreateTokenPair{
        Sender: senderAddress.String(),
        TokenPair: erc20types.TokenPair{
            BankDenom:    usdtDenom,
            Erc20Address: usdtERC20,
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
token_pairTokenPairYes


TokenPair

ParameterTypeDescription
bank_denomstring
erc20_addressstring

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgDeleteTokenPair

Deletes an ERC20 token

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    usdt_denom = "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"

    # prepare tx msg
    msg = composer.msg_delete_token_pair(
        sender=address.to_acc_bech32(),
        bank_denom=usdt_denom,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    erc20types "github.com/InjectiveLabs/sdk-go/chain/erc20/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    usdtDenom := "factory/inj10vkkttgxdeqcgeppu20x9qtyvuaxxev8qh0awq/usdt"

    msg := erc20types.MsgDeleteTokenPair{
        Sender:    senderAddress.String(),
        BankDenom: usdtDenom,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
bank_denomstringYes

Response Parameters

Response Example:

txhash: "5AF048ADCE6AF753256F03AF2404A5B78C4C3E7E42A91F0B5C9994372E8AC2FE"
raw_log: "[]"

gas wanted: 106585
gas fee: 0.0000532925 INJ
DEBU[0001] broadcastTx with nonce 3503                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214406  fn=func1 src="client/chain/chain.go:619"
txHash=31FDA89C3122322C0559B5766CDF892FD0AA12469017CF8BF88B53441464ECC4
DEBU[0002] nonce incremented to 3504                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  133614                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000066807 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- IBC Core Channel

Includes all the messages and queries associated to channels from the IBC core channel module

Channel

Queries an IBC Channel

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"

    channel = await client.fetch_ibc_channel(port_id=port_id, channel_id=channel_id)
    print(channel)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    ctx := context.Background()

    res, err := chainClient.FetchIBCChannel(ctx, portId, channelId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes

Response Parameters

Response Example:

{
   "channel":{
      "state":"STATE_OPEN",
      "ordering":"ORDER_UNORDERED",
      "counterparty":{
         "portId":"transfer",
         "channelId":"channel-352"
      },
      "connectionHops":[
         "connection-173"
      ],
      "version":"ics20-1"
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"26820151"
   },
   "proof":""
}
ParameterTypeDescription
channelChannelchannel associated with the request identifiers
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Channel

ParameterTypeDescription
stateStatecurrent state of the channel end
orderingOrderwhether the channel is ordered or unordered
counterpartyCounterpartycounterparty channel end
connection_hopsstring arraylist of connection identifiers, in order, along which packets sent on this channel will travel
versionstringopaque channel version, which is agreed upon during the handshake
upgrade_sequenceuint64upgrade sequence indicates the latest upgrade attempt performed by this channel the value of 0 indicates the channel has never been upgraded


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Order

CodeName
0ORDER_NONE_UNSPECIFIED
1ORDER_UNORDERED
2ORDER_ORDERED


Counterparty

ParameterTypeDescription
port_idstringport on the counterparty chain which owns the other end of the channel.
channel_idstringchannel end on the counterparty chain


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

Channels

Queries all the IBC channels of a chain

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    pagination = PaginationOption(skip=2, limit=4)

    channels = await client.fetch_ibc_channels(pagination=pagination)
    print(channels)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCChannels(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination requestNo


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "channels":[
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-sweep-inj",
            "channelId":"channel-19"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1v0es67dxtlmzmauhr3krk058sp9cvt6e2hvmys2g8pjnpj30fezq93qp07\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-134"
      },
      {
         "state":"STATE_CLOSED",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-delegation-inj",
            "channelId":"channel-20"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1urqc59ft3hl75mxhru4848xusu5rhpghz48zdfypyuu923w2gzyqm8y02d\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-136"
      },
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-sweep-inj",
            "channelId":"channel-21"
         },
         "connectionHops":[
            "connection-185"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-3\",\"host_connection_id\":\"connection-185\",\"address\":\"inj1s58qfzwjduykz6emh936v8uxytvck4cf0lkvpuerh2qwt6jkaj9qh9cl7x\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-182"
      },
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-reward-inj",
            "channelId":"channel-20"
         },
         "connectionHops":[
            "connection-185"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-3\",\"host_connection_id\":\"connection-185\",\"address\":\"inj1k3cdwxqkjmmjn62tesyumlynj0n5ap2k9ysnyn56zar4uns09a5qvy575s\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-183"
      }
   ],
   "pagination":{
      "nextKey":"L3BvcnRzL2ljYWhvc3QvY2hhbm5lbHMvY2hhbm5lbC0xODQ=",
      "total":"0"
   },
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"26823064"
   }
}
ParameterTypeDescription
channelsIdentifiedChannel arraylist of stored channels of the chain.
paginationquery.PageResponsepagination response
heighttypes.Heightquery block height


IdentifiedChannel

ParameterTypeDescription
stateStatecurrent state of the channel end
orderingOrderwhether the channel is ordered or unordered
counterpartyCounterpartycounterparty channel end
connection_hopsstring arraylist of connection identifiers, in order, along which packets sent on this channel will travel
versionstringopaque channel version, which is agreed upon during the handshake
port_idstringport identifier
channel_idstringchannel identifier
upgrade_sequenceuint64upgrade sequence indicates the latest upgrade attempt performed by this channel the value of 0 indicates the channel has never been upgraded


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Order

CodeName
0ORDER_NONE_UNSPECIFIED
1ORDER_UNORDERED
2ORDER_ORDERED


Counterparty

ParameterTypeDescription
port_idstringport on the counterparty chain which owns the other end of the channel.
channel_idstringchannel end on the counterparty chain


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConnectionChannels

Queries all the channels associated with a connection end

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    connection = "connection-182"
    pagination = PaginationOption(skip=2, limit=4)

    channels = await client.fetch_ibc_connection_channels(connection=connection, pagination=pagination)
    print(channels)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    connection := "connection-182"
    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCConnectionChannels(ctx, connection, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
connectionstringconnection unique identifierYes
paginationquery.PageRequestpagination requestNo


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "channels":[
      {
         "state":"STATE_CLOSED",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-delegation-inj",
            "channelId":"channel-17"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1urqc59ft3hl75mxhru4848xusu5rhpghz48zdfypyuu923w2gzyqm8y02d\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-132"
      },
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-reward-inj",
            "channelId":"channel-18"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1mn3p9d2aw02mdrkfhleefmvr70skrx39mlkkc4f5rnewlc5aux3qs37nt6\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-133"
      },
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-sweep-inj",
            "channelId":"channel-19"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1v0es67dxtlmzmauhr3krk058sp9cvt6e2hvmys2g8pjnpj30fezq93qp07\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-134"
      },
      {
         "state":"STATE_CLOSED",
         "ordering":"ORDER_ORDERED",
         "counterparty":{
            "portId":"icacontroller-delegation-inj",
            "channelId":"channel-20"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"{\"version\":\"ics27-1\",\"controller_connection_id\":\"connection-9\",\"host_connection_id\":\"connection-182\",\"address\":\"inj1urqc59ft3hl75mxhru4848xusu5rhpghz48zdfypyuu923w2gzyqm8y02d\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\"}",
         "portId":"icahost",
         "channelId":"channel-136"
      },
      {
         "state":"STATE_OPEN",
         "ordering":"ORDER_UNORDERED",
         "counterparty":{
            "portId":"transfer",
            "channelId":"channel-16"
         },
         "connectionHops":[
            "connection-182"
         ],
         "version":"ics20-1",
         "portId":"transfer",
         "channelId":"channel-131"
      }
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   },
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"26832162"
   }
}
ParameterTypeDescription
channelsIdentifiedChannel arraylist of channels associated with a connection.
paginationquery.PageResponsepagination response
heighttypes.Heightquery block height


IdentifiedChannel

ParameterTypeDescription
stateStatecurrent state of the channel end
orderingOrderwhether the channel is ordered or unordered
counterpartyCounterpartycounterparty channel end
connection_hopsstring arraylist of connection identifiers, in order, along which packets sent on this channel will travel
versionstringopaque channel version, which is agreed upon during the handshake
port_idstringport identifier
channel_idstringchannel identifier
upgrade_sequenceuint64upgrade sequence indicates the latest upgrade attempt performed by this channel the value of 0 indicates the channel has never been upgraded


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Order

CodeName
0ORDER_NONE_UNSPECIFIED
1ORDER_UNORDERED
2ORDER_ORDERED


Counterparty

ParameterTypeDescription
port_idstringport on the counterparty chain which owns the other end of the channel.
channel_idstringchannel end on the counterparty chain


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ChannelClientState

Queries the client state for the channel associated with the provided channel identifiers

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"

    state = await client.fetch_ibc_channel_client_state(port_id=port_id, channel_id=channel_id)
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    ctx := context.Background()

    res, err := chainClient.FetchIBCChannelClientState(ctx, portId, channelId)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes

Response Parameters

Response Example:

{
   "identifiedClientState":{
      "clientId":"07-tendermint-179",
      "clientState":{
         "@type":"/ibc.lightclients.tendermint.v1.ClientState",
         "chainId":"pisco-1",
         "trustLevel":{
            "numerator":"1",
            "denominator":"3"
         },
         "trustingPeriod":"288000s",
         "unbondingPeriod":"432000s",
         "maxClockDrift":"40s",
         "frozenHeight":{
            "revisionNumber":"0",
            "revisionHeight":"0"
         },
         "latestHeight":{
            "revisionNumber":"1",
            "revisionHeight":"7990906"
         },
         "proofSpecs":[
            {
               "leafSpec":{
                  "hash":"SHA256",
                  "prehashValue":"SHA256",
                  "length":"VAR_PROTO",
                  "prefix":"AA==",
                  "prehashKey":"NO_HASH"
               },
               "innerSpec":{
                  "childOrder":[
                     0,
                     1
                  ],
                  "childSize":33,
                  "minPrefixLength":4,
                  "maxPrefixLength":12,
                  "hash":"SHA256",
                  "emptyChild":""
               },
               "maxDepth":0,
               "minDepth":0,
               "prehashKeyBeforeComparison":false
            },
            {
               "leafSpec":{
                  "hash":"SHA256",
                  "prehashValue":"SHA256",
                  "length":"VAR_PROTO",
                  "prefix":"AA==",
                  "prehashKey":"NO_HASH"
               },
               "innerSpec":{
                  "childOrder":[
                     0,
                     1
                  ],
                  "childSize":32,
                  "minPrefixLength":1,
                  "maxPrefixLength":1,
                  "hash":"SHA256",
                  "emptyChild":""
               },
               "maxDepth":0,
               "minDepth":0,
               "prehashKeyBeforeComparison":false
            }
         ],
         "upgradePath":[
            "upgrade",
            "upgradedIBCState"
         ],
         "allowUpdateAfterExpiry":true,
         "allowUpdateAfterMisbehaviour":true
      }
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"26834667"
   },
   "proof":""
}
ParameterTypeDescription
identified_client_statetypes.IdentifiedClientStateclient state associated with the channel
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


IdentifiedChannel

ParameterTypeDescription
stateStatecurrent state of the channel end
orderingOrderwhether the channel is ordered or unordered
counterpartyCounterpartycounterparty channel end
connection_hopsstring arraylist of connection identifiers, in order, along which packets sent on this channel will travel
versionstringopaque channel version, which is agreed upon during the handshake
port_idstringport identifier
channel_idstringchannel identifier
upgrade_sequenceuint64upgrade sequence indicates the latest upgrade attempt performed by this channel the value of 0 indicates the channel has never been upgraded


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Order

CodeName
0ORDER_NONE_UNSPECIFIED
1ORDER_UNORDERED
2ORDER_ORDERED


Counterparty

ParameterTypeDescription
port_idstringport on the counterparty chain which owns the other end of the channel.
channel_idstringchannel end on the counterparty chain


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ChannelConsensusState

Queries the client state for the channel associated with the provided channel identifiers

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    revision_number = 1
    revision_height = 7990906

    state = await client.fetch_ibc_channel_consensus_state(
        port_id=port_id, channel_id=channel_id, revision_number=revision_number, revision_height=revision_height
    )
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    revisionNumber := uint64(1)
    revisionHeight := uint64(7990906)
    ctx := context.Background()

    res, err := chainClient.FetchIBCChannelConsensusState(ctx, portId, channelId, revisionNumber, revisionHeight)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
revision_numberuint64revision number of the consensus stateYes
revision_heightuint64revision height of the consensus stateYes

Response Parameters

Response Example:

{
   "consensusState":{
      "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
      "timestamp":"2023-10-21T14:57:23.344911848Z",
      "root":{
         "hash":"89ggv/9AgSoyCBZ0ohhBSMI0LX+ZYe24VdUOA1x6i6I="
      },
      "nextValidatorsHash":"8DzvA/mMhLfz2C0qSK5+YtbfTopxfFpKm4kApB/u10Y="
   },
   "clientId":"07-tendermint-179",
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"26835676"
   },
   "proof":""
}
ParameterTypeDescription
consensus_statetypes1.Anyconsensus state associated with the channel
client_idstringclient ID associated with the consensus state
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

PacketCommitment

Queries a stored packet commitment hash

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    sequence = 1

    commitment = await client.fetch_ibc_packet_commitment(port_id=port_id, channel_id=channel_id, sequence=sequence)
    print(commitment)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequence := uint64(1)
    ctx := context.Background()

    res, err := chainClient.FetchIBCPacketCommitment(ctx, portId, channelId, sequence)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
sequenceuint64packet sequenceYes

Response Parameters

Response Example:

{
   "commitment":"bIKl7JAqoA1IGSDDlb0McwW2A/A77Jpph0yt87BnCO4=",
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"26836334"
   },
   "proof":""
}
ParameterTypeDescription
commitmentbyte arraypacket associated with the request fields
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

PacketCommitments

Returns all the packet commitments hashes associated with a channel

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    pagination = PaginationOption(skip=2, limit=4)

    commitment = await client.fetch_ibc_packet_commitments(
        port_id=port_id,
        channel_id=channel_id,
        pagination=pagination,
    )
    print(commitment)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCPacketCommitments(ctx, portId, channelId, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
paginationquery.PageRequestpagination requestNo

Response Parameters

Response Example:

{
   "commitments":[
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"100",
         "data":"CMcjhUhXioc12WQEv+SVK7pdCdBei9Zw2MNyKm64aII="
      },
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"101",
         "data":"hUdJyOfw9Y4X6IqtcZNwOy9vvkir2SK6MGlhqn6gF7w="
      },
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"102",
         "data":"pi3qUxhzyDrgmrTHMu+9AW3vEsGBl1W6YUsEgi/UCwo="
      },
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"103",
         "data":"eDSZipO0vWlCEzM5sS2DNL254KBMSMH5JZn0u5ccIIs="
      }
   ],
   "pagination":{
      "nextKey":"LzEwNA==",
      "total":"0"
   },
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"26836728"
   }
}
ParameterTypeDescription
commitmentsPacketState array
paginationquery.PageResponsepagination response
heighttypes.Heightquery block height


PacketState

ParameterTypeDescription
port_idstringchannel port identifier.
channel_idstringchannel unique identifier.
sequenceuint64packet sequence.
databyte arrayembedded data that represents packet state.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

PacketReceipt

Queries if a given packet sequence has been received on the queried chain

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    sequence = 1

    receipt = await client.fetch_ibc_packet_receipt(port_id=port_id, channel_id=channel_id, sequence=sequence)
    print(receipt)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequence := uint64(1)
    ctx := context.Background()

    res, err := chainClient.FetchIBCPacketReceipt(ctx, portId, channelId, sequence)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
sequenceuint64packet sequenceYes

Response Parameters

Response Example:

{
   "received":true,
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27058834"
   },
   "proof":""
}
ParameterTypeDescription
receivedboolsuccess flag for if receipt exists
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

PacketAcknowledgement

Queries a stored packet acknowledgement hash

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    sequence = 1

    acknowledgement = await client.fetch_ibc_packet_acknowledgement(
        port_id=port_id, channel_id=channel_id, sequence=sequence
    )
    print(acknowledgement)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequence := uint64(1)
    ctx := context.Background()

    res, err := chainClient.FetchIBCPacketAcknowledgement(ctx, portId, channelId, sequence)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
sequenceuint64packet sequenceYes

Response Parameters

Response Example:

{
   "acknowledgement":"CPdVftUYJv4Y2EUSvyTsdQAe268hI6R333KgqfNkCnw=",
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27065978"
   },
   "proof":""
}
ParameterTypeDescription
acknowledgementbyte arraypacket associated with the request fields
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

PacketAcknowledgements

Returns all the packet acknowledgements associated with a channel

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    sequences = [1, 2]
    pagination = PaginationOption(skip=2, limit=4)

    acknowledgements = await client.fetch_ibc_packet_acknowledgements(
        port_id=port_id,
        channel_id=channel_id,
        packet_commitment_sequences=sequences,
        pagination=pagination,
    )
    print(acknowledgements)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequences := []uint64{1, 2}
    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCPacketAcknowledgements(ctx, portId, channelId, sequences, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
paginationquery.PageRequestpagination requestNo
packet_commitment_sequencesuint64 arraylist of packet sequencesYes


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "acknowledgements":[
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"1",
         "data":"CPdVftUYJv4Y2EUSvyTsdQAe268hI6R333KgqfNkCnw="
      },
      {
         "portId":"transfer",
         "channelId":"channel-126",
         "sequence":"2",
         "data":"CPdVftUYJv4Y2EUSvyTsdQAe268hI6R333KgqfNkCnw="
      }
   ],
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"27066401"
   }
}
ParameterTypeDescription
acknowledgementsPacketState array
paginationquery.PageResponsepagination response
heighttypes.Heightquery block height

PacketState

ParameterTypeDescription
port_idstringchannel port identifier.
channel_idstringchannel unique identifier.
sequenceuint64packet sequence.
databyte arrayembedded data that represents packet state.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

UnreceivedPackets

Returns all the unreceived IBC packets associated with a channel and sequences

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"
    sequences = [1, 2]

    packets = await client.fetch_ibc_unreceived_packets(
        port_id=port_id, channel_id=channel_id, packet_commitment_sequences=sequences
    )
    print(packets)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequences := []uint64{1, 2}
    ctx := context.Background()

    res, err := chainClient.FetchIBCUnreceivedPackets(ctx, portId, channelId, sequences)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
packet_commitment_sequencesuint64 arraylist of packet sequencesYes

Response Parameters

Response Example:

{
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"27067282"
   },
   "sequences":[

   ]
}
ParameterTypeDescription
sequencesuint64 arraylist of unreceived packet sequences
heighttypes.Heightquery block height


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

UnreceivedAcks

Returns all the unreceived IBC acknowledgements associated with a channel and sequences

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"

    acks = await client.fetch_ibc_unreceived_acks(
        port_id=port_id,
        channel_id=channel_id,
    )
    print(acks)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    sequences := []uint64{1, 2}
    ctx := context.Background()

    res, err := chainClient.FetchIBCUnreceivedAcks(ctx, portId, channelId, sequences)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes
packet_ack_sequencesuint64 arraylist of acknowledgement sequencesYes

Response Parameters

Response Example:

{
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"27067653"
   },
   "sequences":[

   ]
}
ParameterTypeDescription
sequencesuint64 arraylist of unreceived acknowledgement sequences
heighttypes.Heightquery block height


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

NextSequenceReceive

Returns the next receive sequence for a given channel

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"

    sequence = await client.fetch_next_sequence_receive(
        port_id=port_id,
        channel_id=channel_id,
    )
    print(sequence)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    ctx := context.Background()

    res, err := chainClient.FetchIBCNextSequenceReceive(ctx, portId, channelId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringport unique identifierYes
channel_idstringchannel unique identifierYes

Response Parameters

Response Example:

{
   "nextSequenceReceive":"1",
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27067952"
   },
   "proof":""
}
ParameterTypeDescription
next_sequence_receiveuint64next sequence receive number
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

- IBC Core Client

Includes all the messages and queries associated to clients and consensus from the IBC core client module

ClientState

Queries an IBC light client

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"

    state = await client.fetch_ibc_client_state(client_id=client_id)
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    ctx := context.Background()

    res, err := chainClient.FetchIBCClientState(ctx, clientId)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
client_idstringclient state unique identifierYes

Response Parameters

Response Example:

{
   "clientState":{
      "@type":"/ibc.lightclients.tendermint.v1.ClientState",
      "chainId":"band-laozi-testnet4",
      "trustLevel":{
         "numerator":"1",
         "denominator":"3"
      },
      "trustingPeriod":"1209600s",
      "unbondingPeriod":"1814400s",
      "maxClockDrift":"20s",
      "frozenHeight":{
         "revisionNumber":"0",
         "revisionHeight":"0"
      },
      "latestHeight":{
         "revisionHeight":"7379538",
         "revisionNumber":"0"
      },
      "proofSpecs":[
         {
            "leafSpec":{
               "hash":"SHA256",
               "prehashValue":"SHA256",
               "length":"VAR_PROTO",
               "prefix":"AA==",
               "prehashKey":"NO_HASH"
            },
            "innerSpec":{
               "childOrder":[
                  0,
                  1
               ],
               "childSize":33,
               "minPrefixLength":4,
               "maxPrefixLength":12,
               "hash":"SHA256",
               "emptyChild":""
            },
            "maxDepth":0,
            "minDepth":0,
            "prehashKeyBeforeComparison":false
         },
         {
            "leafSpec":{
               "hash":"SHA256",
               "prehashValue":"SHA256",
               "length":"VAR_PROTO",
               "prefix":"AA==",
               "prehashKey":"NO_HASH"
            },
            "innerSpec":{
               "childOrder":[
                  0,
                  1
               ],
               "childSize":32,
               "minPrefixLength":1,
               "maxPrefixLength":1,
               "hash":"SHA256",
               "emptyChild":""
            },
            "maxDepth":0,
            "minDepth":0,
            "prehashKeyBeforeComparison":false
         }
      ],
      "upgradePath":[
         "upgrade",
         "upgradedIBCState"
      ],
      "allowUpdateAfterExpiry":true,
      "allowUpdateAfterMisbehaviour":true
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27527237"
   },
   "proof":""
}
ParameterTypeDescription
client_statetypes.Anyclient state associated with the request identifier
proofbyte arraymerkle proof of existence
proof_heightHeightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ClientStates

Queries all the IBC light clients of a chain

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    pagination = PaginationOption(skip=2, limit=4)

    states = await client.fetch_ibc_client_states(pagination=pagination)
    print(states)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCClientStates(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination requestNo

Response Parameters

Response Example:

{
   "clientStates":[
      {
         "clientId":"07-tendermint-0",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"band-laozi-testnet4",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"1209600s",
            "unbondingPeriod":"1814400s",
            "maxClockDrift":"20s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionHeight":"7379538",
               "revisionNumber":"0"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-1",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"band-laozi-testnet4",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"1209600s",
            "unbondingPeriod":"1814400s",
            "maxClockDrift":"20s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionHeight":"7692651",
               "revisionNumber":"0"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-10",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"pisco-1",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"345600s",
            "unbondingPeriod":"432000s",
            "maxClockDrift":"50s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionNumber":"1",
               "revisionHeight":"2304261"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-100",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"osmo-test-4",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"806400s",
            "unbondingPeriod":"1209600s",
            "maxClockDrift":"20s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionNumber":"4",
               "revisionHeight":"10356505"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-101",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"osmo-test-4",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"806400s",
            "unbondingPeriod":"1209600s",
            "maxClockDrift":"20s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionNumber":"4",
               "revisionHeight":"10356847"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-102",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"osmo-test-4",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"806400s",
            "unbondingPeriod":"1209600s",
            "maxClockDrift":"20s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionNumber":"4",
               "revisionHeight":"10357322"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      },
      {
         "clientId":"07-tendermint-103",
         "clientState":{
            "@type":"/ibc.lightclients.tendermint.v1.ClientState",
            "chainId":"galileo-3",
            "trustLevel":{
               "numerator":"1",
               "denominator":"3"
            },
            "trustingPeriod":"604800s",
            "unbondingPeriod":"1814400s",
            "maxClockDrift":"30s",
            "frozenHeight":{
               "revisionNumber":"0",
               "revisionHeight":"0"
            },
            "latestHeight":{
               "revisionNumber":"3",
               "revisionHeight":"2848767"
            },
            "proofSpecs":[
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":33,
                     "minPrefixLength":4,
                     "maxPrefixLength":12,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               },
               {
                  "leafSpec":{
                     "hash":"SHA256",
                     "prehashValue":"SHA256",
                     "length":"VAR_PROTO",
                     "prefix":"AA==",
                     "prehashKey":"NO_HASH"
                  },
                  "innerSpec":{
                     "childOrder":[
                        0,
                        1
                     ],
                     "childSize":32,
                     "minPrefixLength":1,
                     "maxPrefixLength":1,
                     "hash":"SHA256",
                     "emptyChild":""
                  },
                  "maxDepth":0,
                  "minDepth":0,
                  "prehashKeyBeforeComparison":false
               }
            ],
            "upgradePath":[
               "upgrade",
               "upgradedIBCState"
            ],
            "allowUpdateAfterExpiry":true,
            "allowUpdateAfterMisbehaviour":true
         }
      }
   ],
   "pagination":{
      "nextKey":"LzA3LXRlbmRlcm1pbnQtMTAzL2NsaWVudFN0YXRl",
      "total":"0"
   }
}
ParameterTypeDescription
client_statesIdentifiedClientStateslist of stored ClientStates of the chain.
paginationquery.PageResponsepagination response


IdentifiedClientState

ParameterTypeDescription
client_idstringclient identifier
client_statetypes.Anyclient state

ConsensusState

Queries a consensus state associated with a client state at a given height

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"
    revision_number = 0
    revision_height = 7379538

    state = await client.fetch_ibc_consensus_state(
        client_id=client_id, revision_number=revision_number, revision_height=revision_height
    )
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    revisionNumber := uint64(0)
    revisionHeight := uint64(7379538)
    latestHeight := false

    ctx := context.Background()

    res, err := chainClient.FetchIBCConsensusState(ctx, clientId, revisionNumber, revisionHeight, latestHeight)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
client_idstringclient identifierYes
revision_numberuint64consensus state revision numberYes
revision_heightuint64consensus state revision heightYes
latest_heightboollatest_height overrrides the height field and queries the latest stored ConsensusStateYes

Response Parameters

Response Example:

{
   "consensusState":{
      "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
      "timestamp":"2022-07-04T10:34:53.874345276Z",
      "root":{
         "hash":"viI6JuzZ/kOAh6jIeecglN7Xt+mGQT/PpvAGqGLcVmM="
      },
      "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27531028"
   },
   "proof":""
}
ParameterTypeDescription
consensus_statetypes.Anyconsensus state associated with the client identifier at the given height
proofbyte arraymerkle proof of existence
proof_heightHeightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConsensusStates

Queries all the consensus state associated with a given client

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"
    pagination = PaginationOption(skip=2, limit=4)

    states = await client.fetch_ibc_consensus_states(client_id=client_id, pagination=pagination)
    print(states)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCConsensusStates(ctx, clientId, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
client_idstringclient identifierYes
paginationquery.PageRequestpagination requestNo

Response Parameters

Response Example:

{
   "consensusStates":[
      {
         "height":{
            "revisionHeight":"7379500",
            "revisionNumber":"0"
         },
         "consensusState":{
            "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
            "timestamp":"2022-07-04T10:32:23.232327085Z",
            "root":{
               "hash":"PlwKOemX6GQh/sGlPzvT89sRijeZa0pUK+sjvASu/5s="
            },
            "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
         }
      },
      {
         "height":{
            "revisionHeight":"7379506",
            "revisionNumber":"0"
         },
         "consensusState":{
            "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
            "timestamp":"2022-07-04T10:32:46.188675417Z",
            "root":{
               "hash":"LTmLr8YzxO/yfajKO1RrnZeTK3JUMrvYcm/IZyi0XeY="
            },
            "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
         }
      },
      {
         "height":{
            "revisionHeight":"7379521",
            "revisionNumber":"0"
         },
         "consensusState":{
            "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
            "timestamp":"2022-07-04T10:33:46.953207174Z",
            "root":{
               "hash":"lyXb+gmcyDOcHL35Zppqv10y0irbqlnsllERaOEb9R4="
            },
            "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
         }
      },
      {
         "height":{
            "revisionHeight":"7379538",
            "revisionNumber":"0"
         },
         "consensusState":{
            "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
            "timestamp":"2022-07-04T10:34:53.874345276Z",
            "root":{
               "hash":"viI6JuzZ/kOAh6jIeecglN7Xt+mGQT/PpvAGqGLcVmM="
            },
            "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
         }
      }
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   }
}
ParameterTypeDescription
consensus_statesConsensusStateWithHeight arrayconsensus states associated with the identifier
paginationquery.PageResponsepagination response


ConsensusStateWithHeight

ParameterTypeDescription
heightHeightconsensus state height
consensus_statetypes.Anyconsensus state


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConsensusStateHeights

Queries the height of every consensus states associated with a given client

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"
    pagination = PaginationOption(skip=2, limit=4)

    states = await client.fetch_ibc_consensus_state_heights(client_id=client_id, pagination=pagination)
    print(states)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCConsensusStateHeights(ctx, clientId, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
client_idstringclient identifierYes
paginationquery.PageRequestpagination requestNo

Response Parameters

Response Example:

{
   "consensusStateHeights":[
      {
         "revisionHeight":"7379500",
         "revisionNumber":"0"
      },
      {
         "revisionHeight":"7379506",
         "revisionNumber":"0"
      },
      {
         "revisionHeight":"7379521",
         "revisionNumber":"0"
      },
      {
         "revisionHeight":"7379538",
         "revisionNumber":"0"
      }
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   }
}
ParameterTypeDescription
consensus_state_heightsHeight arrayconsensus state heights
paginationquery.PageResponsepagination response


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ClientStatus

Queries the status of an IBC client

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"

    state = await client.fetch_ibc_client_status(client_id=client_id)
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    ctx := context.Background()

    res, err := chainClient.FetchIBCClientStatus(ctx, clientId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
client_idstringclient unique identifierYes

Response Parameters

Response Example:

{
   "status":"Expired"
}
ParameterTypeDescription
statusstring

ClientParams

Queries all parameters of the ibc client submodule

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    params = await client.fetch_ibc_client_params()
    print(params)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchIBCClientParams(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "params":{
      "allowedClients":[
         "06-solomachine",
         "07-tendermint"
      ]
   }
}
ParameterTypeDescription
paramsParamsparams defines the parameters of the module.


Params

ParameterTypeDescription
allowed_clientsstring arrayallowed_clients defines the list of allowed client state types which can be created and interacted with. If a client type is removed from the allowed clients list, usage of this client will be disabled until it is added again to the list.

UpgradedClientState

Queries an Upgraded IBC light client

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    state = await client.fetch_ibc_upgraded_client_state()
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchIBCUpgradedClientState(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:


ParameterTypeDescription
upgraded_client_statetypes.Anyclient state associated with the request identifier

UpgradedConsensusState

Queries an Upgraded IBC consensus state

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    state = await client.fetch_ibc_upgraded_consensus_state()
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchIBCUpgradedConsensusState(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:


ParameterTypeDescription
upgraded_consensus_statetypes.AnyConsensus state associated with the request identifier

- IBC Core Connection

Includes all the messages and queries associated to connections from the IBC core connection module

Connection

Queries an IBC connection end

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    connection_id = "connection-0"

    connection = await client.fetch_ibc_connection(connection_id=connection_id)
    print(connection)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    connectionId := "connection-0"
    ctx := context.Background()

    res, err := chainClient.FetchIBCConnection(ctx, connectionId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
connection_idstringconnection unique identifierYes

Response Parameters

Response Example:

{
   "connection":{
      "clientId":"07-tendermint-0",
      "versions":[
         {
            "identifier":"1",
            "features":[
               "ORDER_ORDERED",
               "ORDER_UNORDERED"
            ]
         }
      ],
      "state":"STATE_OPEN",
      "counterparty":{
         "clientId":"07-tendermint-904",
         "connectionId":"connection-877",
         "prefix":{
            "keyPrefix":"aWJj"
         }
      },
      "delayPeriod":"0"
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27778433"
   },
   "proof":""
}
ParameterTypeDescription
connectionConnectionEndconnection associated with the request identifier
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


ConnectionEnd

ParameterTypeDescription
client_idstringclient associated with this connection.
versionsVersion arrayIBC version which can be utilised to determine encodings or protocols for channels or packets utilising this connection.
stateStatecurrent state of the connection end.
counterpartyCounterpartycounterparty chain associated with this connection.
delay_perioduint64delay period that must pass before a consensus state can be used for packet-verification NOTE: delay period logic is only implemented by some clients.


Version

ParameterTypeDescription
identifierstringunique version identifier
featuresstring arraylist of features compatible with the specified identifier


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Counterparty

ParameterTypeDescription
client_idstringidentifies the client on the counterparty chain associated with a given connection.
connection_idstringidentifies the connection end on the counterparty chain associated with a given connection.
prefixtypes.MerklePrefixcommitment merkle prefix of the counterparty chain.


MerklePrefix

ParameterTypeDescription
key_prefixbyte array


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

Connections

Queries all the IBC connections of a chain

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    pagination = PaginationOption(skip=2, limit=4)

    connections = await client.fetch_ibc_connections(pagination=pagination)
    print(connections)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchIBCConnections(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestNo


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "connections":[
      {
         "id":"connection-10",
         "clientId":"07-tendermint-12",
         "versions":[
            {
               "identifier":"1",
               "features":[
                  "ORDER_ORDERED",
                  "ORDER_UNORDERED"
               ]
            }
         ],
         "state":"STATE_OPEN",
         "counterparty":{
            "clientId":"07-tendermint-103",
            "connectionId":"connection-93",
            "prefix":{
               "keyPrefix":"aWJj"
            }
         },
         "delayPeriod":"0"
      },
      {
         "id":"connection-100",
         "clientId":"07-tendermint-126",
         "versions":[
            {
               "identifier":"1",
               "features":[
                  "ORDER_ORDERED",
                  "ORDER_UNORDERED"
               ]
            }
         ],
         "state":"STATE_OPEN",
         "counterparty":{
            "clientId":"07-tendermint-168",
            "connectionId":"connection-118",
            "prefix":{
               "keyPrefix":"aWJj"
            }
         },
         "delayPeriod":"0"
      },
      {
         "id":"connection-101",
         "clientId":"07-tendermint-127",
         "versions":[
            {
               "identifier":"1",
               "features":[
                  "ORDER_ORDERED",
                  "ORDER_UNORDERED"
               ]
            }
         ],
         "state":"STATE_OPEN",
         "counterparty":{
            "clientId":"07-tendermint-3",
            "connectionId":"connection-5",
            "prefix":{
               "keyPrefix":"aWJj"
            }
         },
         "delayPeriod":"0"
      },
      {
         "id":"connection-102",
         "clientId":"07-tendermint-128",
         "versions":[
            {
               "identifier":"1",
               "features":[
                  "ORDER_ORDERED",
                  "ORDER_UNORDERED"
               ]
            }
         ],
         "state":"STATE_OPEN",
         "counterparty":{
            "clientId":"07-tendermint-633",
            "connectionId":"connection-574",
            "prefix":{
               "keyPrefix":"aWJj"
            }
         },
         "delayPeriod":"0"
      }
   ],
   "pagination":{
      "nextKey":"L2Nvbm5lY3Rpb24tMTAz",
      "total":"0"
   },
   "height":{
      "revisionNumber":"888",
      "revisionHeight":"27779944"
   }
}
ParameterTypeDescription
connectionsIdentifiedConnection arraylist of stored connections of the chain.
paginationquery.PageResponsepagination response
heighttypes.Heightquery block height


IdentifiedConnection

ParameterTypeDescription
idstringconnection identifier.
client_idstringclient associated with this connection.
versionsVersion arrayIBC version which can be utilised to determine encodings or protocols for channels or packets utilising this connection
stateStatecurrent state of the connection end.
counterpartyCounterpartycounterparty chain associated with this connection.
delay_perioduint64delay period associated with this connection.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision


Version

ParameterTypeDescription
identifierstringunique version identifier
featuresstring arraylist of features compatible with the specified identifier


State

CodeName
0STATE_UNINITIALIZED_UNSPECIFIED
1STATE_INIT
2STATE_TRYOPEN
3STATE_OPEN
4STATE_CLOSED
5STATE_FLUSHING
6STATE_FLUSHCOMPLETE


Counterparty

ParameterTypeDescription
client_idstringidentifies the client on the counterparty chain associated with a given connection.
connection_idstringidentifies the connection end on the counterparty chain associated with a given connection.
prefixtypes.MerklePrefixcommitment merkle prefix of the counterparty chain.


MerklePrefix

ParameterTypeDescription
key_prefixbyte array

ClientConnections

Queries the connection paths associated with a client state

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    client_id = "07-tendermint-0"

    connections = await client.fetch_ibc_client_connections(client_id=client_id)
    print(connections)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    clientId := "07-tendermint-0"
    ctx := context.Background()

    res, err := chainClient.FetchIBCClientConnections(ctx, clientId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
client_idstringclient identifier associated with a connectionYes

Response Parameters

Response Example:

{
   "connectionPaths":[
      "connection-0"
   ],
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27783349"
   },
   "proof":""
}
ParameterTypeDescription
connection_pathsstring arrayslice of all the connection paths associated with a client.
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was generated


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConnectionClientState

Queries the client state associated with the connection

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    connection_id = "connection-0"

    state = await client.fetch_ibc_connection_client_state(connection_id=connection_id)
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    connectionId := "connection-0"
    ctx := context.Background()

    res, err := chainClient.FetchIBCConnectionClientState(ctx, connectionId)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
connection_idstringconnection identifierYes

Response Parameters

Response Example:

{
   "identifiedClientState":{
      "clientId":"07-tendermint-0",
      "clientState":{
         "@type":"/ibc.lightclients.tendermint.v1.ClientState",
         "chainId":"band-laozi-testnet4",
         "trustLevel":{
            "numerator":"1",
            "denominator":"3"
         },
         "trustingPeriod":"1209600s",
         "unbondingPeriod":"1814400s",
         "maxClockDrift":"20s",
         "frozenHeight":{
            "revisionNumber":"0",
            "revisionHeight":"0"
         },
         "latestHeight":{
            "revisionHeight":"7379538",
            "revisionNumber":"0"
         },
         "proofSpecs":[
            {
               "leafSpec":{
                  "hash":"SHA256",
                  "prehashValue":"SHA256",
                  "length":"VAR_PROTO",
                  "prefix":"AA==",
                  "prehashKey":"NO_HASH"
               },
               "innerSpec":{
                  "childOrder":[
                     0,
                     1
                  ],
                  "childSize":33,
                  "minPrefixLength":4,
                  "maxPrefixLength":12,
                  "hash":"SHA256",
                  "emptyChild":""
               },
               "maxDepth":0,
               "minDepth":0,
               "prehashKeyBeforeComparison":false
            },
            {
               "leafSpec":{
                  "hash":"SHA256",
                  "prehashValue":"SHA256",
                  "length":"VAR_PROTO",
                  "prefix":"AA==",
                  "prehashKey":"NO_HASH"
               },
               "innerSpec":{
                  "childOrder":[
                     0,
                     1
                  ],
                  "childSize":32,
                  "minPrefixLength":1,
                  "maxPrefixLength":1,
                  "hash":"SHA256",
                  "emptyChild":""
               },
               "maxDepth":0,
               "minDepth":0,
               "prehashKeyBeforeComparison":false
            }
         ],
         "upgradePath":[
            "upgrade",
            "upgradedIBCState"
         ],
         "allowUpdateAfterExpiry":true,
         "allowUpdateAfterMisbehaviour":true
      }
   },
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27783852"
   },
   "proof":""
}
ParameterTypeDescription
identified_client_statetypes.IdentifiedClientStateclient state associated with the channel
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


IdentifiedClientState

ParameterTypeDescription
client_idstringclient identifier
client_statetypes.Anyclient state


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConnectionConsensusState

Queries the consensus state associated with the connection

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    connection_id = "connection-0"
    revision_number = 0
    revision_height = 7379538

    state = await client.fetch_ibc_connection_consensus_state(
        connection_id=connection_id, revision_number=revision_number, revision_height=revision_height
    )
    print(state)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    connectionId := "connection-0"
    revisionNumber := uint64(0)
    revisionHeight := uint64(7379538)

    ctx := context.Background()

    res, err := chainClient.FetchIBCConnectionConsensusState(ctx, connectionId, revisionNumber, revisionHeight)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res)

}
ParameterTypeDescriptionRequired
connection_idstringconnection identifierYes
revision_numberuint64Yes
revision_heightuint64Yes

Response Parameters

Response Example:

{
   "consensusState":{
      "@type":"/ibc.lightclients.tendermint.v1.ConsensusState",
      "timestamp":"2022-07-04T10:34:53.874345276Z",
      "root":{
         "hash":"viI6JuzZ/kOAh6jIeecglN7Xt+mGQT/PpvAGqGLcVmM="
      },
      "nextValidatorsHash":"olPEfP4dzPCC07Oyg/3+6U5/uumw/HmELk2MwpMogSg="
   },
   "clientId":"07-tendermint-0",
   "proofHeight":{
      "revisionNumber":"888",
      "revisionHeight":"27784841"
   },
   "proof":""
}
ParameterTypeDescription
consensus_statetypes1.Anyconsensus state associated with the channel
client_idstringclient ID associated with the consensus state
proofbyte arraymerkle proof of existence
proof_heighttypes.Heightheight at which the proof was retrieved


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

ConnectionParams

Queries all parameters of the ibc connection submodule

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    params = await client.fetch_ibc_connection_params()
    print(params)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchIBCConnectionParams(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "params":{
      "maxExpectedTimePerBlock":"30000000000"
   }
}
ParameterTypeDescription
paramsParamsparams defines the parameters of the module.


Params

ParameterTypeDescription
max_expected_time_per_blockuint64maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the largest amount of time that the chain might reasonably take to produce the next block under normal operating conditions. A safe choice is 3-5x the expected time per block.

- IBC Transfer

Includes all the messages and queries associated to transfers from the IBC transfer module

DenomTrace

Queries a denomination trace information

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
from hashlib import sha256

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    path = "transfer/channel-126"
    base_denom = "uluna"
    full_path = f"{path}/{base_denom}"
    path_hash = sha256(full_path.encode()).hexdigest()
    trace_hash = f"ibc/{path_hash}"

    denom_trace = await client.fetch_denom_trace(hash=trace_hash)
    print(denom_trace)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    denomTrace := types.DenomTrace{
        Path:      "transfer/channel-126",
        BaseDenom: "uluna",
    }
    ctx := context.Background()

    res, err := chainClient.FetchDenomTrace(ctx, denomTrace.Hash().String())
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
hashstringhash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information.Yes

Response Parameters

Response Example:

{
   "denomTrace":{
      "path":"transfer/channel-126",
      "baseDenom":"uluna"
   }
}
ParameterTypeDescription
denom_traceDenomTracedenom_trace returns the requested denomination trace information.


DenomTrace

ParameterTypeDescription
pathstringpath defines the chain of port/channel identifiers used for tracing the source of the fungible token.
base_denomstringbase denomination of the relayed fungible token.

DenomTraces

Queries all denomination traces

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    pagination = PaginationOption(skip=2, limit=4)

    denom_traces = await client.fetch_denom_traces(pagination=pagination)
    print(denom_traces)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"
    "github.com/cosmos/cosmos-sdk/types/query"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Offset: 2, Limit: 4}
    ctx := context.Background()

    res, err := chainClient.FetchDenomTraces(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "denomTraces":[
      {
         "path":"transfer/channel-160",
         "baseDenom":"uatom"
      },
      {
         "path":"transfer/channel-2",
         "baseDenom":"uphoton"
      },
      {
         "path":"transfer/channel-43",
         "baseDenom":"uandr"
      },
      {
         "path":"transfer/channel-6",
         "baseDenom":"cw20:terra167dsqkh2alurx997wmycw9ydkyu54gyswe3ygmrs4lwume3vmwks8ruqnv"
      }
   ],
   "pagination":{
      "nextKey":"WZNnsWM6uaj4vFpbpqm1M+3mVbhdRvmgClPl/2jiXlc=",
      "total":"0"
   }
}
ParameterTypeDescription
denom_tracesTracesdenom_traces returns all denominations trace information.
paginationquery.PageResponsepagination defines the pagination in the response.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

DenomHash

Queries a denomination hash information

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    path = "transfer/channel-126"
    base_denom = "uluna"
    full_path = f"{path}/{base_denom}"

    denom_hash = await client.fetch_denom_hash(trace=full_path)
    print(denom_hash)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    path := "transfer/channel-126"
    baseDenom := "uluna"
    fullPath := fmt.Sprintf("%s/%s", path, baseDenom)
    ctx := context.Background()

    res, err := chainClient.FetchDenomHash(ctx, fullPath)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
tracestringThe denomination trace ([port_id]/[channel_id])+/[denom]Yes

Response Parameters

Response Example:

{
   "hash":"97498452BF27CC90656FD7D6EFDA287FA2BFFFF3E84691C84CB9E0451F6DF0A4"
}
ParameterTypeDescription
hashstringhash (in hex format) of the denomination trace information.

EscrowAddress

Returns the escrow address for a particular port and channel id

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    port_id = "transfer"
    channel_id = "channel-126"

    escrow_address = await client.fetch_escrow_address(port_id=port_id, channel_id=channel_id)
    print(escrow_address)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    portId := "transfer"
    channelId := "channel-126"
    ctx := context.Background()

    res, err := chainClient.FetchEscrowAddress(ctx, portId, channelId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
port_idstringunique port identifierYes
channel_idstringunique channel identifierYes

Response Parameters

Response Example:

{
   "escrowAddress":"inj1w8ent9jwwqy2d5s8grq6muk2hqa6kj2863m3mg"
}
ParameterTypeDescription
escrow_addressstringthe escrow account address

TotalEscrowForDenom

Returns the total amount of tokens in escrow based on the denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    base_denom = "uluna"

    escrow = await client.fetch_total_escrow_for_denom(denom=base_denom)
    print(escrow)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/InjectiveLabs/sdk-go/client"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "os"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    baseDenom := "uluna"
    ctx := context.Background()

    res, err := chainClient.FetchTotalEscrowForDenom(ctx, baseDenom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
denomstringYes

Response Parameters

Response Example:

{
   "amount":{
      "denom":"uluna",
      "amount":"0"
   }
}
ParameterTypeDescription
amounttypes.Coin


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

MsgTransfer

Defines a msg to transfer fungible tokens (i.e Coins) between ICS20 enabled chains. See ICS Spec here: ICS Spec

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
    )

    # load account
    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    source_port = "transfer"
    source_channel = "channel-126"
    token_decimals = 18
    transfer_amount = Decimal("0.1") * Decimal(f"1e{token_decimals}")
    inj_chain_denom = "inj"
    token_amount = composer.coin(amount=int(transfer_amount), denom=inj_chain_denom)
    sender = address.to_acc_bech32()
    receiver = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    timeout_height = 10

    # prepare tx msg
    message = composer.msg_ibc_transfer(
        source_port=source_port,
        source_channel=source_channel,
        token_amount=token_amount,
        sender=sender,
        receiver=receiver,
        timeout_height=timeout_height,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
    ibccoretypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    // initialize grpc client
    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        panic(err)
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    sourcePort := "transfer"
    sourceChannel := "channel-126"
    coin := sdktypes.Coin{
        Denom: "inj", Amount: math.NewInt(1000000000000000000), // 1 INJ
    }
    sender := senderAddress.String()
    receiver := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    timeoutHeight := ibccoretypes.Height{RevisionNumber: 10, RevisionHeight: 10}

    msg := &ibctransfertypes.MsgTransfer{
        SourcePort:    sourcePort,
        SourceChannel: sourceChannel,
        Token:         coin,
        Sender:        sender,
        Receiver:      receiver,
        TimeoutHeight: timeoutHeight,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
source_portstringthe port on which the packet will be sentYes
source_channelstringthe channel by which the packet will be sentYes
tokentypes.Cointhe tokens to be transferredYes
senderstringthe sender addressYes
receiverstringthe recipient address on the destination chainYes
timeout_heighttypes1.HeightTimeout height relative to the current block height. The timeout is disabled when set to 0.Yes
timeout_timestampuint64Timeout timestamp in absolute nanoseconds since unix epoch. The timeout is disabled when set to 0.Yes
memostringoptional memoNo


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


Height

ParameterTypeDescription
revision_numberuint64the revision that the client is currently on
revision_heightuint64the height within the given revision

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Insurance

Includes the messages to create, underwrite and redeem in insurance funds.

MsgCreateInsuranceFund

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    # set custom cookie location (optional) - defaults to current dir
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    msg = composer.msg_create_insurance_fund(
        sender=address.to_acc_bech32(),
        ticker="5202d32a9-1701406800-SF",
        quote_denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
        oracle_base="Frontrunner",
        oracle_quote="Frontrunner",
        oracle_type="Band",
        expiry=-2,
        initial_deposit=1000,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringCreator of the insurance fund.Yes
tickerstringTicker for the derivative market.Yes
quote_denomstringCoin denom to use for the market quote denomYes
oracle_basestringOracle base currency of the derivative market OR the oracle symbol for the binary options market.Yes
oracle_quotestringOracle quote currency of the derivative market OR the oracle provider for the binary options market.Yes
oracle_typetypes.OracleTypeOracle type of the binary options or derivative marketYes
expiryint64Expiration time of the derivative market. Should be -1 for perpetual or -2 for binary options markets.Yes
initial_deposittypes1.CoinInitial deposit of the insurance fundYes


OracleType

CodeName
0Unspecified
1Band
2PriceFeed
3Coinbase
4Chainlink
5Razor
6Dia
7API3
8Uma
9Pyth
10BandIBC
11Provider
12Stork

Response Parameters

Response Example:

txhash: "BB882A23CF0BC6E287F164DB2650990C7F317D9CF4CC2138B1EE479A8FB7F1CE"
raw_log: "[]"

gas wanted: 151648
gas fee: 0.000075824 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgUnderwrite

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    # set custom cookie location (optional) - defaults to current dir
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    token_decimals = 6
    amount = 100
    chain_amount = Decimal(str(amount)) * Decimal(f"1e{token_decimals}")

    msg = composer.msg_underwrite(
        sender=address.to_acc_bech32(),
        market_id="0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
        quote_denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
        amount=int(chain_amount),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringAddress of the underwriter.Yes
market_idstringMarketID of the insurance fund.Yes
deposittypes1.CoinAmount of quote_denom to underwrite the insurance fund.Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "1229C821E16F0DB89B64C86F1E00B6EE51D4B528EC5070B231C6FD8363A1A8BE"
raw_log: "[]"

gas wanted: 142042
gas fee: 0.000071021 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgRequestRedemption

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    # set custom cookie location (optional) - defaults to current dir
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    msg = composer.msg_request_redemption(
        sender=address.to_acc_bech32(),
        market_id="0x141e3c92ed55107067ceb60ee412b86256cedef67b1227d6367b4cdf30c55a74",
        share_denom="share15",
        amount=100,  # raw chain value
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringAddress of the underwriter requesting a redemption.Yes
market_idstringMarketID of the insurance fund.Yes
amounttypes1.CoinInsurance fund share token amount to be redeemed.Yes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "47982CB6CC7418FE7F2B406D40C4AD703CD87F4AA04B12E6151B648061785CD8"
raw_log: "[]"

gas wanted: 110689
gas fee: 0.0000553445 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Oracle

Includes the message to relay a price feed.

MsgRelayPriceFeedPrice

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    price = 100
    price_to_send = [str(int(price * 10**18))]
    base = ["BAYC"]
    quote = ["WETH"]

    # prepare tx msg
    msg = composer.msg_relay_price_feed_price(
        sender=address.to_acc_bech32(), price=price_to_send, base=base, quote=quote
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    oracletypes "github.com/InjectiveLabs/sdk-go/chain/oracle/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    price := []math.LegacyDec{math.LegacyMustNewDecFromStr("100")}
    base := []string{"BAYC"}
    quote := []string{"WETH"}

    msg := &oracletypes.MsgRelayPriceFeedPrice{
        Sender: senderAddress.String(),
        Price:  price,
        Base:   base,
        Quote:  quote,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, result, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, msg)

    if err != nil {
        panic(err)
    }

    fmt.Printf("Broadcast result: %s\n", result)

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringYes
basestring arrayYes
quotestring arrayYes
pricecosmossdk_io_math.LegacyDec arrayprice defines the price of the oracle base and quoteYes

Response Example:

txhash: "88F5B9C28813BB32607DF312A5411390F43C44F5E1F9D3BA0023EFE0EE4BD0EC"
raw_log: "[]"

gas wanted: 93486
gas fee: 0.000046743 INJ
DEBU[0001] broadcastTx with nonce 1314                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5215101  fn=func1 src="client/chain/chain.go:619" txHash=641DE5923625C1A81C2544B72E5029E53AE721E47F40221182AFAD6F66F39EA4
DEBU[0002] nonce incremented to 1315                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  113647                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000568235 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgRelayProviderPrices

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    provider = "ufc"
    symbols = ["KHABIB-TKO-05/30/2023", "KHABIB-TKO-05/26/2023"]
    prices = [0.5, 0.8]

    # prepare tx msg
    msg = composer.msg_relay_provider_prices(
        sender=address.to_acc_bech32(), provider=provider, symbols=symbols, prices=prices
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringYes
providerstringYes
symbolsstring arrayYes
pricescosmossdk_io_math.LegacyDec arrayYes

Response Example:

---Transaction Response---
txhash: "784728B42AD56D0241B166A531815FC82511432FF636E2AD22CBA856123F4AB1"
raw_log: "[]"

gas wanted: 172751
gas fee: 0.0000863755 INJ

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Permissions

Permissions module provides an extra layer of configuration for all actions related to tokens: mint, transfer and burn.

NamespaceDenoms

Defines a gRPC query method that returns the denoms for which a namespace exists

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    namespaces = await client.fetch_permissions_namespace_denoms()
    print(namespaces)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsNamespaceDenoms(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
  "denoms": [
    "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/reR"
  ]
}
ParameterTypeDescription
denomsstring arrayList of denoms

Namespaces

Defines a gRPC query method that returns the permissions module's created namespaces

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    namespaces = await client.fetch_permissions_namespaces()
    print(namespaces)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsNamespaces(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
 "namespaces": [
  {
   "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/reR",
   "role_permissions": [
    {
     "name": "EVERYONE",
     "permissions": 8
    },
    {
     "name": "Admin",
     "role_id": 1,
     "permissions": 2013265951
    },
    {
     "name": "Minter",
     "role_id": 2,
     "permissions": 3
    },
    {
     "name": "OtherMinter",
     "role_id": 3,
     "permissions": 1
    },
    {
     "name": "Receiver",
     "role_id": 4,
     "permissions": 2
    },
    {
     "name": "SenderAndReceiver",
     "role_id": 5,
     "permissions": 10
    },
    {
     "name": "Burner",
     "role_id": 6,
     "permissions": 4
    },
    {
     "name": "SuperBurner",
     "role_id": 7,
     "permissions": 16
    },
    {
     "name": "ModifyPolicyManagers",
     "role_id": 8,
     "permissions": 134217728
    },
    {
     "name": "ModifyContractHook",
     "role_id": 9,
     "permissions": 268435456
    },
    {
     "name": "ModifyRoleManagers",
     "role_id": 10,
     "permissions": 1073741824
    },
    {
     "name": "ModifyRolePermission",
     "role_id": 11,
     "permissions": 536870912
    },
    {
     "name": "TestToModify",
     "role_id": 12,
     "permissions": 5
    },
    {
     "name": "TestToModify2",
     "role_id": 13,
     "permissions": 7
    },
    {
     "name": "TestToModify3",
     "role_id": 14,
     "permissions": 15
    },
    {
     "name": "Blacklisted",
     "role_id": 15
    }
   ],
   "actor_roles": [
    {
     "actor": "inj1q82aa323r2vxha9mvsz5nvhc0h6unh2duk48gc",
     "roles": [
      "ModifyRolePermission"
     ]
    },
    {
     "actor": "inj1yv7jzmzcxusrvnaj86mjg59x4nc05wtz93tyhv",
     "roles": [
      "SenderAndReceiver"
     ]
    },
    {
     "actor": "inj1y5vuaw7qvltxp6vmynaf74d0gfgduk3c494x0q",
     "roles": [
      "ModifyPolicyManagers"
     ]
    },
    {
     "actor": "inj188dcnc89c5lvxvhxegju722jsnz3huls6sdw3r",
     "roles": [
      "TestToModify2",
      "OtherMinter"
     ]
    },
    {
     "actor": "inj1gxx3mkvrymyw5u7mdrnzjl6q8vcgvj85kfghkg",
     "roles": [
      "TestToModify"
     ]
    },
    {
     "actor": "inj1g5xj7flevr9nqn068wtenhjtlagpm3kd7hgq2x",
     "roles": [
      "Receiver"
     ]
    },
    {
     "actor": "inj12maj7ndrm0ytumcffd4hrl7jk05du69axnjndz",
     "roles": [
      "Burner",
      "Receiver"
     ]
    },
    {
     "actor": "inj1dku85qn8cs2648trk74kluck286sphrvhrfpfe",
     "roles": [
      "ModifyContractHook"
     ]
    },
    {
     "actor": "inj10zyguxjt3m0yfq4ae5s6flvudyqaev2p2nxzv7",
     "roles": [
      "SuperBurner",
      "Receiver"
     ]
    },
    {
     "actor": "inj1sn9yc5e27sd9c6334ufresn9356narlz0s9vdq",
     "roles": [
      "Receiver"
     ]
    },
    {
     "actor": "inj14enjvrdza0m495q77nk6cnl3c9r0u06wsugkdc",
     "roles": [
      "Receiver"
     ]
    },
    {
     "actor": "inj1kuhunpk695kn93twqhfvamg4tx2lcjafpmgx5s",
     "roles": [
      "TestToModify3"
     ]
    },
    {
     "actor": "inj1cr2jzsgmw4tf4t82nk7hskxpcsvd9c84nyy5rg",
     "roles": [
      "SenderAndReceiver"
     ]
    },
    {
     "actor": "inj16jtcqsyng98wk7fu87wpzgyx59ghle980cjrp8",
     "roles": [
      "Blacklisted"
     ]
    },
    {
     "actor": "inj16nj2c4j2e7scq8r5xkkgdjmwhpv7mw0trtjapf",
     "roles": [
      "SenderAndReceiver"
     ]
    },
    {
     "actor": "inj1mhgedl8exqca4mnmmh0r3tsgxcvz8kgj2tjukf",
     "roles": [
      "OtherMinter"
     ]
    },
    {
     "actor": "inj1az9uh3ytwcgjyy9akspdtaerfqca7jswfupgd7",
     "roles": [
      "ModifyRoleManagers"
     ]
    },
    {
     "actor": "inj1a0cl5hagkcncjsylsqryk8rze9m56gda60f68s",
     "roles": [
      "Blacklisted"
     ]
    },
    {
     "actor": "inj1aj6yxg97ynvyewdyf76q47yn49f6t622ftmud6",
     "roles": [
      "Minter"
     ]
    },
    {
     "actor": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "roles": [
      "Admin"
     ]
    }
   ],
   "role_managers": [
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "roles": [
      "EVERYONE",
      "Admin",
      "Minter",
      "OtherMinter",
      "Receiver",
      "SenderAndReceiver",
      "Burner",
      "SuperBurner",
      "ModifyPolicyManagers",
      "ModifyContractHook",
      "ModifyRoleManagers",
      "ModifyRolePermission",
      "TestToModify",
      "TestToModify2",
      "TestToModify3",
      "Blacklisted"
     ]
    }
   ],
   "policy_statuses": [
    {
     "action": 134217728
    },
    {
     "action": 268435456
    },
    {
     "action": 536870912
    },
    {
     "action": 1073741824
    },
    {
     "action": 1
    },
    {
     "action": 2
    },
    {
     "action": 4
    },
    {
     "action": 8
    },
    {
     "action": 16
    }
   ],
   "policy_manager_capabilities": [
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 134217728,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 268435456,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 536870912,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 1073741824,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 1,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 2,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 4,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 8,
     "can_disable": true,
     "can_seal": true
    },
    {
     "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
     "action": 16,
     "can_disable": true,
     "can_seal": true
    }
   ]
  }
 ]
}
ParameterTypeDescription
namespacesNamespace arrayList of namespaces


Namespace

ParameterTypeDescription
denomstringThe tokenfactory denom to which this namespace applies to
contract_hookstringThe address of smart contract to apply code-based restrictions
role_permissionsRole arraypermissions for each role
actor_rolesActorRoles arrayroles for each actor
role_managersRoleManager arraymanagers for each role
policy_statusesPolicyStatus arraystatus for each policy
policy_manager_capabilitiesPolicyManagerCapability arraycapabilities for each manager for each policy


Role

ParameterTypeDescription
namestringThe role name
role_iduint32The role ID
permissionsuint32Integer representing the bitwise combination of all actions assigned to the role


ActorRoles

ParameterTypeDescription
actorstringThe actor name
rolesstring arrayThe roles for the actor


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

Namespace

Defines a gRPC query method that returns the permissions module's namespace associated with the provided denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    namespace = await client.fetch_permissions_namespace(denom=denom)
    print(namespace)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    namespaceDenom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsNamespace(ctx, namespaceDenom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes

Response Parameters

Response Example:

{
 "namespace": {
  "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/reR",
  "role_permissions": [
   {
    "name": "EVERYONE",
    "permissions": 8
   },
   {
    "name": "Admin",
    "role_id": 1,
    "permissions": 2013265951
   },
   {
    "name": "Minter",
    "role_id": 2,
    "permissions": 3
   },
   {
    "name": "OtherMinter",
    "role_id": 3,
    "permissions": 1
   },
   {
    "name": "Receiver",
    "role_id": 4,
    "permissions": 2
   },
   {
    "name": "SenderAndReceiver",
    "role_id": 5,
    "permissions": 10
   },
   {
    "name": "Burner",
    "role_id": 6,
    "permissions": 4
   },
   {
    "name": "SuperBurner",
    "role_id": 7,
    "permissions": 16
   },
   {
    "name": "ModifyPolicyManagers",
    "role_id": 8,
    "permissions": 134217728
   },
   {
    "name": "ModifyContractHook",
    "role_id": 9,
    "permissions": 268435456
   },
   {
    "name": "ModifyRoleManagers",
    "role_id": 10,
    "permissions": 1073741824
   },
   {
    "name": "ModifyRolePermission",
    "role_id": 11,
    "permissions": 536870912
   },
   {
    "name": "TestToModify",
    "role_id": 12,
    "permissions": 5
   },
   {
    "name": "TestToModify2",
    "role_id": 13,
    "permissions": 7
   },
   {
    "name": "TestToModify3",
    "role_id": 14,
    "permissions": 15
   },
   {
    "name": "Blacklisted",
    "role_id": 15
   }
  ],
  "actor_roles": [
   {
    "actor": "inj1q82aa323r2vxha9mvsz5nvhc0h6unh2duk48gc",
    "roles": [
     "ModifyRolePermission"
    ]
   },
   {
    "actor": "inj1yv7jzmzcxusrvnaj86mjg59x4nc05wtz93tyhv",
    "roles": [
     "SenderAndReceiver"
    ]
   },
   {
    "actor": "inj1y5vuaw7qvltxp6vmynaf74d0gfgduk3c494x0q",
    "roles": [
     "ModifyPolicyManagers"
    ]
   },
   {
    "actor": "inj188dcnc89c5lvxvhxegju722jsnz3huls6sdw3r",
    "roles": [
     "TestToModify2",
     "OtherMinter"
    ]
   },
   {
    "actor": "inj1gxx3mkvrymyw5u7mdrnzjl6q8vcgvj85kfghkg",
    "roles": [
     "TestToModify"
    ]
   },
   {
    "actor": "inj1g5xj7flevr9nqn068wtenhjtlagpm3kd7hgq2x",
    "roles": [
     "Receiver"
    ]
   },
   {
    "actor": "inj12maj7ndrm0ytumcffd4hrl7jk05du69axnjndz",
    "roles": [
     "Burner",
     "Receiver"
    ]
   },
   {
    "actor": "inj1dku85qn8cs2648trk74kluck286sphrvhrfpfe",
    "roles": [
     "ModifyContractHook"
    ]
   },
   {
    "actor": "inj10zyguxjt3m0yfq4ae5s6flvudyqaev2p2nxzv7",
    "roles": [
     "SuperBurner",
     "Receiver"
    ]
   },
   {
    "actor": "inj1sn9yc5e27sd9c6334ufresn9356narlz0s9vdq",
    "roles": [
     "Receiver"
    ]
   },
   {
    "actor": "inj14enjvrdza0m495q77nk6cnl3c9r0u06wsugkdc",
    "roles": [
     "Receiver"
    ]
   },
   {
    "actor": "inj1kuhunpk695kn93twqhfvamg4tx2lcjafpmgx5s",
    "roles": [
     "TestToModify3"
    ]
   },
   {
    "actor": "inj1cr2jzsgmw4tf4t82nk7hskxpcsvd9c84nyy5rg",
    "roles": [
     "SenderAndReceiver"
    ]
   },
   {
    "actor": "inj16jtcqsyng98wk7fu87wpzgyx59ghle980cjrp8",
    "roles": [
     "Blacklisted"
    ]
   },
   {
    "actor": "inj16nj2c4j2e7scq8r5xkkgdjmwhpv7mw0trtjapf",
    "roles": [
     "SenderAndReceiver"
    ]
   },
   {
    "actor": "inj1mhgedl8exqca4mnmmh0r3tsgxcvz8kgj2tjukf",
    "roles": [
     "OtherMinter"
    ]
   },
   {
    "actor": "inj1az9uh3ytwcgjyy9akspdtaerfqca7jswfupgd7",
    "roles": [
     "ModifyRoleManagers"
    ]
   },
   {
    "actor": "inj1a0cl5hagkcncjsylsqryk8rze9m56gda60f68s",
    "roles": [
     "Blacklisted"
    ]
   },
   {
    "actor": "inj1aj6yxg97ynvyewdyf76q47yn49f6t622ftmud6",
    "roles": [
     "Minter"
    ]
   },
   {
    "actor": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "roles": [
     "Admin"
    ]
   }
  ],
  "role_managers": [
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "roles": [
     "EVERYONE",
     "Admin",
     "Minter",
     "OtherMinter",
     "Receiver",
     "SenderAndReceiver",
     "Burner",
     "SuperBurner",
     "ModifyPolicyManagers",
     "ModifyContractHook",
     "ModifyRoleManagers",
     "ModifyRolePermission",
     "TestToModify",
     "TestToModify2",
     "TestToModify3",
     "Blacklisted"
    ]
   }
  ],
  "policy_statuses": [
   {
    "action": 134217728
   },
   {
    "action": 268435456
   },
   {
    "action": 536870912
   },
   {
    "action": 1073741824
   },
   {
    "action": 1
   },
   {
    "action": 2
   },
   {
    "action": 4
   },
   {
    "action": 8
   },
   {
    "action": 16
   }
  ],
  "policy_manager_capabilities": [
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 134217728,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 268435456,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 536870912,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 1073741824,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 1,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 2,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 4,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 8,
    "can_disable": true,
    "can_seal": true
   },
   {
    "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
    "action": 16,
    "can_disable": true,
    "can_seal": true
   }
  ]
 }
}
ParameterTypeDescription
namespaceNamespaceThe namespace details


Namespace

ParameterTypeDescription
denomstringThe tokenfactory denom to which this namespace applies to
contract_hookstringThe address of smart contract to apply code-based restrictions
role_permissionsRole arraypermissions for each role
actor_rolesActorRoles arrayroles for each actor
role_managersRoleManager arraymanagers for each role
policy_statusesPolicyStatus arraystatus for each policy
policy_manager_capabilitiesPolicyManagerCapability arraycapabilities for each manager for each policy


Role

ParameterTypeDescription
namestringThe role name
role_iduint32The role ID
permissionsuint32Integer representing the bitwise combination of all actions assigned to the role


ActorRoles

ParameterTypeDescription
actorstringThe actor name
rolesstring arrayThe roles for the actor


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

RolesByActor

Defines a gRPC query method that returns roles for the actor in the namespace

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    actor = "actor"
    roles = await client.fetch_permissions_roles_by_actor(denom=denom, actor=actor)
    print(roles)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    namespaceDenom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    actor := senderAddress.String()

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsRolesByActor(ctx, namespaceDenom, actor)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes
actorstringThe actor's Injective addressYes

Response Parameters

Response Example:

{
 "roles": [
  "ModifyRolePermission"
 ]
}
ParameterTypeDescription
rolesstring arrayList of roles

ActorsByRole

Defines a gRPC query method that returns a namespace's roles associated with the provided actor

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    role = "roleName"
    addresses = await client.fetch_permissions_actors_by_role(denom=denom, role=role)
    print(addresses)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    namespaceDenom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    role := "blacklisted"

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsActorsByRole(ctx, namespaceDenom, role)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes
rolestringThe role to query actors forYes

Response Parameters

Response Example:

{
 "actors": [
  "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z"
 ]
}
ParameterTypeDescription
actorsstring arrayList of actors' Injective addresses

RoleManagers

Defines a gRPC query method that returns a namespace's role managers

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    managers = await client.fetch_permissions_role_managers(denom=denom)
    print(managers)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    res, err := chainClient.FetchPermissionsRoleManagers(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes

Response Parameters

Response Example:

{
 "role_managers": [
  {
   "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
   "roles": [
    "EVERYONE",
    "Admin",
    "Minter",
    "OtherMinter",
    "Receiver",
    "SenderAndReceiver",
    "Burner",
    "SuperBurner",
    "ModifyPolicyManagers",
    "ModifyContractHook",
    "ModifyRoleManagers",
    "ModifyRolePermission",
    "TestToModify",
    "TestToModify2",
    "TestToModify3",
    "Blacklisted"
   ]
  }
 ]
}
ParameterTypeDescription
role_managersRoleManager arrayList of role managers


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager

RoleManager

Defines a gRPC query method that returns the roles a given role manager manages for a given namespace

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    manager = "manager"
    managers = await client.fetch_permissions_role_manager(denom=denom, manager=manager)
    print(managers)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    manager := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    res, err := chainClient.FetchPermissionsRoleManager(ctx, denom, manager)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes
managerstringThe manager Injective addressYes

Response Parameters

Response Example:

{
 "role_manager": {
  "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
  "roles": [
   "EVERYONE",
   "Admin",
   "Minter",
   "OtherMinter",
   "Receiver",
   "SenderAndReceiver",
   "Burner",
   "SuperBurner",
   "ModifyPolicyManagers",
   "ModifyContractHook",
   "ModifyRoleManagers",
   "ModifyRolePermission",
   "TestToModify",
   "TestToModify2",
   "TestToModify3",
   "Blacklisted"
  ]
 }
}
ParameterTypeDescription
role_managerRoleManagerThe role manager details


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager

PolicyStatuses

Defines a gRPC query method that returns a namespace's policy statuses

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    policy_statuses = await client.fetch_permissions_policy_statuses(denom=denom)
    print(policy_statuses)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    res, err := chainClient.FetchPermissionsPolicyStatuses(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes

Response Parameters

Response Example:

{
 "policy_statuses": [
  {
   "action": 134217728
  },
  {
   "action": 268435456
  },
  {
   "action": 536870912
  },
  {
   "action": 1073741824
  },
  {
   "action": 1
  },
  {
   "action": 2
  },
  {
   "action": 4
  },
  {
   "action": 8
  },
  {
   "action": 16
  }
 ]
}
ParameterTypeDescription
policy_statusesPolicyStatus arrayList of policy statuses


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

PolicyManagerCapabilities

Defines a gRPC query method that returns a namespace's policy manager capabilities

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    policy_manager_capabilities = await client.fetch_permissions_policy_manager_capabilities(denom=denom)
    print(policy_manager_capabilities)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    res, err := chainClient.FetchPermissionsPolicyStatuses(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes

Response Parameters

Response Example:

{
 "policy_statuses": [
  {
   "action": 134217728
  },
  {
   "action": 268435456
  },
  {
   "action": 536870912
  },
  {
   "action": 1073741824
  },
  {
   "action": 1
  },
  {
   "action": 2
  },
  {
   "action": 4
  },
  {
   "action": 8
  },
  {
   "action": 16
  }
 ]
}
ParameterTypeDescription
policy_manager_capabilitiesPolicyManagerCapability arrayList of policy manager capabilities


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

Vouchers

Defines a gRPC query method for the vouchers for a given denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    vouchers = await client.fetch_permissions_vouchers(denom=denom)
    print(vouchers)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    res, err := chainClient.FetchPermissionsVouchers(ctx, denom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes

Response Parameters

Response Example:


ParameterTypeDescription
vouchersAddressVoucher arrayList of vouchers


AddressVoucher

ParameterTypeDescription
addressstringThe Injective address that the voucher is for
vouchergithub_com_cosmos_cosmos_sdk_types.CoinThe voucher amount


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Voucher

Defines a gRPC query method for the vouchers for a given denom and address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    denom = "inj"
    address = "inj1knhahceyp57j5x7xh69p7utegnnnfgxavmahjr"
    voucher = await client.fetch_permissions_voucher(denom=denom, address=address)
    print(voucher)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    address := "inj1knhahceyp57j5x7xh69p7utegnnnfgxavmahjr"

    res, err := chainClient.FetchPermissionsVoucher(ctx, denom, address)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))
}
ParameterTypeDescriptionRequired
denomstringThe token denomYes
addressstringThe Injective address of the receiverYes

Response Parameters

Response Example:


ParameterTypeDescription
vouchergithub_com_cosmos_cosmos_sdk_types.CoinThe voucher amount


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

PermissionsModuleState

Retrieves the entire permissions module's state

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    state = await client.fetch_permissions_module_state()
    print(state)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchPermissionsModuleState(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
 "state": {
  "params": {
   "wasm_hook_query_max_gas": 200000
  },
  "namespaces": [
   {
    "denom": "factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/reR",
    "role_permissions": [
     {
      "name": "EVERYONE",
      "permissions": 8
     },
     {
      "name": "Admin",
      "role_id": 1,
      "permissions": 2013265951
     },
     {
      "name": "Minter",
      "role_id": 2,
      "permissions": 3
     },
     {
      "name": "OtherMinter",
      "role_id": 3,
      "permissions": 1
     },
     {
      "name": "Receiver",
      "role_id": 4,
      "permissions": 2
     },
     {
      "name": "SenderAndReceiver",
      "role_id": 5,
      "permissions": 10
     },
     {
      "name": "Burner",
      "role_id": 6,
      "permissions": 4
     },
     {
      "name": "SuperBurner",
      "role_id": 7,
      "permissions": 16
     },
     {
      "name": "ModifyPolicyManagers",
      "role_id": 8,
      "permissions": 134217728
     },
     {
      "name": "ModifyContractHook",
      "role_id": 9,
      "permissions": 268435456
     },
     {
      "name": "ModifyRoleManagers",
      "role_id": 10,
      "permissions": 1073741824
     },
     {
      "name": "ModifyRolePermission",
      "role_id": 11,
      "permissions": 536870912
     },
     {
      "name": "TestToModify",
      "role_id": 12,
      "permissions": 5
     },
     {
      "name": "TestToModify2",
      "role_id": 13,
      "permissions": 7
     },
     {
      "name": "TestToModify3",
      "role_id": 14,
      "permissions": 15
     },
     {
      "name": "Blacklisted",
      "role_id": 15
     }
    ],
    "actor_roles": [
     {
      "actor": "inj1q82aa323r2vxha9mvsz5nvhc0h6unh2duk48gc",
      "roles": [
       "ModifyRolePermission"
      ]
     },
     {
      "actor": "inj1yv7jzmzcxusrvnaj86mjg59x4nc05wtz93tyhv",
      "roles": [
       "SenderAndReceiver"
      ]
     },
     {
      "actor": "inj1y5vuaw7qvltxp6vmynaf74d0gfgduk3c494x0q",
      "roles": [
       "ModifyPolicyManagers"
      ]
     },
     {
      "actor": "inj188dcnc89c5lvxvhxegju722jsnz3huls6sdw3r",
      "roles": [
       "TestToModify2",
       "OtherMinter"
      ]
     },
     {
      "actor": "inj1gxx3mkvrymyw5u7mdrnzjl6q8vcgvj85kfghkg",
      "roles": [
       "TestToModify"
      ]
     },
     {
      "actor": "inj1g5xj7flevr9nqn068wtenhjtlagpm3kd7hgq2x",
      "roles": [
       "Receiver"
      ]
     },
     {
      "actor": "inj12maj7ndrm0ytumcffd4hrl7jk05du69axnjndz",
      "roles": [
       "Burner",
       "Receiver"
      ]
     },
     {
      "actor": "inj1dku85qn8cs2648trk74kluck286sphrvhrfpfe",
      "roles": [
       "ModifyContractHook"
      ]
     },
     {
      "actor": "inj10zyguxjt3m0yfq4ae5s6flvudyqaev2p2nxzv7",
      "roles": [
       "SuperBurner",
       "Receiver"
      ]
     },
     {
      "actor": "inj1sn9yc5e27sd9c6334ufresn9356narlz0s9vdq",
      "roles": [
       "Receiver"
      ]
     },
     {
      "actor": "inj14enjvrdza0m495q77nk6cnl3c9r0u06wsugkdc",
      "roles": [
       "Receiver"
      ]
     },
     {
      "actor": "inj1kuhunpk695kn93twqhfvamg4tx2lcjafpmgx5s",
      "roles": [
       "TestToModify3"
      ]
     },
     {
      "actor": "inj1cr2jzsgmw4tf4t82nk7hskxpcsvd9c84nyy5rg",
      "roles": [
       "SenderAndReceiver"
      ]
     },
     {
      "actor": "inj16jtcqsyng98wk7fu87wpzgyx59ghle980cjrp8",
      "roles": [
       "Blacklisted"
      ]
     },
     {
      "actor": "inj16nj2c4j2e7scq8r5xkkgdjmwhpv7mw0trtjapf",
      "roles": [
       "SenderAndReceiver"
      ]
     },
     {
      "actor": "inj1mhgedl8exqca4mnmmh0r3tsgxcvz8kgj2tjukf",
      "roles": [
       "OtherMinter"
      ]
     },
     {
      "actor": "inj1az9uh3ytwcgjyy9akspdtaerfqca7jswfupgd7",
      "roles": [
       "ModifyRoleManagers"
      ]
     },
     {
      "actor": "inj1a0cl5hagkcncjsylsqryk8rze9m56gda60f68s",
      "roles": [
       "Blacklisted"
      ]
     },
     {
      "actor": "inj1aj6yxg97ynvyewdyf76q47yn49f6t622ftmud6",
      "roles": [
       "Minter"
      ]
     },
     {
      "actor": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "roles": [
       "Admin"
      ]
     }
    ],
    "role_managers": [
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "roles": [
       "EVERYONE",
       "Admin",
       "Minter",
       "OtherMinter",
       "Receiver",
       "SenderAndReceiver",
       "Burner",
       "SuperBurner",
       "ModifyPolicyManagers",
       "ModifyContractHook",
       "ModifyRoleManagers",
       "ModifyRolePermission",
       "TestToModify",
       "TestToModify2",
       "TestToModify3",
       "Blacklisted"
      ]
     }
    ],
    "policy_statuses": [
     {
      "action": 134217728
     },
     {
      "action": 268435456
     },
     {
      "action": 536870912
     },
     {
      "action": 1073741824
     },
     {
      "action": 1
     },
     {
      "action": 2
     },
     {
      "action": 4
     },
     {
      "action": 8
     },
     {
      "action": 16
     }
    ],
    "policy_manager_capabilities": [
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 134217728,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 268435456,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 536870912,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 1073741824,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 1,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 2,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 4,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 8,
      "can_disable": true,
      "can_seal": true
     },
     {
      "manager": "inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z",
      "action": 16,
      "can_disable": true,
      "can_seal": true
     }
    ]
   }
  ]
 }
}
ParameterTypeDescription
stateGenesisStateThe module state


GenesisState

ParameterTypeDescription
paramsParamsparams defines the parameters of the module
namespacesNamespace arraynamespaces defines the namespaces of the module
vouchersAddressVoucher arrayvouchers defines the vouchers of the module


Params

ParameterTypeDescription
wasm_hook_query_max_gasuint64Max amount of gas allowed for wasm hook queries


Namespace

ParameterTypeDescription
denomstringThe tokenfactory denom to which this namespace applies to
contract_hookstringThe address of smart contract to apply code-based restrictions
role_permissionsRole arraypermissions for each role
actor_rolesActorRoles arrayroles for each actor
role_managersRoleManager arraymanagers for each role
policy_statusesPolicyStatus arraystatus for each policy
policy_manager_capabilitiesPolicyManagerCapability arraycapabilities for each manager for each policy


AddressVoucher

ParameterTypeDescription
addressstringThe Injective address that the voucher is for
vouchergithub_com_cosmos_cosmos_sdk_types.CoinThe voucher amount


Role

ParameterTypeDescription
namestringThe role name
role_iduint32The role ID
permissionsuint32Integer representing the bitwise combination of all actions assigned to the role


ActorRoles

ParameterTypeDescription
actorstringThe actor name
rolesstring arrayThe roles for the actor


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

CreateNamespace

Message to create a new namespace

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.devnet()
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    role1 = composer.permissions_role(
        name="EVERYONE",
        role_id=0,
        permissions=composer.PERMISSIONS_ACTION["RECEIVE"] | composer.PERMISSIONS_ACTION["SEND"],
    )
    role2 = composer.permissions_role(
        name="admin",
        role_id=1,
        permissions=composer.PERMISSIONS_ACTION["MODIFY_ROLE_PERMISSIONS"]
        | composer.PERMISSIONS_ACTION["MODIFY_ADDRESS_ROLES"],
    )
    role3 = composer.permissions_role(
        name="user",
        role_id=2,
        permissions=composer.PERMISSIONS_ACTION["MINT"]
        | composer.PERMISSIONS_ACTION["RECEIVE"]
        | composer.PERMISSIONS_ACTION["BURN"]
        | composer.PERMISSIONS_ACTION["SEND"],
    )

    actor_role1 = composer.permissions_actor_roles(
        actor="inj1specificactoraddress",
        roles=["admin"],
    )
    actor_role2 = composer.permissions_actor_roles(
        actor="inj1anotheractoraddress",
        roles=["user"],
    )

    role_manager = composer.permissions_role_manager(
        manager="inj1manageraddress",
        roles=["admin"],
    )

    policy_status1 = composer.permissions_policy_status(
        action=composer.PERMISSIONS_ACTION["MINT"],
        is_disabled=False,
        is_sealed=False,
    )
    policy_status2 = composer.permissions_policy_status(
        action=composer.PERMISSIONS_ACTION["BURN"],
        is_disabled=False,
        is_sealed=False,
    )

    policy_manager_capability = composer.permissions_policy_manager_capability(
        manager="inj1policymanageraddress",
        action=composer.PERMISSIONS_ACTION["MODIFY_CONTRACT_HOOK"],
        can_disable=True,
        can_seal=False,
    )

    message = composer.msg_create_namespace(
        sender=address.to_acc_bech32(),
        denom=denom,
        contract_hook="",
        role_permissions=[role1, role2, role3],
        actor_roles=[actor_role1, actor_role2],
        role_managers=[role_manager],
        policy_statuses=[policy_status1, policy_status2],
        policy_manager_capabilities=[policy_manager_capability],
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    permissionstypes "github.com/InjectiveLabs/sdk-go/chain/permissions/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    role1 := permissionstypes.Role{
        Name:        "EVERYONE",
        RoleId:      0,
        Permissions: uint32(permissionstypes.Action_RECEIVE | permissionstypes.Action_SEND),
    }
    role2 := permissionstypes.Role{
        Name:        "admin",
        RoleId:      1,
        Permissions: uint32(permissionstypes.Action_MODIFY_ROLE_PERMISSIONS),
    }
    role3 := permissionstypes.Role{
        Name:   "user",
        RoleId: 2,
        Permissions: uint32(
            permissionstypes.Action_MINT |
                permissionstypes.Action_RECEIVE |
                permissionstypes.Action_BURN |
                permissionstypes.Action_SEND),
    }

    actor_role1 := permissionstypes.ActorRoles{
        Actor: "inj1specificactoraddress",
        Roles: []string{"admin"},
    }
    actor_role2 := permissionstypes.ActorRoles{
        Actor: "inj1anotheractoraddress",
        Roles: []string{"user"},
    }

    role_manager := permissionstypes.RoleManager{
        Manager: "inj1manageraddress",
        Roles:   []string{"admin"},
    }

    policy_status1 := permissionstypes.PolicyStatus{
        Action:     permissionstypes.Action_MINT,
        IsDisabled: false,
        IsSealed:   false,
    }
    policy_status2 := permissionstypes.PolicyStatus{
        Action:     permissionstypes.Action_BURN,
        IsDisabled: false,
        IsSealed:   false,
    }

    policy_manager_capability := permissionstypes.PolicyManagerCapability{
        Manager:    "inj1policymanageraddress",
        Action:     permissionstypes.Action_MODIFY_CONTRACT_HOOK,
        CanDisable: true,
        CanSeal:    false,
    }

    namespace := permissionstypes.Namespace{
        Denom:                     denom,
        ContractHook:              "",
        RolePermissions:           []*permissionstypes.Role{&role1, &role2, &role3},
        ActorRoles:                []*permissionstypes.ActorRoles{&actor_role1, &actor_role2},
        RoleManagers:              []*permissionstypes.RoleManager{&role_manager},
        PolicyStatuses:            []*permissionstypes.PolicyStatus{&policy_status1, &policy_status2},
        PolicyManagerCapabilities: []*permissionstypes.PolicyManagerCapability{&policy_manager_capability},
    }

    msg := &permissionstypes.MsgCreateNamespace{
        Sender:    senderAddress.String(),
        Namespace: namespace,
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    pollInterval := 100 * time.Millisecond
    response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
namespaceNamespaceThe namespace informationYes


Namespace

ParameterTypeDescription
denomstringThe tokenfactory denom to which this namespace applies to
contract_hookstringThe address of smart contract to apply code-based restrictions
role_permissionsRole arraypermissions for each role
actor_rolesActorRoles arrayroles for each actor
role_managersRoleManager arraymanagers for each role
policy_statusesPolicyStatus arraystatus for each policy
policy_manager_capabilitiesPolicyManagerCapability arraycapabilities for each manager for each policy


Role

ParameterTypeDescription
namestringThe role name
role_iduint32The role ID
permissionsuint32Integer representing the bitwise combination of all actions assigned to the role


ActorRoles

ParameterTypeDescription
actorstringThe actor name
rolesstring arrayThe roles for the actor


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

UpdateNamespace

Message to update a namespace configuration

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.devnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    role1 = composer.permissions_role(
        name="EVERYONE",
        role_id=0,
        permissions=composer.PERMISSIONS_ACTION["UNSPECIFIED"],  # revoke all permissions
    )
    role2 = composer.permissions_role(
        name="user",
        role_id=2,
        permissions=composer.PERMISSIONS_ACTION["RECEIVE"] | composer.PERMISSIONS_ACTION["SEND"],
    )

    role_manager = composer.permissions_role_manager(
        manager="inj1manageraddress",
        roles=["admin", "user"],
    )

    policy_status1 = composer.permissions_policy_status(
        action=composer.PERMISSIONS_ACTION["MINT"],
        is_disabled=True,
        is_sealed=False,
    )
    policy_status2 = composer.permissions_policy_status(
        action=composer.PERMISSIONS_ACTION["BURN"],
        is_disabled=False,
        is_sealed=True,
    )

    policy_manager_capability = composer.permissions_policy_manager_capability(
        manager="inj1policymanageraddress",
        action=composer.PERMISSIONS_ACTION["MODIFY_ROLE_PERMISSIONS"],
        can_disable=True,
        can_seal=False,
    )

    message = composer.msg_update_namespace(
        sender=address.to_acc_bech32(),
        denom=denom,
        contract_hook="inj19ld6swyldyujcn72j7ugnu9twafhs9wxlyye5m",
        role_permissions=[role1, role2],
        role_managers=[role_manager],
        policy_statuses=[policy_status1, policy_status2],
        policy_manager_capabilities=[policy_manager_capability],
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    permissionstypes "github.com/InjectiveLabs/sdk-go/chain/permissions/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    role1 := permissionstypes.Role{
        Name:        "EVERYONE",
        RoleId:      0,
        Permissions: uint32(permissionstypes.Action_UNSPECIFIED),
    }
    role2 := permissionstypes.Role{
        Name:        "user",
        RoleId:      2,
        Permissions: uint32(permissionstypes.Action_RECEIVE | permissionstypes.Action_SEND),
    }

    role_manager := permissionstypes.RoleManager{
        Manager: "inj1manageraddress",
        Roles:   []string{"admin", "user"},
    }

    policy_status1 := permissionstypes.PolicyStatus{
        Action:     permissionstypes.Action_MINT,
        IsDisabled: true,
        IsSealed:   false,
    }
    policy_status2 := permissionstypes.PolicyStatus{
        Action:     permissionstypes.Action_BURN,
        IsDisabled: false,
        IsSealed:   true,
    }

    policy_manager_capability := permissionstypes.PolicyManagerCapability{
        Manager:    "inj1policymanageraddress",
        Action:     permissionstypes.Action_MODIFY_ROLE_PERMISSIONS,
        CanDisable: true,
        CanSeal:    false,
    }

    msg := &permissionstypes.MsgUpdateNamespace{
        Sender:                    senderAddress.String(),
        Denom:                     denom,
        ContractHook:              &permissionstypes.MsgUpdateNamespace_SetContractHook{NewValue: "inj19ld6swyldyujcn72j7ugnu9twafhs9wxlyye5m"},
        RolePermissions:           []*permissionstypes.Role{&role1, &role2},
        RoleManagers:              []*permissionstypes.RoleManager{&role_manager},
        PolicyStatuses:            []*permissionstypes.PolicyStatus{&policy_status1, &policy_status2},
        PolicyManagerCapabilities: []*permissionstypes.PolicyManagerCapability{&policy_manager_capability},
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    pollInterval := 100 * time.Millisecond
    response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
denomstringdenom whose namespace updates are to be appliedYes
contract_hookMsgUpdateNamespace_SetContractHookaddress of smart contract to apply code-based restrictionsNo
role_permissionsRole arrayrole permissions to updateNo
role_managersRoleManager arrayrole managers to updateNo
policy_statusesPolicyStatus arraypolicy statuses to updateNo
policy_manager_capabilitiesPolicyManagerCapability arraypolicy manager capabilities to updateNo


MsgUpdateNamespace_SetContractHook

ParameterTypeDescriptionRequired
new_valuestringYes


Role

ParameterTypeDescription
namestringThe role name
role_iduint32The role ID
permissionsuint32Integer representing the bitwise combination of all actions assigned to the role


RoleManager

ParameterTypeDescription
managerstringThe manager name
rolesstring arrayList of roles associated with the manager


PolicyStatus

ParameterTypeDescription
actionActionThe action code number
is_disabledboolWhether the policy is disabled
is_sealedboolWhether the policy is sealed


PolicyManagerCapability

ParameterTypeDescription
managerstringThe manager name
actionActionThe action code number
can_disableboolWhether the manager can disable the policy
can_sealboolWhether the manager can seal the policy


Action

CodeName
0UNSPECIFIED
1MINT
2RECEIVE
4BURN
8SEND
16SUPER_BURN
0MODIFY_POLICY_MANAGERS
0MODIFY_CONTRACT_HOOK
0MODIFY_ROLE_PERMISSIONS
0MODIFY_ROLE_MANAGERS

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

UpdateActorRoles

Message to update the roles assigned to an actor

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.devnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    role_actors1 = composer.permissions_role_actors(
        role="admin",
        actors=["inj1actoraddress1", "inj1actoraddress2"],
    )
    role_actors2 = composer.permissions_role_actors(
        role="user",
        actors=["inj1actoraddress3"],
    )
    role_actors3 = composer.permissions_role_actors(
        role="user",
        actors=["inj1actoraddress4"],
    )
    role_actors4 = composer.permissions_role_actors(
        role="admin",
        actors=["inj1actoraddress5"],
    )

    message = composer.msg_update_actor_roles(
        sender=address.to_acc_bech32(),
        denom=denom,
        role_actors_to_add=[role_actors1, role_actors2],
        role_actors_to_revoke=[role_actors3, role_actors4],
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    permissionstypes "github.com/InjectiveLabs/sdk-go/chain/permissions/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    roleActors1 := permissionstypes.RoleActors{
        Role:   "admin",
        Actors: []string{"inj1actoraddress1", "inj1actoraddress2"},
    }
    roleActors2 := permissionstypes.RoleActors{
        Role:   "user",
        Actors: []string{"inj1actoraddress3"},
    }
    roleActors3 := permissionstypes.RoleActors{
        Role:   "user",
        Actors: []string{"inj1actoraddress4"},
    }
    roleActors4 := permissionstypes.RoleActors{
        Role:   "admin",
        Actors: []string{"inj1actoraddress5"},
    }

    msg := &permissionstypes.MsgUpdateActorRoles{
        Sender:             senderAddress.String(),
        Denom:              denom,
        RoleActorsToAdd:    []*permissionstypes.RoleActors{&roleActors1, &roleActors2},
        RoleActorsToRevoke: []*permissionstypes.RoleActors{&roleActors3, &roleActors4},
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
denomstringThe namespace denom to which this updates are appliedYes
role_actors_to_addRoleActors arrayThe roles to add for given actorsNo
role_actors_to_revokeRoleActors arrayThe roles to revoke from given actorsNo


RoleActors

ParameterTypeDescription
rolestringThe role name
actorsstring arrayList of actor names associated with the role

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

ClaimVoucher

Message to claim existing vouchers for a particular address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.devnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    message = composer.msg_claim_voucher(
        sender=address.to_acc_bech32(),
        denom=denom,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"

    permissionstypes "github.com/InjectiveLabs/sdk-go/chain/permissions/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

    msg := &permissionstypes.MsgClaimVoucher{
        Sender: senderAddress.String(),
        Denom:  denom,
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
denomstringThe token denom of the voucher to claimYes

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Staking

Includes the messages to claim and withdraw delegator rewards, and query staking state

ValidatorDistributionInfo

Queries validator commission and self-delegation rewards for validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    validator_address = "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    distribution_info = await client.fetch_validator_distribution_info(validator_address=validator_address)
    print(json.dumps(distribution_info, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    validatorAddress := "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    ctx := context.Background()

    res, err := chainClient.FetchValidatorDistributionInfo(ctx, validatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
validator_addressstringvalidator_address defines the validator address to query for.Yes

Response Parameters

Response Example:

{
   "operatorAddress":"inj1jue5dpr9lerjn6wlwtrywxrsenrf28rusrhqyx",
   "selfBondRewards":[
      {
         "denom":"inj",
         "amount":"520293543167557100000"
      }
   ],
   "commission":[
      {
         "denom":"inj",
         "amount":"105136140964470306856270639550202093130"
      }
   ]
}
ParameterTypeDescription
operator_addressstringoperator_address defines the validator operator address.
self_bond_rewardsgithub_com_cosmos_cosmos_sdk_types.DecCoinsself_bond_rewards defines the self delegations rewards.
commissiongithub_com_cosmos_cosmos_sdk_types.DecCoinscommission defines the commission the validator received.


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

ValidatorOutstandingRewards

Queries rewards of a validator address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    validator_address = "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    rewards = await client.fetch_validator_outstanding_rewards(validator_address=validator_address)
    print(json.dumps(rewards, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    validatorAddress := "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    ctx := context.Background()

    res, err := chainClient.FetchValidatorOutstandingRewards(ctx, validatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
validator_addressstringvalidator_address defines the validator address to query for.Yes

Response Parameters

Response Example:

{
   "rewards":{
      "rewards":[
         {
            "denom":"inj",
            "amount":"1997451426304473936130044829302179245433"
         }
      ]
   }
}
ParameterTypeDescription
rewardsValidatorOutstandingRewards


ValidatorOutstandingRewards

ParameterTypeDescription
rewardsgithub_com_cosmos_cosmos_sdk_types.DecCoins


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

ValidatorCommission

Queries accumulated commission for a validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    validator_address = "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    commission = await client.fetch_validator_commission(validator_address=validator_address)
    print(json.dumps(commission, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    validatorAddress := "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    ctx := context.Background()

    res, err := chainClient.FetchValidatorCommission(ctx, validatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
validator_addressstringvalidator_address defines the validator address to query for.Yes

Response Parameters

Response Example:

{
   "commission":{
      "commission":[
         {
            "denom":"inj",
            "amount":"105379963222887965961634697913891232463"
         }
      ]
   }
}
ParameterTypeDescription
commissionValidatorAccumulatedCommissioncommission defines the commission the validator received.


ValidatorAccumulatedCommission

ParameterTypeDescription
commissiongithub_com_cosmos_cosmos_sdk_types.DecCoins


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

ValidatorSlashes

Queries slash events of a validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    limit = 2
    pagination = PaginationOption(limit=limit)
    validator_address = "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    contracts = await client.fetch_validator_slashes(validator_address=validator_address, pagination=pagination)
    print(json.dumps(contracts, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/cosmos/cosmos-sdk/types/query"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    validatorAddress := "injvaloper1jue5dpr9lerjn6wlwtrywxrsenrf28ru89z99z"
    startingHeight := uint64(0)
    endingHeight := uint64(0)
    pagination := query.PageRequest{Limit: 10}
    ctx := context.Background()

    res, err := chainClient.FetchValidatorSlashes(ctx, validatorAddress, startingHeight, endingHeight, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
validator_addressstringvalidator_address defines the validator address to query for.Yes
starting_heightuint64starting_height defines the optional starting height to query the slashes.No
ending_heightuint64starting_height defines the optional ending height to query the slashes.No
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:


ParameterTypeDescription
slashesValidatorSlashEvent arrayslashes defines the slashes the validator received.
paginationquery.PageResponsepagination defines the pagination in the response.


ValidatorSlashEvent

ParameterTypeDescription
validator_perioduint64
fractioncosmossdk_io_math.LegacyDec


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

DelegationRewards

Queries the total rewards accrued by a delegation

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    delegator_address = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    validator_address = "injvaloper156t3yxd4udv0h9gwagfcmwnmm3quy0nph7tyh5"
    rewards = await client.fetch_delegation_rewards(
        delegator_address=delegator_address, validator_address=validator_address
    )
    print(json.dumps(rewards, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    delegatorAddress := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    validatorAddress := "injvaloper156t3yxd4udv0h9gwagfcmwnmm3quy0nph7tyh5"
    ctx := context.Background()

    res, err := chainClient.FetchDelegationRewards(ctx, delegatorAddress, validatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
delegator_addressstringdelegator_address defines the delegator address to query for.Yes
validator_addressstringvalidator_address defines the validator address to query for.Yes

Response Parameters

Response Example:

{
   "rewards":[
      {
         "denom":"inj",
         "amount":"1965602260312"
      }
   ]
}
ParameterTypeDescription
rewardsgithub_com_cosmos_cosmos_sdk_types.DecCoinsrewards defines the rewards accrued by a delegation.


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

DelegationTotalRewards

Queries the total rewards accrued by each validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    delegator_address = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    rewards = await client.fetch_delegation_total_rewards(
        delegator_address=delegator_address,
    )
    print(json.dumps(rewards, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    delegatorAddress := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    ctx := context.Background()

    res, err := chainClient.FetchDelegationTotalRewards(ctx, delegatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
delegator_addressstringdelegator_address defines the delegator address to query for.Yes

Response Parameters

Response Example:

{
   "rewards":[
      {
         "validatorAddress":"injvaloper156t3yxd4udv0h9gwagfcmwnmm3quy0nph7tyh5",
         "reward":[
            {
               "denom":"inj",
               "amount":"1972565915361"
            }
         ]
      },
      {
         "validatorAddress":"injvaloper1cq6mvxqp978f6lxrh5s6c35ddr2slcj9h7tqng",
         "reward":[

         ]
      },
      {
         "validatorAddress":"injvaloper16nd8yqxe9p6ggnrz58qr7dxn5y2834yeytmczf",
         "reward":[

         ]
      },
      {
         "validatorAddress":"injvaloper1u3slvlxpyckrpdk28a45uthku87wck3e934kl0",
         "reward":[

         ]
      },
      {
         "validatorAddress":"injvaloper17lzhgs2d50qcwlwdn06y3sghphlwl3xxxgml46",
         "reward":[

         ]
      }
   ],
   "total":[
      {
         "denom":"inj",
         "amount":"1972565915361"
      }
   ]
}
ParameterTypeDescription
rewardsDelegationDelegatorReward arrayrewards defines all the rewards accrued by a delegator.
totalgithub_com_cosmos_cosmos_sdk_types.DecCoinstotal defines the sum of all the rewards.


DelegationDelegatorReward

ParameterTypeDescription
validator_addressstring
rewardgithub_com_cosmos_cosmos_sdk_types.DecCoins


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

DelegatorValidators

Queries the validators of a delegator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    delegator_address = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    validators = await client.fetch_delegator_validators(
        delegator_address=delegator_address,
    )
    print(json.dumps(validators, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    delegatorAddress := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    ctx := context.Background()

    res, err := chainClient.FetchDelegatorValidators(ctx, delegatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
delegator_addressstringdelegator_address defines the delegator address to query for.Yes

Response Parameters

Response Example:

{
   "validators":[
      "injvaloper156t3yxd4udv0h9gwagfcmwnmm3quy0nph7tyh5",
      "injvaloper1cq6mvxqp978f6lxrh5s6c35ddr2slcj9h7tqng",
      "injvaloper16nd8yqxe9p6ggnrz58qr7dxn5y2834yeytmczf",
      "injvaloper1u3slvlxpyckrpdk28a45uthku87wck3e934kl0",
      "injvaloper17lzhgs2d50qcwlwdn06y3sghphlwl3xxxgml46"
   ]
}
ParameterTypeDescription
validatorsstring arrayvalidators defines the validators a delegator is delegating for.

DelegatorWithdrawAddress

Queries the withdraw address of a delegator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    delegator_address = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    withdraw_address = await client.fetch_delegator_withdraw_address(
        delegator_address=delegator_address,
    )
    print(json.dumps(withdraw_address, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    delegatorAddress := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
    ctx := context.Background()

    res, err := chainClient.FetchDelegatorWithdrawAddress(ctx, delegatorAddress)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
delegator_addressstringdelegator_address defines the delegator address to query for.Yes

Response Parameters

Response Example:

{
   "withdrawAddress":"inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
}
ParameterTypeDescription
withdraw_addressstringwithdraw_address defines the delegator address to query for.

CommunityPool

Queries the community pool coins

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    community_pool = await client.fetch_community_pool()
    print(json.dumps(community_pool, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchCommunityPool(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "pool":[
      {
         "denom":"inj",
         "amount":"619667912004889463981597377474655365826158034046"
      }
   ]
}
ParameterTypeDescription
poolgithub_com_cosmos_cosmos_sdk_types.DecCoinspool defines community pool's coins.


DecCoin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.LegacyDec

SetWithdrawAddress

Changes the withdraw address for a delegator (or validator self-delegation)

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective import AsyncClient, PrivateKey
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    withdraw_address = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    message = composer.msg_set_withdraw_address(
        delegator_address=address.to_acc_bech32(),
        withdraw_address=withdraw_address,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/x/distribution/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    withdrawAddress := "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    msg := &types.MsgSetWithdrawAddress{
        DelegatorAddress: senderAddress.String(),
        WithdrawAddress:  withdrawAddress,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
delegator_addressstringYes
withdraw_addressstringYes

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgWithdrawDelegatorReward

Withdraw rewards of a delegator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    validator_address = "injvaloper1ultw9r29l8nxy5u6thcgusjn95vsy2caw722q5"

    message = composer.msg_withdraw_delegator_reward(
        delegator_address=address.to_acc_bech32(), validator_address=validator_address
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := distributiontypes.MsgWithdrawDelegatorReward{
        DelegatorAddress: senderAddress.String(),
        ValidatorAddress: "injvaloper14gy4acwjm96wd20awm9ar6j54lev5p7espy9ug",
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
delegator_addressstringYes
validator_addressstringYes

Response parameters

Response Example:

txhash: "0EDB245FE6F59F9DD8B6F03D56E6F37FE0D53DD85C62476BD7A1F72486D44F8E"
raw_log: "[]"

gas wanted: 191525
gas fee: 0.0000957625 INJ
DEBU[0001] broadcastTx with nonce 1321                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5215332  fn=func1 src="client/chain/chain.go:619" txHash=A4F9D6998F075E875F611ED279B617EAB4C0332EBC347468EEDAD81DD8236C48
DEBU[0003] nonce incremented to 1322                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  195046                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000097523 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

WithdrawValidatorCommission

Withdraws the full commission to the validator address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    # prepare tx msg
    validator_address = "injvaloper1ultw9r29l8nxy5u6thcgusjn95vsy2caw722q5"

    message = composer.msg_withdraw_validator_commission(validator_address=validator_address)

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/x/distribution/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    validatorAddress := "injvaloper1ultw9r29l8nxy5u6thcgusjn95vsy2caw722q5"

    msg := &types.MsgWithdrawValidatorCommission{
        ValidatorAddress: validatorAddress,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
validator_addressstringYes

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

FundCommunityPool

Allows an account to directly fund the community pool

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os
from decimal import Decimal

import dotenv

from pyinjective import AsyncClient, PrivateKey
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network


async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(configured_private_key)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    amount = composer.create_coin_amount(amount=Decimal("0.1"), token_name="INJ")

    message = composer.msg_fund_community_pool(
        amounts=[amount],
        depositor=address.to_acc_bech32(),
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    "github.com/cosmos/cosmos-sdk/types"
    distriutiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    amount := types.NewCoin("inj", math.NewInt(1))

    msg := &distriutiontypes.MsgFundCommunityPool{
        Amount:    []types.Coin{amount},
        Depositor: senderAddress.String(),
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
amountgithub_com_cosmos_cosmos_sdk_types.CoinsYes
depositorstringYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:


ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgDelegate

Performs a coins delegation from a delegator to a validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    validator_address = "injvaloper1ultw9r29l8nxy5u6thcgusjn95vsy2caw722q5"
    amount = 100

    msg = composer.msg_delegate(
        delegator_address=address.to_acc_bech32(), validator_address=validator_address, amount=amount
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"
    txtypes "github.com/cosmos/cosmos-sdk/types/tx"
    stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    msg := stakingtypes.MsgDelegate{
        DelegatorAddress: senderAddress.String(),
        ValidatorAddress: "injvaloper14gy4acwjm96wd20awm9ar6j54lev5p7espy9ug",
        Amount: sdktypes.Coin{
            Denom:  "inj",
            Amount: math.NewInt(1000000000000000000), // 1 INJ
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    _, response, err := chainClient.BroadcastMsg(ctx, txtypes.BroadcastMode_BROADCAST_MODE_SYNC, &msg)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
delegator_addressstringYes
validator_addressstringYes
amounttypes1.CoinYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "0EDB245FE6F59F9DD8B6F03D56E6F37FE0D53DD85C62476BD7A1F72486D44F8E"
raw_log: "[]"

gas wanted: 191525
gas fee: 0.0000957625 INJ
DEBU[0001] broadcastTx with nonce 1318                   fn=func1 src="client/chain/chain.go:598"
DEBU[0003] msg batch committed successfully at height 5215234  fn=func1 src="client/chain/chain.go:619" txHash=1714F24FB2BEE871C0A5CED998CCB0C33069FF40F744AE2AEF3720F24893D92A
DEBU[0003] nonce incremented to 1319                     fn=func1 src="client/chain/chain.go:623"
DEBU[0003] gas wanted:  207846                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.000103923 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Tendermint

Cosmos Tendermint module

GetNodeInfo

Gets the current node info

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    node_info = await client.fetch_node_info()
    print(node_info)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchNodeInfo(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "defaultNodeInfo":{
      "protocolVersion":{
         "p2p":"8",
         "block":"11",
         "app":"0"
      },
      "defaultNodeId":"53c19e8ba2deb109ba8d09dd41ae82bbddd74467",
      "listenAddr":"tcp://0.0.0.0:26656",
      "network":"injective-888",
      "version":"0.37.1",
      "channels":"QCAhIiMwOGBhAA==",
      "moniker":"injective",
      "other":{
         "txIndex":"on",
         "rpcAddress":"tcp://0.0.0.0:26657"
      }
   },
   "applicationVersion":{
      "name":"injective",
      "appName":"injectived",
      "gitCommit":"1f0a39381",
      "goVersion":"go version go1.19.13 linux/amd64",
      "buildDeps":[
         {
            "path":"cloud.google.com/go",
            "version":"v0.110.4",
            "sum":"h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk="
         },
         {
            "path":"cloud.google.com/go/compute/metadata",
            "version":"v0.2.3",
            "sum":"h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY="
         }
      ],
      "cosmosSdkVersion":"v0.47.5",
      "version":"",
      "buildTags":""
   }
}
ParameterTypeDescription
default_node_infov11.DefaultNodeInfo
application_versionVersionInfo


DefaultNodeInfo

ParameterTypeDescription
protocol_versionProtocolVersion
default_node_idstring
listen_addrstring
networkstring
versionstring
channelsbyte array
monikerstring
otherDefaultNodeInfoOther


ProtocolVersion

ParameterTypeDescription
p2puint64
blockuint64
appuint64


DefaultNodeInfoOther

ParameterTypeDescription
tx_indexstring
rpc_addressstring


VersionInfo

ParameterTypeDescription
namestring
app_namestring
versionstring
git_commitstring
build_tagsstring
go_versionstring
build_depsModule array
cosmos_sdk_versionstringSince: cosmos-sdk 0.43


Module

ParameterTypeDescription
pathstringmodule path
versionstringmodule version
sumstringchecksum

GetSyncing

Returns the node's syncing status

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    syncing = await client.fetch_syncing()
    print(syncing)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchSyncing(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "syncing":false
}
ParameterTypeDescription
syncingbool

GetLatestBlock

Get the latest block

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    latest_block = await client.fetch_latest_block()
    print(json.dumps(latest_block, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("devnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchLatestBlock(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "blockId":{
      "hash":"bCxPpTR4INvkmf3kAVYi1KhwzX0ySxQuhc8xBBFNmAo=",
      "partSetHeader":{
         "total":1,
         "hash":"6zGn+fBW1y4cpyos4g/tVNQdqS03D/jr/B68SYVvcbQ="
      }
   },
   "block":{
      "header":{
         "version":{
            "block":"11",
            "app":"0"
         },
         "chainId":"injective-888",
         "height":"23197636",
         "time":"2024-03-14T17:39:19.050602Z",
         "lastBlockId":{
            "hash":"SglGvXqUCRelE9NtLBiJ0EIBBxTXmztat4fVrYagYlM=",
            "partSetHeader":{
               "total":1,
               "hash":"AsAE1Sdl69RqHqaseeRn3U6N43gG9T710HUjXJi6fyw="
            }
         },
         "lastCommitHash":"EBSqUY4fpGLr2FmmcYsFa01H0PDWQLVuKslws5Un9zU=",
         "dataHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "validatorsHash":"G0AQ0vfNXTLF7UcNXSvk6ZJRWFo09hadwJSm7haFV6I=",
         "nextValidatorsHash":"G0AQ0vfNXTLF7UcNXSvk6ZJRWFo09hadwJSm7haFV6I=",
         "consensusHash":"5bupI5wNP5Z/jvh5UG/269+5QPiQTXKRNRpGHwCqrU0=",
         "appHash":"UoJN/dwHiiDytgSt3xHcb9zkcP8eFZ+qFZWWclQ6SYg=",
         "lastResultsHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "evidenceHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "proposerAddress":"M5HjW2EATgO+uI+h2rRES5E7174="
      },
      "data":{
         "txs":[

         ]
      },
      "evidence":{
         "evidence":[

         ]
      },
      "lastCommit":{
         "height":"23197635",
         "blockId":{
            "hash":"SglGvXqUCRelE9NtLBiJ0EIBBxTXmztat4fVrYagYlM=",
            "partSetHeader":{
               "total":1,
               "hash":"AsAE1Sdl69RqHqaseeRn3U6N43gG9T710HUjXJi6fyw="
            }
         },
         "signatures":[
            {
               "blockIdFlag":"BLOCK_ID_FLAG_ABSENT",
               "timestamp":"0001-01-01T00:00:00Z",
               "validatorAddress":"",
               "signature":""
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"ObUXYdS8jfTSNPonUBFPJkft7eA=",
               "timestamp":"2024-03-14T17:39:19.050602Z",
               "signature":"3ZdA7LqXq4Hj5olf1XKusJ6NHCBkqjpty9pgmsxKyzSG0VL8Uf+Ro0NDuZo8jK4qfLsuctCte3rdGV6lG/cKAA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"M5HjW2EATgO+uI+h2rRES5E7174=",
               "timestamp":"2024-03-14T17:39:19.044716221Z",
               "signature":"u8QVTQO/QZhNSzAwVCR3bGLUzryi9E+3jQ2COcHi46GfU0SpWOPNBvdbOHsEkRx6EKh0P0acB/hOnDE5JPp5AA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"y8ctJ4QpJ0S7ZTVY7RTE4z1hS2c=",
               "timestamp":"2024-03-14T17:39:19.051153172Z",
               "signature":"0R/H5GkdKJszELjxfwX9qQlr5nuANTQYN9aTTDvKkUqJDoXW3OwbQPHtegKJlVKU8BT80D2Glng+SnQMO3JSCA=="
            }
         ],
         "round":0
      }
   },
   "sdkBlock":{
      "header":{
         "version":{
            "block":"11",
            "app":"0"
         },
         "chainId":"injective-888",
         "height":"23197636",
         "time":"2024-03-14T17:39:19.050602Z",
         "lastBlockId":{
            "hash":"SglGvXqUCRelE9NtLBiJ0EIBBxTXmztat4fVrYagYlM=",
            "partSetHeader":{
               "total":1,
               "hash":"AsAE1Sdl69RqHqaseeRn3U6N43gG9T710HUjXJi6fyw="
            }
         },
         "lastCommitHash":"EBSqUY4fpGLr2FmmcYsFa01H0PDWQLVuKslws5Un9zU=",
         "dataHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "validatorsHash":"G0AQ0vfNXTLF7UcNXSvk6ZJRWFo09hadwJSm7haFV6I=",
         "nextValidatorsHash":"G0AQ0vfNXTLF7UcNXSvk6ZJRWFo09hadwJSm7haFV6I=",
         "consensusHash":"5bupI5wNP5Z/jvh5UG/269+5QPiQTXKRNRpGHwCqrU0=",
         "appHash":"UoJN/dwHiiDytgSt3xHcb9zkcP8eFZ+qFZWWclQ6SYg=",
         "lastResultsHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "evidenceHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "proposerAddress":"injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz"
      },
      "data":{
         "txs":[

         ]
      },
      "evidence":{
         "evidence":[

         ]
      },
      "lastCommit":{
         "height":"23197635",
         "blockId":{
            "hash":"SglGvXqUCRelE9NtLBiJ0EIBBxTXmztat4fVrYagYlM=",
            "partSetHeader":{
               "total":1,
               "hash":"AsAE1Sdl69RqHqaseeRn3U6N43gG9T710HUjXJi6fyw="
            }
         },
         "signatures":[
            {
               "blockIdFlag":"BLOCK_ID_FLAG_ABSENT",
               "timestamp":"0001-01-01T00:00:00Z",
               "validatorAddress":"",
               "signature":""
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"ObUXYdS8jfTSNPonUBFPJkft7eA=",
               "timestamp":"2024-03-14T17:39:19.050602Z",
               "signature":"3ZdA7LqXq4Hj5olf1XKusJ6NHCBkqjpty9pgmsxKyzSG0VL8Uf+Ro0NDuZo8jK4qfLsuctCte3rdGV6lG/cKAA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"M5HjW2EATgO+uI+h2rRES5E7174=",
               "timestamp":"2024-03-14T17:39:19.044716221Z",
               "signature":"u8QVTQO/QZhNSzAwVCR3bGLUzryi9E+3jQ2COcHi46GfU0SpWOPNBvdbOHsEkRx6EKh0P0acB/hOnDE5JPp5AA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"y8ctJ4QpJ0S7ZTVY7RTE4z1hS2c=",
               "timestamp":"2024-03-14T17:39:19.051153172Z",
               "signature":"0R/H5GkdKJszELjxfwX9qQlr5nuANTQYN9aTTDvKkUqJDoXW3OwbQPHtegKJlVKU8BT80D2Glng+SnQMO3JSCA=="
            }
         ],
         "round":0
      }
   }
}
ParameterTypeDescription
block_idv1.BlockID
blockv1.BlockDeprecated: please use `sdk_block` instead
sdk_blockBlockSince: cosmos-sdk 0.47


BlockID

ParameterTypeDescription
hashbyte array
part_set_headerPartSetHeader


PartSetHeader

ParameterTypeDescription
totaluint32
hashbyte array


Block

ParameterTypeDescription
headerHeader
dataData
evidenceEvidenceList
last_commitCommit


Header

ParameterTypeDescription
versionv11.Consensusbasic block info
chain_idstring
heightint64
timetime.Time
last_block_idBlockIDprev block info
last_commit_hashbyte arrayhashes of block data
data_hashbyte array
validators_hashbyte arrayhashes from the app output from the prev block
next_validators_hashbyte array
consensus_hashbyte array
app_hashbyte array
last_results_hashbyte array
evidence_hashbyte arrayconsensus info
proposer_addressbyte array


Consensus

ParameterTypeDescription
blockuint64
appuint64


Data

ParameterTypeDescription
txs][byte arrayTxs that will be applied by state @ block.Height+1. NOTE: not all txs here are valid. We're just agreeing on the order first. This means that block.AppHash does not include these txs.


EvidenceList

ParameterTypeDescription
evidenceEvidence array


Commit

ParameterTypeDescription
heightint64
roundint32
block_idBlockID
signaturesCommitSig array


CommitSig

ParameterTypeDescription
block_id_flagBlockIDFlag
validator_addressbyte array
timestamptime.Time
signaturebyte array


BlockIDFlag

CodeName
0BLOCK_ID_FLAG_UNKNOWN
1BLOCK_ID_FLAG_ABSENT
2BLOCK_ID_FLAG_COMMIT
3BLOCK_ID_FLAG_NIL

GetBlockByHeight

Get the block for a given height

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    block = await client.fetch_block_by_height(height=15793860)
    print(block)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    height := int64(23040174)
    res, err := chainClient.FetchBlockByHeight(ctx, height)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
heightint64Yes

Response Parameters

Response Example:

{
   "blockId":{
      "hash":"MNF+X0DQFIsnEJAzyTxHMD8vZChOpW4rQeSnRKBiJ1Y=",
      "partSetHeader":{
         "total":1,
         "hash":"Fqg81sOmF9dqH8lORXGat/mOFyqh52/lSHvsehg9OWk="
      }
   },
   "block":{
      "header":{
         "version":{
            "block":"11",
            "app":"0"
         },
         "chainId":"injective-888",
         "height":"15793860",
         "time":"2023-09-07T03:59:36.393462082Z",
         "lastBlockId":{
            "hash":"RRhRSiIf1E08mJAtACM4J1RFSVJ96eR0PBVuoD7rb2c=",
            "partSetHeader":{
               "total":1,
               "hash":"SeO5JkVtLUrhegd0rwDatDbvS5PQf/0Yvn+BmL1MOko="
            }
         },
         "lastCommitHash":"rNxjhSihfCPkPMak9qPlmUYeXRc0weFu1nmmKMUPLAQ=",
         "dataHash":"1RjS2VAhrWt2lLnVLozfeI7oAi7PoDILROzeheXN5H0=",
         "validatorsHash":"6lDaVNHY4DtceWtHsVS7SdR8XuPSATqQ7qNKWIxcnhg=",
         "nextValidatorsHash":"6lDaVNHY4DtceWtHsVS7SdR8XuPSATqQ7qNKWIxcnhg=",
         "consensusHash":"ItjUyLlUnqkCxmoaGPck+PeXC45MXx6zsLXxtOHeBTE=",
         "appHash":"Sv2MdUKQxwE/glEI8c8RFQKmc4HSyKO7j3sAqySultQ=",
         "lastResultsHash":"Le4RmI//Wh43Mq6ro+VMWn7ZbVZRw3HXUAQILODtag8=",
         "evidenceHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "proposerAddress":"ObUXYdS8jfTSNPonUBFPJkft7eA="
      },
      "data":{
         "txs":[
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXdsZjU3N21sd3R5bTU3c2N6bWx6a2w3a2N0MDJxc2xkc3hnanY3EippbmoxcjI0OHlzcjJ5NDBxbTJrODMwdmFucXhubTZ2Y21saHFydW1zMmUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXdsZjU3N21sd3R5bTU3c2N6bWx6a2w3a2N0MDJxc2xkc3hnanY3EippbmoxcjI0OHlzcjJ5NDBxbTJrODMwdmFucXhubTZ2Y21saHFydW1zMmUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJz+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAjr+rkaXrlMyQvUjnSB+viWNMY4CU7VHptUN/MxDVEOVEgQKAggBGLymARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCHh6hdDRsHw1dfkRZkwLOmP7uNT6RSwNJPIBf8dg1bsnLtzAhpBlAd1nF1V7oWvAvoZ/gVoiNVdzjCWYYcUB/s",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAyaHY3Zno2djdlOTlzd2tqZmE2OWVyaGNoY2R4aDJreXhxanprEippbmoxY3p0bDhoNThsOHpjdjIzbG0wenI4aDhyeXN1NWh4Y2ZnZDUweXUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAyaHY3Zno2djdlOTlzd2tqZmE2OWVyaGNoY2R4aDJreXhxanprEippbmoxY3p0bDhoNThsOHpjdjIzbG0wenI4aDhyeXN1NWh4Y2ZnZDUweXUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJz+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA3SZsAXlR9pzcFHog/kjOFSR1EiYHVqNOnWpNWiq7NcuEgQKAggBGNmNARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkA0yE1i3DE6GGITZpVWhESrrYNgKdPRPYKCAnz9QcAdEkwOLHJ9HgOz2Ok9NhjFN5akpyxZTKRGTFX11//hT3Wd",
            "CugFCrgECjgvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnUHJpdmlsZWdlZEV4ZWN1dGVDb250cmFjdBL7AwoqaW5qMWV6dGttMzZ5NmMzZTZ6bXI0aGc0Zzc3YTZ3eWoweGMwZDVneDV2EngxMDIwMDAwMDAwIGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3VzZGMsIDExMDAgcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUaKmluajE3cTdkczB5aDdoaHR1c2ZmN2d6OGE1a3gydXd4cnV0dGx4dXI5NiKmAnsiYXJncyI6eyJtc2ciOnsic3Vic2NyaWJlIjp7fX0sInRyYWRlcl9zdWJhY2NvdW50X2lkIjoiMHhjODk3NmRjNzQ0ZDYyMzlkMGI2M2FkZDE1NDdiZGRkMzg5Mjc5YjBmMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwidmF1bHRfc3ViYWNjb3VudF9pZCI6IjB4ZjAzY2Q4M2M5N2Y1ZWViZTQxMjlmMjA0N2VkMmM2NTcxYzYxZjE2YjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMyJ9LCJuYW1lIjoiVmF1bHRTdWJzY3JpYmUiLCJvcmlnaW4iOiJpbmoxZXp0a20zNnk2YzNlNnptcjRoZzRnNzdhNnd5ajB4YzBkNWd4NXYifRjp/cMH+j+kAQovL2luamVjdGl2ZS50eXBlcy52MWJldGExLkV4dGVuc2lvbk9wdGlvbnNXZWIzVHgScQgFEippbmoxN2drdWV0OGY2cHNzeGQ4bnljbTNxcjlkOXk2OTlydXB2NjM5N3oaQS7bNDH7L/B112pVzWT5OTygLht+2aFCIbvRfdlbaJqFAEXaPzWWgHCwBc4C3bCN22c8OHvjiS4ExPfg9EKkTKgAEn4KXgpUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAp46ZxDpNDxsP5gvCZkCc84ZllP7P7q0tL57X7fN0WOcEgQKAgh/GGYSHAoWCgNpbmoSDzM2Mjg2MjUwMDAwMDAwMBDdpSwaQXHoIQ/X5yai6B0reASgAArSShjzpxprthDLEyr+zX7GR07Hr+r8UmZftLbafrcZfRX2UwFw8Q8pHaMINsSjckgb",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTl1cThnZG1reHFmcmdodGVrNDl3YThrMmY4aGhtM3hlNnY5dnh4EippbmoxdzlydjV1MzU1a2UwN2NqZjR3ZzB3YTJjdmF0bWR5Y2RoNm53ZzMaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTl1cThnZG1reHFmcmdodGVrNDl3YThrMmY4aGhtM3hlNnY5dnh4EippbmoxdzlydjV1MzU1a2UwN2NqZjR3ZzB3YTJjdmF0bWR5Y2RoNm53ZzMaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA9YRhWDK9v8bR+HRAI7OzzTaeuCFfDffiIO9zTWhbk4cEgQKAggBGMmeARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBAcshkCtJATtQYYHVorDRUSOGQ7gR1bLp17ZXO5S5aTmB+pRc+/uz8cY3zfP28wpZE4BFa40sSn+vsN7YDc0Ne",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhxcnNtZmx2NzZ0MHcwZnFybXp3enh0eHF1ZTM0bXYzNG1zeHZtEippbmoxdWwyMzVzZnBmbnltY2c4Z2h1dDk4dXdzbnU2OWxuem5hM3pkamQaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhxcnNtZmx2NzZ0MHcwZnFybXp3enh0eHF1ZTM0bXYzNG1zeHZtEippbmoxdWwyMzVzZnBmbnltY2c4Z2h1dDk4dXdzbnU2OWxuem5hM3pkamQaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAimG00m9nDJwqtOiErp8o619mH/3VcEADzWzSqGpnGdIEgQKAggBGLuRARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCnWeua6pt6p7Te8JuofcIaJWaZEhgiOuFqskm9sjQ9yi5qJkOEQXCmCRFCS5uYBpk0/1tuwYXJwtro9GdxHJMI",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWcwbThxM2tkdzMzM3N4cTI5dzduYzM2bWZmY3ZoODBndmNkMzlkEippbmoxbjl3Zmg3YTZjZzJ1Z2d5Z2FkOWFkbGo4M2E0eXdkenV2aHJtcHYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWcwbThxM2tkdzMzM3N4cTI5dzduYzM2bWZmY3ZoODBndmNkMzlkEippbmoxbjl3Zmg3YTZjZzJ1Z2d5Z2FkOWFkbGo4M2E0eXdkenV2aHJtcHYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAhKZIyozzEpDEuAl3ypUW3R3JoD7AtBIAujqq4wwPfVdEgQKAggBGOufARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDMNT7feu38IDUKGBHpWaoydtomgYQZjGPXjj7pb8fEj0MshAm2XfDad53SLdLeKmsXMjQ5cXyYyH15EwUxDYSU",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMW54emhlOTRnc2M5anN5dWMzd3FrdW5qeXZzOHA0ZW1lMGd1NGtlEippbmoxbHFrZ3JkbGh5cWt5M3dnNnJtbnhkajVrd3Rlcjc0ZTJ1ajBtZmYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMW54emhlOTRnc2M5anN5dWMzd3FrdW5qeXZzOHA0ZW1lMGd1NGtlEippbmoxbHFrZ3JkbGh5cWt5M3dnNnJtbnhkajVrd3Rlcjc0ZTJ1ajBtZmYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAxg89Ih7H74zbkYrMXXb55tjKWTQJQ3D2Sk00p5Y0/ZEEgQKAggBGIqVARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCo/7pJIihg01V2zd+y3WH++KyVIB4m7WC9DAHPRzJIAghGLVJkAJjzGWTHrIGlh7CIira+E0UeSdy1Ag4GMBfS",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTljaGVjeHd6dWZmMDlmbTY2YzUwM3gycm1majBreXp6ZmgzZnRmEippbmoxa3R2MjJhenZ0NWg4bnF6NDh3bmhxc2o5NnVsZTR4eDBkYXc3amoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTljaGVjeHd6dWZmMDlmbTY2YzUwM3gycm1majBreXp6ZmgzZnRmEippbmoxa3R2MjJhenZ0NWg4bnF6NDh3bmhxc2o5NnVsZTR4eDBkYXc3amoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAgVaAkMOV5+9OJP2xYw3tKy3aU3SiAIummY3gRAIGDj/EgQKAggBGOihARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBSSP+Fx12//aSYEjjLjr5gl5X4jOUktkOREMTfArsWVxl4Xl7cyV3f7kYAF7kBbQQqrgMerHsc9KePhRVoXB0k",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAzMGtrbDZ1eHlhaG04aGYwZWQ4ZjQwMmY2N2Eyajl4cmM0MnlmEippbmoxejVnNHBhcDdhOGhoeGFheTJwbmZ3ZzNhd241ZHFwNXI0c3Y4a2EaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAzMGtrbDZ1eHlhaG04aGYwZWQ4ZjQwMmY2N2Eyajl4cmM0MnlmEippbmoxejVnNHBhcDdhOGhoeGFheTJwbmZ3ZzNhd241ZHFwNXI0c3Y4a2EaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAl0obf7huaZwDxwoKhqdWfwakrBU8rFlrc/Ihiquc4P5EgQKAggBGIOAARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCGyhKBN8mu+4qID3ZzBPskvusEorT6TXytayPg3k6UpGMaLx38dXS9wmX2yrLrn4G67rihS/fKVCG2yMhdwk4y",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTR0NWY5NG01Zmc0djZkcnM0cXFrZDNkNzMzeTZzczBsanl5cWxtEippbmoxaG05dWhtaGtkdHJ5d3owbXFrOHZhNDAyZTN1ZDB5cGpscWZyM2oaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTR0NWY5NG01Zmc0djZkcnM0cXFrZDNkNzMzeTZzczBsanl5cWxtEippbmoxaG05dWhtaGtkdHJ5d3owbXFrOHZhNDAyZTN1ZDB5cGpscWZyM2oaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA4fTy5A+DmuZfsXgjM48ntVqTXlOBW287TjXr91D0VGREgQKAggBGLuVARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBdYIUr7S8ky4p9g+WWi2Ef8Cnq9W5eRsQ6Q6YNcnr0rhzy6lgo31o9tJg6XB0ZHtaJb00qBdU8/igNmfhEZXqk",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWE0dzk5ejRxZ3FjZDZsNnU0ZGpmeWxjdWN0NTNkdXFrdXFucjVkEippbmoxNTI2azM2Y2szbGh2bXJnOHN5eWE4N3R5Njl1cGw4eXp6cms1ZnEaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWE0dzk5ejRxZ3FjZDZsNnU0ZGpmeWxjdWN0NTNkdXFrdXFucjVkEippbmoxNTI2azM2Y2szbGh2bXJnOHN5eWE4N3R5Njl1cGw4eXp6cms1ZnEaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohArGVpE2Qtw7Pq625UTe8FZfqFAGc7IaBTZYPusGkLfnlEgQKAggBGMmAARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDk8e2Du8ReB4Jz73ZkpdaWHIBSo5x0XtILIMecnJzbQ3TykogSC6OQ+tWOCFQp9mUhff++iCbVpFwAx08k+zYS",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWdkdnRka2x2M3FnNDMzdnVuOWphcGFkYW5yOTYweDB1MjRxa3FsEippbmoxYWVhNG04ZmFydzlkcjljbTg3YWc3ZDB6Nm1jZnAybnhudjI4YTcaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWdkdnRka2x2M3FnNDMzdnVuOWphcGFkYW5yOTYweDB1MjRxa3FsEippbmoxYWVhNG04ZmFydzlkcjljbTg3YWc3ZDB6Nm1jZnAybnhudjI4YTcaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAz+Zjrtxo20HOm1w4l5I57H9MAmt+87msPR5/1R/D1McEgQKAggBGMSqARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDhGCp0+Crr0dfoCZrTb5otuTMtIxxTj9tWfxrfN7cnBTEgKFXVDlsXbay4Wlxz4QBVX4Fb6gtUgQbtDrazOEj9",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhubWRsZWF0dHU3dGV0dTZla3d3OXJtMGNtMDNlemc1amx0cnF6EippbmoxbTYzdTV5a3NhZ3Nzajd3Y3hmbDVzN3Q0dTg3azcwamZ5bm5rMmoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhubWRsZWF0dHU3dGV0dTZla3d3OXJtMGNtMDNlemc1amx0cnF6EippbmoxbTYzdTV5a3NhZ3Nzajd3Y3hmbDVzN3Q0dTg3azcwamZ5bm5rMmoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA+OlGuxc2hUmrU+iVLb2MDnHy6W4exQyJrbMie9/Sv27EgQKAggBGJqQARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBTfe9A/RDSoHQCDunT60QgdtBrz3eIGvIgLEISRMAh/2w3+A9UB5SoDNGZNUfpNsxZyyq2Emi6pXuVpFzUCjI5"
         ]
      },
      "evidence":{
         "evidence":[

         ]
      },
      "lastCommit":{
         "height":"15793859",
         "blockId":{
            "hash":"RRhRSiIf1E08mJAtACM4J1RFSVJ96eR0PBVuoD7rb2c=",
            "partSetHeader":{
               "total":1,
               "hash":"SeO5JkVtLUrhegd0rwDatDbvS5PQf/0Yvn+BmL1MOko="
            }
         },
         "signatures":[
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"y8ctJ4QpJ0S7ZTVY7RTE4z1hS2c=",
               "timestamp":"2023-09-07T03:59:36.496584825Z",
               "signature":"AxnPc5AEa6jizZuKhXUAkNi4vic6miF9emyAx+uSMco7oKVwoXGDJ6L0wneNGYOqpKkMVMQm4hcnWgDBjiBLAA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"M5HjW2EATgO+uI+h2rRES5E7174=",
               "timestamp":"2023-09-07T03:59:36.293269404Z",
               "signature":"mjODCd7P7xHo6Gn+6Qi6/u+FI72noRs9/vcbvpiqz7Hr5hRNhk2a2Jj2tw59GC6cURd2Q6c/CdZhXHgVqzMdAg=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"Nv8cuLE25L4mgnBx8shCmG68xfc=",
               "timestamp":"2023-09-07T03:59:36.393462082Z",
               "signature":"NyTk5W6WLxEbouVJ7LxSwV88FnH/CtmXkr6JczPqEehdrymqrGqT02OJLutGVsBmrPEkMhwa2BegkqvmPLJrBQ=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"ObUXYdS8jfTSNPonUBFPJkft7eA=",
               "timestamp":"2023-09-07T03:59:36.296674286Z",
               "signature":"OAwmf7pEjsXbwIWMD5HbzWiae6OAn0ME49FbXaRLvKIYKWSDKv9f0gprsgRJznOdj60SontlntwmvV+23MV6DQ=="
            }
         ],
         "round":0
      }
   },
   "sdkBlock":{
      "header":{
         "version":{
            "block":"11",
            "app":"0"
         },
         "chainId":"injective-888",
         "height":"15793860",
         "time":"2023-09-07T03:59:36.393462082Z",
         "lastBlockId":{
            "hash":"RRhRSiIf1E08mJAtACM4J1RFSVJ96eR0PBVuoD7rb2c=",
            "partSetHeader":{
               "total":1,
               "hash":"SeO5JkVtLUrhegd0rwDatDbvS5PQf/0Yvn+BmL1MOko="
            }
         },
         "lastCommitHash":"rNxjhSihfCPkPMak9qPlmUYeXRc0weFu1nmmKMUPLAQ=",
         "dataHash":"1RjS2VAhrWt2lLnVLozfeI7oAi7PoDILROzeheXN5H0=",
         "validatorsHash":"6lDaVNHY4DtceWtHsVS7SdR8XuPSATqQ7qNKWIxcnhg=",
         "nextValidatorsHash":"6lDaVNHY4DtceWtHsVS7SdR8XuPSATqQ7qNKWIxcnhg=",
         "consensusHash":"ItjUyLlUnqkCxmoaGPck+PeXC45MXx6zsLXxtOHeBTE=",
         "appHash":"Sv2MdUKQxwE/glEI8c8RFQKmc4HSyKO7j3sAqySultQ=",
         "lastResultsHash":"Le4RmI//Wh43Mq6ro+VMWn7ZbVZRw3HXUAQILODtag8=",
         "evidenceHash":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
         "proposerAddress":"injvalcons18x63wcw5hjxlf535lgn4qy20yer7mm0qedu0la"
      },
      "data":{
         "txs":[
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXdsZjU3N21sd3R5bTU3c2N6bWx6a2w3a2N0MDJxc2xkc3hnanY3EippbmoxcjI0OHlzcjJ5NDBxbTJrODMwdmFucXhubTZ2Y21saHFydW1zMmUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXdsZjU3N21sd3R5bTU3c2N6bWx6a2w3a2N0MDJxc2xkc3hnanY3EippbmoxcjI0OHlzcjJ5NDBxbTJrODMwdmFucXhubTZ2Y21saHFydW1zMmUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajF3bGY1NzdtbHd0eW01N3Njem1semtsN2tjdDAycXNsZHN4Z2p2NxIqaW5qMXIyNDh5c3IyeTQwcW0yazgzMHZhbnF4bm02dmNtbGhxcnVtczJlGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJz+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAjr+rkaXrlMyQvUjnSB+viWNMY4CU7VHptUN/MxDVEOVEgQKAggBGLymARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCHh6hdDRsHw1dfkRZkwLOmP7uNT6RSwNJPIBf8dg1bsnLtzAhpBlAd1nF1V7oWvAvoZ/gVoiNVdzjCWYYcUB/s",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAyaHY3Zno2djdlOTlzd2tqZmE2OWVyaGNoY2R4aDJreXhxanprEippbmoxY3p0bDhoNThsOHpjdjIzbG0wenI4aDhyeXN1NWh4Y2ZnZDUweXUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAyaHY3Zno2djdlOTlzd2tqZmE2OWVyaGNoY2R4aDJreXhxanprEippbmoxY3p0bDhoNThsOHpjdjIzbG0wenI4aDhyeXN1NWh4Y2ZnZDUweXUaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFwMmh2N2Z6NnY3ZTk5c3dramZhNjllcmhjaGNkeGgya3l4cWp6axIqaW5qMWN6dGw4aDU4bDh6Y3YyM2xtMHpyOGg4cnlzdTVoeGNmZ2Q1MHl1GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJz+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA3SZsAXlR9pzcFHog/kjOFSR1EiYHVqNOnWpNWiq7NcuEgQKAggBGNmNARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkA0yE1i3DE6GGITZpVWhESrrYNgKdPRPYKCAnz9QcAdEkwOLHJ9HgOz2Ok9NhjFN5akpyxZTKRGTFX11//hT3Wd",
            "CugFCrgECjgvaW5qZWN0aXZlLmV4Y2hhbmdlLnYxYmV0YTEuTXNnUHJpdmlsZWdlZEV4ZWN1dGVDb250cmFjdBL7AwoqaW5qMWV6dGttMzZ5NmMzZTZ6bXI0aGc0Zzc3YTZ3eWoweGMwZDVneDV2EngxMDIwMDAwMDAwIGZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3VzZGMsIDExMDAgcGVnZ3kweDg3YUIzQjRDODY2MWUwN0Q2MzcyMzYxMjExQjk2ZWQ0RGMzNkIxQjUaKmluajE3cTdkczB5aDdoaHR1c2ZmN2d6OGE1a3gydXd4cnV0dGx4dXI5NiKmAnsiYXJncyI6eyJtc2ciOnsic3Vic2NyaWJlIjp7fX0sInRyYWRlcl9zdWJhY2NvdW50X2lkIjoiMHhjODk3NmRjNzQ0ZDYyMzlkMGI2M2FkZDE1NDdiZGRkMzg5Mjc5YjBmMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwidmF1bHRfc3ViYWNjb3VudF9pZCI6IjB4ZjAzY2Q4M2M5N2Y1ZWViZTQxMjlmMjA0N2VkMmM2NTcxYzYxZjE2YjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMyJ9LCJuYW1lIjoiVmF1bHRTdWJzY3JpYmUiLCJvcmlnaW4iOiJpbmoxZXp0a20zNnk2YzNlNnptcjRoZzRnNzdhNnd5ajB4YzBkNWd4NXYifRjp/cMH+j+kAQovL2luamVjdGl2ZS50eXBlcy52MWJldGExLkV4dGVuc2lvbk9wdGlvbnNXZWIzVHgScQgFEippbmoxN2drdWV0OGY2cHNzeGQ4bnljbTNxcjlkOXk2OTlydXB2NjM5N3oaQS7bNDH7L/B112pVzWT5OTygLht+2aFCIbvRfdlbaJqFAEXaPzWWgHCwBc4C3bCN22c8OHvjiS4ExPfg9EKkTKgAEn4KXgpUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAp46ZxDpNDxsP5gvCZkCc84ZllP7P7q0tL57X7fN0WOcEgQKAgh/GGYSHAoWCgNpbmoSDzM2Mjg2MjUwMDAwMDAwMBDdpSwaQXHoIQ/X5yai6B0reASgAArSShjzpxprthDLEyr+zX7GR07Hr+r8UmZftLbafrcZfRX2UwFw8Q8pHaMINsSjckgb",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTl1cThnZG1reHFmcmdodGVrNDl3YThrMmY4aGhtM3hlNnY5dnh4EippbmoxdzlydjV1MzU1a2UwN2NqZjR3ZzB3YTJjdmF0bWR5Y2RoNm53ZzMaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTl1cThnZG1reHFmcmdodGVrNDl3YThrMmY4aGhtM3hlNnY5dnh4EippbmoxdzlydjV1MzU1a2UwN2NqZjR3ZzB3YTJjdmF0bWR5Y2RoNm53ZzMaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE5dXE4Z2Rta3hxZnJnaHRlazQ5d2E4azJmOGhobTN4ZTZ2OXZ4eBIqaW5qMXc5cnY1dTM1NWtlMDdjamY0d2cwd2EyY3ZhdG1keWNkaDZud2czGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA9YRhWDK9v8bR+HRAI7OzzTaeuCFfDffiIO9zTWhbk4cEgQKAggBGMmeARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBAcshkCtJATtQYYHVorDRUSOGQ7gR1bLp17ZXO5S5aTmB+pRc+/uz8cY3zfP28wpZE4BFa40sSn+vsN7YDc0Ne",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhxcnNtZmx2NzZ0MHcwZnFybXp3enh0eHF1ZTM0bXYzNG1zeHZtEippbmoxdWwyMzVzZnBmbnltY2c4Z2h1dDk4dXdzbnU2OWxuem5hM3pkamQaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhxcnNtZmx2NzZ0MHcwZnFybXp3enh0eHF1ZTM0bXYzNG1zeHZtEippbmoxdWwyMzVzZnBmbnltY2c4Z2h1dDk4dXdzbnU2OWxuem5hM3pkamQaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFocXJzbWZsdjc2dDB3MGZxcm16d3p4dHhxdWUzNG12MzRtc3h2bRIqaW5qMXVsMjM1c2ZwZm55bWNnOGdodXQ5OHV3c251NjlsbnpuYTN6ZGpkGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAimG00m9nDJwqtOiErp8o619mH/3VcEADzWzSqGpnGdIEgQKAggBGLuRARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCnWeua6pt6p7Te8JuofcIaJWaZEhgiOuFqskm9sjQ9yi5qJkOEQXCmCRFCS5uYBpk0/1tuwYXJwtro9GdxHJMI",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWcwbThxM2tkdzMzM3N4cTI5dzduYzM2bWZmY3ZoODBndmNkMzlkEippbmoxbjl3Zmg3YTZjZzJ1Z2d5Z2FkOWFkbGo4M2E0eXdkenV2aHJtcHYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWcwbThxM2tkdzMzM3N4cTI5dzduYzM2bWZmY3ZoODBndmNkMzlkEippbmoxbjl3Zmg3YTZjZzJ1Z2d5Z2FkOWFkbGo4M2E0eXdkenV2aHJtcHYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFnMG04cTNrZHczMzNzeHEyOXc3bmMzNm1mZmN2aDgwZ3ZjZDM5ZBIqaW5qMW45d2ZoN2E2Y2cydWdneWdhZDlhZGxqODNhNHl3ZHp1dmhybXB2GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAhKZIyozzEpDEuAl3ypUW3R3JoD7AtBIAujqq4wwPfVdEgQKAggBGOufARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDMNT7feu38IDUKGBHpWaoydtomgYQZjGPXjj7pb8fEj0MshAm2XfDad53SLdLeKmsXMjQ5cXyYyH15EwUxDYSU",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMW54emhlOTRnc2M5anN5dWMzd3FrdW5qeXZzOHA0ZW1lMGd1NGtlEippbmoxbHFrZ3JkbGh5cWt5M3dnNnJtbnhkajVrd3Rlcjc0ZTJ1ajBtZmYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMW54emhlOTRnc2M5anN5dWMzd3FrdW5qeXZzOHA0ZW1lMGd1NGtlEippbmoxbHFrZ3JkbGh5cWt5M3dnNnJtbnhkajVrd3Rlcjc0ZTJ1ajBtZmYaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFueHpoZTk0Z3NjOWpzeXVjM3dxa3Vuanl2czhwNGVtZTBndTRrZRIqaW5qMWxxa2dyZGxoeXFreTN3ZzZybW54ZGo1a3d0ZXI3NGUydWowbWZmGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAxg89Ih7H74zbkYrMXXb55tjKWTQJQ3D2Sk00p5Y0/ZEEgQKAggBGIqVARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCo/7pJIihg01V2zd+y3WH++KyVIB4m7WC9DAHPRzJIAghGLVJkAJjzGWTHrIGlh7CIira+E0UeSdy1Ag4GMBfS",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTljaGVjeHd6dWZmMDlmbTY2YzUwM3gycm1majBreXp6ZmgzZnRmEippbmoxa3R2MjJhenZ0NWg4bnF6NDh3bmhxc2o5NnVsZTR4eDBkYXc3amoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTljaGVjeHd6dWZmMDlmbTY2YzUwM3gycm1majBreXp6ZmgzZnRmEippbmoxa3R2MjJhenZ0NWg4bnF6NDh3bmhxc2o5NnVsZTR4eDBkYXc3amoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE5Y2hlY3h3enVmZjA5Zm02NmM1MDN4MnJtZmowa3l6emZoM2Z0ZhIqaW5qMWt0djIyYXp2dDVoOG5xejQ4d25ocXNqOTZ1bGU0eHgwZGF3N2pqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAgVaAkMOV5+9OJP2xYw3tKy3aU3SiAIummY3gRAIGDj/EgQKAggBGOihARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBSSP+Fx12//aSYEjjLjr5gl5X4jOUktkOREMTfArsWVxl4Xl7cyV3f7kYAF7kBbQQqrgMerHsc9KePhRVoXB0k",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAzMGtrbDZ1eHlhaG04aGYwZWQ4ZjQwMmY2N2Eyajl4cmM0MnlmEippbmoxejVnNHBhcDdhOGhoeGFheTJwbmZ3ZzNhd241ZHFwNXI0c3Y4a2EaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMXAzMGtrbDZ1eHlhaG04aGYwZWQ4ZjQwMmY2N2Eyajl4cmM0MnlmEippbmoxejVnNHBhcDdhOGhoeGFheTJwbmZ3ZzNhd241ZHFwNXI0c3Y4a2EaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFwMzBra2w2dXh5YWhtOGhmMGVkOGY0MDJmNjdhMmo5eHJjNDJ5ZhIqaW5qMXo1ZzRwYXA3YThoaHhhYXkycG5md2czYXduNWRxcDVyNHN2OGthGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAl0obf7huaZwDxwoKhqdWfwakrBU8rFlrc/Ihiquc4P5EgQKAggBGIOAARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkCGyhKBN8mu+4qID3ZzBPskvusEorT6TXytayPg3k6UpGMaLx38dXS9wmX2yrLrn4G67rihS/fKVCG2yMhdwk4y",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTR0NWY5NG01Zmc0djZkcnM0cXFrZDNkNzMzeTZzczBsanl5cWxtEippbmoxaG05dWhtaGtkdHJ5d3owbXFrOHZhNDAyZTN1ZDB5cGpscWZyM2oaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMTR0NWY5NG01Zmc0djZkcnM0cXFrZDNkNzMzeTZzczBsanl5cWxtEippbmoxaG05dWhtaGtkdHJ5d3owbXFrOHZhNDAyZTN1ZDB5cGpscWZyM2oaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajE0dDVmOTRtNWZnNHY2ZHJzNHFxa2QzZDczM3k2c3MwbGp5eXFsbRIqaW5qMWhtOXVobWhrZHRyeXd6MG1xazh2YTQwMmUzdWQweXBqbHFmcjNqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA4fTy5A+DmuZfsXgjM48ntVqTXlOBW287TjXr91D0VGREgQKAggBGLuVARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBdYIUr7S8ky4p9g+WWi2Ef8Cnq9W5eRsQ6Q6YNcnr0rhzy6lgo31o9tJg6XB0ZHtaJb00qBdU8/igNmfhEZXqk",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWE0dzk5ejRxZ3FjZDZsNnU0ZGpmeWxjdWN0NTNkdXFrdXFucjVkEippbmoxNTI2azM2Y2szbGh2bXJnOHN5eWE4N3R5Njl1cGw4eXp6cms1ZnEaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWE0dzk5ejRxZ3FjZDZsNnU0ZGpmeWxjdWN0NTNkdXFrdXFucjVkEippbmoxNTI2azM2Y2szbGh2bXJnOHN5eWE4N3R5Njl1cGw4eXp6cms1ZnEaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFhNHc5OXo0cWdxY2Q2bDZ1NGRqZnlsY3VjdDUzZHVxa3VxbnI1ZBIqaW5qMTUyNmszNmNrM2xodm1yZzhzeXlhODd0eTY5dXBsOHl6enJrNWZxGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohArGVpE2Qtw7Pq625UTe8FZfqFAGc7IaBTZYPusGkLfnlEgQKAggBGMmAARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDk8e2Du8ReB4Jz73ZkpdaWHIBSo5x0XtILIMecnJzbQ3TykogSC6OQ+tWOCFQp9mUhff++iCbVpFwAx08k+zYS",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3Gj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWdkdnRka2x2M3FnNDMzdnVuOWphcGFkYW5yOTYweDB1MjRxa3FsEippbmoxYWVhNG04ZmFydzlkcjljbTg3YWc3ZDB6Nm1jZnAybnhudjI4YTcaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWdkdnRka2x2M3FnNDMzdnVuOWphcGFkYW5yOTYweDB1MjRxa3FsEippbmoxYWVhNG04ZmFydzlkcjljbTg3YWc3ZDB6Nm1jZnAybnhudjI4YTcaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFnZHZ0ZGtsdjNxZzQzM3Z1bjlqYXBhZGFucjk2MHgwdTI0cWtxbBIqaW5qMWFlYTRtOGZhcnc5ZHI5Y204N2FnN2QwejZtY2ZwMm54bnYyOGE3GkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohAz+Zjrtxo20HOm1w4l5I57H9MAmt+87msPR5/1R/D1McEgQKAggBGMSqARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkDhGCp0+Crr0dfoCZrTb5otuTMtIxxTj9tWfxrfN7cnBTEgKFXVDlsXbay4Wlxz4QBVX4Fb6gtUgQbtDrazOEj9",
            "CvMLCpUBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnUKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGhsKA2luahIUMTAwMDAwMDAwMDAwMDAwMDAwMDAKuQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSmAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGj4KL3BlZ2d5MHg4N2FCM0I0Qzg2NjFlMDdENjM3MjM2MTIxMUI5NmVkNERjMzZCMUI1EgsxMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhubWRsZWF0dHU3dGV0dTZla3d3OXJtMGNtMDNlemc1amx0cnF6EippbmoxbTYzdTV5a3NhZ3Nzajd3Y3hmbDVzN3Q0dTg3azcwamZ5bm5rMmoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvdXNkYxILMTAwMDAwMDAwMDAKxQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSpAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkoKL3BlZ2d5MHg0NEMyMWFmQWFGMjBjMjcwRUJiRjU5MTRDZmMzYjUwMjIxNzNGRUI3EhcxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMArBAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBKgAQoqaW5qMWhubWRsZWF0dHU3dGV0dTZla3d3OXJtMGNtMDNlemc1amx0cnF6EippbmoxbTYzdTV5a3NhZ3Nzajd3Y3hmbDVzN3Q0dTg3azcwamZ5bm5rMmoaRgo3ZmFjdG9yeS9pbmoxN3Z5dGR3cWN6cXo3Mmo2NXNhdWtwbHJrdGQ0Z3lmbWU1YWdmNmMvYWF2ZRILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2NydhILMTAwMDAwMDAwMDAKwAEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSnwEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkUKNmZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL2N2eBILMTAwMDAwMDAwMDAKwQEKHC9jb3Ntb3MuYmFuay52MWJldGExLk1zZ1NlbmQSoAEKKmluajFobm1kbGVhdHR1N3RldHU2ZWt3dzlybTBjbTAzZXpnNWpsdHJxehIqaW5qMW02M3U1eWtzYWdzc2o3d2N4Zmw1czd0NHU4N2s3MGpmeW5uazJqGkYKN2ZhY3RvcnkvaW5qMTd2eXRkd3FjenF6NzJqNjVzYXVrcGxya3RkNGd5Zm1lNWFnZjZjL3NoaWISCzEwMDAwMDAwMDAwGJ3+wwcSggEKYApUCi0vaW5qZWN0aXZlLmNyeXB0by52MWJldGExLmV0aHNlY3AyNTZrMS5QdWJLZXkSIwohA+OlGuxc2hUmrU+iVLb2MDnHy6W4exQyJrbMie9/Sv27EgQKAggBGJqQARIeChcKA2luahIQMTYwMDAwMDAwMDAwMDAwMBCAqMMBGkBTfe9A/RDSoHQCDunT60QgdtBrz3eIGvIgLEISRMAh/2w3+A9UB5SoDNGZNUfpNsxZyyq2Emi6pXuVpFzUCjI5"
         ]
      },
      "evidence":{
         "evidence":[

         ]
      },
      "lastCommit":{
         "height":"15793859",
         "blockId":{
            "hash":"RRhRSiIf1E08mJAtACM4J1RFSVJ96eR0PBVuoD7rb2c=",
            "partSetHeader":{
               "total":1,
               "hash":"SeO5JkVtLUrhegd0rwDatDbvS5PQf/0Yvn+BmL1MOko="
            }
         },
         "signatures":[
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"y8ctJ4QpJ0S7ZTVY7RTE4z1hS2c=",
               "timestamp":"2023-09-07T03:59:36.496584825Z",
               "signature":"AxnPc5AEa6jizZuKhXUAkNi4vic6miF9emyAx+uSMco7oKVwoXGDJ6L0wneNGYOqpKkMVMQm4hcnWgDBjiBLAA=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"M5HjW2EATgO+uI+h2rRES5E7174=",
               "timestamp":"2023-09-07T03:59:36.293269404Z",
               "signature":"mjODCd7P7xHo6Gn+6Qi6/u+FI72noRs9/vcbvpiqz7Hr5hRNhk2a2Jj2tw59GC6cURd2Q6c/CdZhXHgVqzMdAg=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"Nv8cuLE25L4mgnBx8shCmG68xfc=",
               "timestamp":"2023-09-07T03:59:36.393462082Z",
               "signature":"NyTk5W6WLxEbouVJ7LxSwV88FnH/CtmXkr6JczPqEehdrymqrGqT02OJLutGVsBmrPEkMhwa2BegkqvmPLJrBQ=="
            },
            {
               "blockIdFlag":"BLOCK_ID_FLAG_COMMIT",
               "validatorAddress":"ObUXYdS8jfTSNPonUBFPJkft7eA=",
               "timestamp":"2023-09-07T03:59:36.296674286Z",
               "signature":"OAwmf7pEjsXbwIWMD5HbzWiae6OAn0ME49FbXaRLvKIYKWSDKv9f0gprsgRJznOdj60SontlntwmvV+23MV6DQ=="
            }
         ],
         "round":0
      }
   }
}
ParameterTypeDescription
block_idv1.BlockID
blockv1.BlockDeprecated: please use `sdk_block` instead
sdk_blockBlockSince: cosmos-sdk 0.47


BlockID

ParameterTypeDescription
hashbyte array
part_set_headerPartSetHeader


PartSetHeader

ParameterTypeDescription
totaluint32
hashbyte array


Block

ParameterTypeDescription
headerHeader
dataData
evidenceEvidenceList
last_commitCommit


Header

ParameterTypeDescription
versionv11.Consensusbasic block info
chain_idstring
heightint64
timetime.Time
last_block_idBlockIDprev block info
last_commit_hashbyte arrayhashes of block data
data_hashbyte array
validators_hashbyte arrayhashes from the app output from the prev block
next_validators_hashbyte array
consensus_hashbyte array
app_hashbyte array
last_results_hashbyte array
evidence_hashbyte arrayconsensus info
proposer_addressbyte array


Consensus

ParameterTypeDescription
blockuint64
appuint64


Data

ParameterTypeDescription
txs][byte arrayTxs that will be applied by state @ block.Height+1. NOTE: not all txs here are valid. We're just agreeing on the order first. This means that block.AppHash does not include these txs.


EvidenceList

ParameterTypeDescription
evidenceEvidence array


Commit

ParameterTypeDescription
heightint64
roundint32
block_idBlockID
signaturesCommitSig array


CommitSig

ParameterTypeDescription
block_id_flagBlockIDFlag
validator_addressbyte array
timestamptime.Time
signaturebyte array


BlockIDFlag

CodeName
0BLOCK_ID_FLAG_UNKNOWN
1BLOCK_ID_FLAG_ABSENT
2BLOCK_ID_FLAG_COMMIT
3BLOCK_ID_FLAG_NIL

GetLatestValidatorSet

Get the latest validator-set

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    validator_set = await client.fetch_latest_validator_set()
    print(validator_set)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchLatestValidatorSet(ctx)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res.String())

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "blockHeight":"23201498",
   "validators":[
      {
         "address":"injvalcons1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"Bi/7vbVB1uj/zz40/aozZOvVBFkV6hLqqxBIQr5kSc4="
         },
         "votingPower":"200001152291153",
         "proposerPriority":"234447499678197"
      },
      {
         "address":"injvalcons18x63wcw5hjxlf535lgn4qy20yer7mm0qedu0la",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"WlL4lTR+iTbd0rn3xP6oH0juOnGRZ+Hh73Oj6/Lt/Wg="
         },
         "votingPower":"200000153326260",
         "proposerPriority":"-270628320740096"
      },
      {
         "address":"injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"Puku/I45dAZ4wKeN+rbYKnmuUUA7Yh7/TrKX3ZoTmk4="
         },
         "votingPower":"199859452893177",
         "proposerPriority":"-192489141052575"
      },
      {
         "address":"injvalcons1e0rj6fuy9yn5fwm9x4vw69xyuv7kzjm8rvw5r3",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"1mF7OEpB9A60O0e+64pICbqS/nN8VnsVfoySMEW2w1Q="
         },
         "votingPower":"199826816954736",
         "proposerPriority":"228669962114476"
      }
   ],
   "pagination":{
      "total":"4",
      "nextKey":""
   }
}
ParameterTypeDescription
block_heightint64
validatorsValidator array
paginationquery.PageResponsepagination defines an pagination for the response.


Validator

ParameterTypeDescription
addressstring
pub_keytypes.Any
voting_powerint64
proposer_priorityint64


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

GetValidatorSetByHeight

Get the validator-set at a given height

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)

    pagination = PaginationOption(skip=2, limit=4)

    validator_set = await client.fetch_validator_set_by_height(height=23040174, pagination=pagination)
    print(validator_set)


if __name__ == "__main__":
    symbol_db = symbol_database.Default()
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    height := int64(23040174)
    pagination := query.PageRequest{Offset: 2, Limit: 10}
    res, err := chainClient.FetchValidatorSetByHeight(ctx, height, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(res.String())

}
ParameterTypeDescriptionRequired
heightint64Yes
paginationquery.PageRequestpagination defines an pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "blockHeight":"23040174",
   "validators":[
      {
         "address":"injvalcons1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"Bi/7vbVB1uj/zz40/aozZOvVBFkV6hLqqxBIQr5kSc4="
         },
         "votingPower":"200001152291142",
         "proposerPriority":"-117113073985972"
      },
      {
         "address":"injvalcons18x63wcw5hjxlf535lgn4qy20yer7mm0qedu0la",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"WlL4lTR+iTbd0rn3xP6oH0juOnGRZ+Hh73Oj6/Lt/Wg="
         },
         "votingPower":"200000153326249",
         "proposerPriority":"-30678774375098"
      },
      {
         "address":"injvalcons1xwg7xkmpqp8q804c37sa4dzyfwgnh4a74ll9pz",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"Puku/I45dAZ4wKeN+rbYKnmuUUA7Yh7/TrKX3ZoTmk4="
         },
         "votingPower":"199859452893172",
         "proposerPriority":"358858430481236"
      },
      {
         "address":"injvalcons1e0rj6fuy9yn5fwm9x4vw69xyuv7kzjm8rvw5r3",
         "pubKey":{
            "@type":"/cosmos.crypto.ed25519.PubKey",
            "key":"1mF7OEpB9A60O0e+64pICbqS/nN8VnsVfoySMEW2w1Q="
         },
         "votingPower":"199826816954540",
         "proposerPriority":"504834849146021"
      }
   ],
   "pagination":{
      "total":"7",
      "nextKey":""
   }
}
ParameterTypeDescription
block_heightint64
validatorsValidator array
paginationquery.PageResponsepagination defines an pagination for the response.


Validator

ParameterTypeDescription
addressstring
pub_keytypes.Any
voting_powerint64
proposer_priorityint64


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

ABCIQuery

Defines a query handler that supports ABCI queries directly to the application, bypassing Tendermint completely. The ABCI query must contain a valid and supported path, including app, custom, p2p, and store.

IP rate limit group: chain

Request Parameters

Request Example:

ParameterTypeDescriptionRequired
databyte arrayYes
pathstringYes
heightint64Yes
proveboolYes

Response Parameters

Response Example:


ParameterTypeDescription
codeuint32
logstring
infostring
indexint64
keybyte array
valuebyte array
proof_opsProofOps
heightint64
codespacestring


ProofOps

ParameterTypeDescription
opsProofOp array


ProofOp

ParameterTypeDescription
typestring
keybyte array
databyte array

- Tokenfactory

Tokenfactory module

DenomAuthorityMetadata

Gets the authority metadata for tokens by their creator address

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    metadata = await client.fetch_denom_authority_metadata(
        creator="inj1uv6psuupldve0c9n3uezqlecadszqexv5vxx04",
        sub_denom="position",
    )
    print(metadata)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    creator := "inj1uv6psuupldve0c9n3uezqlecadszqexv5vxx04"
    subDenom := "position"
    ctx := context.Background()

    res, err := chainClient.FetchDenomAuthorityMetadata(ctx, creator, subDenom)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
creatorstringThe creator's Injective addressYes
sub_denomstringThe sub-denomYes

Response Parameters

Response Example:

{'authorityMetadata': {'admin': 'inj1uv6psuupldve0c9n3uezqlecadszqexv5vxx04'}}
{
 "authority_metadata": {
  "admin": "inj1uv6psuupldve0c9n3uezqlecadszqexv5vxx04"
 }
}

ParameterTypeDescription
authority_metadataDenomAuthorityMetadataThe authority metadata


DenomAuthorityMetadata

ParameterTypeDescription
adminstringCan be empty for no admin, or a valid injective address
admin_burn_allowedbooltrue if the admin can burn tokens from other addresses

DenomsFromCreator

Gets all the tokens created by a specific admin/creator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    denoms = await client.fetch_denoms_from_creator(creator="inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3")
    print(denoms)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    creator := "inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3"
    ctx := context.Background()

    res, err := chainClient.FetchDenomsFromCreator(ctx, creator)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
creatorstringThe creator's Injective addressYes

Response Parameters

Response Example:

{
   "denoms":[
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Stake-0",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-2",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-3",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-4",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Vote-0",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/banana",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/bananas",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token10",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token2",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token3",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token4",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token5",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token6",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token7",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token8",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token9",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-5",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-6",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-7",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-8",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token10",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token2",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token3",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token4",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token5",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token6",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token7",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token8",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token9",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xTalis-4",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xbanana",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-5",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-6",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-7",
      "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-8"
   ]
}
{
 "denoms": [
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Stake-0",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-2",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-3",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Talis-4",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/Vote-0",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/banana",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/bananas",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token10",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token2",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token3",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token4",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token5",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token6",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token7",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token8",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/stake-token9",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-5",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-6",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-7",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/talis-8",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token10",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token2",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token3",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token4",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token5",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token6",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token7",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token8",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/vote-token9",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xTalis-4",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xbanana",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-5",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-6",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-7",
  "factory/inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3/xtalis-8"
 ]
}

ParameterTypeDescription
denomsstring arrayThe list of denoms

TokenfactoryModuleState

Retrieves the entire auctions module's state

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    state = await client.fetch_tokenfactory_module_state()
    print(state)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchTokenfactoryModuleState(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
   "state":{
      "params":{
         "denomCreationFee":[
            {
               "denom":"inj",
               "amount":"1000000000000000000"
            }
         ]
      },
      "factoryDenoms":[
         {
            "denom":"factory/inj10gcvfpnn4932kzk56h5kp77mrfdqas8z63qr7n/BITS",
            "authorityMetadata":{
               "admin":"inj10gcvfpnn4932kzk56h5kp77mrfdqas8z63qr7n"
            },
            "name":"BITS",
            "symbol":"BITS"
         },
         {
            "denom":"factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
            "authorityMetadata":{
               "admin":"inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27"
            },
            "name":"",
            "symbol":""
         },
         {
            "denom":"factory/inj10jmp6sgh4cc6zt3e8gw05wavvejgr5pw6m8j75/ak",
            "authorityMetadata":{
               "admin":"inj10jmp6sgh4cc6zt3e8gw05wavvejgr5pw6m8j75"
            },
            "name":"AKCoin",
            "symbol":"AK"
         }
      ]
   }
}
{
   "state":{
      "params":{
         "denomCreationFee":[
            {
               "denom":"inj",
               "amount":"1000000000000000000"
            }
         ]
      },
      "factoryDenoms":[
         {
            "denom":"factory/inj10gcvfpnn4932kzk56h5kp77mrfdqas8z63qr7n/BITS",
            "authorityMetadata":{
               "admin":"inj10gcvfpnn4932kzk56h5kp77mrfdqas8z63qr7n"
            },
            "name":"BITS",
            "symbol":"BITS"
         },
         {
            "denom":"factory/inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27/position",
            "authorityMetadata":{
               "admin":"inj10hmmvlqq6rrlf2c2v982d6xqsns4m3sy086r27"
            },
            "name":"",
            "symbol":""
         },
         {
            "denom":"factory/inj10jmp6sgh4cc6zt3e8gw05wavvejgr5pw6m8j75/ak",
            "authorityMetadata":{
               "admin":"inj10jmp6sgh4cc6zt3e8gw05wavvejgr5pw6m8j75"
            },
            "name":"AKCoin",
            "symbol":"AK"
         }
      ]
   }
}

ParameterTypeDescription
stateGenesisStateThe module state


GenesisState

ParameterTypeDescription
paramsParamsparams defines the parameters of the module.
factory_denomsGenesisDenom array


Params

ParameterTypeDescription
denom_creation_feegithub_com_cosmos_cosmos_sdk_types.CoinsThe denom creation fee


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int


GenesisDenom

ParameterTypeDescription
denomstringThe denom
authority_metadataDenomAuthorityMetadataThe authority metadata
namestringThe name
symbolstringThe symbol
decimalsuint32The number of decimals


DenomAuthorityMetadata

ParameterTypeDescription
adminstringCan be empty for no admin, or a valid injective address
admin_burn_allowedbooltrue if the admin can burn tokens from other addresses

CreateDenom

Create a new denom

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    message = composer.msg_create_denom(
        sender=address.to_acc_bech32(),
        subdenom="inj_test",
        name="Injective Test Token",
        symbol="INJTEST",
        decimals=18,
        allow_admin_burn=False,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    tokenfactorytypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    message := tokenfactorytypes.MsgCreateDenom{
        Sender:   senderAddress.String(),
        Subdenom: "inj_test",
        Name:     "Injective Test Token",
        Symbol:   "INJTEST",
        Decimals: 18,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
subdenomstringsubdenom can be up to 44 "alphanumeric" characters long.Yes
namestringThe nameYes
symbolstringThe symbolYes
decimalsuint32The number of decimalsYes
allow_admin_burnbooltrue if admins are allowed to burn tokens from other addressesYes

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgMint

Allows a token admin's account to mint more units

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    amount = composer.coin(amount=1_000_000_000, denom="factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test")

    message = composer.msg_mint(
        sender=address.to_acc_bech32(),
        amount=amount,
        receiver="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"

    tokenfactorytypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    message := tokenfactorytypes.MsgMint{
        Sender: senderAddress.String(),
        Amount: sdktypes.Coin{
            Denom:  "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test",
            Amount: math.NewInt(1000000000),
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
amounttypes.CoinThe amount of tokens to mintYes
receiverstringThe Injective address to receive the tokensYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgBurn

Allows a token admin's account to burn circulating units

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    amount = composer.coin(amount=100, denom="factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test")

    message = composer.msg_burn(
        sender=address.to_acc_bech32(),
        amount=amount,
        burn_from_address="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    "cosmossdk.io/math"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    sdktypes "github.com/cosmos/cosmos-sdk/types"

    tokenfactorytypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    message := tokenfactorytypes.MsgBurn{
        Sender: senderAddress.String(),
        Amount: sdktypes.Coin{
            Denom:  "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test",
            Amount: math.NewInt(100),
        },
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
amounttypes.CoinThe amount of tokens to burnYes
burnFromAddressstringThe Injective address to burn the tokens fromYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgSetDenomMetadata

Allows a token admin's account to set the token metadata

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    sender = address.to_acc_bech32()
    description = "Injective Test Token"
    subdenom = "inj_test"
    denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    token_decimals = 6
    name = "Injective Test"
    symbol = "INJTEST"
    uri = "http://injective-test.com/icon.jpg"
    uri_hash = ""

    message = composer.msg_set_denom_metadata(
        sender=sender,
        description=description,
        denom=denom,
        subdenom=subdenom,
        token_decimals=token_decimals,
        name=name,
        symbol=symbol,
        uri=uri,
        uri_hash=uri_hash,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
    banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

    tokenfactorytypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    denom := "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
    subdenom := "inj_test"
    tokenDecimals := uint32(6)

    microDenomUnit := banktypes.DenomUnit{
        Denom:    denom,
        Exponent: 0,
        Aliases:  []string{fmt.Sprintf("micro%s", subdenom)},
    }
    denomUnit := banktypes.DenomUnit{
        Denom:    subdenom,
        Exponent: tokenDecimals,
        Aliases:  []string{subdenom},
    }

    metadata := banktypes.Metadata{
        Description: "Injective Test Token",
        DenomUnits:  []*banktypes.DenomUnit{&microDenomUnit, &denomUnit},
        Base:        denom,
        Display:     subdenom,
        Name:        "Injective Test",
        Symbol:      "INJTEST",
        URI:         "http://injective-test.com/icon.jpg",
        URIHash:     "",
        Decimals:    tokenDecimals,
    }

    message := tokenfactorytypes.MsgSetDenomMetadata{
        Sender:   senderAddress.String(),
        Metadata: metadata,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
metadatatypes1.MetadataThe metadataYes
admin_burn_disabledMsgSetDenomMetadata_AdminBurnDisabledNo


Metadata

ParameterTypeDescription
descriptionstring
denom_unitsDenomUnit arraydenom_units represents the list of DenomUnit's for a given coin
basestringbase represents the base denom (should be the DenomUnit with exponent = 0).
displaystringdisplay indicates the suggested denom that should be displayed in clients.
namestringname defines the name of the token (eg: Cosmos Atom) Since: cosmos-sdk 0.43
symbolstringsymbol is the token symbol usually shown on exchanges (eg: ATOM). This can be the same as the display. Since: cosmos-sdk 0.43
uristringURI to a document (on or off-chain) that contains additional information. Optional. Since: cosmos-sdk 0.46
uri_hashstringURIHash is a sha256 hash of a document pointed by URI. It's used to verify that the document didn't change. Optional. Since: cosmos-sdk 0.46
decimalsuint32Decimals represent the number of decimals use to represent token amount on chain Since: cosmos-sdk 0.50


DenomUnit

ParameterTypeDescription
denomstringdenom represents the string name of the given denom unit (e.g uatom).
exponentuint32exponent represents power of 10 exponent that one must raise the base_denom to in order to equal the given DenomUnit's denom 1 denom = 10^exponent base_denom (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with exponent = 6, thus: 1 atom = 10^6 uatom).
aliasesstring arrayaliases is a list of string aliases for the given denom

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgChangeAdmin

Allows a token admin's account to transfer administrative privileged to other account

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    message = composer.msg_change_admin(
        sender=address.to_acc_bech32(),
        denom="factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test",
        new_admin="inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49",  # This is the zero address to remove admin permissions
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    tokenfactorytypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    message := tokenfactorytypes.MsgChangeAdmin{
        Sender: senderAddress.String(),
        Denom:  "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test",
        // This is the zero address to remove admin permissions
        NewAdmin: "inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49",
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Print(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringThe sender's Injective addressYes
denomstringThe denomYes
new_adminstringThe new admin's Injective addressYes

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- TXFees

The txfees module for Injective provides the required functionality to support fee market as per EIP-1559.

GetEipBaseFee

Retrieves the current chain gas price

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    metadata = await client.fetch_eip_base_fee()
    print(json.dumps(metadata, indent=2))


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    res, err := chainClient.FetchEipBaseFee(ctx)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}

No parameters

Response Parameters

Response Example:

{
    "baseFee": {
        "baseFee": "160000000000000000000000000"
    }
}
ParameterTypeDescription
base_feeEipBaseFee


EipBaseFee

ParameterTypeDescription
base_feecosmossdk_io_math.LegacyDecThe current chain gas price

- Wasm

CosmWasm smart contract interactions.

ContractInfo

Queries validator commission and self-delegation rewards for validator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    contract_info = await client.fetch_contract_info(address=address)
    print(contract_info)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    ctx := context.Background()

    res, err := chainClient.FetchContractInfo(ctx, address)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address of the contract to queryYes

Response Parameters

Response Example:

{
   "address":"inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
   "contractInfo":{
      "codeId":"290",
      "creator":"inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty",
      "label":"CounterTestInstance",
      "created":{
         "blockHeight":"6232017",
         "txIndex":"145751"
      },
      "admin":"",
      "ibcPortId":""
   }
}
{
 "address": "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
 "code_id": 290,
 "creator": "inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty",
 "label": "CounterTestInstance",
 "created": {
  "block_height": 6232017,
  "tx_index": 145751
 }
}

ParameterTypeDescription
addressstringaddress is the address of the contract
contract_infoContractInfo


ContractInfo

ParameterTypeDescription
code_iduint64CodeID is the reference to the stored Wasm code
creatorstringCreator address who initially instantiated the contract
adminstringAdmin is an optional address that can execute migrations
labelstringLabel is optional metadata to be stored with a contract instance.
createdAbsoluteTxPositionCreated Tx position when the contract was instantiated.
ibc_port_idstring
extensiontypes.AnyExtension is an extension point to store custom metadata within the persistence model.


AbsoluteTxPosition

ParameterTypeDescription
block_heightuint64BlockHeight is the block the contract was created at
tx_indexuint64TxIndex is a monotonic counter within the block (actual transaction index, or gas consumed)

ContractHistory

Gets the contract code history

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj18pp4vjwucpgg4nw3rr4wh4zyjg9ct5t8v9wqgj"
    limit = 2
    pagination = PaginationOption(limit=limit)
    contract_history = await client.fetch_contract_history(address=address, pagination=pagination)
    print(contract_history)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj18pp4vjwucpgg4nw3rr4wh4zyjg9ct5t8v9wqgj"
    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchContractHistory(ctx, address, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address of the contract to queryYes
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "entries":[
      {
         "operation":"CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT",
         "codeId":"3770",
         "updated":{
            "blockHeight":"20210946",
            "txIndex":"2196537"
         },
         "msg":"eyJhZG1pbiI6ImluajFtYWV5dnhmYW10bjhsZnl4cGpjYThrdXZhdXVmMnFldTZndHhtMyIsImNvZGVJZCI6IjM3NzAiLCJsYWJlbCI6IlRhbGlzIGNhbmR5IG1hY2hpbmUiLCJtc2ciOiIiLCJzZW5kZXIiOiJpbmoxandsbmN1dTY3NnQzcWZqZGxjd3NkZ3gwZ2c2anBhOHNuZXM0eHQiLCJmdW5kc0xpc3QiOltdLCJjb250cmFjdF9hZGRyZXNzIjoiaW5qMWd2emdneGc1NGRmd2FlcnpsZWdqdnFlZzN1ZTk3ZHEydmV0OTJ6Iiwib3duZXIiOiJpbmoxandsbmN1dTY3NnQzcWZqZGxjd3NkZ3gwZ2c2anBhOHNuZXM0eHQiLCJmZWVfY29sbGVjdG9yIjoiaW5qMW1hZXl2eGZhbXRuOGxmeXhwamNhOGt1dmF1dWYycWV1Nmd0eG0zIiwib3BlcmF0b3JfcHVia2V5IjoiQSsxQkVrWXVTQjJQa1IwWDVJMnZzQnNuTldHMVlPRDJUUTJJUHZnelJVVXYiLCJwcml2YXRlX3BoYXNlcyI6W3siaWQiOjAsInByaXZhdGUiOnRydWUsInN0YXJ0IjoxNzA0MTM4NTQwLCJlbmQiOjE3MDQxNDIxNDAsInByaWNlIjp7Im5hdGl2ZSI6W3siZGVub20iOiJpbmoiLCJhbW91bnQiOiIwIn1dfSwid2xfbWVya2xlX3Jvb3QiOiI1NGE5Yzg0MmE5MmY4ZGQ3Zjg3ZTZhZDM0MGEwMWI5ZmVhZWE0MjQyOThjYTA1NmY3NGNmZTAyNzFkZDExYjIwIn0seyJpZCI6MSwicHJpdmF0ZSI6dHJ1ZSwic3RhcnQiOjE3MDQxNDIxNDIsImVuZCI6MTcwNDE0NTc0MCwicHJpY2UiOnsibmF0aXZlIjpbeyJkZW5vbSI6ImluaiIsImFtb3VudCI6IjEwMDAwMDAwMDAwMDAwMDAwMCJ9XX0sIndsX21lcmtsZV9yb290IjoiZjU4YTIwZmUyMWUyYzRkNzE0OTRhMGMyOWQyZWRmZDRjZGJiNzgwOTlmZDQ1NWFkZjg0MjdjMjdiMjFiOGQ3YiJ9XSwicHVibGljX3BoYXNlIjp7ImlkIjoyLCJwcml2YXRlIjpmYWxzZSwic3RhcnQiOjE3MDQxNDU3NDIsImVuZCI6MTcwNDE0OTM0MCwicHJpY2UiOnsibmF0aXZlIjpbeyJkZW5vbSI6ImluaiIsImFtb3VudCI6IjQ1MDAwMDAwMDAwMDAwMDAwMCJ9XX0sIm1pbnRfbGltaXQiOjEwfSwicmVzZXJ2ZWRfdG9rZW5zIjo3NywidG90YWxfdG9rZW5zIjo3Nzd9"
      }
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   }
}
{
 "entries": [
  {
   "operation": 1,
   "code_id": 3770,
   "updated": {
    "block_height": 20210946,
    "tx_index": 2196537
   },
   "msg": {
    "admin": "inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3",
    "codeId": "3770",
    "label": "Talis candy machine",
    "msg": "",
    "sender": "inj1jwlncuu676t3qfjdlcwsdgx0gg6jpa8snes4xt",
    "fundsList": [],
    "contract_address": "inj1gvzggxg54dfwaerzlegjvqeg3ue97dq2vet92z",
    "owner": "inj1jwlncuu676t3qfjdlcwsdgx0gg6jpa8snes4xt",
    "fee_collector": "inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3",
    "operator_pubkey": "A+1BEkYuSB2PkR0X5I2vsBsnNWG1YOD2TQ2IPvgzRUUv",
    "private_phases": [
     {
      "id": 0,
      "private": true,
      "start": 1704138540,
      "end": 1704142140,
      "price": {
       "native": [
        {
         "denom": "inj",
         "amount": "0"
        }
       ]
      },
      "wl_merkle_root": "54a9c842a92f8dd7f87e6ad340a01b9feaea424298ca056f74cfe0271dd11b20"
     },
     {
      "id": 1,
      "private": true,
      "start": 1704142142,
      "end": 1704145740,
      "price": {
       "native": [
        {
         "denom": "inj",
         "amount": "100000000000000000"
        }
       ]
      },
      "wl_merkle_root": "f58a20fe21e2c4d71494a0c29d2edfd4cdbb78099fd455adf8427c27b21b8d7b"
     }
    ],
    "public_phase": {
     "id": 2,
     "private": false,
     "start": 1704145742,
     "end": 1704149340,
     "price": {
      "native": [
       {
        "denom": "inj",
        "amount": "450000000000000000"
       }
      ]
     },
     "mint_limit": 10
    },
    "reserved_tokens": 77,
    "total_tokens": 777
   }
  }
 ],
 "pagination": {}
}

ParameterTypeDescription
entriesContractCodeHistoryEntry array
paginationquery.PageResponsepagination defines the pagination in the response.


ContractCodeHistoryEntry

ParameterTypeDescription
operationContractCodeHistoryOperationType
code_iduint64CodeID is the reference to the stored WASM code
updatedAbsoluteTxPositionUpdated Tx position when the operation was executed.
msgRawContractMessage


ContractCodeHistoryOperationType

CodeName
0CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED
1CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT
2CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE
3CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS


AbsoluteTxPosition

ParameterTypeDescription
block_heightuint64BlockHeight is the block the contract was created at
tx_indexuint64TxIndex is a monotonic counter within the block (actual transaction index, or gas consumed)


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

ContractsByCode

Get all smart contracts for a code id

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    code_id = 3770
    limit = 2
    pagination = PaginationOption(limit=limit)
    contracts = await client.fetch_contracts_by_code(code_id=code_id, pagination=pagination)
    print(contracts)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    codeId := uint64(3770)
    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchContractsByCode(ctx, codeId, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
code_iduint64Yes
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "contracts":[
      "inj1z4l7jc8dj3y9484aqcrmf6y8mcctvkmm9zkf7n",
      "inj18jead47nj8j20kxq5j2rm6l9fmf45f8ey9muuh"
   ],
   "pagination":{
      "nextKey":"AAAAAAEWkNYAAAAAAAAAAEnOwG7FHHD7R+iyNAZCsoHr5hA1",
      "total":"0"
   }
}
{
 "contracts": [
  "inj1z4l7jc8dj3y9484aqcrmf6y8mcctvkmm9zkf7n",
  "inj18jead47nj8j20kxq5j2rm6l9fmf45f8ey9muuh"
 ],
 "pagination": {
  "next_key": "AAAAAAEWkNYAAAAAAAAAAEnOwG7FHHD7R+iyNAZCsoHr5hA1"
 }
}

ParameterTypeDescription
contractsstring arraycontracts are a set of contract addresses
paginationquery.PageResponsepagination defines the pagination in the response.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

AllContractState

Gets all raw store data for a single contract

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    limit = 2
    pagination = PaginationOption(limit=limit)
    contract_history = await client.fetch_all_contracts_state(address=address, pagination=pagination)
    print(contract_history)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchAllContractsState(ctx, address, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address of the contractYes
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "models":[
      {
         "key":"Y29udHJhY3RfaW5mbw==",
         "value":"eyJjb250cmFjdCI6ImNyYXRlcy5pbzpjdy1jb3VudGVyIiwidmVyc2lvbiI6IjAuMS4wIn0="
      },
      {
         "key":"c3RhdGU=",
         "value":"eyJjb3VudCI6MTA0MSwib3duZXIiOiJpbmoxaDNnZXBhNHRzemg2NmVlNjdoZTUzanptcHJzcWMybDlucHEzdHkifQ=="
      }
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   }
}
{
 "models": [
  {
   "key": "636F6E74726163745F696E666F",
   "value": "eyJjb250cmFjdCI6ImNyYXRlcy5pbzpjdy1jb3VudGVyIiwidmVyc2lvbiI6IjAuMS4wIn0="
  },
  {
   "key": "7374617465",
   "value": "eyJjb3VudCI6MTA0MSwib3duZXIiOiJpbmoxaDNnZXBhNHRzemg2NmVlNjdoZTUzanptcHJzcWMybDlucHEzdHkifQ=="
  }
 ],
 "pagination": {}
}
ParameterTypeDescription
modelsModel array
paginationquery.PageResponsepagination defines the pagination in the response.


Model

ParameterTypeDescription
keygithub_com_cometbft_cometbft_libs_bytes.HexByteshex-encode key to read it better (this is often ascii)
valuebyte arraybase64-encode raw value


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

RawContractState

Gets single key from the raw store data of a contract

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    query_data = '{"get_count": {}}'
    contract_state = await client.fetch_raw_contract_state(address=address, query_data=query_data)
    print(contract_state)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    queryData := []byte("{\"get_count\": {}}")
    ctx := context.Background()

    res, err := chainClient.RawContractState(ctx, address, queryData)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address of the contractYes
query_databyte arrayYes

Response Parameters

Response Example:

ParameterTypeDescription
databyte arrayData contains the raw store data

SmartContractState

Get smart query result from the contract

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    query_data = '{"get_count": {}}'
    contract_state = await client.fetch_smart_contract_state(address=address, query_data=query_data)
    print(contract_state)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    address := "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
    queryData := []byte("{\"get_count\": {}}")
    ctx := context.Background()

    res, err := chainClient.SmartContractState(ctx, address, queryData)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
addressstringaddress is the address of the contractYes
query_dataRawContractMessageQueryData contains the query data passed to the contractYes

Response Parameters

Response Example:

{'data': 'eyJjb3VudCI6MTA0MX0='}
{
 "data": {
  "count": 1041
 }
}
ParameterTypeDescription
dataRawContractMessageData contains the json data returned from the smart contract

Code

Gets the binary code and metadata for a contract

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import base64

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network)
    response = await client.fetch_code(code_id=290)
    print(response)

    code = base64.b64decode(response["data"]).decode(encoding="utf-8", errors="replace")

    print(f"\n\n\n{code}")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    codeId := uint64(290)
    ctx := context.Background()

    res, err := chainClient.FetchCode(ctx, codeId)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
code_iduint64Yes

Response Parameters

Response Example:

{
   "codeInfo":{
      "codeId":"290",
      "creator":"inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty",
      "dataHash":"+OdoniOsDJ1T9EqP2YxobCCwFAqNdtYA4sVGv7undY0=",
      "instantiatePermission":{
         "permission":"ACCESS_TYPE_EVERYBODY",
         "addresses":[

         ]
      }
   },
   "data":"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Qf8BcQshBgJAAkACQCAEIAZyIgZB/wFxIgVBAkcEQCAGQQFxDQEgC0UNAiADQfACakG5gcAAQQcQGCARRQ0KDAkLIAsNCiADQdACakG5gcAAQQcQFiADKALQAkEVRgRAIAMoAtwCIRQgAygC2AIhESADKALUAiELDAsLIANB+AJqIANB2AJqKQMANwMAIAMgAykD0AI3A/ACDAkLIANB0AJqIA4QjgECQCADKALQAiIPQRVHBEAgFyAYKQIANwIAIBdBCGogGEEIaigCADYCACADIA82AoADDAELIANBgANqIA4QFyADKAKAA0EVRg0CCyADQfgCaiADQYgDaikDADcDACADIAMpA4ADNwPwAgwGCyADQdACaiAOEI4BIAMoAtACIgRBFUcNAiADQdACaiAOEBogAygC3AIhFCADKALYAiERIAMoAtQCIQsgAygC0AIiBEEVRw0JCyADQbABaiAOEJABIAMtALEBIQQgAy0AsAFBAXENAAsMAgsgAygC3AIhFCADKALYAiERIAMoAtQCIQsMBgsgC0H/AXEhC0EEIQQMBQsgAyAJNgL8AiADIAQ2AvgCIAMgBTYC9AIgAyABNgLwAgsgC0UgEUVyDQELIAsQqwELIAMoAvwCIRQgAygC+AIhESADKAL0AiELIAMoAvACIgRBFUcNAQsgA0HQAmogCBCNASADKALQAiIEQRVGDQIgAygC3AIhFCADKALYAiADKALUAiEBIBEEQCALEKsBCyERIAEhCwsgAyAUNgKkAiADIBE2AqACIAMgCzYCnAIgAyAENgKYAgwJCyAhQiiIpyEKICFCIIinIRUgIachGyAJIRYLIANBCGogCBCQASADLQAJIQEgAy0ACEEBcQ0AC0ECIQQMAwtBACENDAMLIANBoAJqIANB2AJqKQMANwMAIAMgAykD0AI3A5gCIBZFDQUgDRCrAQwFCyADIBQ2AsgCIAMpA8gCISAgA0GYAmogA0GIAmoQjQEgAygCmAIiAUEVRwRAIAMtAJ8CQRB0IQkgAy8AnQIgAykDoAIhICADLQCcAiEMIBYEQCANEKsBCyAJciECIBFFDQYgCxCrAQwGCyADQZgCaiADQYgCahCLASADKAKYAiIBQRVHBEAgAy0AnwJBEHQhCSADLwCdAiADKQOgAiEgIAMtAJwCIQwgFgRAIA0QqwELIAlyIQIg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aigCACIENgIAIAMgCykCACIMNwMwIAlBCGogBDYCACAJIAw3AgAMAQsgA0EgaiAHEBcgAygCICIFQRVGDQELIAMoAiwhCSADKAIoIQggAy0AJCEEIAMvACUgAy0AJ0EQdHIMBgsgAyAHEJABIAMtAAEhBSADLQAAQQFxDQALCyAEQf8BcSEEQQIhBQwCCyAKQRU2AgAMAwsgAygCTCEJIAYhBAsgBEEIdgsiBjsABSAKIAk2AAwgCiAINgAIIAogBDoABCAKIAU2AgAgCkEHaiAGQRB2OgAACyADQdAAaiQAIAIoAlAiBEEVRw0KIAJB0ABqIAEQjQEgAigCUCIBQRVGBEAgAEEVNgIADAwLIAJByABqIAJB3ABqKAIAIgQ2AgAgAiACKQJUIgw3A0AgAEEMaiAENgIAIAAgDDcCBCAAIAE2AgAMCwsgAEELNgIADAoLIABBFTYCAAwJCyAAQQA7AAUgAEEENgIAIABBB2pBADoAAAwICyAAQQ42AgAMBwsgAikCVCEMIAAgAigCXDYCDCAAIAw3AgQgACABNgIADAYLIABBADsABSAAQQQ2AgAgAEEHakEAOgAADAULIABBDjYCAAwECyACQcgAaiACQdwAaigCACIBNgIAIAIgAikCVCIMNwNAIABBDGogATYCACAAIAw3AgQgACAENgIADAMLIABBADsABSAAQQQ2AgAgAEEHakEAOgAADAILIABBDjYCAAwBCyACQcgAaiACQdwAaigCACIBNgIAIAIgAikCVCIMNwNAIABBDGogATYCACAAIAw3AgQgACAENgIACyACQeAAaiQAC8UBAQF/IwBB8ABrIgMkACADIAI2AgwgAyABNgIIIANBJGpBATYCACADQgI3AhQgA0GUi8AANgIQIANBATYCLCADIANBKGo2AiAgAyADQQhqNgIoIANBADYCOCADQgE3AzAgA0FAayIBIANBMGpBqIXAABDyASADQRBqIAEQ6AEEQEHAhcAAQTcgA0HoAGpB+IXAAEHUhsAAEOkBAAsgACADKQMwNwIEIABBFDYCACAAQQxqIANBOGooAgA2AgAgA0HwAGokAAuFBAIFfwJ+IwBB4ABrIgMkACADIAI2AgwgAyABNgIIIwBBEGsiBiQAIANBEGoiBAJ/AkACQCACRQRAIARBADoAAQwBCwJAAkACQCABLQAAQStrDgMBAgACCyACQQFGDQMMAQsgAkEBayICRQ0CIAFBAWohAQsCQAJAAkAgAkERTwRAA0AgBiAIQgBCChCMAiABLQAAQTBrIgVBCUsNBiAGKQMIQgBSDQQgBikDACIJIAUgByAFQQpJG618IgggCVQNAyABQQFqIQEgBSEHIAJBAWsiAg0ACwwBCwNAIAEtAABBMGsiBUEJSw0FIAFBAWohASAFrSAIQgp+fCEIIAJBAWsiAg0ACwsgBCAINwMIQQAMBAsgBEECOgABDAELIARBAjoAAQtBAQwBCyAEQQE6AAFBAQs6AAAgBkEQaiQAAkAgAy0AEEUEQCAAIAMpAxg3AwggAEEVNgIADAELIAMgAy0AEToAJyADQcQAakECNgIAIANBATYCPCADIANBJ2o2AkAgAyADQQhqNgI4IANBAjYCXCADQgI3AkwgA0Hci8AANgJIIAMgA0E4ajYCWCADQShqIgEgA0HIAGoiAhDQASACQQRyIAEQ0QEgA0EUNgJIIAMoAiwEQCADKAIoEKsBCyAAIAMpA0g3AgAgAEEIaiADQdAAaikDADcCAAsgA0HgAGokAAvFAgIEfwF+IwBBIGsiAiQAIAJBCGogARCQAQJAAkACQAJAAkAgAi0ACEEBcQRAIAItAAlBIkcNASABEIoBIAJBEGogARCPASACKAIQIgFBFUcNAiACQRxqKAIAIQEgAkEYaigCACEDIAIoAhQiBEUEQAJAIAFFBEBBASEEDAELIAFBf0oiBUUNBSABIAUQPSIERQ0GCyAEIAMgARCLAiEDIABBDGogATYCACAAQQhqIAE2AgAgACADNgIEIABBFTYCAAwGCyAAIAQ2AgQgAEEVNgIAIABBDGogATYCACAAQQhqIAM2AgAMBQsgAEEAOwAFIABBBDYCACAAQQdqQQA6AAAMBAsgAEEONgIADAMLIAIpAhQhBiAAIAIoAhw2AgwgACAGNwIEIAAgATYCAAwCCxDPAQALIAEgBRDOAQALIAJBIGokAAv3AQEDfyMAQUBqIgQkAAJAAkACQAJAIAJFBEBBASEFDAELIAJBf0oiBkUNASACIAYQPSIFRQ0CCyAFIAEgAhCLAiEBIARBADYCCCAEQgE3AwAgBEEQaiIFIARBqIXAABDyASADIAUQhwENAiAAQQxqIAI2AgAgAEEIaiACNgIAIAAgATYCBCAAIAQpAwA3AhAgAEEINgIAIABBGGogBEEIaigCADYCAAJAIAMoAgBBFEkNACADQQhqKAIARQ0AIAMoAgQQqwELIARBQGskAA8LEM8BAAsgAiAGEM4BAAtBwIXAAEE3IARBOGpB+IXAAEHUhsAAEOkBAAvwIwIbfwN+IwBBkAJrIgMkACADQZABaiIHIAEgAhCJASADQYgBaiAHEJABQQAhAgJAAkACQCADLQCIAUEBcUUEQEEEIQEMAQsgAy0AiQFB+wBHBEBBDiEBDAELIANBkAFqIgEQigEgA0GAAWogARCIASADLQCEASEEIANB+ABqIAMoAoABIgwQkAECQAJAAkACQAJAIAMtAHhBAXFFBEBBAiECDAELIAMtAHkhAiAEQQFxIRcgA0HoAWpBBHIhESADQYACakEEciEUIANB8AFqIRggA0HUAWohHCADQfMBaiEdA0ACfwJAAkACfwJAIAJB/wFxIgRBLEcEQCAEQf0ARwRAIBcNAkEJDAMLIA1BgH5xIQJBAwwFC0EQIBcNARogDBCKASADQfAAaiAMEJABIAMtAHBBAXFFDQIgAy0AcSECCyACQf8BcSIEQSJGDQJBECAEQf0ARw0AGkETCyECIA0hCwwECyANQf8BcSELQQQhAgwDCyADQegAaiAMEJABIAMtAGhBAXFFBEBBBCECQQAhCwwDCyADLQBpQSJHBEBBDiECDAMLIAwQigEgA0HIAWogDBCPASADKALUASEFIAMoAtABIQQgAygCzAEhCyADKALIASICQRVHDQICQCALRQRAQQIhAgJAAkAgBUEFaw4CAQADCyAEQa6BwABBBhCNAkEAR0EBdCECDAILQQJBASAEQbSBwABBBRCNAhshAgwBC0ECIQICQAJAAkAgBUEFaw4CAQACCyALQa6BwABBBhCNAkEAR0EBdCECDAELQQJBASALQbSBwABBBRCNAhshAgsgBEUNACALEKsBC0EAIRcgDUGAfnELIQQCQAJAAkACQAJAAkACQCACIARyIg1B/wFxIgtBA0cEQCALDgIDAgELIBkhDQJAIBIiB0UEQCADQcgBakGugcAAQQYQFiADKALIAUEVRw0BIANB1AFqKAIAIRUgAygCzAEhByADQdABaigCACENCwJAIAZFBEAgA0HIAWpBtIHAAEEFEBYgAygCyAFBFUcNASADQdABaigCACEJIAMoAswBIQYgA0HUAWooAgAhCAsgAyAJNgKwASADIAY2AqwBIAMgFTYCqAEgAyANNgKkASADIAc2AqABIAdFDQ4gA0HIAWogA0GQAWoQjQEgAygCyAEiAUEVRg0FIAMoAswBIQsgAygC1AEhBCADKALQASEFIA0EQCAHEKsBCyAIBEAgCEEFdCEHIAZBEGohAgNAIAJBBGooAgAEQCACKAIAEKsBCyACQSBqIQIgB0EgayIHDQALCyALQQh2IQIgCUUNDyAGEKsBDA8LIBJFIQIgA0GsAWogA0HQAWopAwA3AgAgAyADKQPIATcCpAEgDUUNDCAHEKsBDAwLIANBrAFqIANB0AFqKQMANwIAIAMgAykDyAE3AqQBQQAhEiAGDQkMCgsgA0HIAWogDBCOAQJAIAMoAsgBIgFBFUcEQCADQfQBaiADQdQBaigCADYCACADIAMpAswBNwLsASADIAE2AugBDAELIANB6AFqIAwQFyADKALoAUEVRg0GCyADQawBaiADQfABaikDADcCACADIAMpA+gBNwKkASADQQA2AqABIAYNCAwJCyAGRQ0DIANBoAFqQQRyQbSBwABBBRAYIANBADYCoAEMBwsgEkUNASADQaABakEEckGugcAAQQYQGCADQQA2AqABIAYNBgwHCyADQcgBaiADQZABahCLASADKALIASIBQRVHBEAgAygC1AEhBCADKALQASEFIAMoAswBIQIgDQRAIAcQqwELIAgEQCAIQQV0IQcgBkEQaiELA0AgC0EEaigCAARAIAsoAgAQqwELIAtBIGohCyAHQSBrIgcNAAsLIAlFDQsgBhCrAQwLCyAAQRhqIAg2AgAgAEEUaiAJNgIAIABBEGogBjYCACAAQQxqIBU2AgAgAEEIaiANNgIAIAAgBzYCBCAAQQ02AgAMCwsgA0HIAWogDBCOAQJ/IAMoAsgBIgJBFUYEQCADQcgBaiAMEBogAygC1AEhFSADKALMASESIAMoAtABIgQgAygCyAEiAkEVRw0BGiAEIRkMAwsgAygC1AEhFSADKALMASESIAMoAtABCyEBIANBsAFqIBU2AgAgA0GsAWogATYCACADQagBaiASNgIAIAMgAjYCpAFBACESIANBADYCoAEgBg0EDAULIANByAFqIAwQjgECQAJAAkACQAJAAkACQAJAAkAgAygCyAEiCkEVRgRAIANB4ABqIAwQkAEgAy0AYEEBcQRAIAMtAGFB2wBHBEBBDiEKDAsLIAwQigEgA0HYAGogDBCIASADLQBcIQQgAygCWCEQQQAhBiADQQA2AsABIANCCDcDuAEgA0HQAGogEBCQAUEBIQpBCCEHIAMtAFBBAXFFDQggAy0AUSECIARBAXEhBkEAIQhBCCETA0ACQCACQf8BcSIEQSxHBEAgBEHdAEYNBSAGQf8BcSEEQQAhBiAEDQFBByEKDAoLIBAQigEgA0HIAGogEBCQASADLQBIQQFxRQRAQQAhBkEEIQoMCgsgAy0ASSECCyACQf8BcUHdAEYEQEEAIQZBEyEKDAkLIANBQGsgEBCQAUEAIQkgAy0AQEEBcUUEQEEEIQoMCAsgAy0AQUH7AEcEQEEOIQoMCAsgEBCKASADQThqIBAQiAEgAy0APCADQTBqIAMoAjgiDhCQAUECIQIgAy0AMEEBcUUEQEEAIQFBACEEDAULIAMtADEhBUEBcSEJQQAhAUIAIR4DQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAn8CQCAFQf8BcSIEQSxHBEAgBEH9AEcEQCAJQf8BcQ0CQQkMAwsgB0GAfnEhBUEDDAULQRAgCUH/AXENARogDhCKASADQShqIA4QkAEgAy0AKEEBcUUNAiADLQApIQULIAVB/wFxIgRBIkYNAkEQIARB/QBHDQAaQRMLIQIgByEEDBULIAdB/wFxIQRBBCECDBQLIANBIGogDhCQASADLQAgQQFxRQRAQQQhAkEAIQQMFAsgAy0AIUEiRwRAQQ4hAgwUCyAOEIoBIANB6AFqIA4QjwEgAygC9AEhCiADKALwASEJIAMoAuwBIQQgAygC6AEiBUEVRwRAIAUhAgwUCwJAIARFBEBBAiEFAkACQCAKQQVrDgIAAQMLIAlBoIDAAEEFEI0CQQBHQQF0IQUMAgtBAkEBIAlBpYDAAEEGEI0CGyEFDAELQQIhBQJAAkACQCAKQQVrDgIAAQILIARBoIDAAEEFEI0CQQBHQQF0IQUMAQtBAkEBIARBpYDAAEEGEI0CGyEFCyAJRQ0AIAQQqwELQQAhCSAHQYB+cQsgBXIiB0H/AXEiBEEDRwRAIAQOAgMCAQsgGiEFIAEiBEUEQCADQegBakGggMAAQQUQFiADKALoAUEVRw0FIAMoAvQBIRsgAygC8AEhBSADKALsASEECyAepw0DIAFFIQIgEUGlgMAAQQYQFiADQdABaiARQQhqKQIANwMAIAMgESkCADcDyAEgBUUNEyAEEKsBDBMLIANB6AFqIA4QjgECQCADKALoASIFQRVHBEAgFCARKQIANwIAIBRBCGogEUEIaigCADYCACADIAU2AoACDAELIANBgAJqIA4QFyADKAKAAkEVRg0MCyADQdABaiADQYgCaikDADcDACADIAMpA4ACNwPIAUEBIQIMEgsgHqcNByADQYACaiAOEI4BIAMoAoACIgVBFUcNBiADQRhqIA4QkAEgAy0AGEEBcQRAIAMtABlBIkcNBSAOEIoBIANBgAJqIA4QjwEgAygCjAIhDyADKAKIAiEKIAMoAoQCIQUgAygCgAIiFkEVRw0GAkAgBUUEQCADQegBaiAKIA8QHQwBCyADQegBaiAFIA8QHSAKRQ0AIAUQqwELIAMoAugBDQogA0H4AWopAwAhICADKQPwASEfQgEhHgwLCyAdQQA6AAAgA0EAOwDxASADQQQ2AuwBDAkLIAFFDQcgA0HIAWpBoIDAAEEFEBhBASECDBALIAMgHzcDyAEgAyAbNgLgASADIAU2AtwBIAMgBDYC2AEgAyAgNwPQASAERQ0QIAMpA+ABIR4gA0HIAWogEBCNASADKALIASIKQRVGDQEgAykCzAEiHkIgiKchCSAcKAIAIRAgHqchBiAFRQ0SIAQQqwEMEgsgA0HQAWogGCkDADcDACADIAMpA+gBNwPIAQwPCyADKAK8ASAIRgRAIANBuAFqIRMjAEEgayIPJAACQAJAIAhBAWoiAkUNACATQQRqKAIAIhZBAXQiASACIAEgAksbIgFBBCABQQRLGyIIQQV0IQIgCEGAgIAgSUEDdCEBAkAgFgRAIA9BCDYCGCAPIBZBBXQ2AhQgDyATKAIANgIQDAELIA9BADYCGAsgDyACIAEgD0EQahA1IA8oAgQhAiAPKAIARQRAIBMgAjYCACATQQRqIAg2AgAMAgsgD0EIaigCACIBQYGAgIB4Rg0BIAFFDQAgAiABEM4BAAsQzwEACyAPQSBqJAAgAygCuAEhEyADKALAASEICyATIAhBBXRqIgEgIDcDCCABIB83AwAgASAeNwMYIAEgBTYCFCABIAQ2AhBBASEKIAMgCEEBaiIINgLAASADQQhqIBAQkAEgAy0ACSECIAMtAAhBAXENCEEAIQYMEAsgA0EONgLsAQwECyADIA82AvgBIAMgCjYC9AEgAyAFNgLwASADIBY2AuwBDAMLIBggFCkCADcCACAYQQhqIBRBCGooAgA2AgAgAyAFNgLsAQwCCyADQcgBakGlgMAAQQYQGCADQQA2AtgBQQEhAgwJCyADQegBaiAOEI4BAkACQCADKALoASIFQRVHBEAgFCARKQIANwIAIBRBCGogEUEIaigCADYCACADIAU2AoACDAELIANBgAJqIA4QGiADKAKAAkEVRg0BCyADQdABaiADQYgCaikDADcDACADIAMpA4ACNwPIAQwKCyADKAKMAiEbIAMoAogCIRogAygChAIhAQwBCyADQdABaiARQQhqKQIANwMAIANBADYC2AEgAyARKQIANwPIAUEBIQIMBwsgA0EQaiAOEJABIAMtABEhBSADLQAQQQFxDQALCwwDCyAGQf8BcSEGQQQhCgwJCyADKALUASEIIAMoAtABIQkgAygCzAEhBgwICyADKAK8ASEJIAMoArgBIQYMBgsgAyAKNgLUASADIAk2AtABIAMgBDYCzAEgAyACNgLIAUEBIQILIBpFIAFFIAJFcnINACABEKsBCyADKQPIASIeQiCIpyEGIANB0AFqKQMAIh9CIIinIRAgHqchCiAfpyEJDAELQQAhBkEAIRALIAMoArgBIQcgCARAIAhBBXQhAUEAIQIDQCACIAdqIgRBFGooAgAiBQRAIARBEGooAgAQqwELIAEgAkEgaiICRw0ACwsgECEICyADKAK8AQRAIAcQqwELIApBFUcNAQsgA0HIAWogDBCMASADKALIASIKQRVGDQEgAygC1AEgAygC0AEhDSADKALMASAIBEAgCEEFdCEBIAZBEGohAgNAIAJBBGooAgAEQCACKAIAEKsBCyACQSBqIQIgAUEgayIBDQALCyAJBEAgBhCrAQshBiEIIA0hCQsgA0GwAWogCDYCACADQawBaiAJNgIAIANBqAFqIAY2AgAgAyAKNgKkAQwECyADIAwQkAEgAy0AASECIAMtAABBAXENAAtBAiECCyADQbABaiAFNgIAIANBrAFqIAQ2AgAgA0GoAWogCzYCACADIAI2AqQBIAZFDQELIAgEQCAIQQV0IQEg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A2pB+wA6AAAgAkHQAWogBEGYg8AAQQYQlwECQAJAIAIoAtABRQRAIAQoAggiAyAHKAIARgRAIAQgAxAQIAQoAgghAwsgBCADQQFqNgIIIAQoAgAgA2pBOjoAACACQdABaiAEEJsBIAIoAtABRQ0BIAJBzAFqIAVBCGooAgA2AgAgAiAFKQIANwLEAQwCCyACQZABaiACQdwBaigCADYCACACIAIpAtQBNwOIAQwSCyACQcABaiACKALUASACLQDYARCTASACKALAAUUNAwsgAkGQAWogAkHMAWooAgA2AgAgAiACKQLEATcDiAEMEAsgBygCACADRgRAIAQgAxAQIAQoAgghAwsgBCADQQFqNgIIIAQoAgAgA2pB+wA6AAAgAkHQAWogBEGUg8AAQQQQlwEgAigC0AENBCAEKAIIIgMgBygCAEYEQCAEIAMQECAEKAIIIQMLIAQgA0EBajYCCCAEKAIAIANqQTo6AAACQAJAAkACQAJAIAlBAWsOBAMCAQAECyACQdABaiAEQcKDwABBCxCcASACKALQAQ0HIAIgAi0A2AE6AKQBIAIgAigC1AE2AqABIAJB0AFqIAJBoAFqQc2DwABBDSAIQRRrKAIAIAhBDGsoAgAQDyACKALQAUUEQCACQcABaiACKAKgASACLQCkARCUAQwPCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAsLIAJB0AFqIARB2oPAAEEMEJwBIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwLCyACIAItANgBOgCkASACIAIoAtQBNgKgASACQdABaiACQaABakHNg8AAQQ0gCEEUaygCACAIQQxrKAIAEA8gAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAsLIAJB0AFqIAJBoAFqQeaDwABBBSAIQQhrKAIAIAgoAgAQDyACKALQAUUNDCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIARB64PAAEEHEJwBIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwKCyACIAItANgBOgCkASACIAIoAtQBNgKgASACQdABaiACQaABakHNg8AAQQ0gCEEUaygCACAIQQxrKAIAEA8gAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIAJBoAFqQfKDwABBCyAIQQhqKQMAEBIgAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIAJBoAFqIAhBCGsQEyACKALQAUUNCiAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAkLIAJB0AFqIARBgITAAEELEJwBIAIoAtABRQ0HIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMCAsgAkHQAWogBEGXhMAAQQcQnAEgAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAgLIAIgAi0A2AE6AKQBIAIgAigC1AE2AqABIAJB0AFqIAJBoAFqQc2DwABBDSAIQRRrKAIAIAhBDGsoAgAQDyACKALQAQRAIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMCAsgAkHQAWogAkGgAWogCEEIaxATIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwICyACQdABaiACQaABakG0gcAAQQUgCEEEaigCACAIQQxqKAIAEBQgAigC0AFFDQUgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwHCyACQbwBaiACQdwBaigCADYCACACIAIpAtQBNwK0AQwaCyAEKAIIIgMgBygCAEYNCwwMCyACQZABaiACQdwBaigCADYCACACIAIpAtQBNwOIAQwMCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAMLIAJBkAFqIAJB3AFqKAIANgIAIAIgAikC1AE3A4gBDAoLIAJBwAFqIAIoAqABIAItAKQBEJQBDAQLIAIgAigC1AEiAzYCmAEgCEEMaygCACEPIAhBFGsoAgAhDQJAIAItANgBBEAgAygCCCEJDAELIAMoAggiCiADKAIERgRAIAMgChAQIAMoAgghCgsgAyAKQQFqIgk2AgggAygCACAKakEsOgAACyACQQA6AJwBIANBBGoiCigCACAJRgRAIAMgCRAQIAMoAgghCQsgAygCACAJakEiOgAAIAMgCUEBaiIJNgIIIAooAgAgCWtBBE0EQCADIAlBBRARIAMoAgghCQsgAygCACAJaiIQQeaDwAAoAAA2AAAgEEEEakHqg8AALQAAOgAAIAMgCUEFaiIJNgIIIAooAgAgCWtBAU0EQCADIAlBAhARIAMoAgghCQsgAygCACAJakGi9AA7AAAgAyAJQQJqNgIIAkAgDUUEQCACQdABaiADEJgBDAELIAJB0AFqIAMgDSAPEJcBCwJAAkACQAJAIAIoAtABRQRAIAJB0AFqIAJBmAFqQYuEwABBByAIQSBqKQMAEBIgAigC0AENASACQdABaiACQZgBaiAIQQhrEBMgAigC0AENAiACQdABaiACQZgBakG0gcAAQQUgCEEEaigCACAIQQxqKAIAEBQgAigC0AENAyACQdABaiACQZgBakGShMAAQQUgCEEQaigCACAIQRhqKAIAEA8gAigC0AENBCACQcABaiACKAKYASACLQCcARCUAQwICyACQagBaiAFQQhqKAIAIgM2AgAgAiAFKQIAIhE3A6ABIAZBCGogAzYCACAGIBE3AgAMBAsgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwDCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAILIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMAQsgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAsgAkEBNgLAAQwCCyACQcABaiACKAKgASACLQCkARCUAQwBCyACQcABaiACKAKgASACLQCkARCUAQsgAigCwAFFBEAgBCgCCCIDIAcoAgBHDQQMAwsgAkGQAWogBkEIaigCADYCACACIAYpAgA3A4gBDAQLIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAgAkEBNgLAAQsgAigCwAFFBEAgBCgCCCIDIAcoAgBGDQEMAgsgAkGQAWogBkEIaigCADYCACACIAYpAgA3A4gBDAILIAQgAxAQIAQoAgghAwsgBCgCACADakH9ADoAACAEIANBAWoiAzYCCCAMQdAAaikDACERIAxByABqKQMAIRIgAyAHKAIARw0BIAQgAxAQIAQoAgghAwwBCyACQbwBaiACQZABaigCADYCACACIAIpA4gBNwK0AQwLCyAEKAIAIANqQSw6AAAgBCADQQFqIgM2AgggBygCACADRgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEiOgAAIAQgA0EBaiIDNgIIIAcoAgAgA2tBCE0EQCAEIANBCRARIAQoAgghAwsgBCgCACADaiIJQaSEwAApAAA3AAAgCUEIakGshMAALQAAOgAAIAQgA0EJaiIDNgIIIAcoAgAgA2tBAU0EQCAEIANBAhARIAQoAgghAwsgBCgCACADakGi9AA7AAAgBCADQQJqNgIIAkAgElAEQCACQdABaiAEEJgBDAELIAJB0AFqIAQgERCWAQsgAigC0AENAiAMQdgAai0AACEJIAQoAggiAyAHKAIARgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEsOgAAIAQgA0EBaiIDNgIIIAcoAgAgA0YEQCAEIAMQECAEKAIIIQMLIAQoAgAgA2pBIjoAACAEIANBAWoiAzYCCCAHKAIAIANrQQdNBEAgBCADQQgQESAEKAIIIQMLIAQoAgAgA2pC8srB45bv17fuADcAACAEIANBCGoiAzYCCCAHKAIAIANrQQFNBEAgBCADQQIQESAEKAIIIQMLIAQoAgAgA2pBovQAOwAAIAQgA0ECajYCCAJAAkACQAJAAkAgCUEBaw4DAQIDAAsgAkHQAWogBEHFhMAAQQYQmQEMAwsgAkHQAWogBEHAhMAAQQUQmQEMAgsgAkHQAWogBEG5hMAAQQcQmQEMAQsgAkHQAWogBEG0hMAAQQUQmQELIAIoAtABBEAgAkG8AWogAkHcAWooAgA2AgAgAiACKQLUATcCtAEMCwsgAkGwAWogBEEAEJMBIAIoArABDQogCEHgAGohCEEBIQMgDEHgAGogDkcNAAtBAAUgAwtB/wFxQQBHEJIBIAIoAlgNCSACQdABaiACQUBrIAFBDGooAgAgAUEUaigCABAgIAIoAtABBEAgAkE8aiACQdwBaigCADYCACACIAIpAtQBNwI0DAsLIAFBIGooAgAhBiABQRhqKAIAIQcgAigCQCEEIAItAEQEQCAEKAIIIQMMAgsgBCgCCCIFIAQoAgRGBEAgBCAFEBAgBCgCCCEFCyAEIAVBAWoiAzYCCCAEKAIAIAVqQSw6AAAMAQsgAkG8AWogAkHcAWooAgA2AgAgAiACKQLUATcCtAEMBwsgAkEAOgBEIARBBGoiBSgCACADRgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEiOgAAIAQgA0EBaiIDNgIIIAUoAgAgA2tBBU0EQCAEIANBBhARIAQoAgghAwsgBCgCACADaiIFQf6EwAAoAAA2AAAgBUEEakGChcAALwAAOwAAIAQgA0EGaiIDNgIIIARBBGooAgAgA2tBAU0EQCAEIANBAhARIAQoAgghAwsgBCgCACADakGi9AA7AAAgBCADQQJqNgIIIAJB0AFqIAQQmgEgAigC0AENAiACQdgBai0AACEDAkACQAJAIAJBsAFqIAIoAtQBIgUgBgR/IAcgBkEYbGohCCADRSEDIAJB0AFqQQRyIQYDQCADQQFxBEAgBSgCCCIDIAUoAgRGBEAgBSADEBAgBSgCCCEDCyAFIANBAWo2AgggBSgCACADakEsOgAACyACQdABaiAFEJsBIAIoAtABDQIgAiACLQDYAToAjAEgAiACKALUATYCiAEgAkHQAWogAkGIAWpB14TAAEEEIAcoAgAgB0EIaigCABAPIAIoAtABDQYgAkHQAWogAkGIAWogB0EMaigCACAHQRRqKAIAECAgAigC0AEEQCACQcwBaiACQdwBaigCADYCACACIAIpAtQBNwLEAQwJCyACQcABaiACKAKIASACLQCMARCTASACKALAAQ0IQQEhAyAHQRhqIgcgCEcNAAtBAAUgAwtB/wFxQQBHEJIBIAIoArABDQcgBCgCCCIHIARBBGoiAygCAEYEQCAEIAcQECAEKAIIIQcLIAQoAgAgB2pBLDoAACAEIAdBAWoiBzYCCCACQQA6AEQgAygCACAHRgRAIAQgBxAQIAQoAgghBwsgBCgCACAHakEiOgAAIAQgB0EBaiIHNgIIIAFBJGohAyAEQQRqIgUoAgAgB2tBA00EQCAEIAdBBBARIAQoAgghBwsgBCgCACAHakHkwtGLBjYAACAEIAdBBGoiATYCCCAFKAIAIAFrQQFNBEAgBCABQQIQESAEKAIIIQELIAQoAgAgAWpBovQAOwAAIAQgAUECajYCCCADKAIADQEgAkHQAWogBBCYAQwCCyACQcwBaiAGQQhqKAIANgIAIAIgBikCADcCxAEMBQsgAkHAAWogAxBqIAJB0AFqIAQgAigCwAEiASACKALIARCXASACKALEAUUNACABEKsBCyACKALQAQRAIAJBPGogAkHcAWooAgA2AgAgAiACKQLUATcCNAwJCyACQTBqIARBABCTASACKAIwDQggAigCCCIDIAIoAgRGBEAgAiADEBAgAigCCCEDCyACKAIAIANqQf0AOgAAIAIgA0EBajYCCAsgAkHIAWogAkEIaigCACIBNgIAIAIgAikDACIRNwPAASAAQQxqIAE2AgAgACARNwIEIABBDTYCAAwJCyACQcwBaiACQdwBaigCADYCACACIAIpAtQBNwLEAQwBCyACQbwBaiACQdwBaigCADYCACACIAIpAtQBNwK0AQwBCyACQbwBaiACQcwBaigCADYCACACIAIpAsQBNwK0AQsgAkE8aiACQbwBaigCADYCACACIAIpArQBNwI0DAMLIAJB5ABqIAJB3AFqKAIANgIAIAIgAikC1AE3AlwMAQsgAkHkAGogAkG8AWooAgA2AgAgAiACKQK0ATcCXAsgAkE8aiACQeQAaigCADYCACACIAIpAlw3AjQLIAJBHGogAkE8aigCADYCACACIAIpAjQ3AhQLIAJByAFqIgEgAkEcaigCADYCACACIAIpAhQ3A8ABIAIoAgQEQCACKAIAEKsBCyACQdgBaiABKAIANgIAIAIgAikDwAE3A9ABIABBuYfAAEHhACACQdABahAhCyACQeABaiQAC+ACAgJ/AX4jAEEgayIFJAAgASgCCCIEIAEoAgRGBEAgASAEEBAgASgCCCEECyABIARBAWo2AgggASgCACAEakH7ADoAACAFQRBqIAFBwITAAEEFEJcBAkACQCAFKAIQRQRAIAEoAggiBCABKAIERgRAIAEgBBAQIAEoAgghBAsgASAEQQFqNgIIIAEoAgAgBGpBOjoAACAFQRBqIAEgAiADEJcBIAUoAhANASABKAIIIgQgASgCBEYEQCABIAQQECABKAIIIQQLIABBADYCACABIARBAWo2AgggASgCACAEakH9ADoAAAwCCyAFQQhqIAVBHGooAgAiATYCACAFIAUpAhQiBjcDACAAQQxqIAE2AgAgACAGNwIEIABBATYCAAwBCyAFQQhqIAVBHGooAgAiATYCACAFIAUpAhQiBjcDACAAQQxqIAE2AgAgACAGNwIEIABBATYCAAsgBUEgaiQAC9QGAgR/AX4jAEHgAGsiBCQAIAEoAgAhBgJAIAEtAAQEQCAGKAIIIQUMAQsgBigCCCIHIAYoAgRGBEAgBiAHEBAgBigCCCEHCyAGIAdBAWoiBTYCCCAGKAIAIAdqQSw6AAALIAFBADoABCAGQQRqIgEoAgAgBUYEQCAGIAUQECAGKAIIIQULIAYoAgAgBWpBIjoAACAGIAVB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QT9xQYABcjoADyACIAFBBnZBP3FBgAFyOgAOIAIgAUEMdkE/cUGAAXI6AA0gAiABQRJ2QQdxQfABcjoADEEEDAELIAIgAUE/cUGAAXI6AA4gAiABQQx2QeABcjoADCACIAFBBnZBP3FBgAFyOgANQQMLIQEgASAAQQRqKAIAIAAoAggiA2tLBEAgACADIAEQESAAKAIIIQMLIAAoAgAgA2ogAkEMaiABEIsCGiAAIAEgA2o2AggLIAJBEGokAEEAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB9InAACACQQhqEN4BIAJBIGokAAtKAQF/IAIgACgCACIAQQRqKAIAIAAoAggiA2tLBEAgACADIAIQESAAKAIIIQMLIAAoAgAgA2ogASACEIsCGiAAIAIgA2o2AghBAAvGBAICfwF+IwBBsAFrIgIkACACQQhqIAFBDGopAgA3AwAgAkEQaiABQRRqKQIANwMAIAJBGGogAUEcaikCADcDACACQSBqIAFBJGooAgA2AgAgAiABKQIENwMAAkACQCABKAIAIgMEQCABKQMoIQQgACADNgIAIAAgBDcCKCAAIAFBBGoiASkCADcCBCAAQQxqIAFBCGopAgA3AgAgAEEUaiABQRBqKQIANwIAIABBHGogAUEYaikCADcCACAAQSRqIAFBIGooAgA2AgAMAQsgAkFAayACQRxqKQIANwMAIAJBOGogAkEUaikCADcDACACQTBqIAJBDGopAgA3AwAgAiACKQIENwMoIAJBADYCUCACQgE3A0ggAkHYAGogAkHIAGpBqIXAABDyASACKAIoQQ1GBEAgAkGkAWpBADYCACACQYyKwAA2AqABIAJCATcClAEgAkGEjcAANgKQASACQdgAaiACQZABahD3AQ0CIAAgAikDSDcCBCAAQQA2AgAgAEEMaiACQdAAaigCADYCAAwBCyACQaQBakEBNgIAIAJCATcClAEgAkGMjcAANgKQASACQQM2AoQBIAIgAkGAAWo2AqABIAIgAkGMAWo2AoABIAIgAkEoajYCjAEgAkHYAGogAkGQAWoQ9wENASACKAIoIABBDGogAkHQAGooAgA2AgAgACACKQNINwIEIABBADYCAEENRg0AIAJB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yAFBDUcNASADKALMASEBCyADQfQCakH0gMAANgIAIANB7AJqQciAwAA2AgAgA0HkAmpBrIDAADYCACADQbACaiADQcABaikDADcDACADQcgCaiADQbABaikDADcDACADQYwDaiAGNgIAIANBiANqIA02AgAgA0GEA2ogCDYCACADQYADaiATNgIAIANB/AJqIA82AgAgA0HwAmogA0GYA2oiADYCACADQegCaiAANgIAIAMgAykDuAE3A6gCIAMgCjYCvAIgAyAJNgK4AiADIAMpA6gBNwPAAiADIAE2ApADIAMgEDYC+AIgAyAWNwPYAiADIAw2AtQCIAMgCzYC0AIgAyAANgLgAiADQegBaiINIQIgA0GoAmohB0EAIQojAEHgAWsiACQAIAAgATYCDCAAQfAAaiADQfgCaiIEENEBIABBHGogAEH4AGooAgA2AgAgACABNgIQIAAgACkDcDcCFCADQeACaiIBKAIEIQsgASgCACEMAkACQAJAAkACQAJAAkACQAJAQRRBARA9IgEEQCABQRBqQd2MwAAoAAA2AAAgAUEIakHVjMAAKQAANwAAIAFBzYzAACkAADcAAEEFQQEQPSIFRQ0IIAVBBGpB5YzAAC0AADoAACAFQeGMwAAoAAA2AAAgAEGwAWoiBhCVASAAQUBrIAYQmwEgACgCQA0BIAAgACgCRDYCwAEgACAAQcgAai0AADoAxAEgAEFAayAAQcABakGUgcAAQQggAUEUEA8gACgCQA0CIABBQGsgAEHAAWpBk4XAAEEHIAVBBRAPIAAoAkAEQCAAQdQBaiAAQcwAaigCADYCACAAIAApAkQ3AswBDAULIABByAFqIAAoAsABIAAtAMQBEJMBIAAoAsgBRQ0DDAQLQRRBARDOAQALIABB1AFqIABBzABqKAIANgIAIAAgACkCRDcCzAEMAgsgAEHUAWogAEHMAGooAgA2AgAgACAAKQJENwLMAQwBCyAAQfwAaiAAQbgBaigCADYCACAAIAApA7ABNwJ0DAELIABBqAFqIgYgAEHUAWooAgA2AgAgACAAKQLMATcDoAEgACgCtAEEQCAAKAKwARCrAQsgAEHIAGogBigCADYCACAAIAApA6ABNwNAIABB8ABqQd2JwABBFCAAQUBrECEgACgCcCIGQQ1HDQELIABB+ABqKAIAIQhBDSEGIAxBmoXAAEENIAAoAnQiCSAAQfwAaigCACALKAIUEQcAIAhFDQEgCRCrAQwBCyAAQThqIABBiAFqKQMANwMAIAAgACkDgAE3AzAgACgCfCEIIAAoAnghCSAAKAJ0IQoLIAEQqwEgBRCrAQJAAkACQAJAAkACQCAGQQ1GBEAgAEHwAGogDCALIABBEGoQJiAAKAJwIgFBDUYNAiAAQdgAaiAAQYwBaigCACIFNgIAIABB0ABqIABBhAFqKQIAIhU3AwAgAEHIAGogAEH8AGopAgAiFjcDACAAIAApAnQiFzcDQCACQSRqIAU2AgAgAkEcaiAVNwIAIAJBFGogFjcCACACQQxqIBc3AgAgAiABNgIIDAELIABBKGogAEE4aikDACIVNwMAIAAgACkDMCIWNwMgIAJBIGogFTcCACACQRhqIBY3AgAgAkEUaiAINgIAIAJBEGogCTYCACACQQxqIAo2AgAgAiAGNgIICyACQQA2AgAgAEEYaigCAARAIAAoAhQQqwELIARBBGooAgAEQCAEKAIAEKsBCyAEQRRqKAIAIgEEQCABQQV0IQEgBEEMaigCAEEQaiECA0AgAkEEaigCAARAIAIoAgAQqwELIAJBIGohAiABQSBrIgENAAsLIARBEGooAgAEQCAEKAIMEKsBCyAHQRRqKAIABEAgBygCEBCrAQsgB0EsaigCAA0BDAILIABBkAFqQgA3AwAgAEGAAWpCADcDACAAQgQ3A4gBIABCgICAgMAANwN4IABCCDcDcCAAQUBrIABB8ABqQeaMwABBgITAAEELECIgAEE4aiIFIARBCGooAgA2AgAgACAEKQIANwMwQQVBARA9IgFFDQQgAUEEakHwjMAALQAAOgAAIAFB7IzAACgAADYAACAAQfgAaiAFKAIANgIAIAAgACkDMDcDcCAAQdQBaiIFIABB8ABqIgYpAgA3AgAgBUEIaiAGQQhqKAIANgIAIABChYCAgNAANwLMASAAIAE2AsgBIABB1ABqKAIAIgEgAEHQAGooAgBGBEAgAEHMAGogARAjIAAoAlQhAQsgACgCTCABQRhsaiIFIAApA8gBNwIAIAVBCGogAEHQAWopAwA3AgAgBUEQaiAAQdgBaikDADcCACAAQfgAaiAAQcgAaikDADcDACAAQYgBaiAAQdgAaikDADcDACAAQZABaiAAQeAAaikDADcDACAAQZgBaiAAQegAaikDADcDACAAIAFBAWo2AlQgAEGAAWogAEHQAGopAwA3AwAgACAAKQNANwNwIABBADYC0AEgAEIBNwPIASAAQUBrIgUgAEHIAWpBqIXAABDyASAAQQxqKAIAIgGtQgAgAax9IAFBf0oiARsgASAFEIUCDQJBBUEBED0iBUUNAyAFQQRqQfWMwAAtAAA6AAAgBUHxjMAAKAAANgAAIABBhAFqKAIAIgEgAEGAAWoiCCgCAEYEQCAAQfwAaiABECMgACgChAEhAQsgACgCfCABQRhsaiIGQoWAgIDQADcCBCAGIAU2AgAgAiAAKQNwNwIAIAJBCGogAEH4AGopAwA3AgAgAkEYaiAAQYgBaikDADcCACACQSBqIABBkAFqKQMANwIAIAJBKGogAEGYAWopAwA3AgAgACABQQFqNgKEASACQRBqIAgpAwA3AgAgBiAAKQPIATcCDCAGQRRqIABB0AFqKAIANgIAIABBGGooAgAEQCAAKAIUEKsBCyAEQRRqKAIAIgEEQCABQQV0IQEgBEEMaigCAEEQaiECA0AgAkEEaigCAARAIAIoAgAQqwELIAJBIGohAiABQSBrIgENAAsLIARBEGooAgAEQCAEKAIMEKsBCyAHQRRqKAIABEAgBygCEBCrAQsgB0EsaigCAEUNAQsgBygCKBCrAQsgAEHgAWokAAwDC0HAhcAAQTcgAEEwakH4hcAAQdSGwAAQ6QEACwtBBUEBEM4BAAsgA0HIAGogDRAzIAMoApwBBEAgFBCrAQsgAygCjAEEQCASEKsBCyADKAJ8RQ0DIA4QqwEMAwsgA0GAAmogA0HgAWopAwA3AwAgA0H4AWogA0HYAWopAwA3AwAgA0HwAWogA0HQAWopAwA3AwAgAyADKQPIATcD6AEgA0EANgKgAiADQgE3A5gCIANBqAJqIgAgA0GYAmpBqIXAABDyASADQegBaiAAEH1FBEAgA0HUAGogA0GgAmooAgA2AgAgAyADKQOYAjcCTCADQQA2AkggA0HoAWoQLiAPBEAgEBCrAQsgBgRAIAZBBXQhASAIQRBqIQADQCAAQQRqKAIABEAgACgCABCrAQsgAEEgaiEAIAFBIGsiAQ0ACwsgDUUNASAIEKsBDAELDAMLIAoEQCAJEKsBCyAMRQ0AIAsQqwELIAMoApwBBEAgAygCmAEQqwELIAMoAowBBEAgAygCiAEQqwELIAMoAnxFDQAgDhCrAQsgA0HoAWogA0HIAGoQHiADKALoAUENRgRAIANB0AFqIANB9AFqKAIAIgA2AgAgAyADKQLsASIVNwPIASADQbACaiAANgIAIAMgFTcDqAIgA0GoAmoQfiADQcgAahArIANBoANqJAAPCyADQcACaiADQYACaikDADcDACADQbgCaiADQfgBaikDADcDACADQbACaiADQfABaikDADcDACADIAMpA+gBNwOoAkHFgcAAQSsgA0GoAmpB8IHAAEH0gsAAEOkBAAtBwIXAAEE3IANBmANqQfiFwABB1IbAABDpAQALnSoCE38CfiMAQdADayIDJAAQrQEgA0GoAWogABB/IANBuAFqIAEQfyADQcgBaiACEH8gA0HYAmogAygCqAEiEyADKAKwARAVAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACfwJAAkACQAJAAkACQAJAAkACQAJAIAMoAvgCQQJHBEAgA0HwAWogA0HgAmopAwA3AwAgA0HgAWogA0H4AmopAwA3AwAgAyADKQPYAjcD6AEgAyADKQPwAjcD2AEgAygC6AIhESADKALsAiEOIAMoAoADIQ8gAygChAMhEiADKQOIAyEWIANB+AFqIAMoArgBIhQgAygCwAEQHCADKAL4AUENRw0CIANBkAJqKAIAIQwgA0GMAmooAgAhCiADQYgCaigCACEJIANBhAJqKAIAIQIgA0GAAmooAgAhDSADKAL8ASEQIANByAJqIgAgAygCyAEiFSADKALQARCJASADQfAAaiAAEJABIAMtAHBBAXENAQwUCyADQZACaiADQfACaikDADcDACADQYgCaiADQegCaikDADcDACADQYACaiADQeACaikDADcDACADIAMpA9gCNwP4ASADQQA2AtACIANCATcDyAIgA0GYAmoiACADQcgCakGohcAAEPIBIANB+AFqIAAQfQ0aIANBhAFqIANB0AJqKAIANgIAIAMgAykDyAI3AnwgA0EANgJ4IANB+AFqEC4MGAsgAy0AcSIAQfsARwRAIABBIkcEQEEKIQAMFQsgA0HYAmogA0HIAmoQOCADKALYAiIAQRVHDQ9BDiEADBQLIANByAJqIgQQigEgA0HYAmogBBA4AkACfyAD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AEEiRw0GIANBCGogBRCQAUEEIQAgAy0ACEEBcUUNB0EOIQAgAy0ACUEiRw0HIAUQigEgA0HYAmogBRCPASADKALYAiIAQRVHDQEgA0HkAmooAgAhByADQeACaigCACEAIAMoAtwCIgVFBEAgA0GYAmogACAHQYyKwABBABA2DAMLIANBmAJqIAUgB0GMisAAQQAQNiAARQ0CIAUQqwEMAgtBEyEADAYLIAMgAygC5AI2AqQCIAMgAykC3AI3ApwCIAMgADYCmAILIAMoApgCIgBBFUYNACADLwCdAiADLQCfAkEQdHIhByADKQOgAiEXIAMtAJwCIQUMBAsgA0HYAmogBBCNASADKALYAiIAQRVHBEAgAygC3AIiAUEIdiEHIAMoAuQCIQUgAygC4AIhBgwFCyADIAQQkAEgAy0AAEEBcUUNBUELIQAgAy0AAUH9AEcNBgsgBBCKASADQdgCaiADQcgCahCLASADKALYAiIAQRVGDQYLIAMoAuQCIQUgAygC4AIhBiADKALcAiEHDAQLQRAhAAsgBUH/AXEhASAXQiCIpyEFIBenIQYLIAFB/wFxIAdBCHRyIQcMAQtBBCEAQQAhBwsgAyAFNgLkAiADIAY2AuACIAMgBzYC3AIgAyAANgLYAiADQfgBakHkhsAAQRsgA0HYAmoQGyADKAL4AUENRw0BIANBgAJqKAIAIQEgAygC/AEhCAsgA0GkA2pB9IDAADYCACADQZwDakHIgMAANgIAIANBlANqQayAwAA2AgAgA0HgAmogA0HwAWopAwA3AwAgA0H4AmogA0HgAWopAwA3AwAgA0HEA2ogATYCACADQbwDaiAMNgIAIANBuANqIAo2AgAgA0G0A2ogCTYCACADQbADaiACNgIAIANBrANqIA02AgAgA0GgA2ogA0HIA2oiADYCACADQZgDaiAANgIAIAMgAykD6AE3A9gCIAMgDjYC7AIgAyARNgLoAiADIAMpA9gBNwPwAiADIAg2AsADIAMgEDYCqAMgAyAWNwOIAyADIBI2AoQDIAMgDzYCgAMgAyAANgKQAyADQZgCaiISIQogA0GQA2ohACADQdgCaiERIANBqANqIQkgASECIwBBMGsiCyQAAkAgCEUEQCALQShqIABBEGopAgA3AwAgC0EgaiAAQQhqKQIANwMAIAsgACkCADcDGCMAQeAA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AWooAgAhACACQdABaigCACEBIAIoAswBIgVFBEAgAkGgAWogASAAQYyKwABBABA2DAMLIAJBoAFqIAUgAEGMisAAQQAQNiABRQ0CIAUQqwEMAgtBEyEBDAYLIAIgAigC1AE2AqwBIAIgAikCzAE3AqQBIAIgADYCoAELIAIoAqABIgFBFUYNACACLwClASACLQCnAUEQdHIhCyACKQOoASEOIAItAKQBIQMMBAsgAkHIAWogAxCNASACKALIASIBQRVHBEAgAi8AzQEgAi0AzwFBEHRyIQsgAikD0AEhDiACLQDMASEDDAQLIAJBCGogAxCQASACLQAIQQFxRQ0EIAItAAlB/QBHBEBBCyEBDAYLIAMQigEgAkHIAWogAkFAaxCLASACKALIASIBQRVGDQYLIAIpA9ABIQ4gAigCzAEhAwwECyACQZgBaiACQeABaikDADcDACACQZABaiACQdgBaikDADcDACACQYgBaiACQdABaikDADcDACACIAIpA8gBNwOAASACQQA2ArACIAJCATcDqAIgAkGgAWoiACACQagCakGohcAAEPIBIAJBgAFqIAAQfUUEQCACQcwAaiACQbACaigCADYCACACIAIpA6gCNwJEIAJBATYCQCACQYABahAuDAkLDA4LQRAhAQsgA0H/AXEgC0EIdHIhAwwBC0EEIQFBACEDCyACIA43A9ABIAIgAzYCzAEgAiABNgLIASACQYABakGgh8AAQRkgAkHIAWoQGyACKAKAAUENRw0BCyACQZQCakH0gMAANgIAIAJBjAJqQciAwAA2AgAgAkGEAmpBrIDAADYCACACQdABaiACQfgAaikDADcDACACQegBaiACQegAaikDADcDACACQZACaiACQbgCaiIANgIAIAJBiAJqIAA2AgAgAiACKQNwNwPIASACIAY2AtwBIAIgBDYC2AEgAiACKQNgNwPgASACIA83A/gBIAIgCTYC9AEgAiAINgLwASACIAA2AoACIAJBgAFqIgUhASACQcgBaiEDIwBB8ABrIgAkACAAQRhqIAJBgAJqIgQoAgAgBCgCBEEMaigCABAkAkACQAJAAkACQAJAAkAgACgCGCIEQQ1GBEAgACgCHCEEIABBJGooAgAEQCAAQSBqKAIAEKsBCyAAQcgAaiIGEJUBIABBGGogBhCbASAAKAIYDQEgACAAKAIcNgJoIAAgAEEgai0AADoAbCAAQRhqIABB6ABqIAQQJyAAKAIYBEAgAEHkAGogAEEkaigCADYCACAAIAApAhw3AlwMBAsgAEHYAGogACgCaCAALQBsEJMBIAAoAlhFDQIMAwsgAEEQaiAAQTRqKAIAIgY2AgAgACAAKQIsIg43AwggACkCHCEPIAApAiQhECABQRxqIAY2AgAgASAONwIUIAEgEDcCDCABIA83AgQgASAENgIAIANBFGooAgAEQCADKAIQEKsBCyADQSxqKAIARQ0GIAMoAigQqwEMBgsgAEHkAGogAEEkaigCADYCACAAIAApAhw3AlwMAQsgAEEkaiAAQdAAaigCADYCACAAIAApA0g3AhwMAQsgAEFAayIEIABB5ABqKAIANgIAIAAgACkCXDcDOCAAKAJMBEAgACgCSBCrAQsgAEHgAGogBCgCADYCACAAIAApAzg3A1ggAEEYakH/hsAAQSEgAEHYAGoQISAAKAIYQQ1HDQELIAEgACkCHDcCBCABQQ02AgAgAUEMaiAAQSRqKAIANgIADAELIAEgACkDGDcDACABQRhqIABBMGopAwA3AwAgAUEQaiAAQShqKQMANwMAIAFBCGogAEEgaikDADcDAAsgA0EUaigCAARAIAMoAhAQqwELIANBLGooAgBFDQAgAygCKBCrAQsgAEHwAGokACAFQQRyIQACQCACKAKAASIBQQ1GBEAgAkHMAGogAEEIaigCADYCACACQQA2AkAgAiAAKQIANwJEDAELIAJBrAFqIABBCGooAgA2AgAgAkG4AWogAkGYAWopAwA3AwAgAiABNgKgASACIAIpA5ABNwOwASACIAApAgA3AqQBIAJBADYCsAIgAkIBNwOoAiACQcgBaiIAIAJBqAJqQaiFwAAQ8gEgAkGgAWogABB9DQogAkHMAGogAkGwAmooAgA2AgAgAiACKQOoAjcCRCACQQE2AkAgAkGgAWoQLgsgAigCnAIEQCAMEKsBCyACKAJUBEAgBxCrAQsgAkGoAmoQlQEgAUENRw0EIAIoArACIgAgAigCrAJGBEAgAkGoAmogABAQIAIoArACIQALIAIoAqgCIABqQfsAOgAAIAIgAEEBajYCsAIgAkHIAWogAkGoAmpBy4TAAEECEJcBIAIoAsgBDQIgAigCsAIiACACKAKsAkYEQCAC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KAIAIQIjAEEwayIAJAACfwJAAkACQAJAIAIoAgBBAWsOAwECAwALIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABB5KjAADYCCCABIABBCGoQ9wEMAwsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEHIqMAANgIIIAEgAEEIahD3AQwCCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQaiowAA2AgggASAAQQhqEPcBDAELIABBHGpBATYCACAAQgE3AgwgAEHop8AANgIIIABBIDYCJCAAIAJBBGo2AiwgACAAQSBqNgIYIAAgAEEsajYCICABIABBCGoQ9wELIABBMGokAAu0AwEBfyAAKAIAIQIjAEEwayIAJAACfwJAAkACQAJAAkACQAJAIAIoAgBBAWsOBgECAwQFBgALIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABB4LLAADYCCCABIABBCGoQ9wEMBgsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEHMssAANgIIIAEgAEEIahD3AQwFCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQeSowAA2AgggASAAQQhqEPcBDAQLIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABByKjAADYCCCABIABBCGoQ9wEMAwsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEG0ssAANgIIIAEgAEEIahD3AQwCCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQaiowAA2AgggASAAQQhqEPcBDAELIABBHGpBATYCACAAQgE3AgwgAEHop8AANgIIIABBIDYCJCAAIAJBBGo2AiwgACAAQSBqNgIYIAAgAEEsajYCICABIABBCGoQ9wELIABBMGokAAsMACAAKAIAIAEQ3AELYgEBfyMAQTBrIgIkACAAKAIAIQAgAkEcakEBNgIAIAJCAjcCDCACQeSwwAA2AgggAkEeNgIkIAIgADYCLCACIAJBIGo2AhggAiACQSxqNgIgIAEgAkEIahD3ASACQTBqJAALVwEBfyMAQSBrIgIkACACIAA2AgQgAkEYaiABQRBqKQIANwMAIAJBEGogAUEIaikCADcDACACIAEpAgA3AwggAkEEakHckcAAIAJBCGoQ3gEgAkEgaiQACwgAIAEgARBUC5oEAQR/IwBBQGoiACQAIABBADYCCCAAQgE3AwAgAEEQaiIEIABBmI/AABDyAQJAIwBBQGoiAiQAQQEhAwJAIAQoAhgiBUGo38AAQQwgBEEcaigCACIEKAIMEQEADQACQCABKAIIIgMEQCACIAM2AgwgAkHnADYCFCACIAJBDGo2AhBBASEDIAJBATYCPCACQgI3AiwgAkG438AANgIoIAIgAkEQajYCOCAFIAQgAkEoahDeAUUNAQwCCyABKAIAIgMgASgCBEEMaigCABEIAELrkZO19tizovQAUg0AIAIgAzYCDCACQegANgIUIAIgAkEMajYCEEEBIQMgAkEBNgI8IAJCAjcCLCACQbjfwAA2AiggAiACQRBqNgI4IAUgBCACQShqEN4BDQELIAEoAgwhASACQSRqQcoANgIAIAJBHGpBygA2AgAgAiABQQxqNgIgIAIgAUEIajYCGCACQekANgIUIAIgATYCECACQQM2AjwgAkIDNwIsIAJBkN/AADYCKCACIAJBEGo2AjggBSAEIAJBKGoQ3gEhAwsgAkFAayQAIANFBEAgACgCCCECIAAoAgAhA0EMQQQQPSIBRQ0BIAEgAjYCCCABIAI2AgQgASADNgIAIAEQACABEKsBIAAoAgQEQCAAKAIAEKsBCyAAQUBrJAAPC0Gwj8AAQTcgAEE4akHoj8AAQcSQwAAQ6QEAC0EMQQQQzgEAC4cBAQV/IwBBIGsiAyQAAn8gAkUEQEEAIQJBAAwBCwJAA0AgA0EIaiABEFYgAygCCCIFRQ0BIAMoAhggAygCFCEHIAMoAgwEQCAFEKsBCyAEQQFqIQQEQCAHEKsBCyACIARHDQALQQAMAQsgBCECQQELIQEgACACNgIEIAAgATYCACADQSBqJAALiQMCCH8BfiMAQUBqIgIkAAJAIAEoAgAQBSIBBEAgASgCACIDRQ0BIAEpAgQhCiABEKsBIAIgCjcCNCACIAM2AjAgAkEYaiIEIAJBMGoiBRBsIAJBEGogAkEgaigCACIGNgIAIAIgAikDGCIKNwMIIAJBKGoiBygCACEBIAJBLGoiCCgCACEJIAIoAiQhAyACQThqIAY2AgAgAiAKNwMwIAQgBRBsIAgoAgAhBCAHKAIAIQUgAigCJCEGIAIoAhwEQCACKAIYEKsBCwJAIARFBEAgAEEANgIAIAEEQCADEKsBCyAFRQ0BIAYQqwEMAQsgACAJNgIUIAAgATYCECAAIAM2AgwgACAENgIIIAAgBTYCBCAAIAY2AgALIAJBQGskAA8LIAJBLGpBADYCACACQfSRwAA2AiggAkIBNwIcIAJBqKbAADYCGCACQRhqQZCnwAAQ1AEACyACQSxqQQA2AgAgAkH0kcAANgIoIAJCATcCHCACQcCnwAA2AhggAkEYakHIp8AAENQBAAt9AQV/IwBBIGsiAyQAAkAgAkUNAANAAkAgA0EIaiABEFYgAygCCCIERQ0AIAMoAhggAygCFCEGIAMoAgwEQCAEEKsBCwRAIAYQqwELIAJBAWsiAg0BDAILC0EBIQcLAkAgB0UEQCAAIAEQVgwBCyAAQQA2AgALIANBIGokAAsJACAAQgA3AgALDQAgACgCACABEFpBAAvNAgECfyMAQRBrIgIkAAJAAn8CQCABQYABTwRAIAJBADYCDCABQYAQTw0BIAIgAUE/cUGAAXI6AA0gAiABQQZ2QcABcjoADEECDAILIAAoAggiAyAAKAIERgRAIAAgAxAQIAAoAgghAwsgACADQQFqNgIIIAAoAgAgA2ogAToAAAwCCyABQYCABE8EQCACIAFBP3FBgAFyOgAPIAIgAUEGdkE/cUGAAXI6AA4gAiABQQx2QT9xQYABcjoADSACIAFBEnZBB3FB8AFyOgAMQQQMAQsgAiABQT9xQYABcjoADiACIAFBDHZB4AFyOgAMIAIgAUEGdkE/cUGAAXI6AA1BAwshASABIABBBGooAgAgACgCCCIDa0sEQCAAIAMgARARIAAoAgghAwsgACgCACADaiACQQxqIAEQiwIaIAAgASADajYCCAsgAkEQaiQAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB3JHAACACQQhqEN4BIAJBIGokAAsKACAAIAEQWkEAC8UBAQF/IwBB8ABrIgMkACADIAI2AgwgAyABNgIIIANBJGpBATYCACADQgI3AhQgA0Ggk8AANgIQIANBITYCLCADIANBKGo2AiAgAyADQQhqNgIoIANBADYCOCADQgE3AzAgA0FAayIBIANBMGpBmI/AABDyASADQRBq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CCAEIAM2AgQgBCACNgIAQcAAQQEQPSIDRQ0EQQxBBBA9IgJFDQUgAkLAADcCBCACIAM2AgAgBCACEAciAw0BIAIoAgAiA0UNByACKQIEIQUgAhCrASAAQQhqIAU3AgAgACADNgIEIABBDTYCACAEEKsBDAILQSRBARA9IgJFDQUgAEKkgICAwAQ3AwggACACNgIEIABBAjYCACACQSBqQZijwAAoAAA2AAAgAkEYakGQo8AAKQAANwAAIAJBEGpBiKPAACkAADcAACACQQhqQYCjwAApAAA3AAAgAkH4osAAKQAANwAADAELIAMoAgAiAkUNBSADKQIEIQUgAxCrASABIAU3AgQgASACNgIAIAFBIjYCJCABIAE2AiAgAUEBNgI8IAFCATcCLCABQbijwAA2AiggASABQSBqNgI4IAFBEGogAUEoahDQASAAQQI2AgAgACABKQMQNwIEIABBDGogAUEYaigCADYCACABKAIEBEAgASgCABCrAQsgBBCrAQsgAUFAayQADwtBDEEEEM4BAAtBwABBARDOAQALQQxBBBDOAQALQSRBARDOAQALIAFBPGpBADYCACABQfSRwAA2AjggAUIBNwIsIAFBwKfAADYCKCABQShqQcinwAAQ1AEAC5kDAgJ/AX4jAEFAaiIBJAAgAkEIaigCACEDIAIoAgAhAgJAAkACQEEMQQQQPSIEBEAgBCADNgIIIAQgAzYCBCAEIAI2AgBB2gBBARA9IgNFDQFBDEEEED0iAkUNAiACQtoANwIEIAIgAzYCAAJAIAQgAhAIIgNFBEAgAigCACIDRQ0FIAIpAgQhBSACEKsBIABBCGogBTcCACAAIAM2AgQgAEENNgIADAELIAMoAgAiAkUNBCADKQIEIQUgAxCrASABIAU3AgQgASACNgIAIAFBIjYCJCABIAE2AiAgAUEBNgI8IAFCATcCLCABQdijwAA2AiggASABQSBqNgI4IAFBEGogAUEoahDQASAAQQI2AgAgACABKQMQNwIEIABBDGogAUEYaigCADYCACABKAIEBEAgASgCABCrAQsLIAQQqwEgAUFAayQADwtBDEEEEM4BAAtB2gBBARDOAQALQQxBBBDOAQALIAFBPGpBADYCACABQfSRwAA2AjggAUIBNwIsIAFBwKfAADYCKCABQShqQcinwAAQ1AEAC8cCAQF/IwBBIGsiASQAQQxBBBA9IggEQAJAIAggAzYCCCAIIAM2AgQgCCACNgIAQQxBBBA9IgJFDQAgAiAFNgIIIAIgBTYCBCACIAQ2AgBBDEEEED0iA0UNACADIAc2AgggAyAHNgIEIAMgBjYCAAJAAkACQAJAAkACQAJAAkACQCAIIAIgAxAJIgQOCwECAwQFBgAAAAAHAAsgACAENgIEIABBBjYCAAwHCyAAQQc2AgAgAEEBOgAEDAYLIABBBzYCACAAQQA6AAQMBQsgAUEcakEANgIAIAFB9JHAADYCGCABQgE3AgwgAUGYpMAANgIIIAFBCGpBoKTAABDUAQALIABBAjYCAAwDCyAAQQM2AgAMAgsgAEEENgIADAELIABBATYCAAsgAxCrASACEKsBIAgQqwEgAUEgaiQADwsLQQxBBBDOAQALrAMCAX8BfiMAQSBrIgEkAAJAAkACQEEMQQQQPSIHBEAgByADNgIIIAcgAzYCBCAHIAI2AgBBDEEEED0iAkUNASACIAU2AgggAiAFNgIEIAIgBDYCAAJAAkACQAJAAkACQAJAIAcgAiAGQf8BcRAKIghCIIinIgMOBwEAAgMEAAUACyAAQoCAgIAwNwIAIABBCGogAzYCAAwFCyAIpyIDRQ0HIAMoAgAiBEUNCCADKQIEIQggAxCrASAAIAg3AgQgACAENgIADAQLIAFBHGpBADYCACABQfSRwAA2AhggAUIBNwIMIAFBmKTAADYCCCABQQhqQbCkwAAQ1AEACyAAQgA3AgAMAgsgAEKAgICAEDcCAAwBCyAAQoCAgIAgNwIACyACEKsBIAcQqwEgAUEgaiQADwtBDEEEEM4BAAtBDEEEEM4BAAsgAUEcakEANgIAIAFB9JHAADYCGCABQgE3AgwgAUGopsAANgIIIAFBCGpBkKfAABDUAQALIAFBHGpBADYCACABQfSRwAA2AhggAUIBNwIMIAFBwKfAADYCCCABQQhqQcinwAAQ1AEAC/ECAQF/IwBBIGsiASQAQQxBBBA9IggEQAJAIAggAzYCCCAIIAM2AgQgCCACNgIAQQxBBBA9IgJFDQAgAiAFNgIIIAIgBTYCBCACIAQ2AgBBDEEEED0iA0UNACADIAc2AgggAyAHNgIEIAMgBjYCAAJAAkACQAJAAkACQAJAAkACQCAIIAIgAxALIgQOCwECAwQFBgAAAAAHAAsgACAENgIEIABBBjYCAAwHCyAAQQc2AgAgAEEBOgAEDAYLIABBBzYCACAAQQA6AAQMBQsgAUEcakEANgIAIAFB9JHAADYCGCABQgE3AgwgAUHYpcAANgIIIAFBCGpB4KXAABDUAQALIAFBHGpBADYCACABQfSRwAA2AhggAUIBNwIMIAFB/KTAADYCCCABQQhqQYSlwAAQ1AEACyAAQQM2AgAMAgsgAEEENgIADAELIABBATYCAAsgAxCrASACEKsBIAgQqwEgAUEgaiQADwsLQQxBBBDOAQAL5wMBAX8jAEHQAGsiASQAIAFBCGogAiADEGsgASgCECEDIAEoAgghCEEMQQQQPSICBEACQCACIAM2AgggAiADNgIEIAIgCDYCACABQRhqIAQgBRBrIAEoAiAhBCABKAIYIQVBDEEEED0iA0UNACADIAQ2AgggAyAENgIEIAMgBTYCACABQShqIAYgBxBrIAEoAjAhBiABKAIoIQdBDEEEED0iBEUNACAEIAY2AgggBCAGNgIEIAQgBzYCAAJAAkACQAJAAkACQAJAAkACQCACIAMgBBAMIgYOCwECAwQFBgAAAAAHAAsgACAGNgIEIABBBjYCAAwHCyAAQQc2AgAgAEEBOgAEDAYLIABBBzYCACAAQQA6AAQMBQsgAUHMAGpBADYCACABQfSRwAA2AkggAUIBNwI8IAFB2KXAADYCOCABQThqQYCmwAAQ1AEACyABQcwAakEANgIAIAFB9JHAADYCSCABQgE3AjwgAUH8pMAANgI4IAFBOGpB8KXAABDUAQALIABBAzYCAAwCCyAAQQQ2AgAMAQsgAEEBNgIACyAEEKsBIAEoAiwEQCAHEKsBCyADEKsBIAEoAhwEQCAFEKsBCyACEKsBIAEoAgwEQCAIEKsBCyABQdAAaiQADwsLQQxBBBDOAQALNABBDEEEED0iAEUEQEEMQQQQzgEACyAAIAI2AgggACACNgIEIAAgATYCACAAEA0gABCrAQuERAIUfwF+IwBBwANrIgQkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAQQxBBBA9IhIEQCASIAM2AgggEiADNgIEIBIgAjYCACASEA4iAgRAIAIoAgAiFQRAIAIoAgQhFiACKAIIIRdBBCEBIAIQqwEgBEHYAmoiAiAVIBcQiQEgBEHQAmogAhCQAUEAIQMgBC0A0AJBAXFFDR4gBC0A0QIiBkH7AEcEQCAGQSJHDR4gBEGYA2ogBEHYAmoQYwwdCyAEQdgCaiIKEIoBIARBmANqIAoQYyAEKAKYAyICQRVHDQMgBC0AnAMhBiAEQZgDaiAKEI4BIAQoApgDIgJBFUcEQCAELwCdAyAELQCfA0EQdHIhAyAEKAKkAyEKIAQoAqADIQUgBC0AnAMhBiACIQEMHwsgBEHIAmogChCQASAELQDIAkEBcSEFIAQtAMkCIQICQAJAIAZB/wFxRQRAQQAhBiAFRQ0XIAJB+wBHBEAgAkEiRwRAQQohAQwgCyAEQZgDaiAKEGMgBCgCmAMiAUEVRw0bDB4LIAoQigEgBEGYA2ogCiIDEGMCQAJ/IAQoApgDIgFBFUYEQCAELQCcAyEFIARBmANqIAMQjgEgBCgCmAMiAUEVRg0CIAQvAJ0DIAQtAJ8DQRB0cgwBCyAELwCdAyAELQCfA0EQdHILIQIgBCgCpAMhCiAEKAKgAyEFIAQtAJwDIAJBCHRyIQYMHwsgBUH/AXFFDRYgBEEgaiADEJABIAQtACBBAXFFDRcgBC0AIUEiRw0dIAMQigEgBEGYA2ogAxCPASAEKAKYAyIBQRVHDRogBEGkA2ooAgAhByAEQaADaigCACENIAQoApwDIgVFBEACQCAHRQRAQQEhBQwBCyAHQX9KIgFFDQQgByABED0iBUUNAwsgBSANIAcQiwIaIAchDQsgBEEYaiADEJABQQEhAiAELQAYQQFxBEAgBC0AGUH9AEYNHEELIQEgDUUNHyAFEKsBDB8LIA1FDRcgBRCrAUEEIQEMHgsgBUUNICACIgZB+wBHBEAgBkEiRw0gIARBmANqIAoQZgwfCyAKEIoBIARBmANqIAoiCxBmIAQoApgDIgJBFUYEQCAELQCcAyERIARBmANqIAsQjgEgBCgCmAMiDUEVRwRAIAQvAJ0DIAQtAJ8DQRB0ciEDIAQoAqQDIQogBCgCoAMhBSAELQCcAyEGIA0hAQwiCwJAIBFBAWsOBAsKCQgACyAEQeAAaiALEJABQQAhBiAELQBgQQFxRQ0hIAQtAGFB+wBHBEBBDiEBDCILIAsQigEgBEHYAGogCxCIASAELQBcIARB0ABqIAQoAlgiBhCQASAELQBQQQFxRQRAQQIhAkEAIQdBACEFDBMLIAQtAFEhAkEBcSEMIARB6AJqQQRyIRNBACEHA0ACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJ/AkAgAkH/AXEiBUEsRwRAIAVB/QBHBEAgDEH/AXENAkEJDAMLIAlBgH5xIQJBAwwFC0EQIAxB/wFxDQEaIAYQigEgBEHIAGogBhCQASAELQBIQQFxRQ0CIAQtAEkhAgsgAkH/AXEiBUEiRg0CQRAgBUH9AEcNABpBEwshAiAJIQUMIAsgCUH/AXEhBUEEIQIMHwsgBEFAayAGEJABIAQtAEBBAXFFBEBBBCECQQAhBQwfCyAELQBBQSJHBEBBDiECDB8LIAYQigEgBEH4AmogBhCPASAEKAKEAyEPIAQoAoADIQwgBCgC/AIhBSAEKAL4AiICQRVHDR4CQCAFRQRAQQIhAgJAAkAgD0EFaw4DAAMBAwsgDEGEssAAQQUQjQJBAEdBAXQhAgwCC0ECQQEgDEGRssAAQQcQjQIbIQIMAQtBAiECAkACQAJAIA9BBWsOAwACAQILIAVBhLLAAEEFEI0CQQBHQQF0IQIMAQtBAkEBIAVBkbLAAEEHEI0CGyECCyAMRQ0AIAUQqwELQQAhDCAJQYB+cQsgAnIiCUH/AXEiBUEDRwRAIAUOAgMCAQsgDiEJAkAgCCICRQRAIARB+AJqQYSywABBBRBdIAQoAvgCQRVHDQEgBEGEA2ooAgAhDSAEQYADaigCACEJIAQoAvwCIQILAkAgB0UEQCAEQfgCakGRssAAQQcQXSAEKAL4AkEVRw0BIARBhANqKAIAIRQgBEGAA2ooAgAhECAEKAL8AiEHCyAEIBQ2ArADIAQgEDYCrAMgBCkCrAMhGCAEQZgDaiALEI0BIBinIQ4gBCgCmAMiCEEVRg0GIAQoApwDIQYgBCgCpAMhCiAEKAKgAyEFIAkEQCACEKsBCyAGQQh2IQMgDg0FIAghAQwuCyAIRSEDIARBpANqIARBgANqKQMANwIAIAQgBCkD+AI3ApwDIAlFDSEgAhCrAQwhCyAEQaQDaiAEQYADaikDADcCACAEIAQpA/gCNwKcAwwcCyAEQfgCaiAGEI4BAkAgBCgC+AIiAkEVRwRAIARB9AJqIARBhANqKAIANgIAIAQgBCkC/AI3AuwCIAQgAjYC6AIMAQsgBEHoAmogBhBiIAQoAugCQRVGDQkLIARBpANqIARB8AJqKQMANwIAIAQgBCkD6AI3ApwDIARBBTYCmAMMHQsgB0UNBCAEQZgDakEEckGRssAAQQcQXiAQDR0MBQsgCARAIARBmANqQQRyQYSywABBBRBeIARBBTYCmAMMHAsgBEH4AmogBhBgIAQoAvgCQRVGDQIgBEGkA2ogBEGAA2opAwA3AgAgBCAEKQP4AjcCnAMgBEEFNgKYAwwZCyAHEKsBIAghAQwoCyAEQTBqIAsQkAECQCAELQAwQQFxBEAgBC0AMUH9AEcNASALEIoBIAlBgH5xIQUMEwsgCQRAIAIQqwELIA5FDSggBxCrAQwoCyAJBEAgAhCrAQtBCyEBIA5FDScgBxCrAQwnCyAEKAKEAyENIAQoAoADIQ4gBCgC/AIhCAwDCyAEQfgCaiAGEI4BAkAgBCgC+AIiAkEVRwRAIBMgBCkC/AI3AgAgE0EIaiAEQYQDaigCADYCACAEIAI2AugCDAELIARB6AJqIAYQZCAEKALoAkEVRg0CCyAEQaQDaiAEQfACaikDADcCACAEIAQpA+gCNwKcAwtBASEDDBgLIAQoAvQCIRQgBCgC8AIhECAEKALsAiEHCyAEQThqIAYQkAEgBC0AOSECIAQtADhBAXENAAtBAiECDBILIAQvAJ0DIAQtAJ8DQRB0ciEDIAQoAqQDIQogBCgCoAMhBSAELQCcAyEGIAIhAQwgCyAHIAEQzgEACxDPAQALIARBrANqQQA2AgAgBEH0kcAANgKoAyAEQgE3ApwDIARBwKfAADYCmAMgBEGYA2pByKfAABDUAQALIARBrANqQQA2AgAgBEH0kcAANgKoAyAEQgE3ApwDIARBqKbAADYCmAMgBEGYA2pBkKfAABDUAQALQQxBBBDOAQALIAQvAJ0DIAQtAJ8DQRB0ciEDIAQoAqQDIQogBCgCoAMhBSAELQCcAyEGIAIhAQwaCyAEQcACaiALEJABQQAhBiAELQDAAkEBcUUNGSAELQDBAkH7AEcEQEEOIQEMGgsgCxCKASAEQbgCaiALEIgBIAQtALwCIQUgBEGwAmogBCgCuAIiBhCQAQJAAkACQAJAIAQtALACQQFxRQRAQQIhCEEAIQJBACEFDAELIAQtALECIQcgBUEBcSEPQQAhAgNAAkACQAJAAkACQAJAAkACfwJAAkACQCAHQf8BcSIMQSxHBEAgDEH9AEcEQCAPQf8BcQ0CQQkhCAwOC0ECIQcgBUGAfnEMBAsgD0H/AXEEQEEQIQgMDQsgBhCKASAEQagCaiAGEJABIAQtAKgCQQFxRQ0BIAQtAKkCIQcLIAdB/wFxIgdBIkYNAUETQRAgB0H9AEYbIQgMCwsgBUH/AXEhBUEEIQgMCgsgBEGgAmogBhCQASAELQCgAkEBcUUEQEEEIQhBACEFDAoLIAQtAKECQSJHBEBBDiEIDAoLIAYQigEgBEH4AmogBhCPASAEKAKEAyEMIAQoAoADIQcgBCgC/AIhDiAEKAL4AiIIQRVHBEAgDiEFDAoLAkAgDkUEQEEBIQggDEEERw0BIAcoAABB69K5owZHIQgMAQtBASEIIAxBBEYEQCAOKAAAQevSuaMGRyEICyAHRQ0AIA4QqwELIAVBgH5xIQdBACEPIAhB/wFxCyAHciIFQf8BcUECRwRAIAVBAXENASACDQMgBEH4AmogBhBgIAQoAvgCQRVHDQIgBCgChAMhDSAEKAKAAyEJIAQoAvwCIQIMBwsgAkUEQCAEQfgCakGJrsAAQQQQXSAEKAL4AkEVRw0EIARBhANqKAIAIQ0gBEGAA2ooAgAhCSAEKAL8AiECCyAEQZgDaiALEI0BIAQoApgDIgdBFUYNBSAEKAKcAyIGQQh2IQMgBCgCpAMhCiAEKAKgAyEFIAkNBCAHIQEMJQsgBEH4AmogBhCOAQJAIAQoAvgCIgdBFUcEQCAEQfQCaiAEQYQDaigCADYCACAEIAQpAvwCNwLsAiAEIAc2AugCDAELIARB6AJqIAYQYiAEKALoAkEVRg0GCyAEQaQDaiAEQfACaikDADcCACAEIAQpA+gCNwKcAwwICyAEQaQDaiAEQYADaikDADcCACAEIAQpA/gCNwKcAwwJCyAEQZgDakEEckGJrsAAQQQQXiAJRQ0IDAcLIARBpANqIARBgANqKQMANwIAIAQgBCkD+AI3ApwDDAcLIAIQqwEgByEBDCALIARBkAJqIAsQkAECQCAELQCQAkEBcQRAIAQtAJECQf0ARw0BIAsQigEgCUGAfnEhBQwLCyAJRQ0gIAIQqwEMIAtBCyEBIAlFDR8gAhCrAQwfCyAEQZgCaiAGEJABIAQtAJkCIQcgBC0AmAJBAXENAAsgBUH/AXEhBUECIQgLIARBqANqIAw2AgAgBEGkA2ogBzYCACAEQaADaiAFNgIAIAQgCDYCnAMLIAJFIAlFcg0BCyACEKsBCyAEQaADaigCACIGQQh2IQMgBEGoA2ooAgAhCiAEQaQDaigCACEFIAQoApwDIQEMGQsgBEGIAmogCxCQAUEAIQYCfwJAIAQtAIgCQQFxRQ0AAkAgBC0AiQJB+wBHDQAgCxCKASAEQYACaiALEIgBIAQtAIQCIQIgBEH4AWogBCgCgAIiCBCQAQJAAkACQCAELQD4AUEBcQRAIAQtAPkBIQUgAkEBcSEJA0ACfwJAAkACQCAFQf8BcSICQSxHBEAgAkH9AEcEQCAJQf8BcQ0CIAchBkEJDA0LIAdBgH5xDAQLIAlB/wFxBEAgByEGQRAMDAsgCBCKASAEQfABaiAIEJABIAQtAPABQQFxRQ0BIAQtAPEBIQULIAVB/wFxIgVBIkYNASAHIQZBE0EQIAVB/QBGGwwKCyAHQf8BcSEGQQQMCQsgBEHoAWogCBCQASAELQDoAUEBcUUNByAELQDpAUEiRw0GIAgQigEgBEGYA2ogCBCPASAEKAKgAyEFIAQoApwDIQIgBCgCmAMiCUEVRw0EIAJFIAVFckUEQCACEKsBC0EAIQkgB0GAfnFBAXILIgdB/wFxRQ0CIARBmANqIAgQjgEgBCgCmAMiAkEVRwRAIARBhANqIARBpANqKAIANgIAIAQgBCkCnAM3AvwCDAULIARB+AJqIAgQYiAEKAL4AiICQRVHDQQgBEHgAWogCBCQASAELQDhASEFIAQtAOABQQFxDQALCyAHQf8BcSEGQQIMBQsgBEGYA2ogCxCNASAEKAKYAyINQRVHBEAgBCgCpAMhCiAEKAKgAyEFIAQoApwDIQYgDQwFCyAEQdgBaiALEJABIAQtANgBQQFxRQ0dIAQtANkBQf0ARwRAQQshAQweCyALEIoBQQAhBUEAIQkMBwsgBCgCpAMhCiACIQYgCQwDCyAEKAKEAyEKIAQoAoADIQUgBCgC/AIhBiACDAILQQ4MAQtBBAshASAGQQh2IQMMGAsgBEHQAWogCxCQAUEAIQYgBC0A0AFBAXFFDRcgBC0A0QFB+wBHBEBBDiEBDBgLIAsQigEgBEHIAWogCxCIASAELQDMASEFIARBwAFqIAQoAsgBIgYQkAECQAJAAkACQCAELQDAAUEBcUUEQEECIQhBACECQQAhBQwBCyAELQDBASEHIAVBAXEhD0EAIQIDQAJAAkACQAJAAkACQAJAAn8CQAJAAkAgB0H/AXEiDEEsRwRAIAxB/QBHBEAgD0H/AXENAkEJIQgMDgtBAiEHIAVBgH5xDAQLIA9B/wFxBEBBECEIDA0LIAYQigEgBEG4AWogBhCQASAELQC4AUEBcUUNASAELQC5ASEHCyAHQf8BcSIHQSJGDQFBE0EQIAdB/QBGGyEIDAsLIAVB/wFxIQVBBCEIDAoLIARBsAFqIAYQkAEgBC0AsAFBAXFFBEBBBCEIQQAhBQwKCyAELQCxAUEiRwRAQQ4hCAwKCyAGEIoBIARB+AJqIAYQjwEgBCgChAMhDCAEKAKAAyEHIAQoAvwCIQ4gBCgC+AIiCEEVRwRAIA4hBQwKCwJAIA5FBEBBASEIIAxBBEcNASAHKAAAQeHIkZMHRyEIDAELQQEhCCAMQQRGBEAgDigAAEHhyJGTB0chCAsgB0UNACAOEKsBCyAFQYB+cSEHQQAhDyAIQf8BcQsgB3IiBUH/AXFBAkcEQCAFQQFxDQEgAg0DIARB+AJqIAYQYCAEKAL4AkEVRw0CIAQoAoQDIQ0gBCgCgAMhCSAEKAL8AiECDAcLIAJFBEAgBEH4AmpBgLLAAEEEEF0gBCgC+AJBFUcNBCAEQYQDaigCACENIARBgANqKAIAIQkgBCgC/AIhAgsgBEGYA2ogCxCNASAEKAKYAyIHQRVGDQUgBCgCnAMiBkEIdiEDIAQoAqQDIQogBCgCoAMhBSAJDQQgByEBDCMLIARB+AJqIAYQjgECQCAEKAL4AiIHQRVHBEAgBEH0AmogBEGEA2ooAgA2AgAgBCAEKQL8AjcC7AIgBCAHNgLoAgwBCyAEQegCaiAGEGIgBCgC6AJBFUYNBgsgBEGkA2ogBEHwAmopAwA3AgAgBCAEKQPoAjcCnAMMCAsgBEGkA2ogBEGAA2opAwA3AgAgBCAEKQP4AjcCnAMMCQsgBEGYA2pBBHJBgLLAAEEEEF4gCUUNCAwHCyAEQaQDaiAEQYADaikDADcCACAEIAQpA/gCNwKcAwwHCyACEKsBIAchAQweCyAEQaABaiALEJABAkAgBC0AoAFBAXEEQCAELQChAUH9AEcNASALEIoBIAlBgH5xIQUMCQsgCUUNHiACEKsBDB4LQQshASAJRQ0dIAIQqwEMHQsgBEGoAWogBhCQASAELQCpASEHIAQtAKgBQQFxDQALIAVB/wFxIQVBAiEICyAEQagDaiAMNgIAIARBpANqIAc2AgAgBEGgA2ogBTYCACAEIAg2ApwDCyACRSAJRXINAQsgAhCrAQsgBEGgA2ooAgAiBkEIdiEDIARBqANqKAIAIQogBEGkA2ooAgAhBSAEKAKcAyEBDBcLIARBmAFqIAsQkAFBACEGIAQtAJgBQQFxRQ0WIAQtAJkBQfsARwRAQQ4hAQwXCyALEIoBIARBkAFqIAsQiAEgBC0AlAEgBEGIAWogBCgCkAEiBhCQASAELQCIAUEBcUUEQEECIQJBACEHQQAhBQwDCyAELQCJASECQQFxIQwgBEHoAmpBBHIhE0EAIQcDQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAn8CQCACQf8BcSIFQSxHBEAgBUH9AEcEQCAMQf8BcQ0CQQkMAwsgCUGAfnEhAkEDDAULQRAgDEH/AXENARogBhCKASAEQYABaiAGEJABIAQtAIABQQFxRQ0CIAQtAIEBIQILIAJB/wFxIgVBIkYNAkEQIAVB/QBHDQAaQRMLIQIgCSEFDBALIAlB/wFxIQVBBCECDA8LIARB+ABqIAYQkAEgBC0AeEEBcUUEQEEEIQJBACEFDA8LIAQtAHlBIkcEQEEOIQIMDwsgBhCKASAEQfgCaiAGEI8BIAQoAoQDIQ8gBCgCgAMhDCAEKAL8AiEFIAQoAvgCIgJBFUcNDgJAIAVFBEBBAiECAkACQCAPQQVrDgQAAwMBAwsgDEGEssAAQQUQjQJBAEdBAXQhAgwCC0EBQQIgDCkAAELyys2D983bueUAURshAgwBC0ECIQICQAJAAkAgD0EFaw4EAAICAQILIAVBhLLAAEEFEI0CQQBHQQF0IQIMAQtBAUECIAUpAABC8srNg/fN27nlAFEbIQILIAxFDQAgBRCrAQtBACEMIAlBgH5xCyACciIJQf8BcSIFQQNHBEAgBQ4CAwIBCyAOIQkCQCAIIgJFBEAgBEH4AmpBhLLAAEEFEF0gBCgC+AJBFUcNASAEQYQDaigCACENIARBgANqKAIAIQkgBCgC/AIhAgsCQCAHRQRAIARB+AJqQYmywABBCBBdIAQoAvgCQRVHDQEgBEGEA2ooAgAhFCAEQYADaigCACEQIAQoAvwCIQcLIAQgFDYCsAMgBCAQNgKsAyAEKQKsAyEYIARBmANqIAsQjQEgGKchDiAEKAKYAyIIQRVGDQYgBCgCnAMhBiAEKAKkAyEKIAQoAqADIQUgCQRAIAIQqwELIAZBCHYhAyAODQUgCCEBDCMLIAhFIQMgBEGkA2ogBEGAA2opAwA3AgAgBCAEKQP4AjcCnAMgCUUNESACEKsBDBELIARBpANqIARBgANqKQMANwIAIAQgBCkD+AI3ApwDDAwLIARB+AJqIAYQjgECQCAEKAL4AiICQRVHBEAgBEH0AmogBEGEA2ooAgA2AgAgBCAEKQL8AjcC7AIgBCACNgLoAgwBCyAEQegCaiAGEGIgBCgC6AJBFUYNCQsgBEGkA2ogBEHwAmopAwA3AgAgBCAEKQPoAjcCnAMgBEEFNgKYAwwNCyAHRQ0EIARBmANqQQRyQYmywABBCBBeIBANDQwFCyAIBEAgBEGYA2pBBHJBhLLAAEEFEF4gBEEFNgKYAwwMCyAEQfgCaiAGEGAgBCgC+AJBFUYNAiAEQaQDaiAEQYADaikDADcCACAEIAQpA/gCNwKcAyAEQQU2ApgDDAkLIAcQqwEgCCEBDB0LIARB6ABqIAsQkAECQCAELQBoQQFxBEAgBC0AaUH9AEcNASALEIoBIAlBgH5xIQUMCAsgCQRAIAIQqwELIA5FDR0gBxCrAQwdCyAJBEAgAhCrAQtBCyEBIA5FDRwgBxCrAQwcCyAEKAKEAyENIAQoAoADIQ4gBCgC/AIhCAwDCyAEQfgCaiAGEI4BAkAgBCgC+AIiAkEVRwRAIBMgBCkC/AI3AgAgE0EIaiAEQYQDaigCADYCACAEIAI2AugCDAELIARB6AJqIAYQZCAEKALoAkEVRg0CCyAEQaQDaiAEQfACaikDADcCACAEIAQpA+gCNwKcAwtBASEDDAgLIAQoAvQCIRQgBCgC8AIhECAEKALsAiEHCyAEQfAAaiAGEJABIAQtAHEhAiAELQBwQQFxDQALQQIhAgwCCyAEQShqIAoQkAEgCUH/AXEiBiAFciEJIBinIQgCQAJAAkACQAJAIAQtAChBAXEEQCAELQApQf0ARg0FQQshASARDgQBAgMbAwsCQAJAAkACQCARDgQAAQIeAgsgCQRAIAIQqwELIAhFDR0MAgsgCQRAIAIQqwELIAhFDRwMAQsgAiEHIAlFDRsLIAcQqwEMGgsgCQRAIAIQqwELIAhFDRkMAgsgCQRAIAIQqwELIAhFDRgMAQsgAiEHIAlFDRcLIAcQqwEMFgsgChCKAQwQC0EAIQgMAQsgBEGoA2ogDzYCACAEQaQDaiAMNgIAIARBoANqIAU2AgAgBCACNgKcAwtBASEDIAdFIBBFcg0BC0EBIQMgBxCrAQsgDkUgCEUgA0VyckUEQCAIEKsBCyAEQaADaigCACIGQQh2IQMgBEGoA2ooAgAhCiAEQaQDaigCACEFIAQoApwDIQEMEAtBACEIDAELIARBqANqIA82AgAgBEGkA2ogDDYCACAEQaADaiAFNgIAIAQgAjYCnAMLQQEhAyAHRSAQRXINAQtBASEDIAcQqwELIA5FIAhFIANFcnJFBEAgCBCrAQsgBEGgA2ooAgAiBkEIdiEDIARBqANqKAIAIQogBEGkA2ooAgAhBSAEKAKcAyEBDAsLIARBmANqIAMQZCAEKAKYAyIBQRVHDQMgBEGkA2ooAgAhByAEQaADaigCACENIAQoApwDIQUgBEEQaiADEJABIAQtABBBAXEEQEEAIQIgBC0AEUH9AEYNBUELIQEgDQ0DDAgLIA0NAQtBBCEBDAYLIAUQqwFBBCEBDAULIAUQqwEMBAsgBCgCpAMhCiAEKAKgAyEFIAQoApwDIQYMAwsgAxCKASAEQQhqIAoQkAECQAJAAkAgBC0ACEEBcQRAIAQtAAlB/QBGDQNBCyEBIA1FDQEgBRCrAUEAIQMMCQtBBCEBIA0NAQtBACEDDAcLIAUQqwFBACEDDAYLIAoQigEgBUH/AXEhBkEFIRELIAVBgH5xIAZyIQYgBEGYA2ogBEHYAmoQiwEgGKchCSAEKAKYAyIBQRVHBEAgBCgCpAMhCiAEKAKgAyEFIAQoApwDIQMCQAJAAkACQAJAIBEOBgABAgsCAwILIAYEQCACEKsBCyAJRQ0KDAMLIAYEQCACEKsBCyAJRQ0JDAILIAIhByAGRQ0IDAELIAYhByANRQ0HCyAHEKsBDAYLIAAgGEIgiD4CGCAAIAk2AhQgACAHNgIQIAAgDTYCDCAAIAY2AgggACACNgIEIAAgETYCACAWRQ0GIBUQqwEMBgtBDiEBCyAGQQh2IQMMAgsgBCgCmAMiAUEVRwRAIAQvAJ0DIAQtAJ8DQRB0ciEDIAQoAqQDIQogBCgCoAMhBSAELQCcAyEGDAILQQ4hAQwBC0EKIQELIAZB/wFxIANBCHRyIQMLIAQgCjYChAMgBCAFNgKAAyAEIAM2AvwCIAQgATYC+AJBiAFBARA9IgFFBEBBiAFBARDOAQALIAFB1JDAAEGIARCLAiEBIARBADYC8AIgBEIBNwPoAiAEQZgDaiICIARB6AJqQZiPwAAQ8gEgBEH4AmogAhCHAQ0BIAQoAugCIQIgBCgC7AIhAyAEKALwAiEHAkAgBCgC+AJBFEkNACAEKAKAA0UNACAEKAL8AhCrAQsgBCAHNgKQAyAEIAM2AowDIAQgAjYCiAMgBEKIgYCAgBE3A4ADIAQgATYC/AIgBEEINgL4AiAEQQA2AvACIARCATcD6AIgBEGYA2oiASAEQegCakGYj8AAEPIBIARB+AJqIAEQfQ0BIAAgBCkD6AI3AgQgAEEMaiAEQfACaigCADYCACAAIBc2AhggACAWNgIUIAAgFTYCECAAQQE2AgAgBEH4AmoQLgsgEhCrASAEQcADaiQADwtBsI/AAEE3IARB2AJqQeiPwABBxJDAABDpAQALyggBAX8jAEEwayICJAACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAAoAgBBAWsODAECAwQFBgcICQoLDAALIAJBLGpBATYCACACQgE3AhwgAkHwrMAANgIYIAJBIzYCBCACIABBBGo2AhQgAiACNgIoIAIgAkEUajYCACABIAJBGGoQ9wEMDAsgAkEsakEBNgIAIAJCATcCHCACQdSswAA2AhggAkEkNgIEIAIgAEEEajYCFCACIAI2AiggAiACQRRqNgIAIAEgAkEYahD3AQwLCyACQSxqQQE2AgAgAkIBNwIcIAJBtKzAADYCGCACQR42AgQgAiAAQQRqNgIUIAIgAjYCKCACIAJBFGo2AgAgASACQRhqEPcBDAoLIAJBLGpBATYCACACQgE3AhwgAkGcrMAANgIYIAJBHjYCBCACIABBBGo2AhQgAiACNgIoIAIgAkEUajYCACABIAJBGGoQ9wEMCQsgAkEMakElNgIAIAJBLGpBAjYCACACIABBCGo2AhAgAkICNwIcIAJB9KvAADYCGCACQSU2AgQgAiAAQRBqNgIUIAIgAjYCKCACIAJBFGo2AgggAiACQRBqNgIAIAEgAkEYahD3AQwICyACQSxqQQE2AgAgAkIBNwIcIAJByKvAADYCGCACQR42AgQgAiAAQQRqNgIUIAIgAjYCKCACIAJBFGo2AgAgASACQRhqEPcBDAcLIAJBLGpBATYCACACQgE3AhwgAkGsq8AANgIYIAJBHjYCBCACIABBBGo2AhQgAiACNgIoIAIgAkEUajYCACABIAJBGGoQ9wEMBgsgAkEsakEBNgIAIAJCAjcCHCACQfSqwAA2AhggAkEeNgIEIAIgAEEEajYCFCACIAI2AiggAiACQRRqNgIAIAEgAkEYahD3AQwFCyACQQxqQR42AgAgAkEsakECNgIAIAIgAEEEajYCECACQgI3AhwgAkHYqsAANgIYIAJBHjYCBCACIABBEGo2AhQgAiACNgIoIAIgAkEUajYCCCACIAJBEGo2AgAgASACQRhqEPcBDAQLIAJBDGpBHjYCACACQSxqQQI2AgAgAiAAQQRqNgIQIAJCAjcCHCACQbCqwAA2AhggAkEeNgIEIAIgAEEQajYCFCACIAI2AiggAiACQRRqNgIIIAIgAkEQajYCACABIAJBGGoQ9wEMAwsgAkEsakEBNgIAIAJCATcCHCACQYyqwAA2AhggAkEmNgIEIAIgAEEEajYCFCACIAI2AiggAiACQRRqNgIAIAEgAkEYahD3AQwCCyACQSxqQQE2AgAgAkIBNwIcIAJB+KnAADYCGCACQSc2AgQgAiAAQQRqNgIUIAIgAjYCKCACIAJBFGo2AgAgASACQRhqEPcBDAELIAJBLGpBADYCACACQfSRwAA2AiggAkIBNwIcIAJB4KnAADYCGCABIAJBGGoQ9wELIAJBMGokAAtAAQJ/IABBCGooAgAhASAAKAIAIQJBDEEEED0iAEUEQEEMQQQQzgEACyAAIAE2AgggACABNgIEIAAgAjYCACAAC6EBAQJ/IwBBIGsiAiQAAkAgAQRAIAEoAgAiAw0BIAJBHGpBADYCACACQfSRwAA2AhggAkIBNwIMIAJBwKfAADYCCCACQQhqQcinwAAQ1AEACyACQRxqQQA2AgAgAkH0kcAANgIYIAJCATcCDCACQaimwAA2AgggAkEIakGQp8AAENQBAAsgACADNgIAIAAgASkCBDcCBCABEKsBIAJBIGokAAu5BQEBfyMAQRBrIgIkAAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCAEEBaw4MAQIDBAUGBwgJCgsMAAsgAiAAQQRqNgIMIAFBjK/AAEEPQYqtwABBBiACQQxqQZyvwAAQ+gEMDAsgAiAAQQRqNgIMIAFB6a7AAEEQQYqtwABBBiACQQxqQfyuwAAQ+gEMCwsgAiAAQQRqNgIMIAFB367AAEEKQeutwABBAyACQQxqQYSUwAAQ+gEMCgsgAiAAQQRqNgIMIAFB0q7AAEENQeutwABBAyACQQxqQYSUwAAQ+gEMCQsgAiAAQQhqNgIIIAIgAEEQajYCDCABQaKuwABBD0GxrsAAQQggAkEIakG8rsAAQcyuwABBBiACQQxqQbyuwAAQ+wEMCAsgAiAAQQRqNgIMIAFBmK7AAEEKQeutwABBAyACQQxqQYSUwAAQ+gEMBwsgAiAAQQRqNgIMIAFBja7AAEELQeutwABBAyACQQxqQYSUwAAQ+gEMBgsgAiAAQQRqNgIMIAFBga7AAEEIQYmuwABBBCACQQxqQYSUwAAQ+gEMBQsgAiAAQQRqNgIIIAIgAEEQajYCDCABQe6twABBCEH2rcAAQQsgAkEIakGElMAAQeutwABBAyACQQxqQYSUwAAQ+wEMBAsgAiAAQQRqNgIIIAIgAEEQajYCDCABQdStwABBDEHgrcAAQQsgAkEIakGElMAAQeutwABBAyACQQxqQYSUwAAQ+wEMAwsgAiAAQQRqNgIMIAFBvK3AAEEIQYqtwABBBiACQQxqQcStwAAQ+gEMAgsgAiAAQQRqNgIMIAFBoK3AAEEMQYqtwABBBiACQQxqQaytwAAQ+gEMAQsgAiAAQQRqNgIMIAFB+KzAAEESQYqtwABBBiACQQxqQZCtwAAQ+gELIAJBEGokAAscACAAKAIAKAIAIgAoAgAgAEEIaigCACABEIACC7cBAAJAIAIEQAJAAkACfwJAAkAgAUEATgRAIAMoAggNASABDQJBASECDAQLDAYLIAMoAgQiAkUEQCABRQRAQQEhAgwECyABQQEQPQwCCyADKAIAIAJBASABED4MAQsgAUEBED0LIgJFDQELIAAgAjYCBCAAQQhqIAE2AgAgAEEANgIADwsgACABNgIEIABBCGpBATYCACAAQQE2AgAPCyAAIAE2AgQLIABBCGpBADYCACAAQQE2AgALzQEBA38jAEEgayICJAACQAJAIAFBAWoiAUUNACAAQQRqKAIAIgNBAXQiBCABIAEgBEkbIgFBCCABQQhLGyIBQX9zQR92IQQCQCADBEAgAkEBNgIYIAIgAzYCFCACIAAoAgA2AhAMAQsgAkEANgIYCyACIAEgBCACQRBqEIIBIAIoAgQhAyACKAIARQRAIAAgAzYCACAAQQRqIAE2AgAMAgsgAkEIaigCACIAQYGAgIB4Rg0BIABFDQAgAyAAEM4BAAsQzwEACyACQSBqJAALzwEBAn8jAEEgayIDJAACQAJAIAEgASACaiIBSw0AIABBBGooAgAiAkEBdCIEIAEgASAESRsiAUEIIAFBCEsbIgFBf3NBH3YhBAJAIAIEQCADQQE2AhggAyACNgIUIAMgACgCADYCEAwBCyADQQA2AhgLIAMgASAEIANBEGoQggEgAygCBCECIAMoAgBFBEAgACACNgIAIABBBGogATYCAAwCCyADQQhqKAIAIgBBgYCAgHhGDQEgAEUNACACIAAQzgEACxDPAQALIANBIGokAAsdACABKAIARQRAAAsgAEHEs8AANgIEIAAgATYCAAtVAQJ/IAEoAgAhAiABQQA2AgACQCACBEAgASgCBCEDQQhBBBA9IgFFDQEgASADNgIEIAEgAjYCACAAQcSzwAA2AgQgACABNgIADwsAC0EIQQQQzgEAC+0DAQF/IwBBMGsiAiQAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCAEEBaw4UAQIDBAUGBwgJCgsMDQ4PEBESExQACyACQcK5wAA2AihBIgwUCyACQam5wAA2AihBGQwTCyACQY25wAA2AihBHAwSCyACQfK4wAA2AihBGwwRCyACQdO4wAA2AihBHwwQCyACQa24wAA2AihBJgwPCyACQYW4wAA2AihBKAwOCyACQc63wAA2AihBNwwNCyACQae3wAA2AihBJwwMCyACQe+2wAA2AihBOAwLCyACQbe2wAA2AihBOAwKCyACQYm2wAA2AihBLgwJCyACQfG1wAA2AihBGAwICyACQeK1wAA2AihBDwwHCyACQda1wAA2AihBDAwGCyACQbu1wAA2AihBGwwFCyACQaC1wAA2AihBGwwECyACQdG0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ACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgBEEBagwHCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakEiOgAAIARBAWoMBgsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB4gA6AAAgBEEBagwFCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakH0ADoAACAEQQFqDAQLIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQdwAOgAAIAEgBEEBaiIENgIIIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQe4AOgAAIARBAWoMAwsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB5gA6AAAgBEEBagwCCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHyADoAACAEQQFqDAELAn8CQAJAIAVBIE8EQCAFQYABSQ0BIAVBgBBPDQIgBiAFQT9xQYABcjoADSAGIAVBBnZBwAFyOgAMQQIMAwsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB9QA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpBMDoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakEwOgAAIAEgBEEBaiIENgIIIAVBD3EiCEEKSSEHIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAVB8AFxQQR2QTByOgAAIAEgBEEBaiIENgIIIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAhBMHIgCEE3aiAHGzoAACAEQQFqDAMLIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAU6AAAgBEEBagwCCyAFQYCABE8EQCAGIAVBP3FBgAFyOgAPIAYgBUESdkHwAXI6AAwgBiAFQQZ2QT9xQYABcjoADiAGIAVBDHZBP3FBgAFyOgANQQQMAQsgBiAFQT9xQYABcjoADiAGIAVBDHZB4AFyOgAMIAYgBUEGdkE/cUGAAXI6AA1BAwshBSAFIAMoAgAgBGtLBEAgASAEIAUQhAEgASgCCCEECyABKAIAIARqIAZBDGogBRCLAhogBCAFagsiBDYCCCACIAlHDQALCyABQQRqKAIAIARGBEAgASAEEIMBIAEoAgghBAsgAEEANgIAIAEgBEEBajYCCCABKAIAIARqQSI6AAAgBkEQaiQAC0wBAX8gAUEEaigCACABKAIIIgJrQQNNBEAgASACQQQQhAEgASgCCCECCyAAQQA2AgAgASACQQRqNgIIIAEoAgAgAmpB7uqx4wY2AAALDQAgACABIAIgAxCXAQtSAQF/IAEoAggiAiABKAIERgRAIAEgAhCDASABKAIIIQILIAAgATYCBCAAQQA2AgAgASACQQFqNgIIIABBCGpBAToAACABKAIAIAJqQdsAOgAAC1IBAX8gASgCCCICIAEoAgRGBEAgASACEIMBIAEoAgghAgsgACABNgIEIABBADYCACABIAJBAWo2AgggAEEIakEBOgAAIAEoAgAgAmpB+wA6AAALngICAn8BfiMAQSBrIgUkACABKAIIIgQgASgCBEYEQCABIAQQgwEgASgCCCEECyABIARBAWo2AgggASgCACAEakH7ADoAACAFQRBqIAEgAiADEJcBAkAgBSgCEEUEQCABKAIIIgQgASgCBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQTo6AAAgASAEQQFqIgQ2AgggASgCBCAERgRAIAEgBBCDASABKAIIIQQLIAAgATYCBCAAQQA2AgAgASAEQQFqNgIIIABBCGpBAToAACABKAIAIARqQfsAOgAADAELIAVBCGogBUEcaigCACIBNgIAIAUgBSkCFCIGNwMAIABBDGogATYCACAAIAY3AgQgAEEBNgIACyAFQSBqJAALFgAgACgCACIAKAIAIAAoAgQgARCAAgsdACABKAIARQRAAAsgAEGI1cAANgIEIAAgATYCAAtVAQJ/IAEoAgAhAiABQQA2AgACQCACBEAgASgCBCEDQQhBBBA9IgFFDQEgASADNgIEIAEgAjYCACAAQYjVwAA2AgQgACABNgIADwsAC0EIQQQQzgEAC5QEAQN/IwBBMGsiAiQAAn8CQAJAAkACQCAAKAIEIgMOAwACAwELIwBBEGsiACQAIABB0NbAADYCCCAAQQ42AgQgAEG/1sAANgIAIwBBEGsiASQAIAFBCGogAEEIaigCADYCACABIAApAgA3AwAjAEEQayIAJAAgACABKQIANwMIIABBCGpB9NTAAEEAIAEoAghBARCyAQALIAJBLGpBADYCACACQYjVwAA2AiggAkIBNwIcIAJBoNXAADYCGEEBIAEgAkEYahD3AQ0CGiADQQN0IQMgACgCACEAAkADQCACIAA2AhQgBARAIAJBADYCLCACQYjVwAA2AiggAkIBNwIcIAJBrNXAADYCGCABIAJBGGoQ9wENAgsgAkEBNgIsIAJCAjcCHCACQbTVwAA2AhggAkHMADYCBCACIAI2AiggAiACQRRqNgIAIAEgAkEYahD3AQ0BIABBCGohACAEQQFrIQQgA0EIayIDDQALQQAMAwtBAQwCCyACQSxqQQE2AgAgAkICNwIcIAJBtNXAADYCGCACQc0ANgIEIAIgACgCADYCACACIAI2AiggASACQRhqEPcBDAELIAJBDGpBzQA2AgAgAkEsakECNgIAIAJCAzcCHCACQczVwAA2AhggAkHNADYCBCACIAAoAgAiADYCACACIABBCGo2AgggAiACNgIoIAEgAkEYahD3AQsgAkEwaiQACwwAQsiF+aSet9TbEgshAQF/AkAgACgCBCIBRQ0AIABBCGooAgBFDQAgARCrAQsL1gIBAn8jAEEQayICJAAgACgCACEAAkACfwJAIAFBgAFPBEAgAkEANgIMIAFBgBBPDQEgAiABQT9xQYABcjoADSACIAFBBnZBwAFyOgAMQQIMAgsgACgCCCIDIAAoAgRGBEAgACADEBAgACgCCCEDCyAAIANBAWo2AgggACgCACADaiABOgAADAILIAFBgIAETwRAIAIgAUE/cUGAAXI6AA8gAiABQQZ2QT9xQYABcjoADiACIAFBDHZBP3FBgAFyOgANIAIgAUESdkEHcUHwAXI6AAxBBAwBCyACIAFBP3FBgAFyOgAOIAIgAUEMdkHgAXI6AAwgAiABQQZ2QT9xQYABcjoADUEDCyEBIAEgAEEEaigCACAAKAIIIgNrSwRAIAAgAyABEBEgACgCCCEDCyAAKAIAIANqIAJBDGogARCLAhogACABIANqNgIICyACQRBqJABBAAtaAQF/IwBBIGsiAiQAIAIgACgCADYCBCACQRhqIAFBEGopAgA3AwAgAkEQaiABQQhqKQIANwMAIAIgASkCADcDCCACQQRqQeDWwAAgAkEIahDeASACQSBqJAALkwMBBX8CQAJAAkACQCABQQlPBEBBEEEIELMBIAFLDQEMAgsgABCmASEEDAILQRBBCBCzASEBC0EIQQgQswEhA0EUQQgQswEhAkEQQQgQswEhBUEAQRBBCBCzAUECdGsiBkGAgHwgBSACIANqamtBd3FBA2siAyADIAZLGyABayAATQ0AIAFBECAAQQRqQRBBCBCzAUEFayAASxtBCBCzASIDakEQQQgQswFqQQRrEKYBIgJFDQAgAhDDASEAAkAgAUEBayIEIAJxRQRAIAAhAQwBCyACIARqQQAgAWtxEMMBIQJBEEEIELMBIQQgABC3ASACQQAgASACIABrIARLG2oiASAAayICayEEIAAQugFFBEAgASAEELsBIAAgAhC7ASAAIAIQpwEMAQsgACgCACEAIAEgBDYCBCABIAAgAmo2AgALIAEQugENASABELcBIgJBEEEIELMBIANqTQ0BIAEgAxDAASEAIAEgAxC7ASAAIAIgA2siAxC7ASAAIAMQpwEMAQsgBA8LIAEQwgEgARC6ARoL7SECD38BfiMAQRBrIgskAAJAAkAgAEH1AU8EQEEIQQgQswEhBkEUQQgQswEhBUEQQQgQswEhAUEAQRBBCBCzAUECdGsiAkGAgHwgASAFIAZqamtBd3FBA2siASABIAJLGyAATQ0CIABBBGpBCBCzASEEQdD8wAAoAgBFDQFBACAEayEDAkACQAJ/QQAgBEGAAkkNABpBHyAEQf///wdLDQAaIARB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Gg8LDwsgAkF4cUHU/MAAaiEBAn9BzPzAACgCACIDQQEgAkEDdnQiAnEEQCABKAIIDAELQcz8wAAgAiADcjYCACABCyEDIAEgADYCCCADIAA2AgwgACABNgIMIAAgAzYCCAtpACMAQTBrIgEkAEG0/MAALQAABEAgAUEcakEBNgIAIAFCAjcCDCABQcjXwAA2AgggAUHKADYCJCABIAA2AiwgASABQSBqNgIYIAEgAUEsajYCICABQQhqQfDXwAAQ1AEACyABQTBqJAAL3gEBA38jAEEgayIAJAACQEHI/MAAKAIAQf////8HcQRAQZCAwQAoAgANAQtBvPzAACgCAEG8/MAAQX82AgBFBEBBxPzAACgCACEBQcT8wABBuJvAADYCAEHA/MAAKAIAIQJBwPzAAEEBNgIAQbz8wABBADYCAAJAIAFFDQAgAiABKAIAEQYAIAFBBGooAgBFDQAgAUEIaigCABogAhCrAQsgAEEgaiQADwsACyAAQRxqQQA2AgAgAEH41sAANgIYIABCATcCDCAAQbTYwAA2AgggAEEIakHY2MAAENQBAAuLAgIEfwF+IwBBMGsiAiQAIAFBBGohBCABKAIERQRAIAEoAgAhAyACQRBqIgVBADYCACACQgE3AwggAiACQQhqNgIUIAJBKGogA0EQaikCADcDACACQSBqIANBCGopAgA3AwAgAiADKQIANwMYIAJBFGpB4NbAACACQRhqEN4BGiAEQQhqIAUoAgA2AgAgBCACKQMINwIACyACQSBqIgMgBEEIaigCADYCACABQQxqQQA2AgAgBCkCACEGIAFCATcCBCACIAY3AxhBDEEEED0iAUUEQEEMQQQQzgEACyABIAIpAxg3AgAgAUEIaiADKAIANgIAIABBiNnAADYCBCAAIAE2AgAgAkEwaiQAC60BAQN/IwBBMGsiAiQAIAFBBGohAyABKAIERQRAIAEoAgAhASACQRBqIgRBADYCACACQgE3AwggAiACQQhqNgIUIAJBKGogAUEQaikCADcDACACQSBqIAFBCGopAgA3AwAgAiABKQIANwMYIAJBFGpB4NbAACACQRhqEN4BGiADQQhqIAQoAgA2AgAgAyACKQMINwIACyAAQYjZwAA2AgQgACADNgIAIAJBMGokAAtFAQJ/IAEoAgQhAiABKAIAIQNBCEEEED0iAUUEQEEIQQQQzgEACyABIAI2AgQgASADNgIAIABBmNnAADYCBCAAIAE2AgALEwAgAEGY2cAANgIEIAAgATYCAAvvAQEDfyMAQSBrIgUkAEHI/MAAQcj8wAAoAgAiB0EBajYCAEGQgMEAQZCAwQAoAgBBAWoiBjYCAAJAAkAgB0EASCAGQQJLcg0AIAUgBDoAGCAFIAM2AhQgBSACNgIQQbz8wAAoAgAiAkF/TA0AQbz8wAAgAkEBaiICNgIAQbz8wABBxPzAACgCACIDBH9BwPzAACgCACAFIAAgASgCEBECACAFIAUpAwA3AwggBUEIaiADKAIUEQIAQbz8wAAoAgAFIAILQQFrNgIAIAZBAUsNACAEDQELAAsjAEEQayICJAAgAiABNgIMIAIgADYCCAALEAAgACABakEBa0EAIAFrcQsPACAAQQF0IgBBACAAa3ILCgBBACAAayAAcQsSAEEAQRkgAEEBdmsgAEEfRhsLCgAgACgCBEF4cQsNACAALQAEQQJxQQF2CwoAIAAoAgRBAXELCwAgAC0ABEEDcUULJwAgACAAKAIEQQFxIAFyQQJyNgIEIAAgAWoiACAAKAIEQQFyNgIECx4AIAAgAUEDcjYCBCAAIAFqIgAgACgCBEEBcjYCBAsMACAAIAFBA3I2AgQLFgAgACABQQFyNgIEIAAgAWogATYCAAsjACACIAIoAgRBfnE2AgQgACABQQFyNgIEIAAgAWogATYCAAsHACAAIAFqCwcAIAAgAWsLBwAgAEEIagsHACAAQQhrCxkBAX8gACgCECIBBH8gAQUgAEEUaigCAAsLCgAgACgCDEEBcQsKACAAKAIMQQF2Cw0AIAAoAgAgACgCBGoL8QEBAX8gACgCACECIwBBEGsiACQAIAAgAjYCACAAIAJBBGo2AgQgASgCGEGJ9cAAQQkgAUEcaigCACgCDBEBACECIABBADoADSAAIAI6AAwgACABNgIIIABBCGpBkvXAAEELIABB9PTAABDiAUGd9cAAQQkgAEEEakGo9cAAEOIBIQECfyAALQAMIgIgAC0ADUUNABpBASACDQAaIAEoAgAiAS0AAEEEcUUEQCABKAIYQZvgwABBAiABQRxqKAIAKAIMEQEADAELIAEoAhhBmuDAAEEBIAFBHGooAgAoAgwRAQALIABBEGokAEH/AXFBAEcLhgQCB38CfiMAQRBrIgUkACAAKAIAIgBBCGooAgAhBiAAKAIAIQAgASgCGEGi4MAAQQEgAUEcaigCACgCDBEBACECIAVBADoABSAFIAI6AAQgBSABNgIAIAYEQANAIAUgADYCDCAFQQxqIQcjAEFAaiICJABBASEEAkAgBSIBLQAEDQAgAS0ABSEEAkACQAJAIAEoAgAiAygCACIIQQRxRQRAIAQNAQwDCyAEDQFBASEEIAMoAhhBoeDAAEEBIANBHGooAgAoAgwRAQANAyADKAIAIQgMAQtBASEEIAMoAhhBleDAAEECIANBHGooAgAoAgwRAQBFDQEMAgtBASEEIAJBAToAFyACQTRqQfTfwAA2AgAgAiAINgIYIAIgAykCGDcDCCACIAJBF2o2AhAgAykCCCEJIAMpAhAhCiACIAMtACA6ADggAiADKAIENgIcIAIgCjcDKCACIAk3AyAgAiACQQhqNgIwIAcgAkEYakH02cAAKAIAEQAADQEgAigCMEGT4MAAQQIgAigCNCgCDBEBACEEDAELIAcgA0H02cAAKAIAEQAAIQQLIAFBAToABSABIAQ6AAQgAkFAayQAIABBAWohACAGQQFrIgYNAAsLIAUiAC0ABAR/QQEFIAAoAgAiAEEYaigCAEG04MAAQQEgAEEcaigCACgCDBEBAAsgBUEQaiQAC7sCAQN/IAAoAgAhACABEPgBRQRAIAEQ+QFFBEAgACABEIICDwsjAEGAAWsiAyQAIAAtAAAhAANAIAIgA2pB/wBqQTBBNyAAQQ9xIgRBCkkbIARqOgAAIAJBAWshAiAAIgRBBHYhACAEQQ9LDQALIAJBgAFqIgBBgQFPBEAgAEGAAUHQ4MAAENYBAAsgAUEBQeDgwABBAiACIANqQYABakEAIAJrEOwBIANBgAFqJAAPCyMAQYABayIDJAAgAC0AACEAA0AgAiADakH/AGpBMEHXACAAQQ9xIgRBCkkbIARqOgAAIAJBAWshAiAAIgRBBHYhACAEQQ9LDQALIAJBgAFqIgBBgQFPBEAgAEGAAUHQ4MAAENYBAAsgAUEBQeDgwABBAiACIANqQYABakEAIAJrEOwBIANBgAFqJAAL2AIBAn8gACgCACEAIwBBEGsiAiQAAkACfwJAIAFBgAFPBEAgAkEANgIMIAFBgBBPDQEgAiABQT9xQYABcjoADSACIAFBBnZBwAFyOgAMQQIMAgsgACgCCCIDIAAoAgRGBEAgACADEIMBIAAoAgghAwsgACADQQFqNgIIIAAoAgAgA2ogAToAAAwCCyABQYCABE8EQCACIAFBP3FBgAFyOgAPIAIgAUEGdkE/cUGAAXI6AA4gAiABQQx2QT9xQYABcjoADSACIAFBEnZBB3FB8AFyOgAMQQQMAQsgAiABQT9xQYABcjoADiACIAFBDHZB4AFyOgAMIAIgAUEGdkE/cUGAAXI6AA1BAwshASABIABBBGooAgAgACgCCCIDa0sEQCAAIAMgARCEASAAKAIIIQMLIAAoAgAgA2ogAkEMaiABEIsCGiAAIAEgA2o2AggLIAJBEGokAEEAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB0NnAACACQQhqEN4BIAJBIGokAAtLAQF/IAIgACgCACIAQQRqKAIAIAAoAggiA2tLBEAgACADIAIQhAEgACgCCCEDCyAAKAIAIANqIAEgAhCLAhogACACIANqNgIIQQALGgAgACABQbj8wAAoAgAiAEHSACAAGxECAAALQAEBfyMAQSBrIgAkACAAQRxqQQA2AgAgAEH42cAANgIYIABCATcCDCAAQajawAA2AgggAEEIakGw2sAAENQBAAvpAwEGfyMAQTBrIgUkAAJAAkACQAJAAkAgASgCBCIDBEAgASgCACEHIANBAWtB/////wFxIgNBAWoiBkEHcSEEAn8gA0EHSQRAQQAhAyAHDAELIAdBPGohAiAGQfj///8DcSEGQQAhAwNAIAIoAgAgAkEIaygCACACQRBrKAIAIAJBGGsoAgAgAkEgaygCACACQShrKAIAIAJBMGsoAgAgAkE4aygCACADampqampqamohAyACQUBrIQIgBkEIayIGDQALIAJBPGsLIQIgBARAIAJBBGohAgNAIAIoAgAgA2ohAyACQQhqIQIgBEEBayIEDQALCyABQRRqKAIADQEgAyEEDAMLQQAhAyABQRRqKAIADQFBASECDAQLIAcoAgQNACADQRBJDQILIAMgA2oiBCADSQ0BCyAERQ0AAkAgBEF/SgRAIARBARA9IgJFDQEgBCEDDAMLEM8BAAsgBEEBEM4BAAtBASECQQAhAwsgAEEANgIIIAAgAzYCBCAAIAI2AgAgBSAANgIMIAVBIGogAUEQaikCADcDACAFQRhqIAFBCGopAgA3AwAgBSABKQIANwMQIAVBDGpB0NnAACAFQRBqEN4BBEBBwNrAAEEzIAVBKGpB9NrAAEGc28AAEOkBAAsgBUEwaiQAC2cBAn8gASgCACEDAkACQAJAIAFBCGooAgAiAUUEQEEBIQIMAQsgAUF/TA0BIAFBARA9IgJFDQILIAIgAyABEIsCIQIgACABNgIIIAAgATYCBCAAIAI2AgAPCxDPAQALIAFBARDOAQALUwEBfyMAQRBrIgIkACACIAA2AgggAiAAQQxqNgIMIAFBzNzAAEENQbDcwABBBSACQQhqQaDcwABBtdzAAEEFIAJBDGpBvNzAABD7ASACQRBqJAALDgAgACgCABoDQAwACwAL4QIBAn8jAEEgayICJAAgAkEBOgAYIAIgATYCFCACIAA2AhAgAkHQ38AANgIMIAJB3NzAADYCCCMAQRBrIgEkAAJAIAJBCGoiACgCDCICBEAgACgCCCIDRQ0BIAEgAjYCCCABIAA2AgQgASADNgIAIwBBEGsiACQAIABBCGogAUEIaigCADYCACAAIAEpAgA3AwAjAEEQayIBJAAgACgCACICQRRqKAIAIQMCQAJ/AkACQCACKAIEDgIAAQMLIAMNAkEAIQJB+NbAAAwBCyADDQEgAigCACIDKAIEIQIgAygCAAshAyABIAI2AgQgASADNgIAIAFBvNnAACAAKAIEIgEoAgggACgCCCABLQAQELIBAAsgAUEANgIEIAEgAjYCACABQajZwAAgACgCBCIBKAIIIAAoAgggAS0AEBCyAQALQfjWwABBK0H42MAAENkBAAtB+NbAAEErQejYwAAQ2QEAC28BAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQRxqQQI2AgAgA0EsakHKADYCACADQgI3AgwgA0H83sAANgIIIANBygA2AiQgAyADQSBqNgIYIAMgAzYCKCADIANBBGo2AiAgA0EIaiACENQBAAtvAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0EcakECNgIAIANBLGpBygA2AgAgA0ICNwIMIANBkOTAADYCCCADQcoANgIkIAMgA0EgajYCGCADIANBBGo2AiggAyADNgIgIANB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AAgAAAAUAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvZXhwb3J0cy5ycwAAAAABEABhAAAAjQAAAA0AAAAAARAAYQAAAG8AAAANAAAAAAEQAGEAAADqAAAADQAAAHdhc21jdXN0b21iYW5rQmFua01zZ2J1cm5zZW5kdG9fYWRkcmVzc1dhc21Nc2djbGVhcl9hZG1pbmNvbnRyYWN0X2FkZHJ1cGRhdGVfYWRtaW5hZG1pbm1pZ3JhdGVuZXdfY29kZV9pZG1zZ2luc3RhbnRpYXRlY29kZV9pZGxhYmVsZXhlY3V0ZVN1Yk1zZ2dhc19saW1pdFJlcGx5T25uZXZlcnN1Y2Nlc3NlcnJvcmFsd2F5c29rRW1wdHlFdmVudHR5cGVhdHRyaWJ1dGVzQXR0cmlidXRla2V5dmFsdWVSZXNwb25zZWV2ZW50c0NvbnRyYWN0VmVyc2lvbnZlcnNpb25jb250cmFjdF9pbmZvABUAAAAMAAAABAAAABYAAAAXAAAAGAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkABQAAAAAAAAABAAAAGQAAAC9ydXN0Yy84OTdlMzc1NTNiYmE4YjQyNzUxYzY3NjU4OTY3ODg5ZDExZWNkMTIwL2xpYnJhcnkvYWxsb2Mvc3JjL3N0cmluZy5ycwAIAxAASwAAAM4JAAAJAAAAY3dfY291bnRlcjo6bXNnOjpFeGVjdXRlTXNnY3dfY291bnRlcjo6bXNnOjpHZXRDb3VudFJlc3BvbnNlY3dfY291bnRlcjo6bXNnOjpRdWVyeU1zZ2Nvc213YXNtX3N0ZDo6cmVzdWx0czo6Y29udHJhY3RfcmVzdWx0OjpDb250cmFjdFJlc3VsdDxjb3Ntd2FzbV9zdGQ6OnJlc3VsdHM6OnJlc3BvbnNlOjpSZXNwb25zZT5jb3Ntd2FzbV9zdGQ6OnJlc3VsdHM6OmNvbnRyYWN0X3Jlc3VsdDo6Q29udHJhY3RSZXN1bHQ8Y29zbXdhc21fc3RkOjpiaW5hcnk6OkJpbmFyeT5jb3Ntd2FzbV9zdGQ6OnR5cGVzOjpNZXNzYWdlSW5mb2Nvc213YXNtX3N0ZDo6dHlwZXM6OkVudmN3X2NvdW50ZXI6OnN0YXRlOjpTdGF0ZWN3X2NvdW50ZXI6Om1zZzo6SW5zdGFudGlhdGVNc2djdzI6OkNvbnRyYWN0VmVyc2lvbgAAAAUAAAAEAAAABAAAABoAAAAbAAAAHAAAAG1pc3NpbmcgZmllbGQgYGAMBRAADwAAABsFEAABAAAAdW5rbm93biBmaWVsZCBgYCwgZXhwZWN0ZWQgACwFEAAPAAAAOwUQAAwAAABgLCB0aGVyZSBhcmUgbm8gZmllbGRzAAAsBRAADwAAAFgFEAAWAAAAZHVwbGljYXRlIGZpZWxkIGAAAACABRAAEQAAABsFEAABAAAAdW5rbm93biB2YXJpYW50IGAAAACkBRAAEQAAADsFEAAMAAAAaW52YWxpZCBVaW50NjQgJycgLSDIBRAAEAAAANgFEAAEAAAAaW52YWxpZCBVaW50MTI4ICcAAADsBRAAEQAAANgFEAAEAAAAdWxsc3RhdGVhY3Rpb25pbmNyZW1lbnRzcmMvY29udHJhY3QucnMAACcGEAAPAAAANAAAAA0AAAByZXNldGNyYXRlcy5pbzpjdy1jb3VudGVyMC4xLjBtZXRob2Rvd25lcmNvdW50VW5hdXRob3JpemVkAAB2BhAADAAAAAwFEAAAAAAAcQYQAAUAAAAeBhAACQAAAEgGEAAFAAAAZ2V0X2NvdW50AAAArAYQAAkAAABHZXRDb3VudFJlc3BvbnNlU3RhdGUvcnVzdGMvODk3ZTM3NTUzYmJhOGI0Mjc1MWM2NzY1ODk2Nzg4OWQxMWVjZDEyMC9saWJyYXJ5L2NvcmUvc3JjL2l0ZXIvYWRhcHRlcnMvZW51bWVyYXRlLnJz1QYQAFsAAAAwAAAACQAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3cAAAAAYXR0ZW1wdCB0byBtdWx0aXBseSB3aXRoIG92ZXJmbG93AAAAKAAAAAgAAAAEAAAAKQAAACoAAAArAAAADAAAAAQAAAAsAAAALQAAAC4AAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5ACgAAAAAAAAAAQAAABkAAAAvcnVzdGMvODk3ZTM3NTUzYmJhOGI0Mjc1MWM2NzY1ODk2Nzg4OWQxMWVjZDEyMC9saWJyYXJ5L2FsbG9jL3NyYy9zdHJpbmcucnMA+AcQAEsAAADOCQAACQAAAGNvc213YXNtX3N0ZDo6cmVzdWx0czo6c3lzdGVtX3Jlc3VsdDo6U3lzdGVtUmVzdWx0PGNvc213YXNtX3N0ZDo6cmVzdWx0czo6Y29udHJhY3RfcmVzdWx0OjpDb250cmFjdFJlc3VsdDxjb3Ntd2FzbV9zdGQ6OmJpbmFyeTo6QmluYXJ5Pj4oAAAABAAAAAQAAAAvAAAAMAAAADEAAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlOiAAAPQIEAAqAAAAL3J1c3RjLzg5N2UzNzU1M2JiYThiNDI3NTFjNjc2NTg5Njc4ODlkMTFlY2QxMjAvbGlicmFyeS9jb3JlL3NyYy9pdGVyL3RyYWl0cy9hY2N1bS5ycwAAACgJEABVAAAAjQAAAAEAAABtaXNzaW5nIGZpZWxkIGBgkAkQAA8AAACfCRAAAQAAAGR1cGxpY2F0ZSBmaWVsZCBgAAAAsAkQABEAAACfCRAAAQAAAHVua25vd24gdmFyaWFudCBgYCwgZXhwZWN0ZWQgAAAA1AkQABEAAADlCRAADAAAACgAAAAEAAAABAAAADIAAAAvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZGVjb2RlLnJzABQKEABbAAAAbgAAAC8AAABhdHRlbXB0IHRvIHN1YnRyYWN0IHdpdGggb3ZlcmZsb3cAAAAUChAAWwAAAAMBAAA3AAAAFAoQAFsAAAADAQAAJAAAABQKEABbAAAABAEAACkAAAAUChAAWwAAACEBAAARAAAAFAoQAFsAAAAqAQAAKQAAABQKEABbAAAAKgEAABYAAAAUChAAWwAAAC4BAAApAAAAFAoQAFsAAAAuAQAAKAAAABQKEABbAAAALQEAABoAAAAUChAAWwAAADMBAAARAAAAFAoQAFsAAABBAQAADgAAABQKEABbAAAARAEAACcAAAAUChAAWwAAAEQBAAASAAAAFAoQAFsAAABHAQAACQAAABQKEABbAAAAWAEAABMAAAAUChAAWwAAAGYBAAApAAAAFAoQAFsAAAB4AQAADQAAABQKEABbAAAAggEAABEAAAAUChAAWwAAAIoBAAAVAAAAFAoQAFsAAACOAQAAMQAAAEltcG9zc2libGU6IG11c3Qgb25seSBoYXZlIDAgdG8gOCBpbnB1dCBieXRlcyBpbiBsYXN0IGNodW5rLCB3aXRoIG5vIGludmFsaWQgbGVuZ3Roc+QLEABUAAAAFAoQAFsAAACdAQAADgAAABQKEABbAAAAqAEAAA0AAAAUChAAWwAAALEBAAAJAAAAT3ZlcmZsb3cgd2hlbiBjYWxjdWxhdGluZyBvdXRwdXQgYnVmZmVyIGxlbmd0aAAAFAoQAFsAAACTAAAAIAAAABQKEABbAAAAJwIAAAUAAABJbnZhbGlkIFVURjgrAAAAFAAAAAQAAAAzAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Jhc2U2NC0wLjEzLjAvc3JjL2VuY29kZS5ycwDcDBAAWwAAADQAAAAFAAAAaW50ZWdlciBvdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIGJ1ZmZlciBzaXplAAAA3AwQAFsAAAAvAAAAEQAAACgAAAAIAAAABAAAADQAAAD0CBAAAAAAAGludmFsaWQgYmFzZTY0OiCgDRAAEAAAACgAAAAAAAAAAQAAADUAAAA2AAAANgAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9jb3Ntd2FzbS1zdGQtMS4xLjkvc3JjL3NlY3Rpb25zLnJzAADQDRAAYgAAABoAAAAQAAAA0A0QAGIAAAAaAAAABQAAANANEABiAAAAOQAAABgAAABDYW5ub3QgcmVhZCBzZWN0aW9uIGxlbmd0aAAAZA4QABoAAADQDRAAYgAAADcAAAAJAAAAVEw7RFI6IFZhbHVlIG11c3Qgbm90IGJlIGVtcHR5IGluIFN0b3JhZ2U6OnNldCBidXQgaW4gbW9zdCBjYXNlcyB5b3UgY2FuIHVzZSBTdG9yYWdlOjpyZW1vdmUgaW5zdGVhZC4gTG9uZyBzdG9yeTogR2V0dGluZyBlbXB0eSB2YWx1ZXMgZnJvbSBzdG9yYWdlIGlzIG5vdCB3ZWxsIHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50LiBTb21lIG9mIG91ciBpbnRlcm5hbCBpbnRlcmZhY2VzIGNhbm5vdCBkaWZmZXJlbnRpYXRlIGJldHdlZW4gYSBub24tZXhpc3RlbnQga2V5IGFuZCBhbiBlbXB0eSB2YWx1ZS4gUmlnaHQgbm93LCB5b3UgY2Fubm90IHJlbHkgb24gdGhlIGJlaGF2aW91ciBvZiBlbXB0eSB2YWx1ZXMuIFRvIHByb3RlY3QgeW91IGZyb20gdHJvdWJsZSBsYXRlciBvbiwgd2Ugc3RvcCBoZXJlLiBTb3JyeSBmb3IgdGhlIGluY29udmVuaWVuY2UhIFdlIGhpZ2hseSB3ZWxjb21lIHlvdSB0byBjb250cmlidXRlIHRvIENvc21XYXNtLCBtYWtpbmcgdGhpcyBtb3JlIHNvbGlkIG9uZSB3YXkgb3IgdGhlIG90aGVyLpgOEAAIAgAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvaW1wb3J0cy5ycwAAAKgQEABhAAAAawAAAA0AAAAoAAAABAAAAAQAAAA3AAAAOAAAADkAAAA6AAAAaW5wdXQgdG9vIGxvbmcgZm9yIGFkZHJfdmFsaWRhdGVhZGRyX3ZhbGlkYXRlIGVycm9yZWQ6IABYERAAFwAAAGlucHV0IHRvbyBsb25nIGZvciBhZGRyX2Nhbm9uaWNhbGl6ZWFkZHJfY2Fub25pY2FsaXplIGVycm9yZWQ6IACcERAAGwAAAGFkZHJfaHVtYW5pemUgZXJyb3JlZDogAMAREAAXAAAATWVzc2FnZVRvb0xvbmcgbXVzdCBub3QgaGFwcGVuLiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS7gERAAOAAAAKgQEABhAAAACAEAABIAAACoEBAAYQAAACUBAAASAAAASW52YWxpZEhhc2hGb3JtYXQgbXVzdCBub3QgaGFwcGVuLiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS4AQBIQADsAAACoEBAAYQAAAD8BAAASAAAARXJyb3IgY29kZSAyIHVudXNlZCBzaW5jZSBDb3NtV2FzbSAwLjE1LiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS4AAACUEhAAQQAAAKgQEABhAAAAPgEAABIAAACoEBAAYQAAAF8BAAASAAAAqBAQAGEAAABeAQAAEgAAAFJlZ2lvbiBwb2ludGVyIGlzIG51bGwAABATEAAWAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvbWVtb3J5LnJzMBMQAGAAAAA5AAAABQAAAFJlZ2lvbiBzdGFydHMgYXQgbnVsbCBwb2ludGVyAAAAoBMQAB0AAAAwExAAYAAAAD8AAAAFAAAAVW5rbm93biBlcnJvcjogANgTEAAPAAAASW52YWxpZCByZWNvdmVyeSBwYXJhbWV0ZXIuIFN1cHBvcnRlZCB2YWx1ZXM6IDAgYW5kIDEuAADwExAANgAAAEludmFsaWQgc2lnbmF0dXJlIGZvcm1hdDAUEAAYAAAASW52YWxpZCBoYXNoIGZvcm1hdABQFBAAEwAAAFVua25vd25FcnJlcnJvcl9jb2RlKAAAAAQAAAAEAAAAOwAAAEludmFsaWRSZWNvdmVyeVBhcmFtSW52YWxpZFNpZ25hdHVyZUZvcm1hdEludmFsaWRIYXNoRm9ybWF0Q29udmVyc2lvbiBlcnJvcjogAAAAyxQQABIAAABEaXZpZGUgYnkgemVybzog6BQQABAAAABPdmVyZmxvdzogAAAAFRAACgAAAEVycm9yIHNlcmlhbGl6aW5nIHR5cGUgOiAAAAAUFRAAFwAAACsVEAACAAAARXJyb3IgcGFyc2luZyBpbnRvIHR5cGUgQBUQABgAAAArFRAAAgAAACBub3QgZm91bmQAAPQIEAAAAAAAaBUQAAoAAABDYW5ub3QgZGVjb2RlIFVURjggYnl0ZXMgaW50byBzdHJpbmc6IAAAhBUQACYAAABJbnZhbGlkIGhleCBzdHJpbmc6ILQVEAAUAAAASW52YWxpZCBkYXRhIHNpemU6IGV4cGVjdGVkPSBhY3R1YWw90BUQABwAAADsFRAACAAAAEludmFsaWQgQmFzZTY0IHN0cmluZzogAAQWEAAXAAAAR2VuZXJpYyBlcnJvcjogACQWEAAPAAAAUmVjb3ZlciBwdWJrZXkgZXJyb3I6IAAAPBYQABYAAABWZXJpZmljYXRpb24gZXJyb3I6IFwWEAAUAAAAQ29udmVyc2lvbk92ZXJmbG93c291cmNlKAAAAAQAAAAEAAAAPAAAAERpdmlkZUJ5WmVybygAAAAEAAAABAAAAD0AAABPdmVyZmxvdygAAAAEAAAABAAAAD4AAABTZXJpYWxpemVFcnJzb3VyY2VfdHlwZW1zZ1BhcnNlRXJydGFyZ2V0X3R5cGVOb3RGb3VuZGtpbmRJbnZhbGlkVXRmOEludmFsaWRIZXhJbnZhbGlkRGF0YVNpemVleHBlY3RlZAAAACgAAAAEAAAABAAAAD8AAABhY3R1YWxJbnZhbGlkQmFzZTY0R2VuZXJpY0VyclJlY292ZXJQdWJrZXlFcnIAAAAoAAAABAAAAAQAAABAAAAAVmVyaWZpY2F0aW9uRXJyACgAAAAEAAAABAAAAEEAAABTaGxTaHJQb3dNdWxTdWJBZGRDYW5ub3QgIHdpdGggIGFuZCC+FxAABwAAAMUXEAAGAAAAyxcQAAUAAABPdmVyZmxvd0Vycm9yb3BlcmF0aW9uAAAoAAAABAAAAAQAAAAdAAAAb3BlcmFuZDFvcGVyYW5kMkNvbnZlcnNpb25PdmVyZmxvd0Vycm9yACgAAAAEAAAABAAAAEIAAAB2YWx1ZUNhbm5vdCBkZXZpZGUgIGJ5IHplcm8ATRgQAA4AAABbGBAACAAAAERpdmlkZUJ5WmVyb0Vycm9yb3BlcmFuZGludmFsaWRfcmVxdWVzdGludmFsaWRfcmVzcG9uc2Vub19zdWNoX2NvbnRyYWN0dW5rbm93bnVuc3VwcG9ydGVkX3JlcXVlc3QAAACMGBAADwAAAJsYEAAQAAAAqxgQABAAAAC7GBAABwAAAMIYEAATAAAAYWRkcmVycm9ycmVzcG9uc2VyZXF1ZXN0SW52YWxpZCBwdWJsaWMga2V5IGZvcm1hdAAAABgZEAAZAAAAR2VuZXJpYyBlcnJvcgAAADwZEAANAAAAQmF0Y2ggZXJyb3IAVBkQAAsAAABJbnZhbGlkUHVia2V5Rm9ybWF0QmF0Y2hFcnJvawAAAIMZEAACAAAABBkQAAUAAAC7FxAAuBcQALUXEACyFxAArxcQAKwXEABFAAAACAAAAAQAAABGAAAARwAAAEUAAAAIAAAABAAAAEgAAADEGRAAAAAAAEpTT04gaGFzIGEgY29tbWEgYWZ0ZXIgdGhlIGxhc3QgdmFsdWUgaW4gYW4gYXJyYXkgb3IgbWFwLkpTT04gaGFzIG5vbi13aGl0ZXNwYWNlIHRyYWlsaW5nIGNoYXJhY3RlcnMgYWZ0ZXIgdGhlIHZhbHVlLkZvdW5kIGEgbG9uZSBzdXJyb2dhdGUsIHdoaWNoIGNhbiBleGlzdCBpbiBKU09OIGJ1dCBjYW5ub3QgYmUgZW5jb2RlZCB0byBVVEYtOC5PYmplY3Qga2V5IGlzIG5vdCBhIHN0cmluZy5JbnZhbGlkIHVuaWNvZGUgY29kZSBwb2ludC5JbnZhbGlkIHR5cGVJbnZhbGlkIG51bWJlci5JbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS5FeHBlY3RlZCB0aGlzIGNoYXJhY3RlciB0byBzdGFydCBhIEpTT04gdmFsdWUuRXhwZWN0ZWQgdG8gcGFyc2UgZWl0aGVyIGEgYHRydWVgLCBgZmFsc2VgLCBvciBhIGBudWxsYC5FeHBlY3RlZCB0aGlzIGNoYXJhY3RlciB0byBiZSBlaXRoZXIgYSBgJywnYCBvciBhIGAnfSdgLkV4cGVjdGVkIGEgbG93IHN1cnJvZ2F0ZSAoREMwMOKAk0RGRkYpLkV4cGVjdGVkIHRoaXMgY2hhcmFjdGVyIHRvIGJlIGVpdGhlciBhIGAnLCdgIG9yYSBgJ10nYC5FeHBlY3RlZCBhIGhpZ2ggc3Vycm9nYXRlIChEODAw4oCTREJGRikuRXhwZWN0ZWQgdGhpcyBjaGFyYWN0ZXIgdG8gYmUgYSBgJzonYC5FT0Ygd2hpbGUgcGFyc2luZyBhIEpTT04gdmFsdWUuRU9GIHdoaWxlIHBhcnNpbmcgYSBzdHJpbmcuRU9GIHdoaWxlIHBhcnNpbmcgYW4gb2JqZWN0LkVPRiB3aGlsZSBwYXJzaW5nIGEgbGlzdC5Db250cm9sIGNoYXJhY3RlciBmb3VuZCBpbiBzdHJpbmcuL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3NlcmRlLWpzb24td2FzbS0wLjQuMS9zcmMvZGUvdW5lc2NhcGUucnPkHBAAaAAAACUAAAAVAAAAAAAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3fkHBAAaAAAADMAAAApAAAAAAAAAGF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvd05vbi1oZXggQVNDSUkgY2hhcmFjdGVyIGZvdW5kAADkHBAAaAAAAJkAAAAOAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3NlcmRlLWpzb24td2FzbS0wLjQuMS9zcmMvZGUvbW9kLnJzAOAdEABjAAAAJAAAAAkAAADgHRAAYwAAAH0AAAAiAAAA4B0QAGMAAACBAAAALAAAAEJ1ZmZlciBpcyBmdWxsAAB0HhAADgAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS1qc29uLXdhc20tMC40LjEvc3JjL3Nlci9tb2QucnOMHhAAZAAAALUAAAAJAAAAjB4QAGQAAADXAAAACQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGU6IAAAEB8QACoAQdC+wAALIWF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvdwBBgL/AAAv0JmF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3cvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZW5jb2RlLnJzAJwfEABbAAAAkgAAACcAAAB1c2l6ZSBvdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIGI2NCBsZW5ndGgAAJwfEABbAAAAlwAAABkAAACcHxAAWwAAALYAAAAgAAAAnB8QAFsAAAC3AAAAOgAAAJwfEABbAAAAtwAAACUAAACcHxAAWwAAAPcAAAAYAAAAnB8QAFsAAAD8AAAALwAAAJwfEABbAAAA/AAAABwAAACcHxAAWwAAAP0AAAA2AAAAnB8QAFsAAAD9AAAAIQAAAJwfEABbAAAAEwEAAC4AAACcHxAAWwAAABMBAAAJAAAAnB8QAFsAAAAUAQAACQAAAJwfEABbAAAACwEAAC4AAACcHxAAWwAAAAsBAAAJAAAAnB8QAFsAAAANAQAADwAAAJwfEABbAAAADAEAAAkAAACcHxAAWwAAAA8BAAAJAAAAnB8QAFsAAAARAQAACQAAAEltcG9zc2libGUgcmVtYWluZGVyVCEQABQAAACcHxAAWwAAACoBAAAWAAAAnB8QAFsAAAA7AQAACQAAAEludmFsaWQgbGFzdCBzeW1ib2wgLCBvZmZzZXQgLgAAkCEQABQAAACkIRAACQAAAK0hEAABAAAARW5jb2RlZCB0ZXh0IGNhbm5vdCBoYXZlIGEgNi1iaXQgcmVtYWluZGVyLgDIIRAAKwAAAEludmFsaWQgYnl0ZSAAAAD8IRAADQAAAKQhEAAJAAAArSEQAAEAAABPdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIG51bWJlciBvZiBjaHVua3MgaW4gaW5wdXQvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZGVjb2RlLnJzAABXIhAAWwAAALkAAAAFAAAAISIjJCUmJygpKissLTAxMjM0NTY3ODlAQUJDREVGR0hJSktMTU5QUVJTVFVWWFlaW2BhYmNkZWhpamtsbXBxckFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5KywuL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Li8wMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5LV9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsv////////////////////////////////////////////AAECAwQFBgcICQoLDP//DQ4PEBESExQVFv///////xcYGRobHB0eHyAhIiMkJf8mJygpKiss/y0uLzD/////MTIzNDU2//83ODk6Ozz//z0+P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8+P////zQ1Njc4OTo7PD3/////////AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBn///////8aGxwdHh8gISIjJCUmJygpKissLS4vMDEyM///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAE2Nzg5Ojs8PT4//////////wIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob////////HB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDX//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wABAgMEBQYHCAkKC/////////8MDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJf///////yYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z7//zQ1Njc4OTo7PD3/////////AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBn/////P/8aGxwdHh8gISIjJCUmJygpKissLS4vMDEyM///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Pv///z80NTY3ODk6Ozw9/////////wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ////////GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////BCQQAMQjEACEIxAARCMQAAQjEADEIhAARCkQAEQoEABEJxAARCYQAEQlEABEJBAATgAAAAgAAAAEAAAATwAAAFAAAABOAAAACAAAAAQAAABRAAAAYG9uZSBvZiCZKhAABwAAACwgAACoKhAAAgAAAJgqEAABAAAAmCoQAAEAAABgIG9yIGAAAJgqEAABAAAAxCoQAAYAAACYKhAAAQAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS0xLjAuMTUwL3NyYy9kZS9tb2QucnNleHBsaWNpdCBwYW5pYwAAAOQqEABbAAAA7QgAABIAAABTAAAABAAAAAQAAABUAAAAVQAAAFYAAABjYWxsZWQgYE9wdGlvbjo6dW53cmFwKClgIG9uIGEgYE5vbmVgIHZhbHVlbWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAoAAKMrEAAVAAAAuCsQAA4AAABsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnPYKxAAGAAAAFUBAAAJAAAAY2Fubm90IG1vZGlmeSB0aGUgcGFuaWMgaG9vayBmcm9tIGEgcGFuaWNraW5nIHRocmVhZAAsEAA0AAAAbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5yczwsEAAcAAAAfQAAAAkAAAA8LBAAHAAAAEcCAAAPAAAAPCwQABwAAABGAgAADwAAAFcAAAAMAAAABAAAAFgAAABTAAAACAAAAAQAAABZAAAAWgAAABAAAAAEAAAAWwAAAFwAAABTAAAACAAAAAQAAABdAAAAXgAAAF8AAAAEAAAABAAAAGAAAABhAAAAYgAAAF8AAAAEAAAABAAAAGMAAABsaWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJzY2FwYWNpdHkgb3ZlcmZsb3cAAAAULRAAEQAAAPgsEAAcAAAABgIAAAUAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IAXwAAAAAAAAABAAAAGQAAAGxpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5yc4QtEAAYAAAAZAIAAAkAAAApbGlicmFyeS9hbGxvYy9zcmMvdmVjL21vZC5ycykgc2hvdWxkIGJlIDw9IGxlbiAoaXMgYGF0YCBzcGxpdCBpbmRleCAoaXMgAAAA4C0QABUAAADJLRAAFwAAAKwtEAABAAAArS0QABwAAADLBwAADQAAAF8AAAAEAAAABAAAAGQAAABieXRlc2Vycm9yAABfAAAABAAAAAQAAABlAAAARnJvbVV0ZjhFcnJvcgAAAGNhbGxlZCBgT3B0aW9uOjp1bndyYXAoKWAgb24gYSBgTm9uZWAgdmFsdWVudW1iZXIgd291bGQgYmUgemVybyBmb3Igbm9uLXplcm8gdHlwZW51bWJlciB0b28gc21hbGwgdG8gZml0IGluIHRhcmdldCB0eXBlbnVtYmVyIHRvbyBsYXJnZSB0byBmaXQgaW4gdGFyZ2V0IHR5cGVpbnZhbGlkIGRpZ2l0IGZvdW5kIGluIHN0cmluZ2Nhbm5vdCBwYXJzZSBpbnRlZ2VyIGZyb20gZW1wdHkgc3RyaW5nKS4uAD0vEAACAAAAaW5kZXggb3V0IG9mIGJvdW5kczogdGhlIGxlbiBpcyAgYnV0IHRoZSBpbmRleCBpcyAAAEgvEAAgAAAAaC8QABIAAAA6AAAAXC4QAAAAAACMLxAAAQAAAIwvEAABAAAAcGFuaWNrZWQgYXQgJycsILQvEAABAAAAtS8QAAMAAABcLhAAAAAAAG0AAAAAAAAAAQAAAG4AAABgOiAAXC4QAAAAAADhLxAAAgAAAG0AAAAMAAAABAAAAG8AAABwAAAAcQAAACAgICAgewosCiwgIHsgfSB9KAooLApbAG0AAAAEAAAABAAAAHIAAABdbGlicmFyeS9jb3JlL3NyYy9mbXQvbnVtLnJzNTAQABsAAABlAAAAFAAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlhc3NlcnRpb24gZmFpbGVkOiAqY3VyciA+IDE5AAA1MBAAGwAAAOUBAAAFAAAAbQAAAAQAAAAEAAAAcwAAAHQAAAB1AAAAbGlicmFyeS9jb3JlL3NyYy9mbXQvbW9kLnJzAHAxEAAbAAAAdAkAAB4AAABwMRAAGwAAAHsJAAAWAAAAbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tZW1jaHIucnOsMRAAIAAAAGgAAAAnAAAAcmFuZ2Ugc3RhcnQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoINwxEAASAAAA7jEQACIAAAByYW5nZSBlbmQgaW5kZXggIDIQABAAAADuMRAAIgAAAHNsaWNlIGluZGV4IHN0YXJ0cyBhdCAgYnV0IGVuZHMgYXQgAEAyEAAWAAAAVjIQAA0AAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBtubAAAszAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwMDAwMDAwMDAwMDAwMDAwQEBAQEAEH05sAAC78VWy4uLl1ieXRlIGluZGV4ICBpcyBvdXQgb2YgYm91bmRzIG9mIGAAAHkzEAALAAAAhDMQABYAAADgLxAAAQAAAGJlZ2luIDw9IGVuZCAoIDw9ICkgd2hlbiBzbGljaW5nIGAAALQzEAAOAAAAwjMQAAQAAADGMxAAEAAAAOAvEAABAAAAIGlzIG5vdCBhIGNoYXIgYm91bmRhcnk7IGl0IGlzIGluc2lkZSAgKGJ5dGVzICkgb2YgYHkzEAALAAAA+DMQACYAAAAeNBAACAAAACY0EAAGAAAA4C8QAAEAAABsaWJyYXJ5L2NvcmUvc3JjL3N0ci9tb2QucnMAVDQQABsAAAAHAQAAHQAAAGxpYnJhcnkvY29yZS9zcmMvdW5pY29kZS9wcmludGFibGUucnMAAACANBAAJQAAAAoAAAAcAAAAgDQQACUAAAAaAAAAKAAAAAABAwUFBgYCBwYIBwkRChwLGQwaDRAODQ8EEAMSEhMJFgEXBBgBGQMaBxsBHAIfFiADKwMtCy4BMAMxAjIBpwKpAqoEqwj6AvsF/QL+A/8JrXh5i42iMFdYi4yQHN0OD0tM+/wuLz9cXV/ihI2OkZKpsbq7xcbJyt7k5f8ABBESKTE0Nzo7PUlKXYSOkqmxtLq7xsrOz+TlAAQNDhESKTE0OjtFRklKXmRlhJGbncnOzw0RKTo7RUlXW1xeX2RljZGptLq7xcnf5OXwDRFFSWRlgISyvL6/1dfw8YOFi6Smvr/Fx87P2ttImL3Nxs7PSU5PV1leX4mOj7G2t7/BxsfXERYXW1z29/7/gG1x3t8OH25vHB1ffX6ur3+7vBYXHh9GR05PWFpcXn5/tcXU1dzw8fVyc490dZYmLi+nr7e/x8/X35pAl5gwjx/S1M7/Tk9aWwcIDxAnL+7vbm83PT9CRZCRU2d1yMnQ0djZ5/7/ACBfIoLfBIJECBsEBhGBrA6AqwUfCYEbAxkIAQQvBDQEBwMBBwYHEQpQDxIHVQcDBBwKCQMIAwcDAgMDAwwEBQMLBgEOFQVOBxsHVwcCBhYNUARDAy0DAQQRBg8MOgQdJV8gbQRqJYDIBYKwAxoGgv0DWQcWCRgJFAwUDGoGCgYaBlkHKwVGCiwEDAQBAzELLAQaBgsDgKwGCgYvMU0DgKQIPAMPAzwHOAgrBYL/ERgILxEtAyEPIQ+AjASClxkLFYiUBS8FOwcCDhgJgL4idAyA1hoMBYD/BYDfDPKdAzcJgVwUgLgIgMsFChg7AwoGOAhGCAwGdAseA1oEWQmAgxgcChYJTASAigarpAwXBDGhBIHaJgcMBQWAphCB9QcBICoGTASAjQSAvgMbAw8NAAYBAQMBBAIFBwcCCAgJAgoFCwIOBBABEQISBRMRFAEVAhcCGQ0cBR0IJAFqBGsCrwO8As8C0QLUDNUJ1gLXAtoB4AXhAucE6ALuIPAE+AL6AvsBDCc7Pk5Pj56en3uLk5aisrqGsQYHCTY9Plbz0NEEFBg2N1ZXf6qur7014BKHiY6eBA0OERIpMTQ6RUZJSk5PZGVctrcbHAcICgsUFzY5Oqip2NkJN5CRqAcKOz5maY+Sb1+/7u9aYvT8/5qbLi8nKFWdoKGjpKeorbq8xAYLDBUdOj9FUaanzM2gBxkaIiU+P+fs7//FxgQgIyUmKDM4OkhKTFBTVVZYWlxeYGNlZmtzeH1/iqSqr7DA0K6vbm+TXiJ7BQMELQNmAwEvLoCCHQMxDxwEJAkeBSsFRAQOKoCqBiQEJAQoCDQLTkOBNwkWCggYO0U5A2MICTAWBSEDGwUBQDgESwUvBAoHCQdAICcEDAk2AzoFGgcEDAdQSTczDTMHLggKgSZSTigIKhYaJhwUFwlOBCQJRA0ZBwoGSAgnCXULP0EqBjsFCgZRBgEFEAMFgItiHkgICoCmXiJFCwoGDRM6Bgo2LAQXgLk8ZFMMSAkKRkUbSAhTDUmBB0YKHQNHSTcDDggKBjkHCoE2GYC3AQ8yDYObZnULgMSKTGMNhC+P0YJHobmCOQcqBFwGJgpGCigFE4KwW2VLBDkHEUAFCwIOl/gIhNYqCaLngTMtAxEECIGMiQRrBQ0DCQcQkmBHCXQ8gPYKcwhwFUaAmhQMVwkZgIeBRwOFQg8VhFAfgOErgNUtAxoEAoFAHxE6BQGE4ID3KUwECgQCgxFETD2AwjwGAQRVBRs0AoEOLARkDFYKgK44HQ0sBAkHAg4GgJqD2AUQAw0DdAxZBwwEAQ8MBDgICgYoCCJOgVQMFQMFAwcJHQMLBQYKCgYICAcJgMslCoQGbGlicmFyeS9jb3JlL3NyYy91bmljb2RlL3VuaWNvZGVfZGF0YS5ycwAAADE6EAAoAAAAVwAAAD4AAABTb21lTm9uZW0AAAAEAAAABAAAAHYAAABFcnJvclV0ZjhFcnJvcnZhbGlkX3VwX3RvZXJyb3JfbGVuAABtAAAABAAAAAQAAAB3AAAAAAMAAIMEIACRBWAAXROgABIXIB8MIGAf7yygKyowICxvpuAsAqhgLR77YC4A/iA2nv9gNv0B4TYBCiE3JA3hN6sOYTkvGKE5MBzhR/MeIUzwauFPT28hUJ28oVAAz2FRZdGhUQDaIVIA4OFTMOFhVa7ioVbQ6OFWIABuV/AB/1cAcAAHAC0BAQECAQIBAUgLMBUQAWUHAgYCAgEEIwEeG1sLOgkJARgEAQkBAwEFKwM8CCoYASA3AQEBBAgEAQMHCgIdAToBAQECBAgBCQEKAhoBAgI5AQQCBAICAwMBHgIDAQsCOQEEBQECBAEUAhYGAQE6AQECAQQIAQcDCgIeATsBAQEMAQkBKAEDATcBAQMFAwEEBwILAh0BOgECAQIBAwEFAgcCCwIcAjkCAQECBAgBCQEKAh0BSAEEAQIDAQEIAVEBAgcMCGIBAgkLBkoCGwEBAQEBNw4BBQECBQsBJAkBZgQBBgECAgIZAgQDEAQNAQICBgEPAQADAAMdAh4CHgJAAgEHCAECCwkBLQMBAXUCIgF2AwQCCQEGA9sCAgE6AQEHAQEBAQIIBgoCATAfMQQwBwEBBQEoCQwCIAQCAgEDOAEBAgMBAQM6CAICmAMBDQEHBAEGAQMCxkAAAcMhAAONAWAgAAZpAgAEAQogAlACAAEDAQQBGQIFAZcCGhINASYIGQsuAzABAgQCAicBQwYCAgICDAEIAS8BMwEBAwICBQIBASoCCAHuAQIBBAEAAQAQEBAAAgAB4gGVBQADAQIFBCgDBAGlAgAEAAKZCzEEewE2DykBAgIKAzEEAgIHAT0DJAUBCD4BDAI0CQoEAgFfAwIBAQIGAaABAwgVAjkCAQEBARYBDgcDBcMIAgMBARcBUQECBgEBAgEBAgEC6wECBAYCAQIbAlUIAgEBAmoBAQECBgEBZQMCBAEFAAkBAvUBCgIBAQQBkAQCAgQBIAooBgIECAEJBgIDLg0BAgAHAQYBAVIWAgcBAgECegYDAQECAQcBAUgCAwEBAQACAAU7BwABPwRRAQACAC4CFwABAQMEBQgIAgceBJQDADcEMggBDgEWBQEPAAcBEQIHAQIBBQAHAAE9BAAHbQcAYIDwAAAxOhAAKAAAADwBAAAJAAAAJgAAAB0AAAAmAAAAJgAAACYAAAAWLxAA+S4QANMuEACtLhAAhy4Q"
}
{
 "id": 290,
 "creator": "inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty",
 "data_hash": "F8E7689E23AC0C9D53F44A8FD98C686C20B0140A8D76D600E2C546BFBBA7758D",
 "instantiate_permission": {
  "permission": "Everybody"
 },
 "data": "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Qf8BcQshBgJAAkACQCAEIAZyIgZB/wFxIgVBAkcEQCAGQQFxDQEgC0UNAiADQfACakG5gcAAQQcQGCARRQ0KDAkLIAsNCiADQdACakG5gcAAQQcQFiADKALQAkEVRgRAIAMoAtwCIRQgAygC2AIhESADKALUAiELDAsLIANB+AJqIANB2AJqKQMANwMAIAMgAykD0AI3A/ACDAkLIANB0AJqIA4QjgECQCADKALQAiIPQRVHBEAgFyAYKQIANwIAIBdBCGogGEEIaigCADYCACADIA82AoADDAELIANBgANqIA4QFyADKAKAA0EVRg0CCyADQfgCaiADQYgDaikDADcDACADIAMpA4ADNwPwAgwGCyADQdACaiAOEI4BIAMoAtACIgRBFUcNAiADQdACaiAOEBogAygC3AIhFCADKALYAiERIAMoAtQCIQsgAygC0AIiBEEVRw0JCyADQbABaiAOEJABIAMtALEBIQQgAy0AsAFBAXENAAsMAgsgAygC3AIhFCADKALYAiERIAMoAtQCIQsMBgsgC0H/AXEhC0EEIQQMBQsgAyAJNgL8AiADIAQ2AvgCIAMgBTYC9AIgAyABNgLwAgsgC0UgEUVyDQELIAsQqwELIAMoAvwCIRQgAygC+AIhESADKAL0AiELIAMoAvACIgRBFUcNAQsgA0HQAmogCBCNASADKALQAiIEQRVGDQIgAygC3AIhFCADKALYAiADKALUAiEBIBEEQCALEKsBCyERIAEhCwsgAyAUNgKkAiADIBE2AqACIAMgCzYCnAIgAyAENgKYAgwJCyAhQiiIpyEKICFCIIinIRUgIachGyAJIRYLIANBCGogCBCQASADLQAJIQEgAy0ACEEBcQ0AC0ECIQQMAwtBACENDAMLIANBoAJqIANB2AJqKQMANwMAIAMgAykD0AI3A5gCIBZFDQUgDRCrAQwFCyADIBQ2AsgCIAMpA8gCISAgA0GYAmogA0GIAmoQjQEgAygCmAIiAUEVRwRAIAMtAJ8CQRB0IQkgAy8AnQIgAykDoAIhICADLQCcAiEMIBYEQCANEKsBCyAJciECIBFFDQYgCxCrAQwGCyADQZgCaiADQYgCahCLASADKAKYAiIBQRVHBEAgAy0AnwJBEHQhCSADLwCdAiADKQOgAiEgIAMtAJwCIQwgFgRAIA0QqwELIAlyIQIg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aigCACIENgIAIAMgCykCACIMNwMwIAlBCGogBDYCACAJIAw3AgAMAQsgA0EgaiAHEBcgAygCICIFQRVGDQELIAMoAiwhCSADKAIoIQggAy0AJCEEIAMvACUgAy0AJ0EQdHIMBgsgAyAHEJABIAMtAAEhBSADLQAAQQFxDQALCyAEQf8BcSEEQQIhBQwCCyAKQRU2AgAMAwsgAygCTCEJIAYhBAsgBEEIdgsiBjsABSAKIAk2AAwgCiAINgAIIAogBDoABCAKIAU2AgAgCkEHaiAGQRB2OgAACyADQdAAaiQAIAIoAlAiBEEVRw0KIAJB0ABqIAEQjQEgAigCUCIBQRVGBEAgAEEVNgIADAwLIAJByABqIAJB3ABqKAIAIgQ2AgAgAiACKQJUIgw3A0AgAEEMaiAENgIAIAAgDDcCBCAAIAE2AgAMCwsgAEELNgIADAoLIABBFTYCAAwJCyAAQQA7AAUgAEEENgIAIABBB2pBADoAAAwICyAAQQ42AgAMBwsgAikCVCEMIAAgAigCXDYCDCAAIAw3AgQgACABNgIADAYLIABBADsABSAAQQQ2AgAgAEEHakEAOgAADAULIABBDjYCAAwECyACQcgAaiACQdwAaigCACIBNgIAIAIgAikCVCIMNwNAIABBDGogATYCACAAIAw3AgQgACAENgIADAMLIABBADsABSAAQQQ2AgAgAEEHakEAOgAADAILIABBDjYCAAwBCyACQcgAaiACQdwAaigCACIBNgIAIAIgAikCVCIMNwNAIABBDGogATYCACAAIAw3AgQgACAENgIACyACQeAAaiQAC8UBAQF/IwBB8ABrIgMkACADIAI2AgwgAyABNgIIIANBJGpBATYCACADQgI3AhQgA0GUi8AANgIQIANBATYCLCADIANBKGo2AiAgAyADQQhqNgIoIANBADYCOCADQgE3AzAgA0FAayIBIANBMGpBqIXAABDyASADQRBqIAEQ6AEEQEHAhcAAQTcgA0HoAGpB+IXAAEHUhsAAEOkBAAsgACADKQMwNwIEIABBFDYCACAAQQxqIANBOGooAgA2AgAgA0HwAGokAAuFBAIFfwJ+IwBB4ABrIgMkACADIAI2AgwgAyABNgIIIwBBEGsiBiQAIANBEGoiBAJ/AkACQCACRQRAIARBADoAAQwBCwJAAkACQCABLQAAQStrDgMBAgACCyACQQFGDQMMAQsgAkEBayICRQ0CIAFBAWohAQsCQAJAAkAgAkERTwRAA0AgBiAIQgBCChCMAiABLQAAQTBrIgVBCUsNBiAGKQMIQgBSDQQgBikDACIJIAUgByAFQQpJG618IgggCVQNAyABQQFqIQEgBSEHIAJBAWsiAg0ACwwBCwNAIAEtAABBMGsiBUEJSw0FIAFBAWohASAFrSAIQgp+fCEIIAJBAWsiAg0ACwsgBCAINwMIQQAMBAsgBEECOgABDAELIARBAjoAAQtBAQwBCyAEQQE6AAFBAQs6AAAgBkEQaiQAAkAgAy0AEEUEQCAAIAMpAxg3AwggAEEVNgIADAELIAMgAy0AEToAJyADQcQAakECNgIAIANBATYCPCADIANBJ2o2AkAgAyADQQhqNgI4IANBAjYCXCADQgI3AkwgA0Hci8AANgJIIAMgA0E4ajYCWCADQShqIgEgA0HIAGoiAhDQASACQQRyIAEQ0QEgA0EUNgJIIAMoAiwEQCADKAIoEKsBCyAAIAMpA0g3AgAgAEEIaiADQdAAaikDADcCAAsgA0HgAGokAAvFAgIEfwF+IwBBIGsiAiQAIAJBCGogARCQAQJAAkACQAJAAkAgAi0ACEEBcQRAIAItAAlBIkcNASABEIoBIAJBEGogARCPASACKAIQIgFBFUcNAiACQRxqKAIAIQEgAkEYaigCACEDIAIoAhQiBEUEQAJAIAFFBEBBASEEDAELIAFBf0oiBUUNBSABIAUQPSIERQ0GCyAEIAMgARCLAiEDIABBDGogATYCACAAQQhqIAE2AgAgACADNgIEIABBFTYCAAwGCyAAIAQ2AgQgAEEVNgIAIABBDGogATYCACAAQQhqIAM2AgAMBQsgAEEAOwAFIABBBDYCACAAQQdqQQA6AAAMBAsgAEEONgIADAMLIAIpAhQhBiAAIAIoAhw2AgwgACAGNwIEIAAgATYCAAwCCxDPAQALIAEgBRDOAQALIAJBIGokAAv3AQEDfyMAQUBqIgQkAAJAAkACQAJAIAJFBEBBASEFDAELIAJBf0oiBkUNASACIAYQPSIFRQ0CCyAFIAEgAhCLAiEBIARBADYCCCAEQgE3AwAgBEEQaiIFIARBqIXAABDyASADIAUQhwENAiAAQQxqIAI2AgAgAEEIaiACNgIAIAAgATYCBCAAIAQpAwA3AhAgAEEINgIAIABBGGogBEEIaigCADYCAAJAIAMoAgBBFEkNACADQQhqKAIARQ0AIAMoAgQQqwELIARBQGskAA8LEM8BAAsgAiAGEM4BAAtBwIXAAEE3IARBOGpB+IXAAEHUhsAAEOkBAAvwIwIbfwN+IwBBkAJrIgMkACADQZABaiIHIAEgAhCJASADQYgBaiAHEJABQQAhAgJAAkACQCADLQCIAUEBcUUEQEEEIQEMAQsgAy0AiQFB+wBHBEBBDiEBDAELIANBkAFqIgEQigEgA0GAAWogARCIASADLQCEASEEIANB+ABqIAMoAoABIgwQkAECQAJAAkACQAJAIAMtAHhBAXFFBEBBAiECDAELIAMtAHkhAiAEQQFxIRcgA0HoAWpBBHIhESADQYACakEEciEUIANB8AFqIRggA0HUAWohHCADQfMBaiEdA0ACfwJAAkACfwJAIAJB/wFxIgRBLEcEQCAEQf0ARwRAIBcNAkEJDAMLIA1BgH5xIQJBAwwFC0EQIBcNARogDBCKASADQfAAaiAMEJABIAMtAHBBAXFFDQIgAy0AcSECCyACQf8BcSIEQSJGDQJBECAEQf0ARw0AGkETCyECIA0hCwwECyANQf8BcSELQQQhAgwDCyADQegAaiAMEJABIAMtAGhBAXFFBEBBBCECQQAhCwwDCyADLQBpQSJHBEBBDiECDAMLIAwQigEgA0HIAWogDBCPASADKALUASEFIAMoAtABIQQgAygCzAEhCyADKALIASICQRVHDQICQCALRQRAQQIhAgJAAkAgBUEFaw4CAQADCyAEQa6BwABBBhCNAkEAR0EBdCECDAILQQJBASAEQbSBwABBBRCNAhshAgwBC0ECIQICQAJAAkAgBUEFaw4CAQACCyALQa6BwABBBhCNAkEAR0EBdCECDAELQQJBASALQbSBwABBBRCNAhshAgsgBEUNACALEKsBC0EAIRcgDUGAfnELIQQCQAJAAkACQAJAAkACQCACIARyIg1B/wFxIgtBA0cEQCALDgIDAgELIBkhDQJAIBIiB0UEQCADQcgBakGugcAAQQYQFiADKALIAUEVRw0BIANB1AFqKAIAIRUgAygCzAEhByADQdABaigCACENCwJAIAZFBEAgA0HIAWpBtIHAAEEFEBYgAygCyAFBFUcNASADQdABaigCACEJIAMoAswBIQYgA0HUAWooAgAhCAsgAyAJNgKwASADIAY2AqwBIAMgFTYCqAEgAyANNgKkASADIAc2AqABIAdFDQ4gA0HIAWogA0GQAWoQjQEgAygCyAEiAUEVRg0FIAMoAswBIQsgAygC1AEhBCADKALQASEFIA0EQCAHEKsBCyAIBEAgCEEFdCEHIAZBEGohAgNAIAJBBGooAgAEQCACKAIAEKsBCyACQSBqIQIgB0EgayIHDQALCyALQQh2IQIgCUUNDyAGEKsBDA8LIBJFIQIgA0GsAWogA0HQAWopAwA3AgAgAyADKQPIATcCpAEgDUUNDCAHEKsBDAwLIANBrAFqIANB0AFqKQMANwIAIAMgAykDyAE3AqQBQQAhEiAGDQkMCgsgA0HIAWogDBCOAQJAIAMoAsgBIgFBFUcEQCADQfQBaiADQdQBaigCADYCACADIAMpAswBNwLsASADIAE2AugBDAELIANB6AFqIAwQFyADKALoAUEVRg0GCyADQawBaiADQfABaikDADcCACADIAMpA+gBNwKkASADQQA2AqABIAYNCAwJCyAGRQ0DIANBoAFqQQRyQbSBwABBBRAYIANBADYCoAEMBwsgEkUNASADQaABakEEckGugcAAQQYQGCADQQA2AqABIAYNBgwHCyADQcgBaiADQZABahCLASADKALIASIBQRVHBEAgAygC1AEhBCADKALQASEFIAMoAswBIQIgDQRAIAcQqwELIAgEQCAIQQV0IQcgBkEQaiELA0AgC0EEaigCAARAIAsoAgAQqwELIAtBIGohCyAHQSBrIgcNAAsLIAlFDQsgBhCrAQwLCyAAQRhqIAg2AgAgAEEUaiAJNgIAIABBEGogBjYCACAAQQxqIBU2AgAgAEEIaiANNgIAIAAgBzYCBCAAQQ02AgAMCwsgA0HIAWogDBCOAQJ/IAMoAsgBIgJBFUYEQCADQcgBaiAMEBogAygC1AEhFSADKALMASESIAMoAtABIgQgAygCyAEiAkEVRw0BGiAEIRkMAwsgAygC1AEhFSADKALMASESIAMoAtABCyEBIANBsAFqIBU2AgAgA0GsAWogATYCACADQagBaiASNgIAIAMgAjYCpAFBACESIANBADYCoAEgBg0EDAULIANByAFqIAwQjgECQAJAAkACQAJAAkACQAJAAkAgAygC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IAMgCEEBaiIINgLAASADQQhqIBAQkAEgAy0ACSECIAMtAAhBAXENCEEAIQYMEAsgA0EONgLsAQwECyADIA82AvgBIAMgCjYC9AEgAyAFNgLwASADIBY2AuwBDAMLIBggFCkCADcCACAYQQhqIBRBCGooAgA2AgAgAyAFNgLsAQwCCyADQcgBakGlgMAAQQYQGCADQQA2AtgBQQEhAgwJCyADQegBaiAOEI4BAkACQCADKALoASIFQRVHBEAgFCARKQIANwIAIBRBCGogEUEIaigCADYCACADIAU2AoACDAELIANBgAJqIA4QGiADKAKAAkEVRg0BCyADQdABaiADQYgCaikDADcDACADIAMpA4ACNwPIAQwKCyADKAKMAiEbIAMoAogCIRogAygChAIhAQwBCyADQdABaiARQQhqKQIANwMAIANBADYC2AEgAyARKQIANwPIAUEBIQIMBwsgA0EQaiAOEJABIAMtABEhBSADLQAQQQFxDQALCwwDCyAGQf8BcSEGQQQhCgwJCyADKALUASEIIAMoAtABIQkgAygCzAEhBgwICyADKAK8ASEJIAMoArgBIQYMBgsgAyAKNgLUASADIAk2AtABIAMgBDYCzAEgAyACNgLIAUEBIQILIBpFIAFFIAJFcnINACABEKsBCyADKQPIASIeQiCIpyEGIANB0AFqKQMAIh9CIIinIRAgHqchCiAfpyEJDAELQQAhBkEAIRALIAMoArgBIQcgCARAIAhBBXQhAUEAIQIDQCACIAdqIgRBFGooAgAiBQRAIARBEGooAgAQqwELIAEgAkEgaiICRw0ACwsgECEICyADKAK8AQRAIAcQqwELIApBFUcNAQsgA0HIAWogDBCMASADKALIASIKQRVGDQEgAygC1AEgAygC0AEhDSADKALMASAIBEAgCEEFdCEBIAZBEGohAgNAIAJBBGooAgAEQCACKAIAEKsBCyACQSBqIQIgAUEgayIBDQALCyAJBEAgBhCrAQshBiEIIA0hCQsgA0GwAWogCDYCACADQawBaiAJNgIAIANBqAFqIAY2AgAgAyAKNgKkAQwECyADIAwQkAEgAy0AASECIAMtAABBAXENAAtBAiECCyADQbABaiAFNgIAIANBrAFqIAQ2AgAgA0GoAWogCzYCACADIAI2AqQBIAZFDQELIAgEQCAIQQV0IQEg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A2pB+wA6AAAgAkHQAWogBEGYg8AAQQYQlwECQAJAIAIoAtABRQRAIAQoAggiAyAHKAIARgRAIAQgAxAQIAQoAgghAwsgBCADQQFqNgIIIAQoAgAgA2pBOjoAACACQdABaiAEEJsBIAIoAtABRQ0BIAJBzAFqIAVBCGooAgA2AgAgAiAFKQIANwLEAQwCCyACQZABaiACQdwBaigCADYCACACIAIpAtQBNwOIAQwSCyACQcABaiACKALUASACLQDYARCTASACKALAAUUNAwsgAkGQAWogAkHMAWooAgA2AgAgAiACKQLEATcDiAEMEAsgBygCACADRgRAIAQgAxAQIAQoAgghAwsgBCADQQFqNgIIIAQoAgAgA2pB+wA6AAAgAkHQAWogBEGUg8AAQQQQlwEgAigC0AENBCAEKAIIIgMgBygCAEYEQCAEIAMQECAEKAIIIQMLIAQgA0EBajYCCCAEKAIAIANqQTo6AAACQAJAAkACQAJAIAlBAWsOBAMCAQAECyACQdABaiAEQcKDwABBCxCcASACKALQAQ0HIAIgAi0A2AE6AKQBIAIgAigC1AE2AqABIAJB0AFqIAJBoAFqQc2DwABBDSAIQRRrKAIAIAhBDGsoAgAQDyACKALQAUUEQCACQcABaiACKAKgASACLQCkARCUAQwPCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAsLIAJB0AFqIARB2oPAAEEMEJwBIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwLCyACIAItANgBOgCkASACIAIoAtQBNgKgASACQdABaiACQaABakHNg8AAQQ0gCEEUaygCACAIQQxrKAIAEA8gAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAsLIAJB0AFqIAJBoAFqQeaDwABBBSAIQQhrKAIAIAgoAgAQDyACKALQAUUNDCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIARB64PAAEEHEJwBIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwKCyACIAItANgBOgCkASACIAIoAtQBNgKgASACQdABaiACQaABakHNg8AAQQ0gCEEUaygCACAIQQxrKAIAEA8gAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIAJBoAFqQfKDwABBCyAIQQhqKQMAEBIgAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAoLIAJB0AFqIAJBoAFqIAhBCGsQEyACKALQAUUNCiAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAkLIAJB0AFqIARBgITAAEELEJwBIAIoAtABRQ0HIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMCAsgAkHQAWogBEGXhMAAQQcQnAEgAigC0AEEQCAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAgLIAIgAi0A2AE6AKQBIAIgAigC1AE2AqABIAJB0AFqIAJBoAFqQc2DwABBDSAIQRRrKAIAIAhBDGsoAgAQDyACKALQAQRAIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMCAsgAkHQAWogAkGgAWogCEEIaxATIAIoAtABBEAgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwICyACQdABaiACQaABakG0gcAAQQUgCEEEaigCACAIQQxqKAIAEBQgAigC0AFFDQUgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwHCyACQbwBaiACQdwBaigCADYCACACIAIpAtQBNwK0AQwaCyAEKAIIIgMgBygCAEYNCwwMCyACQZABaiACQdwBaigCADYCACACIAIpAtQBNwOIAQwMCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAMLIAJBkAFqIAJB3AFqKAIANgIAIAIgAikC1AE3A4gBDAoLIAJBwAFqIAIoAqABIAItAKQBEJQBDAQLIAIgAigC1AEiAzYCmAEgCEEMaygCACEPIAhBFGsoAgAhDQJAIAItANgBBEAgAygCCCEJDAELIAMoAggiCiADKAIERgRAIAMgChAQIAMoAgghCgsgAyAKQQFqIgk2AgggAygCACAKakEsOgAACyACQQA6AJwBIANBBGoiCigCACAJRgRAIAMgCRAQIAMoAgghCQsgAygCACAJakEiOgAAIAMgCUEBaiIJNgIIIAooAgAgCWtBBE0EQCADIAlBBRARIAMoAgghCQsgAygCACAJaiIQQeaDwAAoAAA2AAAgEEEEakHqg8AALQAAOgAAIAMgCUEFaiIJNgIIIAooAgAgCWtBAU0EQCADIAlBAhARIAMoAgghCQsgAygCACAJakGi9AA7AAAgAyAJQQJqNgIIAkAgDUUEQCACQdABaiADEJgBDAELIAJB0AFqIAMgDSAPEJcBCwJAAkACQAJAIAIoAtABRQRAIAJB0AFqIAJBmAFqQYuEwABBByAIQSBqKQMAEBIgAigC0AENASACQdABaiACQZgBaiAIQQhrEBMgAigC0AENAiACQdABaiACQZgBakG0gcAAQQUgCEEEaigCACAIQQxqKAIAEBQgAigC0AENAyACQdABaiACQZgBakGShMAAQQUgCEEQaigCACAIQRhqKAIAEA8gAigC0AENBCACQcABaiACKAKYASACLQCcARCUAQwICyACQagBaiAFQQhqKAIAIgM2AgAgAiAFKQIAIhE3A6ABIAZBCGogAzYCACAGIBE3AgAMBAsgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAwDCyAGIAUpAgA3AgAgBkEIaiAFQQhqKAIANgIADAILIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAMAQsgBiAFKQIANwIAIAZBCGogBUEIaigCADYCAAsgAkEBNgLAAQwCCyACQcABaiACKAKgASACLQCkARCUAQwBCyACQcABaiACKAKgASACLQCkARCUAQsgAigCwAFFBEAgBCgCCCIDIAcoAgBHDQQMAwsgAkGQAWogBkEIaigCADYCACACIAYpAgA3A4gBDAQLIAYgBSkCADcCACAGQQhqIAVBCGooAgA2AgAgAkEBNgLAAQsgAigCwAFFBEAgBCgCCCIDIAcoAgBGDQEMAgsgAkGQAWogBkEIaigCADYCACACIAYpAgA3A4gBDAILIAQgAxAQIAQoAgghAwsgBCgCACADakH9ADoAACAEIANBAWoiAzYCCCAMQdAAaikDACERIAxByABqKQMAIRIgAyAHKAIARw0BIAQgAxAQIAQoAgghAwwBCyACQbwBaiACQZABaigCADYCACACIAIpA4gBNwK0AQwLCyAEKAIAIANqQSw6AAAgBCADQQFqIgM2AgggBygCACADRgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEiOgAAIAQgA0EBaiIDNgIIIAcoAgAgA2tBCE0EQCAEIANBCRARIAQoAgghAwsgBCgCACADaiIJQaSEwAApAAA3AAAgCUEIakGshMAALQAAOgAAIAQgA0EJaiIDNgIIIAcoAgAgA2tBAU0EQCAEIANBAhARIAQoAgghAwsgBCgCACADakGi9AA7AAAgBCADQQJqNgIIAkAgElAEQCACQdABaiAEEJgBDAELIAJB0AFqIAQgERCWAQsgAigC0AENAiAMQdgAai0AACEJIAQoAggiAyAHKAIARgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEsOgAAIAQgA0EBaiIDNgIIIAcoAgAgA0YEQCAEIAMQECAEKAIIIQMLIAQoAgAgA2pBIjoAACAEIANBAWoiAzYCCCAHKAIAIANrQQdNBEAgBCADQQgQESAEKAIIIQMLIAQoAgAgA2pC8srB45bv17fuADcAACAEIANBCGoiAzYCCCAHKAIAIANrQQFNBEAgBCADQQIQESAEKAIIIQMLIAQoAgAgA2pBovQAOwAAIAQgA0ECajYCCAJAAkACQAJAAkAgCUEBaw4DAQIDAAsgAkHQAWogBEHFhMAAQQYQmQEMAwsgAkHQAWogBEHAhMAAQQUQmQEMAgsgAkHQAWogBEG5hMAAQQcQmQEMAQsgAkHQAWogBEG0hMAAQQUQmQELIAIoAtABBEAgAkG8AWogAkHcAWooAgA2AgAgAiACKQLUATcCtAEMCwsgAkGwAWogBEEAEJMBIAIoArABDQogCEHgAGohCEEBIQMgDEHgAGogDkcNAAtBAAUgAwtB/wFxQQBHEJIBIAIoAlgNCSACQdABaiACQUBrIAFBDGooAgAgAUEUaigCABAgIAIoAtABBEAgAkE8aiACQdwBaigCADYCACACIAIpAtQBNwI0DAsLIAFBIGooAgAhBiABQRhqKAIAIQcgAigCQCEEIAItAEQEQCAEKAIIIQMMAgsgBCgCCCIFIAQoAgRGBEAgBCAFEBAgBCgCCCEFCyAEIAVBAWoiAzYCCCAEKAIAIAVqQSw6AAAMAQsgAkG8AWogAkHcAWooAgA2AgAgAiACKQLUATcCtAEMBwsgAkEAOgBEIARBBGoiBSgCACADRgRAIAQgAxAQIAQoAgghAwsgBCgCACADakEiOgAAIAQgA0EBaiIDNgIIIAUoAgAgA2tBBU0EQCAEIANBBhARIAQoAgghAwsgBCgCACADaiIFQf6EwAAoAAA2AAAgBUEEakGChcAALwAAOwAAIAQgA0EGaiIDNgIIIARBBGooAgAgA2tBAU0EQCAEIANBAhARIAQoAgghAwsgBCgCACADakGi9AA7AAAgBCADQQJqNgIIIAJB0AFqIAQQmgEgAigC0AENAiACQdgBai0AACEDAkACQAJAIAJBsAFqIAIoAtQBIgUgBgR/IAcgBkEYbGohCCADRSEDIAJB0AFqQQRyIQYDQCADQQFxBEAgBSgCCCIDIAUoAgRGBEAgBSADEBAgBSgCCCEDCyAFIANBAWo2AgggBSgCACADakEsOgAACyACQdABaiAFEJsBIAIoAtABDQIgAiACLQDYAToAjAEgAiACKALUATYCiAEgAkHQAWogAkGIAWpB14TAAEEEIAcoAgAgB0EIaigCABAPIAIoAtABDQYgAkHQAWogAkGIAWogB0EMaigCACAHQRRqKAIAECAgAigC0AEEQCACQcwBaiACQdwBaigCADYCACACIAIpAtQBNwLEAQwJCyACQcABaiACKAKIASACLQCMARCTASACKALAAQ0IQQEhAyAHQRhqIgcgCEcNAAtBAAUgAwtB/wFxQQBHEJIBIAIoArABDQcgBCgCCCIHIARBBGoiAygCAEYEQCAEIAcQECAEKAIIIQcLIAQoAgAgB2pBLDoAACAEIAdBAWoiBzYCCCACQQA6AEQgAygCACAHRgRAIAQgBxAQIAQoAgghBwsgBCgCACAHakEiOgAAIAQgB0EBaiIHNgIIIAFBJGohAyAEQQRqIgUoAgAgB2tBA00EQCAEIAdBBBARIAQoAgghBwsgBCgCACAHakHkwtGLBjYAACAEIAdBBGoiATYCCCAFKAIAIAFrQQFNBEAgBCABQQIQESAEKAIIIQELIAQoAgAgAWpBovQAOwAAIAQgAUECajYCCCADKAIADQEgAkHQAWogBBCYAQwCCyACQcwBaiAGQQhqKAIANgIAIAIgBikCADcCxAEMBQsgAkHAAWogAxBqIAJB0AFqIAQgAigCwAEiASACKALIARCXASACKALEAUUNACABEKsBCyACKALQAQRAIAJBPGogAkHcAWooAgA2AgAgAiACKQLUATcCNAwJCyACQTBqIARBABCTASACKAIwDQggAigCCCIDIAIoAgRGBEAgAiADEBAgAigCCCEDCyACKAIAIANqQf0AOgAAIAIgA0EBajYCCAsgAkHIAWogAkEIaigCACIBNgIAIAIgAikDACIRNwPAASAAQQxqIAE2AgAgACARNwIEIABBDTYCAAwJCyACQcwBaiACQdwBaigCADYCACACIAIpAtQBNwLEAQwBCyACQbwBaiACQdwBaigCADYCACACIAIpAtQBNwK0AQwBCyACQbwBaiACQcwBaigCADYCACACIAIpAsQBNwK0AQsgAkE8aiACQbwBaigCADYCACACIAIpArQBNwI0DAMLIAJB5ABqIAJB3AFqKAIANgIAIAIgAikC1AE3AlwMAQsgAkHkAGogAkG8AWooAgA2AgAgAiACKQK0ATcCXAsgAkE8aiACQeQAaigCADYCACACIAIpAlw3AjQLIAJBHGogAkE8aigCADYCACACIAIpAjQ3AhQLIAJByAFqIgEgAkEcaigCADYCACACIAIpAhQ3A8ABIAIoAgQEQCACKAIAEKsBCyACQdgBaiABKAIANgIAIAIgAikDwAE3A9ABIABBuYfAAEHhACACQdABahAhCyACQeABaiQAC+ACAgJ/AX4jAEEgayIFJAAgASgCCCIEIAEoAgRGBEAgASAEEBAgASgCCCEECyABIARBAWo2AgggASgCACAEakH7ADoAACAFQRBqIAFBwITAAEEFEJcBAkACQCAFKAIQRQRAIAEoAggiBCABKAIERgRAIAEgBBAQIAEoAgghBAsgASAEQQFqNgIIIAEoAgAgBGpBOjoAACAFQRBqIAEgAiADEJcBIAUoAhANASABKAIIIgQgASgCBEYEQCABIAQQECABKAIIIQQLIABBADYCACABIARBAWo2AgggASgCACAEakH9ADoAAAwCCyAFQQhqIAVBHGooAgAiATYCACAFIAUpAhQiBjcDACAAQQxqIAE2AgAgACAGNwIEIABBATYCAAwBCyAFQQhqIAVBHGooAgAiATYCACAFIAUpAhQiBjcDACAAQQxqIAE2AgAgACAGNwIEIABBATYCAAsgBUEgaiQAC9QGAgR/AX4jAEHgAGsiBCQAIAEoAgAhBgJAIAEtAAQEQCAGKAIIIQUMAQsgBigCCCIHIAYoAgRGBEAgBiAHEBAgBigCCCEHCyAGIAdBAWoiBTYCCCAGKAIAIAdqQSw6AAALIAFBADoABCAGQQRqIgEoAgAgBUYEQCAGIAUQECAGKAIIIQULIAYoAgAgBWpBIjoAACAGIAVB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QT9xQYABcjoADyACIAFBBnZBP3FBgAFyOgAOIAIgAUEMdkE/cUGAAXI6AA0gAiABQRJ2QQdxQfABcjoADEEEDAELIAIgAUE/cUGAAXI6AA4gAiABQQx2QeABcjoADCACIAFBBnZBP3FBgAFyOgANQQMLIQEgASAAQQRqKAIAIAAoAggiA2tLBEAgACADIAEQESAAKAIIIQMLIAAoAgAgA2ogAkEMaiABEIsCGiAAIAEgA2o2AggLIAJBEGokAEEAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB9InAACACQQhqEN4BIAJBIGokAAtKAQF/IAIgACgCACIAQQRqKAIAIAAoAggiA2tLBEAgACADIAIQESAAKAIIIQMLIAAoAgAgA2ogASACEIsCGiAAIAIgA2o2AghBAAvGBAICfwF+IwBBsAFrIgIkACACQQhqIAFBDGopAgA3AwAgAkEQaiABQRRqKQIANwMAIAJBGGogAUEcaikCADcDACACQSBqIAFBJGooAgA2AgAgAiABKQIENwMAAkACQCABKAIAIgMEQCABKQMoIQQgACADNgIAIAAgBDcCKCAAIAFBBGoiASkCADcCBCAAQQxqIAFBCGopAgA3AgAgAEEUaiABQRBqKQIANwIAIABBHGogAUEYaikCADcCACAAQSRqIAFBIGooAgA2AgAMAQsgAkFAayACQRxqKQIANwMAIAJBOGogAkEUaikCADcDACACQTBqIAJBDGopAgA3AwAgAiACKQIENwMoIAJBADYCUCACQgE3A0ggAkHYAGogAkHIAGpBqIXAABDyASACKAIoQQ1GBEAgAkGkAWpBADYCACACQYyKwAA2AqABIAJCATcClAEgAkGEjcAANgKQASACQdgAaiACQZABahD3AQ0CIAAgAikDSDcCBCAAQQA2AgAgAEEMaiACQdAAaigCADYCAAwBCyACQaQBakEBNgIAIAJCATcClAEgAkGMjcAANgKQASACQQM2AoQBIAIgAkGAAWo2AqABIAIgAkGMAWo2AoABIAIgAkEoajYCjAEgAkHYAGogAkGQAWoQ9wENASACKAIoIABBDGogAkHQAGooAgA2AgAgACACKQNINwIEIABBADYCAEENRg0AIAJBKGoQLgsgAkGwAWokAA8LQcCFwABBNyACQagBakH4hcAAQdSGwAAQ6QEAC0UBAX8gAiAAQQRqKAIAIAAoAggiA2tLBEAgACADIAIQESAAKAIIIQMLIAAoAgAgA2ogASACEIsCGiAAIAIgA2o2AghBAAurAQEBfwJAIAIEQAJ/AkACQAJAIAFBAE4EQCADKAIIRQ0CIAMoAgQiBA0BIAENAyACDAQLIABBCGpBADYCAAwFCyADKAIAIAQgAiABED4MAgsgAQ0AIAIMAQsgASACED0LIgMEQCAAIAM2AgQgAEEIaiABNgIAIABBADYCAA8LIAAgATYCBCAAQQhqIAI2AgAMAQsgACABNgIEIABBCGpBADYCAAsgAEEBNgIAC/0CAQF/IwBBgAFrIgUkACAFIAI2AgwgBSABNgIIAkACQCAERQRAIAVBJGpBATYCACAFQgI3AhQgBUHwisAANgIQIAVBATYCRCAFIAVBQGs2AiAgBSAFQQhqNgJAIAVBADYCMCAFQgE3AyggBUHQAGoiASAFQShqQaiFwAAQ8gEgBUEQaiABEOgBDQIgACAFKQMoNwIEIABBFDYCACAAQQxqIAVBMGooAgA2AgAMAQsgBUE0akEENgIAIAVBJGpBAjYCACAFQgI3AhQgBUHIisAANgIQIAVBATYCLCAFQQE2AjwgBSADNgI4IAUgBUEoajYCICAFIAVBOGo2AjAgBSAFQQhqNgIoIAVBADYCSCAFQgE3A0AgBUHQAGoiASAFQUBrQaiFwAAQ8gEgBUEQaiABEOgBDQEgACAFKQNANwIEIABBFDYCACAAQQxqIAVByABqKAIANgIACyAFQYABaiQADwtBwIXAAEE3IAVB+ABqQfiFwABB1IbAABDpAQAL6QEBAX8jAEGAAWsiBSQAIAUgAjYCDCAFIAE2AgggBUEkakECNgIAIAVBNGpBBDYCACAFQgI3AhQgBUG4i8AANgIQIAVBATYCLCAFIAQ2AjwgBSADNgI4IAUgBUEoajYCICAFIAVBOGo2AjAgBSAFQQhqNgIoIAVBADYCSCAFQgE3A0AgBUHQAGoiASAFQUBrQaiFwAAQ8gEgBUEQaiABEOgBBEBBwIXAAEE3IAVB+ABqQfiFwABB1IbAABDpAQALIAAgBSkDQDcCBCAAQRQ2AgAgAEEMaiAFQcgAaigCADYCACAFQYABaiQAC5kDAgN/AX4jAEEgayICJAAgAkEIaiABEJABAkACQAJAAkACQAJAAkACQCACLQAIQQFxBEAgAi0ACUEiRw0BIAEQigEgAkEQaiABEI8BIAIoAhAiAUEVRw0CIAJBHGooAgAhASACQRhqKAIAIQMgAigCFCIERQRAAkACQCABQQVrDgUBCQkJAAkLIANBnozAAEEJEI0CRQ0JDAgLIANByIzAAEEFEI0CDQcgAEEVNgIAIABBAToABAwJCwJAAkAgAUEFaw4FAQUFBQAFCyAEQZ6MwABBCRCNAkUNBQwECyAEQciMwABBBRCNAg0DIABBFTYCACAAQQE6AAQMBQsgAEEAOwAFIABBBDYCACAAQQdqQQA6AAAMBwsgAEEONgIADAYLIAIpAhQhBSAAIAIoAhw2AgwgACAFNwIEIAAgATYCAAwFCyAAIAQgAUGcjcAAQQIQNwwBCyAAQRU2AgAgAEEAOgAECyADRQ0CIAQQqwEMAgsgACADIAFBnI3AAEECEDcMAQsgAEEVNgIAIABBADoABAsgAkEgaiQAC68CAgN/AX4jAEEgayICJAAgAkEIaiABEJABAkACQAJAIAItAAhBAXEEQCACLQAJQSJHDQEgARCKASACQRBqIAEQjwEgAigCECIBQRVHDQIgAkEcaigCACEBIAJBGGooAgAhAyACKAIUIgRFBEACQCABQQlGBEAgA0GsjcAAQQkQjQJFDQELIAAgAyABQbiNwABBARA3DAULIABBFTYCAAwECwJAAkAgAUEJRgRAIARBrI3AAEEJEI0CRQ0BCyAAIAQgAUG4jcAAQQEQNwwBCyAAQRU2AgALIANFDQMgBBCrAQwDCyAAQQA7AAUgAEEENgIAIABBB2pBADoAAAwCCyAAQQ42AgAMAQsgAikCFCEFIAAgAigCHDYCDCAAIAU3AgQgACABNgIACyACQSBqJAAL0SYCEn8DfiMAQaADayIDJAAQrQEgA0H4AGogABB/IANBiAFqIAEQfyADQZgBaiACEH8gA0GoAmogAygCeCIOIAMoAoABEBUCQAJAAkACQAJAAkACfwJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAygCyAJBAkcEQCADQcABaiADQbACaikDADcDACADQbABaiADQcgCaikDADcDACADIAMpA6gCNwO4ASADIAMpA8ACNwOoASADKAK4AiEJIAMoArwCIQogAygC0AIhCyADKALUAiEMIAMpA9gCIRYgA0HIAWogAygCiAEiEiADKAKQARAcIAMoAsgBQQ1HDQIgA0HgAWooAgAhBiADQdwBaigCACENIANB2AFqKAIAIQggA0HUAWooAgAhEyADQdABaigCACEPIAMoAswBIRAgA0GYAmoiACADKAKYASIUIAMoAqABEIkBIANBQGsgABCQAUEAIQEgAy0AQEEBcQ0BQQQhBEEADA0LIANB4AFqIANBwAJqKQMANwMAIANB2AFqIANBuAJqKQMANwMAIANB0AFqIANBsAJqKQMANwMAIAMgAykDqAI3A8gBIANBADYCoAIgA0IBNwOYAiADQegBaiIAIANBmAJqQaiFwAAQ8gEgA0HIAWogABB9DRQgA0HUAGogA0GgAmooAgA2AgAgAyADKQOYAjcCTCADQQA2AkggA0HIAWoQLgwSCyADLQBBQfsARwRAQQ4hBEEADAwLIANBmAJqIgAQigEgA0E4aiAAEIgBIAMtADwgA0EwaiADKAI4IgIQkAFBASERIAMtADBBAXFFBEBBAiEBDAgLQQFxIQECQAJAAkAgAy0AMSIAIgdBLEcEQCAHQf0ARg0CIAENAUEJIQEMCwsgAQRAQRAhAQwLCyACEIoBIANBKGogAhCQASADLQAoQQFxRQ0JIAMtACkhAAsgAEH9AEYNBkEQIQEgAEEiRw0JIANBIGogAhCQASADLQAgQQFxRQ0FQQ4hASADLQAhQSJHDQcgAhCKASADQagCaiACEI8BIAMoArQCIQAgAygCsAIhBSADKAKsAiEHIAMoAqgCIgFBFUcNAwJAIAdFBEAgAEEFRgRAIAVB8YzAAEEFEI0CRQ0ECyADQegBaiAFIABBlI3AAEEBEDYMAQsCQAJAIABBBUYEQCAHQfGMwABBBRCNAkUNAQsgA0HoAWogByAAQZSNwABBARA2DAELIANBFTYC6AELIAVFDQAgBxCrAQsgAygC6AEiAUEVRg0BDAcLIANBqAJqQfGMwABBBRAWIAMoAqgCQRVGBEAgAygCrAIhAQwLCyADQdAAaiADQbACaikDADcDACADIAMpA6gCNwNIDAkLIANBqAJqIAIQJSADKAKoAkEVRg0CIANB0ABqIANBsAJqKQMANwMAIAMgAykDqAI3A0gMCAsgA0GAAmogA0HgAWopAwA3AwAgA0H4AWogA0HYAWopAwA3AwAgA0HwAWogA0HQAWopAwA3AwAgAyADKQPIATcD6AEgA0EANgKgAiADQgE3A5gCIANBqAJqIgAgA0GYAmpBqIXAABDyASADQegBaiAAEH0NEiADQdQAaiADQaACaigCADYCACADIAMpA5gCNwJMIANBADYCSCADQegBahAuDA8LIAMgADYC9AEgAyAFNgLwASADIAc2AuwBIAMgATYC6AEMAwsgAygCrAIhASADQRhqIAIQkAEgAy0AGEEBcUUEQEECIQEMBQsgAy0AGSIAQf0ARg0GIABBLEcEQEEJIQEMBQsgAhCKASADQRBqIAIQkAEgAy0AEEEBcUUNAyADLQARIgBB/QBGDQFBECEBIABBIkcNBCADQQhqIAIQkAEgAy0ACEEBcUUNAEEOIQEgAy0ACUEiRw0CIAIQigEgA0GoAmogAhCPASADKAK0AiEAIAMoArACIQQgAygCrAIhAiADKAKoAiIBQRVHBEAgAyAANgL0ASADIAQ2AvABIAMgAjYC7AEgAyABNgLoAQwDCwJAAkAgAgRAAkACQCAAQQVGBEAgAkHxjMAAQQUQjQJFDQELIANB6AFqIAIgAEGUjcAAQQEQNgwBCyADQRU2AugBCyAERQ0BIAIQqwEMAQsgAEEFRgRAIARB8YzAAEEFEI0CRQ0CCyADQegBaiAEIABBlI3AAEEBEDYLIAMoAugBIgFBFUcNAwsgA0HIAGpB8YzAAEEFEBgMBQsgA0EAOgDvASADQQA7AO0BQQQhASADQQQ2AugBDAELQRMhAQwCCyADLwDtASADLQDvAUEQdHIhBCADKQPwASEVIAMtAOwBIREMAQtBBCEBCyADIBU3A1AgAyAROgBMIAMgATYCSCADIAQ7AE0gAyAEQRB2OgBPCyADKAJIIgRBFUcNASADKAJMIQELIANBqAJqIANBmAJqEI0BIAMoAqgCIgRBFUYNAiADKQOwAiEVIAMoAqwCIgFBgH5xDAELIAMpA1AhFSADKAJMIgFBgH5xCyABQf8BcXIMAQsgA0GoAmogA0GYAmoQiwEgAygCqAIiBEEVRg0BIAMpA7ACIRUgAygCrAILIQAgAyAVNwOwAiADIAA2AqwCIAMgBDYCqAIgA0HIAWpBvonAAEEfIANBqAJqEBsgAygCyAFBDUcNASADKALMASEBCyADQfQCakH0gMAANgIAIANB7AJqQciAwAA2AgAgA0HkAmpBrIDAADYCACADQbACaiADQcABaikDADcDACADQcgCaiADQbABaikDADcDACADQYwDaiAGNgIAIANBiANqIA02AgAgA0GEA2ogCDYCACADQYADaiATNgIAIANB/AJqIA82AgAgA0HwAmogA0GYA2oiADYCACADQegCaiAANgIAIAMgAykDuAE3A6gCIAMgCjYCvAIgAyAJNgK4AiADIAMpA6gBNwPAAiADIAE2ApADIAMgEDYC+AIgAyAWNwPYAiADIAw2AtQCIAMgCzYC0AIgAyAANgLgAiADQegBaiINIQIgA0GoAmohB0EAIQojAEHgAWsiACQAIAAgATYCDCAAQfAAaiADQfgCaiIEENEBIABBHGogAEH4AGooAgA2AgAgACABNgIQIAAgACkDcDcCFCADQeACaiIBKAIEIQsgASgCACEMAkACQAJAAkACQAJAAkACQAJAQRRBARA9IgEEQCABQRBqQd2MwAAoAAA2AAAgAUEIakHVjMAAKQAANwAAIAFBzYzAACkAADcAAEEFQQEQPSIFRQ0IIAVBBGpB5YzAAC0AADoAACAFQeGMwAAoAAA2AAAgAEGwAWoiBhCVASAAQUBrIAYQmwEgACgCQA0BIAAgACgCRDYCwAEgACAAQcgAai0AADoAxAEgAEFAayAAQcABakGUgcAAQQggAUEUEA8gACgCQA0CIABBQGsgAEHAAWpBk4XAAEEHIAVBBRAPIAAoAkAEQCAAQdQBaiAAQcwAaigCADYCACAAIAApAkQ3AswBDAULIABByAFqIAAoAsABIAAtAMQBEJMBIAAoAsgBRQ0DDAQLQRRBARDOAQALIABB1AFqIABBzABqKAIANgIAIAAgACkCRDcCzAEMAgsgAEHUAWogAEHMAGooAgA2AgAgACAAKQJENwLMAQwBCyAAQfwAaiAAQbgBaigCADYCACAAIAApA7ABNwJ0DAELIABBqAFqIgYgAEHUAWooAgA2AgAgACAAKQLMATcDoAEgACgCtAEEQCAAKAKwARCrAQsgAEHIAGogBigCADYCACAAIAApA6ABNwNAIABB8ABqQd2JwABBFCAAQUBrECEgACgCcCIGQQ1HDQELIABB+ABqKAIAIQhBDSEGIAxBmoXAAEENIAAoAnQiCSAAQfwAaigCACALKAIUEQcAIAhFDQEgCRCrAQwBCyAAQThqIABBiAFqKQMANwMAIAAgACkDgAE3AzAgACgCfCEIIAAoAnghCSAAKAJ0IQoLIAEQqwEgBRCrAQJAAkACQAJAAkACQCAGQQ1GBEAgAEHwAGogDCALIABBEGoQJiAAKAJwIgFBDUYNAiAAQdgAaiAAQYwBaigCACIFNgIAIABB0ABqIABBhAFqKQIAIhU3AwAgAEHIAGogAEH8AGopAgAiFjcDACAAIAApAnQiFzcDQCACQSRqIAU2AgAgAkEcaiAVNwIAIAJBFGogFjcCACACQQxqIBc3AgAgAiABNgIIDAELIABBKGogAEE4aikDACIVNwMAIAAgACkDMCIWNwMgIAJBIGogFTcCACACQRhqIBY3AgAgAkEUaiAINgIAIAJBEGogCTYCACACQQxqIAo2AgAgAiAGNgIICyACQQA2AgAgAEEYaigCAARAIAAoAhQQqwELIARBBGooAgAEQCAEKAIAEKsBCyAEQRRqKAIAIgEEQCABQQV0IQEgBEEMaigCAEEQaiECA0AgAkEEaigCAARAIAIoAgAQqwELIAJBIGohAiABQSBrIgENAAsLIARBEGooAgAEQCAEKAIMEKsBCyAHQRRqKAIABEAgBygCEBCrAQsgB0EsaigCAA0BDAILIABBkAFqQgA3AwAgAEGAAWpCADcDACAAQgQ3A4gBIABCgICAgMAANwN4IABCCDcDcCAAQUBrIABB8ABqQeaMwABBgITAAEELECIgAEE4aiIFIARBCGooAgA2AgAgACAEKQIANwMwQQVBARA9IgFFDQQgAUEEakHwjMAALQAAOgAAIAFB7IzAACgAADYAACAAQfgAaiAFKAIANgIAIAAgACkDMDcDcCAAQdQBaiIFIABB8ABqIgYpAgA3AgAgBUEIaiAGQQhqKAIANgIAIABChYCAgNAANwLMASAAIAE2AsgBIABB1ABqKAIAIgEgAEHQAGooAgBGBEAgAEHMAGogARAjIAAoAlQhAQsgACgCTCABQRhsaiIFIAApA8gBNwIAIAVBCGogAEHQAWopAwA3AgAgBUEQaiAAQdgBaikDADcCACAAQfgAaiAAQcgAaikDADcDACAAQYgBaiAAQdgAaikDADcDACAAQZABaiAAQeAAaikDADcDACAAQZgBaiAAQegAaikDADcDACAAIAFBAWo2AlQgAEGAAWogAEHQAGopAwA3AwAgACAAKQNANwNwIABBADYC0AEgAEIBNwPIASAAQUBrIgUgAEHIAWpBqIXAABDyASAAQQxqKAIAIgGtQgAgAax9IAFBf0oiARsgASAFEIUCDQJBBUEBED0iBUUNAyAFQQRqQfWMwAAtAAA6AAAgBUHxjMAAKAAANgAAIABBhAFqKAIAIgEgAEGAAWoiCCgCAEYEQCAAQfwAaiABECMgACgChAEhAQsgACgCfCABQRhsaiIGQoWAgIDQADcCBCAGIAU2AgAgAiAAKQNwNwIAIAJBCGogAEH4AGopAwA3AgAgAkEYaiAAQYgBaikDADcCACACQSBqIABBkAFqKQMANwIAIAJBKGogAEGYAWopAwA3AgAgACABQQFqNgKEASACQRBqIAgpAwA3AgAgBiAAKQPIATcCDCAGQRRqIABB0AFqKAIANgIAIABBGGooAgAEQCAAKAIUEKsBCyAEQRRqKAIAIgEEQCABQQV0IQEgBEEMaigCAEEQaiECA0AgAkEEaigCAARAIAIoAgAQqwELIAJBIGohAiABQSBrIgENAAsLIARBEGooAgAEQCAEKAIMEKsBCyAHQRRqKAIABEAgBygCEBCrAQsgB0EsaigCAEUNAQsgBygCKBCrAQsgAEHgAWokAAwDC0HAhcAAQTcgAEEwakH4hcAAQdSGwAAQ6QEACwtBBUEBEM4BAAsgA0HIAGogDRAzIAMoApwBBEAgFBCrAQsgAygCjAEEQCASEKsBCyADKAJ8RQ0DIA4QqwEMAwsgA0GAAmogA0HgAWopAwA3AwAgA0H4AWogA0HYAWopAwA3AwAgA0HwAWogA0HQAWopAwA3AwAgAyADKQPIATcD6AEgA0EANgKgAiADQgE3A5gCIANBqAJqIgAgA0GYAmpBqIXAABDyASADQegBaiAAEH1FBEAgA0HUAGogA0GgAmooAgA2AgAgAyADKQOYAjcCTCADQQA2AkggA0HoAWoQLiAPBEAgEBCrAQsgBgRAIAZBBXQhASAIQRBqIQADQCAAQQRqKAIABEAgACgCABCrAQsgAEEgaiEAIAFBIGsiAQ0ACwsgDUUNASAIEKsBDAELDAMLIAoEQCAJEKsBCyAMRQ0AIAsQqwELIAMoApwBBEAgAygCmAEQqwELIAMoAowBBEAgAygCiAEQqwELIAMoAnxFDQAgDhCrAQsgA0HoAWogA0HIAGoQHiADKALoAUENRgRAIANB0AFqIANB9AFqKAIAIgA2AgAgAyADKQLsASIVNwPIASADQbACaiAANgIAIAMgFTcDqAIgA0GoAmoQfiADQcgAahArIANBoANqJAAPCyADQcACaiADQYACaikDADcDACADQbgCaiADQfgBaikDADcDACADQbACaiADQfABaikDADcDACADIAMpA+gBNwOoAkHFgcAAQSsgA0GoAmpB8IHAAEH0gsAAEOkBAAtBwIXAAEE3IANBmANqQfiFwABB1IbAABDpAQALnSoCE38CfiMAQdADayIDJAAQrQEgA0GoAWogABB/IANBuAFqIAEQfyADQcgBaiACEH8gA0HYAmogAygCqAEiEyADKAKwARAVAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACfwJAAkACQAJAAkACQAJAAkACQAJAIAMoAvgCQQJHBEAgA0HwAWogA0HgAmopAwA3AwAgA0HgAWogA0H4AmopAwA3AwAgAyADKQPYAjcD6AEgAyADKQPwAjcD2AEgAygC6AIhESADKALsAiEOIAMoAoADIQ8gAygChAMhEiADKQOIAyEWIANB+AFqIAMoArgBIhQgAygCwAEQHCADKAL4AUENRw0CIANBkAJqKAIAIQwgA0GMAmooAgAhCiADQYgCaigCACEJIANBhAJqKAIAIQIgA0GAAmooAgAhDSADKAL8ASEQIANByAJqIgAgAygCyAEiFSADKALQARCJASADQfAAaiAAEJABIAMtAHBBAXENAQwUCyADQZACaiADQfACaikDADcDACADQYgCaiADQegCaikDADcDACADQYACaiADQeACaikDADcDACADIAMpA9gCNwP4ASADQQA2AtACIANCATcDyAIgA0GYAmoiACADQcgCakGohcAAEPIBIANB+AFqIAAQfQ0aIANBhAFqIANB0AJqKAIANgIAIAMgAykDyAI3AnwgA0EANgJ4IANB+AFqEC4MGAsgAy0AcSIAQfsARwRAIABBIkcEQEEKIQAMFQsgA0HYAmogA0HIAmoQOCADKALYAiIAQRVHDQ9BDiEADBQLIANByAJqIgQQigEgA0HYAmogBBA4AkACfyAD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AEEiRw0GIANBCGogBRCQAUEEIQAgAy0ACEEBcUUNB0EOIQAgAy0ACUEiRw0HIAUQigEgA0HYAmogBRCPASADKALYAiIAQRVHDQEgA0HkAmooAgAhByADQeACaigCACEAIAMoAtwCIgVFBEAgA0GYAmogACAHQYyKwABBABA2DAMLIANBmAJqIAUgB0GMisAAQQAQNiAARQ0CIAUQqwEMAgtBEyEADAYLIAMgAygC5AI2AqQCIAMgAykC3AI3ApwCIAMgADYCmAILIAMoApgCIgBBFUYNACADLwCdAiADLQCfAkEQdHIhByADKQOgAiEXIAMtAJwCIQUMBAsgA0HYAmogBBCNASADKALYAiIAQRVHBEAgAygC3AIiAUEIdiEHIAMoAuQCIQUgAygC4AIhBgwFCyADIAQQkAEgAy0AAEEBcUUNBUELIQAgAy0AAUH9AEcNBgsgBBCKASADQdgCaiADQcgCahCLASADKALYAiIAQRVGDQYLIAMoAuQCIQUgAygC4AIhBiADKALcAiEHDAQLQRAhAAsgBUH/AXEhASAXQiCIpyEFIBenIQYLIAFB/wFxIAdBCHRyIQcMAQtBBCEAQQAhBwsgAyAFNgLkAiADIAY2AuACIAMgBzYC3AIgAyAANgLYAiADQfgBakHkhsAAQRsgA0HYAmoQGyADKAL4AUENRw0BIANBgAJqKAIAIQEgAygC/AEhCAsgA0GkA2pB9IDAADYCACADQZwDakHIgMAANgIAIANBlANqQayAwAA2AgAgA0HgAmogA0HwAWopAwA3AwAgA0H4AmogA0HgAWopAwA3AwAgA0HEA2ogATYCACADQbwDaiAMNgIAIANBuANqIAo2AgAgA0G0A2ogCTYCACADQbADaiACNgIAIANBrANqIA02AgAgA0GgA2ogA0HIA2oiADYCACADQZgDaiAANgIAIAMgAykD6AE3A9gCIAMgDjYC7AIgAyARNgLoAiADIAMpA9gBNwPwAiADIAg2AsADIAMgEDYCqAMgAyAWNwOIAyADIBI2AoQDIAMgDzYCgAMgAyAANgKQAyADQZgCaiISIQogA0GQA2ohACADQdgCaiERIANBqANqIQkgASECIwBBMGsiCyQAAkAgCEUEQCALQShqIABBEGopAgA3AwAgC0EgaiAAQQhqKQIANwMAIAsgACkCADcDGCMAQeAA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AWooAgAhACACQdABaigCACEBIAIoAswBIgVFBEAgAkGgAWogASAAQYyKwABBABA2DAMLIAJBoAFqIAUgAEGMisAAQQAQNiABRQ0CIAUQqwEMAgtBEyEBDAYLIAIgAigC1AE2AqwBIAIgAikCzAE3AqQBIAIgADYCoAELIAIoAqABIgFBFUYNACACLwClASACLQCnAUEQdHIhCyACKQOoASEOIAItAKQBIQMMBAsgAkHIAWogAxCNASACKALIASIBQRVHBEAgAi8AzQEgAi0AzwFBEHRyIQsgAikD0AEhDiACLQDMASEDDAQLIAJBCGogAxCQASACLQAIQQFxRQ0EIAItAAlB/QBHBEBBCyEBDAYLIAMQigEgAkHIAWogAkFAaxCLASACKALIASIBQRVGDQYLIAIpA9ABIQ4gAigCzAEhAwwECyACQZgBaiACQeABaikDADcDACACQZABaiACQdgBaikDADcDACACQYgBaiACQdABaikDADcDACACIAIpA8gBNwOAASACQQA2ArACIAJCATcDqAIgAkGgAWoiACACQagCakGohcAAEPIBIAJBgAFqIAAQfUUEQCACQcwAaiACQbACaigCADYCACACIAIpA6gCNwJEIAJBATYCQCACQYABahAuDAkLDA4LQRAhAQsgA0H/AXEgC0EIdHIhAwwBC0EEIQFBACEDCyACIA43A9ABIAIgAzYCzAEgAiABNgLIASACQYABakGgh8AAQRkgAkHIAWoQGyACKAKAAUENRw0BCyACQZQCakH0gMAANgIAIAJBjAJqQciAwAA2AgAgAkGEAmpBrIDAADYCACACQdABaiACQfgAaikDADcDACACQegBaiACQegAaikDADcDACACQZACaiACQbgCaiIANgIAIAJBiAJqIAA2AgAgAiACKQNwNwPIASACIAY2AtwBIAIgBDYC2AEgAiACKQNgNwPgASACIA83A/gBIAIgCTYC9AEgAiAINgLwASACIAA2AoACIAJBgAFqIgUhASACQcgBaiEDIwBB8ABrIgAkACAAQRhqIAJBgAJqIgQoAgAgBCgCBEEMaigCABAkAkACQAJAAkACQAJAAkAgACgCGCIEQQ1GBEAgACgCHCEEIABBJGooAgAEQCAAQSBqKAIAEKsBCyAAQcgAaiIGEJUBIABBGGogBhCbASAAKAIYDQEgACAAKAIcNgJoIAAgAEEgai0AADoAbCAAQRhqIABB6ABqIAQQJyAAKAIYBEAgAEHkAGogAEEkaigCADYCACAAIAApAhw3AlwMBAsgAEHYAGogACgCaCAALQBsEJMBIAAoAlhFDQIMAwsgAEEQaiAAQTRqKAIAIgY2AgAgACAAKQIsIg43AwggACkCHCEPIAApAiQhECABQRxqIAY2AgAgASAONwIUIAEgEDcCDCABIA83AgQgASAENgIAIANBFGooAgAEQCADKAIQEKsBCyADQSxqKAIARQ0GIAMoAigQqwEMBgsgAEHkAGogAEEkaigCADYCACAAIAApAhw3AlwMAQsgAEEkaiAAQdAAaigCADYCACAAIAApA0g3AhwMAQsgAEFAayIEIABB5ABqKAIANgIAIAAgACkCXDcDOCAAKAJMBEAgACgCSBCrAQsgAEHgAGogBCgCADYCACAAIAApAzg3A1ggAEEYakH/hsAAQSEgAEHYAGoQISAAKAIYQQ1HDQELIAEgACkCHDcCBCABQQ02AgAgAUEMaiAAQSRqKAIANgIADAELIAEgACkDGDcDACABQRhqIABBMGopAwA3AwAgAUEQaiAAQShqKQMANwMAIAFBCGogAEEgaikDADcDAAsgA0EUaigCAARAIAMoAhAQqwELIANBLGooAgBFDQAgAygCKBCrAQsgAEHwAGokACAFQQRyIQACQCACKAKAASIBQQ1GBEAgAkHMAGogAEEIaigCADYCACACQQA2AkAgAiAAKQIANwJEDAELIAJBrAFqIABBCGooAgA2AgAgAkG4AWogAkGYAWopAwA3AwAgAiABNgKgASACIAIpA5ABNwOwASACIAApAgA3AqQBIAJBADYCsAIgAkIBNwOoAiACQcgBaiIAIAJBqAJqQaiFwAAQ8gEgAkGgAWogABB9DQogAkHMAGogAkGwAmooAgA2AgAgAiACKQOoAjcCRCACQQE2AkAgAkGgAWoQLgsgAigCnAIEQCAMEKsBCyACKAJUBEAgBxCrAQsgAkGoAmoQlQEgAUENRw0EIAIoArACIgAgAigCrAJGBEAgAkGoAmogABAQIAIoArACIQALIAIoAqgCIABqQfsAOgAAIAIgAEEBajYCsAIgAkHIAWogAkGoAmpBy4TAAEECEJcBIAIoAsgBDQIgAigCsAIiACACKAKsAkYEQCAC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KAIAIQIjAEEwayIAJAACfwJAAkACQAJAIAIoAgBBAWsOAwECAwALIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABB5KjAADYCCCABIABBCGoQ9wEMAwsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEHIqMAANgIIIAEgAEEIahD3AQwCCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQaiowAA2AgggASAAQQhqEPcBDAELIABBHGpBATYCACAAQgE3AgwgAEHop8AANgIIIABBIDYCJCAAIAJBBGo2AiwgACAAQSBqNgIYIAAgAEEsajYCICABIABBCGoQ9wELIABBMGokAAu0AwEBfyAAKAIAIQIjAEEwayIAJAACfwJAAkACQAJAAkACQAJAIAIoAgBBAWsOBgECAwQFBgALIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABB4LLAADYCCCABIABBCGoQ9wEMBgsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEHMssAANgIIIAEgAEEIahD3AQwFCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQeSowAA2AgggASAAQQhqEPcBDAQLIABBHGpBADYCACAAQfSRwAA2AhggAEIBNwIMIABByKjAADYCCCABIABBCGoQ9wEMAwsgAEEcakEANgIAIABB9JHAADYCGCAAQgE3AgwgAEG0ssAANgIIIAEgAEEIahD3AQwCCyAAQRxqQQA2AgAgAEH0kcAANgIYIABCATcCDCAAQaiowAA2AgggASAAQQhqEPcBDAELIABBHGpBATYCACAAQgE3AgwgAEHop8AANgIIIABBIDYCJCAAIAJBBGo2AiwgACAAQSBqNgIYIAAgAEEsajYCICABIABBCGoQ9wELIABBMGokAAsMACAAKAIAIAEQ3AELYgEBfyMAQTBrIgIkACAAKAIAIQAgAkEcakEBNgIAIAJCAjcCDCACQeSwwAA2AgggAkEeNgIkIAIgADYCLCACIAJBIGo2AhggAiACQSxqNgIgIAEgAkEIahD3ASACQTBqJAALVwEBfyMAQSBrIgIkACACIAA2AgQgAkEYaiABQRBqKQIANwMAIAJBEGogAUEIaikCADcDACACIAEpAgA3AwggAkEEakHckcAAIAJBCGoQ3gEgAkEgaiQACwgAIAEgARBUC5oEAQR/IwBBQGoiACQAIABBADYCCCAAQgE3AwAgAEEQaiIEIABBmI/AABDyAQJAIwBBQGoiAiQAQQEhAwJAIAQoAhgiBUGo38AAQQwgBEEcaigCACIEKAIMEQEADQACQCABKAIIIgMEQCACIAM2AgwgAkHnADYCFCACIAJBDGo2AhBBASEDIAJBATYCPCACQgI3AiwgAkG438AANgIoIAIgAkEQajYCOCAFIAQgAkEoahDeAUUNAQwCCyABKAIAIgMgASgCBEEMaigCABEIAELrkZO19tizovQAUg0AIAIgAzYCDCACQegANgIUIAIgAkEMajYCEEEBIQMgAkEBNgI8IAJCAjcCLCACQbjfwAA2AiggAiACQRBqNgI4IAUgBCACQShqEN4BDQELIAEoAgwhASACQSRqQcoANgIAIAJBHGpBygA2AgAgAiABQQxqNgIgIAIgAUEIajYCGCACQekANgIUIAIgATYCECACQQM2AjwgAkIDNwIsIAJBkN/AADYCKCACIAJBEGo2AjggBSAEIAJBKGoQ3gEhAwsgAkFAayQAIANFBEAgACgCCCECIAAoAgAhA0EMQQQQPSIBRQ0BIAEgAjYCCCABIAI2AgQgASADNgIAIAEQACABEKsBIAAoAgQEQCAAKAIAEKsBCyAAQUBrJAAPC0Gwj8AAQTcgAEE4akHoj8AAQcSQwAAQ6QEAC0EMQQQQzgEAC4cBAQV/IwBBIGsiAyQAAn8gAkUEQEEAIQJBAAwBCwJAA0AgA0EIaiABEFYgAygCCCIFRQ0BIAMoAhggAygCFCEHIAMoAgwEQCAFEKsBCyAEQQFqIQQEQCAHEKsBCyACIARHDQALQQAMAQsgBCECQQELIQEgACACNgIEIAAgATYCACADQSBqJAALiQMCCH8BfiMAQUBqIgIkAAJAIAEoAgAQBSIBBEAgASgCACIDRQ0BIAEpAgQhCiABEKsBIAIgCjcCNCACIAM2AjAgAkEYaiIEIAJBMGoiBRBsIAJBEGogAkEgaigCACIGNgIAIAIgAikDGCIKNwMIIAJBKGoiBygCACEBIAJBLGoiCCgCACEJIAIoAiQhAyACQThqIAY2AgAgAiAKNwMwIAQgBRBsIAgoAgAhBCAHKAIAIQUgAigCJCEGIAIoAhwEQCACKAIYEKsBCwJAIARFBEAgAEEANgIAIAEEQCADEKsBCyAFRQ0BIAYQqwEMAQsgACAJNgIUIAAgATYCECAAIAM2AgwgACAENgIIIAAgBTYCBCAAIAY2AgALIAJBQGskAA8LIAJBLGpBADYCACACQfSRwAA2AiggAkIBNwIcIAJBqKbAADYCGCACQRhqQZCnwAAQ1AEACyACQSxqQQA2AgAgAkH0kcAANgIoIAJCATcCHCACQcCnwAA2AhggAkEYakHIp8AAENQBAAt9AQV/IwBBIGsiAyQAAkAgAkUNAANAAkAgA0EIaiABEFYgAygCCCIERQ0AIAMoAhggAygCFCEGIAMoAgwEQCAEEKsBCwRAIAYQqwELIAJBAWsiAg0BDAILC0EBIQcLAkAgB0UEQCAAIAEQVgwBCyAAQQA2AgALIANBIGokAAsJACAAQgA3AgALDQAgACgCACABEFpBAAvNAgECfyMAQRBrIgIkAAJAAn8CQCABQYABTwRAIAJBADYCDCABQYAQTw0BIAIgAUE/cUGAAXI6AA0gAiABQQZ2QcABcjoADEECDAILIAAoAggiAyAAKAIERgRAIAAgAxAQIAAoAgghAwsgACADQQFqNgIIIAAoAgAgA2ogAToAAAwCCyABQYCABE8EQCACIAFBP3FBgAFyOgAPIAIgAUEGdkE/cUGAAXI6AA4gAiABQQx2QT9xQYABcjoADSACIAFBEnZBB3FB8AFyOgAMQQQMAQsgAiABQT9xQYABcjoADiACIAFBDHZB4AFyOgAMIAIgAUEGdkE/cUGAAXI6AA1BAwshASABIABBBGooAgAgACgCCCIDa0sEQCAAIAMgARARIAAoAgghAwsgACgCACADaiACQQxqIAEQiwIaIAAgASADajYCCAsgAkEQaiQAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB3JHAACACQQhqEN4BIAJBIGokAAsKACAAIAEQWkEAC8UBAQF/IwBB8ABrIgMkACADIAI2AgwgAyABNgIIIANBJGpBATYCACADQgI3AhQgA0Ggk8AANgIQIANBITYCLCADIANBKGo2AiAgAyADQQhqNgIoIANBADYCOCADQgE3AzAgA0FAayIBIANBMGpBmI/AABDyASADQRBq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CCAEIAM2AgQgBCACNgIAQcAAQQEQPSIDRQ0EQQxBBBA9IgJFDQUgAkLAADcCBCACIAM2AgAgBCACEAciAw0BIAIoAgAiA0UNByACKQIEIQUgAhCrASAAQQhqIAU3AgAgACADNgIEIABBDTYCACAEEKsBDAILQSRBARA9IgJFDQUgAEKkgICAwAQ3AwggACACNgIEIABBAjYCACACQSBqQZijwAAoAAA2AAAgAkEYakGQo8AAKQAANwAAIAJBEGpBiKPAACkAADcAACACQQhqQYCjwAApAAA3AAAgAkH4osAAKQAANwAADAELIAMoAgAiAkUNBSADKQIEIQUgAxCrASABIAU3AgQgASACNgIAIAFBIjYCJCABIAE2AiAgAUEBNgI8IAFCATcCLCABQbijwAA2AiggASABQSBqNgI4IAFBEGogAUEoahDQASAAQQI2AgAgACABKQMQNwIEIABBDGogAUEYaigCADYCACABKAIEBEAgASgCABCrAQsgBBCrAQsgAUFAayQADwtBDEEEEM4BAAtBwABBARDOAQALQQxBBBDOAQALQSRBARDOAQALIAFBPGpBADYCACABQfSRwAA2AjggAUIBNwIsIAFBwKfAADYCKCABQShqQcinwAAQ1AEAC5kDAgJ/AX4jAEFAaiIBJAAgAkEIaigCACEDIAIoAgAhAgJAAkACQEEMQQQQPSIEBEAgBCADNgIIIAQgAzYCBCAEIAI2AgBB2gBBARA9IgNFDQFBDEEEED0iAkUNAiACQtoANwIEIAIgAzYCAAJAIAQgAhAIIgNFBEAgAigCACIDRQ0FIAIpAgQhBSACEKsBIABBCGogBTcCACAAIAM2AgQgAEENNgIADAELIAMoAgAiAkUNBCADKQIEIQUgAxCrASABIAU3AgQgASACNgIAIAFBIjYCJCABIAE2AiAgAUEBNgI8IAFCATcCLCABQdijwAA2AiggASABQSBqNgI4IAFBEGogAUEoahDQASAAQQI2AgAgACABKQMQNwIEIABBDGogAUEYaigCADYCACABKAIEBEAgASgCABCrAQsLIAQQqwEgAUFAayQADwtBDEEEEM4BAAtB2gBBARDOAQALQQxBBBDOAQALIAFBPGpBADYCACABQfSRwAA2AjggAUIBNwIsIAFBwKfAADYCKCABQShqQcinwAAQ1AEAC8cCAQF/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IABBCGpBADYCACAAQQE2AgALzQEBA38jAEEgayICJAACQAJAIAFBAWoiAUUNACAAQQRqKAIAIgNBAXQiBCABIAEgBEkbIgFBCCABQQhLGyIBQX9zQR92IQQCQCADBEAgAkEBNgIYIAIgAzYCFCACIAAoAgA2AhAMAQsgAkEANgIYCyACIAEgBCACQRBqEIIBIAIoAgQhAyACKAIARQRAIAAgAzYCACAAQQRqIAE2AgAMAgsgAkEIaigCACIAQYGAgIB4Rg0BIABFDQAgAyAAEM4BAAsQzwEACyACQSBqJAALzwEBAn8jAEEgayIDJAACQAJAIAEgASACaiIBSw0AIABBBGooAgAiAkEBdCIEIAEgASAESRsiAUEIIAFBCEsbIgFBf3NBH3YhBAJAIAIEQCADQQE2AhggAyACNgIUIAMgACgCADYCEAwBCyADQQA2AhgLIAMgASAEIANBEGoQggEgAygCBCECIAMoAgBFBEAgACACNgIAIABBBGogATYCAAwCCyADQQhqKAIAIgBBgYCAgHhGDQEgAEUNACACIAAQzgEACxDPAQALIANBIGokAAsdACABKAIARQRAAAsgAEHEs8AANgIEIAAgATYCAAtVAQJ/IAEoAgAhAiABQQA2AgACQCACBEAgASgCBCEDQQhBBBA9IgFFDQEgASADNgIEIAEgAjYCACAAQcSzwAA2AgQgACABNgIADwsAC0EIQQQQzgEAC+0DAQF/IwBBMGsiAiQAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCAEEBaw4UAQIDBAUGBwgJCgsMDQ4PEBESExQACyACQcK5wAA2AihBIgwUCyACQam5wAA2AihBGQwTCyACQY25wAA2AihBHAwSCyACQfK4wAA2AihBGwwRCyACQdO4wAA2AihBHwwQCyACQa24wAA2AihBJgwPCyACQYW4wAA2AihBKAwOCyACQc63wAA2AihBNwwNCyACQae3wAA2AihBJwwMCyACQe+2wAA2AihBOAwLCyACQbe2wAA2AihBOAwKCyACQYm2wAA2AihBLgwJCyACQfG1wAA2AihBGAwICyACQeK1wAA2AihBDwwHCyACQda1wAA2AihBDAwGCyACQbu1wAA2AihBGwwFCyACQaC1wAA2AihBGwwECyACQdG0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ACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgBEEBagwHCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakEiOgAAIARBAWoMBgsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB4gA6AAAgBEEBagwFCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakH0ADoAACAEQQFqDAQLIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQdwAOgAAIAEgBEEBaiIENgIIIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQe4AOgAAIARBAWoMAwsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB5gA6AAAgBEEBagwCCyADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHcADoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakHyADoAACAEQQFqDAELAn8CQAJAIAVBIE8EQCAFQYABSQ0BIAVBgBBPDQIgBiAFQT9xQYABcjoADSAGIAVBBnZBwAFyOgAMQQIMAwsgAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB3AA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpB9QA6AAAgASAEQQFqIgQ2AgggAygCACAERgRAIAEgBBCDASABKAIIIQQLIAEoAgAgBGpBMDoAACABIARBAWoiBDYCCCADKAIAIARGBEAgASAEEIMBIAEoAgghBAsgASgCACAEakEwOgAAIAEgBEEBaiIENgIIIAVBD3EiCEEKSSEHIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAVB8AFxQQR2QTByOgAAIAEgBEEBaiIENgIIIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAhBMHIgCEE3aiAHGzoAACAEQQFqDAMLIAMoAgAgBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqIAU6AAAgBEEBagwCCyAFQYCABE8EQCAGIAVBP3FBgAFyOgAPIAYgBUESdkHwAXI6AAwgBiAFQQZ2QT9xQYABcjoADiAGIAVBDHZBP3FBgAFyOgANQQQMAQsgBiAFQT9xQYABcjoADiAGIAVBDHZB4AFyOgAMIAYgBUEGdkE/cUGAAXI6AA1BAwshBSAFIAMoAgAgBGtLBEAgASAEIAUQhAEgASgCCCEECyABKAIAIARqIAZBDGogBRCLAhogBCAFagsiBDYCCCACIAlHDQALCyABQQRqKAIAIARGBEAgASAEEIMBIAEoAgghBAsgAEEANgIAIAEgBEEBajYCCCABKAIAIARqQSI6AAAgBkEQaiQAC0wBAX8gAUEEaigCACABKAIIIgJrQQNNBEAgASACQQQQhAEgASgCCCECCyAAQQA2AgAgASACQQRqNgIIIAEoAgAgAmpB7uqx4wY2AAALDQAgACABIAIgAxCXAQtSAQF/IAEoAggiAiABKAIERgRAIAEgAhCDASABKAIIIQILIAAgATYCBCAAQQA2AgAgASACQQFqNgIIIABBCGpBAToAACABKAIAIAJqQdsAOgAAC1IBAX8gASgCCCICIAEoAgRGBEAgASACEIMBIAEoAgghAgsgACABNgIEIABBADYCACABIAJBAWo2AgggAEEIakEBOgAAIAEoAgAgAmpB+wA6AAALngICAn8BfiMAQSBrIgUkACABKAIIIgQgASgCBEYEQCABIAQQgwEgASgCCCEECyABIARBAWo2AgggASgCACAEakH7ADoAACAFQRBqIAEgAiADEJcBAkAgBSgCEEUEQCABKAIIIgQgASgCBEYEQCABIAQQgwEgASgCCCEECyABKAIAIARqQTo6AAAgASAEQQFqIgQ2AgggASgCBCAERgRAIAEgBBCDASABKAIIIQQLIAAgATYCBCAAQQA2AgAgASAEQQFqNgIIIABBCGpBAToAACABKAIAIARqQfsAOgAADAELIAVBCGogBUEcaigCACIBNgIAIAUgBSkCFCIGNwMAIABBDGogATYCACAAIAY3AgQgAEEBNgIACyAFQSBqJAALFgAgACgCACIAKAIAIAAoAgQgARCAAgsdACABKAIARQRAAAsgAEGI1cAANgIEIAAgATYCAAtVAQJ/IAEoAgAhAiABQQA2AgACQCACBEAgASgCBCEDQQhBBBA9IgFFDQEgASADNgIEIAEgAjYCACAAQYjVwAA2AgQgACABNgIADwsAC0EIQQQQzgEAC5QEAQN/IwBBMGsiAiQAAn8CQAJAAkACQCAAKAIEIgMOAwACAwELIwBBEGsiACQAIABB0NbAADYCCCAAQQ42AgQgAEG/1sAANgIAIwBBEGsiASQAIAFBCGogAEEIaigCADYCACABIAApAgA3AwAjAEEQayIAJAAgACABKQIANwMIIABBCGpB9NTAAEEAIAEoAghBARCyAQALIAJBLGpBADYCACACQYjVwAA2AiggAkIBNwIcIAJBoNXAADYCGEEBIAEgAkEYahD3AQ0CGiADQQN0IQMgACgCACEAAkADQCACIAA2AhQgBARAIAJBADYCLCACQYjVwAA2AiggAkIBNwIcIAJBrNXAADYCGCABIAJBGGoQ9wENAgsgAkEBNgIsIAJCAjcCHCACQbTVwAA2AhggAkHMADYCBCACIAI2AiggAiACQRRqNgIAIAEgAkEYahD3AQ0BIABBCGohACAEQQFrIQQgA0EIayIDDQALQQAMAwtBAQwCCyACQSxqQQE2AgAgAkICNwIcIAJBtNXAADYCGCACQc0ANgIEIAIgACgCADYCACACIAI2AiggASACQRhqEPcBDAELIAJBDGpBzQA2AgAgAkEsakECNgIAIAJCAzcCHCACQczVwAA2AhggAkHNADYCBCACIAAoAgAiADYCACACIABBCGo2AgggAiACNgIoIAEgAkEYahD3AQsgAkEwaiQACwwAQsiF+aSet9TbEgshAQF/AkAgACgCBCIBRQ0AIABBCGooAgBFDQAgARCrAQsL1gIBAn8jAEEQayICJAAgACgCACEAAkACfwJAIAFBgAFPBEAgAkEANgIMIAFBgBBPDQEgAiABQT9xQYABcjoADSACIAFBBnZBwAFyOgAMQQIMAgsgACgCCCIDIAAoAgRGBEAgACADEBAgACgCCCEDCyAAIANBAWo2AgggACgCACADaiABOgAADAILIAFBgIAETwRAIAIgAUE/cUGAAXI6AA8gAiABQQZ2QT9xQYABcjoADiACIAFBDHZBP3FBgAFyOgANIAIgAUESdkEHcUHwAXI6AAxBBAwBCyACIAFBP3FBgAFyOgAOIAIgAUEMdkHgAXI6AAwgAiABQQZ2QT9xQYABcjoADUEDCyEBIAEgAEEEaigCACAAKAIIIgNrSwRAIAAgAyABEBEgACgCCCEDCyAAKAIAIANqIAJBDGogARCLAhogACABIANqNgIICyACQRBqJABBAAtaAQF/IwBBIGsiAiQAIAIgACgCADYCBCACQRhqIAFBEGopAgA3AwAgAkEQaiABQQhqKQIANwMAIAIgASkCADcDCCACQQRqQeDWwAAgAkEIahDeASACQSBqJAALkwMBBX8CQAJAAkACQCABQQlPBEBBEEEIELMBIAFLDQEMAgsgABCmASEEDAILQRBBCBCzASEBC0EIQQgQswEhA0EUQQgQswEhAkEQQQgQswEhBUEAQRBBCBCzAUECdGsiBkGAgHwgBSACIANqamtBd3FBA2siAyADIAZLGyABayAATQ0AIAFBECAAQQRqQRBBCBCzAUEFayAASxtBCBCzASIDakEQQQgQswFqQQRrEKYBIgJFDQAgAhDDASEAAkAgAUEBayIEIAJxRQRAIAAhAQwBCyACIARqQQAgAWtxEMMBIQJBEEEIELMBIQQgABC3ASACQQAgASACIABrIARLG2oiASAAayICayEEIAAQugFFBEAgASAEELsBIAAgAhC7ASAAIAIQpwEMAQsgACgCACEAIAEgBDYCBCABIAAgAmo2AgALIAEQugENASABELcBIgJBEEEIELMBIANqTQ0BIAEgAxDAASEAIAEgAxC7ASAAIAIgA2siAxC7ASAAIAMQpwEMAQsgBA8LIAEQwgEgARC6ARoL7SECD38BfiMAQRBrIgskAAJAAkAgAEH1AU8EQEEIQQgQswEhBkEUQQgQswEhBUEQQQgQswEhAUEAQRBBCBCzAUECdGsiAkGAgHwgASAFIAZqamtBd3FBA2siASABIAJLGyAATQ0CIABBBGpBCBCzASEEQdD8wAAoAgBFDQFBACAEayEDAkACQAJ/QQAgBEGAAkkNABpBHyAEQf///wdLDQAaIARB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Gg8LDwsgAkF4cUHU/MAAaiEBAn9BzPzAACgCACIDQQEgAkEDdnQiAnEEQCABKAIIDAELQcz8wAAgAiADcjYCACABCyEDIAEgADYCCCADIAA2AgwgACABNgIMIAAgAzYCCAtpACMAQTBrIgEkAEG0/MAALQAABEAgAUEcakEBNgIAIAFCAjcCDCABQcjXwAA2AgggAUHKADYCJCABIAA2AiwgASABQSBqNgIYIAEgAUEsajYCICABQQhqQfDXwAAQ1AEACyABQTBqJAAL3gEBA38jAEEgayIAJAACQEHI/MAAKAIAQf////8HcQRAQZCAwQAoAgANAQtBvPzAACgCAEG8/MAAQX82AgBFBEBBxPzAACgCACEBQcT8wABBuJvAADYCAEHA/MAAKAIAIQJBwPzAAEEBNgIAQbz8wABBADYCAAJAIAFFDQAgAiABKAIAEQYAIAFBBGooAgBFDQAgAUEIaigCABogAhCrAQsgAEEgaiQADwsACyAAQRxqQQA2AgAgAEH41sAANgIYIABCATcCDCAAQbTYwAA2AgggAEEIakHY2MAAENQBAAuLAgIEfwF+IwBBMGsiAiQAIAFBBGohBCABKAIERQRAIAEoAgAhAyACQRBqIgVBADYCACACQgE3AwggAiACQQhqNgIUIAJBKGogA0EQaikCADcDACACQSBqIANBCGopAgA3AwAgAiADKQIANwMYIAJBFGpB4NbAACACQRhqEN4BGiAEQQhqIAUoAgA2AgAgBCACKQMINwIACyACQSBqIgMgBEEIaigCADYCACABQQxqQQA2AgAgBCkCACEGIAFCATcCBCACIAY3AxhBDEEEED0iAUUEQEEMQQQQzgEACyABIAIpAxg3AgAgAUEIaiADKAIANgIAIABBiNnAADYCBCAAIAE2AgAgAkEwaiQAC60BAQN/IwBBMGsiAiQAIAFBBGohAyABKAIERQRAIAEoAgAhASACQRBqIgRBADYCACACQgE3AwggAiACQQhqNgIUIAJBKGogAUEQaikCADcDACACQSBqIAFBCGopAgA3AwAgAiABKQIANwMYIAJBFGpB4NbAACACQRhqEN4BGiADQQhqIAQoAgA2AgAgAyACKQMINwIACyAAQYjZwAA2AgQgACADNgIAIAJBMGokAAtFAQJ/IAEoAgQhAiABKAIAIQNBCEEEED0iAUUE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BnZBwAFyOgAMQQIMAgsgACgCCCIDIAAoAgRGBEAgACADEIMBIAAoAgghAwsgACADQQFqNgIIIAAoAgAgA2ogAToAAAwCCyABQYCABE8EQCACIAFBP3FBgAFyOgAPIAIgAUEGdkE/cUGAAXI6AA4gAiABQQx2QT9xQYABcjoADSACIAFBEnZBB3FB8AFyOgAMQQQMAQsgAiABQT9xQYABcjoADiACIAFBDHZB4AFyOgAMIAIgAUEGdkE/cUGAAXI6AA1BAwshASABIABBBGooAgAgACgCCCIDa0sEQCAAIAMgARCEASAAKAIIIQMLIAAoAgAgA2ogAkEMaiABEIsCGiAAIAEgA2o2AggLIAJBEGokAEEAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpB0NnAACACQQhqEN4BIAJBIGokAAtLAQF/IAIgACgCACIAQQRqKAIAIAAoAggiA2tLBEAgACADIAIQhAEgACgCCCEDCyAAKAIAIANqIAEgAhCLAhogACACIANqNgIIQQALGgAgACABQbj8wAAoAgAiAEHSACAAGxECAAALQAEBfyMAQSBrIgAkACAAQRxqQQA2AgAgAEH42cAANgIYIABCATcCDCAAQajawAA2AgggAEEIakGw2sAAENQBAAvpAwEGfyMAQTBrIgUkAAJAAkACQAJAAkAgASgCBCIDBEAgASgCACEHIANBAWtB/////wFxIgNBAWoiBkEHcSEEAn8gA0EHSQRAQQAhAyAHDAELIAdBPGohAiAGQfj///8DcSEGQQAhAwNAIAIoAgAgAkEIaygCACACQRBrKAIAIAJBGGsoAgAgAkEgaygCACACQShrKAIAIAJBMGsoAgAgAkE4aygCACADampqampqamohAyACQUBrIQIgBkEIayIGDQALIAJBPGsLIQIgBARAIAJBBGohAgNAIAIoAgAgA2ohAyACQQhqIQIgBEEBayIEDQALCyABQRRqKAIADQEgAyEEDAMLQQAhAyABQRRqKAIADQFBASECDAQLIAcoAgQNACADQRBJDQILIAMgA2oiBCADSQ0BCyAERQ0AAkAgBEF/SgRAIARBARA9IgJFDQEgBCEDDAMLEM8BAAsgBEEBEM4BAAtBASECQQAhAwsgAEEANgIIIAAgAzYCBCAAIAI2AgAgBSAANgIMIAVBIGogAUEQaikCADcDACAFQRhqIAFBCGopAgA3AwAgBSABKQIANwMQIAVBDGpB0NnAACAFQRBqEN4BBEBBwNrAAEEzIAVBKGpB9NrAAEGc28AAEOkBAAsgBUEwaiQAC2cBAn8gASgCACEDAkACQAJAIAFBCGooAgAiAUUEQEEBIQIMAQsgAUF/TA0BIAFBARA9IgJFDQILIAIgAyABEIsCIQIgACABNgIIIAAgATYCBCAAIAI2AgAPCxDPAQALIAFBARDOAQALUwEBfyMAQRBrIgIkACACIAA2AgggAiAAQQxqNgIMIAFBzNzAAEENQbDcwABBBSACQQhqQaDcwABBtdzAAEEFIAJBDGpBvNzAABD7ASACQRBqJAALDgAgACgCABoDQAwACwAL4QIBAn8jAEEgayICJAAgAkEBOgAYIAIgATYCFCACIAA2AhAgAkHQ38AANgIMIAJB3NzAADYCCCMAQRBrIgEkAAJAIAJBCGoiACgCDCICBEAgACgCCCIDRQ0BIAEgAjYCCCABIAA2AgQgASADNgIAIwBBEGsiACQAIABBCGogAUEIaigCADYCACAAIAEpAgA3AwAjAEEQayIBJAAgACgCACICQRRqKAIAIQMCQAJ/AkACQCACKAIEDgIAAQMLIAMNAkEAIQJB+NbAAAwBCyADDQEgAigCACIDKAIEIQIgAygCAAshAyABIAI2AgQgASADNgIAIAFBvNnAACAAKAIEIgEoAgggACgCCCABLQAQELIBAAsgAUEANgIEIAEgAjYCACABQajZwAAgACgCBCIBKAIIIAAoAgggAS0AEBCyAQALQfjWwABBK0H42MAAENkBAAtB+NbAAEErQejYwAAQ2QEAC28BAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQRxqQQI2AgAgA0EsakHKADYCACADQgI3AgwgA0H83sAANgIIIANBygA2AiQgAyADQSBqNgIYIAMgAzYCKCADIANBBGo2AiAgA0EIaiACENQBAAtvAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0EcakECNgIAIANBLGpBygA2AgAgA0ICNwIMIANBkOTAADYCCCADQcoANgIkIAMgA0EgajYCGCADIANBBGo2AiggAyADNgIgIANB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AAgAAAAUAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvZXhwb3J0cy5ycwAAAAABEABhAAAAjQAAAA0AAAAAARAAYQAAAG8AAAANAAAAAAEQAGEAAADqAAAADQAAAHdhc21jdXN0b21iYW5rQmFua01zZ2J1cm5zZW5kdG9fYWRkcmVzc1dhc21Nc2djbGVhcl9hZG1pbmNvbnRyYWN0X2FkZHJ1cGRhdGVfYWRtaW5hZG1pbm1pZ3JhdGVuZXdfY29kZV9pZG1zZ2luc3RhbnRpYXRlY29kZV9pZGxhYmVsZXhlY3V0ZVN1Yk1zZ2dhc19saW1pdFJlcGx5T25uZXZlcnN1Y2Nlc3NlcnJvcmFsd2F5c29rRW1wdHlFdmVudHR5cGVhdHRyaWJ1dGVzQXR0cmlidXRla2V5dmFsdWVSZXNwb25zZWV2ZW50c0NvbnRyYWN0VmVyc2lvbnZlcnNpb25jb250cmFjdF9pbmZvABUAAAAMAAAABAAAABYAAAAXAAAAGAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkABQAAAAAAAAABAAAAGQAAAC9ydXN0Yy84OTdlMzc1NTNiYmE4YjQyNzUxYzY3NjU4OTY3ODg5ZDExZWNkMTIwL2xpYnJhcnkvYWxsb2Mvc3JjL3N0cmluZy5ycwAIAxAASwAAAM4JAAAJAAAAY3dfY291bnRlcjo6bXNnOjpFeGVjdXRlTXNnY3dfY291bnRlcjo6bXNnOjpHZXRDb3VudFJlc3BvbnNlY3dfY291bnRlcjo6bXNnOjpRdWVyeU1zZ2Nvc213YXNtX3N0ZDo6cmVzdWx0czo6Y29udHJhY3RfcmVzdWx0OjpDb250cmFjdFJlc3VsdDxjb3Ntd2FzbV9zdGQ6OnJlc3VsdHM6OnJlc3BvbnNlOjpSZXNwb25zZT5jb3Ntd2FzbV9zdGQ6OnJlc3VsdHM6OmNvbnRyYWN0X3Jlc3VsdDo6Q29udHJhY3RSZXN1bHQ8Y29zbXdhc21fc3RkOjpiaW5hcnk6OkJpbmFyeT5jb3Ntd2FzbV9zdGQ6OnR5cGVzOjpNZXNzYWdlSW5mb2Nvc213YXNtX3N0ZDo6dHlwZXM6OkVudmN3X2NvdW50ZXI6OnN0YXRlOjpTdGF0ZWN3X2NvdW50ZXI6Om1zZzo6SW5zdGFudGlhdGVNc2djdzI6OkNvbnRyYWN0VmVyc2lvbgAAAAUAAAAEAAAABAAAABoAAAAbAAAAHAAAAG1pc3NpbmcgZmllbGQgYGAMBRAADwAAABsFEAABAAAAdW5rbm93biBmaWVsZCBgYCwgZXhwZWN0ZWQgACwFEAAPAAAAOwUQAAwAAABgLCB0aGVyZSBhcmUgbm8gZmllbGRzAAAsBRAADwAAAFgFEAAWAAAAZHVwbGljYXRlIGZpZWxkIGAAAACABRAAEQAAABsFEAABAAAAdW5rbm93biB2YXJpYW50IGAAAACkBRAAEQAAADsFEAAMAAAAaW52YWxpZCBVaW50NjQgJycgLSDIBRAAEAAAANgFEAAEAAAAaW52YWxpZCBVaW50MTI4ICcAAADsBRAAEQAAANgFEAAEAAAAdWxsc3RhdGVhY3Rpb25pbmNyZW1lbnRzcmMvY29udHJhY3QucnMAACcGEAAPAAAANAAAAA0AAAByZXNldGNyYXRlcy5pbzpjdy1jb3VudGVyMC4xLjBtZXRob2Rvd25lcmNvdW50VW5hdXRob3JpemVkAAB2BhAADAAAAAwFEAAAAAAAcQYQAAUAAAAeBhAACQAAAEgGEAAFAAAAZ2V0X2NvdW50AAAArAYQAAkAAABHZXRDb3VudFJlc3BvbnNlU3RhdGUvcnVzdGMvODk3ZTM3NTUzYmJhOGI0Mjc1MWM2NzY1ODk2Nzg4OWQxMWVjZDEyMC9saWJyYXJ5L2NvcmUvc3JjL2l0ZXIvYWRhcHRlcnMvZW51bWVyYXRlLnJz1QYQAFsAAAAwAAAACQAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3cAAAAAYXR0ZW1wdCB0byBtdWx0aXBseSB3aXRoIG92ZXJmbG93AAAAKAAAAAgAAAAEAAAAKQAAACoAAAArAAAADAAAAAQAAAAsAAAALQAAAC4AAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5ACgAAAAAAAAAAQAAABkAAAAvcnVzdGMvODk3ZTM3NTUzYmJhOGI0Mjc1MWM2NzY1ODk2Nzg4OWQxMWVjZDEyMC9saWJyYXJ5L2FsbG9jL3NyYy9zdHJpbmcucnMA+AcQAEsAAADOCQAACQAAAGNvc213YXNtX3N0ZDo6cmVzdWx0czo6c3lzdGVtX3Jlc3VsdDo6U3lzdGVtUmVzdWx0PGNvc213YXNtX3N0ZDo6cmVzdWx0czo6Y29udHJhY3RfcmVzdWx0OjpDb250cmFjdFJlc3VsdDxjb3Ntd2FzbV9zdGQ6OmJpbmFyeTo6QmluYXJ5Pj4oAAAABAAAAAQAAAAvAAAAMAAAADEAAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlOiAAAPQIEAAqAAAAL3J1c3RjLzg5N2UzNzU1M2JiYThiNDI3NTFjNjc2NTg5Njc4ODlkMTFlY2QxMjAvbGlicmFyeS9jb3JlL3NyYy9pdGVyL3RyYWl0cy9hY2N1bS5ycwAAACgJEABVAAAAjQAAAAEAAABtaXNzaW5nIGZpZWxkIGBgkAkQAA8AAACfCRAAAQAAAGR1cGxpY2F0ZSBmaWVsZCBgAAAAsAkQABEAAACfCRAAAQAAAHVua25vd24gdmFyaWFudCBgYCwgZXhwZWN0ZWQgAAAA1AkQABEAAADlCRAADAAAACgAAAAEAAAABAAAADIAAAAvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZGVjb2RlLnJzABQKEABbAAAAbgAAAC8AAABhdHRlbXB0IHRvIHN1YnRyYWN0IHdpdGggb3ZlcmZsb3cAAAAUChAAWwAAAAMBAAA3AAAAFAoQAFsAAAADAQAAJAAAABQKEABbAAAABAEAACkAAAAUChAAWwAAACEBAAARAAAAFAoQAFsAAAAqAQAAKQAAABQKEABbAAAAKgEAABYAAAAUChAAWwAAAC4BAAApAAAAFAoQAFsAAAAuAQAAKAAAABQKEABbAAAALQEAABoAAAAUChAAWwAAADMBAAARAAAAFAoQAFsAAABBAQAADgAAABQKEABbAAAARAEAACcAAAAUChAAWwAAAEQBAAASAAAAFAoQAFsAAABHAQAACQAAABQKEABbAAAAWAEAABMAAAAUChAAWwAAAGYBAAApAAAAFAoQAFsAAAB4AQAADQAAABQKEABbAAAAggEAABEAAAAUChAAWwAAAIoBAAAVAAAAFAoQAFsAAACOAQAAMQAAAEltcG9zc2libGU6IG11c3Qgb25seSBoYXZlIDAgdG8gOCBpbnB1dCBieXRlcyBpbiBsYXN0IGNodW5rLCB3aXRoIG5vIGludmFsaWQgbGVuZ3Roc+QLEABUAAAAFAoQAFsAAACdAQAADgAAABQKEABbAAAAqAEAAA0AAAAUChAAWwAAALEBAAAJAAAAT3ZlcmZsb3cgd2hlbiBjYWxjdWxhdGluZyBvdXRwdXQgYnVmZmVyIGxlbmd0aAAAFAoQAFsAAACTAAAAIAAAABQKEABbAAAAJwIAAAUAAABJbnZhbGlkIFVURjgrAAAAFAAAAAQAAAAzAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Jhc2U2NC0wLjEzLjAvc3JjL2VuY29kZS5ycwDcDBAAWwAAADQAAAAFAAAAaW50ZWdlciBvdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIGJ1ZmZlciBzaXplAAAA3AwQAFsAAAAvAAAAEQAAACgAAAAIAAAABAAAADQAAAD0CBAAAAAAAGludmFsaWQgYmFzZTY0OiCgDRAAEAAAACgAAAAAAAAAAQAAADUAAAA2AAAANgAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9jb3Ntd2FzbS1zdGQtMS4xLjkvc3JjL3NlY3Rpb25zLnJzAADQDRAAYgAAABoAAAAQAAAA0A0QAGIAAAAaAAAABQAAANANEABiAAAAOQAAABgAAABDYW5ub3QgcmVhZCBzZWN0aW9uIGxlbmd0aAAAZA4QABoAAADQDRAAYgAAADcAAAAJAAAAVEw7RFI6IFZhbHVlIG11c3Qgbm90IGJlIGVtcHR5IGluIFN0b3JhZ2U6OnNldCBidXQgaW4gbW9zdCBjYXNlcyB5b3UgY2FuIHVzZSBTdG9yYWdlOjpyZW1vdmUgaW5zdGVhZC4gTG9uZyBzdG9yeTogR2V0dGluZyBlbXB0eSB2YWx1ZXMgZnJvbSBzdG9yYWdlIGlzIG5vdCB3ZWxsIHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50LiBTb21lIG9mIG91ciBpbnRlcm5hbCBpbnRlcmZhY2VzIGNhbm5vdCBkaWZmZXJlbnRpYXRlIGJldHdlZW4gYSBub24tZXhpc3RlbnQga2V5IGFuZCBhbiBlbXB0eSB2YWx1ZS4gUmlnaHQgbm93LCB5b3UgY2Fubm90IHJlbHkgb24gdGhlIGJlaGF2aW91ciBvZiBlbXB0eSB2YWx1ZXMuIFRvIHByb3RlY3QgeW91IGZyb20gdHJvdWJsZSBsYXRlciBvbiwgd2Ugc3RvcCBoZXJlLiBTb3JyeSBmb3IgdGhlIGluY29udmVuaWVuY2UhIFdlIGhpZ2hseSB3ZWxjb21lIHlvdSB0byBjb250cmlidXRlIHRvIENvc21XYXNtLCBtYWtpbmcgdGhpcyBtb3JlIHNvbGlkIG9uZSB3YXkgb3IgdGhlIG90aGVyLpgOEAAIAgAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvaW1wb3J0cy5ycwAAAKgQEABhAAAAawAAAA0AAAAoAAAABAAAAAQAAAA3AAAAOAAAADkAAAA6AAAAaW5wdXQgdG9vIGxvbmcgZm9yIGFkZHJfdmFsaWRhdGVhZGRyX3ZhbGlkYXRlIGVycm9yZWQ6IABYERAAFwAAAGlucHV0IHRvbyBsb25nIGZvciBhZGRyX2Nhbm9uaWNhbGl6ZWFkZHJfY2Fub25pY2FsaXplIGVycm9yZWQ6IACcERAAGwAAAGFkZHJfaHVtYW5pemUgZXJyb3JlZDogAMAREAAXAAAATWVzc2FnZVRvb0xvbmcgbXVzdCBub3QgaGFwcGVuLiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS7gERAAOAAAAKgQEABhAAAACAEAABIAAACoEBAAYQAAACUBAAASAAAASW52YWxpZEhhc2hGb3JtYXQgbXVzdCBub3QgaGFwcGVuLiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS4AQBIQADsAAACoEBAAYQAAAD8BAAASAAAARXJyb3IgY29kZSAyIHVudXNlZCBzaW5jZSBDb3NtV2FzbSAwLjE1LiBUaGlzIGlzIGEgYnVnIGluIHRoZSBWTS4AAACUEhAAQQAAAKgQEABhAAAAPgEAABIAAACoEBAAYQAAAF8BAAASAAAAqBAQAGEAAABeAQAAEgAAAFJlZ2lvbiBwb2ludGVyIGlzIG51bGwAABATEAAWAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL2Nvc213YXNtLXN0ZC0xLjEuOS9zcmMvbWVtb3J5LnJzMBMQAGAAAAA5AAAABQAAAFJlZ2lvbiBzdGFydHMgYXQgbnVsbCBwb2ludGVyAAAAoBMQAB0AAAAwExAAYAAAAD8AAAAFAAAAVW5rbm93biBlcnJvcjogANgTEAAPAAAASW52YWxpZCByZWNvdmVyeSBwYXJhbWV0ZXIuIFN1cHBvcnRlZCB2YWx1ZXM6IDAgYW5kIDEuAADwExAANgAAAEludmFsaWQgc2lnbmF0dXJlIGZvcm1hdDAUEAAYAAAASW52YWxpZCBoYXNoIGZvcm1hdABQFBAAEwAAAFVua25vd25FcnJlcnJvcl9jb2RlKAAAAAQAAAAEAAAAOwAAAEludmFsaWRSZWNvdmVyeVBhcmFtSW52YWxpZFNpZ25hdHVyZUZvcm1hdEludmFsaWRIYXNoRm9ybWF0Q29udmVyc2lvbiBlcnJvcjogAAAAyxQQABIAAABEaXZpZGUgYnkgemVybzog6BQQABAAAABPdmVyZmxvdzogAAAAFRAACgAAAEVycm9yIHNlcmlhbGl6aW5nIHR5cGUgOiAAAAAUFRAAFwAAACsVEAACAAAARXJyb3IgcGFyc2luZyBpbnRvIHR5cGUgQBUQABgAAAArFRAAAgAAACBub3QgZm91bmQAAPQIEAAAAAAAaBUQAAoAAABDYW5ub3QgZGVjb2RlIFVURjggYnl0ZXMgaW50byBzdHJpbmc6IAAAhBUQACYAAABJbnZhbGlkIGhleCBzdHJpbmc6ILQVEAAUAAAASW52YWxpZCBkYXRhIHNpemU6IGV4cGVjdGVkPSBhY3R1YWw90BUQABwAAADsFRAACAAAAEludmFsaWQgQmFzZTY0IHN0cmluZzogAAQWEAAXAAAAR2VuZXJpYyBlcnJvcjogACQWEAAPAAAAUmVjb3ZlciBwdWJrZXkgZXJyb3I6IAAAPBYQABYAAABWZXJpZmljYXRpb24gZXJyb3I6IFwWEAAUAAAAQ29udmVyc2lvbk92ZXJmbG93c291cmNlKAAAAAQAAAAEAAAAPAAAAERpdmlkZUJ5WmVybygAAAAEAAAABAAAAD0AAABPdmVyZmxvdygAAAAEAAAABAAAAD4AAABTZXJpYWxpemVFcnJzb3VyY2VfdHlwZW1zZ1BhcnNlRXJydGFyZ2V0X3R5cGVOb3RGb3VuZGtpbmRJbnZhbGlkVXRmOEludmFsaWRIZXhJbnZhbGlkRGF0YVNpemVleHBlY3RlZAAAACgAAAAEAAAABAAAAD8AAABhY3R1YWxJbnZhbGlkQmFzZTY0R2VuZXJpY0VyclJlY292ZXJQdWJrZXlFcnIAAAAoAAAABAAAAAQAAABAAAAAVmVyaWZpY2F0aW9uRXJyACgAAAAEAAAABAAAAEEAAABTaGxTaHJQb3dNdWxTdWJBZGRDYW5ub3QgIHdpdGggIGFuZCC+FxAABwAAAMUXEAAGAAAAyxcQAAUAAABPdmVyZmxvd0Vycm9yb3BlcmF0aW9uAAAoAAAABAAAAAQAAAAdAAAAb3BlcmFuZDFvcGVyYW5kMkNvbnZlcnNpb25PdmVyZmxvd0Vycm9yACgAAAAEAAAABAAAAEIAAAB2YWx1ZUNhbm5vdCBkZXZpZGUgIGJ5IHplcm8ATRgQAA4AAABbGBAACAAAAERpdmlkZUJ5WmVyb0Vycm9yb3BlcmFuZGludmFsaWRfcmVxdWVzdGludmFsaWRfcmVzcG9uc2Vub19zdWNoX2NvbnRyYWN0dW5rbm93bnVuc3VwcG9ydGVkX3JlcXVlc3QAAACMGBAADwAAAJsYEAAQAAAAqxgQABAAAAC7GBAABwAAAMIYEAATAAAAYWRkcmVycm9ycmVzcG9uc2VyZXF1ZXN0SW52YWxpZCBwdWJsaWMga2V5IGZvcm1hdAAAABgZEAAZAAAAR2VuZXJpYyBlcnJvcgAAADwZEAANAAAAQmF0Y2ggZXJyb3IAVBkQAAsAAABJbnZhbGlkUHVia2V5Rm9ybWF0QmF0Y2hFcnJvawAAAIMZEAACAAAABBkQAAUAAAC7FxAAuBcQALUXEACyFxAArxcQAKwXEABFAAAACAAAAAQAAABGAAAARwAAAEUAAAAIAAAABAAAAEgAAADEGRAAAAAAAEpTT04gaGFzIGEgY29tbWEgYWZ0ZXIgdGhlIGxhc3QgdmFsdWUgaW4gYW4gYXJyYXkgb3IgbWFwLkpTT04gaGFzIG5vbi13aGl0ZXNwYWNlIHRyYWlsaW5nIGNoYXJhY3RlcnMgYWZ0ZXIgdGhlIHZhbHVlLkZvdW5kIGEgbG9uZSBzdXJyb2dhdGUsIHdoaWNoIGNhbiBleGlzdCBpbiBKU09OIGJ1dCBjYW5ub3QgYmUgZW5jb2RlZCB0byBVVEYtOC5PYmplY3Qga2V5IGlzIG5vdCBhIHN0cmluZy5JbnZhbGlkIHVuaWNvZGUgY29kZSBwb2ludC5JbnZhbGlkIHR5cGVJbnZhbGlkIG51bWJlci5JbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS5FeHBlY3RlZCB0aGlzIGNoYXJhY3RlciB0byBzdGFydCBhIEpTT04gdmFsdWUuRXhwZWN0ZWQgdG8gcGFyc2UgZWl0aGVyIGEgYHRydWVgLCBgZmFsc2VgLCBvciBhIGBudWxsYC5FeHBlY3RlZCB0aGlzIGNoYXJhY3RlciB0byBiZSBlaXRoZXIgYSBgJywnYCBvciBhIGAnfSdgLkV4cGVjdGVkIGEgbG93IHN1cnJvZ2F0ZSAoREMwMOKAk0RGRkYpLkV4cGVjdGVkIHRoaXMgY2hhcmFjdGVyIHRvIGJlIGVpdGhlciBhIGAnLCdgIG9yYSBgJ10nYC5FeHBlY3RlZCBhIGhpZ2ggc3Vycm9nYXRlIChEODAw4oCTREJGRikuRXhwZWN0ZWQgdGhpcyBjaGFyYWN0ZXIgdG8gYmUgYSBgJzonYC5FT0Ygd2hpbGUgcGFyc2luZyBhIEpTT04gdmFsdWUuRU9GIHdoaWxlIHBhcnNpbmcgYSBzdHJpbmcuRU9GIHdoaWxlIHBhcnNpbmcgYW4gb2JqZWN0LkVPRiB3aGlsZSBwYXJzaW5nIGEgbGlzdC5Db250cm9sIGNoYXJhY3RlciBmb3VuZCBpbiBzdHJpbmcuL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3NlcmRlLWpzb24td2FzbS0wLjQuMS9zcmMvZGUvdW5lc2NhcGUucnPkHBAAaAAAACUAAAAVAAAAAAAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3fkHBAAaAAAADMAAAApAAAAAAAAAGF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvd05vbi1oZXggQVNDSUkgY2hhcmFjdGVyIGZvdW5kAADkHBAAaAAAAJkAAAAOAAAAL1VzZXJzL2RlYXJrYW5lLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3NlcmRlLWpzb24td2FzbS0wLjQuMS9zcmMvZGUvbW9kLnJzAOAdEABjAAAAJAAAAAkAAADgHRAAYwAAAH0AAAAiAAAA4B0QAGMAAACBAAAALAAAAEJ1ZmZlciBpcyBmdWxsAAB0HhAADgAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS1qc29uLXdhc20tMC40LjEvc3JjL3Nlci9tb2QucnOMHhAAZAAAALUAAAAJAAAAjB4QAGQAAADXAAAACQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGU6IAAAEB8QACoAQdC+wAALIWF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvdwBBgL/AAAv0JmF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3cvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZW5jb2RlLnJzAJwfEABbAAAAkgAAACcAAAB1c2l6ZSBvdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIGI2NCBsZW5ndGgAAJwfEABbAAAAlwAAABkAAACcHxAAWwAAALYAAAAgAAAAnB8QAFsAAAC3AAAAOgAAAJwfEABbAAAAtwAAACUAAACcHxAAWwAAAPcAAAAYAAAAnB8QAFsAAAD8AAAALwAAAJwfEABbAAAA/AAAABwAAACcHxAAWwAAAP0AAAA2AAAAnB8QAFsAAAD9AAAAIQAAAJwfEABbAAAAEwEAAC4AAACcHxAAWwAAABMBAAAJAAAAnB8QAFsAAAAUAQAACQAAAJwfEABbAAAACwEAAC4AAACcHxAAWwAAAAsBAAAJAAAAnB8QAFsAAAANAQAADwAAAJwfEABbAAAADAEAAAkAAACcHxAAWwAAAA8BAAAJAAAAnB8QAFsAAAARAQAACQAAAEltcG9zc2libGUgcmVtYWluZGVyVCEQABQAAACcHxAAWwAAACoBAAAWAAAAnB8QAFsAAAA7AQAACQAAAEludmFsaWQgbGFzdCBzeW1ib2wgLCBvZmZzZXQgLgAAkCEQABQAAACkIRAACQAAAK0hEAABAAAARW5jb2RlZCB0ZXh0IGNhbm5vdCBoYXZlIGEgNi1iaXQgcmVtYWluZGVyLgDIIRAAKwAAAEludmFsaWQgYnl0ZSAAAAD8IRAADQAAAKQhEAAJAAAArSEQAAEAAABPdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIG51bWJlciBvZiBjaHVua3MgaW4gaW5wdXQvVXNlcnMvZGVhcmthbmUvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTMuMC9zcmMvZGVjb2RlLnJzAABXIhAAWwAAALkAAAAFAAAAISIjJCUmJygpKissLTAxMjM0NTY3ODlAQUJDREVGR0hJSktMTU5QUVJTVFVWWFlaW2BhYmNkZWhpamtsbXBxckFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5KywuL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Li8wMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5LV9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsv////////////////////////////////////////////AAECAwQFBgcICQoLDP//DQ4PEBESExQVFv///////xcYGRobHB0eHyAhIiMkJf8mJygpKiss/y0uLzD/////MTIzNDU2//83ODk6Ozz//z0+P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8+P////zQ1Njc4OTo7PD3/////////AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBn///////8aGxwdHh8gISIjJCUmJygpKissLS4vMDEyM///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAE2Nzg5Ojs8PT4//////////wIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob////////HB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDX//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wABAgMEBQYHCAkKC/////////8MDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJf///////yYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z7//zQ1Njc4OTo7PD3/////////AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBn/////P/8aGxwdHh8gISIjJCUmJygpKissLS4vMDEyM///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Pv///z80NTY3ODk6Ozw9/////////wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ////////GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////BCQQAMQjEACEIxAARCMQAAQjEADEIhAARCkQAEQoEABEJxAARCYQAEQlEABEJBAATgAAAAgAAAAEAAAATwAAAFAAAABOAAAACAAAAAQAAABRAAAAYG9uZSBvZiCZKhAABwAAACwgAACoKhAAAgAAAJgqEAABAAAAmCoQAAEAAABgIG9yIGAAAJgqEAABAAAAxCoQAAYAAACYKhAAAQAAAC9Vc2Vycy9kZWFya2FuZS8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS0xLjAuMTUwL3NyYy9kZS9tb2QucnNleHBsaWNpdCBwYW5pYwAAAOQqEABbAAAA7QgAABIAAABTAAAABAAAAAQAAABUAAAAVQAAAFYAAABjYWxsZWQgYE9wdGlvbjo6dW53cmFwKClgIG9uIGEgYE5vbmVgIHZhbHVlbWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAoAAKMrEAAVAAAAuCsQAA4AAABsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnPYKxAAGAAAAFUBAAAJAAAAY2Fubm90IG1vZGlmeSB0aGUgcGFuaWMgaG9vayBmcm9tIGEgcGFuaWNraW5nIHRocmVhZAAsEAA0AAAAbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5yczwsEAAcAAAAfQAAAAkAAAA8LBAAHAAAAEcCAAAPAAAAPCwQABwAAABGAgAADwAAAFcAAAAMAAAABAAAAFgAAABTAAAACAAAAAQAAABZAAAAWgAAABAAAAAEAAAAWwAAAFwAAABTAAAACAAAAAQAAABdAAAAXgAAAF8AAAAEAAAABAAAAGAAAABhAAAAYgAAAF8AAAAEAAAABAAAAGMAAABsaWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJzY2FwYWNpdHkgb3ZlcmZsb3cAAAAULRAAEQAAAPgsEAAcAAAABgIAAAUAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IAXwAAAAAAAAABAAAAGQAAAGxpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5yc4QtEAAYAAAAZAIAAAkAAAApbGlicmFyeS9hbGxvYy9zcmMvdmVjL21vZC5ycykgc2hvdWxkIGJlIDw9IGxlbiAoaXMgYGF0YCBzcGxpdCBpbmRleCAoaXMgAAAA4C0QABUAAADJLRAAFwAAAKwtEAABAAAArS0QABwAAADLBwAADQAAAF8AAAAEAAAABAAAAGQAAABieXRlc2Vycm9yAABfAAAABAAAAAQAAABlAAAARnJvbVV0ZjhFcnJvcgAAAGNhbGxlZCBgT3B0aW9uOjp1bndyYXAoKWAgb24gYSBgTm9uZWAgdmFsdWVudW1iZXIgd291bGQgYmUgemVybyBmb3Igbm9uLXplcm8gdHlwZW51bWJlciB0b28gc21hbGwgdG8gZml0IGluIHRhcmdldCB0eXBlbnVtYmVyIHRvbyBsYXJnZSB0byBmaXQgaW4gdGFyZ2V0IHR5cGVpbnZhbGlkIGRpZ2l0IGZvdW5kIGluIHN0cmluZ2Nhbm5vdCBwYXJzZSBpbnRlZ2VyIGZyb20gZW1wdHkgc3RyaW5nKS4uAD0vEAACAAAAaW5kZXggb3V0IG9mIGJvdW5kczogdGhlIGxlbiBpcyAgYnV0IHRoZSBpbmRleCBpcyAAAEgvEAAgAAAAaC8QABIAAAA6AAAAXC4QAAAAAACMLxAAAQAAAIwvEAABAAAAcGFuaWNrZWQgYXQgJycsILQvEAABAAAAtS8QAAMAAABcLhAAAAAAAG0AAAAAAAAAAQAAAG4AAABgOiAAXC4QAAAAAADhLxAAAgAAAG0AAAAMAAAABAAAAG8AAABwAAAAcQAAACAgICAgewosCiwgIHsgfSB9KAooLApbAG0AAAAEAAAABAAAAHIAAABdbGlicmFyeS9jb3JlL3NyYy9mbXQvbnVtLnJzNTAQABsAAABlAAAAFAAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlhc3NlcnRpb24gZmFpbGVkOiAqY3VyciA+IDE5AAA1MBAAGwAAAOUBAAAFAAAAbQAAAAQAAAAEAAAAcwAAAHQAAAB1AAAAbGlicmFyeS9jb3JlL3NyYy9mbXQvbW9kLnJzAHAxEAAbAAAAdAkAAB4AAABwMRAAGwAAAHsJAAAWAAAAbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tZW1jaHIucnOsMRAAIAAAAGgAAAAnAAAAcmFuZ2Ugc3RhcnQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoINwxEAASAAAA7jEQACIAAAByYW5nZSBlbmQgaW5kZXggIDIQABAAAADuMRAA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"
}
ParameterTypeDescription
databyte array

Codes

Gets the metadata for all stored contract codes

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    limit = 2
    pagination = PaginationOption(limit=limit)
    response = await client.fetch_codes(pagination=pagination)
    print(response)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchCodes(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "codeInfos":[
      {
         "codeId":"1",
         "creator":"inj180rl9ezc4389t72pc3vvlkxxs5d9jx60w9eeu3",
         "dataHash":"y9Pfljq5aQPc3nx8Apg3IeUw4JZ15GQe6mp577XlaQc=",
         "instantiatePermission":{
            "permission":"ACCESS_TYPE_EVERYBODY",
            "addresses":[

            ]
         }
      },
      {
         "codeId":"2",
         "creator":"inj180rl9ezc4389t72pc3vvlkxxs5d9jx60w9eeu3",
         "dataHash":"rKYFl6749PJgIK4stNXmpWv7UdX+4rcR6UaGK4JUhu8=",
         "instantiatePermission":{
            "permission":"ACCESS_TYPE_EVERYBODY",
            "addresses":[

            ]
         }
      }
   ],
   "pagination":{
      "nextKey":"AAAAAAAAAAM=",
      "total":"0"
   }
}
{
 "code_infos": [
  {
   "id": 1,
   "creator": "inj180rl9ezc4389t72pc3vvlkxxs5d9jx60w9eeu3",
   "data_hash": "CBD3DF963AB96903DCDE7C7C02983721E530E09675E4641EEA6A79EFB5E56907",
   "instantiate_permission": {
    "permission": "Everybody"
   }
  },
  {
   "id": 2,
   "creator": "inj180rl9ezc4389t72pc3vvlkxxs5d9jx60w9eeu3",
   "data_hash": "ACA60597AEF8F4F26020AE2CB4D5E6A56BFB51D5FEE2B711E946862B825486EF",
   "instantiate_permission": {
    "permission": "Everybody"
   }
  }
 ],
 "pagination": {
  "next_key": "AAAAAAAAAAM="
 }
}

ParameterTypeDescription
code_infosCodeInfoResponse array
paginationquery.PageResponsepagination defines the pagination in the response.


CodeInfoResponse

ParameterTypeDescription
code_iduint64
creatorstring
data_hashgithub_com_cometbft_cometbft_libs_bytes.HexBytes
instantiate_permissionAccessConfig


AccessConfig

ParameterTypeDescription
permissionAccessType
addressesstring array


AccessType

CodeName
0ACCESS_TYPE_UNSPECIFIED
1ACCESS_TYPE_NOBODY
3ACCESS_TYPE_EVERYBODY
4ACCESS_TYPE_ANY_OF_ADDRESSES


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

PinnedCodes

Gets the pinned code ids

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    limit = 2
    pagination = PaginationOption(limit=limit)
    response = await client.fetch_pinned_codes(pagination=pagination)
    print(response)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchPinnedCodes(ctx, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
paginationquery.PageRequestpagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "codeIds":[
      "135",
      "136"
   ],
   "pagination":{
      "nextKey":"AAAAAAAAAIk=",
      "total":"0"
   }
}
{
 "code_ids": [
  135,
  136
 ],
 "pagination": {
  "next_key": "AAAAAAAAAIk="
 }
}

ParameterTypeDescription
code_idsuint64 array
paginationquery.PageResponsepagination defines the pagination in the response.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

ContractsByCreator

Gets the contracts by creator

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    creator = "inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty"
    limit = 2
    pagination = PaginationOption(limit=limit)
    response = await client.fetch_contracts_by_creator(creator_address=creator, pagination=pagination)
    print(response)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/cosmos/cosmos-sdk/types/query"

    "os"

    "github.com/InjectiveLabs/sdk-go/client"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    rpchttp "github.com/cometbft/cometbft/rpc/client/http"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )

    if err != nil {
        panic(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
        common.OptionGasPrices(client.DefaultGasPriceWithDenom),
    )

    if err != nil {
        panic(err)
    }

    creator := "inj1h3gepa4tszh66ee67he53jzmprsqc2l9npq3ty"
    pagination := query.PageRequest{Limit: 2}
    ctx := context.Background()

    res, err := chainClient.FetchContractsByCreator(ctx, creator, &pagination)
    if err != nil {
        fmt.Println(err)
    }

    str, _ := json.MarshalIndent(res, "", "\t")
    fmt.Print(string(str))

}
ParameterTypeDescriptionRequired
creator_addressstringCreatorAddress is the address of contract creatorYes
paginationquery.PageRequestPagination defines an optional pagination for the request.No


PageRequest

ParameterTypeDescriptionRequired
keybyte arraykey is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.Yes
offsetuint64offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set.Yes
limituint64limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.Yes
count_totalboolcount_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.Yes
reverseboolreverse is set to true if results are to be returned in the descending order. Since: cosmos-sdk 0.43Yes

Response Parameters

Response Example:

{
   "contractAddresses":[
      "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
   ],
   "pagination":{
      "nextKey":"",
      "total":"0"
   }
}
{
 "contract_addresses": [
  "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7"
 ],
 "pagination": {}
}

ParameterTypeDescription
contract_addressesstring arrayContractAddresses result set
paginationquery.PageResponsePagination defines the pagination in the response.


PageResponse

ParameterTypeDescription
next_keybyte arraynext_key is the key to be passed to PageRequest.key to query the next page most efficiently. It will be empty if there are no more results.
totaluint64total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise

MsgExecuteContract

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    # set custom cookie location (optional) - defaults to current dir
    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    # NOTE: COIN MUST BE SORTED IN ALPHABETICAL ORDER BY DENOMS
    funds = [
        composer.coin(
            amount=69,
            denom="factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj12ngevx045zpvacus9s6anr258gkwpmthnz80e9",
        ),
        composer.coin(amount=420, denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7"),
        composer.coin(amount=1, denom="peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"),
    ]
    msg = composer.msg_execute_contract(
        sender=address.to_acc_bech32(),
        contract="inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
        msg='{"increment":{}}',
        funds=funds,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringSender is the that actor that signed the messagesYes
contractstringContract is the address of the smart contractYes
msgRawContractMessageMsg json encoded message to be passed to the contractYes
fundsgithub_com_cosmos_cosmos_sdk_types.CoinsFunds coins that are transferred to the contract on executionYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Example:

txhash: "814807A5C827FC385DF6108E52494E63A2010F36B1D6F36E43B2AEED5D530D60"
raw_log: "[]"

gas wanted: 217930
gas fee: 0.000108965 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

MsgExecuteContract (second example)

This example shows how to interact with a contract to execute the guardian_set_info functionality using the post_message method in the contract. The parameter sent to the post_message function has to be encoded in Base64 format.

Request Parameters

Request Example:

import asyncio
import base64
import json
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.constant import GAS_FEE_BUFFER_AMOUNT, GAS_PRICE
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey, Address


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e")
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()
    await client.fetch_account(address.to_acc_bech32())

    contract_message = '{"guardian_set_info":{}}'
    encoded_message = base64.b64encode(contract_message.encode(encoding="utf-8")).decode()

    execute_message_parameter = {
        "post_message": {
            "message": encoded_message,
            "nonce": 1}
    }

    # prepare tx msg
    msg = composer.MsgExecuteContract(
        sender=address.to_acc_bech32(),
        contract="inj14hj2tavq8fpesdwxxcu44rty3hh90vhujaxlnz",
        msg=json.dumps(execute_message_parameter),
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(client.get_sequence())
        .with_account_num(client.get_number())
        .with_chain_id(network.chain_id)
    )
    sim_sign_doc = tx.get_sign_doc(pub_key)
    sim_sig = priv_key.sign(sim_sign_doc.SerializeToString())
    sim_tx_raw_bytes = tx.get_tx_data(sim_sig, pub_key)

    # simulate tx
    try:
        sim_res = await client.simulate(sim_tx_raw_bytes)
    except RpcError as ex:
        print(ex)
        return

    # build tx
    gas_price = GAS_PRICE
    gas_limit = int(sim_res["gasInfo"]["gasUsed"]) + GAS_FEE_BUFFER_AMOUNT  # add buffer for gas fee computation
    gas_fee = '{:.18f}'.format((gas_price * gas_limit) / pow(10, 18)).rstrip('0')
    fee = [composer.Coin(
        amount=gas_price * gas_limit,
        denom=network.fee_denom,
    )]
    tx = tx.with_gas(gas_limit).with_fee(fee).with_memo('').with_timeout_height(client.timeout_height)
    sign_doc = tx.get_sign_doc(pub_key)
    sig = priv_key.sign(sign_doc.SerializeToString())
    tx_raw_bytes = tx.get_tx_data(sig, pub_key)

    # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
    res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
ParameterTypeDescriptionRequired
senderstringSender is the that actor that signed the messagesYes
contractstringContract is the address of the smart contractYes
msgRawContractMessageMsg json encoded message to be passed to the contractYes
fundsgithub_com_cosmos_cosmos_sdk_types.CoinsFunds coins that are transferred to the contract on executionYes


Coin

ParameterTypeDescription
denomstring
amountcosmossdk_io_math.Int

Response Parameters

Response Example:

txhash: "03DDA0A4B49EF093CCC2999435D6D23C71A570B84E588137A0D314F73F5A336B"
raw_log: "[]"

gas wanted: 139666
gas fee: 0.000069833 INJ
ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Wasmx

Wasmx smart contract interactions.

MsgExecuteContractCompat

IP rate limit group: chain

Request Parameters

Request Example:

import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    dotenv.load_dotenv()
    private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
    composer = await client.composer()

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)

    message_broadcaster = MsgBroadcasterWithPk.new_using_gas_heuristics(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    priv_key = PrivateKey.from_hex(private_key_in_hexa)
    pub_key = priv_key.to_public_key()
    address = pub_key.to_address()

    # prepare tx msg
    # NOTE: COIN MUST BE SORTED IN ALPHABETICAL ORDER BY DENOMS
    funds = (
        "69factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj12ngevx045zpvacus9s6anr258gkwpmthnz80e9,"
        "420peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7,"
        "1peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    )

    msg = composer.msg_execute_contract_compat(
        sender=address.to_acc_bech32(),
        contract="inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
        msg=json.dumps({"increment": {}}),
        funds=funds,
    )

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

    gas_price = await client.current_chain_gas_price()
    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gas_price = int(gas_price * 1.1)
    message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "os"
    "time"

    rpchttp "github.com/cometbft/cometbft/rpc/client/http"

    wasmxtypes "github.com/InjectiveLabs/sdk-go/chain/wasmx/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
)

func main() {
    network := common.LoadNetwork("testnet", "lb")
    tmClient, err := rpchttp.New(network.TmEndpoint)
    if err != nil {
        panic(err)
    }

    senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring(
        os.Getenv("HOME")+"/.injectived",
        "injectived",
        "file",
        "inj-user",
        "12345678",
        "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided
        false,
    )

    if err != nil {
        panic(err)
    }

    clientCtx, err := chainclient.NewClientContext(
        network.ChainId,
        senderAddress.String(),
        cosmosKeyring,
    )
    if err != nil {
        fmt.Println(err)
        return
    }
    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmClient)

    chainClient, err := chainclient.NewChainClientV2(
        clientCtx,
        network,
    )

    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    gasPrice := chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)

    firstAmount := 69
    firstToken := "factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj12ngevx045zpvacus9s6anr258gkwpmthnz80e9"
    secondAmount := 420
    secondToken := "peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7"
    thirdAmount := 1
    thirdToken := "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"
    funds := fmt.Sprintf(
        "%v%s,%v%s,%v%s",
        firstAmount,
        firstToken,
        secondAmount,
        secondToken,
        thirdAmount,
        thirdToken,
    )

    message := wasmxtypes.MsgExecuteContractCompat{
        Sender:   senderAddress.String(),
        Contract: "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
        Msg:      "{\"increment\": {}}",
        Funds:    funds,
    }

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    response, err := chainClient.AsyncBroadcastMsg(ctx, &message)

    if err != nil {
        panic(err)
    }

    str, _ := json.MarshalIndent(response, "", "\t")
    fmt.Println(string(str))

    gasPrice = chainClient.CurrentChainGasPrice(ctx)
    // adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
    gasPrice = int64(float64(gasPrice) * 1.1)
    chainClient.SetGasPrice(gasPrice)
}
ParameterTypeDescriptionRequired
senderstringSender is the that actor that signed the messagesYes
contractstringContract is the address of the smart contractYes
msgstringMsg json encoded message to be passed to the contractYes
fundsstringFunds coins that are transferred to the contract on executionYes

Response Parameters

Response Example:

ParameterTypeDescription
tx_responsetypes.TxResponsetx_response is the queried TxResponses.


TxResponse

ParameterTypeDescription
heightint64The block height
txhashstringThe transaction hash.
codespacestringNamespace for the Code
codeuint32Response code.
datastringResult bytes, if any.
raw_logstringThe output of the application's logger (raw string). May be non-deterministic.
logsABCIMessageLogsThe output of the application's logger (typed). May be non-deterministic.
infostringAdditional information. May be non-deterministic.
gas_wantedint64Amount of gas requested for transaction.
gas_usedint64Amount of gas consumed by transaction.
txtypes.AnyThe request transaction bytes.
timestampstringTime of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time.
eventsv1.Event arrayEvents defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages. Since: cosmos-sdk 0.42.11, 0.44.5, 0.45


ABCIMessageLog

ParameterTypeDescription
msg_indexuint32
logstring
eventsStringEventsEvents contains a slice of Event objects that were emitted during some execution.

- Historical Queries

Execute historical chain queries by passing the block height in the headers. Keep in mind that the chain node being used in the query should not be pruned for the height specified.

Publicly maintained nodes are being pruned every 5-10 days.

To find the available chain queries visit Swagger for Mainnet and Testnet.

Request Parameters

Request Example:

import requests
import asyncio
import logging

async def main() -> None:
    block_height = "9858070"
    lcd = "https://testnet.lcd.injective.network/injective/exchange/v1beta1/derivative/orderbook/0x2e94326a421c3f66c15a3b663c7b1ab7fb6a5298b3a57759ecf07f0036793fc9"
    lcd_request = requests.get(lcd, headers={"Content-Type": "application/json", "x-cosmos-block-height": "{}".format(block_height)}).json()
    print(lcd_request)

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

func queryAtHeight(url, method string, height int64) ([]byte, error) {
    client := &http.Client{
        Timeout: time.Second * 10,
    }

    req, err := http.NewRequest(method, url, nil)
    if err != nil {
        return nil, fmt.Errorf("new request err: %w", err)
    }

    req.Header.Set("x-cosmos-block-height", fmt.Sprintf("%d", height))
    response, err := client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("exec request err: %w", err)
    }
    defer response.Body.Close()

    return ioutil.ReadAll(response.Body)
}

func main() {
    result, err := queryAtHeight("https://testnet.lcd.injective.network/injective/exchange/v1beta1/derivative/orderbook/0x2e94326a421c3f66c15a3b663c7b1ab7fb6a5298b3a57759ecf07f0036793fc9", "GET", 9858070)
    if err != nil {
        panic(err)
    }

    fmt.Println("query result:", string(result))
}
Parameter Type Description Required
block_height String The block height at which we want to execute the query Yes

Response Example:

query result:  {'buys_price_level': [{'p': '30624950000.000000000000000000', 'q': '4.000000000000000000'}, {'p': '29885630000.000000000000000000', 'q': '3.000000000000000000'}, {'p': '29710520000.000000000000000000', 'q': '3.000000000000000000'}, {'p': '29321790000.000000000000000000', 'q': '2.000000000000000000'}, {'p': '28861950000.000000000000000000', 'q': '1.000000000000000000'}, {'p': '28766450000.000000000000000000', 'q': '1.000000000000000000'}, {'p': '28386560000.000000000000000000', 'q': '4.000000000000000000'}, {'p': '28378550000.000000000000000000', 'q': '2.000000000000000000'}, {'p': '27677610000.000000000000000000', 'q': '6.000000000000000000'}, {'p': '26828710000.000000000000000000', 'q': '1.000000000000000000'}, {'p': '26773560000.000000000000000000', 'q': '8.000000000000000000'}, {'p': '26479000000.000000000000000000', 'q': '9.000000000000000000'}, {'p': '26203470000.000000000000000000', 'q': '16.000000000000000000'}, {'p': '26038150000.000000000000000000', 'q': '14.000000000000000000'}], 'sells_price_level': []}
query result: {
  "buys_price_level": [
    {
      "p": "30624950000.000000000000000000",
      "q": "4.000000000000000000"
    },
    {
      "p": "29885630000.000000000000000000",
      "q": "3.000000000000000000"
    },
    {
      "p": "29710520000.000000000000000000",
      "q": "3.000000000000000000"
    },
    {
      "p": "29321790000.000000000000000000",
      "q": "2.000000000000000000"
    },
    {
      "p": "28861950000.000000000000000000",
      "q": "1.000000000000000000"
    },
    {
      "p": "28766450000.000000000000000000",
      "q": "1.000000000000000000"
    },
    {
      "p": "28386560000.000000000000000000",
      "q": "4.000000000000000000"
    },
    {
      "p": "28378550000.000000000000000000",
      "q": "2.000000000000000000"
    },
    {
      "p": "27677610000.000000000000000000",
      "q": "6.000000000000000000"
    },
    {
      "p": "26828710000.000000000000000000",
      "q": "1.000000000000000000"
    },
    {
      "p": "26773560000.000000000000000000",
      "q": "8.000000000000000000"
    },
    {
      "p": "26479000000.000000000000000000",
      "q": "9.000000000000000000"
    },
    {
      "p": "26203470000.000000000000000000",
      "q": "16.000000000000000000"
    },
    {
      "p": "26038150000.000000000000000000",
      "q": "14.000000000000000000"
    }
  ],
  "sells_price_level": [
  ]
}

- HealthAPI

HealthAPI (HTTP) checks if backend data is up-to-date and reliable or not.

GetStatus

IP rate limit group: chain

To check the health of a node, the GetStatus API can be queried to obtain the Indexer height (localHeight) and the network height (horacleHeight). Next, the chain node height can be queried directly from the node (e.g. curl --insecure http://sentry.lcd.injective.network:26657/abci_info | grep last_block_height or in Python (await async_client.get_latest_block()).block.header.height). Comparing last_block_height with horacleHeight gives a sense of the chain node's health, with a threshold of a 20 block difference being a good starting point for detecting unhealthy nodes. localHeight and horacleHeight can also be compared to check Indexer health, though an error should already be returned from the API query if the Indexer is deemed unhealthy (more than 20 block height difference).

If LB/K8S endpoints are being used, there is no need to do these checks, as the cluster has built-in liveliness checks and excludes unhealthy nodes if any are detected.

A recommended health check frequency of once every 20-30 seconds is recommended.

Notes

horacleHeight: the network height of the chain (average returned by multiple nodes in the network)

localHeight: the latest synced block on the indexer

lastBlock: the latest synced block on the chain

Request Parameters

Request Example:

import requests

def main() -> None:
    r = requests.get('https://sentry.lcd.injective.network:4444/api/health/v1/status', verify=False)
    print(r.text)

if __name__ == '__main__':
    main()

package main

import (
  "crypto/tls"
  "fmt"
  "io/ioutil"
  "net/http"
  "time"
)

func queryHealthAPI(url, method string) ([]byte, error) {
  tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  }
  client := &http.Client{
    Transport: tr,
    Timeout:   time.Second * 10,
  }

  req, err := http.NewRequest(method, url, nil)
  if err != nil {
    return nil, fmt.Errorf("new request err: %w", err)
  }

  response, err := client.Do(req)
  if err != nil {
    return nil, fmt.Errorf("exec request err: %w", err)
  }
  defer response.Body.Close()

  return ioutil.ReadAll(response.Body)
}

func main() {
  result, err := queryHealthAPI("https://sentry.lcd.injective.network:4444/api/health/v1/status", "GET")
  if err != nil {
    panic(err)
  }

  fmt.Println("query result:", string(result))
}

Response Parameters

Response Example:

{
  "s": "",
  "data": {
    "localHeight": 26953309,
    "localTimestamp": 1677042872,
    "horacleHeight": 26953309,
    "horacleTimestamp": 1677042872
  }
}
ParameterTypeDescription
sstringStatus of the response.
errmsgstringError message.
dataHealthStatus
statusstring


HealthStatus

ParameterTypeDescription
local_heightint32Block height from local mongo exchange db.
local_timestampint32block timestamp from local mongo exchange db.
horacle_heightint32block height from Horacle service.
horacle_timestampint32block timestamp from Horacle service.
migration_last_versionint32Migration version of the database.
ep_heightint32Block height from event provider service.
ep_timestampint32Block UNIX timestamp from event provider service.

Glossary

Injective Chain

The Injective Chain refers to the blockchain running the Injective Protocol. It is is the fundamental piece of infrastructure and ultimate source of truth for any trades happening on the network.

Validator / Injective Node

A validator is a node for the Injective Chain. The term node itself refers to a host computer in a network. In the context of blockchains, nodes are the computers participating in producing new blocks and validating new transactions in a peer-to-peer fashion. All on-chain code for Injective is executed on the hardware of every validator, in contrast to a CEX where code is executed on a central server.

On-chain Matching

The matching algorithm is executed as part of validating the chain. It is executed on the hardware of every validator. Therefore it must be deterministic, so every validator comes to the same matching result. For fairness reasons the matching algorithm consists of frequent batch auctions (FBA).

Frequent Batch Auction (FBA)

Frequent Batch Auctions (FBA) are ensuring fair order matching prices by calculating one uniform clearing price over all orders in the same block. Rather than calculating the clearing price for every order, the FBA algorithm calculates the clearing price for a batch of orders. For more details, here.

Relayer

The Injective Chain itself provides no historical data, no detailed statistics and no front-end. This is the role of the relayer. A relayer will index data emitted from the Injective Chain to provide an additional API and front-end.

Mempool

A mempool refers to pending transactions in a blockchain. It is the place where transactions are stored before they are included in a block.

gRPC

gRPC is a high-performance, open-source, general-purpose RPC framework that is used by the Injective Chain. It is used to communicate with the Injective Chain and the relayer.

Mark Price

Mark price refers to the oracle price for the underlying asset in a futures market. It is used to determine when a position is liquidable. Only when the mark price falls below your position's liquidation price, the position can be liquidated. The mark price is further used for market settlements, either in the case of an emergency stop due to the insurance fund draining or in the case of planned settlements for time-expiry future markets.

Perpetual Swap

A perpetual swap is a futures contract without expiry date. Since those contracts never expire with a settlement price, a new mechanism is used to align future contract prices with the mark price: the funding rate.

Funding Rate

In perpetual swaps a funding rate is used to align future contract prices with the mark price. The funding rate is calculated by keeping track of the volume weighted average of the deltas from mark price vs. trade execution price. It is applied to a position proportionally to the position's size.

FAQ

1. What are the trading fees on Injective?

Trading fees differ per market and are defined through governance for both maker and taker orders. The fees can also be reduced based on your tier which is determined based on your staked INJ and 30-day trailing fees.

Note that if you place trades through the API, you will only pay 60% of the trading fees regardless if your order is filled as a maker or taker. In every exchange-related message you can set recipient_fee to your own address in order to collect 40% of the trading fees. On the DEX UI, recipient_fee is set to the relayer's address which acts as a source of revenue but on the API you can set this field to any address of your choosing, including your own.

The DEX UI will also show you the full fees but if you have placed a trade through the API you would have paid only 60% of those fees.

2. What are the gas fees on Injective?

If you place trades through the UI on one of the available relayers you can experience gas-less trading, if you place trades from the API you will pay gas fees in INJ but they will be very low at an average of 0.00005 INJ per message. Note that the INJ to pay for gas must be in the bank balance (wallet) and not the subaccount (trading account).

3. How can I calculate the gas fees in INJ?

The minimum gas price currently accepted by nodes is 160000000. In order to find the exact INJ amount paid you multiply the gas wanted by the minimum gas price and divide by 1e18 (because INJ token has 18 decimals). For instance, if gas wanted is 104519 then you would calculate it as follows:

160000000 * 104519 / 1e18 = 0.00001672304 INJ

4. Which API nodes can I connect to?

The SDKs default to using a load balanced endpoint. It is possible also to run a local node. The guide to set up your own node can be found here.

5. Does Injective have an API support channel?

Yes, you can join the Discord and Telegram API channels to ask any questions you might have or if you need any support.

6. Can I get the order_hash (order_id) right after I send a new order?

Yes, you can actually fetch the order_hash before you even send the transaction through our simulation, you can see the Chain API examples on how to use the simulation.

A better alternative is to set a client order id (cid) to the orders. It is possible to then cancel the orders by cid instead of hash. With this it is no longer necessary to calculate the order hash in advance.

7. Are there limits in the API requests?

All public nodes have limits to the number of request they allow per IP. Please check the rate limits page.

8. What is the normal order latency I can expect?

There's no guarantee on when the chain will process your transaction. It depends on the peer to peer gossip of the network and whether your transaction reaches a given block producer to get included in a block. You can read more details about this here https://docs.tendermint.com/v0.35/assets/img/tm-transaction-flow.258ca020.png as well as the docs here https://docs.tendermint.com/v0.35/introduction/what-is-tendermint.html

We strongly recommend following the guide to setup your own infrastructure which will ultimately reduce latency to a great extent.

Following we include more details regarding transactions latency and blocks production:

- Validators might miss consensus rounds which will delay block production (instead of a 800ms block, we’ll have a 5000ms block). This happens very rarely and it’s due to issues on the validator node (they have a big chain state and they need to download a pruned snapshot, hardware resources etc.). We’re working with all validators to ensure these don’t take place anymore. This was the issue you mentioned last time with block 61885380 above. Additionally, we can decrease the block proposal timeout so we can lower the delayed block from a missed consensus round if this ever takes place again.

- Even though the Tendermint/CometBFT docs don’t make this clear, transactions are only executed in the next block - a concept called deferred/next-block execution. You can find more details/discussion on Github from the core teams: https://github.com/tendermint/tendermint/issues/7898. This means that if you send txs in block N, they are only executed in block N+1.

- There’s a max block gas limit which is currently set to 50M. This prevents spamming/DDoS attacks since if it has very high or even -1, this would allow one to send huge transactions and delay block time by minutes since the node would take a while to process each tx. We’ve observed that we’re currently hitting the block gas limit and we’re going to put up a proposal soon to increase it. This means that even though the validator mempool might have 100 txs, only 40 or 50 will be included (up to 50M gas) so you’re experiencing unnecessary delay. As an example, this tx spent 1M gas: https://explorer.injective.network/transaction/2CC4E5A54D23AF6CC599E7A4328CAE2EFBF6719F40976985E2381A3411B6DD0A/. There are other txs that spend 200K or even 3-5M in gas. Based on some empirical observations, a reasonable gas increase in the block will not cause any performance issues but we’re running more extensive tests and we’ll put up a proposal soon. We’ll be increasing this value progressively as we scale up along with some on-chain improvements.

- As more nodes get online in the network, this will increase the P2P latency. Gossip latency might increase depending on the peers on the node you sent your tx. Consider this scenario:

A. There are 400 nodes online in the network, the node you broadcast to has 40 peers but none of these peers is the validator proposing the next block.

B. Your node will gossip to its 40 peers, then these 40 peers will gossip to the next peers etc.

C. We don’t have metrics as to how long it takes for a tx to be gossiped but there’s some latency involved here since every node will run checkTx/validations before it includes the tx in its mempool.

On the other hand, your node might have direct peering with the block proposer for the upcoming block so you have zero P2P latency.

9. Can I have my own client id to send messages through the API?

No, we don't store private information on the Injective Chain.

10. Would I save gas fees if I batch messages in transactions?

Yes, a transaction includes fields such as messages, fee, signatures, memo and timeout height. When you send a batch of messages in a single transaction, the transaction size is less than the cumulative transaction size of individual transactions which ultimately results in less gas fees.

11. What is the timeout_height?

The timeout_height specifies a height at which your transaction will timeout and eventually prevents it from being committed past a certain height. Essentially, the transaction will be discarded from the mempool (timeout) after the block with number timeout_height has been mined and your sequence number is cleared if a bad transaction with a lower account sequence does not get processed correctly.

12. Do fee discounts apply to all markets?

Discounts apply to all markets apart from markets that have negative maker fees or markets that have been explicitly excluded.

13. What is the block time on the network?

The average block time is 800ms.

14. Does gas fee affect block inclusion and transaction ordering?

Gas fee affects block inclusion but not ordering, currently there's no ordering of transactions other than the order they've arrived (based on the sequence number). For more information refer to the Tendermint docs

15. When may I see account sequence mismatch errors?

On a high-level, when a sentry node receives a transaction it runs a CheckTx to verify the validity of the transaction which includes stateless and stateful checks. One of those checks is to verify that the sender’s sequence number is valid - the sequence number is primarily used for replay protection and it also affects the ordering logic of transactions.

When you broadcast multiple transactions sequentially to the node the sequence is incremented by one for each transaction and your transactions will be included in a block in the order they arrive (based on the sequence). Should the transaction pass all the checks from CheckTx then it is included in the nodes’ mempool (an in-memory pool of transactions unique to each node) which will be gossiped to other peers in the network prior to consensus. When the transaction reaches the proposer validator node then it will be included in a block. Note that in Tendermint BFT (cosmos-sdk consensus algorithm) finality is absolute, meaning that transactions are finalized when they are included in a block.

There are a couple of reasons you might see account sequence mismatch errors:

1) If you run a trading bot and at the same time you try to broadcast a transaction on the DEX you'll end up with a sequence mismatch since the bot will fetch the sequence from the node and the same will happen with the Frontend so you end up broadcasting a transaction with the same sequence number. Similarly, if you run a trading bot with the same private key you'll also see sequence mismatch errors, thus you should use the private key only at one platform at a time.

2) In the examples we're using a function to handle the sequence locally because if you send multiple transactions in a single block the only way to do that is to use local sequence as until the tx is confirmed the peers in the network are not aware that the sequence has been increased. Essentially, we fetch the sequence the first time through the node directly and then handle it locally for consecutive transactions. If you use sync/async and fetch the sequence from the node every time opposed to handling it locally then you'll occasionally end up with a sequence mismatch.

You can refer to these functions below for sdk-python.

https://github.com/InjectiveLabs/sdk-python/blob/master/pyinjective/wallet.py#L269

https://github.com/InjectiveLabs/sdk-python/blob/master/pyinjective/wallet.py#L296

On the other hand, if you use broadcast mode you essentially expect the tx to be included in a block and then you'll get a response back from the sentry - that's not really recommended since it's wasting a lot of resources from the sentry and it's slower on the client-side too but in this case it guarantees that the sequence will always be unique and you can fetch it from the node every time you send a tx.

3) If you broadcasted a transaction with gas fee lower than the minimum threshold on the node then this transaction will remain in the mempool until the node is restarted and the transaction is discarded or until the transaction expires (if you've set a timeout_height before you broadcasted it). If a transaction is stuck in the mempool then you won't be able to broadcast transactions to that node (and potentially to other nodes in the network if it has been gossiped) since the account sequence will be incorrect. To ensure that transactions don't get stuck in the mempool please use the gas fee set in the examples.

16. What are the broadcast modes I can use to send a transaction?

Sync: Wait for the tx to pass/fail CheckTx

Async: Don’t wait for the tx to pass/fail CheckTx; send and return tx immediately

17. When may I see a max subscriptions per client error?

You can open up to 5 chain channels per IP, if you run more than 5 trading bots from the same IP then this error would naturally show up and you should use a different IP. Every trading bot should open one chain channel only, thus if you're seeing this error and don't have 5 distinct trading bots then it indicates an issue in your logic. If you want to broadcast multiple transactions in a single block you can use sync mode and open one channel only. You can refer here for the chain channel initialization in sdk-python.

18. How long does it take until the Exchange API returns my orders/trades after the transaction has been sent?

This depends on a lot of factors such as the P2P network topology and geolocation of the client-server. When you broadcast a transaction, the following cycle takes place:

1) The transaction is gossiped to other peers in the network

2) The transaction eventually reaches the proposer node

3) Validators participating in the consensus round sign the block and it's produced on-chain

4) The block information is gossiped to the read-only peers (sentry nodes)

5) The events emitted by the chain are picked up by the indexer (Exchange API) and included in a MongoDB

6) Exchange API will query MongoDB to fetch you the data

7) Geolocation between client-sentry will determine the latency until the data is served on the client

Error Codes

This section lists all error codes from various modules in the Injective ecosystem.

06-solomachine module

module_nameerror_codedescription
06-solomachine2invalid header
06-solomachine3invalid sequence
06-solomachine4invalid signature and data
06-solomachine5signature verification failed
06-solomachine6invalid solo machine proof

07-tendermint module

module_nameerror_codedescription
07-tendermint2invalid chain-id
07-tendermint3invalid trusting period
07-tendermint4invalid unbonding period
07-tendermint5invalid header height
07-tendermint6invalid header
07-tendermint7invalid max clock drift
07-tendermint8processed time not found
07-tendermint9processed height not found
07-tendermint10packet-specified delay period has not been reached
07-tendermint11time since latest trusted state has passed the trusting period
07-tendermint12time since latest trusted state has passed the unbonding period
07-tendermint13invalid proof specs
07-tendermint14invalid validator set

Auction module

module_nameerror_codedescription
auction1invalid bid denom
auction2invalid bid round

Authz module

module_nameerror_codedescription
authz2authorization not found
authz3expiration time of authorization should be more than current time
authz4unknown authorization type
authz5grant key not found
authz6authorization expired
authz7grantee and granter should be different
authz9authorization can be given to msg with only one signer
authz12max tokens should be positive

Bandoracle module

module_nameerror_codedescription
bandoracle1owasm compilation failed
bandoracle2bad wasm execution
bandoracle3data source not found
bandoracle4oracle script not found
bandoracle5request not found
bandoracle6raw request not found
bandoracle7reporter not found
bandoracle8result not found
bandoracle9reporter already exists
bandoracle10validator not requested
bandoracle11validator already reported
bandoracle12invalid report size
bandoracle13reporter not authorized
bandoracle14editor not authorized
bandoracle16validator already active
bandoracle17too soon to activate
bandoracle18too long name
bandoracle19too long description
bandoracle20empty executable
bandoracle21empty wasm code
bandoracle22too large executable
bandoracle23too large wasm code
bandoracle24invalid min count
bandoracle25invalid ask count
bandoracle26too large calldata
bandoracle27too long client id
bandoracle28empty raw requests
bandoracle29empty report
bandoracle30duplicate external id
bandoracle31too long schema
bandoracle32too long url
bandoracle33too large raw report data
bandoracle34insufficient available validators
bandoracle35cannot create with [do-not-modify] content
bandoracle36cannot reference self as reporter
bandoracle37obi decode failed
bandoracle38uncompression failed
bandoracle39request already expired
bandoracle40bad drbg initialization
bandoracle41max oracle channels
bandoracle42invalid ICS20 version
bandoracle43not enough fee
bandoracle44invalid owasm gas
bandoracle45sending oracle request via IBC is disabled
bandoracle46invalid request key
bandoracle47too long request key

Bank module

module_nameerror_codedescription
bank2no inputs to send transaction
bank3no outputs to send transaction
bank4sum inputs != sum outputs
bank5send transactions are disabled
bank6client denom metadata not found
bank7invalid key
bank8duplicate entry
bank9multiple senders not allowed

Capability module

module_nameerror_codedescription
capability2capability name not valid
capability3provided capability is nil
capability4capability name already taken
capability5given owner already claimed capability
capability6capability not owned by module
capability7capability not found
capability8owners not found for capability
module_nameerror_codedescription
chainlink1stale report
chainlink2incomplete proposal
chainlink3repeated oracle address
chainlink4too many signers
chainlink5incorrect config
chainlink6config digest doesn't match
chainlink7wrong number of signatures
chainlink8incorrect signature
chainlink9no transmitter specified
chainlink10incorrect transmission data
chainlink11no transmissions found
chainlink12median value is out of bounds
chainlink13LINK denom doesn't match
chainlink14Reward Pool doesn't exist
chainlink15wrong number of payees and transmitters
chainlink16action is restricted to the module admin
chainlink17feed already exists
chainlink19feed doesnt exists
chainlink20action is admin-restricted
chainlink21insufficient reward pool
chainlink22payee already set
chainlink23action is payee-restricted
chainlink24feed config not found

Channel module

module_nameerror_codedescription
channel2channel already exists
channel3channel not found
channel4invalid channel
channel5invalid channel state
channel6invalid channel ordering
channel7invalid counterparty channel
channel8invalid channel capability
channel9channel capability not found
channel10sequence send not found
channel11sequence receive not found
channel12sequence acknowledgement not found
channel13invalid packet
channel14packet timeout
channel15too many connection hops
channel16invalid acknowledgement
channel17acknowledgement for packet already exists
channel18invalid channel identifier
channel19packet already received
channel20packet commitment not found
channel21packet sequence is out of order
channel22packet messages are redundant
channel23message is redundant, no-op will be performed
channel24invalid channel version
channel25packet has not been sent
channel26invalid packet timeout
channel27upgrade error receipt not found
channel28invalid upgrade
channel29invalid upgrade sequence
channel30upgrade not found
channel31incompatible counterparty upgrade
channel32invalid upgrade error
channel33restore failed
channel34upgrade timed-out
channel35upgrade timeout is invalid
channel36pending inflight packets exist
channel37upgrade timeout failed
channel38invalid pruning limit
channel39timeout not reached
channel40timeout elapsed
channel41pruning sequence start not found
channel42recv start sequence not found

Client module

module_nameerror_codedescription
client2light client already exists
client3light client is invalid
client4light client not found
client5light client is frozen due to misbehaviour
client6invalid client metadata
client7consensus state not found
client8invalid consensus state
client9client type not found
client10invalid client type
client11commitment root not found
client12invalid client header
client13invalid light client misbehaviour
client14client state verification failed
client15client consensus state verification failed
client16connection state verification failed
client17channel state verification failed
client18packet commitment verification failed
client19packet acknowledgement verification failed
client20packet receipt verification failed
client21next sequence receive verification failed
client22self consensus state not found
client23unable to update light client
client24invalid recovery client
client25invalid client upgrade
client26invalid height
client27invalid client state substitute
client28invalid upgrade proposal
client29client state is not active
client30membership verification failed
client31non-membership verification failed
client32client type not supported

Commitment module

module_nameerror_codedescription
commitment2invalid proof
commitment3invalid prefix
commitment4invalid merkle proof

Connection module

module_nameerror_codedescription
connection2connection already exists
connection3connection not found
connection4light client connection paths not found
connection5connection path is not associated to the given light client
connection6invalid connection state
connection7invalid counterparty connection
connection8invalid connection
connection9invalid connection version
connection10connection version negotiation failed
connection11invalid connection identifier

Crisis module

module_nameerror_codedescription
crisis2sender address is empty
crisis3unknown invariant

Distribution module

module_nameerror_codedescription
distribution2delegator address is empty
distribution3withdraw address is empty
distribution4validator address is empty
distribution5no delegation distribution info
distribution6no validator distribution info
distribution7no validator commission to withdraw
distribution8set withdraw address disabled
distribution9community pool does not have sufficient coins to distribute
distribution10invalid community pool spend proposal amount
distribution11invalid community pool spend proposal recipient
distribution12validator does not exist
distribution13delegation does not exist

Erc20 module

module_nameerror_codedescription
erc202attempting to create a token pair for bank denom that already has a pair associated
erc203unauthorized account
erc204invalid genesis
erc205invalid token pair
erc206invalid ERC20 contract address
erc207unknown bank denom or zero supply
erc208error uploading ERC20 contract
erc209invalid token factory denom
erc2010respective erc20:... denom has existing supply
erc2011invalid query request

Evidence module

module_nameerror_codedescription
evidence2unregistered handler for evidence type
evidence3invalid evidence
evidence5evidence already exists

Evm module

module_nameerror_codedescription
evm2invalid storage state
evm3execution reverted
evm4chain configuration not found
evm5invalid chain configuration
evm6invalid zero address
evm7empty hash
evm8block bloom not found
evm9transaction receipt not found
evm10EVM Create operation is disabled
evm11EVM Call operation is disabled
evm12invalid transaction amount
evm13invalid gas price
evm14invalid gas fee
evm15evm transaction execution failed
evm16invalid gas refund amount
evm17inconsistent gas
evm18invalid gas cap
evm19invalid base fee
evm20gas computation overflow/underflow
evm21account type is not a valid ethereum account
evm22invalid gas limit
evm23failed to apply state override
evm24EVM Create operation is not authorized for user

Exchange module

module_nameerror_codedescription
exchange1failed to validate order
exchange2spot market not found
exchange3spot market exists
exchange4struct field error
exchange5failed to validate market
exchange6subaccount has insufficient deposits
exchange7unrecognized order type
exchange8position quantity insufficient for order
exchange9order hash is not valid
exchange10subaccount id is not valid
exchange11invalid ticker
exchange12invalid base denom
exchange13invalid quote denom
exchange14invalid oracle
exchange15invalid expiry
exchange16invalid price
exchange17invalid quantity
exchange18unsupported oracle type
exchange19order doesnt exist
exchange20spot limit orderbook fill invalid
exchange21perpetual market exists
exchange22expiry futures market exists
exchange23expiry futures market expired
exchange24no liquidity on the orderbook!
exchange25orderbook liquidity cannot satisfy current worst price
exchange26insufficient margin
exchange27derivative market not found
exchange28position not found
exchange29position direction does not oppose the reduce-only order
exchange30price Surpasses Bankruptcy Price
exchange31position not liquidable
exchange32invalid trigger price
exchange33invalid oracle type
exchange34invalid minimum price tick size
exchange35invalid minimum quantity tick size
exchange36invalid minimum order margin
exchange37exceeds order side count
exchange38subaccount cannot place a market order when a market order in the same market was already placed in same block
exchange39cannot place a conditional market order when a conditional market order in same relative direction already exists
exchange40equivalent market launch proposal already exists
exchange41invalid market status
exchange42base denom cannot be same with quote denom
exchange43oracle base cannot be same with oracle quote
exchange44makerFeeRate does not match TakerFeeRate requirements
exchange45ensure that MaintenanceMarginRatio < InitialMarginRatio <= ReduceMarginRatio
exchange46oracleScaleFactor cannot be greater than MaxOracleScaleFactor
exchange47spot exchange is not enabled yet
exchange48derivatives exchange is not enabled yet
exchange49oracle price delta exceeds threshold
exchange50invalid hourly interest rate
exchange51invalid hourly funding rate cap
exchange52only perpetual markets can update funding parameters
exchange53invalid trading reward campaign
exchange54invalid fee discount schedule
exchange55invalid liquidation order
exchange56unknown error happened for campaign distributions
exchange57invalid trading reward points update
exchange58invalid batch msg update
exchange59post-only order exceeds top of book price
exchange60order type not supported for given message
exchange61sender must match dmm account
exchange62already opted out of rewards
exchange63invalid margin ratio
exchange64provided funds are below minimum
exchange65position is below initial margin requirement
exchange66pool has non-positive total lp token supply
exchange67passed lp token burn amount is greater than total lp token supply
exchange68unsupported action
exchange69position quantity cannot be negative
exchange70binary options market exists
exchange71binary options market not found
exchange72invalid settlement
exchange73account doesnt exist
exchange74sender should be a market admin
exchange75market is already scheduled to settle
exchange76market not found
exchange77denom decimal should be greater than 0 and not greater than max scale factor
exchange78state is invalid
exchange79transient orders up to cancellation not supported
exchange80invalid trade
exchange81no margin locked in subaccount
exchange82invalid access level to perform action
exchange83invalid address
exchange84invalid argument
exchange85invalid funds direction
exchange86no funds provided
exchange87invalid signature
exchange88no funds to unlock
exchange89no msgs provided
exchange90no msg provided
exchange91invalid amount
exchange92The current feature has been disabled
exchange93order has too much margin
exchange94subaccount nonce is invalid
exchange95insufficient funds
exchange96exchange is in post-only mode
exchange97client order id already exists
exchange98client order id is invalid. Max length is 36 chars
exchange99market cannot be settled in emergency mode
exchange100invalid notional
exchange101stale oracle price
exchange102invalid stake grant
exchange103insufficient stake for grant
exchange104invalid permissions
exchange105the decimals specified for the denom is incorrect
exchange106insufficient market balance
exchange107invalid expiration block
exchange108v1 perpetual and expiry market launch proposal is not supported
exchange109position not offsettable
exchange110offsetting subaccount IDs cannot be empty
exchange111invalid open notional cap

Feegrant module

module_nameerror_codedescription
feegrant2fee limit exceeded
feegrant3fee allowance expired
feegrant4invalid duration
feegrant5no allowance
feegrant6allowed messages are empty
feegrant7message not allowed

Feeibc module

module_nameerror_codedescription
feeibc2invalid ICS29 middleware version
feeibc3no account found for given refund address
feeibc4balance not found for given account address
feeibc5there is no fee escrowed for the given packetID
feeibc6relayers must not be set. This feature is not supported
feeibc7counterparty payee must not be empty
feeibc8forward relayer address not found
feeibc9fee module is not enabled for this channel. If this error occurs after channel setup, fee module may not be enabled
feeibc10relayer address must be stored for async WriteAcknowledgement
feeibc11the fee module is currently locked, a severe bug has been detected
feeibc12unsupported action

Gov module

module_nameerror_codedescription
gov3inactive proposal
gov4proposal already active
gov5invalid proposal content
gov6invalid proposal type
gov7invalid vote option
gov8invalid genesis state
gov9no handler exists for proposal type
gov10proposal message not recognized by router
gov11no messages proposed
gov12invalid proposal message
gov13expected gov account as only signer for proposal message
gov15metadata too long
gov16minimum deposit is too small
gov18invalid proposer
gov20voting period already ended
gov21invalid proposal
gov22summary too long
gov23invalid deposit denom

Host module

module_nameerror_codedescription
host2invalid identifier
host3invalid path
host4invalid packet

Hyperlane module

module_nameerror_codedescription
hyperlane1no receiver ISM
hyperlane2required hook not set
hyperlane3default hook not set

Ibc module

module_nameerror_codedescription
ibc1invalid sequence
ibc2unauthorized
ibc3insufficient funds
ibc4unknown request
ibc5invalid address
ibc6invalid coins
ibc7out of gas
ibc8invalid request
ibc9invalid height
ibc10invalid version
ibc11invalid chain-id
ibc12invalid type
ibc13failed packing protobuf message to Any
ibc14failed unpacking protobuf message from Any
ibc15internal logic error
ibc16not found

Ibchooks module

module_nameerror_codedescription
ibchooks2error in wasmhook message validation

Icacontroller module

module_nameerror_codedescription
icacontroller2controller submodule is disabled

Icahost module

module_nameerror_codedescription
icahost2host submodule is disabled

Injective module

module_nameerror_codedescription
injective3invalid chain ID

Insurance module

module_nameerror_codedescription
insurance1insurance fund already exists
insurance2insurance fund not found
insurance3redemption already exists
insurance4invalid deposit amount
insurance5invalid deposit denom
insurance6insurance payout exceeds deposits
insurance7invalid ticker
insurance8invalid quote denom
insurance9invalid oracle
insurance10invalid expiration time
insurance11invalid marketID
insurance12invalid share denom

Interchainaccounts module

module_nameerror_codedescription
interchainaccounts2unknown data type
interchainaccounts3account already exist
interchainaccounts4port is already bound
interchainaccounts5invalid message sent to channel end
interchainaccounts6invalid outgoing data
interchainaccounts7invalid route
interchainaccounts8interchain account not found
interchainaccounts9interchain account is already set
interchainaccounts10active channel already set for this owner
interchainaccounts11no active channel for this owner
interchainaccounts12invalid interchain accounts version
interchainaccounts13invalid account address
interchainaccounts14interchain account does not support this action
interchainaccounts15invalid controller port
interchainaccounts16invalid host port
interchainaccounts17timeout timestamp must be in the future
interchainaccounts18codec is not supported
interchainaccounts19invalid account reopening

Ism module

module_nameerror_codedescription
ism1unexpected error
ism2invalid multisig configuration
ism3invalid announce
ism4mailbox does not exist
ism5invalid signature
ism6invalid ism type
ism7unknown ism id
ism8no route found
ism9unauthorized
ism10invalid owner
ism11route for domain already exists

Oracle module

module_nameerror_codedescription
oracle1relayer address is empty
oracle2bad rates count
oracle3bad resolve times
oracle4bad request ID
oracle5relayer not authorized
oracle6bad price feed base count
oracle7bad price feed quote count
oracle8unsupported oracle type
oracle9bad messages count
oracle10bad Coinbase message
oracle11bad Ethereum signature
oracle12bad Coinbase message timestamp
oracle13Coinbase price not found
oracle14Prices must be positive
oracle15Prices must be less than 10 million.
oracle16Invalid Band IBC Request
oracle17sample error
oracle18invalid packet timeout
oracle19invalid symbols count
oracle20could not claim port capability
oracle21invalid IBC Port ID
oracle22invalid IBC Channel ID
oracle23invalid Band IBC request interval
oracle24Invalid Band IBC Update Request Proposal
oracle25Band IBC Oracle Request not found
oracle26Base Info is empty
oracle27provider is empty
oracle28invalid provider name
oracle29invalid symbol
oracle30relayer already exists
oracle31provider price not found
oracle32invalid oracle request
oracle33no price for oracle was found
oracle34no address for Pyth contract found
oracle35unauthorized Pyth price relay
oracle36unauthorized Pyth price relay
oracle37unauthorized Pyth price relay
oracle38unauthorized Pyth price relay
oracle39empty price attestations
oracle40bad Stork message timestamp
oracle41sender stork is empty
oracle42invalid stork signature
oracle43stork asset id not unique

Params module

module_nameerror_codedescription
params2unknown subspace
params3failed to set parameter
params4submitted parameter changes are empty
params5parameter subspace is empty
params6parameter key is empty
params7parameter value is empty

Peggy module

module_nameerror_codedescription
peggy1internal
peggy2duplicate
peggy3invalid
peggy4timeout
peggy5unknown
peggy6empty
peggy7outdated
peggy8unsupported
peggy9non contiguous event nonce
peggy10no unbatched txs found
peggy11can not set orchestrator addresses more than once
peggy12supply cannot exceed max ERC20 value
peggy13invalid ethereum sender on claim
peggy14invalid ethereum destination
peggy15missing previous claim for validator

Permissions module

module_nameerror_codedescription
permissions2attempting to create a namespace for denom that already exists
permissions3unauthorized account
permissions4invalid genesis
permissions5invalid namespace
permissions6invalid permissions
permissions7unknown role
permissions8unknown contract address
permissions9restricted action
permissions10invalid role
permissions11namespace for denom does not exist
permissions12wasm hook query error
permissions13voucher was not found
permissions14invalid contract hook
permissions15unknown policy
permissions16unauthorized policy change

Port module

module_nameerror_codedescription
port2port is already binded
port3port not found
port4invalid port
port5route not found

Post_dispatch module

module_nameerror_codedescription
post_dispatch1mailbox does not exist
post_dispatch2sender is not designated mailbox
post_dispatch3hook does not exist or isn't registered
post_dispatch4unauthorized
post_dispatch5invalid owner

Sdk module

module_nameerror_codedescription
sdk2tx parse error
sdk3invalid sequence
sdk4unauthorized
sdk5insufficient funds
sdk6unknown request
sdk7invalid address
sdk8invalid pubkey
sdk9unknown address
sdk10invalid coins
sdk11out of gas
sdk12memo too large
sdk13insufficient fee
sdk14maximum number of signatures exceeded
sdk15no signatures supplied
sdk16failed to marshal JSON bytes
sdk17failed to unmarshal JSON bytes
sdk18invalid request
sdk19tx already in mempool
sdk20mempool is full
sdk21tx too large
sdk22key not found
sdk23invalid account password
sdk24tx intended signer does not match the given signer
sdk25invalid gas adjustment
sdk26invalid height
sdk27invalid version
sdk28invalid chain-id
sdk29invalid type
sdk30tx timeout height
sdk31unknown extension options
sdk32incorrect account sequence
sdk33failed packing protobuf message to Any
sdk34failed unpacking protobuf message from Any
sdk35internal logic error
sdk36conflict
sdk37feature not supported
sdk38not found
sdk39Internal IO error
sdk40error in app.toml
sdk41invalid gas limit

Slashing module

module_nameerror_codedescription
slashing2address is not associated with any known validator
slashing3validator does not exist for that address
slashing4validator still jailed; cannot be unjailed
slashing5validator not jailed; cannot be unjailed
slashing6validator has no self-delegation; cannot be unjailed
slashing7validator's self delegation less than minimum; cannot be unjailed
slashing8no validator signing info found
slashing9validator already tombstoned

Staking module

module_nameerror_codedescription
staking2empty validator address
staking3validator does not exist
staking4validator already exist for this operator address; must use new validator operator address
staking5validator already exist for this pubkey; must use new validator pubkey
staking6validator pubkey type is not supported
staking7validator for this address is currently jailed
staking8failed to remove validator
staking9commission must be positive
staking10commission cannot be more than 100%
staking11commission cannot be more than the max rate
staking12commission cannot be changed more than once in 24h
staking13commission change rate must be positive
staking14commission change rate cannot be more than the max rate
staking15commission cannot be changed more than max change rate
staking16validator's self delegation must be greater than their minimum self delegation
staking17minimum self delegation cannot be decrease
staking18empty delegator address
staking19no delegation for (address, validator) tuple
staking20delegator does not exist with address
staking21delegator does not contain delegation
staking22insufficient delegation shares
staking23cannot delegate to an empty validator
staking24not enough delegation shares
staking25entry not mature
staking26no unbonding delegation found
staking27too many unbonding delegation entries for (delegator, validator) tuple
staking28no redelegation found
staking29cannot redelegate to the same validator
staking30too few tokens to redelegate (truncates to zero tokens)
staking31redelegation destination validator not found
staking32redelegation to this validator already in progress; first redelegation to this validator must complete before next redelegation
staking33too many redelegation entries for (delegator, src-validator, dst-validator) tuple
staking34cannot delegate to validators with invalid (zero) ex-rate
staking35both shares amount and shares percent provided
staking36neither shares amount nor shares percent provided
staking37invalid historical info
staking38no historical info found
staking39empty validator public key
staking40commission cannot be less than min rate
staking41unbonding operation not found
staking42cannot un-hold unbonding operation that is not on hold
staking43expected authority account as only signer for proposal message
staking44redelegation source validator not found
staking45unbonding type not found
staking70commission rate too small

Store module

module_nameerror_codedescription
store2invalid proof
store3tx parse error
store4unknown request
store5internal logic error
store6conflict
store7invalid request

Table_testdata module

module_nameerror_codedescription
table_testdata2test

Tokenfactory module

module_nameerror_codedescription
tokenfactory2attempting to create a denom that already exists (has bank metadata)
tokenfactory3unauthorized account
tokenfactory4invalid denom
tokenfactory5invalid creator
tokenfactory6invalid authority metadata
tokenfactory7invalid genesis
tokenfactory8subdenom too long, max length is 44 bytes
tokenfactory9subdenom too short, min length is 1 bytes
tokenfactory10nested subdenom too short, each one should have at least 1 bytes
tokenfactory11creator too long, max length is 75 bytes
tokenfactory12denom does not exist
tokenfactory13amount has to be positive

Transfer module

module_nameerror_codedescription
transfer2invalid packet timeout
transfer3invalid denomination for cross-chain transfer
transfer4invalid ICS20 version
transfer5invalid token amount
transfer6denomination trace not found
transfer7fungible token transfers from this chain are disabled
transfer8fungible token transfers to this chain are disabled
transfer9max transfer channels
transfer10invalid transfer authorization
transfer11invalid memo

Tx module

module_nameerror_codedescription
tx1tx parse error
tx2unknown protobuf field

Txfees module

module_nameerror_codedescription
txfees1invalid fee token
txfees2more than one coin in fee
txfees3unsupported query param

Undefined module

module_nameerror_codedescription
undefined1internal
undefined2stop iterating
undefined111222panic

Upgrade module

module_nameerror_codedescription
upgrade2module version not found
upgrade3upgrade plan not found
upgrade4upgraded client not found
upgrade5upgraded consensus state not found
upgrade6expected authority account as only signer for proposal message

Warp module

module_nameerror_codedescription
warp1not enough collateral
warp2token not found

Wasm module

module_nameerror_codedescription
wasm2create wasm contract failed
wasm3contract account already exists
wasm4instantiate wasm contract failed
wasm5execute wasm contract failed
wasm6insufficient gas
wasm7invalid genesis
wasm8not found
wasm9query wasm contract failed
wasm10invalid CosmosMsg from the contract
wasm11migrate wasm contract failed
wasm12empty
wasm13exceeds limit
wasm14invalid
wasm15duplicate
wasm16max transfer channels
wasm17unsupported for this contract
wasm18pinning contract failed
wasm19unpinning contract failed
wasm20unknown message from the contract
wasm21invalid event
wasm22no such contract
wasm27max query stack size exceeded
wasm28no such code
wasm29wasmvm error
wasm30max call depth exceeded

Wasm-hooks module

module_nameerror_codedescription
wasm-hooks3cannot marshal the ICS20 packet
wasm-hooks4invalid packet data
wasm-hooks5cannot create response
wasm-hooks6wasm error
wasm-hooks7bad sender

Xwasm module

module_nameerror_codedescription
xwasm1invalid gas limit
xwasm2invalid gas price
xwasm3invalid contract address
xwasm4contract already registered
xwasm5duplicate contract
xwasm6no contract addresses found
xwasm7invalid code id
xwasm8not possible to deduct gas fees
xwasm9missing granter address
xwasm10granter address does not exist
xwasm11invalid funding mode