polymarket-apis 0.2.6__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of polymarket-apis might be problematic. Click here for more details.
- polymarket_apis/__init__.py +41 -2
- polymarket_apis/clients/__init__.py +23 -0
- polymarket_apis/clients/clob_client.py +184 -88
- polymarket_apis/clients/data_client.py +90 -65
- polymarket_apis/clients/gamma_client.py +96 -75
- polymarket_apis/clients/graphql_client.py +60 -0
- polymarket_apis/clients/web3_client.py +132 -60
- polymarket_apis/clients/websockets_client.py +25 -9
- polymarket_apis/types/__init__.py +195 -0
- polymarket_apis/types/clob_types.py +30 -10
- polymarket_apis/types/common.py +5 -3
- polymarket_apis/types/data_types.py +6 -3
- polymarket_apis/types/gamma_types.py +27 -8
- polymarket_apis/types/websockets_types.py +109 -30
- polymarket_apis/utilities/config.py +1 -0
- polymarket_apis/utilities/exceptions.py +5 -0
- polymarket_apis/utilities/order_builder/builder.py +32 -14
- polymarket_apis/utilities/order_builder/helpers.py +13 -12
- polymarket_apis/utilities/signing/hmac.py +5 -1
- polymarket_apis/utilities/web3/abis/custom_contract_errors.py +1 -1
- polymarket_apis/utilities/web3/helpers.py +1 -0
- polymarket_apis-0.3.1.dist-info/METADATA +164 -0
- polymarket_apis-0.3.1.dist-info/RECORD +41 -0
- polymarket_apis-0.2.6.dist-info/METADATA +0 -18
- polymarket_apis-0.2.6.dist-info/RECORD +0 -40
- {polymarket_apis-0.2.6.dist-info → polymarket_apis-0.3.1.dist-info}/WHEEL +0 -0
polymarket_apis/__init__.py
CHANGED
|
@@ -1,2 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"""
|
|
2
|
+
Polymarket APIs - Unified interface for Polymarket's various APIs.
|
|
3
|
+
|
|
4
|
+
This package provides a comprehensive interface to Polymarket's APIs including:
|
|
5
|
+
- CLOB (Central Limit Order Book) API for trading
|
|
6
|
+
- Gamma API for event and market information
|
|
7
|
+
- Data API for user information
|
|
8
|
+
- Web3 API for blockchain interactions
|
|
9
|
+
- WebSocket API for real-time data streams
|
|
10
|
+
- GraphQL API for flexible data queries
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__version__ = "0.3.1"
|
|
14
|
+
__author__ = "Razvan Gheorghe"
|
|
15
|
+
__email__ = "razvan@gheorghe.me"
|
|
16
|
+
|
|
17
|
+
from .clients import (
|
|
18
|
+
AsyncPolymarketGraphQLClient,
|
|
19
|
+
PolymarketClobClient,
|
|
20
|
+
PolymarketDataClient,
|
|
21
|
+
PolymarketGammaClient,
|
|
22
|
+
PolymarketGraphQLClient,
|
|
23
|
+
PolymarketWeb3Client,
|
|
24
|
+
PolymarketWebsocketsClient,
|
|
25
|
+
)
|
|
26
|
+
from .types.clob_types import MarketOrderArgs, OrderArgs
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"AsyncPolymarketGraphQLClient",
|
|
30
|
+
"MarketOrderArgs",
|
|
31
|
+
"OrderArgs",
|
|
32
|
+
"PolymarketClobClient",
|
|
33
|
+
"PolymarketDataClient",
|
|
34
|
+
"PolymarketGammaClient",
|
|
35
|
+
"PolymarketGraphQLClient",
|
|
36
|
+
"PolymarketWeb3Client",
|
|
37
|
+
"PolymarketWebsocketsClient",
|
|
38
|
+
"__author__",
|
|
39
|
+
"__email__",
|
|
40
|
+
"__version__",
|
|
41
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Client modules for Polymarket APIs.
|
|
3
|
+
|
|
4
|
+
This module contains all the client classes for interacting with different
|
|
5
|
+
Polymarket APIs including CLOB, Data, Gamma, GraphQL, Web3, and WebSocket clients.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .clob_client import PolymarketClobClient
|
|
9
|
+
from .data_client import PolymarketDataClient
|
|
10
|
+
from .gamma_client import PolymarketGammaClient
|
|
11
|
+
from .graphql_client import AsyncPolymarketGraphQLClient, PolymarketGraphQLClient
|
|
12
|
+
from .web3_client import PolymarketWeb3Client
|
|
13
|
+
from .websockets_client import PolymarketWebsocketsClient
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"AsyncPolymarketGraphQLClient",
|
|
17
|
+
"PolymarketClobClient",
|
|
18
|
+
"PolymarketDataClient",
|
|
19
|
+
"PolymarketGammaClient",
|
|
20
|
+
"PolymarketGraphQLClient",
|
|
21
|
+
"PolymarketWeb3Client",
|
|
22
|
+
"PolymarketWebsocketsClient",
|
|
23
|
+
]
|
|
@@ -16,6 +16,7 @@ from ..types.clob_types import (
|
|
|
16
16
|
CreateOrderOptions,
|
|
17
17
|
DailyEarnedReward,
|
|
18
18
|
MarketOrderArgs,
|
|
19
|
+
MarketRewards,
|
|
19
20
|
Midpoint,
|
|
20
21
|
OpenOrder,
|
|
21
22
|
OrderArgs,
|
|
@@ -26,12 +27,11 @@ from ..types.clob_types import (
|
|
|
26
27
|
PaginatedResponse,
|
|
27
28
|
PartialCreateOrderOptions,
|
|
28
29
|
PolygonTrade,
|
|
29
|
-
PolymarketRewardItem,
|
|
30
30
|
PostOrdersArgs,
|
|
31
31
|
Price,
|
|
32
32
|
PriceHistory,
|
|
33
33
|
RequestArgs,
|
|
34
|
-
|
|
34
|
+
RewardMarket,
|
|
35
35
|
Spread,
|
|
36
36
|
TickSize,
|
|
37
37
|
TokenBidAskDict,
|
|
@@ -88,15 +88,16 @@ from ..utilities.signing.signer import Signer
|
|
|
88
88
|
|
|
89
89
|
logger = logging.getLogger(__name__)
|
|
90
90
|
|
|
91
|
+
|
|
91
92
|
class PolymarketClobClient:
|
|
92
93
|
def __init__(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
self,
|
|
95
|
+
private_key: str,
|
|
96
|
+
proxy_address: EthAddress,
|
|
97
|
+
creds: Optional[ApiCreds] = None,
|
|
98
|
+
chain_id: Literal[137, 80002] = POLYGON,
|
|
99
|
+
signature_type: Literal[0, 1, 2] = 1,
|
|
100
|
+
# 0 - EOA wallet, 1 - Proxy wallet, 2 - Gnosis Safe wallet
|
|
100
101
|
):
|
|
101
102
|
self.proxy_address = proxy_address
|
|
102
103
|
self.client = httpx.Client(http2=True, timeout=30.0)
|
|
@@ -199,7 +200,9 @@ class PolymarketClobClient:
|
|
|
199
200
|
return fee_rate
|
|
200
201
|
|
|
201
202
|
def __resolve_tick_size(
|
|
202
|
-
|
|
203
|
+
self,
|
|
204
|
+
token_id: str,
|
|
205
|
+
tick_size: TickSize = None,
|
|
203
206
|
) -> TickSize:
|
|
204
207
|
min_tick_size = self.get_tick_size(token_id)
|
|
205
208
|
if tick_size is not None:
|
|
@@ -211,12 +214,19 @@ class PolymarketClobClient:
|
|
|
211
214
|
return tick_size
|
|
212
215
|
|
|
213
216
|
def __resolve_fee_rate(
|
|
214
|
-
|
|
217
|
+
self,
|
|
218
|
+
token_id: str,
|
|
219
|
+
user_fee_rate: Optional[int] = None,
|
|
215
220
|
) -> int:
|
|
216
221
|
market_fee_rate_bps = self.get_fee_rate_bps(token_id)
|
|
217
222
|
# If both fee rate on the market and the user supplied fee rate are non-zero, validate that they match
|
|
218
223
|
# else return the market fee rate
|
|
219
|
-
if
|
|
224
|
+
if (
|
|
225
|
+
market_fee_rate_bps > 0
|
|
226
|
+
and user_fee_rate is not None
|
|
227
|
+
and user_fee_rate > 0
|
|
228
|
+
and user_fee_rate != market_fee_rate_bps
|
|
229
|
+
):
|
|
220
230
|
msg = f"invalid user provided fee rate: ({user_fee_rate}), fee rate for the market must be {market_fee_rate_bps}"
|
|
221
231
|
raise InvalidFeeRateError(msg)
|
|
222
232
|
return market_fee_rate_bps
|
|
@@ -291,10 +301,14 @@ class PolymarketClobClient:
|
|
|
291
301
|
response.raise_for_status()
|
|
292
302
|
return [OrderBookSummary(**obs) for obs in response.json()]
|
|
293
303
|
|
|
294
|
-
async def get_order_books_async(
|
|
304
|
+
async def get_order_books_async(
|
|
305
|
+
self, token_ids: list[str]
|
|
306
|
+
) -> list[OrderBookSummary]:
|
|
295
307
|
"""Get the orderbook for a set of tokens asynchronously."""
|
|
296
308
|
body = [{"token_id": token_id} for token_id in token_ids]
|
|
297
|
-
response = await self.async_client.post(
|
|
309
|
+
response = await self.async_client.post(
|
|
310
|
+
self._build_url(GET_ORDER_BOOKS), json=body
|
|
311
|
+
)
|
|
298
312
|
response.raise_for_status()
|
|
299
313
|
return [OrderBookSummary(**obs) for obs in response.json()]
|
|
300
314
|
|
|
@@ -304,7 +318,7 @@ class PolymarketClobClient:
|
|
|
304
318
|
response.raise_for_status()
|
|
305
319
|
return ClobMarket(**response.json())
|
|
306
320
|
|
|
307
|
-
def get_markets(self, next_cursor="MA==")
|
|
321
|
+
def get_markets(self, next_cursor="MA==") -> PaginatedResponse[ClobMarket]:
|
|
308
322
|
"""Get paginated ClobMarkets."""
|
|
309
323
|
params = {"next_cursor": next_cursor}
|
|
310
324
|
response = self.client.get(self._build_url(GET_MARKETS), params=params)
|
|
@@ -333,10 +347,10 @@ class PolymarketClobClient:
|
|
|
333
347
|
return current_markets + next_page_markets
|
|
334
348
|
|
|
335
349
|
def get_recent_history(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
350
|
+
self,
|
|
351
|
+
token_id: str,
|
|
352
|
+
interval: Optional[Literal["1d", "6h", "1h"]] = "1d",
|
|
353
|
+
fidelity: int = 1, # resolution in minutes
|
|
340
354
|
) -> PriceHistory:
|
|
341
355
|
"""Get the recent price history of a token (up to now) - 1h, 6h, 1d."""
|
|
342
356
|
if fidelity < 1:
|
|
@@ -353,17 +367,17 @@ class PolymarketClobClient:
|
|
|
353
367
|
return PriceHistory(**response.json(), token_id=token_id)
|
|
354
368
|
|
|
355
369
|
def get_history(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
370
|
+
self,
|
|
371
|
+
token_id: str,
|
|
372
|
+
start_time: Optional[datetime] = None,
|
|
373
|
+
end_time: Optional[datetime] = None,
|
|
374
|
+
interval: Literal["max", "1m", "1w"] = "max",
|
|
375
|
+
fidelity: int = 2, # resolution in minutes
|
|
362
376
|
) -> PriceHistory:
|
|
363
377
|
"""Get the price history of a token between selected dates - 1m, 1w, max."""
|
|
364
|
-
min_fidelities = {"1m": 10, "1w": 5, "max": 2}
|
|
378
|
+
min_fidelities: dict[str, int] = {"1m": 10, "1w": 5, "max": 2}
|
|
365
379
|
|
|
366
|
-
if fidelity < min_fidelities[interval]:
|
|
380
|
+
if fidelity is None or fidelity < min_fidelities[interval]:
|
|
367
381
|
msg = f"invalid filters: minimum 'fidelity' for '{interval}' range is {min_fidelities[interval]}"
|
|
368
382
|
raise ValueError(msg)
|
|
369
383
|
|
|
@@ -389,7 +403,13 @@ class PolymarketClobClient:
|
|
|
389
403
|
response.raise_for_status()
|
|
390
404
|
return PriceHistory(**response.json(), token_id=token_id)
|
|
391
405
|
|
|
392
|
-
def get_orders(
|
|
406
|
+
def get_orders(
|
|
407
|
+
self,
|
|
408
|
+
order_id: Optional[str] = None,
|
|
409
|
+
condition_id: Optional[Keccak256] = None,
|
|
410
|
+
token_id: Optional[str] = None,
|
|
411
|
+
next_cursor: str = "MA==",
|
|
412
|
+
) -> list[OpenOrder]:
|
|
393
413
|
"""Gets your active orders, filtered by order_id, condition_id, token_id."""
|
|
394
414
|
params = {}
|
|
395
415
|
if order_id:
|
|
@@ -406,14 +426,18 @@ class PolymarketClobClient:
|
|
|
406
426
|
next_cursor = next_cursor if next_cursor is not None else "MA=="
|
|
407
427
|
while next_cursor != END_CURSOR:
|
|
408
428
|
params["next_cursor"] = next_cursor
|
|
409
|
-
response = self.client.get(
|
|
429
|
+
response = self.client.get(
|
|
430
|
+
self._build_url(ORDERS), headers=headers, params=params
|
|
431
|
+
)
|
|
410
432
|
response.raise_for_status()
|
|
411
433
|
next_cursor = response.json()["next_cursor"]
|
|
412
434
|
results += [OpenOrder(**order) for order in response.json()["data"]]
|
|
413
435
|
|
|
414
436
|
return results
|
|
415
437
|
|
|
416
|
-
def create_order(
|
|
438
|
+
def create_order(
|
|
439
|
+
self, order_args: OrderArgs, options: Optional[PartialCreateOrderOptions] = None
|
|
440
|
+
) -> SignedOrder:
|
|
417
441
|
"""Creates and signs an order."""
|
|
418
442
|
# add resolve_order_options, or similar
|
|
419
443
|
tick_size = self.__resolve_tick_size(
|
|
@@ -425,7 +449,6 @@ class PolymarketClobClient:
|
|
|
425
449
|
msg = f"price ({order_args.price}), min: {tick_size} - max: {1 - float(tick_size)}"
|
|
426
450
|
raise InvalidPriceError(msg)
|
|
427
451
|
|
|
428
|
-
|
|
429
452
|
neg_risk = (
|
|
430
453
|
options.neg_risk
|
|
431
454
|
if options and options.neg_risk
|
|
@@ -433,7 +456,9 @@ class PolymarketClobClient:
|
|
|
433
456
|
)
|
|
434
457
|
|
|
435
458
|
# fee rate
|
|
436
|
-
fee_rate_bps = self.__resolve_fee_rate(
|
|
459
|
+
fee_rate_bps = self.__resolve_fee_rate(
|
|
460
|
+
order_args.token_id, order_args.fee_rate_bps
|
|
461
|
+
)
|
|
437
462
|
order_args.fee_rate_bps = fee_rate_bps
|
|
438
463
|
|
|
439
464
|
return self.builder.create_order(
|
|
@@ -444,7 +469,9 @@ class PolymarketClobClient:
|
|
|
444
469
|
),
|
|
445
470
|
)
|
|
446
471
|
|
|
447
|
-
def post_order(
|
|
472
|
+
def post_order(
|
|
473
|
+
self, order: SignedOrder, order_type: OrderType = OrderType.GTC
|
|
474
|
+
) -> Optional[OrderPostResponse]:
|
|
448
475
|
"""Posts a SignedOrder."""
|
|
449
476
|
body = order_to_json(order, self.creds.key, order_type)
|
|
450
477
|
headers = create_level_2_headers(
|
|
@@ -467,19 +494,27 @@ class PolymarketClobClient:
|
|
|
467
494
|
error_json = exc.response.json()
|
|
468
495
|
print("Details:", error_json["error"])
|
|
469
496
|
|
|
470
|
-
def create_and_post_order(
|
|
497
|
+
def create_and_post_order(
|
|
498
|
+
self,
|
|
499
|
+
order_args: OrderArgs,
|
|
500
|
+
options: Optional[PartialCreateOrderOptions] = None,
|
|
501
|
+
order_type: OrderType = OrderType.GTC,
|
|
502
|
+
) -> OrderPostResponse:
|
|
471
503
|
"""Utility function to create and publish an order."""
|
|
472
504
|
order = self.create_order(order_args, options)
|
|
473
505
|
return self.post_order(order=order, order_type=order_type)
|
|
474
506
|
|
|
475
507
|
def post_orders(self, args: list[PostOrdersArgs]):
|
|
476
508
|
"""Posts multiple SignedOrders at once."""
|
|
477
|
-
body = [
|
|
509
|
+
body = [
|
|
510
|
+
order_to_json(arg.order, self.creds.key, arg.order_type) for arg in args
|
|
511
|
+
]
|
|
478
512
|
headers = create_level_2_headers(
|
|
479
513
|
self.signer,
|
|
480
514
|
self.creds,
|
|
481
515
|
RequestArgs(method="POST", request_path=POST_ORDERS, body=body),
|
|
482
516
|
)
|
|
517
|
+
|
|
483
518
|
try:
|
|
484
519
|
response = self.client.post(
|
|
485
520
|
self._build_url("/orders"),
|
|
@@ -492,8 +527,10 @@ class PolymarketClobClient:
|
|
|
492
527
|
resp = OrderPostResponse(**item)
|
|
493
528
|
order_responses.append(resp)
|
|
494
529
|
if resp.error_msg:
|
|
495
|
-
msg = (
|
|
496
|
-
|
|
530
|
+
msg = (
|
|
531
|
+
f"Error posting order in position {index} \n"
|
|
532
|
+
f"Details: {resp.error_msg}"
|
|
533
|
+
)
|
|
497
534
|
logger.warning(msg)
|
|
498
535
|
except httpx.HTTPStatusError as exc:
|
|
499
536
|
msg = f"Client Error '{exc.response.status_code} {exc.response.reason_phrase}' while posting order"
|
|
@@ -503,15 +540,22 @@ class PolymarketClobClient:
|
|
|
503
540
|
else:
|
|
504
541
|
return order_responses
|
|
505
542
|
|
|
506
|
-
def create_and_post_orders(
|
|
543
|
+
def create_and_post_orders(
|
|
544
|
+
self, args: list[OrderArgs], order_types: list[OrderType]
|
|
545
|
+
) -> list[OrderPostResponse]:
|
|
507
546
|
"""Utility function to create and publish multiple orders at once."""
|
|
508
547
|
return self.post_orders(
|
|
509
|
-
[
|
|
510
|
-
|
|
511
|
-
|
|
548
|
+
[
|
|
549
|
+
PostOrdersArgs(
|
|
550
|
+
order=self.create_order(order_args), order_type=order_type
|
|
551
|
+
)
|
|
552
|
+
for order_args, order_type in zip(args, order_types, strict=True)
|
|
553
|
+
],
|
|
512
554
|
)
|
|
513
555
|
|
|
514
|
-
def calculate_market_price(
|
|
556
|
+
def calculate_market_price(
|
|
557
|
+
self, token_id: str, side: str, amount: float, order_type: OrderType
|
|
558
|
+
) -> float:
|
|
515
559
|
"""Calculates the matching price considering an amount and the current orderbook."""
|
|
516
560
|
book = self.get_order_book(token_id)
|
|
517
561
|
if book is None:
|
|
@@ -522,16 +566,27 @@ class PolymarketClobClient:
|
|
|
522
566
|
msg = "No ask orders available"
|
|
523
567
|
raise LiquidityError(msg)
|
|
524
568
|
return self.builder.calculate_buy_market_price(
|
|
525
|
-
book.asks,
|
|
569
|
+
book.asks,
|
|
570
|
+
amount,
|
|
571
|
+
order_type,
|
|
526
572
|
)
|
|
527
|
-
if
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
573
|
+
if side == "SELL":
|
|
574
|
+
if book.bids is None:
|
|
575
|
+
msg = "No bid orders available"
|
|
576
|
+
raise LiquidityError(msg)
|
|
577
|
+
return self.builder.calculate_sell_market_price(
|
|
578
|
+
book.bids,
|
|
579
|
+
amount,
|
|
580
|
+
order_type,
|
|
581
|
+
)
|
|
582
|
+
msg = 'Side must be "BUY" or "SELL"'
|
|
583
|
+
raise ValueError(msg)
|
|
533
584
|
|
|
534
|
-
def create_market_order(
|
|
585
|
+
def create_market_order(
|
|
586
|
+
self,
|
|
587
|
+
order_args: MarketOrderArgs,
|
|
588
|
+
options: Optional[PartialCreateOrderOptions] = None,
|
|
589
|
+
):
|
|
535
590
|
"""Creates and signs a market order."""
|
|
536
591
|
tick_size = self.__resolve_tick_size(
|
|
537
592
|
order_args.token_id,
|
|
@@ -557,7 +612,9 @@ class PolymarketClobClient:
|
|
|
557
612
|
)
|
|
558
613
|
|
|
559
614
|
# fee rate
|
|
560
|
-
fee_rate_bps = self.__resolve_fee_rate(
|
|
615
|
+
fee_rate_bps = self.__resolve_fee_rate(
|
|
616
|
+
order_args.token_id, order_args.fee_rate_bps
|
|
617
|
+
)
|
|
561
618
|
order_args.fee_rate_bps = fee_rate_bps
|
|
562
619
|
|
|
563
620
|
return self.builder.create_market_order(
|
|
@@ -569,10 +626,10 @@ class PolymarketClobClient:
|
|
|
569
626
|
)
|
|
570
627
|
|
|
571
628
|
def create_and_post_market_order(
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
629
|
+
self,
|
|
630
|
+
order_args: MarketOrderArgs,
|
|
631
|
+
options: Optional[PartialCreateOrderOptions] = None,
|
|
632
|
+
order_type: OrderType = OrderType.FOK,
|
|
576
633
|
) -> OrderPostResponse:
|
|
577
634
|
"""Utility function to create and publish a market order."""
|
|
578
635
|
order = self.create_market_order(order_args, options)
|
|
@@ -585,7 +642,12 @@ class PolymarketClobClient:
|
|
|
585
642
|
request_args = RequestArgs(method="DELETE", request_path=CANCEL, body=body)
|
|
586
643
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
587
644
|
|
|
588
|
-
response = self.client.request(
|
|
645
|
+
response = self.client.request(
|
|
646
|
+
"DELETE",
|
|
647
|
+
self._build_url(CANCEL),
|
|
648
|
+
headers=headers,
|
|
649
|
+
data=json.dumps(body).encode("utf-8"),
|
|
650
|
+
)
|
|
589
651
|
response.raise_for_status()
|
|
590
652
|
return OrderCancelResponse(**response.json())
|
|
591
653
|
|
|
@@ -594,11 +656,18 @@ class PolymarketClobClient:
|
|
|
594
656
|
body = order_ids
|
|
595
657
|
|
|
596
658
|
request_args = RequestArgs(
|
|
597
|
-
method="DELETE",
|
|
659
|
+
method="DELETE",
|
|
660
|
+
request_path=CANCEL_ORDERS,
|
|
661
|
+
body=body,
|
|
598
662
|
)
|
|
599
663
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
600
664
|
|
|
601
|
-
response = self.client.request(
|
|
665
|
+
response = self.client.request(
|
|
666
|
+
"DELETE",
|
|
667
|
+
self._build_url(CANCEL_ORDERS),
|
|
668
|
+
headers=headers,
|
|
669
|
+
data=json.dumps(body).encode("utf-8"),
|
|
670
|
+
)
|
|
602
671
|
response.raise_for_status()
|
|
603
672
|
return OrderCancelResponse(**response.json())
|
|
604
673
|
|
|
@@ -616,7 +685,11 @@ class PolymarketClobClient:
|
|
|
616
685
|
request_args = RequestArgs(method="GET", request_path=IS_ORDER_SCORING)
|
|
617
686
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
618
687
|
|
|
619
|
-
response = self.client.get(
|
|
688
|
+
response = self.client.get(
|
|
689
|
+
self._build_url(IS_ORDER_SCORING),
|
|
690
|
+
headers=headers,
|
|
691
|
+
params={"order_id": order_id},
|
|
692
|
+
)
|
|
620
693
|
response.raise_for_status()
|
|
621
694
|
return response.json()["scoring"]
|
|
622
695
|
|
|
@@ -624,37 +697,44 @@ class PolymarketClobClient:
|
|
|
624
697
|
"""Check if the orders are currently scoring."""
|
|
625
698
|
body = order_ids
|
|
626
699
|
request_args = RequestArgs(
|
|
627
|
-
method="POST",
|
|
700
|
+
method="POST",
|
|
701
|
+
request_path=ARE_ORDERS_SCORING,
|
|
702
|
+
body=body,
|
|
628
703
|
)
|
|
629
704
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
630
705
|
headers["Content-Type"] = "application/json"
|
|
631
706
|
|
|
632
|
-
response = self.client.post(
|
|
707
|
+
response = self.client.post(
|
|
708
|
+
self._build_url(ARE_ORDERS_SCORING), headers=headers, json=body
|
|
709
|
+
)
|
|
633
710
|
response.raise_for_status()
|
|
634
711
|
return response.json()
|
|
635
712
|
|
|
636
|
-
def
|
|
713
|
+
def get_market_rewards(self, condition_id: Keccak256) -> MarketRewards:
|
|
637
714
|
"""
|
|
638
|
-
Get the
|
|
715
|
+
Get the MarketRewards for a given market (condition_id).
|
|
639
716
|
|
|
640
717
|
- metadata, tokens, max_spread, min_size, rewards_config, market_competitiveness.
|
|
641
718
|
"""
|
|
642
719
|
request_args = RequestArgs(method="GET", request_path="/rewards/markets/")
|
|
643
720
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
644
721
|
|
|
645
|
-
response = self.client.get(
|
|
722
|
+
response = self.client.get(
|
|
723
|
+
self._build_url("/rewards/markets/" + condition_id), headers=headers
|
|
724
|
+
)
|
|
646
725
|
response.raise_for_status()
|
|
647
|
-
return next(
|
|
726
|
+
return next(MarketRewards(**market) for market in response.json()["data"])
|
|
648
727
|
|
|
649
728
|
def get_trades(
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
729
|
+
self,
|
|
730
|
+
condition_id: Optional[Keccak256] = None,
|
|
731
|
+
token_id: Optional[str] = None,
|
|
732
|
+
trade_id: Optional[str] = None,
|
|
733
|
+
before: Optional[datetime] = None,
|
|
734
|
+
after: Optional[datetime] = None,
|
|
735
|
+
proxy_address: Optional[int] = None,
|
|
736
|
+
next_cursor="MA==",
|
|
737
|
+
) -> list[PolygonTrade]:
|
|
658
738
|
"""Fetches the trade history for a user."""
|
|
659
739
|
params = {}
|
|
660
740
|
if condition_id:
|
|
@@ -667,8 +747,8 @@ class PolymarketClobClient:
|
|
|
667
747
|
params["before"] = int(before.replace(microsecond=0).timestamp())
|
|
668
748
|
if after:
|
|
669
749
|
params["after"] = int(after.replace(microsecond=0).timestamp())
|
|
670
|
-
if
|
|
671
|
-
params["maker_address"] =
|
|
750
|
+
if proxy_address:
|
|
751
|
+
params["maker_address"] = proxy_address
|
|
672
752
|
|
|
673
753
|
request_args = RequestArgs(method="GET", request_path=TRADES)
|
|
674
754
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
@@ -677,7 +757,9 @@ class PolymarketClobClient:
|
|
|
677
757
|
next_cursor = next_cursor if next_cursor is not None else "MA=="
|
|
678
758
|
while next_cursor != END_CURSOR:
|
|
679
759
|
params["next_cursor"] = next_cursor
|
|
680
|
-
response =
|
|
760
|
+
response = self.client.get(
|
|
761
|
+
self._build_url(TRADES), headers=headers, params=params
|
|
762
|
+
)
|
|
681
763
|
response.raise_for_status()
|
|
682
764
|
next_cursor = response.json()["next_cursor"]
|
|
683
765
|
results += [PolygonTrade(**trade) for trade in response.json()["data"]]
|
|
@@ -690,14 +772,16 @@ class PolymarketClobClient:
|
|
|
690
772
|
date = datetime.now(UTC)
|
|
691
773
|
params = {
|
|
692
774
|
"authenticationType": "magic",
|
|
693
|
-
"date": f"{date.strftime(
|
|
775
|
+
"date": f"{date.strftime('%Y-%m-%d')}",
|
|
694
776
|
}
|
|
695
777
|
|
|
696
778
|
request_args = RequestArgs(method="GET", request_path="/rewards/user/total")
|
|
697
779
|
headers = create_level_2_headers(self.signer, self.creds, request_args)
|
|
698
780
|
params["l2Headers"] = json.dumps(headers)
|
|
699
781
|
|
|
700
|
-
response = self.client.get(
|
|
782
|
+
response = self.client.get(
|
|
783
|
+
"https://polymarket.com/api/rewards/totalEarnings", params=params
|
|
784
|
+
)
|
|
701
785
|
response.raise_for_status()
|
|
702
786
|
if response.json():
|
|
703
787
|
return DailyEarnedReward(**response.json()[0])
|
|
@@ -710,14 +794,25 @@ class PolymarketClobClient:
|
|
|
710
794
|
)
|
|
711
795
|
|
|
712
796
|
def get_reward_markets(
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
797
|
+
self,
|
|
798
|
+
query: Optional[str] = None,
|
|
799
|
+
sort_by: Optional[
|
|
800
|
+
Literal[
|
|
801
|
+
"market",
|
|
802
|
+
"max_spread",
|
|
803
|
+
"min_size",
|
|
804
|
+
"rate_per_day",
|
|
805
|
+
"spread",
|
|
806
|
+
"price",
|
|
807
|
+
"earnings",
|
|
808
|
+
"earning_percentage",
|
|
809
|
+
]
|
|
810
|
+
] = "market",
|
|
811
|
+
sort_direction: Optional[Literal["ASC", "DESC"]] = None,
|
|
812
|
+
show_favorites: bool = False,
|
|
813
|
+
) -> list[RewardMarket]:
|
|
719
814
|
"""
|
|
720
|
-
|
|
815
|
+
Search through markets that offer rewards (polymarket.com/rewards items) by query, sorted by different metrics. If query is empty, returns all markets with rewards.
|
|
721
816
|
|
|
722
817
|
- market start date ("market") - TODO confirm this
|
|
723
818
|
- max spread for rewards in usdc
|
|
@@ -749,11 +844,12 @@ class PolymarketClobClient:
|
|
|
749
844
|
next_cursor = "MA=="
|
|
750
845
|
while next_cursor != END_CURSOR:
|
|
751
846
|
params["nextCursor"] = next_cursor
|
|
752
|
-
response = self.client.get(
|
|
753
|
-
|
|
847
|
+
response = self.client.get(
|
|
848
|
+
"https://polymarket.com/api/rewards/markets", params=params
|
|
849
|
+
)
|
|
754
850
|
response.raise_for_status()
|
|
755
851
|
next_cursor = response.json()["next_cursor"]
|
|
756
|
-
results += [
|
|
852
|
+
results += [RewardMarket(**reward) for reward in response.json()["data"]]
|
|
757
853
|
|
|
758
854
|
return results
|
|
759
855
|
|