@d8x/perpetuals-sdk
Version:
Node TypeScript SDK for D8X Perpetual Futures
209 lines (208 loc) • 10.4 kB
TypeScript
import { BigNumberish, BlockTag, Overrides, Signer, TransactionResponse } from "ethers";
import { PayableOverrides } from "./contracts/common";
import { IdxPriceInfo, type NodeSDKConfig, type Order, type PerpetualStaticInfo, type PriceFeedSubmission, type SmartContractOrder } from "./nodeSDKTypes";
import WriteAccessHandler from "./writeAccessHandler";
/**
* Functions to execute existing conditional orders from the limit order book. This class
* requires a private key and executes smart-contract interactions that require
* gas-payments.
* @extends WriteAccessHandler
*/
export default class OrderExecutorTool extends WriteAccessHandler {
/**
* Constructor.
* @param {NodeSDKConfig} config Configuration object, see PerpetualDataHandler.readSDKConfig.
* @example
* import { OrderExecutorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
* async function main() {
* console.log(OrderExecutorTool);
* // load configuration for Polygon zkEVM (testnet)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* // OrderExecutorTool (authentication required, PK is an environment variable with a private key)
* const pk: string = <string>process.env.PK;
* let orderTool = new OrderExecutorTool(config, pk);
* // Create a proxy instance to access the blockchain
* await orderTool.createProxyInstance();
* }
* main();
*
* @param {string | Signer} signer Private key or ethers Signer of the account
*/
constructor(config: NodeSDKConfig, signer: string | Signer);
/**
* Executes an order by symbol and ID. This action interacts with the blockchain and incurs gas costs.
* @param {string} symbol Symbol of the form ETH-USD-MATIC.
* @param {string} orderId ID of the order to be executed.
* @param {string} executorAddr optional address of the wallet to be credited for executing the order, if different from the one submitting this transaction.
* @param {number} nonce optional nonce
* @param {PriceFeedSubmission=} submission optional signed prices obtained via PriceFeeds::fetchLatestFeedPriceInfoForPerpetual
* @example
* import { OrderExecutorTool, PerpetualDataHandler, Order } from "@d8x/perpetuals-sdk";
* async function main() {
* console.log(OrderExecutorTool);
* // Setup (authentication required, PK is an environment variable with a private key)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* const pk: string = <string>process.env.PK;
* const symbol = "ETH-USD-MATIC";
* let orderTool = new OrderExecutorTool(config, pk);
* await orderTool.createProxyInstance();
* // get some open orders
* const maxOrdersToGet = 5;
* let [orders, ids]: [Order[], string[]] = await orderTool.pollLimitOrders(symbol, maxOrdersToGet);
* console.log(`Got ${ids.length} orders`);
* for (let k = 0; k < ids.length; k++) {
* // check whether order meets conditions
* let doExecute = await orderTool.isTradeable(orders[k]);
* if (doExecute) {
* // execute
* let tx = await orderTool.executeOrder(symbol, ids[k]);
* console.log(`Sent order id ${ids[k]} for execution, tx hash = ${tx.hash}`);
* }
* }
* }
* main();
* @returns Transaction object.
*/
executeOrder(symbol: string, orderId: string, executorAddr?: string, submission?: PriceFeedSubmission, overrides?: PayableOverrides): Promise<TransactionResponse>;
/**
* Executes a list of orders of the symbol. This action interacts with the blockchain and incurs gas costs.
* @param {string} symbol Symbol of the form ETH-USD-MATIC.
* @param {string[]} orderIds IDs of the orders to be executed.
* @param {string} executorAddr optional address of the wallet to be credited for executing the order, if different from the one submitting this transaction.
* @param {number} nonce optional nonce
* @param {PriceFeedSubmission=} submission optional signed prices obtained via PriceFeeds::fetchLatestFeedPriceInfoForPerpetual
* @example
* import { OrderExecutorTool, PerpetualDataHandler, Order } from "@d8x/perpetuals-sdk";
* async function main() {
* console.log(OrderExecutorTool);
* // Setup (authentication required, PK is an environment variable with a private key)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* const pk: string = <string>process.env.PK;
* const symbol = "ETH-USD-MATIC";
* let orderTool = new OrderExecutorTool(config, pk);
* await orderTool.createProxyInstance();
* // get some open orders
* const maxOrdersToGet = 5;
* let [orders, ids]: [Order[], string[]] = await orderTool.pollLimitOrders(symbol, maxOrdersToGet);
* console.log(`Got ${ids.length} orders`);
* // execute
* let tx = await orderTool.executeOrders(symbol, ids);
* console.log(`Sent order ids ${ids.join(", ")} for execution, tx hash = ${tx.hash}`);
* }
* main();
* @returns Transaction object.
*/
executeOrders(symbol: string, orderIds: string[], executorAddr?: string, submission?: PriceFeedSubmission, overrides?: PayableOverrides & {
rpcURL?: string;
splitTx?: boolean;
maxGasLimit?: BigNumberish;
}): Promise<TransactionResponse>;
/**
* Get order from the digest (=id)
* @param symbol symbol of order book, e.g. ETH-USD-MATIC
* @param digest digest of the order (=order ID)
* @example
* import { OrderExecutorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
* async function main() {
* console.log(OrderExecutorTool);
* // setup (authentication required, PK is an environment variable with a private key)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* const pk: string = <string>process.env.PK;
* let orderTool = new OrderExecutorTool(config, pk);
* await orderTool.createProxyInstance();
* // get order by ID
* let myorder = await orderTool.getOrderById("MATIC-USD-MATIC",
* "0x0091a1d878491479afd09448966c1403e9d8753122e25260d3b2b9688d946eae");
* console.log(myorder);
* }
* main();
*
* @returns order or undefined
*/
getOrderById(symbol: string, id: string, overrides?: Overrides & {
rpcURL?: string;
}): Promise<Order | undefined>;
/**
* Check if a conditional order can be executed
* @param order order structure
* @param indexPrices pair of index prices S2 and S3. S3 set to zero if not required. If undefined
* the function will fetch the latest prices from the REST API
* @example
* import { OrderExecutorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
* async function main() {
* console.log(OrderExecutorTool);
* // setup (authentication required, PK is an environment variable with a private key)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* const pk: string = <string>process.env.PK;
* let orderTool = new OrderExecutorTool(config, pk);
* await orderTool.createProxyInstance();
* // check if tradeable
* let openOrders = await orderTool.getAllOpenOrders("MATIC-USD-MATIC");
* let check = await orderTool.isTradeable(openOrders[0][0]);
* console.log(check);
* }
* main();
* @returns true if order can be executed for the current state of the perpetuals
*/
isTradeable(order: Order, orderId: string, blockTimestamp?: number, indexPrices?: IdxPriceInfo, overrides?: Overrides & {
rpcURL?: string;
}): Promise<boolean>;
/**
* Check for a batch of orders on the same perpetual whether they can be traded
* @param orders orders belonging to 1 perpetual
* @param indexPrice S2,S3-index prices for the given perpetual. Will fetch prices from REST API
* if not defined.
* @returns array of tradeable boolean
* @example
* import { OrderExecutorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
* async function main() {
* console.log(OrderExecutorTool);
* // setup (authentication required, PK is an environment variable with a private key)
* const config = PerpetualDataHandler.readSDKConfig("cardona");
* const pk: string = <string>process.env.PK;
* let orderTool = new OrderExecutorTool(config, pk);
* await orderTool.createProxyInstance();
* // check if tradeable
* let openOrders = await orderTool.getAllOpenOrders("MATIC-USD-MATIC");
* let check = await orderTool.isTradeableBatch(
* [openOrders[0][0], openOrders[0][1]],
* [openOrders[1][0], openOrders[1][1]]
* );
* console.log(check);
* }
* main();
*/
isTradeableBatch(orders: Order[], orderIds: string[], blockTimestamp?: number, indexPrices?: IdxPriceInfo, overrides?: Overrides & {
rpcURL?: string;
}): Promise<boolean[]>;
/**
* Performs on-chain checks via multicall
* @param orders orders to check
* @param orderIds order ids
* @ignore
*/
private _isTradeableBatch;
/**
* Can the order be executed?
* @param order order struct
* @param tradePrice "preview" price of this order
* @param markPrice current mark price
* @param atBlockTimestamp block timestamp when execution would take place
* @param symbolToPerpInfoMap metadata
* @returns true if trading conditions met, false otherwise
* @ignore
*/
protected _isTradeable(order: Order, tradePrice: number, markPrice: number, atBlockTimestamp: number, symbolToPerpInfoMap: Map<string, PerpetualStaticInfo>): boolean;
/**
* Wrapper of static method to use after mappings have been loaded into memory.
* @param scOrder Perpetual order as received in the proxy events.
* @returns A user-friendly order struct.
*/
smartContractOrderToOrder(scOrder: SmartContractOrder): Order;
/**
* Gets the current transaction count for the connected signer
* @param blockTag
* @returns The nonce for the next transaction
*/
getTransactionCount(blockTag?: BlockTag): Promise<number>;
}