package polymarket

  1. Overview
  2. Docs
OCaml client library for the Polymarket prediction market API

Install

dune-project
 Dependency

Authors

Maintainers

Sources

0.2.0.tar.gz
md5=4eb4c5d2f63ff081c9713d90be5a51b2
sha512=0e3de0c9b40683e09ab8f9f966a44784ef1b9b482c3eefef84104a7e8042c92f1d79893ee9588b24fa3d0decaed7f365509f4d1c23c66ce8328efb64e721f276

doc/src/polymarket.clob/types.ml.html

Source file types.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
(** CLOB API types for Polymarket.

    These types correspond to the Polymarket CLOB API
    (https://clob.polymarket.com). *)

open Ppx_yojson_conv_lib.Yojson_conv.Primitives

(** {1 Primitive Types} *)

type address = string [@@deriving yojson, show, eq]
(** Ethereum address (0x-prefixed, 40 hex chars). *)

type signature = string [@@deriving yojson, show, eq]
(** Hex-encoded signature (0x-prefixed). *)

type token_id = string [@@deriving yojson, show, eq]
(** ERC1155 token ID. *)

(** {1 Validation Errors} *)

exception Invalid_address of string
exception Invalid_signature of string

(** {1 Enum Modules} *)

module Side = Polymarket_common.Primitives.Side
(** Re-export shared Side module from Common.Primitives *)

(** Gtc: Good Till Cancelled, Gtd: Good Till Date, Fok: Fill or Kill, Fak: Fill
    and Kill *)
module Order_type = struct
  type t = Gtc | Gtd | Fok | Fak [@@deriving enum]
end

module Interval = struct
  type t =
    | Min_1 [@value "1m"]
    | Min_5 [@value "5m"]
    | Min_15 [@value "15m"]
    | Hour_1 [@value "1h"]
    | Hour_6 [@value "6h"]
    | Day_1 [@value "1d"]
    | Week_1 [@value "1w"]
    | Max [@value "max"]
  [@@deriving enum]
end

module Status = struct
  type t = Live | Matched | Delayed | Unmatched | Cancelled | Expired
  [@@deriving enum]
end

(** Eoa: EIP712 from externally owned account (0), Poly_proxy: EIP712 from
    Polymarket proxy wallet signer (1), Poly_gnosis_safe: EIP712 from Polymarket
    Gnosis Safe signer (2) *)
module Signature_type = struct
  type t = Eoa | Poly_proxy | Poly_gnosis_safe

  let to_int = function Eoa -> 0 | Poly_proxy -> 1 | Poly_gnosis_safe -> 2

  let of_int_opt = function
    | 0 -> Some Eoa
    | 1 -> Some Poly_proxy
    | 2 -> Some Poly_gnosis_safe
    | _ -> None

  let of_int n =
    match of_int_opt n with
    | Some v -> v
    | None -> failwith (Printf.sprintf "Unknown Signature_type: %d" n)

  let t_of_yojson = function
    | `Int n -> of_int n
    | `String s -> (
        match int_of_string_opt s with
        | Some n -> of_int n
        | None -> failwith ("Expected int for Signature_type, got: " ^ s))
    | _ -> failwith "Expected int for Signature_type"

  let yojson_of_t t = `Int (to_int t)
  let pp fmt t = Format.fprintf fmt "%d" (to_int t)
  let equal a b = Int.equal (to_int a) (to_int b)
end

module Trade_type = struct
  type t = Taker | Maker [@@deriving enum]
end

(** {1 Order Book Types} *)

type order_book_level = {
  price : string option; [@yojson.option]
  size : string option; [@yojson.option]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Order book price level with price and size *)

type order_book_summary = {
  market : string option; [@yojson.option]
  asset_id : string option; [@yojson.option] [@key "asset_id"]
  timestamp : string option; [@yojson.option]
  hash : string option; [@yojson.option]
  bids : order_book_level list; [@default []]
  asks : order_book_level list; [@default []]
  min_order_size : string option; [@yojson.option] [@key "min_order_size"]
  tick_size : string option; [@yojson.option] [@key "tick_size"]
  neg_risk : bool option; [@yojson.option] [@key "neg_risk"]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Order book summary for a token *)

(** {1 Signed Order Types} *)

type signed_order = {
  salt : string option; [@yojson.option]
  maker : address option; [@yojson.option]
  signer : address option; [@yojson.option]
  taker : address option; [@yojson.option]
  token_id : token_id option; [@yojson.option] [@key "tokenId"]
  maker_amount : string option; [@yojson.option] [@key "makerAmount"]
  taker_amount : string option; [@yojson.option] [@key "takerAmount"]
  expiration : string option; [@yojson.option]
  nonce : string option; [@yojson.option]
  fee_rate_bps : string option; [@yojson.option] [@key "feeRateBps"]
  side : Side.t option; [@yojson.option]
  signature_type : Signature_type.t option;
      [@yojson.option] [@key "signatureType"]
  signature : signature option; [@yojson.option]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Cryptographically signed order for the CLOB *)

type order_request = {
  order : signed_order option; [@yojson.option]
  owner : string option; [@yojson.option]
  order_type : Order_type.t option; [@yojson.option] [@key "orderType"]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Request body for creating an order *)

type create_order_response = {
  success : bool option; [@yojson.option]
  error_msg : string option; [@yojson.option] [@key "errorMsg"]
  order_id : string option; [@yojson.option] [@key "orderId"]
  order_hashes : string list; [@default []] [@key "orderHashes"]
  status : Status.t option; [@yojson.option]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Response from creating an order *)

(** {1 Open Order Types} *)

type open_order = {
  id : string option; [@yojson.option]
  status : Status.t option; [@yojson.option]
  market : string option; [@yojson.option]
  asset_id : token_id option; [@yojson.option] [@key "asset_id"]
  original_size : string option; [@yojson.option] [@key "original_size"]
  size_matched : string option; [@yojson.option] [@key "size_matched"]
  price : string option; [@yojson.option]
  side : Side.t option; [@yojson.option]
  outcome : string option; [@yojson.option]
  maker_address : address option; [@yojson.option] [@key "maker_address"]
  owner : string option; [@yojson.option]
  expiration : string option; [@yojson.option]
  order_type : Order_type.t option; [@yojson.option] [@key "type"]
  created_at : string option; [@yojson.option] [@key "created_at"]
  associate_trades : string list; [@default []] [@key "associate_trades"]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** An open/active order *)

(** {1 Cancel Types} *)

type cancel_response = {
  canceled : string list; [@default []]
  not_canceled : (string * string) list; [@default []] [@key "not_canceled"]
}
[@@deriving show, eq]
(** Response from canceling orders *)

(** Custom JSON handling for cancel_response due to map structure *)
let cancel_response_of_yojson json =
  match json with
  | `Assoc fields ->
      let canceled =
        match List.assoc_opt "canceled" fields with
        | Some (`List items) ->
            List.filter_map (function `String s -> Some s | _ -> None) items
        | _ -> []
      in
      let not_canceled =
        match List.assoc_opt "not_canceled" fields with
        | Some (`Assoc pairs) ->
            List.filter_map
              (fun (k, v) ->
                match v with `String s -> Some (k, s) | _ -> None)
              pairs
        | _ -> []
      in
      { canceled; not_canceled }
  | _ -> failwith "cancel_response_of_yojson: expected object"

let yojson_of_cancel_response resp =
  `Assoc
    [
      ("canceled", `List (List.map (fun s -> `String s) resp.canceled));
      ( "not_canceled",
        `Assoc (List.map (fun (k, v) -> (k, `String v)) resp.not_canceled) );
    ]

(** {1 Trade Types} *)

type maker_order_fill = {
  order_id : string option; [@yojson.option] [@key "order_id"]
  maker_address : address option; [@yojson.option] [@key "maker_address"]
  owner : string option; [@yojson.option]
  matched_amount : string option; [@yojson.option] [@key "matched_amount"]
  fee_rate_bps : string option; [@yojson.option] [@key "fee_rate_bps"]
  price : string option; [@yojson.option]
  asset_id : token_id option; [@yojson.option] [@key "asset_id"]
  outcome : string option; [@yojson.option]
  side : Side.t option; [@yojson.option]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Maker order that was filled in a trade *)

type clob_trade = {
  id : string option; [@yojson.option]
  taker_order_id : string option; [@yojson.option] [@key "taker_order_id"]
  market : string option; [@yojson.option]
  asset_id : token_id option; [@yojson.option] [@key "asset_id"]
  side : Side.t option; [@yojson.option]
  size : string option; [@yojson.option]
  fee_rate_bps : string option; [@yojson.option] [@key "fee_rate_bps"]
  price : string option; [@yojson.option]
  status : string option; [@yojson.option]
  match_time : string option; [@yojson.option] [@key "match_time"]
  last_update : string option; [@yojson.option] [@key "last_update"]
  outcome : string option; [@yojson.option]
  maker_address : address option; [@yojson.option] [@key "maker_address"]
  owner : string option; [@yojson.option]
  transaction_hash : string option; [@yojson.option] [@key "transaction_hash"]
  bucket_index : int option; [@yojson.option] [@key "bucket_index"]
  maker_orders : maker_order_fill list; [@default []] [@key "maker_orders"]
  trade_type : Trade_type.t option; [@yojson.option] [@key "type"]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** A trade on the CLOB *)

(** {1 Price Types} *)

type price_response = { price : string option [@yojson.option] }
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Response from get price endpoint *)

type midpoint_response = { mid : string option [@yojson.option] }
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Response from get midpoint endpoint *)

type token_price = {
  buy : string option; [@yojson.option] [@key "BUY"]
  sell : string option; [@yojson.option] [@key "SELL"]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Token prices for buy and sell sides *)

type prices_response = (token_id * token_price) list [@@deriving show, eq]
(** prices_response is a map from token_id to token_price *)

let prices_response_of_yojson = function
  | `Assoc pairs ->
      List.map (fun (token_id, v) -> (token_id, token_price_of_yojson v)) pairs
  | _ -> failwith "prices_response_of_yojson: expected object"

let yojson_of_prices_response resp =
  `Assoc (List.map (fun (tid, tp) -> (tid, yojson_of_token_price tp)) resp)

type spreads_response = (token_id * string) list [@@deriving show, eq]
(** spreads_response is a map from token_id to spread value *)

let spreads_response_of_yojson = function
  | `Assoc pairs ->
      List.filter_map
        (fun (token_id, v) ->
          match v with `String s -> Some (token_id, s) | _ -> None)
        pairs
  | _ -> failwith "spreads_response_of_yojson: expected object"

let yojson_of_spreads_response resp =
  `Assoc (List.map (fun (tid, s) -> (tid, `String s)) resp)

(** {1 Timeseries Types} *)

type price_point = {
  t : int64 option; [@yojson.option]
  p : float option; [@yojson.option]
}
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Single price point with timestamp and price *)

type price_history = { history : price_point list [@default []] }
[@@yojson.allow_extra_fields] [@@deriving yojson, show, eq, yojson_fields]
(** Historical price data *)

(** {1 Error Response} *)

type error = Polymarket_http.Client.error
(** Structured error type for all API errors *)

let error_to_string = Polymarket_http.Client.error_to_string
let pp_error = Polymarket_http.Client.pp_error

(** {1 Validation Functions}

    These functions delegate to Polymarket_common.Primitives for validation
    logic. This ensures a single source of truth for validation rules. *)

(** Validates an address string (0x-prefixed, 40 hex chars). *)
let is_valid_address s =
  match Polymarket_common.Primitives.Address.make s with
  | Ok _ -> true
  | Error _ -> false

(** Validates a hex signature string (0x-prefixed). *)
let is_valid_signature s =
  match Polymarket_common.Primitives.Hash.make s with
  | Ok _ -> true
  | Error _ -> false

(** {1 Validating Deserializers} *)

(** Deserialize an address with validation.
    @raise Invalid_address if the address doesn't match the expected pattern *)
let address_of_yojson_exn json =
  let addr = address_of_yojson json in
  if is_valid_address addr then addr else raise (Invalid_address addr)

(** Deserialize a signature with validation.
    @raise Invalid_signature if the signature is invalid *)
let signature_of_yojson_exn json =
  let sig_ = signature_of_yojson json in
  if is_valid_signature sig_ then sig_ else raise (Invalid_signature sig_)

(** Deserialize an address with validation, returning a result. *)
let address_of_yojson_result json =
  try
    let addr = address_of_yojson json in
    if is_valid_address addr then Ok addr
    else Error ("Invalid address format: " ^ addr)
  with Ppx_yojson_conv_lib.Yojson_conv.Of_yojson_error (exn, _) ->
    Error ("JSON parse error: " ^ Printexc.to_string exn)

(** Deserialize a signature with validation, returning a result. *)
let signature_of_yojson_result json =
  try
    let sig_ = signature_of_yojson json in
    if is_valid_signature sig_ then Ok sig_
    else Error ("Invalid signature format: " ^ sig_)
  with Ppx_yojson_conv_lib.Yojson_conv.Of_yojson_error (exn, _) ->
    Error ("JSON parse error: " ^ Printexc.to_string exn)