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
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
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:
- The Injective Chain node (the Chain API)
- The Injective Exchange API
The trading lifecycle is as follows:
- First, traders cryptographically sign a transaction containing one or more order messages (e.g.
MsgBatchCreateDerivativeLimitOrders
,MsgCreateSpotMarketOrder
,MsgCancelDerivativeLimitOrder
, etc. ). - Then the transaction is broadcasted to an Injective Chain node.
- The transaction is then added to the mempool and becomes included in a block. More details on this process can be found here.
- 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.
- 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.
- The funds are settled accordingly, with positions being created for derivative trades and assets being swapped for spot trades.
- Events containing the trade and settlement information are emitted by the Chain.
- The Injective Exchange API backend indexes the events and pushes updates to all subscribed traders.
Key Differences To CEX
- All information is public which includes things like untriggered Stop/Take orders or pending orders in the mempool.
- The data stored on-chain is minimal for performance reasons and reflects only the current state, relayers provide additional historical data as well as a user interface for traders through the Injective Exchange API backend.
- Usually a DEX has front-running issues, but those are mitigated at Injective through fast block times and FBA.
- The order of execution is different. Any new exchange action is a new transaction and is not executed immediately. Instead, it is added to a queue (mempool) and executed once the block is committed. At the time of the block commit, all included transactions happen more or less instantly. Firstly, code that is inside the handler is executed in the transaction sequence which is decided by the miner. This is not a problem since the sequence does not affect matching prices due to FBA and thus fairness is guaranteed.
To summarize the sequence of state changes on the Injective Chain:
- Mempool: A queue of pending transactions.
- 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).
- Handler: Code that is executed when a transaction is included in a block.
- 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:
- 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.
- 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.
- If you are a trader using a DEX UI, you don't need to worry about the gas costs, because the relayer will pay them for you. But in return you will be paying the trading fee in full.
- If you are using the API, then you will need to pay the gas costs.
- The gas costs are currently very small. 20K transactions will cost about 1 INJ.
- You can set the recipient_fee to any of your own wallet addresses since you are in essence your own relayer saving you about 40% of all fees.
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:
Margin >= InitialMarginRatio * Quantity * EntryPrice
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:
Margin >= Quantity * (InitialMarginRatio * MarkPrice - PNL)
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.
- Note that there is a caching mechanism in place which can take up to one day to before being updated with a new tier.
- Negative maker fee markets are not eligible for discounts.
- If the fee discount proposal was passed less than 30 days ago, the fee paid requirement is ignored so we don't unfairly penalize people who onboard immediately.
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
- partially closed
- fully closed
- 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:
- LONG:
1 BTC
with EntryPrice of $59,000
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
- If any reduce-only orders would be invalid after executing all of the trader's other limit sell orders that have better prices in the same direction.
In our example, consider a new reduce-only order of 0.4 BTC
at $64,600
.
Sell Price | Quantity | Order Type |
---|---|---|
$66,500 | 0.2 BTC | Vanilla |
$65,500 | 0.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
- If any reduce-only limit orders would be invalidated when all the orders up to and including the new vanilla limit order were filled.
In our example, consider a new vanilla order of 0.4 BTC
at $64,600
.
Sell Price | Quantity | Order Type |
---|---|---|
$66,500 | 0.2 BTC | Vanilla |
$65,500 | 0.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
Maker Fee = 0.1%
Taker Fee = 0.2%
Market Buy Order:
Quantity = 1 ETH
Worst Price = 3,000 USDT
→ 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:
Trading Fee = 1 * 2,000 * 0.002 = 4 USDT
Credit Amount = 1 ETH
Debit Amount = 1 * 2,000 + 4 = 2,004 USDT
Clearing Refund = 3,006 - 2,004 = 1,002 USDT
Adding a Spot Market Sell Order
Maker Fee = 0.1%
Taker Fee = 0.2%
Market Sell Order:
Quantity = 1 ETH
Worst Price = 1,500 USDT
→ 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:
Trading Fee = 1 * 2,000 * 0.002 = 4 USDT
Debit Amount = 1 ETH
Credit Amount = 1 * 2,000 - 4 = 1,996 USDT
Clearing Refund = 0
Adding a Spot Limit Buy Order
Maker Fee = 0.1%
Taker Fee = 0.2%
Market Buy Order:
Quantity = 1 ETH
Price = 2,000 USDT
→ 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:
Fee Refund = 1 * 2,000 * (0.002 - 0.001) = 2 USDT
If Matched Immediately: (assuming an FBA clearing price of 1,900 USDT)
Trading Fee = 1 * 1,900 * 0.002 = 3.8 USDT
Credit Amount = 1 ETH
Debit Amount = 1 * 1,900 + 3.8 = 1,903.8 USDT
Clearing Refund = (1 + 0.002) * (2,000 - 1,900) = 100.2 USDT
Unmatched Fee Refund = 0 USDT
If Filled Later By Market Order:
Trading Fee = 1 * 2,000 * 0.001 = 2 USDT
Credit Amount (in base asset) = 1 ETH
Debit Amount (in quote asset) = 1 * 2,000 + 2 = 2,002 USDT
Adding a Spot Limit Sell Order
Maker Fee = 0.1%
Taker Fee = 0.2%
Market Sell Order:
Quantity = 1 ETH
Price = 2,000 USDT
→ 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:
Fee Refund = 0 ETH
If Matched Immediately: (assuming an FBA clearing price of 2,100 USDT)
Trading Fee = 1 * 2,100 * 0.002 = 4.2 USDT
Credit Amount = 1 * 2,100 * (1 - 0.002) = 2,095.8 USDT
Debit Amount = 1 ETH
Clearing Refund = 0 ETH
Fee Refund = 0 USDT
If Filled Later By Market Order:
Credit Amount (in quote asset) = 1 * 2,000 - 2 = 1,998 USDT
Debit Amount (in base asset) = 1 ETH
Trading Fee = 1 * 2,000 * 0.001 = 2 USDT
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
Quantity = 1
,Price = 2,000
,Margin = 200
TakerFeeRate = 0.002
MakerFeeRate = 0.001
→ 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):
Fee Refund = Quantity * Price * (TakerFeeRate - MakerFeeRate) = 1 * 2,000 * (0.002 - 0.001) = 2 USDT
AvailableBalance = AvailableBalance + Fee Refund = 0 + 2 = 2
If Matched:
Assuming:
- an FBA clearing price of 1,990 USDT
an existing
SHORT
position:Position Quantity = 0.5 ETH
Position Entry Price = 1,950 USDT
Position Margin = 400 USDT
Would result in:
1. Closing existing position with proportional order margin for closing:
CloseExecutionMargin = ExecutionMargin * CloseQuantity / OrderQuantity = 200 * 0.5 / 1 = 100 USDT
ClosingPayout = PNL + PositionMargin * CloseQuantity / PositionQuantity
PNL = CloseQuantity * (FillPrice - EntryPrice) = 0.5 * (1,990 - 1,950) = 20 USDT
ClosingPayout = 20 + 400 * 0.5 / 0.5 = 420 USDT
2. Opening new position in opposite direction:
a new
LONG
position:Position Quantity = 0.5 ETH
Position Entry Price = 2,000 USDT
Position Margin = 100 USDT
3. Refunding fee difference from order price vs. clearing price:
PriceDelta = Price - ClearingPrice = 2,000 - 1,990 = 10
ClearingFeeRefund = FillQuantity * PriceDelta * TakerFeeRate = 1 * 10 * 0.002 = 0.002 USDT
(in the case of matching a sell order, this would have been a charge, not a refund)
Market Order Matching
Existing Orderbook
Sells | Buys | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
New Orders
- 1x market buy order for 0.2 BTC with worst price 64,360
- 1x market buy order for 0.4 BTC with worst price 66,000
- 1x market sell order for 0.1 BTC with worst price 60,000
- 1x market sell order for 0.2 BTC with worst price 61,000
- 1x market sell order for 0.3 BTC with worst price 69,000
Resulting Orderbook
Sells | Buys | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
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 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
New Orders
Sells | Buys | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
Matching Orders
All new orders are incorporated into the existing orderbook. In our case this results in a negative spread:
Sells | Buys | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
As long as negative spread exists, orders are matched against each other. The first buy order is fully matched:
Sells | Buys | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
Now the second buy order can still be fully matched:
Sells | Buys | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
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
(64,180*0.2 + 64,200*0.1 + 64,360*0.2 + 64,370*0.4 + 64,360*0.1) / (0.5*2) = 64,312
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
Explorer
A Web interface that allows you to search for information on the Injective Chain
Faucet
A web-based service that provides free tokens to users on testnet and allows them to experiment on the Injective Chain.
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
- Market for market orders
- limitFill for a resting limit order getting filled by a market order
- LimitMatchRestingOrder for a resting limit order getting matched with another new limit order
- 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
- Market for market orders
- limitFill for a resting limit order getting filled by a market order
- LimitMatchRestingOrder for a resting limit order getting matched with another new limit order
- 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
- Market for market orders
- limitFill for a resting limit order getting filled by a market order
- LimitMatchRestingOrder for a resting limit order getting matched with another new limit order
- 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
- Market for market orders
- limitFill for a resting limit order getting filled by a market order
- LimitMatchRestingOrder for a resting limit order getting matched with another new limit order
- 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 |