prediction-market-agent-tooling 0.61.1.dev484__py3-none-any.whl → 0.61.1.dev486__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.
@@ -11,21 +11,12 @@ from prediction_market_agent_tooling.gtypes import (
11
11
  ChecksumAddress,
12
12
  HexAddress,
13
13
  HexBytes,
14
- Probability,
15
- xdai_type,
16
14
  )
17
- from prediction_market_agent_tooling.loggers import logger
18
15
  from prediction_market_agent_tooling.markets.data_models import Resolution
19
16
  from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
20
17
  SeerParentMarket,
21
- SeerPool,
22
18
  )
23
- from prediction_market_agent_tooling.tools.caches.inmemory_cache import (
24
- persistent_inmemory_cache,
25
- )
26
- from prediction_market_agent_tooling.tools.cow.cow_manager import CowManager
27
19
  from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
28
- from prediction_market_agent_tooling.tools.web3_utils import xdai_to_wei
29
20
 
30
21
 
31
22
  class SeerOutcomeEnum(str, Enum):
@@ -165,93 +156,6 @@ class SeerMarket(BaseModel):
165
156
  def created_time(self) -> DatetimeUTC:
166
157
  return DatetimeUTC.to_datetime_utc(self.block_timestamp)
167
158
 
168
- @persistent_inmemory_cache
169
- def get_price_for_token(
170
- self,
171
- token: ChecksumAddress,
172
- ) -> float:
173
- collateral_exchange_amount = xdai_to_wei(xdai_type(1))
174
- try:
175
- quote = CowManager().get_quote(
176
- collateral_token=self.collateral_token_contract_address_checksummed,
177
- buy_token=token,
178
- sell_amount=collateral_exchange_amount,
179
- )
180
- except Exception as e:
181
- logger.warning(
182
- f"Could not get quote for {token=} from Cow, exception {e=}. Falling back to pools. "
183
- )
184
- price = self.get_token_price_from_pools(token=token)
185
- return price
186
-
187
- return collateral_exchange_amount / float(quote.quote.buyAmount.root)
188
-
189
- @staticmethod
190
- def _pool_token0_matches_token(token: ChecksumAddress, pool: SeerPool) -> bool:
191
- return pool.token0.id.hex().lower() == token.lower()
192
-
193
- def get_token_price_from_pools(
194
- self,
195
- token: ChecksumAddress,
196
- collateral_token_contract_address_checksummed: ChecksumAddress,
197
- ) -> float:
198
- pool = self.subgraph_handler.get_pool_by_token(token_address=token)
199
-
200
- if not pool:
201
- logger.warning(f"Could not find a pool for {token=}, returning 0.")
202
- return 0
203
- # Check if other token is market's collateral (sanity check).
204
-
205
- collateral_address = (
206
- pool.token0.id
207
- if self._pool_token0_matches_token(token=token, pool=pool)
208
- else pool.token1.id
209
- )
210
- if (
211
- collateral_address.hex().lower()
212
- != collateral_token_contract_address_checksummed.lower()
213
- ):
214
- logger.warning(
215
- f"Pool {pool.id.hex()} has collateral mismatch with market. Collateral from pool {collateral_address.hex()}, collateral from market {collateral_token_contract_address_checksummed}, returning 0."
216
- )
217
- return 0
218
-
219
- price_in_collateral_units = (
220
- pool.token0Price
221
- if self._pool_token0_matches_token(pool)
222
- else pool.token1Price
223
- )
224
- return price_in_collateral_units
225
-
226
- @property
227
- def current_p_yes(self) -> Probability:
228
- price_data = {}
229
- for idx, wrapped_token in enumerate(self.wrapped_tokens):
230
- price = self.get_price_for_token(
231
- token=Web3.to_checksum_address(wrapped_token),
232
- )
233
-
234
- price_data[idx] = price
235
-
236
- if sum(price_data.values()) == 0:
237
- logger.warning(
238
- f"Could not get p_yes for market {self.id.hex()}, all price quotes are 0."
239
- )
240
- return Probability(0)
241
-
242
- price_yes = price_data[self.outcome_as_enums[SeerOutcomeEnum.YES]]
243
- price_no = price_data[self.outcome_as_enums[SeerOutcomeEnum.NO]]
244
- if price_yes and not price_no:
245
- # We simply return p_yes since it's probably a bug that p_no wasn't found.
246
- return Probability(price_yes)
247
- elif price_no and not price_yes:
248
- # We return the complement of p_no (and ignore invalid).
249
- return Probability(1.0 - price_no)
250
- else:
251
- # If all prices are available, we normalize price_yes by the other prices for the final probability.
252
- price_yes = price_yes / sum(price_data.values())
253
- return Probability(price_yes)
254
-
255
159
  @property
256
160
  def url(self) -> str:
257
161
  chain_id = RPCConfig().chain_id
@@ -1,5 +1,109 @@
1
- from prediction_market_agent_tooling.gtypes import ChecksumAddress
1
+ from web3 import Web3
2
+
3
+ from prediction_market_agent_tooling.gtypes import ChecksumAddress, xdai_type
4
+ from prediction_market_agent_tooling.gtypes import Probability
5
+ from prediction_market_agent_tooling.loggers import logger
6
+ from prediction_market_agent_tooling.markets.seer.data_models import (
7
+ SeerMarket,
8
+ SeerOutcomeEnum,
9
+ )
10
+ from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
11
+ SeerSubgraphHandler,
12
+ )
2
13
  from prediction_market_agent_tooling.markets.seer.subgraph_data_models import SeerPool
14
+ from prediction_market_agent_tooling.tools.caches.inmemory_cache import (
15
+ persistent_inmemory_cache,
16
+ )
17
+ from prediction_market_agent_tooling.tools.cow.cow_manager import CowManager
18
+ from prediction_market_agent_tooling.tools.web3_utils import xdai_to_wei
3
19
 
4
20
 
5
21
  class PriceManager:
22
+ def __init__(self, seer_market: SeerMarket, seer_subgraph: SeerSubgraphHandler):
23
+ self.seer_market = seer_market
24
+ self.seer_subgraph = seer_subgraph
25
+
26
+ def current_p_yes(self) -> Probability:
27
+ price_data = {}
28
+ for idx, wrapped_token in enumerate(self.seer_market.wrapped_tokens):
29
+ price = self.get_price_for_token(
30
+ token=Web3.to_checksum_address(wrapped_token),
31
+ )
32
+
33
+ price_data[idx] = price
34
+
35
+ if sum(price_data.values()) == 0:
36
+ logger.warning(
37
+ f"Could not get p_yes for market {self.seer_market.id.hex()}, all price quotes are 0."
38
+ )
39
+ return Probability(0)
40
+
41
+ price_yes = price_data[self.seer_market.outcome_as_enums[SeerOutcomeEnum.YES]]
42
+ price_no = price_data[self.seer_market.outcome_as_enums[SeerOutcomeEnum.NO]]
43
+ if price_yes and not price_no:
44
+ # We simply return p_yes since it's probably a bug that p_no wasn't found.
45
+ return Probability(price_yes)
46
+ elif price_no and not price_yes:
47
+ # We return the complement of p_no (and ignore invalid).
48
+ return Probability(1.0 - price_no)
49
+ else:
50
+ # If all prices are available, we normalize price_yes by the other prices for the final probability.
51
+ price_yes = price_yes / sum(price_data.values())
52
+ return Probability(price_yes)
53
+
54
+ @persistent_inmemory_cache
55
+ def get_price_for_token(
56
+ self,
57
+ token: ChecksumAddress,
58
+ ) -> float:
59
+ collateral_exchange_amount = xdai_to_wei(xdai_type(1))
60
+ try:
61
+ quote = CowManager().get_quote(
62
+ collateral_token=self.seer_market.collateral_token_contract_address_checksummed,
63
+ buy_token=token,
64
+ sell_amount=collateral_exchange_amount,
65
+ )
66
+ except Exception as e:
67
+ logger.warning(
68
+ f"Could not get quote for {token=} from Cow, exception {e=}. Falling back to pools. "
69
+ )
70
+ price = self.get_token_price_from_pools(token=token)
71
+ return price
72
+
73
+ return collateral_exchange_amount / float(quote.quote.buyAmount.root)
74
+
75
+ @staticmethod
76
+ def _pool_token0_matches_token(token: ChecksumAddress, pool: SeerPool) -> bool:
77
+ return pool.token0.id.hex().lower() == token.lower()
78
+
79
+ def get_token_price_from_pools(
80
+ self,
81
+ token: ChecksumAddress,
82
+ ) -> float:
83
+ pool = SeerSubgraphHandler().get_pool_by_token(token_address=token)
84
+
85
+ if not pool:
86
+ logger.warning(f"Could not find a pool for {token=}, returning 0.")
87
+ return 0
88
+ # Check if other token is market's collateral (sanity check).
89
+
90
+ collateral_address = (
91
+ pool.token0.id
92
+ if self._pool_token0_matches_token(token=token, pool=pool)
93
+ else pool.token1.id
94
+ )
95
+ if (
96
+ collateral_address.hex().lower()
97
+ != self.seer_market.collateral_token_contract_address_checksummed.lower()
98
+ ):
99
+ logger.warning(
100
+ f"Pool {pool.id.hex()} has collateral mismatch with market. Collateral from pool {collateral_address.hex()}, collateral from market {self.seer_market.collateral_token_contract_address_checksummed}, returning 0."
101
+ )
102
+ return 0
103
+
104
+ price_in_collateral_units = (
105
+ pool.token0Price
106
+ if self._pool_token0_matches_token(token=token, pool=pool)
107
+ else pool.token1Price
108
+ )
109
+ return price_in_collateral_units
@@ -13,6 +13,7 @@ from prediction_market_agent_tooling.gtypes import (
13
13
  wei_type,
14
14
  xDai,
15
15
  xdai_type,
16
+ Probability,
16
17
  )
17
18
  from prediction_market_agent_tooling.loggers import logger
18
19
  from prediction_market_agent_tooling.markets.agent_market import (
@@ -33,16 +34,19 @@ from prediction_market_agent_tooling.markets.market_fees import MarketFees
33
34
  from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
34
35
  from prediction_market_agent_tooling.markets.omen.omen_contracts import sDaiContract
35
36
  from prediction_market_agent_tooling.markets.seer.data_models import (
36
- NewMarketEvent,
37
37
  SeerMarket,
38
38
  SeerOutcomeEnum,
39
39
  )
40
+ from prediction_market_agent_tooling.markets.seer.price_manager import PriceManager
40
41
  from prediction_market_agent_tooling.markets.seer.seer_contracts import (
41
42
  SeerMarketFactory,
42
43
  )
43
44
  from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
44
45
  SeerSubgraphHandler,
45
46
  )
47
+ from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
48
+ NewMarketEvent,
49
+ )
46
50
  from prediction_market_agent_tooling.tools.balances import get_balances
47
51
  from prediction_market_agent_tooling.tools.contract import (
48
52
  ContractERC20OnGnosisChain,
@@ -166,6 +170,33 @@ class SeerAgentMarket(AgentMarket):
166
170
  def verify_operational_balance(api_keys: APIKeys) -> bool:
167
171
  return OmenAgentMarket.verify_operational_balance(api_keys=api_keys)
168
172
 
173
+ @staticmethod
174
+ def from_data_model_with_subgraph(
175
+ model: SeerMarket, seer_subgraph: SeerSubgraphHandler
176
+ ) -> "SeerAgentMarket":
177
+ p = PriceManager(seer_market=model, seer_subgraph=seer_subgraph)
178
+ current_p_yes = p.current_p_yes()
179
+
180
+ return SeerAgentMarket(
181
+ id=model.id.hex(),
182
+ question=model.title,
183
+ creator=model.creator,
184
+ created_time=model.created_time,
185
+ outcomes=model.outcomes,
186
+ collateral_token_contract_address_checksummed=model.collateral_token_contract_address_checksummed,
187
+ condition_id=model.condition_id,
188
+ url=model.url,
189
+ close_time=model.close_time,
190
+ wrapped_tokens=[Web3.to_checksum_address(i) for i in model.wrapped_tokens],
191
+ fees=MarketFees.get_zero_fees(),
192
+ outcome_token_pool=None,
193
+ resolution=model.get_resolution_enum(),
194
+ volume=None,
195
+ # current_p_yes=model.current_p_yes,
196
+ current_p_yes=current_p_yes,
197
+ seer_outcomes=model.outcome_as_enums,
198
+ )
199
+
169
200
  @staticmethod
170
201
  def from_data_model(model: SeerMarket) -> "SeerAgentMarket":
171
202
  return SeerAgentMarket(
@@ -183,7 +214,7 @@ class SeerAgentMarket(AgentMarket):
183
214
  outcome_token_pool=None,
184
215
  resolution=model.get_resolution_enum(),
185
216
  volume=None,
186
- current_p_yes=model.current_p_yes,
217
+ current_p_yes=Probability(123), # ToDo dont use this method
187
218
  seer_outcomes=model.outcome_as_enums,
188
219
  )
189
220
 
@@ -195,13 +226,16 @@ class SeerAgentMarket(AgentMarket):
195
226
  created_after: t.Optional[DatetimeUTC] = None,
196
227
  excluded_questions: set[str] | None = None,
197
228
  ) -> t.Sequence["SeerAgentMarket"]:
229
+ seer_subgraph = SeerSubgraphHandler()
230
+ markets = seer_subgraph.get_binary_markets(
231
+ limit=limit, sort_by=sort_by, filter_by=filter_by
232
+ )
233
+
198
234
  return [
199
- SeerAgentMarket.from_data_model(m)
200
- for m in SeerSubgraphHandler().get_binary_markets(
201
- limit=limit,
202
- sort_by=sort_by,
203
- filter_by=filter_by,
235
+ SeerAgentMarket.from_data_model_with_subgraph(
236
+ model=m, seer_subgraph=seer_subgraph
204
237
  )
238
+ for m in markets
205
239
  ]
206
240
 
207
241
  def has_liquidity_for_outcome(self, outcome: bool) -> bool:
@@ -352,4 +386,4 @@ def extract_market_address_from_tx(
352
386
  .process_receipt(tx_receipt)
353
387
  )
354
388
  new_market_event = NewMarketEvent(**event_logs[0]["args"])
355
- return Web3.to_checksum_address(new_market_event.seer_market)
389
+ return Web3.to_checksum_address(new_market_event.market)
@@ -5,7 +5,7 @@ from web3.types import TxReceipt
5
5
 
6
6
  from prediction_market_agent_tooling.config import APIKeys
7
7
  from prediction_market_agent_tooling.gtypes import ABI, ChecksumAddress, xDai
8
- from prediction_market_agent_tooling.markets.seer.data_models import (
8
+ from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
9
9
  CreateCategoricalMarketsParams,
10
10
  )
11
11
  from prediction_market_agent_tooling.tools.contract import (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.61.1.dev484
3
+ Version: 0.61.1.dev486
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -61,10 +61,10 @@ prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=Fd5PI5y
61
61
  prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=VZhVccTApygSKMmy6Au2G02JCJOKJnR_oVeKlaesuSg,12548
62
62
  prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=NRoZK71PtH8kkangMqme7twcAXhRJSSabbmOir-UnAI,3418
63
63
  prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=8kTeVjXPcXC6DkDvWYsZQLY7x8DS6CEp_yznSEazsNU,2037
64
- prediction_market_agent_tooling/markets/seer/data_models.py,sha256=jLfCiwkw4OZyqw5RV3kEimmWWeBBF6SMmn4Oxzlm5pQ,9101
65
- prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=k0I8xLFs0cXEDrTiOtQUxVPaAVYchfz-D8cijeONlXc,176
66
- prediction_market_agent_tooling/markets/seer/seer.py,sha256=Anxp66UUzIIKt5wgLoqtUjUM-5HQ0wC5f5rDiYwrRRg,12959
67
- prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=E7CYAKZiK6cg3dyj1kJuIPKSYYUft98F64shF5S0g4s,2730
64
+ prediction_market_agent_tooling/markets/seer/data_models.py,sha256=ECuCDqRcs9vB9rKIec399HxsL915oT7VGSwztcMfGIw,5347
65
+ prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=fUszpmwUW2iJw5My3FJO2Lim2yXUuaZWQ9aNKX39-d0,4392
66
+ prediction_market_agent_tooling/markets/seer/seer.py,sha256=kBF7ALzlh0HsAgbdTa3A9XayyXrddtgi-dMWquLZX8Y,14365
67
+ prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=TXGDbv7CI08X8N5re1SAm-X_BaXj8m4ceyzkS_ktQok,2739
68
68
  prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=lcaKbFHxigMYwi4TCePyTb5HXJhGoCu5dJPFWTj5E28,9047
69
69
  prediction_market_agent_tooling/markets/seer/subgraph_data_models.py,sha256=RIt2oO-PbykzbYN11Qltt8tjjYTty-PfjH3Q4D2VEoA,1644
70
70
  prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py,sha256=fjIgjDIx5MhH5mwf7S0cspLOOSU3elYLhGYoIiM26mU,2746
@@ -119,8 +119,8 @@ prediction_market_agent_tooling/tools/tokens/main_token.py,sha256=7JPgVF4RbiFzLD
119
119
  prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
120
120
  prediction_market_agent_tooling/tools/utils.py,sha256=jLG4nbEoIzzJiZ4RgMx4Q969Zdl0p0s63p8uET_0Fuw,6440
121
121
  prediction_market_agent_tooling/tools/web3_utils.py,sha256=3wfqNxvMn44ivweFRoeKNVb9QRtFd7kFtp7VUY5juEE,12862
122
- prediction_market_agent_tooling-0.61.1.dev484.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
123
- prediction_market_agent_tooling-0.61.1.dev484.dist-info/METADATA,sha256=IpD8pQ3IicG0EyoDNg33hCkmVHBpXGKbNg-_FpdXve0,8636
124
- prediction_market_agent_tooling-0.61.1.dev484.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
125
- prediction_market_agent_tooling-0.61.1.dev484.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
126
- prediction_market_agent_tooling-0.61.1.dev484.dist-info/RECORD,,
122
+ prediction_market_agent_tooling-0.61.1.dev486.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
123
+ prediction_market_agent_tooling-0.61.1.dev486.dist-info/METADATA,sha256=7XZFv83NtgtmTfYh1aq17OY1M69UzMcLnyhdkuMmNB0,8636
124
+ prediction_market_agent_tooling-0.61.1.dev486.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
125
+ prediction_market_agent_tooling-0.61.1.dev486.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
126
+ prediction_market_agent_tooling-0.61.1.dev486.dist-info/RECORD,,