diff --git a/examples/deriveApiKey.ts b/examples/deriveApiKey.ts new file mode 100644 index 0000000..135fba7 --- /dev/null +++ b/examples/deriveApiKey.ts @@ -0,0 +1,23 @@ +import { ethers } from "ethers"; +import { config as dotenvConfig } from "dotenv"; +import { resolve } from "path"; +import { ClobClient } 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 = "http://localhost:8080"; + const clobClient = new ClobClient(host, wallet); + + console.log(`Response: `); + const resp = await clobClient.deriveApiKey(); + console.log(resp); + console.log(`Complete!`); +} + +main(); diff --git a/package.json b/package.json index 1454c4c..0d6701b 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.21", + "version": "1.0.22", "contributors": [ { "name": "Jonathan Amenechi", diff --git a/src/client.ts b/src/client.ts index 9dd80b9..90e1ea4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -16,7 +16,6 @@ import { OrderHistory, } from "./types"; import { createL1Headers, createL2Headers } from "./headers"; -import { CREDS_CREATION_WARNING } from "./constants"; import { del, DELETE, GET, get, POST, post } from "./http_helpers"; import { L1_AUTH_UNAVAILABLE_ERROR, L2_AUTH_NOT_AVAILABLE } from "./errors"; import { marketOrderToJson, limitOrderToJson, addQueryParamsToUrl } from "./utilities"; @@ -35,6 +34,7 @@ import { PRICE, OPEN_ORDERS, ORDER_HISTORY, + DERIVE_API_KEY, } from "./endpoints"; import { OrderBuilder } from "./order-builder/builder"; @@ -92,13 +92,32 @@ export class ClobClient { } // L1 Authed - public async createApiKey(): Promise { + + /** + * Creates a new API key for a user + * @param nonce + * @returns ApiKeyCreds + */ + public async createApiKey(nonce?: number): Promise { this.canL1Auth(); const endpoint = `${this.host}${CREATE_API_KEY}`; - const headers = await createL1Headers(this.signer as Wallet | JsonRpcSigner); + const headers = await createL1Headers(this.signer as Wallet | JsonRpcSigner, nonce); const resp = await post(endpoint, headers); - console.log(CREDS_CREATION_WARNING); + return resp; + } + + /** + * Derives an existing API key for a user + * @param nonce + * @returns ApiKeyCreds + */ + public async deriveApiKey(nonce?: number): Promise { + this.canL1Auth(); + + const endpoint = `${this.host}${DERIVE_API_KEY}`; + const headers = await createL1Headers(this.signer as Wallet | JsonRpcSigner, nonce); + const resp = await get(endpoint, headers); return resp; } diff --git a/src/endpoints.ts b/src/endpoints.ts index 9816cd5..ecf9a43 100644 --- a/src/endpoints.ts +++ b/src/endpoints.ts @@ -12,6 +12,8 @@ export const GET_API_KEYS = "/get-api-keys"; export const DELETE_API_KEY = "/delete-api-key"; +export const DERIVE_API_KEY = "/derive-api-key"; + export const TRADE_HISTORY = "/trade-history"; export const ORDER_HISTORY = "/order-history"; diff --git a/src/headers/index.ts b/src/headers/index.ts index e0a207a..eb21e7d 100644 --- a/src/headers/index.ts +++ b/src/headers/index.ts @@ -3,15 +3,21 @@ import { Wallet } from "@ethersproject/wallet"; import { buildClobEip712Signature, buildPolyHmacSignature } from "../signing"; import { ApiKeyCreds, L1PolyHeader, L2HeaderArgs, L2PolyHeader } from "../types"; -export const createL1Headers = async (signer: Wallet | JsonRpcSigner): Promise => { +export const createL1Headers = async (signer: Wallet | JsonRpcSigner, nonce?: number): Promise => { const now = Math.floor(Date.now() / 1000); - const sig = await buildClobEip712Signature(signer, now); + let n = 0; // Default nonce is 0 + if (nonce !== undefined) { + n = nonce; + } + + const sig = await buildClobEip712Signature(signer, now, n); const address = await signer.getAddress(); const headers = { POLY_ADDRESS: address, POLY_SIGNATURE: sig, POLY_TIMESTAMP: `${now}`, + POLY_NONCE: `${n}`, }; return headers; }; diff --git a/src/signing/eip712.ts b/src/signing/eip712.ts index a901672..e7a43b1 100644 --- a/src/signing/eip712.ts +++ b/src/signing/eip712.ts @@ -9,7 +9,11 @@ import { MSG_TO_SIGN } from "./constants"; * @param ts * @returns string */ -export const buildClobEip712Signature = async (signer: Wallet | JsonRpcSigner, timestamp: number): Promise => { +export const buildClobEip712Signature = async ( + signer: Wallet | JsonRpcSigner, + timestamp: number, + nonce: number, +): Promise => { const address = await signer.getAddress(); const chainID = await signer.getChainId(); const ts = `${timestamp}`; @@ -24,12 +28,14 @@ export const buildClobEip712Signature = async (signer: Wallet | JsonRpcSigner, t ClobAuth: [ { name: "address", type: "address" }, { name: "timestamp", type: "string" }, + { name: "nonce", type: "uint256" }, { name: "message", type: "string" }, ], }; const value = { address, timestamp: ts, + nonce, message: MSG_TO_SIGN, }; // eslint-disable-next-line no-underscore-dangle diff --git a/src/types.ts b/src/types.ts index ca680d6..8c3430b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -17,6 +17,7 @@ export interface L1PolyHeader { POLY_ADDRESS: string; POLY_SIGNATURE: string; POLY_TIMESTAMP: string; + POLY_NONCE: string; } // API key verification