import {z} from 'zod' export type TradeState = 'TRADE_STATE_NEW' | 'TRADE_STATE_CLEARED' | 'TRADE_STATE_BUSTED' | 'TRADE_STATE_INFLIGHT' | 'TRADE_STATE_PENDING_RISK' | 'TRADE_STATE_PENDING_CLEARED' | 'TRADE_STATE_REJECTED' | 'TRADE_STATE_CLEARING_ACKNOWLEDGED' | 'TRADE_STATE_RETRY_REQUEST'; export type SearchTradesRequest = {pageSize?: number | undefined, pageToken?: string | undefined, orderId?: string | undefined, tradeId?: string | undefined, execId?: string | undefined, startTime?: string | undefined, endTime?: string | undefined, symbol?: string | undefined, accounts?: Array | undefined, states?: Array | undefined, tradeLinkId?: string | undefined}; export type CreateApiV1ReportTradesSearchArgs = {body: SearchTradesRequest}; export type CreateApiV1ReportTradesSearchOptions = {baseUrl?: string | undefined, XPMAccessKey?: string | undefined, XPMTimestamp?: string | undefined, XPMSignature?: string | undefined, fetch?: typeof fetch | undefined}; export const orderType = z.enum(["ORDER_TYPE_MARKET_TO_LIMIT", "ORDER_TYPE_LIMIT", "ORDER_TYPE_STOP", "ORDER_TYPE_STOP_LIMIT"]); export const side = z.enum(["SIDE_BUY", "SIDE_SELL"]); export const timeInForce = z.enum(["TIME_IN_FORCE_DAY", "TIME_IN_FORCE_GOOD_TILL_CANCEL", "TIME_IN_FORCE_IMMEDIATE_OR_CANCEL", "TIME_IN_FORCE_GOOD_TILL_TIME", "TIME_IN_FORCE_FILL_OR_KILL"]); export const orderState = z.enum(["ORDER_STATE_PARTIALLY_FILLED", "ORDER_STATE_FILLED", "ORDER_STATE_CANCELED", "ORDER_STATE_REPLACED", "ORDER_STATE_REJECTED", "ORDER_STATE_EXPIRED", "ORDER_STATE_PENDING_NEW", "ORDER_STATE_PENDING_REPLACE", "ORDER_STATE_PENDING_CANCEL", "ORDER_STATE_PENDING_RISK"]); export const selfMatchPreventionInstruction = z.enum(["SELF_MATCH_PREVENTION_INSTRUCTION_REJECT_AGGRESSOR", "SELF_MATCH_PREVENTION_INSTRUCTION_CANCEL_RESTING", "SELF_MATCH_PREVENTION_INSTRUCTION_REMOVE_BOTH"]); export const orderCapacity = z.enum(["ORDER_CAPACITY_AGENCY", "ORDER_CAPACITY_PRINCIPAL", "ORDER_CAPACITY_PROPRIETARY", "ORDER_CAPACITY_INDIVIDUAL", "ORDER_CAPACITY_RISKLESS_PRINCIPAL", "ORDER_CAPACITY_AGENT_FOR_OTHER_MEMBER"]); export const manualOrderIndicator = z.enum(["MANUAL_ORDER_INDICATOR_MANUAL", "MANUAL_ORDER_INDICATOR_AUTOMATED"]); export const order = z.object({id: z.string().optional(), type: orderType.optional(), side: side.optional(), orderQty: z.string().optional(), symbol: z.string().optional(), clordId: z.string().optional(), timeInForce: timeInForce.optional(), account: z.string().optional(), cumQty: z.string().optional(), avgPx: z.string().optional(), leavesQty: z.string().optional(), state: orderState.optional(), participant: z.string().optional(), price: z.string().optional(), insertTime: z.string().optional(), stopPrice: z.string().optional(), minQty: z.string().optional(), createTime: z.string().optional(), allOrNone: z.boolean().optional(), crossId: z.string().optional(), hostCrossId: z.string().optional(), submittingParticipant: z.string().optional(), clientAccountId: z.string().optional(), clientParticipantId: z.string().optional(), parentOrderId: z.string().optional(), commissionsBasisPoints: z.string().optional(), participateDontInitiate: z.boolean().optional(), cashOrderQty: z.string().optional(), strictLimit: z.boolean().optional(), goodTillTime: z.string().optional(), bestLimit: z.boolean().optional(), immediatelyExecutableLimit: z.boolean().optional(), lastTradeId: z.string().optional(), commissionNotionalTotalCollected: z.string().optional(), selfMatchPreventionInstruction: selfMatchPreventionInstruction.optional(), orderCapacity: orderCapacity.optional(), ignorePriceValidityChecks: z.boolean().optional(), lastTransactTime: z.string().optional(), makerCommissionsBasisPoints: z.string().optional(), manualOrderIndicator: manualOrderIndicator.optional(), fractionalQuantityScale: z.string().optional(), priceToQuantityFilled: z.record(z.string(), z.string()).optional()}); export const executionType = z.enum(["EXECUTION_TYPE_PARTIAL_FILL", "EXECUTION_TYPE_FILL", "EXECUTION_TYPE_CANCELED", "EXECUTION_TYPE_REPLACE", "EXECUTION_TYPE_REJECTED", "EXECUTION_TYPE_EXPIRED", "EXECUTION_TYPE_DONE_FOR_DAY"]); export const ordRejectReason = z.enum(["ORD_REJECT_REASON_UNKNOWN_SYMBOL", "ORD_REJECT_REASON_EXCHANGE_CLOSED", "ORD_REJECT_REASON_INCORRECT_QUANTITY", "ORD_REJECT_REASON_INVALID_PRICE_INCREMENT", "ORD_REJECT_REASON_INCORRECT_ORDER_TYPE", "ORD_REJECT_REASON_PRICE_OUT_OF_BOUNDS", "ORD_REJECT_REASON_NO_LIQUIDITY"]); export const legPrice = z.object({symbol: z.string().optional(), anchor: z.boolean().optional(), px: z.string().optional(), qty: z.string().optional(), side: z.string().optional(), referencePx: z.string().optional()}); export const unsolicitedCxlReason = z.enum(["UNSOLICITED_CXL_REASON_CONNECTION_LOSS", "UNSOLICITED_CXL_REASON_LOGOUT", "UNSOLICITED_CXL_REASON_EXCHANGE_OPTION", "UNSOLICITED_CXL_REASON_OTHER"]); export const date = z.object({year: z.number().int().optional(), month: z.number().int().optional(), day: z.number().int().optional()}); export const execution = z.object({id: z.string().optional(), order: order.optional(), lastShares: z.string().optional(), lastPx: z.string().optional(), type: executionType.optional(), text: z.string().optional(), orderRejectReason: ordRejectReason.optional(), transactTime: z.string().optional(), legPrices: z.array(legPrice).optional(), tradeId: z.string().optional(), aggressor: z.boolean().optional(), commissionNotionalCollected: z.string().optional(), unsolicitedCancelReason: unsolicitedCxlReason.optional(), traceId: z.string().optional(), commissionSpreadPx: z.string().optional(), transactTradeDate: date.optional()}); export const tradeType = z.enum(["TRADE_TYPE_REGULAR", "TRADE_TYPE_REQUEST_FOR_QUOTE", "TRADE_TYPE_BLOCK", "TRADE_TYPE_CROSS"]); export const tradeState = z.enum(["TRADE_STATE_NEW", "TRADE_STATE_CLEARED", "TRADE_STATE_BUSTED", "TRADE_STATE_INFLIGHT", "TRADE_STATE_PENDING_RISK", "TRADE_STATE_PENDING_CLEARED", "TRADE_STATE_REJECTED", "TRADE_STATE_CLEARING_ACKNOWLEDGED", "TRADE_STATE_RETRY_REQUEST"]); export const trade = z.object({id: z.string().optional(), aggressor: execution.optional(), passive: execution.optional(), tradeType: tradeType.optional(), state: tradeState.optional(), reportingCounterparty: side.optional(), text: z.string().optional(), tradeLinkId: z.string().optional(), metadata: z.record(z.string(), z.string()).optional()}); export const searchTradesResponse = z.object({trade: z.array(trade).optional(), nextPageToken: z.string().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Search trades * * POST /v1/report/trades/search */ export const createApiV1ReportTradesSearch = async (args: CreateApiV1ReportTradesSearchArgs, options?: CreateApiV1ReportTradesSearchOptions) => { const {baseUrl = "https://api.polymarket.us", fetch: fetchFn = fetch, XPMAccessKey, XPMTimestamp, XPMSignature} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (XPMAccessKey !== undefined) headers.set("X-PM-Access-Key", XPMAccessKey) if (XPMTimestamp !== undefined) headers.set("X-PM-Timestamp", XPMTimestamp) if (XPMSignature !== undefined) headers.set("X-PM-Signature", XPMSignature) const url = `${baseUrl.replace(/\/+$/, '')}/v1/report/trades/search${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(searchTradesResponse, await res.json()) };