From 89ad416969c8198ac18287d0f4346864bc2a1003 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Thu, 23 Jun 2022 16:30:46 -0300 Subject: [PATCH 1/3] Marketable limit orders --- examples/marketOrderIOC.ts | 56 ++++++++++++++++++++++++++++++++++++ package.json | 4 +-- src/order-builder/helpers.ts | 10 +++++++ src/types.ts | 6 ++++ src/utilities.ts | 1 + yarn.lock | 8 +++--- 6 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 examples/marketOrderIOC.ts diff --git a/examples/marketOrderIOC.ts b/examples/marketOrderIOC.ts new file mode 100644 index 0000000..863c86b --- /dev/null +++ b/examples/marketOrderIOC.ts @@ -0,0 +1,56 @@ +import { ethers } from "ethers"; +import { config as dotenvConfig } from "dotenv"; +import { resolve } from "path"; +import { ApiKeyCreds, ClobClient, Side } from "../src"; + +dotenvConfig({ path: resolve(__dirname, "../.env") }); + +async function main() { + const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL); + const pk = new ethers.Wallet(`${process.env.PK}`); + const wallet = pk.connect(provider); + console.log(`Address: ${await wallet.getAddress()}`); + + const host = process.env.CLOB_API_URL || "http://localhost:8080"; + const creds: ApiKeyCreds = { + key: `${process.env.CLOB_API_KEY}`, + secret: `${process.env.CLOB_SECRET}`, + passphrase: `${process.env.CLOB_PASS_PHRASE}`, + }; + const clobClient = new ClobClient(host, wallet, creds); + + const NO_TOKEN = "1343197538147866997676250008839231694243646439454152539053893078719042421992" + + await clobClient.postOrder(await clobClient.createLimitOrder({ + tokenID: NO_TOKEN, + price: 0.5, + side: Side.BUY, + size: 100, + })); + + // FOK, error expected + const fok_order = await clobClient.createMarketOrder({ + tokenID: NO_TOKEN, + side: Side.SELL, + size: 200, + timeInForce: "FOK" + }) + console.log(`FOK market order: `); + console.log(fok_order); + + console.log(await clobClient.postOrder(fok_order)); + + // Create a IOC market sell order for 100 YES tokens + const ioc_order = await clobClient.createMarketOrder({ + tokenID: NO_TOKEN, + side: Side.SELL, + size: 200, + timeInForce: "IOC" + }); + console.log(`IOC market order: `); + console.log(ioc_order); + + console.log(await clobClient.postOrder(ioc_order)); +} + +main(); diff --git a/package.json b/package.json index 684c9f7..aaa3619 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@polymarket/clob-client", "description": "Typescript client for Polymarket's CLOB", - "version": "1.0.31", + "version": "1.0.32", "contributors": [ { "name": "Jonathan Amenechi", @@ -23,7 +23,7 @@ "@ethersproject/random": "^5.5.0", "@ethersproject/transactions": "^5.5.0", "@ethersproject/wallet": "^5.5.0", - "@polymarket/order-utils": "^1.2.13", + "@polymarket/order-utils": "^1.2.14", "axios": "^0.21.1", "commitizen": "^4.2.1", "cz-conventional-changelog": "^3.3.0", diff --git a/src/order-builder/helpers.ts b/src/order-builder/helpers.ts index a0e94a0..0d37458 100644 --- a/src/order-builder/helpers.ts +++ b/src/order-builder/helpers.ts @@ -11,6 +11,7 @@ import { MarketOrderBuilder, MarketOrderData, SignatureType, + TimeInForce, } from "@polymarket/order-utils"; import { ethers } from "ethers"; import { OrderCreationArgs, UserMarketOrder, UserLimitOrder, MarketOrderCreationArgs, Side } from "../types"; @@ -103,6 +104,8 @@ export const buildMarketOrderCreationArgs = async ( let minAmountReceived = "0"; // Default to 0 + let timeInForce:TimeInForce = "FOK" + if (userOrder.side === Side.BUY) { // market buy makerAsset = collateral; // Set maker asset to collateral if market buy @@ -135,6 +138,11 @@ export const buildMarketOrderCreationArgs = async ( minAmountReceived = ethers.utils.parseUnits(minAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString(); } } + + if (userOrder.timeInForce) { + timeInForce = userOrder.timeInForce + } + return { chainID, exchange, @@ -147,6 +155,7 @@ export const buildMarketOrderCreationArgs = async ( takerAssetID, signatureType, minAmountReceived, + timeInForce }; }; @@ -246,6 +255,7 @@ const buildMarketOrder = async (signer: Wallet | JsonRpcSigner, args: MarketOrde signature: sig, orderType: "market", minAmountReceived: args.minAmountReceived, + timeInForce: args.timeInForce }; console.log(`Generated Market order!`); return orderAndSignature; diff --git a/src/types.ts b/src/types.ts index 086c516..92db0ef 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,5 @@ +import { TimeInForce } from "@polymarket/order-utils"; + export * from "@polymarket/order-utils"; export interface ApiKeyCreds { @@ -59,6 +61,9 @@ export interface UserMarketOrder { // (Optional) Worst price // The worst price this market order can be executed at worstPrice?: number; + // (Optional) FOK (fill or kill) / IOC (immediate or cancel) + // Default: FOK + timeInForce?: TimeInForce } export interface OrderPayload { @@ -92,6 +97,7 @@ export interface MarketOrderCreationArgs { takerAssetID?: string; signatureType: number; minAmountReceived: string; + timeInForce: TimeInForce } export interface ApiKeysResponse { diff --git a/src/utilities.ts b/src/utilities.ts index 19eae28..59d245f 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -38,6 +38,7 @@ export const marketOrderToJson = (mktOrder: MarketOrderAndSignature): any => { signature: mktOrder.signature, orderType: "market", minAmountReceived: mktOrder.minAmountReceived, + timeInForce: mktOrder.timeInForce, }; }; diff --git a/yarn.lock b/yarn.lock index 1b19e17..4ec25f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -636,10 +636,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@polymarket/order-utils@^1.2.13": - version "1.2.13" - resolved "https://registry.yarnpkg.com/@polymarket/order-utils/-/order-utils-1.2.13.tgz#ddff9c6f074ce363f7d281cd74766b3ba2ede992" - integrity sha512-QcZb4CIS0EF0+EJbHmOiXnG0ZY2S2NVJTD+zzrNBUkMVpyy9c863LBSkZnThzUOnkQlcwljcenzwObK8zvGU4g== +"@polymarket/order-utils@^1.2.14": + version "1.2.14" + resolved "https://registry.yarnpkg.com/@polymarket/order-utils/-/order-utils-1.2.14.tgz#279728af3dac24e2b17cdab5386034ba8281dc09" + integrity sha512-PbBaqwOvtUL1Ks/ZabtQpb/M8cVMR7TZqHfTOemJQbYsTPjuxwRWhyGr5BhgdnU8Dw60cXBEhBSw7b1lrCtrKw== "@types/bn.js@^4.11.3": version "4.11.6" From 9381a1b6812d1c80cd6f5febc1eddb6acb0b4592 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Thu, 23 Jun 2022 18:58:13 -0300 Subject: [PATCH 2/3] Adding slippage check to IOC orders --- examples/marketOrderIOC.ts | 39 +++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/examples/marketOrderIOC.ts b/examples/marketOrderIOC.ts index 863c86b..32c9f74 100644 --- a/examples/marketOrderIOC.ts +++ b/examples/marketOrderIOC.ts @@ -27,12 +27,30 @@ async function main() { side: Side.BUY, size: 100, })); + await clobClient.postOrder(await clobClient.createLimitOrder({ + tokenID: NO_TOKEN, + price: 0.5, + side: Side.BUY, + size: 100, + })); + await clobClient.postOrder(await clobClient.createLimitOrder({ + tokenID: NO_TOKEN, + price: 0.4, + side: Side.BUY, + size: 100, + })); + await clobClient.postOrder(await clobClient.createLimitOrder({ + tokenID: NO_TOKEN, + price: 0.4, + side: Side.BUY, + size: 100, + })); // FOK, error expected const fok_order = await clobClient.createMarketOrder({ tokenID: NO_TOKEN, side: Side.SELL, - size: 200, + size: 500, timeInForce: "FOK" }) console.log(`FOK market order: `); @@ -40,11 +58,26 @@ async function main() { console.log(await clobClient.postOrder(fok_order)); - // Create a IOC market sell order for 100 YES tokens + // Create a IOC market sell that will fail because the slippage check + const ioc_slippage_check_order = await clobClient.createMarketOrder({ + tokenID: NO_TOKEN, + side: Side.SELL, + size: 500, + worstPrice: 0.5, + timeInForce: "IOC" + }); + console.log(`IOC market order: `); + console.log(ioc_slippage_check_order); + + console.log(await clobClient.postOrder(ioc_slippage_check_order)); + + + // Create a IOC market sell that will match const ioc_order = await clobClient.createMarketOrder({ tokenID: NO_TOKEN, side: Side.SELL, - size: 200, + size: 250, + worstPrice: 0.45, timeInForce: "IOC" }); console.log(`IOC market order: `); From c7cd5e0876f032e3a17a03dea88f0a0123ab2c94 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Fri, 24 Jun 2022 19:05:36 -0300 Subject: [PATCH 3/3] Fixing IOC order example --- examples/marketOrderIOC.ts | 46 ++++---------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/examples/marketOrderIOC.ts b/examples/marketOrderIOC.ts index 32c9f74..8ad9c05 100644 --- a/examples/marketOrderIOC.ts +++ b/examples/marketOrderIOC.ts @@ -21,62 +21,24 @@ async function main() { const NO_TOKEN = "1343197538147866997676250008839231694243646439454152539053893078719042421992" - await clobClient.postOrder(await clobClient.createLimitOrder({ - tokenID: NO_TOKEN, - price: 0.5, - side: Side.BUY, - size: 100, - })); - await clobClient.postOrder(await clobClient.createLimitOrder({ - tokenID: NO_TOKEN, - price: 0.5, - side: Side.BUY, - size: 100, - })); await clobClient.postOrder(await clobClient.createLimitOrder({ tokenID: NO_TOKEN, price: 0.4, side: Side.BUY, - size: 100, + size: 200, })); await clobClient.postOrder(await clobClient.createLimitOrder({ tokenID: NO_TOKEN, - price: 0.4, + price: 0.45, side: Side.BUY, - size: 100, + size: 250, })); - // FOK, error expected - const fok_order = await clobClient.createMarketOrder({ - tokenID: NO_TOKEN, - side: Side.SELL, - size: 500, - timeInForce: "FOK" - }) - console.log(`FOK market order: `); - console.log(fok_order); - - console.log(await clobClient.postOrder(fok_order)); - - // Create a IOC market sell that will fail because the slippage check - const ioc_slippage_check_order = await clobClient.createMarketOrder({ - tokenID: NO_TOKEN, - side: Side.SELL, - size: 500, - worstPrice: 0.5, - timeInForce: "IOC" - }); - console.log(`IOC market order: `); - console.log(ioc_slippage_check_order); - - console.log(await clobClient.postOrder(ioc_slippage_check_order)); - - // Create a IOC market sell that will match const ioc_order = await clobClient.createMarketOrder({ tokenID: NO_TOKEN, side: Side.SELL, - size: 250, + size: 500, worstPrice: 0.45, timeInForce: "IOC" });