UNPKG

@d8x/perpetuals-sdk

Version:

Node TypeScript SDK for D8X Perpetual Futures

209 lines (208 loc) 10.4 kB
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>; }