In cases where a Maker's orders have been requested as part of a Taker's potential fill order, Makers will have to wait for the Operator signature to lapse before their order can be gaslessly cancelled. As long as the Taker's fill order is not executed, Makers still have the option to immediately cancel their orders by paying a gas fee to prioritize their cancellation on-chain. Usage of this Hard Cancel option is expected to be minimal unless the Maker's orders are consistently close to the market price.
Please refer to Decentralized Limit Orders for more details regarding this design.
KyberSwap exposes 2 API options for Makers who wish to cancel their orders on-chain:
/read-ks/api/v1/encode/cancel-batch-orders
: Encode the batch cancellation data to be sent on-chain. This API can be used to cancel a singleorderId
or multiple orders by specifying the targetorderIds
./read-ks/api/v1/encode/increase-nonce
: Encode the increase nonce data to be sent on-chain. By increasing the LO contract nonce tied to the Maker, the LO contract is able to nullify all existing orders.
In addition to the above, Makers are also able to query their active order(s) to aid with filtering orders to cancel:
/read-ks/api/v1/orders
: Get all orders created by a Maker address filtered by the order status.
{% hint style="success" %} Limit Order API Demo
The code snippets in the guide below have been extracted from our demo GitHub repo which showcases the full end-to-end Limit Order operations in a TypeScript environment. {% endhint %}
{% embed url="https://github.com/KyberNetwork/ks-limit-order-API-demo" %}
{% hint style="info" %} Active/Open Orders
To proceed with this guide, users must have created an Active or Open Limit Order. Please refer to the Create Limit Order developer guide for instructions on how to achieve this programmatically. {% endhint %}
We can use the /read-ks/api/v1/orders
to get the list of "active" or "open" Maker orders:
const targetPathConfig = {
params: {
chainId: ChainId.MATIC,
maker: signerAddress,
status: "active"
}
};
In this case, the above query will return all of the Maker active orders from which we can then filter for our target order to cancel.
{% hint style="info" %} Cancel All Orders
If you would like to cancel all orders instead, you can call /read-ks/api/v1/encode/increase-nonce
which will return the encoded increase nonce data. This can be used in place of the encoded data from step 5 onwards.
Please refer to postCancelAllOrders.ts
for a Cancel All example.
{% endhint %}
For our purposes, we will just take the first order which matches our makerAsset
and takerAsset
pair:
const orders = await getMakerOrders();
const targetOrders = orders.filter(order =>
order.makerAsset.toLowerCase() == makerAsset.address.toLowerCase() &&
order.takerAsset.toLowerCase() == takerAsset.address.toLowerCase()
);
const targetOrderId = Number(targetOrders[targetOrders.length-1].id);
The orderId
will be included as part of the orderIds
array:
const requestBody: CancelBatchOrdersBody = {
orderIds: [targetOrderId]
};
Note that you can include multiple orderId
s to be encoded in the same transaction so that you will only have to pay gas once to hard cancel all the included orders.
With the orderIds prepared, we can then request the encoded data via /read-ks/api/v1/encode/cancel-batch-orders
:
const {data} = await axios.post(
LimitOrderDomain+targetPath,
requestBody
);
This will return the batch cancel encoded data which will be used as the calldata when executing the transaction on-chain.
To execute the transaction, we can use our ethers.js signer instance to send the transaction with the required gas fees:
const cancelOrderTx = await signer.sendTransaction({
data: data.data.encodedData,
to: limitOrderContract,
from: signerAddress,
maxFeePerGas: 100000000000,
maxPriorityFeePerGas: 100000000000
});
A transaction hash will be returned once the cancel order has been executed. You can copy this hash into a scanner (i.e. PolygonScan) and see that your transaction has been successfully completed by the network.