NAV
Python Golang TypeScript

Introduction

Welcome to Injective Protocol'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.

Golang Client

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

go mod init foo

2. Import SDK into go.mod

module foo

go 1.18

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

3. Download the package

Download the package using go mod download

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

Reference

InjectiveLabs/sdk-go.

Consult the sdk-go repository to find the latest release and replace the version in your go.mod file

Typescript Client

Installation

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

yarn add @injectivelabs/sdk-ts

Reference

Overview

Injective Protocol is a fully decentralized layer-2 DEX protocol built for the next generation of decentralized derivatives exchange. 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 layer-2 fully decentralized exchange protocol for decentralized 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 the decentralized financial markets, we are striving to empower individuals with the ability to more efficiently allocate capital in our society.

Architecture Overview

Injective Protocol 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 funds changes and update the positions.

Comparison to CEX

When you submit an order to Injective Chain,

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 fast block times combined 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,500.

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. What happens on-chain is that automatically a reduce-only market order of the same size as the position is 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.

Also note that 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. So long as you meet both conditions for a tier (past fees paid 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 are paying shorts. If the rate is negative shorts are paying longs. The further trade prices within that hour deviated from the mark price, 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 getting 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 vis 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 a the following position:

And the following SELL orders:

Buy Price Quantity Order Type
$66,500 0.2 BTC Vanilla
$65,500 0.2 BTC Reduce-only
$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

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.2 BTC Reduce-only
$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. 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.2 BTC Reduce-only
$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 reduce-only of $65,500 with 0.2 BTC order is reached, the position will have been reduced to 1 BTC - 0.1 BTC - 0.3 BTC - 0.5 BTC = 0.1 BTC. A reduce-only order of 0.2 BTC after that will thus be invalid.

To prevent that, we simply reject the creation of the new 0.5 BTC reduce-only order. In other words any reduce-only order can never be larger than the expected position's quantity at the time of matching.

Upon placing a vanilla limit order

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.2 BTC Reduce-only
$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. 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.2 BTC Reduce-only
$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 of $65,500 with 0.2 BTC order is reached, the position will have been reduced to 1 BTC - 0.1 BTC - 0.3 BTC - 0.5 BTC = 0.1 BTC. A reduce-only order of 0.2 BTC after that will thus be invalid.

To prevent that, we simply cancel the existing 0.2 BTC reduce-only order. In other words new vanilla limit orders can invalidate and auto-cancel existing reduce-only limit orders.

Examples

Adding a Spot Market Buy Order

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

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

Adding a Spot Market Sell Order

→ The account's available balance is decremented by 1 ETH.

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

Adding a Spot Limit Buy Order

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

After creation:

If Unmatched, the order becomes a resting limit order (maker) and we refund the fee difference between maker and taker:

If Matched Immediately: (assuming an FBA clearing price of 1,900 USDT)

If Filled Later By Market Order:

Adding a Spot Limit Sell Order

→ The account's available balance is decremented by 1 ETH.

After creation:

If Unmatched, the order becomes a resting limit order (maker) and we refund the fee difference between maker and taker:

If Matched Immediately: (assuming an FBA clearing price of 2,100 USDT)

If Filled Later By Market Order:

Derivative Market Order Payouts

The payouts for derivative market orders work the same way as for derivative limit orders with the one difference that 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 = 200 + 2000*0.002 = 204 USDT.

After creation:

If Unmatched, the order becomes a resting limit order (maker) and we refund the fee difference between maker and taker for 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 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,3600.5 BTC
PriceQuantity
$64,2100.1 BTC
$64,2050.3 BTC
$64,2000.2 BTC

New Orders

Sells Buys
PriceQuantity
$64,2000.1 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,3600.5 BTC
$64,2000.1 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,3600.4 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,3600.3 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,360 > 62,210).

All orders will be matched with a clearing price of

for a total quantity of 0.5 BTC. In edge cases where this clearing price violates any order price, it is instead calculated as the average of the last matched order on buy and sell side.

Swagger

A REST interface for state queries, legacy transactions

Swagger Mainnet

Swagger Testnet

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

Exchange API

The Exchange 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 Exchange API which reconstructs state from events emitted by chain.

On a high-level the end-user trading applications and Injective Products use the Exchange 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 Exchange 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.

- InjectiveAccountsRPC

InjectiveAccountsRPC defines the gRPC API of the Exchange Accounts provider.

SubaccountsList

Get a list of subaccounts for a specific address.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    subacc_list = await client.get_subaccount_list(account_address)
    print(subacc_list)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}
import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const accountAddress = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku";
  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountLists = await exchangeClient.accountApi.fetchSubaccountsList(
    accountAddress
  );

  console.log(protoObjectToJson(subaccountLists, {}));
})();

Parameter Type Description Required
account_address String The Injective Chain address Yes

Response Parameters

Response Example:

{
  "subaccounts": [
    "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000",
    "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000001",
    "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002"
  ]
}
Parameter Type Description
subaccounts Array

SubaccountHistory

Get the subaccount's transfer history.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denom = "inj"
    transfer_types = ["withdraw", "deposit"] # Enum with values "withdraw", "deposit", "internal", "external"
    subacc_history = await client.get_subaccount_history(subaccount_id=subaccount, denom=denom, transfer_types=transfer_types)
    print(subacc_history)

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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  req := accountPB.SubaccountHistoryRequest{
    Denom:         denom,
    SubaccountId:  subaccountId,
    TransferTypes: transferTypes,
  }

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

  fmt.Println(res)
}
import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const subaccountId =
    "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const denom = "inj";
  const transferTypes = ["deposit"];
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountHistory = await exchangeClient.accountApi.fetchSubaccountHistory(
    {
      subaccountId: subaccountId,
      denom: denom,
      transferTypes: transferTypes,
      pagination: pagination,
    });

  console.log(protoObjectToJson(subaccountHistory, {}));
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
denom String Filter by denom No
transfer_types Array Filter by transfer types No
skip Integer Skip the last transfers, you can use this to fetch all transfers since the API caps at 100 No
limit Integer Limit the transfers returned No

Response Parameters

Response Example:

{
  "transfers": {
  "transfer_type": "withdraw",
  "src_subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "dst_account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "amount": {
    "denom": "inj",
    "amount": "50000000000000000000"
  },
  "executed_at": 1633006684272
},

"transfers": {
  "transfer_type": "withdraw",
  "src_subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "dst_account_address": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "amount": {
    "denom": "inj",
    "amount": "1000000000000000000000"
  },
  "executed_at": 1633011955869
}

}
Parameter Type Description
transfers SubaccountBalanceTransfer Array of SubaccountBalanceTransfer

SubaccountBalanceTransfer

Parameter Type Description
amount CosmosCoin Array of CosmosCoin
dst_account_address String Account address of the receiving side
executed_at Integer Timestamp of the transfer in UNIX millis
src_subaccount_id String Subaccount ID of the sending side
transfer_type String Type of the subaccount balance transfer (Should be one of: [internal external withdraw deposit])

CosmosCoin

Parameter Type Description
amount String Coin amount
denom String Coin denominator

SubaccountBalance

Get the balance of a subaccount for a specific denom.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    denom = "inj"
    balance = await client.get_subaccount_balance(subaccount_id=subaccount_id, denom=denom)
    print(balance)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const subaccountId =
    "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const denom = "inj";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountBalance = await exchangeClient.accountApi.fetchSubaccountBalance(
    subaccountId,
    denom
  );

  console.log(protoObjectToJson(subaccountBalance, {}));
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
denom String Filter by denom Yes

Response Parameters

Response Example:

{
  "balance": {
    "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
    "account_address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
    "denom": "inj",
    "deposit": {
      "available_balance": "1000000000000000000",
      "total_balance": "1960000000000000000"
    }
  }
}
Parameter Type Description
balance SubaccountBalance Array of SubaccountBalance

SubaccountBalance

Parameter Type Description
denom String Coin denom on the chain
deposit SubaccountDeposit Array of SubaccountDeposit
subaccount_id String Filter by subaccount ID
account_address String The Injective Chain address

SubaccountDeposit

Parameter Type Description
available_balance String The available balance for a denom
total_balance String The total balance for a denom

SubaccountBalancesList

List the subaccount's balances for all denoms.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    subacc_balances_list = await client.get_subaccount_balances_list(subaccount)
    print(subacc_balances_list)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const accountAddress = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku";
  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountLists = await exchangeClient.accountApi.fetchSubaccountsList(
    accountAddress
  );

  console.log(protoObjectToJson(subaccountLists, {}));
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes

Response Parameters

Response Example:

{
  "balances": [
    {
      "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
      "account_address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
      "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "deposit": {
        "available_balance": "1000000000000000000",
        "total_balance": "1960000000000000000"
      }
    },
    {
      "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
      "account_address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
      "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "deposit": {
        "available_balance": "1000000000000000000",
        "total_balance": "1960000000000000000"
      }, 
    }
    {
      "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
      "account_address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
      "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "deposit": {
        "available_balance": "1000000000000000000",
        "total_balance": "1960000000000000000"
      }
    }
  ]
}
Parameter Type Description
balances SubaccountBalance Array of SubaccountBalance

SubaccountBalance

Parameter Type Description
account_address String The Injective Chain address
denom String Coin denom on the chain
deposit SubaccountDeposit Array of SubaccountDeposit
subaccount_id String Filter by subaccount ID

SubaccountDeposit

Parameter Type Description
available_balance String The available balance for a denom
total_balance String The total balance for a denom

SubaccountOrderSummary

Get the subaccount's orders summary.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    order_direction = "buy" #buy or sell
    subacc_order_summary = await client.get_subaccount_order_summary(subaccount_id=subaccount, order_direction=order_direction, market_id=market_id)
    print(subacc_order_summary)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const orderDirection = "buy";
  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountOrderSummary = await exchangeClient.accountApi.fetchSubaccountOrderSummary(
    {
    subaccountId,
    marketId,
    orderDirection
  }
  );

  console.log(protoObjectToJson(subaccountOrderSummary, {}));
})();


Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
market_id String Filter by market ID No
order_direction String Filter by the direction of the orders (Should be one of: [buy sell]) No

Response Parameters

Response Example:

{
  "derivative_orders_total": 10,
  "spot_orders_total": 11
}
Parameter Type Description
derivative_orders_total Integer Total count of subaccount's derivative orders in a given market
spot_orders_total Integer Total count of subaccount's spot orders in a given market

StreamSubaccountBalance

Stream the subaccount's balance for all denoms.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    subaccount = await client.stream_subaccount_balance(subaccount_id)
    async for balance in subaccount:
        print("Subaccount balance Update:\n")
        print(balance)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const subaccountId =
    "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.accountStream.streamSubaccountBalance({
    subaccountId,
    callback: (subaccountBalance) => {
      console.log(protoObjectToJson(subaccountBalance, {}));
    },
    onEndCallback: (status) => {
      console.log("Stream has ended with status: " + status);
    },
  });
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes

Response Parameters

Streaming Response Example:

{
  "balance": {
    "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
    "account_address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "deposit": {
      "available_balance": "1000000000000000000",
      "total_balance": "1960000000000000000"
    }
  },
  "timestamp": 1544614248000
}
Parameter Type Description
balance SubaccountBalance Array of SubaccountBalance
timestamp Integer Operation timestamp in UNIX millis

SubaccountBalance

Parameter Type Description
denom String Coin denom on the chain
deposit SubaccountDeposit Array of SubaccountDeposit
subaccount_id String Filter by subaccount ID
account_address String The Injective Chain address

SubaccountDeposit

Parameter Type Description
available_balance String The available balance for a denom
total_balance String The total balance for a denom

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 1 day. Should your order be filled or canceled you will still be able to fetch it for 3 minutes.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    spot_order_hashes = ["0xce0d9b701f77cd6ddfda5dd3a4fe7b2d53ba83e5d6c054fb2e9e886200b7b7bb", "0x2e2245b5431638d76c6e0cc6268970418a1b1b7df60a8e94b8cf37eae6105542"]
    derivative_order_hashes = ["0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50", "0xbb1f036001378cecb5fff1cc69303919985b5bf058c32f37d5aaf9b804c07a06"]
    orders = await client.get_order_states(spot_order_hashes=spot_order_hashes, derivative_order_hashes=derivative_order_hashes)
    print(orders)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const spotOrderHashes = ["0xbae2927fbc4fd12c70eb7f41fb69b28eeceabbad68fecf4547df7c9dba5eb816"];
  const derivativeOrderHashes = ["0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const orderStates = await exchangeClient.accountApi.fetchOrderStates(
    {
      spotOrderHashes,
      derivativeOrderHashes
    }
  );

  console.log(protoObjectToJson(orderStates, {}));
})();

Parameter Type Description Required
spot_order_hashes Array Array with the order hashes you want to fetch in spot markets No
derivative_order_hashes Array Array with the order hashes you want to fetch in derivative markets No

Response Parameters

Response Example:

{
"spot_order_states": {
  "order_hash": "0xce0d9b701f77cd6ddfda5dd3a4fe7b2d53ba83e5d6c054fb2e9e886200b7b7bb",
  "subaccount_id": "0x0cd5450e3dad3836c66761eb626495b6195a56a2000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "order_type": "limit",
  "order_side": "buy",
  "state": "booked",
  "quantity_filled": "0",
  "quantity_remaining": "2000000000000000000",
  "created_at": 1636237921271,
  "updated_at": 1636237921271
},
"spot_order_states": {
  "order_hash": "0x2e2245b5431638d76c6e0cc6268970418a1b1b7df60a8e94b8cf37eae6105542",
  "subaccount_id": "0x0cd5450e3dad3836c66761eb626495b6195a56a2000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "order_type": "limit",
  "order_side": "buy",
  "state": "canceled",
  "quantity_filled": "0",
  "quantity_remaining": "0",
  "created_at": 1636237914316,
  "updated_at": 1636238238466
},
"derivative_order_states": {
  "order_hash": "0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50",
  "subaccount_id": "0x0cd5450e3dad3836c66761eb626495b6195a56a2000000000000000000000000",
  "market_id": "0xb64332daa987dcb200c26965bc9adaf8aa301fe3a0aecb0232fadbd3dfccd0d8",
  "order_type": "limit",
  "order_side": "buy",
  "state": "booked",
  "quantity_filled": "0",
  "quantity_remaining": "15",
  "created_at": 1636238295539,
  "updated_at": 1636238295539
},
"derivative_order_states": {
  "order_hash": "0xbb1f036001378cecb5fff1cc69303919985b5bf058c32f37d5aaf9b804c07a06",
  "subaccount_id": "0x0cd5450e3dad3836c66761eb626495b6195a56a2000000000000000000000000",
  "market_id": "0x979731deaaf17d26b2e256ad18fecd0ac742b3746b9ea5382bac9bd0b5e58f74",
  "order_type": "limit",
  "order_side": "buy",
  "state": "booked",
  "quantity_filled": "0",
  "quantity_remaining": "1",
  "created_at": 1636238267475,
  "updated_at": 1636238267475
}

}
Parameter Type Description
spot_order_states SpotOrderStates Array of SpotOrderStates
derivative_order_states DerivativeOrderStates Array of DerivativeOrderStates

SpotOrderStates

Parameter Type Description
order_hash String The order hash
subaccount_id String The subaccount ID that posted the order
market_id String The market ID of the order
order_type String The order type (Should be one of: [limit, market])
order_side String The order side (Should be one of: [buy, sell])
state String The order state (Should be one of: [booked, partial_filled, filled, canceled])
quantity_filled String The quantity that has been filled for your order
quantity_remaining String The quantity that hasn't been filled for your order
created_at String The timestamp of your order when it was first created
updated_at String The timestamp of your order when it was last updated

DerivativeOrderStates

Parameter Type Description
order_hash String The order hash
subaccount_id String The subaccount ID that posted the order
market_id String The market ID of the order
order_type String The order type (Should be one of: [limit, market])
order_side String The order side (Should be one of: [buy, sell])
state String The order state (Should be one of: [booked, partial_filled, filled, canceled])
quantity_filled String The quantity that has been filled for your order
quantity_remaining String The quantity that hasn't been filled for your order
created_at String The timestamp of your order when it was first created
updated_at String The timestamp of your order when it was last updated

Portfolio

Get an overview of your portfolio.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
    portfolio = await client.get_portfolio(account_address=account_address)
    print(portfolio)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const accountAddress = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const portfolio = await exchangeClient.accountApi.fetchPortfolio(
      accountAddress
    );

  console.log(protoObjectToJson(portfolio, {}));
})();

Parameter Type Description Required
account_address String The Injective Chain address Yes

Response Parameters

Response Example:

{
"portfolio": {
  "portfolio_value": "14172.9011909999761785",
  "available_balance": "14112.5174909999761785",
  "locked_balance": "60.3837",
  "unrealized_pnl": "0",
  "subaccounts": {
    "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
    "available_balance": "14112.5174909999761785",
    "locked_balance": "60.3837",
    "unrealized_pnl": "500"
  }
}

}
Parameter Type Description
portfolio_value String The total value of your portfolio including bank balance, subaccounts' balance, unrealized profit & loss as well as margin in open positions
available_balance String The total available balance in the subaccounts
locked_balance String The amount of margin in open orders and positions
unrealized_pnl String The approximate unrealized profit and loss across all positions (based on the mark price)
subaccount_id String Filter balances by subaccount ID

Rewards

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

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    account_address = "inj13q8u96uftm0d7ljcf6hdp0uj5tyqrwftmxllaq"
    epoch = 2
    rewards = await client.get_rewards(account_address=account_address, epoch=epoch)
    print(rewards)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku";
  const epoch = -1;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const rewards = await exchangeClient.accountApi.fetchRewards(
    {
      address: address,
      epoch: epoch
    }
    );

  console.log(protoObjectToJson(rewards, {}));
})();

Parameter Type Description Required
account_address String The Injective Chain address No
epoch Integer The epoch ID No

Response Parameters

Response Example:

{
"rewards": {
  "account_address": "inj13q8u96uftm0d7ljcf6hdp0uj5tyqrwftmxllaq",
  "rewards": {
    "denom": "inj",
    "amount": "100000000000000000000"
  },
  "distributed_at": 1641821040539
}

}
Parameter Type Description
account_address String The Injective Chain address
denom String The token denom
amount String The amount of rewards distributed
distributed_at Integer Timestamp of the transfer in UNIX millis

- InjectiveSpotExchangeRPC

InjectiveSpotExchangeRPC defines the gRPC API of the Spot Exchange provider.

Market

Get details of a spot market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    market = await client.get_spot_market(market_id=market_id)
    print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotMarket(marketId);

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes

Response Parameters

Response Example:

{
"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"
}

}
Parameter Type Description
market SpotMarketInfo Array of SpotMarketInfo

SpotMarketInfo

Parameter Type Description
base_denom String Coin denom of the base asset
market_id String SpotMarket ID is keccak265(baseDenom
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
quote_token_meta TokenMeta Array of TokenMeta
service_provider_fee String Percentage of the transaction fee shared with the service provider
base_token_meta TokenMeta Array of TokenMeta
maker_fee_rate String Defines the fee percentage makers pay when trading (in the quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
quote_denom String Coin denom of the quote asset
taker_fee_rate String Defines the fee percentage takers pay when trading (in the quote asset)
ticker String A name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset

TokenMeta

Parameter Type Description
address String Token's Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name
updatedAt Integer Token metadata fetched timestamp in UNIX millis

Markets

Get a list of spot markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_status = "active" # active, paused, suspended, demolished or expired
    base_denom = "inj"
    quote_denom = "peggy0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08"
    market = await client.get_spot_markets(market_status=market_status, base_denom=base_denom, quote_denom=quote_denom)
    print(market)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketStatus = "active";
  const quoteDenom = "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const markets = await exchangeClient.spotApi.fetchSpotMarkets({
    marketStatus: marketStatus,
    quoteDenom: quoteDenom,
  })

  console.log(protoObjectToJson(markets, {}));
})();

Parameter Type Description Required
base_denom String Filter by the base currency No
market_status String Filter by market status (Should be one of: [active paused suspended demolished expired]) No
quote_denom String Filter by the quote currency No

Response Parameters

Response Example:

{
"markets": {
  "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"
}

}
Parameter Type Description
markets SpotMarketInfo Array of SpotMarketInfo

SpotMarketInfo

Parameter Type Description
base_denom String Coin denom of the base asset
market_id String SpotMarket ID is keccak265(baseDenom
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
quote_token_meta TokenMeta Array of TokenMeta
service_provider_fee String Percentage of the transaction fee shared with the service provider
base_token_meta TokenMeta Array of TokenMeta
maker_fee_rate String Defines the fee percentage makers pay when trading (in the quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
quote_denom String Coin denom of the quote asset
taker_fee_rate String Defines the fee percentage takers pay when trading (in the quote asset)
ticker String A name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset

TokenMeta

Parameter Type Description
address String Token's Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name
updatedAt Integer Token metadata fetched timestamp in UNIX millis

StreamMarkets

Stream live updates of spot markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    markets = await client.stream_spot_markets()
    async for market in markets:
        print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const marketIds = ["0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.spotStream.streamSpotMarket({
    marketIds,
      callback: (streamSpotMarket) => {
        console.log(protoObjectToJson(streamSpotMarket, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Response Parameters

Streaming Response Example:

{
"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"
},
  "operation_type": "update",
  "timestamp": 1632535055790
}
Parameter Type Description
market SpotMarketInfo Array of SpotMarketInfo
operation_type String Update type (Should be one of: [insert replace update invalidate])
timestamp Integer Operation timestamp in UNIX millis

SpotMarketInfo

Parameter Type Description
base_denom String Coin denom of the base asset
market_id String SpotMarket ID is keccak265(baseDenom
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
quote_token_meta TokenMeta Array of TokenMeta
service_provider_fee String Percentage of the transaction fee shared with the service provider
base_token_meta TokenMeta Array of TokenMeta
maker_fee_rate String Defines the fee percentage makers pay when trading (in the quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
quote_denom String Coin denom of the quote asset
taker_fee_rate String Defines the fee percentage takers pay when trading (in the quote asset)
ticker String A name of the pair in format AAA/BBB, where AAA is base asset, BBB is quote asset

TokenMeta

Parameter Type Description
address String Token's Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name
updatedAt Integer Token metadata fetched timestamp in UNIX millis

Orders

Get orders of a spot market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    order_side = "sell" # buy or sell
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    orders = await client.get_spot_orders(market_id=market_id, order_side=order_side, subaccount_id=subaccount_id)
    print(orders)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  req := spotExchangePB.OrdersRequest{
    MarketId: marketId,
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, SpotOrderSide, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const orderSide = SpotOrderSide.Buy;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotOrders(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      orderSide: orderSide,
      pagination: pagination,
    }
  );

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
order_side String Filter by order side (Should be one of: [buy sell]) No
subaccount_id String Filter by subaccount ID No
skip Integer Skip the last orders, you can use this to fetch all orders since the API caps at 100 No
limit Integer Limit the orders returned No

Response Parameters

Response Example:

{
"orders": {
  "order_hash": "0xb0704040d8a2005fc5154f8e7fd7bcc013a6e40b8f6ec79ac2235740a57e7d32",
  "order_side": "buy",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "subaccount_id": "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
  "price": "0.000000000007523",
  "quantity": "10000000000000000",
  "unfilled_quantity": "10000000000000000",
  "trigger_price": "0",
  "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
  "state": "booked",
  "created_at": 1633720869740
},
"orders": {
  "order_hash": "0xd5c94c3e7fbf7eaa6a1a3f831accc10929932315d06114bd7bd810ded4628590",
  "order_side": "buy",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "subaccount_id": "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000",
  "price": "0.000000000007523",
  "quantity": "10000000000000000",
  "unfilled_quantity": "10000000000000000",
  "trigger_price": "0",
  "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
  "state": "booked",
  "created_at": 1633720644128
}

}
Parameter Type Description
orders SpotLimitOrder Array of SpotLimitOrder

SpotLimitOrder

Parameter Type Description
unfilled_quantity String The amount of the quantity remaining unfilled
market_id String Spot Market ID is keccak265(baseDenom + quoteDenom)
order_hash String Hash of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
state String The state of the order (Should be one of: [booked partial_filled filled canceled])
subaccount_id String The subaccount ID this order belongs to
fee_recipient String The fee recipient address
price String The price of the order
quantity String The quantity of the order
trigger_price String The price used by stop/take orders. This will be 0 if the trigger price is not set
created_at Integer Order committed timestamp in UNIX millis

StreamOrders

Stream order updates of a spot market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    order_side = "sell" # sell or buy
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    orders = await client.stream_spot_orders(market_id=market_id, order_side=order_side, subaccount_id=subaccount_id)
    async for order in orders:
        print(order)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  req := spotExchangePB.StreamOrdersRequest{
    MarketId:     marketId,
    SubaccountId: subaccountId,
    OrderSide:    orderSide,
  }
  stream, err := exchangeClient.StreamSpotOrders(ctx, req)
  if err != nil {
    fmt.Println(err)
  }

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, SpotOrderSide, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const orderSide = SpotOrderSide.Buy;

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.spotStream.streamSpotOrders(
    {
      marketId,
      orderSide,
      subaccountId,
      callback: (streamSpotOrders) => {
        console.log(protoObjectToJson(streamSpotOrders, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
order_side String Filter by order side (Should be one of: [buy sell]) No
subaccount_id String Filter by subaccount ID No

Response Parameters

Streaming Response Example:

{
"order": {
  "order_hash": "0x1f07217915afff20f9fb6819ff265c260c65ab75743ea72ca3dcbe275872951b",
  "order_side": "sell",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "price": "0.00000000001318",
  "quantity": "46000000000000000000",
  "unfilled_quantity": "0",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "filled",
  "created_at": 1634819677953,
  "updated_at": 1634820261139
},
"operation_type": "update",
"timestamp": 1634820263000,

"order": {
  "order_hash": "0x1074fc29ae8d41d00e5483a8116937c7059d57527c654272c1216b6e5de72134",
  "order_side": "sell",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "price": "0.000000000013186",
  "quantity": "40000000000000000000",
  "unfilled_quantity": "0",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "filled",
  "created_at": 1634819677953,
  "updated_at": 1634820305633,
},
"operation_type": "update",
"timestamp": 1634820307000

}
Parameter Type Description
order SpotLimitOrder Array of SpotLimitOrder
operation_type String Order update type (Should be one of: [insert replace update invalidate])
timestamp Integer Operation timestamp in UNIX millis

SpotLimitOrder

Parameter Type Description
unfilled_quantity String The amount of the quantity remaining unfilled
market_id String Spot Market ID is keccak265(baseDenom + quoteDenom)
order_hash String Hash of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
state String The state of the order (Should be one of: [booked partial_filled filled canceled])
subaccount_id String The subaccount ID this order belongs to
fee_recipient String The fee recipient address
price String The price of the order
quantity String The quantity of the order
trigger_price String The price used by stop/take orders. This will be 0 if the trigger price is not set
created_at Integer Order committed timestamp in UNIX millis

Trades

Get trades of a spot market.

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 the other way around (new limit order getting matched)

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    direction = "buy" # buy or sell
    execution_side = "taker" # taker or maker
    orders = await client.get_spot_trades(market_id=market_id, execution_side=execution_side, direction=direction, subaccount_id=subaccount_id)
    print(orders)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, TradeExecutionSide, TradeDirection, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const direction = TradeDirection.Buy;
  const executionSide = TradeExecutionSide.Maker;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotTrades(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      direction: direction,
      executionSide: executionSide,
  });

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
subaccount_id String Filter by subaccount ID No
direction String Filter by the direction of the trade (Should be one of: [buy sell]) No
execution_side String Filter by the execution side of the trade (Should be one of: [maker taker]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Response Example:

{
"trades": {
  "order_hash": "0x4e3068bfad0050d38908fd6604190c45c24633b462b886aac377023007276f70",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "limitFill",
  "trade_direction": "sell",
  "price": {
    "price": "0.000000000013512",
    "quantity": "18000000000000000000",
    "timestamp": 1634818491163
  },
  "fee": "243216",
  "executed_at": 1634818491163
},
"trades": {
  "order_hash": "0xc3085f4a23a0303f69aac5ee47914acb6257b10e844ea97281e0c422b8611109",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "market",
  "trade_direction": "buy",
  "price": {
    "price": "0.000000000013406",
    "quantity": "30000000000000000000",
    "timestamp": 1634818450613
  },
  "fee": "804360",
  "executed_at": 1634818450613,
  "fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
}

}
Parameter Type Description
trades SpotTrade Array of SpotTrade

SpotTrade

Parameter Type Description
trade_direction String Filter by the trade direction(Should be one of: [buy sell])
trade_execution_type String Filter by the trade execution type (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade (quote asset denom)
market_id String Filter by the market ID
order_hash String The order hash
price PriceLevel Array of PriceLevel
subaccount_id String Filter by the subaccount ID
executed_at Integer Timestamp of trade execution in UNIX millis
fee_recipient String The address that received 40% of the fees

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

StreamTrades

Stream trades of a spot market.

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 the other way around (new limit order getting matched)

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    execution_side = "maker" # maker or taker
    direction = "sell" # sell or buy
    trades = await client.stream_spot_trades(market_id=market_id, execution_side=execution_side, direction=direction, subaccount_id=subaccount_id)
    async for trade in trades:
        print(trade)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  req := spotExchangePB.StreamTradesRequest{
    MarketId:     marketId,
    SubaccountId: subaccountId,
  }
  stream, err := exchangeClient.StreamSpotTrades(ctx, req)
  if err != nil {
    fmt.Println(err)
  }

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, TradeExecutionSide, TradeDirection, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const direction = TradeDirection.Buy;
  const executionSide = TradeExecutionSide.Maker;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.spotStream.streamSpotTrades(
    {
      marketId: marketId,
      direction: direction,
      subaccountId: subaccountId,
      pagination: pagination,
      executionSide: executionSide,
      callback: (streamSpotTrades) => {
        console.log(protoObjectToJson(streamSpotTrades, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_ids Array Filter by an array of market IDs Conditional
market_id String Filter by market ID Conditional
subaccount_ids Array Filter by an array of subaccount IDs Conditional
subaccount_id String Filter by subaccount ID Conditional
execution_side String Filter by the execution side of the trade (Should be one of: [maker taker]) No
direction String Filter by the direction of the trade (Should be one of: [buy sell]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Streaming Response Example:

{
  "operation_type": "insert",
  "timestamp": 1544614248000,
  "trade": {
    "executed_at": 1544614248000,
    "fee": "1960000000000000",
    "market_id": "0x3bdb3d8b5eb4d362371b72cf459216553d74abdb55eb0208091f7777dd85c8bb",
    "order_hash": "0x482ce078117d4835fe005b643056d2d3f439e3010db40f68449d9e5b77e911bc",
    "price": {
      "price": "1960000000000000000",
      "quantity": "40",
      "timestamp": 1544614248000
    },
    "subaccount_id": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000002",
    "trade_direction": "buy",
    "trade_execution_type": "market",
    "fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
  }
}
Parameter Type Description
operation_type String Trade operation type (Should be one of: [insert invalidate])
timestamp Integer Operation timestamp in UNIX millis
trade SpotTrade Array of SpotTrade

SpotTrade

Parameter Type Description
trade_direction String Filter by the trade direction(Should be one of: [buy sell])
trade_execution_type String Filter by the trade execution type (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade (quote asset denom)
market_id String Filter by the market ID
order_hash String The order hash
price PriceLevel Array of PriceLevel
subaccount_id String Filter by the subaccount ID
executed_at Integer Timestamp of trade execution in UNIX millis
fee_recipient String The address that received 40% of the fees

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

Orderbook

Get the orderbook of a spot market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    orderbook = await client.get_spot_orderbook(market_id=market_id)
    print(orderbook)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotOrderbook(marketId);

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes

Response Parameters

Response Example:

{
"orderbook": {
  "buys": {
    "price": "0.000000000010716",
    "quantity": "10000000000000000000",
    "timestamp": 1636697333186
  },
  "buys": {
    "price": "0.00000000001",
    "quantity": "1000000000000000",
    "timestamp": 1616059590812
  },
  "buys": {
    "price": "0.000000000009523",
    "quantity": "2501950000000000000000",
    "timestamp": 1636705938416
  },
 "sells": {
    "price": "0.000000000011464",
    "quantity": "44000000000000000000",
    "timestamp": 1636698175470
  },
  "sells": {
    "price": "0.000000000011476",
    "quantity": "12000000000000000000",
    "timestamp": 1636898385842
  },
  "sells": {
    "price": "0.000000000011488",
    "quantity": "24000000000000000000",
    "timestamp": 1636705308464
  }

}
Parameter Type Description
orderbook SpotLimitOrderbook Array of SpotLimitOrderbook

SpotLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

Orderbooks

Get the orderbook for an array of spot markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    orderbook = await client.get_spot_orderbook(market_id=market_id)
    print(orderbook)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketIds = ["0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotOrderbooks(marketIds);

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_ids Array Filter by an array of market IDs Yes

Response Parameters

Response Example:

{
"orderbooks": {
  "market_id": "0x26413a70c9b78a495023e5ab8003c9cf963ef963f6755f8b57255feb5744bf31",
  "orderbook": {
    "buys": {
      "price": "0.00000000001376",
      "quantity": "40000000000000000000",
      "timestamp": 1646999035779
    },
    "buys": {
      "price": "0.000000000013747",
      "quantity": "36000000000000000000",
      "timestamp": 1647007029601
    }
  }
},
"orderbooks": {
  "market_id": "0x74b17b0d6855feba39f1f7ab1e8bad0363bd510ee1dcc74e40c2adfe1502f781",
  "orderbook": {
    "buys": {
      "price": "0.000000000379929",
      "quantity": "40000000000000000000",
      "timestamp": 1646998834092
    },
    "buys": {
      "price": "0.000000000378619",
      "quantity": "28000000000000000000",
      "timestamp": 1647006634098
    }
  }
}
}
Parameter Type Description
orderbook SpotLimitOrderbook Array of SpotLimitOrderbook
market_id String Filter by market ID

SpotLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

StreamOrderbooks

Stream orderbook updates for an array of spot markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_ids = ["0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", "0x26413a70c9b78a495023e5ab8003c9cf963ef963f6755f8b57255feb5744bf31"]
    orderbook = await client.stream_spot_orderbooks(market_ids=market_ids)
    async for orders in orderbook:
        print(orders)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(res)
    }
  }
}
import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const marketIds = ["0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.spotStream.streamSpotOrderbook(
    {
      marketIds,
      callback: (streamSpotOrderbook) => {
        console.log(protoObjectToJson(streamSpotOrderbook, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_ids Array Filter by market IDs Yes

Response Parameters

Streaming Response Example:

{
  "orderbooks": {
    "buys": {
      "price": "0.000000000005616",
      "quantity": "32000000000000000000",
      "timestamp": 1642702243902,
    },
    "buys": {
      "price": "0.00000000000561",
      "quantity": "36000000000000000000",
      "timestamp": 1642585507231
    },
    "sells": {
      "price": "0.000000000006069",
      "quantity": "46000000000000000000",
      "timestamp": 1642753915151
    },
    "sells": {
      "price": "0.000000000006089",
      "quantity": "46000000000000000000",
      "timestamp": 1642753915151
    }
  },
  "operation_type": "update",
  "timestamp": 1642755027000,
  "market_id":"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
}
Parameter Type Description
operation_type String Order update type (Should be one of: [insert replace update invalidate])
orderbook SpotLimitOrderbook Array of SpotLimitOrderbook
timestamp Integer Operation timestamp in UNIX millis
market_id String Filter by market ID

SpotLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

SubaccountOrdersList

Get orders of a subaccount.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    orders = await client.get_spot_subaccount_orders(subaccount_id=subaccount_id, market_id=market_id)
    print(orders)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };
  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotSubaccountOrdersList(
    {
      subaccountId: subaccountId,
      marketId: marketId,
      pagination: pagination,
    }
  );

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
market_id String Filter by market ID No
skip Integer Skip the last orders, you can use this to fetch all orders since the API caps at 100 No
limit Integer Limit the orders returned No

Response Parameters

Response Example:

{
"orders": {
  "order_hash": "0x89d99cc898fdd6746c89c82e38adf935a3400181a0b9502daa6b4845e3447dfa",
  "order_side": "buy",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "price": "0.000000000005",
  "quantity": "1000000000000000000",
  "unfilled_quantity": "1000000000000000000",
  "trigger_price": "0",
  "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
  "state": "booked",
  "created_at": 1634813876780
},
"orders": {
  "order_hash": "0xf43af77013733ec274194b9b7d344933db0977eec154e391d3db7316fd38fe95",
  "order_side": "buy",
  "market_id": "0x51092ddec80dfd0d41fee1a7d93c8465de47cd33966c8af8ee66c14fe341a545",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "price": "0.000000000001",
  "quantity": "1000000000000000000",
  "unfilled_quantity": "1000000000000000000",
  "trigger_price": "0",
  "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
  "state": "booked",
  "created_at": 1616059590812
}

}
Parameter Type Description
orders SpotLimitOrder Array of SpotLimitOrder

SpotLimitOrder

Parameter Type Description
state String Order state (Should be one of: [booked partial_filled filled canceled])
subaccount_id String The subaccount ID this order belongs to
unfilled_quantity String The amount of the quantity remaining unfilled
market_id String Spot market ID is keccak265(baseDenom + quoteDenom)
order_hash String Hash of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
fee_recipient String The fee recipient address
price String The price of the order
quantity String The quantity of the order
trigger_price String The price used by stop/take orders
created_at Integer Order committed timestamp in UNIX millis

SubaccountTradesList

Get trades of a subaccount.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    direction = "buy" # buy or sell
    execution_type = "market" # market, limitFill, limitMatchRestingOrder or limitMatchNewOrder
    trades = await client.get_spot_subaccount_trades(subaccount_id=subaccount_id, market_id=market_id, execution_type=execution_type, direction=direction)
    print(trades)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, TradeExecutionType, TradeDirection, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0";
  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const direction = TradeDirection.Buy;
  const executionType = TradeExecutionType.Market;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.spotApi.fetchSpotSubaccountTradesList(
    {
      subaccountId: subaccountId,
      marketId: marketId,
      direction: direction,
      executionType: executionType,
      pagination: pagination,
    }
  );

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
market_id String Filter by market ID No
direction String Filter by the direction of the trades (Should be one of: [buy sell]) No
execution_type String Filter by the execution type of the trades (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Response Example:

{
"trades": {
  "order_hash": "0x66616966cb813a4fd89603f3bfe9a762db659b6a5890ba8572925e22e727dafe",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "limitMatchRestingOrder",
  "trade_direction": "buy",
  "price": {
    "price": "0.000000000010952",
    "quantity": "650000000000000000000",
    "timestamp": 1633088740309
  },
  "fee": "7118800",
  "executed_at": 1633088740309
},
"trades": {
  "order_hash": "0x66616966cb813a4fd89603f3bfe9a762db659b6a5890ba8572925e22e727dafe",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0",
  "trade_execution_type": "limitMatchRestingOrder",
  "trade_direction": "buy",
  "price": {
    "price": "0.000000000010965",
    "quantity": "650000000000000000000",
    "timestamp": 1633088723991
  },
  "fee": "7127250",
  "executed_at": 1633088723991,
  "fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
}

}
Parameter Type Description
trades SpotTrade Array of SpotTrade

SpotTrade

Parameter Type Description
trade_direction String Filter by the trade direction(Should be one of: [buy sell])
trade_execution_type String Filter by the trade execution type (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade (quote asset denom)
market_id String Filter by the market ID
order_hash String The order hash
price PriceLevel Array of PriceLevel
subaccount_id String Filter by the subaccount ID
executed_at Integer Timestamp of trade execution in UNIX millis
fee_recipient String The address that received 40% of the fees

PriceLevel

Parameter Type Description
price String Number of the price level
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis

- InjectiveDerivativeExchangeRPC

InjectiveDerivativeExchangeRPC defines the gRPC API of the Derivative Exchange provider.

Market

Get details of a derivative market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    market = await client.get_derivative_market(market_id=market_id)
    print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.derivativesApi.fetchDerivativeMarket(marketId);

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes

Response Parameters

Response Example:

{
  "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.05",
  "maintenance_margin_ratio": "0.02",
  "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": 1632535056616
  },
  "maker_fee_rate": "0.001",
  "taker_fee_rate": "0.002",
  "service_provider_fee": "0.4",
  "is_perpetual": true,
  "min_price_tick_size": "1000",
  "min_quantity_tick_size": "0.01",
  "perpetual_market_info": {
    "hourly_funding_rate_cap": "0.000625",
    "hourly_interest_rate": "0.00000416666",
    "next_funding_timestamp": 1634806800,
    "funding_interval": 3600
  },
  "perpetual_market_funding": {
    "cumulative_funding": "0.675810253053067335",
    "cumulative_price": "20.137372841146815096",
    "last_timestamp": 1634806754
  }
}
}
Parameter Type Description
market DerivativeMarketInfo Array of DerivativeMarketInfo

DerivativeMarketInfo

Parameter Type Description
oracle_quote String Oracle quote currency
oracle_type String Oracle Type
quote_denom String Coin denom used for the quote asset
is_perpetual Boolean True if the market is a perpetual swap market
maker_fee_rate String Defines the fee percentage makers pay when trading (in quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
oracle_scale_factor Integer OracleScaleFactor
taker_fee_rate String Defines the fee percentage takers pay when trading (in quote asset)
expiry_futures_market_info Array Array of ExpiryFuturesMarketInfo
initial_margin_ratio String Defines the initial margin ratio of a derivative market
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
service_provider_fee String Percentage of the transaction fee shared with the service provider
oracle_base String Oracle base currency
perpetual_market_funding PerpetualMarketFunding Array of PerpetualMarketFunding
perpetual_market_info PerpetualMarketInfo Array of PerpetualMarketInfo
ticker String The name of the pair in format AAA/BBB, where AAA is the base asset and BBB is the quote asset
maintenance_margin_ratio String Defines the maintenance margin ratio of a derivative market
market_id String The market ID
quoteTokenMeta TokenMeta Array of TokenMeta

PerpetualMarketFunding

Parameter Type Description
cumulative_funding String Defines the cumulative funding of a perpetual market
cumulative_price String Defines the cumulative price for the current hour up to the last timestamp
last_timestamp Integer Defines the last funding timestamp in UNIX seconds

PerpetualMarketInfo

Parameter Type Description
hourly_funding_rate_cap String Defines the default maximum absolute value of the hourly funding rate
hourly_interest_rate String Defines the hourly interest rate of the perpetual market
next_funding_timestamp Integer Defines the next funding timestamp in UNIX seconds
funding_interval Integer Defines the funding interval in seconds

TokenMeta

Parameter Type Description
updated_at Integer Token metadata fetched timestamp in UNIX millis
address String Token Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name

Markets

Get a list of derivative markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_status = "active" # active, paused, suspended, demolished or expired
    quote_denom = "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7"
    market = await client.get_derivative_markets(market_status=market_status, quote_denom=quote_denom)
    print(market)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketStatus = "active";
  const quoteDenom = "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const markets = await exchangeClient.derivativesApi.fetchDerivativeMarkets(
    {
      marketStatus: marketStatus,
      quoteDenom: quoteDenom
    }
  );

  console.log(protoObjectToJson(markets, {}));
})();

Parameter Type Description Required
market_status String Filter by market status (Should be one of: [active paused suspended demolished expired]) No
quote_denom String Filter by the Coin denomination of the quote currency No

Response Parameters

Response Example:

{
  "markets": {
  "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.05",
  "maintenance_margin_ratio": "0.02",
  "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": 1632535056616
  },
  "maker_fee_rate": "0.001",
  "taker_fee_rate": "0.002",
  "service_provider_fee": "0.4",
  "is_perpetual": true,
  "min_price_tick_size": "1000",
  "min_quantity_tick_size": "0.01",
  "perpetual_market_info": {
    "hourly_funding_rate_cap": "0.000625",
    "hourly_interest_rate": "0.00000416666",
    "next_funding_timestamp": 1634806800,
    "funding_interval": 3600
  },
  "perpetual_market_funding": {
    "cumulative_funding": "0.675810253053067335",
    "cumulative_price": "20.137372841146815096",
    "last_timestamp": 1634806754
  }
}
}
Parameter Type Description
markets DerivativeMarketInfo Array of DerivativeMarketInfo

DerivativeMarketInfo

Parameter Type Description
oracle_quote String Oracle quote currency
oracle_type String Oracle Type
quote_denom String Coin denom used for the quote asset
is_perpetual Boolean True if the market is a perpetual swap market
maker_fee_rate String Defines the fee percentage makers pay when trading (in quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
oracle_scale_factor Integer OracleScaleFactor
taker_fee_rate String Defines the fee percentage takers pay when trading (in quote asset)
expiry_futures_market_info Array Array of ExpiryFuturesMarketInfo
initial_margin_ratio String Defines the initial margin ratio of a derivative market
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
service_provider_fee String Percentage of the transaction fee shared with the service provider
oracle_base String Oracle base currency
perpetual_market_funding PerpetualMarketFunding Array of PerpetualMarketFunding
perpetual_market_info PerpetualMarketInfo Array of PerpetualMarketInfo
ticker String The name of the pair in format AAA/BBB, where AAA is the base asset and BBB is the quote asset
maintenance_margin_ratio String Defines the maintenance margin ratio of a derivative market
market_id String The market ID
quoteTokenMeta TokenMeta Array of TokenMeta

PerpetualMarketFunding

Parameter Type Description
cumulative_funding String Defines the cumulative funding of a perpetual market
cumulative_price String Defines the cumulative price for the current hour up to the last timestamp
last_timestamp Integer Defines the last funding timestamp in UNIX seconds

PerpetualMarketInfo

Parameter Type Description
hourly_funding_rate_cap String Defines the default maximum absolute value of the hourly funding rate
hourly_interest_rate String Defines the hourly interest rate of the perpetual market
next_funding_timestamp Integer Defines the next funding timestamp in UNIX seconds
funding_interval Integer Defines the funding interval in seconds

TokenMeta

Parameter Type Description
updated_at Integer Token metadata fetched timestamp in UNIX millis
address String Token Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name

StreamMarket

Stream live updates of derivative markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    markets = await client.stream_derivative_markets()
    async for market in markets:
        print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketIds = ["0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.derivativesStream.streamDerivativeMarket(
    {
      marketIds,
      callback: (streamDerivativeMarket) => {
        console.log(protoObjectToJson(streamDerivativeMarket, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Response Parameters

Streaming Response Example:

{
  "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.05",
  "maintenance_margin_ratio": "0.02",
  "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": 1632535056616
  },
  "maker_fee_rate": "0.001",
  "taker_fee_rate": "0.002",
  "service_provider_fee": "0.4",
  "is_perpetual": true,
  "min_price_tick_size": "1000",
  "min_quantity_tick_size": "0.01",
  "perpetual_market_info": {
    "hourly_funding_rate_cap": "0.000625",
    "hourly_interest_rate": "0.00000416666",
    "next_funding_timestamp": 1634806800,
    "funding_interval": 3600
  },
  "perpetual_market_funding": {
    "cumulative_funding": "0.675810253053067335",
    "cumulative_price": "20.137372841146815096",
    "last_timestamp": 1634806754
  }
}
}
Parameter Type Description
market DerivativeMarketInfo Array of DerivativeMarketInfo

DerivativeMarketInfo

Parameter Type Description
oracle_quote String Oracle quote currency
oracle_type String Oracle Type
quote_denom String Coin denom used for the quote asset
is_perpetual Boolean True if the market is a perpetual swap market
maker_fee_rate String Defines the fee percentage makers pay when trading (in quote asset)
min_price_tick_size String Defines the minimum required tick size for the order's price
min_quantity_tick_size String Defines the minimum required tick size for the order's quantity
oracle_scale_factor Integer OracleScaleFactor
taker_fee_rate String Defines the fee percentage takers pay when trading (in quote asset)
expiry_futures_market_info Array Array of ExpiryFuturesMarketInfo
initial_margin_ratio String Defines the initial margin ratio of a derivative market
market_status String The status of the market (Should be one of: [active paused suspended demolished expired])
service_provider_fee String Percentage of the transaction fee shared with the service provider
oracle_base String Oracle base currency
perpetual_market_funding PerpetualMarketFunding Array of PerpetualMarketFunding
perpetual_market_info PerpetualMarketInfo Array of PerpetualMarketInfo
ticker String The name of the pair in format AAA/BBB, where AAA is the base asset and BBB is the quote asset
maintenance_margin_ratio String Defines the maintenance margin ratio of a derivative market
market_id String The market ID
quoteTokenMeta TokenMeta Array of TokenMeta

PerpetualMarketFunding

Parameter Type Description
cumulative_funding String Defines the cumulative funding of a perpetual market
cumulative_price String Defines the cumulative price for the current hour up to the last timestamp
last_timestamp Integer Defines the last funding timestamp in UNIX seconds

PerpetualMarketInfo

Parameter Type Description
hourly_funding_rate_cap String Defines the default maximum absolute value of the hourly funding rate
hourly_interest_rate String Defines the hourly interest rate of the perpetual market
next_funding_timestamp Integer Defines the next funding timestamp in UNIX seconds
funding_interval Integer Defines the funding interval in seconds

TokenMeta

Parameter Type Description
updated_at Integer Token metadata fetched timestamp in UNIX millis
address String Token Ethereum contract address
decimals Integer Token decimals
logo String URL to the logo image
name String Token full name
symbol String Token symbol short name

Orders

Get orders of a derivative market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id= "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    order_side = "buy" # buy or sell
    orders = await client.get_derivative_orders(market_id=market_id, order_side=order_side, subaccount_id=subaccount_id)
    print(orders)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  req := derivativeExchangePB.OrdersRequest{
    MarketId: marketId,
  }

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

  fmt.Println(res)
}

import {getNetworkInfo, Network} from "@injectivelabs/networks";
import {protoObjectToJson, DerivativeOrderSide, ExchangeClient} from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const orderSide = DerivativeOrderSide.Buy;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const orders = await exchangeClient.derivativesApi.fetchDerivativeOrders({
    marketId: marketId,
    subaccountId: subaccountId,
    orderSide: orderSide,
    pagination: pagination,
  });

  console.log(protoObjectToJson(orders, {}));
})();
Parameter Type Description Required
market_id String Filter by market ID Yes
subaccount_id String Filter by subaccount ID No
order_side String Filter by order side (Should be one of: [buy sell]) No
skip Integer Skip the last orders, you can use this to fetch all orders since the API caps at 100 No
limit Integer Limit the orders returned No

Response Parameters

Response Example:

{
"orders": {
  "order_hash": "0xeb650941906fe707534a70979c43714c0ca703b0d02e450a9f25bbe302419fc9",
  "order_side": "buy",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "margin": "507634400000",
  "price": "39048800000",
  "quantity": "13",
  "unfilled_quantity": "13",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "booked",
  "created_at": 1616059590812
},
"orders": {
  "order_hash": "0xbdb49ed59947cdce7544aa8d983b77f76e50177cc4287a6136bee8f16deb4bd2",
  "order_side": "buy",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "margin": "500714162000",
  "price": "38516474000",
  "quantity": "13",
  "unfilled_quantity": "13",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "booked",
  "created_at": 1616059590812
}

}
Parameter Type Description
orders Array of DerivativeLimitOrder List of derivative market orders

DerivativeLimitOrder:

Parameter Type Description
fee_recipient String Fee recipient address
order_hash String Hash of the order
quantity String Quantity of the order
state String Order state (Should be one of: [booked partial_filled filled canceled])
trigger_price String Trigger price is the trigger price used by stop/take orders
market_id String Derivative Market ID
created_at Integer Order committed timestamp in UNIX millis.
price String Price of the order
subaccount_id String The subaccountId that this order belongs to
updated_at Integer Order updated timestamp in UNIX millis.
is_reduce_only Boolean True if the order is a reduce-only order
margin String Margin of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
unfilled_quantity String The amount of the quantity remaining unfilled

StreamOrders

Stream order updates of a derivative market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    order_side = "buy" # buy or sell
    orders = await client.stream_derivative_orders(market_id=market_id, order_side=order_side, subaccount_id=subaccount_id)
    async for order in orders:
        print(order)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

  ctx := context.Background()
  marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
  subaccountId := "0x7453466968297ccaf24f78deb674ad54f9b86697000000000000000000000000"
  orderSide := "buy"

  req := derivativeExchangePB.StreamOrdersRequest{
    MarketId:     marketId,
    SubaccountId: subaccountId,
    OrderSide:    orderSide,
  }
  stream, err := exchangeClient.StreamDerivativeOrders(ctx, req)
  if err != nil {
    panic(err)
  }

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        panic(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, DerivativeOrderSide, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const orderSide = DerivativeOrderSide.Buy;

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.derivativesStream.streamDerivativeOrders(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      orderSide: orderSide,
      callback: (streamDerivativeOrders) => {
        console.log(protoObjectToJson(streamDerivativeOrders, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
order_side String Filter by order side (Should be one of: [buy sell]) No
subaccount_id String Filter by subaccount ID No

Response Parameters

Streaming Response Example:

{
"orders": {
  "order_hash": "0xeb650941906fe707534a70979c43714c0ca703b0d02e450a9f25bbe302419fc9",
  "order_side": "buy",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "margin": "507634400000",
  "price": "39048800000",
  "quantity": "13",
  "unfilled_quantity": "13",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "booked",
  "created_at": 1616059590812,
},
  "operation_type": "update",
  "timestamp": 1634815592000,

"orders": {
  "order_hash": "0xbdb49ed59947cdce7544aa8d983b77f76e50177cc4287a6136bee8f16deb4bd2",
  "order_side": "buy",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "margin": "500714162000",
  "price": "38516474000",
  "quantity": "13",
  "unfilled_quantity": "13",
  "trigger_price": "0",
  "fee_recipient": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "state": "booked",
  "created_at": 1616059590812
},
  "operation_type": "update",
  "timestamp": 1634815592000,

}
Parameter Type Description
order DerivativeLimitOrder Array of DerivativeLimitOrder
operation_type String Order update type (Should be one of: [insert delete replace update invalidate])
timestamp Integer Operation timestamp in UNIX millis

DerivativeLimitOrder

Parameter Type Description
fee_recipient String Fee recipient address
order_hash String Hash of the order
quantity String Quantity of the order
state String Order state (Should be one of: [booked partial_filled filled canceled])
trigger_price String The price used by stop/take orders
market_id String The market ID
created_at Integer Order committed timestamp in UNIX millis
price String Price of the order
subaccount_id String The subaccount ID this order belongs to
updated_at Integer Order updated timestamp in UNIX millis
is_reduce_only Boolean True if the order is a reduce-only order
margin String Margin of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
unfilled_quantity String The amount of the quantity remaining unfilled

Trades

Get trades of a derivative market.

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 the other way around (new limit order getting matched)

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    trades = await client.get_derivative_trades(market_id=market_id, subaccount_id=subaccount_id)
    print(trades)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, TradeExecutionSide, TradeDirection, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const executionSide = TradeExecutionSide.Maker;
  const direction = TradeDirection.Buy;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const trades = await exchangeClient.derivativesApi.fetchDerivativeTrades(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      executionSide: executionSide,
      direction: direction,
      pagination: pagination,
    }
  );

  console.log(protoObjectToJson(trades, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
subaccount_id String Filter by subaccount ID No
execution_side String Filter by the execution side of the trade (Should be one of: [maker taker]) No
direction String Filter by the direction of the trade (Should be one of: [buy sell]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Response Example:

{
  "trades": {
  "order_hash": "0xfdd7865b3fe35fe986b07fafea8e1c301a9d83f9683542505085eb8730c3a907",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchRestingOrder",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "63003464233.333333333333333333",
    "execution_quantity": "1",
    "execution_margin": "66900442000",
  },
  "payout": "65693228106.612872505612710833",
  "fee": "63003464.233333333333333333",
  "executed_at": 1634816869894
},
"trades": {
  "order_hash": "0x28a99e824c0e19c1bdd63676cfe58f37c018f9db12b9c3e5466c377e1354633c",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchRestingOrder",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "63003464233.333333333333333333",
    "execution_quantity": "1",
    "execution_margin": "66576312000"
  },
  "payout": "65693228106.612872505612710833",
  "fee": "63003464.233333333333333333",
  "executed_at": 1634816869894,
  "fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"
}

}
Parameter Type Description
trades DerivativeTrade Array of DerivativeTrade

DerivativeTrade

Parameter Type Description
executed_at Integer Timestamp of trade execution in UNIX millis
position_delta PositionDelta Array of PositionDelta
subaccount_id String The subaccount ID that executed the trade
trade_execution_type String The execution type of the trade (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade
is_liquidation Boolean True if the trade is a liquidation
market_id String The market ID
order_hash String The order hash
payout String The payout associated with the trade
fee_recipient String The address that received 40% of the fees

PositionDelta

Parameter Type Description
execution_price String Execution price of the trade
execution_quantity String Execution quantity of the trade
trade_direction String The direction the trade (Should be one of: [buy sell])
execution_margin String Execution margin of the trade

StreamTrades

Stream trades of a derivative market.

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 the other way around (new limit order getting matched)

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    trades = await client.stream_derivative_trades(market_id=market_id, subaccount_id=subaccount_id)
    async for trade in trades:
        print(trade)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        panic(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import {getNetworkInfo, Network} from "@injectivelabs/networks";
import {protoObjectToJson, ExchangeClient, TradeDirection, TradeExecutionSide} from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketIds = ["0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"];
  const subaccountIds = ["0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"];
  const executionSide = TradeExecutionSide.Maker;
  const direction = TradeDirection.Buy;
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.derivativesStream.streamDerivativeTrades(
    {
      marketIds: marketIds,
      subaccountIds: subaccountIds,
      executionSide: executionSide,
      direction: direction,
      pagination: pagination,
      callback: (streamDerivativeTrades) => {
        console.log(protoObjectToJson(streamDerivativeTrades, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();


Parameter Type Description Required
market_ids Array Filter by an array of market IDs Conditional
market_id String Filter by market ID Conditional
subaccount_ids Array Filter by an array of subaccount IDs Conditional
subaccount_id String Filter by subaccount ID Conditional
execution_side String Filter by the execution side of the trade (Should be one of: [maker taker]) No
direction String Filter by the direction of the trade (Should be one of: [buy sell]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Streaming Response Example:

{
  "trade": {
  "order_hash": "0x53940e211d5cd6caa2ea4f9d557c6992a8165ce328e7a3220b4b0e8ae7909897",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchNewOrder",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "65765036468.75",
    "execution_quantity": "4",
    "execution_margin": "271119536000"
  },
  "payout": "249899684995.443928042695147937",
  "fee": "526120291.75",
  "executed_at": 1634817291783
},
"operation_type": "insert",
"timestamp": 1634817293000,

"trade": {
  "order_hash": "0x88cc481ff9f0e77a51fd1e829647bad434787080963bf20e275beb692a5d3558",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchNewOrder",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "65765036468.75",
    "execution_quantity": "6",
    "execution_margin": "396570642000"
  },
  "payout": "374849527493.165892064042721905",
  "fee": "789180437.625",
  "executed_at": 1634817291783
},
"operation_type": "insert",
"timestamp": 1634817293000,
"fee_recipient": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku"


}
Parameter Type Description
trade DerivativeTrade Array of DerivativeTrade
operation_type String Executed trades update type (Should be one of: [insert invalidate])
timestamp Integer Operation timestamp in UNIX millis

DerivativeTrade

Parameter Type Description
executed_at Integer Timestamp of trade execution in UNIX millis
position_delta PositionDelta Array of PositionDelta
subaccount_id String The subaccount ID that executed the trade
trade_execution_type String The execution type of the trade (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade
is_liquidation Boolean True if the trade is a liquidation
market_id String The market ID
order_hash String The order hash
payout String The payout associated with the trade
fee_recipient String The address that received 40% of the fees

PositionDelta

Parameter Type Description
execution_price String Execution price of the trade
execution_quantity String Execution quantity of the trade
trade_direction String The direction the trade (Should be one of: [buy sell])
execution_margin String Execution margin of the trade

Positions

Get the positions of a market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    positions = await client.get_derivative_positions(market_id=market_id, subaccount_id=subaccount_id)
    print(positions)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";
  const pagination = {
    skip: 0,
    limit: 10,
    key: ""
  };

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const positions = await exchangeClient.derivativesApi.fetchDerivativePositions(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      pagination: pagination,
  });

  console.log(protoObjectToJson(positions, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
subaccount_id String Filter by subaccount ID No
skip Integer Skip the last positions, you can use this to fetch all positions since the API caps at 100 No
limit Integer Limit the positions returned No

Response Parameters

Response Example:

{
"positions": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xdffcc8962c7662ba69c3eb2b5ed7c435879e5229000000000000000000000000",
  "direction": "long",
  "quantity": "0.75",
  "entry_price": "34478090933.333333333333333333",
  "margin": "-19949596884",
  "liquidation_price": "62324034127",
  "mark_price": "64595190000",
  "aggregate_reduce_only_quantity": "0"
},
"positions": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xfdc59dcaa0077fc178bcf12f9d677cbe75511d4a000000000000000000000000",
  "direction": "long",
  "quantity": "28.35",
  "entry_price": "29450904077.30599647266313933",
  "margin": "-693874107774",
  "liquidation_price": "55026715558",
  "mark_price": "64595190000",
  "aggregate_reduce_only_quantity": "0"
}

}
Parameter Type Description
positions DerivativePosition Array of DerivativePosition

DerivativePosition

Parameter Type Description
direction String Direction of the position (Should be one of: [long short])
market_id String The market ID
subaccount_id String The subaccount ID the position belongs to
ticker String Ticker of the derivative market
aggregate_reduce_only_quantity String Aggregate quantity of the reduce-only orders associated with the position
entry_price String Entry price of the position
liquidation_price String Liquidation price of the position
margin String Margin of the position
mark_price String Oracle price of the base asset
quantity String Quantity of the position

StreamPositions

Stream position updates for a specific market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000"
    positions = await client.stream_derivative_positions(market_id=market_id, subaccount_id=subaccount_id)
    async for position in positions:
        print(position)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        panic(err)
        return
      }
      fmt.Println(res)
    }
  }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const subaccountId = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000";

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.derivativesStream.streamDerivativePositions(
    {
      marketId,
      subaccountId,
      callback: (streamDerivativePositions) => {
        console.log(protoObjectToJson(streamDerivativePositions, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_id String Filter by market ID Yes
subaccount_ids Array Filter by an array of subaccount IDs Conditional
subaccount_id String Filter by subaccount ID Conditional

Response Parameters

Streaming Response Example:

{
"position": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "direction": "short",
  "quantity": "500.36",
  "entry_price": "64766166958.497442183360445476",
  "margin": "31629324725359",
  "liquidation_price": "125469904854",
  "mark_price": "64878330000",
  "aggregate_reduce_only_quantity": "0"
},
"timestamp": 1634817807000,

"position": {
  "ticker": "BTC/USDT PERP",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000",
  "direction": "short",
  "quantity": "500.36",
  "entry_price": "64705529584.98346944076741553",
  "margin": "31605881697496",
  "liquidation_price": "125364522799",
  "mark_price": "64919990000",
  "aggregate_reduce_only_quantity": "0"
},
"timestamp": 1634817814000

}
Parameter Type Description
positions DerivativePosition Array of DerivativePosition
timestamp Integer Operation timestamp in UNIX millis

DerivativePosition

Parameter Type Description
direction String Direction of the position (Should be one of: [long short])
market_id String The market ID
subaccount_id String The subaccount ID the position belongs to
ticker String Ticker of the derivative market
aggregate_reduce_only_quantity String Aggregate quantity of the reduce-only orders associated with the position
entry_price String Entry price of the position
liquidation_price String Liquidation price of the position
margin String Margin of the position
mark_price String Oracle price of the base asset
quantity String Quantity of the position

Orderbook

Get the orderbook of a derivative market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    market = await client.get_derivative_orderbook(market_id=market_id)
    print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const orderbook = await exchangeClient.derivativesApi.fetchDerivativeOrderbook(marketId);

  console.log(protoObjectToJson(orderbook, {}));
})();

Parameter Type Description Required
market_id String Filter by market ID Yes

Response Parameters

Response Example:

{
  "orderbook": {
    "buys": [
      {
        "price": "41236062000",
        "quantity": "0.15",
        "timestamp": 1632184552530
      },
      {
        "price": "41186284000",
        "quantity": "0.15",
        "timestamp": 1632183950930
      }
    ],
    "sells": [
      {
        "price": "43015302000",
        "quantity": "0.05",
        "timestamp": 1632241829042
      },
      {
        "price": "43141817000",
        "quantity": "0.3",
        "timestamp": 1632242197021
      }
    ]
  }
}
Parameter Type Description
orderbook DerivativeLimitOrderbook Array of DerivativeLimitOrderbook

DerivativeLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis
price String Price number of the price level

Orderbooks

Get the orderbook for an array of derivative markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
        market_ids = [
        "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
        "0x1f73e21972972c69c03fb105a5864592ac2b47996ffea3c500d1ea2d20138717"
    ]
    market = await client.get_derivative_orderbooks(market_ids=market_ids)
    print(market)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketIds = ["0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const market = await exchangeClient.derivativesApi.fetchDerivativeOrderbooks(marketIds);

  console.log(protoObjectToJson(market, {}));
})();

Parameter Type Description Required
market_ids Array Filter by an array of market IDs Yes

Response Parameters

Response Example:

{
"orderbooks": {
  "market_id": "0x1f73e21972972c69c03fb105a5864592ac2b47996ffea3c500d1ea2d20138717",
  "orderbook": {
    "buys": {
      "price": "13107000",
      "quantity": "0.3",
      "timestamp": 1646998496535
    },
    "buys": {
      "price": "12989000",
      "quantity": "0.8",
      "timestamp": 1646998520256
    }
  }
},
"orderbooks": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "orderbook": {
    "buys": {
      "price": "39873942000",
      "quantity": "0.1",
      "timestamp": 1646998535041
    },
    "buys": {
      "price": "39752458000",
      "quantity": "0.3",
      "timestamp": 1646998517630
    }
  }
}
}
Parameter Type Description
orderbook DerivativeLimitOrderbook Array of DerivativeLimitOrderbook
market_id String Filter by market ID

DerivativeLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis
price String Price number of the price level

StreamOrderbooks

Stream orderbook updates for an array of derivative markets.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_ids = ["0x897519d4cf8c460481638b3ff64871668d0a7f6afea10c1b0a952c0b5927f48f", "0x31200279ada822061217372150d567be124f02df157650395d1d6ce58a8207aa"]
    orderbooks = await client.stream_derivative_orderbooks(market_ids=market_ids)
    async for orderbook in orderbooks:
        print(orderbook)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        panic(err)
        return
      }
      fmt.Println(res)
    }
  }
}
import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketIds = ["0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"];

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.derivativesStream.streamDerivativeOrderbook(
    {
      marketIds,
      callback: (streamDerivativeOrderbook) => {
        console.log(protoObjectToJson(streamDerivativeOrderbook, {}));
      },
      onEndCallback: (status) => {
        console.log("Stream has ended with status: " + status);
      },
    });
})();

Parameter Type Description Required
market_ids Array Filter by market IDs Yes

Response Parameters

Streaming Response Example:

{
"orderbook": {
  "buys": {
    "price": "486810000",
    "quantity": "8",
    "timestamp": 1642519597300
  },
  "buys": {
    "price": "476840000",
    "quantity": "2",
    "timestamp": 1642519597300
  },
  "sells": {
    "price": "515310000",
    "quantity": "20",
    "timestamp": 1642754433928
  },
  "sells": {
    "price": "517680000",
    "quantity": "19",
    "timestamp": 1642754322373
  }
},
"operation_type": "update",
"timestamp": 1642754436000,
"market_id": "0x1c79dac019f73e4060494ab1b4fcba734350656d6fc4d474f6a238c13c6f9ced"


}
Parameter Type Description
operation_type String Order update type (Should be one of: [insert delete replace update invalidate])
orderbook DerivativeLimitOrderbook Array of DerivativeLimitOrderbook
timestamp Integer Operation timestamp in UNIX millis
market_id String Filter by market ID

DerivativeLimitOrderbook

Parameter Type Description
buys PriceLevel Array of PriceLevel
sells PriceLevel Array of PriceLevel

PriceLevel

Parameter Type Description
quantity String Quantity of the price level
timestamp Integer Price level last updated timestamp in UNIX millis
price String Price number of the price level

SubaccountOrdersList

Get the derivative orders of a specific subaccount.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    orders = await client.get_derivative_subaccount_orders(subaccount_id=subaccount_id, market_id=market_id)
    print(orders)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountOrders = await exchangeClient.derivativesApi.fetchDerivativeSubaccountOrdersList(
    {
      subaccountId: subaccountId,
      marketId: marketId,
    }
  );

  console.log(protoObjectToJson(subaccountOrders, {}));
})();
Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
market_id String Filter by market ID No
skip Integer Skip the last orders, you can use this to fetch all orders since the API caps at 100 No
limit Integer Limit the orders returned No

Response Parameters

Response Example:

{
"orders": {
  "order_hash": "0xc62f52eb7bfc034c26a0a53f21f8588e27ba9b7daac226aac805ae9dcb2e4ea9",
  "order_side": "buy",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "margin": "30000000000",
  "price": "30000000000",
  "quantity": "1",
  "unfilled_quantity": "1",
  "trigger_price": "0",
  "fee_recipient": "inj1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8dkncm8",
  "state": "booked",
  "created_at": 1642754699821,
  "updated_at": 1642754699821
}

}
Parameter Type Description
orders DerivativeLimitOrder Array of DerivativeLimitOrder

DerivativeLimitOrder

Parameter Type Description
fee_recipient String Fee recipient address
order_hash String Hash of the order
quantity String Quantity of the order
state String Order state (Should be one of: [booked partial_filled filled canceled])
trigger_price String The price used by stop/take orders
market_id String The market ID
created_at Integer Order committed timestamp in UNIX millis
price String Price of the order
subaccount_id String The subaccount ID this order belongs to
updated_at Integer Order updated timestamp in UNIX millis
is_reduce_only Boolean True if the order is a reduce-only order
margin String Margin of the order
order_side String The type of the order (Should be one of: [buy sell stop_buy stop_sell take_buy take_sell])
unfilled_quantity String The amount of the quantity remaining unfilled

SubaccountTradesList

Get the derivative trades for a specific subaccount.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    execution_type = "market" # market, limitFill, limitMatchRestingOrder or limitMatchNewOrder
    direction = "buy" # buy or sell
    trades = await client.get_derivative_subaccount_trades(subaccount_id=subaccount_id, market_id=market_id, execution_type=execution_type, direction=direction)
    print(trades)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    panic(err)
  }

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

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

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, TradeDirection, TradeExecutionType, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const direction = TradeDirection.Buy;
  const executionType = TradeExecutionType.Market;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const subaccountTrades = await exchangeClient.derivativesApi.fetchDerivativeSubaccountTradesList(
    {
      subaccountId: subaccountId,
      marketId: marketId,
      direction: direction,
      executionType: executionType,
    }
  );

  console.log(protoObjectToJson(subaccountTrades, {}));
})();
Parameter Type Description Required
subaccount_id String Filter by Subaccount ID Yes
market_id String Filter by Market ID No
direction String Filter by the direction of the trades (Should be one of: [buy sell]) No
execution_type String Filter by the execution type of the trades (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder]) No
skip Integer Skip the last trades, you can use this to fetch all trades since the API caps at 100 No
limit Integer Limit the trades returned No

Response Parameters

Response Example:

{
"trades": {
  "order_hash": "0x86ba61241e10ec8f38ae00c5c7245604716f96894d87c826dc4f64d83b4f5d2c",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "limitMatchNewOrder",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "40788500000",
    "execution_quantity": "0.01",
    "execution_margin": "586100000"
  },
  "payout": "0",
  "fee": "489462",
  "executed_at": 1642585227580,
  "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
},
"trades": {
  "order_hash": "0x93b6420c81ed82f1c3c1dbcc60afc86efd62a46756b2db81da511c0ae9c3f4a2",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "trade_execution_type": "market",
  "position_delta": {
    "trade_direction": "buy",
    "execution_price": "42855400000",
    "execution_quantity": "0.01",
    "execution_margin": "166600000"
  },
  "payout": "0",
  "fee": "514264.8",
  "executed_at": 1642584958566,
  "fee_recipient": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
}

}
Parameter Type Description
trades DerivativeTrade Array of DerivativeTrade

DerivativeTrade

Parameter Type Description
executed_at Integer Timestamp of trade execution in UNIX millis
position_delta PositionDelta Array of PositionDelta
subaccount_id String The subaccount ID that executed the trade
trade_execution_type String The execution type of the trade (Should be one of: [market limitFill limitMatchRestingOrder limitMatchNewOrder])
fee String The fee associated with the trade
is_liquidation Boolean True if the trade is a liquidation
market_id String The market ID
order_hash String The order hash
payout String The payout associated with the trade
fee_recipient String The address that received 40% of the fees

PositionDelta

Parameter Type Description
execution_price String Execution price of the trade
execution_quantity String Execution quantity of the trade
trade_direction String The direction the trade (Should be one of: [buy sell])
execution_margin String Execution margin of the trade

FundingPayments

Get the funding payments for a subaccount.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000"
    funding = await client.get_funding_payments(market_id=market_id, subaccount_id=subaccount_id)
    print(funding)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const subaccountId = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000";
  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const skip = 0;
  const limit = 10;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const fundingPayments = await exchangeClient.derivativesApi.fetchDerivativeFundingPayments(
    {
      marketId: marketId,
      subaccountId: subaccountId,
      pagination: {
        skip: skip,
        limit: limit,
        key: ""
      }
    }
  );

  console.log(protoObjectToJson(fundingPayments, {}));
})();
Parameter Type Description Required
subaccount_id String Filter by subaccount ID Yes
market_id String Filter by market ID No
skip Integer Skip the last funding payments, you can use this to fetch all payments since the API caps at 100 No
limit Integer Limit the funding payments returned No

Response Parameters

Response Example:

{
"payments": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "subaccount_id": "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
  "amount": "79677138",
  "timestamp": 1634515200458
}

}
Parameter Type Description
market_id String The market ID
subaccount_id String The subaccount ID
amount String The amount of the funding payment
timestamp Integer Operation timestamp in UNIX millis

FundingRates

Get the historical funding rates for a specific market.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    skip=0
    limit=2
    funding_rates = await client.get_funding_rates(
        market_id=market_id,
        skip=skip,
        limit=limit
    )
    print(funding_rates)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  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)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const marketId = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce";
  const skip = 0;
  const limit = 10;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );

  const fundingRates = await exchangeClient.derivativesApi.fetchDerivativeFundingRates(
    {
      marketId,
      pagination: {
        skip: skip,
        limit: limit,
        key: "" }
    }
    );

  console.log(protoObjectToJson(fundingRates, {}));
})();
Parameter Type Description Required
market_id String Filter by market ID Yes
skip Integer Skip the last funding rates, you can use this to fetch all funding rates since the API caps at 100 No
limit Integer Limit the funding rates returned No

Response Parameters

Response Example:

{
"funding_rates": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "rate": "0.00449891062",
  "timestamp": 1643572800988
},
"funding_rates": {
  "market_id": "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
  "rate": "-0.03218407323",
  "timestamp": 1643587201580
}

}
Parameter Type Description
market_id String The market ID
rate String The funding rate
timestamp Integer Timestamp in UNIX millis

- InjectiveOracleRPC

InjectiveOracleRPC defines the gRPC API of the Exchange Oracle provider.

OracleList

Get a list with oracles and feeds.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    oracle_list = await client.get_oracle_list()
    print(oracle_list)
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("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()
    res, err := exchangeClient.GetOracleList(ctx)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const oracleList = await exchangeClient.oracleApi.fetchOracleList(
  );

  console.log(protoObjectToJson(oracleList, {}));
})();

Response Parameters

Response Example:

{
"oracles": {
  "symbol": "ADA",
  "oracle_type": "bandibc",
  "price": "2.797398",
},
"oracles": {
  "symbol": "AKRO",
  "oracle_type": "bandibc",
  "price": "0.0333066"
},
"oracles": {
  "symbol": "AMPL",
  "oracle_type": "bandibc",
  "price": "0.955257"
}

}

Parameter Type Description
oracles Oracle Array of Oracle

Oracle

Parameter Type Description
symbol String The symbol of the asset
oracle_type String The oracle provider
price String The price of the asset

Price

Get the oracle price of an asset.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    base_symbol = 'BTC'
    quote_symbol = 'USDT'
    oracle_type = 'bandibc'
    oracle_scale_factor = 6
    oracle_prices = await client.get_oracle_prices(base_symbol=base_symbol, quote_symbol=quote_symbol, oracle_type=oracle_type, oracle_scale_factor=oracle_scale_factor)
    print(oracle_prices)
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("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()
    baseSymbol := "BTC"
    quoteSymbol := "USDT"
    oracleType := "BandIBC"
    oracleScaleFactor := uint32(6)
    res, err := exchangeClient.GetPrice(ctx, baseSymbol, quoteSymbol, oracleType, oracleScaleFactor)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const baseSymbol = "BTC";
  const quoteSymbol = "USDT";
  const oracleType = "bandibc";
  const oracleScaleFactor = 6;

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const oraclePrice = await exchangeClient.oracleApi.fetchOraclePrice(
    {
      baseSymbol,
      quoteSymbol,
      oracleType,
      oracleScaleFactor
    }
  );

  console.log(protoObjectToJson(oraclePrice, {}));
})();

Parameter Type Description Required
base_symbol String Oracle base currency Yes
quote_symbol String Oracle quote currency Yes
oracle_type String The oracle provider Yes
oracle_scale_factor Integer Oracle scale factor for the quote asset Yes

Response Parameters

Response Example:

{
  "price": "46361990000"
}
Parameter Type Description
price String The price of the oracle asset

StreamPrices

Stream oracle prices for an asset.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    base_symbol = 'BTC'
    quote_symbol = 'USDT'
    oracle_type = 'bandibc'
    oracle_prices = await client.stream_oracle_prices(
        base_symbol=base_symbol,
        quote_symbol=quote_symbol,
        oracle_type=oracle_type
    )
    async for oracle in oracle_prices:
        print(oracle)
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("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()
    baseSymbol := "BTC"
    quoteSymbol := "USDT"
    oracleType := "BandIBC"
    stream, err := exchangeClient.StreamPrices(ctx, baseSymbol, quoteSymbol, oracleType)
    if err != nil {
        fmt.Println(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            fmt.Println(res)
        }
    }
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const baseSymbol = "BTC";
  const quoteSymbol = "USDT";
  const oracleType = "bandibc";

  const exchangeClient = new ExchangeClient.ExchangeGrpcStreamClient(
    network.exchangeApi
  );

  await exchangeClient.oracleStream.streamOraclePrices(
    {
    oracleType,
    baseSymbol,
    quoteSymbol,
    callback: (streamPrices) => {
      console.log(protoObjectToJson(streamPrices, {}));
    },
    onEndCallback: (status) => {
      console.log("Stream has ended with status: " + status);
    },
  });
})();

Parameter Type Description Required
base_symbol String Oracle base currency Yes
quote_symbol String Oracle quote currency Yes
oracle_type String The oracle provider Yes

Response Parameters

Streaming Response Example:

{
  "price": "14.01",
  "timestamp": 1544614248000
}
Parameter Type Description
price String The price of the oracle asset
timestamp Integer Operation timestamp in UNIX millis.

- InjectiveInsuranceRPC

InjectiveInsuranceRPC defines the gRPC API of the Insurance Exchange provider.

InsuranceFunds

Get all the insurance funds.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    insurance_funds = await client.get_insurance_funds()
    print(insurance_funds)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()

  req := insurancePB.FundsRequest{}

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const insuranceFunds = await exchangeClient.insuranceFundApi.fetchInsuranceFunds(
  );

  console.log(protoObjectToJson(insuranceFunds, {}))
})();

Response Parameters

Response Example:

{
"funds": {
  "market_ticker": "REP/USDT",
  "market_id": "0xb6174e35c4aae49607d210b85ffb83f1fb3028f8c161a8b99a76f29b689da240",
  "deposit_denom": "peggy0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
  "pool_token_denom": "share8",
  "redemption_notice_period_duration": 1209600,
  "balance": "172000000",
  "total_share": "1720000000000000000",
  "oracle_base": "REP",
  "oracle_quote": "USD",
  "oracle_type": "coinbase"
},
"funds": {
  "market_ticker": "BTC/USDT",
  "market_id": "0xd0f46edfba58827fe692aab7c8d46395d1696239fdf6aeddfa668b73ca82ea30",
  "deposit_denom": "peggy0x69efCB62D98f4a6ff5a0b0CFaa4AAbB122e85e08",
  "pool_token_denom": "share1",
  "redemption_notice_period_duration": 1209600,
  "balance": "178249894780",
  "total_share": "1758870900000000000000",
  "oracle_base": "BTC",
  "oracle_quote": "USD",
  "oracle_type": "coinbase"
}

}
Parameter Type Description
funds InsuranceFund Array of InsuranceFund

InsuranceFund

Parameter Type Description
oracle_type String Oracle Type
pool_token_denom String Pool token denom
total_share String Total share
balance String The balance
oracle_base String Oracle base currency
market_id String The market ID
market_ticker String Ticker of the derivative market
oracle_quote String Oracle quote currency
redemption_notice_period_duration Integer Redemption notice period duration in seconds
deposit_denom String Coin denom used to underwrite the insurance fund

Redemptions

Get the pending redemptions.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    redeemer = "inj1gxqdj76ul07w4ujsl8403nhhzyvug2h66qk057"
    redemption_denom = "share2"
    status = "disbursed" # disbursed or pending
    insurance_redemptions = await client.get_redemptions(redeemer=redeemer, redemption_denom=redemption_denom, status=status)
    print(insurance_redemptions)
package main

import (
  "context"
  "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", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()

  req := insurancePB.RedemptionsRequest{}

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

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const denom = "share2";
  const address = "inj1gxqdj76ul07w4ujsl8403nhhzyvug2h66qk057";
  const status = "disbursed";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );

  const redemptions = await exchangeClient.insuranceFundApi.fetchRedemptions(
    {
      denom,
      address,
      status
    }
  );

  console.log(protoObjectToJson(redemptions, {}))
})();

Parameter Type Description Required
redeemer String Filter by account address No
redemption_denom String Filter by insurance pool denom No
status String Filter by redemption status (Should be one of: [disbursed pending]) No

Response Parameters

Response Example:

{
"redemption_schedules": {
  "redemption_id": 1,
  "status": "disbursed",
  "redeemer": "inj17ruhpkury0n9el2azce32cucvgql43eresspnp",
  "claimable_redemption_time": 1627450463607000,
  "redemption_amount": "10000000000000000000",
  "redemption_denom": "share1",
  "requested_at": 1626240863607000,
  "disbursed_amount": "50000000",
  "disbursed_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "disbursed_at": 1627450465211000
},
"redemption_schedules": {
  "redemption_id": 2,
  "status": "disbursed",
  "redeemer": "inj1g6grlgchxw95mxc5c3949ygw75hqpghqhgkj0k",
  "claimable_redemption_time": 1628874830848000,
  "redemption_amount": "960000000000000000",
  "redemption_denom": "share1",
  "requested_at": 1627665230848000,
  "disbursed_amount": "4800000",
  "disbursed_denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "disbursed_at": 1628874832996000
}

}
Parameter Type Description
redemption_schedules RedemptionSchedule Array of RedemptionSchedule

RedemptionSchedule

Parameter Type Description
claimable_redemption_time Integer Claimable redemption time in seconds
redeemer String Account address of the redemption owner
redemption_denom String Pool token denom being redeemed
requested_at Integer Redemption request time in unix milliseconds
status String Status of the redemption (Should be one of: [disbursed pending])
redemption_amount String Amount of pool tokens being redeemed
redemption_id Integer Redemption ID
disbursed_amount String Amount of quote tokens disbursed
disbursed_at Integer Redemption disbursement time in unix milliseconds
disbursed_denom String Denom of the quote tokens disbursed

- InjectiveAuctionRPC

InjectiveAuctionRPC defines the gRPC API of the Auction provider.

Auction

Get the details of a specific auction.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    action_round = 12
    auction = await client.get_auction(bid_round=action_round)
    print(auction)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()
  round := int64(35)
  res, err := exchangeClient.GetAuction(ctx, round)
  if err != nil {
    fmt.Println(err)
  }

  fmt.Println(res)
}

Parameter Type Description Required
bid_round Integer The auction round Yes

Response Parameters

Response Example:

{
"auction": {
  "winner": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "basket": {
    "denom": "peggy0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "amount": "300100663"
  },
  "basket": {
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "amount": "8084075059004"
  },
  "winning_bid_amount": "1000000000000000000000",
  "round": 12,
  "end_timestamp": 1639999020325,
  "updated_at": 1639999022779,
},
"bids": {
  "bidder": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "amount": "1000000000000000000000",
  "timestamp": 1640000366576
}

}
Parameter Type Description
auction Auction Array of Auction
bids Bids Array of Bids

Auction

Parameter Type Description
winner String The Injective Chain address with the highest bid
basket Basket Array of Basket
winning_bid_amount String The highest bid
round Integer The auction round
end_timestamp Integer The auction's ending timestamp
updated_at Integer The timestamp of the last submitted bid

Bids

Parameter Type Description
bidder String The Injective Chain address
amount String The bid amount
timestamp Integer The timestamp at which the bid was submitted

Basket

Parameter Type Description
denom String Token denominator
amount String Token quantity

Auctions

Get the details of previous auctions.

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    auctions = await client.get_auctions()
    print(auctions)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()
  res, err := exchangeClient.GetAuctions(ctx)
  if err != nil {
    fmt.Println(err)
  }

  fmt.Println(res)
}

Response Parameters

Response Example:

{
"auctions": {
  "winner": "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku",
  "basket": {
    "denom": "peggy0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "amount": "300100663"
  },
  "basket": {
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "amount": "8084075059004"
  },
  "winning_bid_amount": "1000000000000000000000",
  "round": 12,
  "end_timestamp": 1639999020325,
  "updated_at": 1639999022779
},
"auctions": {
  "basket": {
    "denom": "peggy0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "amount": "18930656"
  },
  "basket": {
    "denom": "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "amount": "404428070978"
  },
  "round": 13,
  "end_timestamp": 1640000820966,
  "updated_at": 1640000824348
}

}
Parameter Type Description
auction Auction Array of Auction
bids Bids Array of Bids

Auction

Parameter Type Description
winner String The Injective Chain address with the highest bid
basket Basket Array of Basket
winning_bid_amount String The highest bid
round Integer The auction round
end_timestamp Integer The auction's ending timestamp
updated_at Integer The timestamp of the last submitted bid

Bids

Parameter Type Description
bidder String The Injective Chain address
amount String The bid amount
timestamp Integer The timestamp at which the bid was submitted

Basket

Parameter Type Description
denom String Token denominator
amount String Token quantity

StreamBids

Stream live updates for auction bids.

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network


async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    bids = await client.stream_bids()
    async for bid in bids:
        print(bid)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()

  stream, err := exchangeClient.StreamBids(ctx)
  if err != nil {
    fmt.Println(err)
  }

  for {
    select {
    case <-ctx.Done():
      return
    default:
      res, err := stream.Recv()
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(res)
    }
  }
}

Response Parameters

Response Example:

{
"bidder": "inj1pn252r3a45urd3n8v84kyey4kcv4544zj70wkp",
"bid_amount": "1000000000000000000",
"round": 69,
"timestamp": 1638401749218,

"bidder": "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
"bid_amount": "2000000000000000000",
"round": 69,
"timestamp": 1638401841673

}
Parameter Type Description
bidder String The Injective Chain address
bid_amount String Bid quantity
round Integer The auction round
timestamp Integer The timestamp at which the bid was submitted

- InjectiveExplorerRPC

InjectiveExplorerRPC defines the gRPC API of the Explorer provider.

GetTxByHash

Get the details for a specific transaction.

Request Parameters

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

async def main() -> None:
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    tx_hash = "CF241CAACFA434DBC38645441FA330743C0F5BEB413FDE6DFCE6082EEB3E3D27"
    account = await client.get_tx_by_hash(tx_hash=tx_hash)
    print(account)
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("mainnet", "k8s")
  network := common.LoadNetwork("testnet", "k8s")
  exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
  if err != nil {
    fmt.Println(err)
  }

  ctx := context.Background()
  hash := "E5DCF04CC670A0567F58683409F7DAFC49754278DAAD507FE6EB40DFBFD71830"
  res, err := exchangeClient.GetTxByTxHash(ctx, hash)
  if err != nil {
    fmt.Println(err)
  }

  fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);
  const tx_hash =
    "d7a1c7ee985f807bf6bc06de728810fd52d85141549af0540486faf5e7de0d1d";

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const tx = await exchangeClient.explorerApi.fetchTxByHash(tx_hash);

  console.log(protoObjectToJson(tx, {}));
})();

Parameter Type Description Required
tx_hash String The transaction hash Yes

Response Parameters

Response Example:

{
"block_number": 11267326,
"block_timestamp": "2021-11-14 22:46:46.236 +0000 UTC",
"hash": "0xcf241caacfa434dbc38645441fa330743c0f5beb413fde6dfce6082eeb3e3d27",
"data": "\n|\n4/injective.exchange.v1beta1.MsgCreateSpotMarketOrder\022D\nB0xbe0a8f656c8cb5619b4b76e3884ef6db85fd00802879494ea9bba40f408a3945",
"gas_wanted": 120072,
"gas_used": 90395,
"tx_type": "injective",
"messages": "[{\"type\":\"/injective.exchange.v1beta1.MsgCreateSpotMarketOrder\",\"value\":{\"sender\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\",\"order\":{\"market_id\":\"0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b\",\"order_info\":{\"subaccount_id\":\"0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000\",\"fee_recipient\":\"inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r\",\"price\":\"0.000000000317140000\",\"quantity\":\"40000000000000000000.000000000000000000\"},\"order_type\":\"BUY\",\"trigger_price\":null}}}]",
"signatures": {
  "pubkey": "injvalcons1cml96vmptgw99syqrrz8az79xer2pcgpvgp7ex",
  "address": "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r",
  "sequence": 5367952,
  "signature": "wu7hFy9d3af86V4GnhsNArq8PmZA2PhHiAgSS3XedTZI4wU5WVj+PrZYf6E7ugsJ4DsXxHQ5mMH202oShjMAcwA="
}

}
Parameter Type Description
block_number Integer The block at which the transaction was executed
block_timestamp String The timestamp of the block
hash String The transaction hash
data bytes The raw data in bytes
gas_wanted Integer The gas wanted for this transaction
gas_used Integer The actual gas paid for this transaction
tx_type String The transaction type
messages String The messages included in this transaction
pubkey String The public key of the block proposer
address String The transaction sender address
sequence Integer The sequence number of the sender's address
signature String The signature

- InjectiveMetaRPC

InjectiveMetaRPC defines the gRPC API of the Exchange Meta provider.

Ping

Get the server health.

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    resp = await client.ping()
    print('Health OK?', resp)
package main

import (
    "context"
    "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", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()

    req := metaPB.PingRequest{}

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

    fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const ping = await exchangeClient.metaApi.fetchPing(
  );

  console.log(protoObjectToJson(ping, {}))
})();

Response Example:

{
"Health OK?"
}

Version

Get the server version.

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    resp = await client.version()
    print(resp)
package main

import (
    "context"
    "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", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()

    req := metaPB.VersionRequest{}

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

    fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";

(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const version = await exchangeClient.metaApi.fetchVersion(
  );

  console.log(protoObjectToJson(version, {}));
})();

Response Example:

{
"version": "dev",
"build": {
  "key": "BuildDate",
  "value": "20211106-1852",
},
"build": {
  "key": "GitCommit",
  "value": "2705336"
},
"build": {
  "key": "GoArch",
  "value": "amd64"
},
"build": {
  "key": "GoVersion",
  "value": "go1.17.2"
}

}

Info

Get the server information.

Request Example:

import time

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network, insecure=False)
    resp = await client.info()
    print('[!] Info:')
    print(resp)

    latency = int(round(time.time() * 1000)) - resp.timestamp
    print(f'Server Latency: {latency}ms')
package main

import (
    "context"
    "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", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()

    req := metaPB.InfoRequest{}

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

    fmt.Println(res)
}

import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { protoObjectToJson, ExchangeClient } from "@injectivelabs/sdk-ts";


(async () => {
  const network = getNetworkInfo(Network.Testnet);

  const exchangeClient = new ExchangeClient.ExchangeGrpcClient(
    network.exchangeApi
  );
  const info = await exchangeClient.metaApi.fetchInfo(
  );

  console.log(protoObjectToJson(info, {}));
})();

Response Example:

{
"[!] Info": {
"timestamp": 1636235761154,
"server_time": 1636235762168,
"version": "dev",
"build": {
  "key": "BuildDate",
  "value": "20211106-1852"
},
"build": {
  "key": "GitCommit",
  "value": "2705336"
},
"build": {
  "key": "GoArch",
  "value": "amd64"
},
"build": {
  "key": "GoVersion",
  "value": "go1.17.2"
},

"Server Latency": "822ms"
}
}

StreamKeepAlive

Subscribe to a stream and gracefully disconnect and connect to another sentry node if the primary becomes unavailable.

Request Example:

from pyinjective.async_client import AsyncClient
from pyinjective.constant import Network

import asyncio


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

    task1 = asyncio.create_task(get_markets(client))
    task2 = asyncio.create_task(keepalive(client, [task1]))

    try:
        await asyncio.gather(
            task1,
            task2,
        )
    except asyncio.CancelledError:
        print("main(): get_markets is cancelled now")


async def get_markets(client):
    stream = await client.stream_spot_markets()
    async for market in stream:
        print(market)


async def keepalive(client, tasks: list):
    stream = await client.stream_keepalive()
    async for announce in stream:
        print(announce)
        for task in tasks:
            task.cancel()
        print('Cancelled all tasks')
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("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    exchangeClient, err := exchangeclient.NewExchangeClient(network.ExchangeGrpcEndpoint, common.OptionTLSCert(network.ExchangeTlsCert))
    if err != nil {
        fmt.Println(err)
    }

    ctx := context.Background()

    stream, err := exchangeClient.StreamKeepalive(ctx)
    if err != nil {
        fmt.Println(err)
    }

    for {
        select {
        case <-ctx.Done():
            return
        default:
            res, err := stream.Recv()
            if err != nil {
                fmt.Println(err)
                return
            }
            fmt.Println(res)
        }
    }
}

Response Example:

{
"event": "shutdown",
"timestamp": 1636236225847,

"Cancelled all tasks"

}

Chain API

The Exchange 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 Exchange API which reconstructs state from events emitted by chain.

On a high-level the end-user trading applications and Injective Products use the Exchange 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 Exchange 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.

- Derivatives

Includes all messages related to derivative markets.

MsgCreateDerivativeMarketOrder

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.MsgCreateDerivativeMarketOrder(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=50000,
        quantity=0.01,
        leverage=3,
        is_buy=True
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    amount := decimal.NewFromFloat(0.01)
    price := cosmtypes.MustNewDecFromStr("33000000000") //33,000
    leverage := cosmtypes.MustNewDecFromStr("2.5")

    order := chainClient.DerivativeOrder(defaultSubaccountID, network, &chainclient.DerivativeOrderData{
        OrderType:    exchangetypes.OrderType_SELL, //BUY SELL
        Quantity:     amount,
        Price:        price,
        Leverage:     leverage,
        FeeRecipient: senderAddress.String(),
        MarketId:     marketId,
        IsReduceOnly: false,
    })

    msg := new(exchangetypes.MsgCreateDerivativeMarketOrder)
    msg.Sender = senderAddress.String()
    msg.Order = exchangetypes.DerivativeOrder(*order)

    simRes, err := chainClient.SimulateMsg(clientCtx, msg)

    if err != nil {
        fmt.Println(err)
    }

    simResMsgs := common.MsgResponse(simRes.Result.Data)
    msgCreateDerivativeMarketOrderResponse := exchangetypes.MsgCreateDerivativeMarketOrderResponse{}
    msgCreateDerivativeMarketOrderResponse.Unmarshal(simResMsgs[0].Data)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("simulated order hash", msgCreateDerivativeMarketOrderResponse.OrderHash)

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
sender String The Injective Chain address Yes
subaccount_id String The subaccount we want to send an order from Yes
fee_recipient String The address that will receive 40% of the fees, this could be set to your own address Yes
price Float The worst accepted price of the base asset Yes
quantity Float The quantity of the base asset Yes
leverage Float The leverage factor for the order No
is_buy Boolean Set to true or false for buy and sell orders respectively Yes
is_reduce_only Boolean Set to true or false for reduce-only or normal orders respectively No

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

MsgCreateDerivativeLimitOrder

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    # prepare tx msg
    msg = composer.MsgCreateDerivativeLimitOrder(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        subaccount_id=subaccount_id,
        fee_recipient=fee_recipient,
        price=50000,
        quantity=0.1,
        leverage=1,
        is_buy=False,
        is_reduce_only=False
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    amount := decimal.NewFromFloat(0.001)
    price := cosmtypes.MustNewDecFromStr("31000000000") //31,000
    leverage := cosmtypes.MustNewDecFromStr("2.5")

    order := chainClient.DerivativeOrder(defaultSubaccountID, network, &chainclient.DerivativeOrderData{
        OrderType:    exchangetypes.OrderType_BUY, //BUY SELL BUY_PO SELL_PO
        Quantity:     amount,
        Price:        price,
        Leverage:     leverage,
        FeeRecipient: senderAddress.String(),
        MarketId:     marketId,
        IsReduceOnly: false,
    })

    msg := new(exchangetypes.MsgCreateDerivativeLimitOrder)
    msg.Sender = senderAddress.String()
    msg.Order = exchangetypes.DerivativeOrder(*order)

    simRes, err := chainClient.SimulateMsg(clientCtx, msg)

    if err != nil {
        fmt.Println(err)
    }

    simResMsgs := common.MsgResponse(simRes.Result.Data)
    msgCreateDerivativeLimitOrderResponse := exchangetypes.MsgCreateDerivativeLimitOrderResponse{}
    msgCreateDerivativeLimitOrderResponse.Unmarshal(simResMsgs[0].Data)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("simulated order hash", msgCreateDerivativeLimitOrderResponse.OrderHash)

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
sender String The Injective Chain address Yes
subaccount_id String The subaccount we want to send an order from Yes
fee_recipient String The address that will receive 40% of the fees, this could be set to your own address Yes
price Float The price of the base asset Yes
quantity Float The quantity of the base asset Yes
leverage Float The leverage factor for the order No
is_buy Boolean Set to true or false for buy and sell orders respectively Yes
is_reduce_only Boolean Set to true or false for reduce-only or normal orders respectively No
is_po Boolean Set to true or false for post-only or normal orders respectively No

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

MsgCancelDerivativeOrder

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    orders = [
        composer.OrderData(
            market_id=market_id,
            subaccount_id=subaccount_id,
            order_hash="0x690864eaedf9aae908f0636357aa2de6fc3d95386b0fad38410496ce4325a882"
        ),
        composer.OrderData(
            market_id=market_id,
            subaccount_id=subaccount_id,
            order_hash="0x9c552c62970061a5cf16fd6de4bb5defc023f8fe5692628588fef7b6519eedf6"
        )
    ]

    # prepare tx msg
    msg = composer.MsgBatchCancelDerivativeOrders(
        sender=address.to_acc_bech32(),
        data=orders
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    msg := &exchangetypes.MsgCancelDerivativeOrder{
        Sender:       senderAddress.String(),
        MarketId:     "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
        SubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        OrderHash:    "0x25233ede1fee09310d549241647edcf94cf5378749593b55c27148a80ce655c1",
    }

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
market_id String Market ID of the market we want to cancel an order Yes
sender String The Injective Chain address Yes
subaccount_id String The subaccount we want to cancel an order from Yes
order_hash String The hash of a specific order Yes

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

MsgBatchCreateDerivativeLimitOrders

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    orders = [
        composer.DerivativeOrder(
            market_id=market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=41027,
            quantity=0.01,
            leverage=0.7,
            is_buy=True,
            is_po=False

        ),
        composer.DerivativeOrder(
            market_id=market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=62140,
            quantity=0.01,
            leverage=0.7,
            is_buy=False,
            is_reduce_only=False
        ),
    ]

    # prepare tx msg
    msg = composer.MsgBatchCreateDerivativeLimitOrders(
        sender=address.to_acc_bech32(),
        orders=orders
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    amount := decimal.NewFromFloat(2)
    price := cosmtypes.MustNewDecFromStr("31000000000") //31,000
    leverage := cosmtypes.MustNewDecFromStr("2.5")

    order := chainClient.DerivativeOrder(defaultSubaccountID, network, &chainclient.DerivativeOrderData{
        OrderType:    exchangetypes.OrderType_BUY, //BUY SELL BUY_PO SELL_PO
        Quantity:     amount,
        Price:        price,
        Leverage:     leverage,
        FeeRecipient: senderAddress.String(),
        MarketId:     marketId,
        IsReduceOnly: false,
    })

    msg := new(exchangetypes.MsgBatchCreateDerivativeLimitOrders)
    msg.Sender = senderAddress.String()
    msg.Orders = []exchangetypes.DerivativeOrder{*order}

    simRes, err := chainClient.SimulateMsg(clientCtx, msg)

    if err != nil {
        fmt.Println(err)
    }

    simResMsgs := common.MsgResponse(simRes.Result.Data)
    msgBatchCreateDerivativeLimitOrdersResponse := exchangetypes.MsgBatchCreateDerivativeLimitOrdersResponse{}
    msgBatchCreateDerivativeLimitOrdersResponse.Unmarshal(simResMsgs[0].Data)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("simulated order hashes", msgBatchCreateDerivativeLimitOrdersResponse.OrderHashes)

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
sender String The Injective Chain address Yes
orders DerivativeOrder Array of DerivativeOrder Yes

DerivativeOrder

Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
subaccount_id String The subaccount ID we want to send an order from Yes
fee_recipient String The address that will receive 40% of the fees, this could be set to your own address Yes
price Float The price of the base asset Yes
quantity Float The quantity of the base asset Yes
leverage Float The leverage factor for the order No
is_buy Boolean Set to true or false for buy and sell orders respectively Yes
is_reduce_only Boolean Set to true or false for reduce-only or normal orders respectively No
is_po Boolean Set to true or false for post-only or normal orders respectively No

Response Example:

---Simulation Response---
[order_hashes: "0x8b59dad73b75545c763898c2c03cd69cbf1e351e6cef2414d0714a151a4aada2"
order_hashes: "0x59d814e060c862f5e90bcd25542d48fcd903f51df36d7383bde7ac41691b0c68"
]
---Transaction Response---
txhash: "D17DCBC552D19D858B5C022A894DEC6DC13EDF45B3225F0B2512D181100C047B"
raw_log: "[]"

gas wanted: 163908
gas fee: 0.000081954 INJ
simulated order hashes [0xc86f24dd1ce271aafd8be77a72420497a6956d15cad4a400a0a0823476333b4b]
DEBU[0001] broadcastTx with nonce 3502                   fn=func1 src="client/chain/chain.go:598"
DEBU[0002] msg batch committed successfully at height 5214382  fn=func1 src="client/chain/chain.go:619" txHash=8A7506B32E923F918DE839A4C849B22CE26ACC3E063F871CF4E68B02F764B507
DEBU[0002] nonce incremented to 3503                     fn=func1 src="client/chain/chain.go:623"
DEBU[0002] gas wanted:  171795                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000858975 INJ

MsgBatchCancelDerivativeOrders

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    orders = [
        composer.OrderData(
            market_id=market_id,
            subaccount_id=subaccount_id,
            order_hash="0x920a4ea4144c46d1e1084ca5807e4f5608639ce00f97139d5b44e628d487e15e"
        ),
        composer.OrderData(
            market_id=market_id,
            subaccount_id=subaccount_id,
            order_hash="0x9c552c62970061a5cf16fd6de4bb5defc023f8fe5692628588fef7b6519eedf6"
        )
    ]

    # prepare tx msg
    msg = composer.MsgBatchCancelDerivativeOrders(
        sender=address.to_acc_bech32(),
        data=orders
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    marketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    orderHash := "0xb2bea3b15c204699a9ee945ca49650001560518d1e54266adac580aa061fedd4"

    order := chainClient.OrderCancel(defaultSubaccountID, &chainclient.OrderCancelData{
        MarketId:  marketId,
        OrderHash: orderHash,
    })

    msg := new(exchangetypes.MsgBatchCancelDerivativeOrders)
    msg.Sender = senderAddress.String()
    msg.Data = []exchangetypes.OrderData{*order}
    CosMsgs := []cosmtypes.Msg{msg}

    // AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(CosMsgs...)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
sender String The Injective Chain address Yes
orders OrderData Array of OrderData Yes

OrderData

Parameter Type Description Required
market_id String Market ID of the market we want to cancel an order Yes
subaccount_id String The subaccount we want to cancel an order from Yes
order_hash String The hash of a specific order Yes

Response Example:

---Simulation Response---
[success: true
success: false
]
---Transaction Response---
txhash: "6928C4FBEC47FB63D3EBC813576834CE7B6A34628BEDCA6DE8B7854355F823AC"
raw_log: "[]"

gas wanted: 118158
gas fee: 0.000059079 INJ
DEBU[0001] broadcastTx with nonce 3516                   fn=func1 src="client/chain/chain.go:598"
DEBU[0004] msg batch committed successfully at height 5215877  fn=func1 src="client/chain/chain.go:619" txHash=448729DE967243C10C11787AA6488FAA1B1EDD6E32D3710862FCF92A09E4E8D0
DEBU[0004] nonce incremented to 3517                     fn=func1 src="client/chain/chain.go:623"
DEBU[0004] gas wanted:  140577                           fn=func1 src="client/chain/chain.go:624"
gas fee: 0.0000702885 INJ

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.

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    derivative_market_id_create = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    spot_market_id_create = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"

    derivative_market_id_cancel = "0x1f73e21972972c69c03fb105a5864592ac2b47996ffea3c500d1ea2d20138717"
    derivative_market_id_cancel_2 = "0x8158e603fb80c4e417696b0e98765b4ca89dcf886d3b9b2b90dc15bfb1aebd51"
    spot_market_id_cancel = "0x74b17b0d6855feba39f1f7ab1e8bad0363bd510ee1dcc74e40c2adfe1502f781"
    spot_market_id_cancel_2 = "0x01edfab47f124748dc89998eb33144af734484ba07099014594321729a0ca16b"

    spot_market_ids_to_cancel_all =['0x28f3c9897e23750bf653889224f93390c467b83c86d736af79431958fff833d1', '0xe8bf0467208c24209c1cf0fd64833fa43eb6e8035869f9d043dbff815ab76d01']
    derivative_market_ids_to_cancel_all = ['0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce', '0x979731deaaf17d26b2e256ad18fecd0ac742b3746b9ea5382bac9bd0b5e58f74']

    derivative_orders_to_cancel = [
        composer.OrderData(
            market_id=derivative_market_id_cancel,
            subaccount_id=subaccount_id,
            order_hash="0x48690013c382d5dbaff9989db04629a16a5818d7524e027d517ccc89fd068103"
        ),
        composer.OrderData(
            market_id=derivative_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5"
        )
    ]

    spot_orders_to_cancel = [
        composer.OrderData(
            market_id=spot_market_id_cancel,
            subaccount_id=subaccount_id,
            order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d"
        ),
        composer.OrderData(
            market_id=spot_market_id_cancel_2,
            subaccount_id=subaccount_id,
            order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2"
        )
    ]

    derivative_orders_to_create = [
        composer.DerivativeOrder(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=25000,
            quantity=0.1,
            leverage=1,
            is_buy=True,
            is_po=False
        ),
        composer.DerivativeOrder(
            market_id=derivative_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=50000,
            quantity=0.01,
            leverage=1,
            is_buy=False,
            is_po=False
        ),
    ]

    spot_orders_to_create = [
        composer.SpotOrder(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=3,
            quantity=55,
            is_buy=True,
            is_po=False
        ),
        composer.SpotOrder(
            market_id=spot_market_id_create,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=300,
            quantity=55,
            is_buy=False,
            is_po=False
        ),
    ]

    # prepare tx msg
    msg = composer.MsgBatchUpdateOrders(
        sender=address.to_acc_bech32(),
        subaccount_id=subaccount_id,
        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_ids_to_cancel_all=spot_market_ids_to_cancel_all,
        derivative_market_ids_to_cancel_all=derivative_market_ids_to_cancel_all,
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res.result.data, simulation=True)
    print("---Simulation Response---")
    print(sim_res_msg)

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000 # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print("---Transaction Response---")
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    smarketId := "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa"
    samount := decimal.NewFromFloat(2)
    sprice := decimal.NewFromFloat(22.5)
    smarketIds := []string{"0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"}

    spot_order := chainClient.SpotOrder(defaultSubaccountID, network, &chainclient.SpotOrderData{
        OrderType:    exchangetypes.OrderType_BUY, //BUY SELL BUY_PO SELL_PO
        Quantity:     samount,
        Price:        sprice,
        FeeRecipient: senderAddress.String(),
        MarketId:     smarketId,
    })

    dmarketId := "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    damount := decimal.NewFromFloat(0.01)
    dprice := cosmtypes.MustNewDecFromStr("31000000000") //31,000
    dleverage := cosmtypes.MustNewDecFromStr("2")
    dmarketIds := []string{"0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"}

    derivative_order := chainClient.DerivativeOrder(defaultSubaccountID, network, &chainclient.DerivativeOrderData{
        OrderType:    exchangetypes.OrderType_BUY, //BUY SELL BUY_PO SELL_PO
        Quantity:     damount,
        Price:        dprice,
        Leverage:     dleverage,
        FeeRecipient: senderAddress.String(),
        MarketId:     dmarketId,
        IsReduceOnly: false,
    })

    msg := new(exchangetypes.MsgBatchUpdateOrders)
    msg.Sender = senderAddress.String()
    msg.SubaccountId = defaultSubaccountID.Hex()
    msg.SpotOrdersToCreate = []*exchangetypes.SpotOrder{spot_order}
    msg.DerivativeOrdersToCreate = []*exchangetypes.DerivativeOrder{derivative_order}
    msg.SpotMarketIdsToCancelAll = smarketIds
    msg.DerivativeMarketIdsToCancelAll = dmarketIds

    simRes, err := chainClient.SimulateMsg(clientCtx, msg)

    if err != nil {
        fmt.Println(err)
    }

    simResMsgs := common.MsgResponse(simRes.Result.Data)
    MsgBatchUpdateOrdersResponse := exchangetypes.MsgBatchUpdateOrdersResponse{}
    MsgBatchUpdateOrdersResponse.Unmarshal(simResMsgs[0].Data)

    fmt.Println("simulated spot order hashes", MsgBatchUpdateOrdersResponse.SpotOrderHashes)

    fmt.Println("simulated derivative order hashes", MsgBatchUpdateOrdersResponse.DerivativeOrderHashes)

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
sender String The Injective Chain address Yes
subaccount_id String The subaccount ID Conditional
derivative_orders_to_create DerivativeOrder DerivativeOrder object No
spot_orders_to_create SpotOrder SpotOrder object No
derivative_orders_to_cancel OrderData OrderData object to cancel No
spot_orders_to_cancel Orderdata OrderData object to cancel No
spot_market_ids_to_cancel_all Array Spot Market IDs for the markets the trader wants to cancel all active orders No
derivative_market_ids_to_cancel_all Array Derivative Market IDs for the markets the trader wants to cancel all active orders No

SpotOrder

Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
subaccount_id String The subaccount we want to send an order from Yes
fee_recipient String The address that will receive 40% of the fees, this could be set to your own address Yes
price Float The price of the base asset Yes
quantity Float The quantity of the base asset Yes
is_buy Boolean Set to true or false for buy and sell orders respectively Yes
is_po Boolean Set to true or false for post-only or normal orders respectively No

DerivativeOrder

Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
subaccount_id String The subaccount ID we want to send an order from Yes
fee_recipient String The address that will receive 40% of the fees, this could be set to your own address Yes
price Float The price of the base asset Yes
quantity Float The quantity of the base asset Yes
leverage Float The leverage factor for the order No
is_buy Boolean Set to true or false for buy and sell orders respectively Yes
is_reduce_only Boolean Set to true or false for reduce-only or normal orders respectively No
is_po Boolean Set to true or false for post-only or normal orders respectively No

OrderData

Parameter Type Description Required
market_id String Market ID of the market we want to cancel an order Yes
subaccount_id String The subaccount we want to cancel an order from Yes
order_hash String The hash of a specific order Yes

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

MsgIncreasePositionMargin

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"

    # prepare tx msg
    msg = composer.MsgIncreasePositionMargin(
        sender=address.to_acc_bech32(),
        market_id=market_id,
        source_subaccount_id=subaccount_id,
        destination_subaccount_id=subaccount_id,
        amount=2
    )

    # build sim tx
    tx = (
        Transaction()
        .with_messages(msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    "os"
    "time"

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

    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    msg := &exchangetypes.MsgIncreasePositionMargin{
        Sender:                  senderAddress.String(),
        MarketId:                "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
        SourceSubaccountId:      "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        DestinationSubaccountId: "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000",
        Amount:                  cosmtypes.MustNewDecFromStr("100000000"), //100 USDT
    }

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    //AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
    err = chainClient.QueueBroadcastMsg(msg)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}
Parameter Type Description Required
sender String The Injective Chain address Yes
market_id String Market ID of the market we want to increase the margin of the position Yes
source_subaccount_id String The subaccount to send funds from Yes
destination_subaccount_id String The subaccount to send funds to Yes
amount String The amount of tokens to be used as additional margin Yes

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

LocalOrderHashComputation

This function computes order hashes locally for SpotOrder and DerivativeOrder. Note that the subaccount nonce is used as one of the primary parameters to the calculation and is fetched every time from the Chain Node when you call the function. Thus, to use the function properly you must provide all the orders you'll send in a given block and call it only once per block.

Also note that if any of the orders does not get submitted on-chain either because of low account balance, incorrect order details or any other reason then the subsequent order hashes will be incorrect. That's because when you post the actual transactions and one of them fails the subaccount nonce won't be increased so the subsequent order hashes derived from the local calculation will be incorrect.

Request Parameters

Request Example:

import asyncio
import logging

from pyinjective.composer import Composer as ProtoMsgComposer
from pyinjective.async_client import AsyncClient
from pyinjective.transaction import Transaction
from pyinjective.constant import Network
from pyinjective.wallet import PrivateKey
from pyinjective.orderhash import compute_order_hashes


async def main() -> None:
    # select network: local, testnet, mainnet
    network = Network.testnet()
    composer = ProtoMsgComposer(network=network.string())

    # initialize grpc client
    client = AsyncClient(network, insecure=False)
    await client.sync_timeout_height()

    # load account
    priv_key = PrivateKey.from_hex("5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e")
    pub_key = priv_key.to_public_key()
    address = await pub_key.to_address().async_init_num_seq(network.lcd_endpoint)
    subaccount_id = address.get_subaccount_id(index=0)

    # prepare trade info
    spot_market_id = "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0"
    deriv_market_id = "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce"
    fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"

    spot_orders = [
        composer.SpotOrder(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=3.524,
            quantity=0.01,
            is_buy=True,
            is_po=True
        ),
        composer.SpotOrder(
            market_id=spot_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=27.92,
            quantity=0.01,
            is_buy=False,
            is_po=False
        ),
    ]

    derivative_orders = [
        composer.DerivativeOrder(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=25111,
            quantity=0.01,
            leverage=1.5,
            is_buy=True,
            is_po=False
        ),
        composer.DerivativeOrder(
            market_id=deriv_market_id,
            subaccount_id=subaccount_id,
            fee_recipient=fee_recipient,
            price=65111,
            quantity=0.01,
            leverage=2,
            is_buy=False,
            is_reduce_only=False
        ),
    ]

    # prepare tx msg
    spot_msg = composer.MsgBatchCreateSpotLimitOrders(
        sender=address.to_acc_bech32(),
        orders=spot_orders
    )

    deriv_msg = composer.MsgBatchCreateDerivativeLimitOrders(
        sender=address.to_acc_bech32(),
        orders=derivative_orders
    )

    # compute order hashes
    order_hashes = compute_order_hashes(network, spot_orders=spot_orders, derivative_orders=derivative_orders)

    print("computed spot order hashes", order_hashes.spot)
    print("computed derivative order hashes", order_hashes.derivative)

    # build sim tx
    tx = (
        Transaction()
        .with_messages(spot_msg, deriv_msg)
        .with_sequence(address.get_sequence())
        .with_account_num(address.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
    (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
    if not success:
        print(sim_res)
        return

    # build tx
    gas_price = 500000000
    gas_limit = sim_res.gas_info.gas_used + 20000  # add 20k 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.send_tx_sync_mode(tx_raw_bytes)
    print(res)
    print("gas wanted: {}".format(gas_limit))
    print("gas fee: {} INJ".format(gas_fee))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.get_event_loop().run_until_complete(main())
package main

import (
    "fmt"
    exchangetypes "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
    chainclient "github.com/InjectiveLabs/sdk-go/client/chain"
    "github.com/InjectiveLabs/sdk-go/client/common"
    cosmtypes "github.com/cosmos/cosmos-sdk/types"
    "github.com/shopspring/decimal"
    rpchttp "github.com/tendermint/tendermint/rpc/client/http"
    "os"
    "time"
)

func main() {
    // network := common.LoadNetwork("mainnet", "k8s")
    network := common.LoadNetwork("testnet", "k8s")
    tmRPC, err := rpchttp.New(network.TmEndpoint, "/websocket")

    if err != nil {
        fmt.Println(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 {
        fmt.Println(err)
    }

    clientCtx = clientCtx.WithNodeURI(network.TmEndpoint).WithClient(tmRPC)

    chainClient, err := chainclient.NewChainClient(
        clientCtx,
        network.ChainGrpcEndpoint,
        common.OptionTLSCert(network.ChainTlsCert),
        common.OptionGasPrices("500000000inj"),
    )

    if err != nil {
        fmt.Println(err)
    }

    // prepare tx msg
    defaultSubaccountID := chainClient.DefaultSubaccount(senderAddress)

    spotOrder := chainClient.SpotOrder(defaultSubaccountID, network, &chainclient.SpotOrderData{
        OrderType:    exchangetypes.OrderType_BUY,
        Quantity:     decimal.NewFromFloat(2),
        Price:        decimal.NewFromFloat(22.55),
        FeeRecipient: senderAddress.String(),
        MarketId:     "0x0511ddc4e6586f3bfe1acb2dd905f8b8a82c97e1edaef654b12ca7e6031ca0fa",
    })

    derivativeOrder := chainClient.DerivativeOrder(defaultSubaccountID, network, &chainclient.DerivativeOrderData{
        OrderType:    exchangetypes.OrderType_BUY,
        Quantity:     decimal.NewFromFloat(2),
        Price:        cosmtypes.MustNewDecFromStr("31000000000"),
        Leverage:     cosmtypes.MustNewDecFromStr("2.5"),
        FeeRecipient: senderAddress.String(),
        MarketId:     "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce",
    })

    msg := new(exchangetypes.MsgBatchCreateSpotLimitOrders)
    msg.Sender = senderAddress.String()
    msg.Orders = []exchangetypes.SpotOrder{*spotOrder}

    msg1 := new(exchangetypes.MsgBatchCreateDerivativeLimitOrders)
    msg1.Sender = senderAddress.String()
    msg1.Orders = []exchangetypes.DerivativeOrder{*derivativeOrder, *derivativeOrder}

    // compute local order hashes
    orderHashes, err := chainClient.ComputeOrderHashes(msg.Orders, msg1.Orders)

    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
    err = chainClient.QueueBroadcastMsg(msg, msg1)

    if err != nil {
        fmt.Println(err)
    }

    time.Sleep(time.Second * 5)

    gasFee, err := chainClient.GetGasFee()

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("gas fee:", gasFee, "INJ")
}

MsgBatchCreateDerivativeLimitOrders

Parameter Type Description Required
sender String The Injective Chain address Yes
orders DerivativeOrder Array of DerivativeOrder Yes

DerivativeOrder

Parameter Type Description Required
market_id String Market ID of the market we want to send an order Yes
subaccount_id String The subaccount ID we want to send an order