API

You can use ethers.js, viem or similar tools to automate trading.

You can also retrieve data from The Graph; see Subgraph.

Create an order

Contract struct

For marketID, see Metadata

struct Order {
    ActionType action; // Order action, 0 for OpenPosition, 1 for ReduceOnly
    uint256 marketId; // See link above
    /// @notice Use `amount` and `price` to control slippage
    int256 amount; // Amount of base token, 18 decimals
    uint256 price; // Order price, 18 decimals
    uint256 expiry; // Expiry timestamp
    TradeType tradeType; // Fill type, 0 for Fill or Kill, 1 for Partial Fill
    address owner; // Order address (must be same as signer)
    uint256 marginXCD; // Margin amount for the order, decimals match collateral
    /// @notice `relayFee` is 0.10 USDT; in the future this fee will be queryable via API
    uint256 relayFee; // Relayer fee, decimals match collateral
    bytes32 id; // User generated; may not repeat
}

API Endpoint

POST https://dcn9cxclqj1v1.cloudfront.net/production/place-order

Request

{
"signedOrder": {
		"order": {
		    "action": integer,
		    "marketId": integer,
		    "amount": string,
		    "price": string,
		    "expiry": integer,
		    "tradeType": integer,
		    "owner": string,
		    "margin": string,
		    "relayFee": string,
		    "id": string, // length 66
    }
    "signature": string // length 132
  }
}

Response

if success
{
  "isSuccess": true
}
else
{
  "isSuccess": false,
  "message": "Error message here"
}

Cancel an order

Orders are cancelled using the signed order and orderID (not just orderID, since it would allow anyone to cancel another account's order).

API Endpoint

POST https://dcn9cxclqj1v1.cloudfront.net/production/cancel-order

Request

{
  "orderId": string, // length 66
  "signature": string // length 132
}

Response

if success
{
  "isSuccess": true
}
else
{
  "isSuccess": false,
  "message": "Error message here"
}

Examples

Create order

const order = {
    action: 0,
    marketId: 0,
    amount: parseEther("1", 18),
    price: parseEther("100", 18),
    expiry: DateTime.now().plus({ minutes: 1 }).toUnixInteger(),
    tradeType: 1,
    owner: 0xbeef...,
    margin: parseEther("10", 6),
    relayFee: signedOrder.order.relayFee.toFixed(),
    id: signedOrder.order.id,
}

const domain = {
    name: "OrderGatewayV2",
    version: "1",
    chainId: publicClient.chain.id,
    verifyingContract: orderGatewayV2Proxy.contractAddress,
}

const typeWithoutDomain = {
    Order: [
        { name: "action", type: "uint8" },
        { name: "marketId", type: "uint256" },
        { name: "amount", type: "int256" },
        { name: "price", type: "uint256" },
        { name: "expiry", type: "uint256" },
        { name: "tradeType", type: "uint8" },
        { name: "owner", type: "address" },
        { name: "marginXCD", type: "uint256" },
        { name: "relayFee", type: "uint256" },
        { name: "id", type: "bytes32" },
    ],
}

const typedData = {
    domain: domain,
    types: typeWithoutDomain,
    primaryType: "Order",
    message: {
        action: order.action,
        marketId: order.marketId,
        amount: big2Bigint(order.amount, this.weiDecimals),
        price: big2Bigint(order.price, this.weiDecimals),
        expiry: order.expiry,
        tradeType: order.tradeType,
        owner: signerAddress,
        marginXCD: big2Bigint(order.margin, this.collateralDecimals),
        relayFee: big2Bigint(order.relayFee, this.collateralDecimals),
        id: order.id,
    },
}

const signature = signTypedData(walletAddress, order)

const body = JSON.stringify({
   signedOrder: {
       order,
      signature,
   }
})

await fetch(placeOrderApi, {
   method: "POST",
   body,
})

Cancel order

const signature = signMessage({
      account: 0xbeef...
      orderId: 0xdead...
})

const body = JSON.stringify({
      orderId,
      signature,
})

await fetch(cancelOrderApi, {
      method: "POST",
      body,
})

Last updated