Skip to content

Commit

Permalink
Neg Risk Support (#100)
Browse files Browse the repository at this point in the history
* refactor for neg risk

* update tests, misc

* update examples

* rename

* add approve NegRisk example

* update examples

* delete negRiskAdapter abi

* update helpers.test.ts

* adding new neg risk test cases

* bump order-utils

---------

Co-authored-by: Rodrigo <[email protected]>
  • Loading branch information
mshrieve and poly-rodr authored Nov 29, 2023
1 parent b91af5c commit 0a69c12
Show file tree
Hide file tree
Showing 24 changed files with 6,283 additions and 2,982 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ typechain/
# files
.solcover.js
coverage.json
.eslintrc.js
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
plugins: ["@typescript-eslint", "unused-imports"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
parserOptions: {
project: "./tsconfig.json",
project: "./tsconfig.eslint.json",
tsconfigRootDir: __dirname,
sourceType: "module",
},
Expand Down
34 changes: 14 additions & 20 deletions examples/approveAllowances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { BigNumber, constants, ethers } from "ethers";
import { config as dotenvConfig } from "dotenv";
import { resolve } from "path";
import { Chain } from "../src";
import { getContractConfig } from "../src/config";
import { usdcAbi } from "./abi/usdcAbi";
import { ctfAbi } from "./abi/ctfAbi";
import { getContracts } from "@polymarket/order-utils";

dotenvConfig({ path: resolve(__dirname, "../.env") });

export function getWallet(mainnetQ: boolean): ethers.Wallet {
const pk = process.env.PK as string;
const rpcToken: string = process.env.RPC_TOKEN as string;
let rpcUrl: string = "";
let rpcUrl = "";
if (mainnetQ) {
rpcUrl = `https://polygon-mainnet.g.alchemy.com/v2/${rpcToken}`;
} else {
Expand All @@ -24,21 +24,15 @@ export function getWallet(mainnetQ: boolean): ethers.Wallet {
}

export function getUsdcContract(mainnetQ: boolean, wallet: ethers.Wallet): ethers.Contract {
if (mainnetQ) {
const mainnetContracts = getContracts(137);
return new ethers.Contract(mainnetContracts.Collateral, usdcAbi, wallet);
}
const mumbaiContracts = getContracts(80001);
return new ethers.Contract(mumbaiContracts.Collateral, usdcAbi, wallet);
const chainId = mainnetQ ? 137 : 80001;
const contractConfig = getContractConfig(chainId);
return new ethers.Contract(contractConfig.collateral, usdcAbi, wallet);
}

export function getCtfContract(mainnetQ: boolean, wallet: ethers.Wallet): ethers.Contract {
if (mainnetQ) {
const mainnetContracts = getContracts(137);
return new ethers.Contract(mainnetContracts.Conditional, ctfAbi, wallet);
}
const mumbaiContracts = getContracts(80001);
return new ethers.Contract(mumbaiContracts.Conditional, ctfAbi, wallet);
const chainId = mainnetQ ? 137 : 80001;
const contractConfig = getContractConfig(chainId);
return new ethers.Contract(contractConfig.conditionalTokens, ctfAbi, wallet);
}

async function main() {
Expand All @@ -50,7 +44,7 @@ async function main() {
const chainId = parseInt(`${process.env.CHAIN_ID || Chain.MUMBAI}`) as Chain;
console.log(`Address: ${await wallet.getAddress()}, chainId: ${chainId}`);

const contracts = getContracts(isMainnet ? 137 : 80001);
const contractConfig = getContractConfig(chainId);
const usdc = getUsdcContract(isMainnet, wallet);
const ctf = getCtfContract(isMainnet, wallet);

Expand All @@ -61,31 +55,31 @@ async function main() {
console.log(`usdcAllowanceCtf: ${usdcAllowanceCtf}`);
const usdcAllowanceExchange = (await usdc.allowance(
wallet.address,
contracts.Exchange,
contractConfig.exchange,
)) as BigNumber;
const conditionalTokensAllowanceExchange = (await ctf.isApprovedForAll(
wallet.address,
contracts.Exchange,
contractConfig.exchange,
)) as BigNumber;

let txn;

if (!usdcAllowanceCtf.gt(constants.Zero)) {
txn = await usdc.approve(contracts.Conditional, constants.MaxUint256, {
txn = await usdc.approve(contractConfig.conditionalTokens, constants.MaxUint256, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting USDC allowance for CTF: ${txn.hash}`);
}
if (!usdcAllowanceExchange.gt(constants.Zero)) {
txn = await usdc.approve(contracts.Exchange, constants.MaxUint256, {
txn = await usdc.approve(contractConfig.exchange, constants.MaxUint256, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting USDC allowance for Exchange: ${txn.hash}`);
}
if (!conditionalTokensAllowanceExchange) {
txn = await ctf.setApprovalForAll(contracts.Exchange, true, {
txn = await ctf.setApprovalForAll(contractConfig.exchange, true, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
Expand Down
111 changes: 111 additions & 0 deletions examples/approveNegRiskAllowances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { BigNumber, constants, ethers } from "ethers";
import { config as dotenvConfig } from "dotenv";
import { resolve } from "path";
import { Chain } from "../src";
import { getContractConfig } from "../src/config";
import { usdcAbi } from "./abi/usdcAbi";
import { ctfAbi } from "./abi/ctfAbi";

dotenvConfig({ path: resolve(__dirname, "../.env") });

/**
* NegRisk markets require separate allowances
* for the NegRiskCtfExchange and the NegRiskAdapter.
*/

export function getWallet(mainnetQ: boolean): ethers.Wallet {
const pk = process.env.PK as string;
const rpcToken: string = process.env.RPC_TOKEN as string;
let rpcUrl = "";
if (mainnetQ) {
rpcUrl = `https://polygon-mainnet.g.alchemy.com/v2/${rpcToken}`;
} else {
rpcUrl = `https://polygon-mumbai.g.alchemy.com/v2/${rpcToken}`;
}
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
let wallet = new ethers.Wallet(pk);
wallet = wallet.connect(provider);
return wallet;
}

export function getUsdcContract(mainnetQ: boolean, wallet: ethers.Wallet): ethers.Contract {
const chainId = mainnetQ ? 137 : 80001;
const contractConfig = getContractConfig(chainId);
return new ethers.Contract(contractConfig.collateral, usdcAbi, wallet);
}

export function getCtfContract(mainnetQ: boolean, wallet: ethers.Wallet): ethers.Contract {
const chainId = mainnetQ ? 137 : 80001;
const contractConfig = getContractConfig(chainId);
return new ethers.Contract(contractConfig.conditionalTokens, ctfAbi, wallet);
}

async function main() {
// --------------------------
// SET MAINNET OR MUMBAI HERE
const isMainnet = false;
// --------------------------
const wallet = getWallet(isMainnet);
const chainId = parseInt(`${process.env.CHAIN_ID || Chain.MUMBAI}`) as Chain;
console.log(`Address: ${await wallet.getAddress()}, chainId: ${chainId}`);

const contractConfig = getContractConfig(chainId);
const usdc = getUsdcContract(isMainnet, wallet);
const ctf = getCtfContract(isMainnet, wallet);

console.log(`usdc: ${usdc.address}`);
console.log(`ctf: ${ctf.address}`);

const usdcAllowanceNegRiskAdapter = (await usdc.allowance(
wallet.address,
contractConfig.negRiskAdapter,
)) as BigNumber;
console.log(`usdcAllowanceNegRiskAdapter: ${usdcAllowanceNegRiskAdapter}`);
const usdcAllowanceNegRiskExchange = (await usdc.allowance(
wallet.address,
contractConfig.negRiskExchange,
)) as BigNumber;
const conditionalTokensAllowanceNegRiskExchange = (await ctf.isApprovedForAll(
wallet.address,
contractConfig.negRiskExchange,
)) as BigNumber;
const conditionalTokensAllowanceNegRiskAdapter = (await ctf.isApprovedForAll(
wallet.address,
contractConfig.negRiskAdapter,
)) as BigNumber;

let txn;

// for splitting through the NegRiskAdapter
if (!usdcAllowanceNegRiskAdapter.gt(constants.Zero)) {
txn = await usdc.approve(contractConfig.negRiskAdapter, constants.MaxUint256, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting USDC allowance for NegRiskAdapter: ${txn.hash}`);
}
if (!usdcAllowanceNegRiskExchange.gt(constants.Zero)) {
txn = await usdc.approve(contractConfig.negRiskExchange, constants.MaxUint256, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting USDC allowance for NegRiskExchange: ${txn.hash}`);
}
if (!conditionalTokensAllowanceNegRiskExchange) {
txn = await ctf.setApprovalForAll(contractConfig.negRiskExchange, true, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting Conditional Tokens allowance for NegRiskExchange: ${txn.hash}`);
}
if (!conditionalTokensAllowanceNegRiskAdapter) {
txn = await ctf.setApprovalForAll(contractConfig.negRiskAdapter, true, {
gasPrice: 100_000_000_000,
gasLimit: 200_000,
});
console.log(`Setting Conditional Tokens allowance for NegRiskAdapter: ${txn.hash}`);
}
console.log("Allowances set");
}

main();
4 changes: 2 additions & 2 deletions examples/geoToken.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ethers } from "ethers";
import { config as dotenvConfig } from "dotenv";
import { resolve } from "path";
import { ApiKeyCreds, Chain, ClobClient, PriceHistoryInterval, Side } from "../src";
import { ApiKeyCreds, Chain, ClobClient, Side } from "../src";

dotenvConfig({ path: resolve(__dirname, "../.env") });

Expand Down Expand Up @@ -37,7 +37,7 @@ async function main() {
side: Side.BUY,
size: 100,
},
"0.01",
{ tickSize: "0.01" },
);
console.log("Created Order", order);

Expand Down
2 changes: 2 additions & 0 deletions examples/getOpenOrders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ async function main() {
console.log(
await clobClient.getOpenOrders({
asset_id:
// eslint-disable-next-line max-len
"16678291189211314787145083999015737376658799626183230671758641503291735614088", // NO
owner: creds.key,
}),
);
console.log(
await clobClient.getOpenOrders({
asset_id:
// eslint-disable-next-line max-len
"1343197538147866997676250008839231694243646439454152539053893078719042421992", // YES
owner: creds.key,
}),
Expand Down
2 changes: 2 additions & 0 deletions examples/getTrades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async function main() {
console.log(
await clobClient.getTrades({
asset_id:
// eslint-disable-next-line max-len
"16678291189211314787145083999015737376658799626183230671758641503291735614088", // NO
maker: await wallet.getAddress(),
limit: 10,
Expand All @@ -29,6 +30,7 @@ async function main() {
console.log(
await clobClient.getTrades({
asset_id:
// eslint-disable-next-line max-len
"1343197538147866997676250008839231694243646439454152539053893078719042421992", // YES
maker: await wallet.getAddress(),
limit: 10,
Expand Down
2 changes: 1 addition & 1 deletion examples/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function main() {
nonce: 0,
expiration: 0,
},
"0.01",
{ tickSize: "0.01" },
);
console.log("Created Order", order);

Expand Down
22 changes: 18 additions & 4 deletions examples/signatureTypes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ethers } from "ethers";
import { config as dotenvConfig } from "dotenv";
import { resolve } from "path";
import { ApiKeyCreds, Chain, ClobClient, Side } from "../src";
import { ApiKeyCreds, Chain, ClobClient } from "../src";
import { SignatureType } from "@polymarket/order-utils";

dotenvConfig({ path: resolve(__dirname, "../.env") });
Expand All @@ -22,12 +22,26 @@ async function main() {
const clobClient = new ClobClient(host, chainId, wallet, creds);

// Client used with a Polymarket Proxy Wallet: Signature type 1
const proxyWalletAddress = "0x...";
const polyProxyClient = new ClobClient(host, chainId, wallet, creds, SignatureType.POLY_PROXY, proxyWalletAddress);
const proxyWalletAddress = "0x...";
const polyProxyClient = new ClobClient(
host,
chainId,
wallet,
creds,
SignatureType.POLY_PROXY,
proxyWalletAddress,
);

// Client used with a Polymarket Gnosis safe: Signature Type 2
const gnosisSafeAddress = "0x...";
const polyGnosisSafeClient = new ClobClient(host, chainId, wallet, creds, SignatureType.POLY_GNOSIS_SAFE, gnosisSafeAddress)
const polyGnosisSafeClient = new ClobClient(
host,
chainId,
wallet,
creds,
SignatureType.POLY_GNOSIS_SAFE,
gnosisSafeAddress,
);
}

main();
3 changes: 2 additions & 1 deletion examples/socketConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { WebSocket } from "ws";
import { ApiKeyCreds } from "../src";

const YES_TOKEN_ID = "1343197538147866997676250008839231694243646439454152539053893078719042421992";
// eslint-disable-next-line max-len
// const NO_TOKEN_ID = "16678291189211314787145083999015737376658799626183230671758641503291735614088";
const CONDITION_ID = "0xbd31dc8a20211944f6b70f31557f1001557b59905b7738480ca09bd4532f84af";

Expand All @@ -22,7 +23,7 @@ interface subscriptionMessage {
async function main(type: "user" | "market" | "live-activity") {
const host = process.env.WS_URL || "ws://localhost:8081";
console.log(`${host}/ws/${type}`);
let ws = new WebSocket(`${host}/ws/${type}`); // change to market for market, user for user
const ws = new WebSocket(`${host}/ws/${type}`); // change to market for market, user for user

let subscriptionMessage: subscriptionMessage = {} as subscriptionMessage;

Expand Down
1 change: 1 addition & 0 deletions examples/testPolyProxyMarketBuy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async function populateBook(client: ClobClient) {
await client.postOrder(
await client.createOrder({
tokenID:
// eslint-disable-next-line max-len
"16678291189211314787145083999015737376658799626183230671758641503291735614088", // NO
side: newOrder.side,
price: newOrder.price,
Expand Down
1 change: 1 addition & 0 deletions examples/testPolyProxyMarketSell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async function populateBook(client: ClobClient) {
await client.postOrder(
await client.createOrder({
tokenID:
// eslint-disable-next-line max-len
"16678291189211314787145083999015737376658799626183230671758641503291735614088", // NO
side: newOrder.side,
price: newOrder.price,
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@polymarket/clob-client",
"description": "Typescript client for Polymarket's CLOB",
"version": "3.2.0",
"version": "4.0.0",
"contributors": [
{
"name": "Jonathan Amenechi",
Expand All @@ -18,6 +18,10 @@
{
"name": "Liam Kovatch",
"url": "https://github.com/l-kov"
},
{
"name": "Mike Shrieve",
"url": "https://github.com/mshrieve"
}
],
"main": "dist/index.js",
Expand All @@ -37,7 +41,7 @@
"test": "make test"
},
"dependencies": {
"@polymarket/order-utils": "^1.3.1",
"@polymarket/order-utils": "^2.0.0",
"axios": "^0.27.2",
"browser-or-node": "^2.1.1",
"ethers": "^5.7.1"
Expand Down
Loading

0 comments on commit 0a69c12

Please sign in to comment.