If you inspect the underlying types for these transactions, you'll notice that a "nonce" field is required. This is a unique integer in ascending order. Our off-chain engine has a nonce query to return the latest nonce for a given subaccount. All this is abstracted away within the SDK, so you do not need to manually use this query.
An order requires a number of parameters, encapsulated by the OrderActionParams['order'] type.
In the example below:
The order expiration time is given by calling the nowInSeconds function from the utils package and adding 60 seconds. This means the order will expire 60 seconds from now.
Notice the usage of getExpirationTimestamp, order types, such as IOC (immediate or cancel) are encoded in the expiration field, the getExpirationTimestamp function will return the correct expiration timestamp for the given order type.
The price field is set at 20000 - a low value (at the time of writing) to prevent execution. This enables us to cancel the order later on without it being instantly filled. Please adjust this price accordingly.
The amount field is set at 10**16 - this is the amount to buy/sell. A positive value is to buy, negative is to sell.
Amount is normalized to 18 decimal places, which is what toFixedPoint does by default.
NOTE: Min size for BTC is 10**16 and for ETH is 10**17. Orders below these sizes will fail to be placed.
Use the order parameters to place the order with the placeOrder function.
constplaceOrderResult=awaitvertexClient.market.placeOrder({ order: orderParams, productId:1,});prettyPrintJson("Place Order Result", placeOrderResult);
Create an order tx
Alternatively, you can create an order tx and interface with lower level methods to place the order. The order parameters are encapsulated by OrderParams.
import { Wallet } from'ethers';import { getVertexClient, prettyPrintJson } from"./common";import { OrderActionParams } from"@vertex-protocol/client";import { nowInSeconds } from"@vertex-protocol/utils";import { getExpirationTimestamp } from"@vertex-protocol/contracts";asyncfunctionmain() {constvertexClient=awaitgetVertexClient();constaddress=await (vertexClient.context.signerOrProvider asWallet ).getAddress();constsubaccountName="default";constdepositAmount=10**6;// SETUP - skipping logging here as it's in depositWithdrawlet tx =awaitvertexClient.spot._mintMockERC20({ productId:0, amount: depositAmount, });awaittx.wait(); tx =awaitvertexClient.spot.approveAllowance({ productId:0, amount: depositAmount, });awaittx.wait(); tx =awaitvertexClient.spot.deposit({ productId:0, amount: depositAmount, subaccountName, });awaittx.wait();awaitnewPromise((resolve) =>setTimeout(resolve,10000));// Create the orderconstorderParams:OrderActionParams["order"] = { subaccountName,// `nowInSeconds` is exposed by the `@vertex-protocol/utils` package// This gives 60s before the order expires// Currently, IOC is also supported as an expiration type expiration:getExpirationTimestamp("default",nowInSeconds() +60).toString(),// Limit price // Set this to a low amount so that the order does not fill immediately, this might need adjustment based on the product & current price
price:20000,// Positive amount for buys, negative for sells amount:1, };// Place the orderconstplaceOrderResult=awaitvertexClient.market.placeOrder({ order: orderParams, productId:1, });prettyPrintJson("Place Order Result", placeOrderResult);// Now query orders for this subaccountconstopenOrders=awaitvertexClient.market.getOpenSubaccountOrders({ subaccountOwner: address, subaccountName, productId:1, });prettyPrintJson("Subaccount Open Orders", openOrders);// Now cancel the order by its digest, you can cancel multiple at onceconstcancelOrderResult=awaitvertexClient.market.cancelOrder({ digests: [placeOrderResult.digest], productIds: [1], subaccountName, });prettyPrintJson("Cancel Order Result", cancelOrderResult);// Now query orders after cancellationconstopenOrdersAfterCancel=awaitvertexClient.market.getOpenSubaccountOrders({ subaccountOwner: address, subaccountName, productId:1, });prettyPrintJson("Subaccount Open Orders After Cancel", openOrdersAfterCancel);// Cleanup by withdrawingawaitvertexClient.spot.withdraw({ productId:0, amount: depositAmount -10**5, subaccountName, });}main();