prediction-market-agent-tooling 0.27.0__py3-none-any.whl → 0.29.0__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.
@@ -1,5 +1,7 @@
1
+ import builtins
1
2
  import logging
2
3
  import sys
4
+ import typing as t
3
5
  import warnings
4
6
  from enum import Enum
5
7
 
@@ -35,9 +37,11 @@ def patch_logger() -> None:
35
37
  format_loguru = GCP_LOG_LOGURU_FORMAT
36
38
  format_logging = GCP_LOG_LOGGING_FORMAT
37
39
  datefmt_logging = GCP_LOG_FORMAT_LOGGING_DATEFMT
40
+ print_logging = print_using_loguru_info
38
41
 
39
42
  elif config.LOG_FORMAT == LogFormat.DEFAULT:
40
43
  format_loguru, format_logging, datefmt_logging = None, None, None
44
+ print_logging = None
41
45
 
42
46
  else:
43
47
  raise ValueError(f"Unknown log format: {config.LOG_FORMAT}")
@@ -63,11 +67,30 @@ def patch_logger() -> None:
63
67
  # Use logging module for warnings.
64
68
  logging.captureWarnings(True)
65
69
 
70
+ # Use loguru for prints.
71
+ if print_logging is not None:
72
+ builtins.print = print_logging # type: ignore[assignment] # Monkey patching, it's messy but it works.
73
+
66
74
  logger.info(f"Patched logger for {config.LOG_FORMAT.value} format.")
67
75
 
68
76
 
77
+ def print_using_loguru_info(
78
+ *values: object,
79
+ sep: str = " ",
80
+ end: str = "\n",
81
+ **kwargs: t.Any,
82
+ ) -> None:
83
+ message = sep.join(map(str, values)) + end
84
+ message = message.strip().replace(
85
+ "\n", "\\n"
86
+ ) # Escape new lines, because otherwise logs will be broken.
87
+ logger.info(message)
88
+
89
+
69
90
  def simple_warning_format(message, category, filename, lineno, line=None): # type: ignore[no-untyped-def] # Not typed in the standard library neither.
70
- return f"{category.__name__}: {message}"
91
+ return f"{category.__name__}: {message}".strip().replace(
92
+ "\n", "\\n"
93
+ ) # Escape new lines, because otherwise logs will be broken.
71
94
 
72
95
 
73
96
  if not getattr(logger, "_patched", False):
@@ -18,6 +18,7 @@ from prediction_market_agent_tooling.tools.utils import (
18
18
  add_utc_timezone_validator,
19
19
  check_not_none,
20
20
  should_not_happen,
21
+ utcnow,
21
22
  )
22
23
 
23
24
 
@@ -147,9 +148,18 @@ class AgentMarket(BaseModel):
147
148
  ) -> list[Bet]:
148
149
  raise NotImplementedError("Subclasses must implement this method")
149
150
 
151
+ def is_closed(self) -> bool:
152
+ return self.close_time is not None and self.close_time <= utcnow()
153
+
150
154
  def is_resolved(self) -> bool:
151
155
  return self.resolution is not None
152
156
 
157
+ def get_liquidity(self) -> TokenAmount:
158
+ raise NotImplementedError("Subclasses must implement this method")
159
+
160
+ def has_liquidity(self) -> bool:
161
+ return self.get_liquidity().amount > 0
162
+
153
163
  def has_successful_resolution(self) -> bool:
154
164
  return self.resolution in [Resolution.YES, Resolution.NO]
155
165
 
@@ -174,8 +184,15 @@ class AgentMarket(BaseModel):
174
184
  raise NotImplementedError("Subclasses must implement this method")
175
185
 
176
186
  @classmethod
177
- def get_positions(cls, user_id: str) -> list[Position]:
187
+ def get_positions(cls, user_id: str, liquid_only: bool = False) -> list[Position]:
178
188
  """
179
189
  Get all non-zero positions a user has in any market.
190
+
191
+ If `liquid_only` is True, only return positions that can be sold.
180
192
  """
181
193
  raise NotImplementedError("Subclasses must implement this method")
194
+
195
+ def can_be_traded(self) -> bool:
196
+ if self.is_closed() or not self.has_liquidity():
197
+ return False
198
+ return True
@@ -422,7 +422,7 @@ class RealityQuestion(BaseModel):
422
422
  # And because all the contract methods so far needed bytes32 input, when asked for question id, `questionId` field was the correct one to use so far.
423
423
  id: str
424
424
  user: HexAddress
425
- historyHash: HexBytes
425
+ historyHash: HexBytes | None
426
426
  updatedTimestamp: datetime
427
427
  contentHash: HexBytes
428
428
  questionId: HexBytes
@@ -117,11 +117,17 @@ class OmenAgentMarket(AgentMarket):
117
117
  else None
118
118
  )
119
119
 
120
- def get_liquidity(self) -> Wei:
120
+ def get_liquidity_in_wei(self) -> Wei:
121
121
  return self.get_contract().totalSupply()
122
122
 
123
123
  def get_liquidity_in_xdai(self) -> xDai:
124
- return wei_to_xdai(self.get_liquidity())
124
+ return wei_to_xdai(self.get_liquidity_in_wei())
125
+
126
+ def get_liquidity(self) -> TokenAmount:
127
+ return TokenAmount(
128
+ amount=self.get_liquidity_in_xdai(),
129
+ currency=Currency.xDai,
130
+ )
125
131
 
126
132
  def get_tiny_bet_amount(self) -> BetAmount:
127
133
  return BetAmount(amount=0.00001, currency=self.currency)
@@ -133,6 +139,10 @@ class OmenAgentMarket(AgentMarket):
133
139
  omen_auto_deposit: bool = True,
134
140
  web3: Web3 | None = None,
135
141
  ) -> None:
142
+ if not self.can_be_traded():
143
+ raise ValueError(
144
+ f"Market {self.id} is not open for trading. Cannot place bet."
145
+ )
136
146
  if amount.currency != self.currency:
137
147
  raise ValueError(f"Omen bets are made in xDai. Got {amount.currency}.")
138
148
  amount_xdai = xDai(amount.amount)
@@ -148,6 +158,10 @@ class OmenAgentMarket(AgentMarket):
148
158
  def sell_tokens(
149
159
  self, outcome: bool, amount: TokenAmount, auto_withdraw: bool = True
150
160
  ) -> None:
161
+ if not self.can_be_traded():
162
+ raise ValueError(
163
+ f"Market {self.id} is not open for trading. Cannot sell tokens."
164
+ )
151
165
  binary_omen_sell_outcome_tx(
152
166
  api_keys=APIKeys(),
153
167
  amount=xDai(amount.amount),
@@ -301,7 +315,7 @@ class OmenAgentMarket(AgentMarket):
301
315
  )
302
316
 
303
317
  @classmethod
304
- def get_positions(cls, user_id: str) -> list[Position]:
318
+ def get_positions(cls, user_id: str, liquid_only: bool = False) -> list[Position]:
305
319
  sgh = OmenSubgraphHandler()
306
320
  omen_positions = sgh.get_user_positions(
307
321
  better_address=Web3.to_checksum_address(user_id),
@@ -329,6 +343,11 @@ class OmenAgentMarket(AgentMarket):
329
343
  positions = []
330
344
  for condition_id, omen_positions in omen_positions_dict.items():
331
345
  market = cls.from_data_model(omen_markets[condition_id])
346
+
347
+ # Skip markets that cannot be traded if `liquid_only`` is True.
348
+ if liquid_only and not market.can_be_traded():
349
+ continue
350
+
332
351
  amounts: dict[OutcomeStr, TokenAmount] = {}
333
352
  for omen_position in omen_positions:
334
353
  outecome_str = market.index_set_to_outcome_str(
@@ -31,6 +31,7 @@ from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
31
31
  from prediction_market_agent_tooling.markets.polymarket.utils import (
32
32
  find_resolution_on_polymarket,
33
33
  )
34
+ from prediction_market_agent_tooling.tools.utils import check_not_none
34
35
  from prediction_market_agent_tooling.tools.web3_utils import ZERO_BYTES, xdai_to_wei
35
36
 
36
37
 
@@ -95,7 +96,12 @@ def claim_bonds_on_realitio_question(
95
96
  # TODO: See `if len(answers_objects) > 1` above.
96
97
  # This is from the original Olas implementation (https://github.com/kongzii/trader/blob/700af475a4538cc3d5d22caf9dec9e9d22d72af1/packages/valory/skills/market_manager_abci/graph_tooling/requests.py#L297),
97
98
  # but it's most probably wrong (see comment above).
98
- history_hashes.append(answers_objects[i + 1].question.historyHash)
99
+ history_hashes.append(
100
+ check_not_none(
101
+ answers_objects[i + 1].question.historyHash,
102
+ "Shouldn't be None here.",
103
+ )
104
+ )
99
105
 
100
106
  # last-to-first, the address of each answerer or commitment sender
101
107
  addresses.append(Web3.to_checksum_address(answer.question.user))
@@ -1,6 +1,8 @@
1
1
  import typing as t
2
2
 
3
3
  import requests
4
+ import tenacity
5
+ from loguru import logger
4
6
 
5
7
  from prediction_market_agent_tooling.markets.polymarket.data_models import (
6
8
  POLYMARKET_FALSE_OUTCOME,
@@ -18,6 +20,27 @@ POLYMARKET_API_BASE_URL = "https://clob.polymarket.com/"
18
20
  MARKETS_LIMIT = 100 # Polymarket will only return up to 100 markets
19
21
 
20
22
 
23
+ @tenacity.retry(
24
+ stop=tenacity.stop_after_attempt(5),
25
+ wait=tenacity.wait_chain(*[tenacity.wait_fixed(n) for n in range(1, 6)]),
26
+ after=lambda x: logger.debug(f"get_polymarkets failed, {x.attempt_number=}."),
27
+ )
28
+ def get_polymarkets(
29
+ limit: int,
30
+ with_rewards: bool = False,
31
+ next_cursor: str | None = None,
32
+ ) -> MarketsEndpointResponse:
33
+ url = (
34
+ f"{POLYMARKET_API_BASE_URL}/{'sampling-markets' if with_rewards else 'markets'}"
35
+ )
36
+ params: dict[str, str | int | float | None] = {
37
+ "limit": min(limit, MARKETS_LIMIT),
38
+ }
39
+ if next_cursor is not None:
40
+ params["next_cursor"] = next_cursor
41
+ return response_to_model(requests.get(url, params=params), MarketsEndpointResponse)
42
+
43
+
21
44
  def get_polymarket_binary_markets(
22
45
  limit: int,
23
46
  closed: bool | None = False,
@@ -28,17 +51,13 @@ def get_polymarket_binary_markets(
28
51
  """
29
52
  See https://learn.polymarket.com/trading-rewards for information about rewards.
30
53
  """
31
- url = (
32
- f"{POLYMARKET_API_BASE_URL}/{'sampling-markets' if with_rewards else 'markets'}"
33
- )
54
+
34
55
  all_markets: list[PolymarketMarketWithPrices] = []
35
- params: dict[str, str | int | float | None] = {
36
- "limit": min(limit, MARKETS_LIMIT),
37
- }
56
+ next_cursor: str | None = None
38
57
 
39
58
  while True:
40
- response = response_to_model(
41
- requests.get(url, params=params), MarketsEndpointResponse
59
+ response = get_polymarkets(
60
+ limit, with_rewards=with_rewards, next_cursor=next_cursor
42
61
  )
43
62
 
44
63
  for market in response.data:
@@ -81,12 +100,12 @@ def get_polymarket_binary_markets(
81
100
  if len(all_markets) >= limit:
82
101
  break
83
102
 
84
- if response.next_cursor == "LTE=":
103
+ next_cursor = response.next_cursor
104
+
105
+ if next_cursor == "LTE=":
85
106
  # 'LTE=' means the end.
86
107
  break
87
108
 
88
- params["next_cursor"] = response.next_cursor
89
-
90
109
  return all_markets[:limit]
91
110
 
92
111
 
@@ -32,8 +32,8 @@ class PolymarketMarket(BaseModel):
32
32
  active: bool
33
33
  closed: bool
34
34
  archived: bool
35
- minimum_order_size: str
36
- minimum_tick_size: str
35
+ minimum_order_size: str | float
36
+ minimum_tick_size: str | float
37
37
  condition_id: str
38
38
  question_id: str
39
39
  question: str
@@ -54,8 +54,8 @@ class PolymarketMarket(BaseModel):
54
54
  rewards: PolymarketRewards
55
55
  tokens: tuple[PolymarketToken, ...]
56
56
  is_50_50_outcome: bool
57
- categories: list[str]
58
- parent_categories: list[str]
57
+ categories: list[str] | None = None
58
+ parent_categories: list[str] | None = None
59
59
  accepting_orders: bool
60
60
 
61
61
  @property
@@ -83,7 +83,7 @@ class Market(BaseModel):
83
83
  category: t.Any | None
84
84
  ammType: t.Any | None
85
85
  description: str
86
- liquidity: str
86
+ liquidity: str | None
87
87
  startDate: datetime
88
88
  createdAt: datetime
89
89
  xAxisValue: t.Any | None
@@ -128,7 +128,7 @@ class Market(BaseModel):
128
128
  umaResolutionStatus: t.Any | None
129
129
  curationOrder: t.Any | None
130
130
  volumeNum: USDC | None
131
- liquidityNum: float
131
+ liquidityNum: float | None
132
132
  endDateIso: datetime | None
133
133
  startDateIso: datetime | None
134
134
  umaEndDateIso: datetime | None
@@ -137,8 +137,8 @@ class Market(BaseModel):
137
137
  gameStartTime: datetime | None
138
138
  secondsDelay: int | None
139
139
  clobTokenIds: list[str]
140
- liquidityAmm: float
141
- liquidityClob: float
140
+ liquidityAmm: float | None
141
+ liquidityClob: float | None
142
142
  makerBaseFee: int | None
143
143
  takerBaseFee: int | None
144
144
  negRisk: t.Any | None
@@ -163,7 +163,7 @@ class Market(BaseModel):
163
163
  closed_time: t.Any | None
164
164
  wide_format: bool | None
165
165
  volume_num: USDC | None
166
- liquidity_num: USDC
166
+ liquidity_num: USDC | None
167
167
  image_raw: str
168
168
  resolutionData: ResolutionData
169
169
 
@@ -208,6 +208,25 @@ class Category(BaseModel):
208
208
  slug: str
209
209
 
210
210
 
211
+ class Bid(BaseModel):
212
+ price: str
213
+ size: str
214
+
215
+
216
+ class Ask(BaseModel):
217
+ price: str
218
+ size: str
219
+
220
+
221
+ class MarketBidsAndAsks(BaseModel):
222
+ market: str
223
+ asset_id: str
224
+ hash: str
225
+ bids: list[Bid]
226
+ asks: list[Ask]
227
+ lastUpdated: int
228
+
229
+
211
230
  class PolymarketFullMarket(BaseModel):
212
231
  id: str
213
232
  ticker: str
@@ -228,10 +247,10 @@ class PolymarketFullMarket(BaseModel):
228
247
  new: bool
229
248
  featured: bool
230
249
  restricted: bool
231
- liquidity: USDC
250
+ liquidity: USDC | None
232
251
  volume: USDC | None
233
252
  volume24hr: USDC | None
234
- competitive: float
253
+ competitive: float | None
235
254
  openInterest: int | None
236
255
  sortBy: str | None
237
256
  createdAt: datetime
@@ -239,8 +258,8 @@ class PolymarketFullMarket(BaseModel):
239
258
  disqusThread: t.Any | None
240
259
  updatedAt: datetime
241
260
  enableOrderBook: bool
242
- liquidityAmm: float
243
- liquidityClob: float
261
+ liquidityAmm: float | None
262
+ liquidityClob: float | None
244
263
  imageOptimized: ImageOptimized | None
245
264
  iconOptimized: IconOptimized | None
246
265
  featuredImageOptimized: str | None
@@ -248,7 +267,7 @@ class PolymarketFullMarket(BaseModel):
248
267
  negRiskMarketID: t.Any | None
249
268
  negRiskFeeBips: t.Any | None
250
269
  markets: list[Market]
251
- categories: list[Category] | None
270
+ categories: list[Category] | None = None
252
271
  series: t.Any | None
253
272
  image_raw: str
254
273
 
@@ -327,7 +346,12 @@ class PriceSide(BaseModel):
327
346
 
328
347
  class State(BaseModel):
329
348
  data: (
330
- PolymarketFullMarket | PriceSide | None
349
+ PolymarketFullMarket
350
+ | MarketBidsAndAsks
351
+ | PriceSide
352
+ | dict[str, MarketBidsAndAsks]
353
+ | dict[str, PriceSide]
354
+ | None
331
355
  ) # It's none if you go to the website and it says "Oops...we didn't forecast this".
332
356
  dataUpdateCount: int
333
357
  dataUpdatedAt: int
@@ -9,7 +9,11 @@ from prediction_market_agent_tooling.tools.google import search_google
9
9
  def find_resolution_on_polymarket(question: str) -> Resolution | None:
10
10
  full_market = find_full_polymarket(question)
11
11
  # TODO: Only main markets are supported right now, add logic for others if needed.
12
- return full_market.main_market.resolution if full_market else None
12
+ return (
13
+ full_market.main_market.resolution
14
+ if full_market and full_market.is_main_market
15
+ else None
16
+ )
13
17
 
14
18
 
15
19
  def find_full_polymarket(question: str) -> PolymarketFullMarket | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.27.0
3
+ Version: 0.29.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -19,8 +19,8 @@ prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5
19
19
  prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=qYIHRxQLac3yxtZ8ChikiPG9O1aUQucHW0muTSm1nto,2627
20
20
  prediction_market_agent_tooling/deploy/gcp/utils.py,sha256=oyW0jgrUT2Tr49c7GlpcMsYNQjoCSOcWis3q-MmVAhU,6089
21
21
  prediction_market_agent_tooling/gtypes.py,sha256=xGSJXw12hzp8LwvQ956l01GiZMWd07MZTYqo8CXVeLY,2417
22
- prediction_market_agent_tooling/loggers.py,sha256=0znHrzxSbeBaDiB920EZC6a2TiF0tw80Sa_yoLwvo_w,2289
23
- prediction_market_agent_tooling/markets/agent_market.py,sha256=b2gsqEXADJir_LxcNUmzEfxGCcJ_V5mWPGM2SZfIA6M,6250
22
+ prediction_market_agent_tooling/loggers.py,sha256=p_ibaEpUGGdcpPtzIJxh5UusJNCQyN1y_RDvoTaeUfA,3001
23
+ prediction_market_agent_tooling/markets/agent_market.py,sha256=I1r83EU5yMJ1dJhCqZjJ523XOElhBkb96oGDxbr4mlU,6818
24
24
  prediction_market_agent_tooling/markets/categorize.py,sha256=yTd-lDMPW4ESDSzmxeLLBuzLX0FggOF7Vbswh7295o0,941
25
25
  prediction_market_agent_tooling/markets/data_models.py,sha256=uODY3aoFp8YYeLAUcrzMk1yU8pIKsTLobB9xIEGTmKs,1170
26
26
  prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -30,16 +30,16 @@ prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=DJZ88r5BGtAu
30
30
  prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
31
31
  prediction_market_agent_tooling/markets/markets.py,sha256=w05Oo7yCA2axpCw69Q9y4i9Gcdpht0u5bZGbWqld3rU,2964
32
32
  prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- prediction_market_agent_tooling/markets/omen/data_models.py,sha256=f7RO1Zvytii-M2koGuLQiPERjTq_DsDjrT01mar_sX4,14398
34
- prediction_market_agent_tooling/markets/omen/omen.py,sha256=YcM9AbBUOJ1xoZTI9UlHZTSNR4T1cTwyl3lZlXy2qbs,31209
33
+ prediction_market_agent_tooling/markets/omen/data_models.py,sha256=EXtjmcujx68Xu50BVkYXvLuf_Asx5o65RvFS3ZS6HGs,14405
34
+ prediction_market_agent_tooling/markets/omen/omen.py,sha256=UeBKfiEzTVZMRJ-r6YHXdlrMniwz3V1Te2yZgNX64rA,31902
35
35
  prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=eDS8vN4Klv_-Y1wwfIeLDt3twhl9U_AJjPQov0JScb0,19888
36
- prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=-qssaOJweI_QktR7bQiYjn-V6T_bBTQOH9qQjG35D48,8809
36
+ prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=g77QsQ5WnSI2rzBlX87L_EhWMwobkyXyfRhHQmpAdzo,9012
37
37
  prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=QZWwkqvOqQ-b15jidwTNsn1K64x3FY_Un-l6A6g3Twg,22299
38
- prediction_market_agent_tooling/markets/polymarket/api.py,sha256=p1JkqL9kF8C04qbmqFzF0hgtzD5kN3yup2hYOjxazQ4,4188
39
- prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=srTl8-0FM76AGLRDWzjLpf46ikWloaBCgkn0XqZoKCI,4248
40
- prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=qop9lK4-3VfEJ9SuSCJdYPhjMqP4g6F5FpHziJv8HDY,10887
38
+ prediction_market_agent_tooling/markets/polymarket/api.py,sha256=HXmA1akA0qDj0m3e-GEvWG8x75pm6BX4H7YJPQcST7I,4767
39
+ prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=9CJzakyEcsn6DQBK2nOXjOMzTZBLAmK_KqevXvW17DI,4292
40
+ prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=f8SRQy0Rn-gIHSEMrJJAI8H3J7l8lzOLj3aCMe0vJv8,11324
41
41
  prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=zqGfiUOH9f7jmDcQAt30wrHyfmqLMNwCYtotsxFoJmA,2678
42
- prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=Gwd2kOK_DrsjtyqgO6ob8oK7tjsB1Yo-Hf7IS5UGnio,1960
42
+ prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=m4JG6WULh5epCJt4XBMHg0ae5NoVhqlOvAl0A7DR9iM,2023
43
43
  prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py,sha256=b6T69YB1x8kSUvW9uRFuSWPLOrXzapZG7m5O5SU0QTQ,895
44
44
  prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=GdYpgRX1GahDi-75Mr53jgtEg6nWcs_rHDUkg4o_7dQ,3352
45
45
  prediction_market_agent_tooling/monitor/markets/omen.py,sha256=jOLPnIbDU9syjnYtHfOb2xa6-Ize3vbplgh-8WWkuT4,3323
@@ -65,8 +65,8 @@ prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_
65
65
  prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
66
66
  prediction_market_agent_tooling/tools/utils.py,sha256=zkmwPi3YisgZDPCeNwaRbL8sInOYOkvFgFY4Q8PbEo4,5077
67
67
  prediction_market_agent_tooling/tools/web3_utils.py,sha256=cboATXNmEdn5RmPbVblHOwOdUMKBYrUK3GiI6i6Vzxo,9855
68
- prediction_market_agent_tooling-0.27.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
69
- prediction_market_agent_tooling-0.27.0.dist-info/METADATA,sha256=EOgPmMy7tmfMsgdKgxB_zVCFZN8YQO5n49IazPE9gJA,5465
70
- prediction_market_agent_tooling-0.27.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
71
- prediction_market_agent_tooling-0.27.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
72
- prediction_market_agent_tooling-0.27.0.dist-info/RECORD,,
68
+ prediction_market_agent_tooling-0.29.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
69
+ prediction_market_agent_tooling-0.29.0.dist-info/METADATA,sha256=o_gMRsvw7wrtl0JcbGw11_I-wyNA7VzW5GDlNqeR9tM,5465
70
+ prediction_market_agent_tooling-0.29.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
71
+ prediction_market_agent_tooling-0.29.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
72
+ prediction_market_agent_tooling-0.29.0.dist-info/RECORD,,