prediction-market-agent-tooling 0.61.1.dev489__py3-none-any.whl → 0.62.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.
Files changed (50) hide show
  1. prediction_market_agent_tooling/deploy/agent.py +4 -5
  2. prediction_market_agent_tooling/deploy/betting_strategy.py +53 -69
  3. prediction_market_agent_tooling/gtypes.py +105 -27
  4. prediction_market_agent_tooling/jobs/jobs_models.py +5 -7
  5. prediction_market_agent_tooling/jobs/omen/omen_jobs.py +13 -17
  6. prediction_market_agent_tooling/markets/agent_market.py +96 -55
  7. prediction_market_agent_tooling/markets/blockchain_utils.py +2 -32
  8. prediction_market_agent_tooling/markets/data_models.py +40 -44
  9. prediction_market_agent_tooling/markets/manifold/api.py +2 -6
  10. prediction_market_agent_tooling/markets/manifold/data_models.py +33 -25
  11. prediction_market_agent_tooling/markets/manifold/manifold.py +13 -11
  12. prediction_market_agent_tooling/markets/market_fees.py +6 -2
  13. prediction_market_agent_tooling/markets/omen/data_models.py +66 -57
  14. prediction_market_agent_tooling/markets/omen/omen.py +222 -250
  15. prediction_market_agent_tooling/markets/omen/omen_contracts.py +32 -33
  16. prediction_market_agent_tooling/markets/omen/omen_resolving.py +7 -14
  17. prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +20 -14
  18. prediction_market_agent_tooling/markets/polymarket/data_models.py +3 -3
  19. prediction_market_agent_tooling/markets/polymarket/data_models_web.py +4 -4
  20. prediction_market_agent_tooling/markets/polymarket/polymarket.py +3 -5
  21. prediction_market_agent_tooling/markets/seer/data_models.py +92 -5
  22. prediction_market_agent_tooling/markets/seer/seer.py +93 -115
  23. prediction_market_agent_tooling/markets/seer/seer_contracts.py +11 -6
  24. prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +18 -26
  25. prediction_market_agent_tooling/monitor/monitor.py +2 -2
  26. prediction_market_agent_tooling/tools/_generic_value.py +261 -0
  27. prediction_market_agent_tooling/tools/balances.py +14 -11
  28. prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +12 -10
  29. prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +31 -24
  30. prediction_market_agent_tooling/tools/betting_strategies/utils.py +3 -1
  31. prediction_market_agent_tooling/tools/contract.py +14 -10
  32. prediction_market_agent_tooling/tools/cow/cow_manager.py +3 -4
  33. prediction_market_agent_tooling/tools/cow/cow_order.py +51 -7
  34. prediction_market_agent_tooling/tools/langfuse_client_utils.py +13 -1
  35. prediction_market_agent_tooling/tools/omen/sell_positions.py +6 -3
  36. prediction_market_agent_tooling/tools/safe.py +5 -6
  37. prediction_market_agent_tooling/tools/tokens/auto_deposit.py +36 -27
  38. prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +4 -25
  39. prediction_market_agent_tooling/tools/tokens/main_token.py +2 -2
  40. prediction_market_agent_tooling/tools/tokens/token_utils.py +46 -0
  41. prediction_market_agent_tooling/tools/tokens/usd.py +79 -0
  42. prediction_market_agent_tooling/tools/utils.py +14 -8
  43. prediction_market_agent_tooling/tools/web3_utils.py +24 -41
  44. {prediction_market_agent_tooling-0.61.1.dev489.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/METADATA +2 -1
  45. {prediction_market_agent_tooling-0.61.1.dev489.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/RECORD +48 -47
  46. prediction_market_agent_tooling/markets/seer/price_manager.py +0 -111
  47. prediction_market_agent_tooling/markets/seer/subgraph_data_models.py +0 -57
  48. {prediction_market_agent_tooling-0.61.1.dev489.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/LICENSE +0 -0
  49. {prediction_market_agent_tooling-0.61.1.dev489.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/WHEEL +0 -0
  50. {prediction_market_agent_tooling-0.61.1.dev489.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/entry_points.txt +0 -0
@@ -4,16 +4,16 @@ from eth_typing import ChecksumAddress
4
4
  from web3 import Web3
5
5
  from web3.types import TxReceipt
6
6
 
7
- from prediction_market_agent_tooling.config import APIKeys
7
+ from prediction_market_agent_tooling.config import APIKeys, RPCConfig
8
8
  from prediction_market_agent_tooling.gtypes import (
9
+ USD,
10
+ CollateralToken,
9
11
  HexAddress,
10
12
  HexBytes,
11
13
  OutcomeStr,
12
- Wei,
13
- wei_type,
14
+ OutcomeToken,
15
+ OutcomeWei,
14
16
  xDai,
15
- xdai_type,
16
- Probability,
17
17
  )
18
18
  from prediction_market_agent_tooling.loggers import logger
19
19
  from prediction_market_agent_tooling.markets.agent_market import (
@@ -24,30 +24,20 @@ from prediction_market_agent_tooling.markets.agent_market import (
24
24
  SortBy,
25
25
  )
26
26
  from prediction_market_agent_tooling.markets.blockchain_utils import store_trades
27
- from prediction_market_agent_tooling.markets.data_models import (
28
- BetAmount,
29
- Currency,
30
- Position,
31
- TokenAmount,
32
- )
27
+ from prediction_market_agent_tooling.markets.data_models import ExistingPosition
33
28
  from prediction_market_agent_tooling.markets.market_fees import MarketFees
34
29
  from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
35
- from prediction_market_agent_tooling.markets.omen.omen_contracts import sDaiContract
36
30
  from prediction_market_agent_tooling.markets.seer.data_models import (
31
+ NewMarketEvent,
37
32
  SeerMarket,
38
33
  SeerOutcomeEnum,
39
34
  )
40
- from prediction_market_agent_tooling.markets.seer.price_manager import PriceManager
41
35
  from prediction_market_agent_tooling.markets.seer.seer_contracts import (
42
36
  SeerMarketFactory,
43
37
  )
44
38
  from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
45
39
  SeerSubgraphHandler,
46
40
  )
47
- from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
48
- NewMarketEvent,
49
- )
50
- from prediction_market_agent_tooling.tools.balances import get_balances
51
41
  from prediction_market_agent_tooling.tools.contract import (
52
42
  ContractERC20OnGnosisChain,
53
43
  init_collateral_token_contract,
@@ -61,14 +51,16 @@ from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
61
51
  from prediction_market_agent_tooling.tools.tokens.auto_deposit import (
62
52
  auto_deposit_collateral_token,
63
53
  )
64
- from prediction_market_agent_tooling.tools.web3_utils import wei_to_xdai, xdai_to_wei
54
+ from prediction_market_agent_tooling.tools.tokens.usd import (
55
+ get_token_in_usd,
56
+ get_usd_in_token,
57
+ )
65
58
 
66
59
  # We place a larger bet amount by default than Omen so that cow presents valid quotes.
67
- SEER_TINY_BET_AMOUNT = xdai_type(0.1)
60
+ SEER_TINY_BET_AMOUNT = USD(0.1)
68
61
 
69
62
 
70
63
  class SeerAgentMarket(AgentMarket):
71
- currency = Currency.sDai
72
64
  wrapped_tokens: list[ChecksumAddress]
73
65
  creator: HexAddress
74
66
  collateral_token_contract_address_checksummed: ChecksumAddress
@@ -78,6 +70,16 @@ class SeerAgentMarket(AgentMarket):
78
70
  None # Seer markets don't have a description, so just default to None.
79
71
  )
80
72
 
73
+ def get_collateral_token_contract(
74
+ self, web3: Web3 | None = None
75
+ ) -> ContractERC20OnGnosisChain:
76
+ web3 = web3 or RPCConfig().get_web3()
77
+ return to_gnosis_chain_contract(
78
+ init_collateral_token_contract(
79
+ self.collateral_token_contract_address_checksummed, web3
80
+ )
81
+ )
82
+
81
83
  def store_prediction(
82
84
  self,
83
85
  processed_market: ProcessedMarket | None,
@@ -91,39 +93,36 @@ class SeerAgentMarket(AgentMarket):
91
93
  traded_market: ProcessedTradedMarket | None,
92
94
  keys: APIKeys,
93
95
  agent_name: str,
94
- web3: Web3 | None = None,
95
- ) -> TxReceipt:
96
+ ) -> None:
96
97
  return store_trades(
97
98
  market_id=self.id,
98
99
  traded_market=traded_market,
99
100
  keys=keys,
100
101
  agent_name=agent_name,
101
- web3=web3,
102
102
  )
103
103
 
104
- def _convert_bet_amount_into_wei(self, bet_amount: BetAmount) -> Wei:
105
- if bet_amount.currency == self.currency:
106
- return xdai_to_wei(xdai_type(bet_amount.amount))
107
- raise ValueError(
108
- f"Currencies don't match. Currency bet amount {bet_amount.currency} currency market: {self.currency}"
109
- )
104
+ def get_token_in_usd(self, x: CollateralToken) -> USD:
105
+ return get_token_in_usd(x, self.collateral_token_contract_address_checksummed)
106
+
107
+ def get_usd_in_token(self, x: USD) -> CollateralToken:
108
+ return get_usd_in_token(x, self.collateral_token_contract_address_checksummed)
110
109
 
111
110
  def get_buy_token_amount(
112
- self, bet_amount: BetAmount, direction: bool
113
- ) -> TokenAmount:
111
+ self, bet_amount: USD | CollateralToken, direction: bool
112
+ ) -> OutcomeToken:
114
113
  """Returns number of outcome tokens returned for a given bet expressed in collateral units."""
115
114
 
116
115
  outcome_token = self.get_wrapped_token_for_outcome(direction)
117
-
118
- bet_amount_in_wei = self._convert_bet_amount_into_wei(bet_amount=bet_amount)
116
+ bet_amount_in_tokens = self.get_in_token(bet_amount)
117
+ bet_amount_in_wei = bet_amount_in_tokens.as_wei
119
118
 
120
119
  quote = CowManager().get_quote(
121
120
  buy_token=outcome_token,
122
121
  sell_amount=bet_amount_in_wei,
123
122
  collateral_token=self.collateral_token_contract_address_checksummed,
124
123
  )
125
- sell_amount = wei_to_xdai(wei_type(quote.quote.buyAmount.root))
126
- return TokenAmount(amount=sell_amount, currency=bet_amount.currency)
124
+ sell_amount = OutcomeWei(quote.quote.buyAmount.root).as_outcome_token
125
+ return sell_amount
127
126
 
128
127
  def get_outcome_str_from_bool(self, outcome: bool) -> OutcomeStr:
129
128
  outcome_translated = SeerOutcomeEnum.from_bool(outcome)
@@ -131,33 +130,46 @@ class SeerAgentMarket(AgentMarket):
131
130
  return OutcomeStr(self.outcomes[idx])
132
131
 
133
132
  @staticmethod
134
- def get_trade_balance(api_keys: APIKeys) -> float:
133
+ def get_trade_balance(api_keys: APIKeys) -> USD:
135
134
  return OmenAgentMarket.get_trade_balance(api_keys=api_keys)
136
135
 
137
- @classmethod
138
- def get_tiny_bet_amount(cls) -> BetAmount:
139
- return BetAmount(amount=SEER_TINY_BET_AMOUNT, currency=cls.currency)
136
+ def get_tiny_bet_amount(self) -> CollateralToken:
137
+ return self.get_in_token(SEER_TINY_BET_AMOUNT)
140
138
 
141
- def get_position(self, user_id: str, web3: Web3 | None = None) -> Position | None:
139
+ def get_position(
140
+ self, user_id: str, web3: Web3 | None = None
141
+ ) -> ExistingPosition | None:
142
142
  """
143
143
  Fetches position from the user in a given market.
144
144
  We ignore the INVALID balances since we are only interested in binary outcomes.
145
145
  """
146
146
 
147
- amounts = {}
147
+ amounts_ot: dict[OutcomeStr, OutcomeToken] = {}
148
148
 
149
149
  for outcome in [True, False]:
150
150
  wrapped_token = self.get_wrapped_token_for_outcome(outcome)
151
151
 
152
- outcome_token_balance = ContractERC20OnGnosisChain(
153
- address=wrapped_token
154
- ).balanceOf(for_address=Web3.to_checksum_address(user_id), web3=web3)
155
- outcome_str = self.get_outcome_str_from_bool(outcome=outcome)
156
- amounts[outcome_str] = TokenAmount(
157
- amount=wei_to_xdai(outcome_token_balance), currency=self.currency
152
+ outcome_token_balance_wei = OutcomeWei.from_wei(
153
+ ContractERC20OnGnosisChain(address=wrapped_token).balanceOf(
154
+ for_address=Web3.to_checksum_address(user_id), web3=web3
155
+ )
158
156
  )
159
-
160
- return Position(market_id=self.id, amounts=amounts)
157
+ outcome_str = self.get_outcome_str_from_bool(outcome=outcome)
158
+ amounts_ot[outcome_str] = outcome_token_balance_wei.as_outcome_token
159
+
160
+ amounts_current = {
161
+ k: self.get_token_in_usd(self.get_sell_value_of_outcome_token(k, v))
162
+ for k, v in amounts_ot.items()
163
+ }
164
+ amounts_potential = {
165
+ k: self.get_token_in_usd(v.as_token) for k, v in amounts_ot.items()
166
+ }
167
+ return ExistingPosition(
168
+ market_id=self.id,
169
+ amounts_current=amounts_current,
170
+ amounts_potential=amounts_potential,
171
+ amounts_ot=amounts_ot,
172
+ )
161
173
 
162
174
  @staticmethod
163
175
  def get_user_id(api_keys: APIKeys) -> str:
@@ -172,33 +184,6 @@ class SeerAgentMarket(AgentMarket):
172
184
  def verify_operational_balance(api_keys: APIKeys) -> bool:
173
185
  return OmenAgentMarket.verify_operational_balance(api_keys=api_keys)
174
186
 
175
- @staticmethod
176
- def from_data_model_with_subgraph(
177
- model: SeerMarket, seer_subgraph: SeerSubgraphHandler
178
- ) -> "SeerAgentMarket":
179
- p = PriceManager(seer_market=model, seer_subgraph=seer_subgraph)
180
- current_p_yes = p.current_p_yes()
181
-
182
- return SeerAgentMarket(
183
- id=model.id.hex(),
184
- question=model.title,
185
- creator=model.creator,
186
- created_time=model.created_time,
187
- outcomes=model.outcomes,
188
- collateral_token_contract_address_checksummed=model.collateral_token_contract_address_checksummed,
189
- condition_id=model.condition_id,
190
- url=model.url,
191
- close_time=model.close_time,
192
- wrapped_tokens=[Web3.to_checksum_address(i) for i in model.wrapped_tokens],
193
- fees=MarketFees.get_zero_fees(),
194
- outcome_token_pool=None,
195
- resolution=model.get_resolution_enum(),
196
- volume=None,
197
- # current_p_yes=model.current_p_yes,
198
- current_p_yes=current_p_yes,
199
- seer_outcomes=model.outcome_as_enums,
200
- )
201
-
202
187
  @staticmethod
203
188
  def from_data_model(model: SeerMarket) -> "SeerAgentMarket":
204
189
  return SeerAgentMarket(
@@ -216,7 +201,7 @@ class SeerAgentMarket(AgentMarket):
216
201
  outcome_token_pool=None,
217
202
  resolution=model.get_resolution_enum(),
218
203
  volume=None,
219
- current_p_yes=Probability(123), # ToDo dont use this method
204
+ current_p_yes=model.current_p_yes,
220
205
  seer_outcomes=model.outcome_as_enums,
221
206
  )
222
207
 
@@ -228,16 +213,13 @@ class SeerAgentMarket(AgentMarket):
228
213
  created_after: t.Optional[DatetimeUTC] = None,
229
214
  excluded_questions: set[str] | None = None,
230
215
  ) -> t.Sequence["SeerAgentMarket"]:
231
- seer_subgraph = SeerSubgraphHandler()
232
- markets = seer_subgraph.get_binary_markets(
233
- limit=limit, sort_by=sort_by, filter_by=filter_by
234
- )
235
-
236
216
  return [
237
- SeerAgentMarket.from_data_model_with_subgraph(
238
- model=m, seer_subgraph=seer_subgraph
217
+ SeerAgentMarket.from_data_model(m)
218
+ for m in SeerSubgraphHandler().get_binary_markets(
219
+ limit=limit,
220
+ sort_by=sort_by,
221
+ filter_by=filter_by,
239
222
  )
240
- for m in markets
241
223
  ]
242
224
 
243
225
  def has_liquidity_for_outcome(self, outcome: bool) -> bool:
@@ -246,9 +228,9 @@ class SeerAgentMarket(AgentMarket):
246
228
  CowManager().get_quote(
247
229
  collateral_token=self.collateral_token_contract_address_checksummed,
248
230
  buy_token=outcome_token,
249
- sell_amount=xdai_to_wei(
250
- xdai_type(1)
251
- ), # we take 1 xDai as a baseline value for common trades the agents take.
231
+ sell_amount=CollateralToken(
232
+ 1
233
+ ).as_wei, # we take 1 as a baseline value for common trades the agents take.
252
234
  )
253
235
  return True
254
236
  except NoLiquidityAvailableOnCowException:
@@ -272,7 +254,7 @@ class SeerAgentMarket(AgentMarket):
272
254
  def place_bet(
273
255
  self,
274
256
  outcome: bool,
275
- amount: BetAmount,
257
+ amount: USD,
276
258
  auto_deposit: bool = True,
277
259
  web3: Web3 | None = None,
278
260
  api_keys: APIKeys | None = None,
@@ -283,32 +265,27 @@ class SeerAgentMarket(AgentMarket):
283
265
  f"Market {self.id} is not open for trading. Cannot place bet."
284
266
  )
285
267
 
286
- if amount.currency != self.currency:
287
- raise ValueError(f"Seer bets are made in xDai. Got {amount.currency}.")
268
+ amount_in_token = self.get_usd_in_token(amount)
269
+ amount_wei = amount_in_token.as_wei
270
+ collateral_contract = self.get_collateral_token_contract()
288
271
 
289
- collateral_contract = sDaiContract()
290
272
  if auto_deposit:
291
- # We convert the deposit amount (in sDai) to assets in order to convert.
292
- asset_amount = collateral_contract.convertToAssets(
293
- xdai_to_wei(xdai_type(amount.amount))
294
- )
295
273
  auto_deposit_collateral_token(
296
- collateral_contract, asset_amount, api_keys, web3
274
+ collateral_contract, amount_wei, api_keys, web3
297
275
  )
298
276
 
299
- # We require that amount is given in sDAI.
300
- collateral_balance = get_balances(address=api_keys.bet_from_address, web3=web3)
301
- if collateral_balance.sdai < amount.amount:
277
+ collateral_balance = collateral_contract.balanceOf(api_keys.bet_from_address)
278
+ if collateral_balance < amount_wei:
302
279
  raise ValueError(
303
- f"Balance {collateral_balance.sdai} not enough for bet size {amount.amount}"
280
+ f"Balance {collateral_balance} not enough for bet size {amount}"
304
281
  )
305
282
 
306
283
  outcome_token = self.get_wrapped_token_for_outcome(outcome)
307
- # Sell sDAI using token address
284
+ # Sell using token address
308
285
  order_metadata = CowManager().swap(
309
- amount=xdai_type(amount.amount),
286
+ amount=amount_in_token,
310
287
  sell_token=collateral_contract.address,
311
- buy_token=Web3.to_checksum_address(outcome_token),
288
+ buy_token=outcome_token,
312
289
  api_keys=api_keys,
313
290
  web3=web3,
314
291
  )
@@ -318,18 +295,17 @@ class SeerAgentMarket(AgentMarket):
318
295
 
319
296
  def seer_create_market_tx(
320
297
  api_keys: APIKeys,
321
- initial_funds: xDai,
298
+ initial_funds: USD | CollateralToken,
322
299
  question: str,
323
300
  opening_time: DatetimeUTC,
324
301
  language: str,
325
- outcomes: list[str],
302
+ outcomes: t.Sequence[OutcomeStr],
326
303
  auto_deposit: bool,
327
304
  category: str,
328
305
  min_bond_xdai: xDai,
329
306
  web3: Web3 | None = None,
330
307
  ) -> ChecksumAddress:
331
308
  web3 = web3 or SeerMarketFactory.get_web3() # Default to Gnosis web3.
332
- initial_funds_wei = xdai_to_wei(initial_funds)
333
309
 
334
310
  factory_contract = SeerMarketFactory()
335
311
  collateral_token_address = factory_contract.collateral_token(web3=web3)
@@ -337,24 +313,26 @@ def seer_create_market_tx(
337
313
  init_collateral_token_contract(collateral_token_address, web3)
338
314
  )
339
315
 
316
+ initial_funds_in_collateral = (
317
+ get_usd_in_token(initial_funds, collateral_token_address)
318
+ if isinstance(initial_funds, USD)
319
+ else initial_funds
320
+ )
321
+ initial_funds_in_collateral_wei = initial_funds_in_collateral.as_wei
322
+
340
323
  if auto_deposit:
341
324
  auto_deposit_collateral_token(
342
325
  collateral_token_contract=collateral_token_contract,
343
326
  api_keys=api_keys,
344
- amount_wei=initial_funds_wei,
327
+ collateral_amount_wei_or_usd=initial_funds_in_collateral_wei,
345
328
  web3=web3,
346
329
  )
347
330
 
348
- # In case of ERC4626, obtained (for example) sDai out of xDai could be lower than the `amount_wei`, so we need to handle it.
349
- initial_funds_in_shares = collateral_token_contract.get_in_shares(
350
- amount=initial_funds_wei, web3=web3
351
- )
352
-
353
331
  # Approve the market maker to withdraw our collateral token.
354
332
  collateral_token_contract.approve(
355
333
  api_keys=api_keys,
356
334
  for_address=factory_contract.address,
357
- amount_wei=initial_funds_in_shares,
335
+ amount_wei=initial_funds_in_collateral_wei,
358
336
  web3=web3,
359
337
  )
360
338
 
@@ -365,7 +343,7 @@ def seer_create_market_tx(
365
343
  opening_time=opening_time,
366
344
  language=language,
367
345
  category=category,
368
- min_bond_xdai=min_bond_xdai,
346
+ min_bond=min_bond_xdai,
369
347
  )
370
348
  tx_receipt = factory_contract.create_categorical_market(
371
349
  api_keys=api_keys, params=params, web3=web3
@@ -1,11 +1,17 @@
1
1
  import os
2
+ import typing as t
2
3
 
3
4
  from web3 import Web3
4
5
  from web3.types import TxReceipt
5
6
 
6
7
  from prediction_market_agent_tooling.config import APIKeys
7
- from prediction_market_agent_tooling.gtypes import ABI, ChecksumAddress, xDai
8
- from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
8
+ from prediction_market_agent_tooling.gtypes import (
9
+ ABI,
10
+ ChecksumAddress,
11
+ OutcomeStr,
12
+ xDai,
13
+ )
14
+ from prediction_market_agent_tooling.markets.seer.data_models import (
9
15
  CreateCategoricalMarketsParams,
10
16
  )
11
17
  from prediction_market_agent_tooling.tools.contract import (
@@ -13,7 +19,6 @@ from prediction_market_agent_tooling.tools.contract import (
13
19
  abi_field_validator,
14
20
  )
15
21
  from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
16
- from prediction_market_agent_tooling.tools.web3_utils import xdai_to_wei
17
22
 
18
23
 
19
24
  class SeerMarketFactory(ContractOnGnosisChain):
@@ -31,9 +36,9 @@ class SeerMarketFactory(ContractOnGnosisChain):
31
36
  @staticmethod
32
37
  def build_market_params(
33
38
  market_question: str,
34
- outcomes: list[str],
39
+ outcomes: t.Sequence[OutcomeStr],
35
40
  opening_time: DatetimeUTC,
36
- min_bond_xdai: xDai,
41
+ min_bond: xDai,
37
42
  language: str = "en_US",
38
43
  category: str = "misc",
39
44
  ) -> CreateCategoricalMarketsParams:
@@ -42,7 +47,7 @@ class SeerMarketFactory(ContractOnGnosisChain):
42
47
  token_names=[
43
48
  o.upper() for o in outcomes
44
49
  ], # Following usual token names on Seer (YES,NO).
45
- min_bond=xdai_to_wei(min_bond_xdai),
50
+ min_bond=min_bond.as_xdai_wei.value,
46
51
  opening_time=int(opening_time.timestamp()),
47
52
  outcomes=outcomes,
48
53
  lang=language,
@@ -5,17 +5,17 @@ from typing import Any
5
5
  from subgrounds import FieldPath
6
6
  from web3.constants import ADDRESS_ZERO
7
7
 
8
- from prediction_market_agent_tooling.gtypes import ChecksumAddress
9
8
  from prediction_market_agent_tooling.markets.agent_market import FilterBy, SortBy
10
9
  from prediction_market_agent_tooling.markets.base_subgraph_handler import (
11
10
  BaseSubgraphHandler,
12
11
  )
13
12
  from prediction_market_agent_tooling.markets.seer.data_models import (
14
13
  SeerMarket,
14
+ SeerPool,
15
15
  )
16
- from prediction_market_agent_tooling.markets.seer.subgraph_data_models import SeerPool
17
16
  from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
18
17
  from prediction_market_agent_tooling.tools.utils import to_int_timestamp, utcnow
18
+ from prediction_market_agent_tooling.tools.web3_utils import unwrap_generic_value
19
19
 
20
20
 
21
21
  class SeerSubgraphHandler(BaseSubgraphHandler):
@@ -50,7 +50,6 @@ class SeerSubgraphHandler(BaseSubgraphHandler):
50
50
  markets_field.creator,
51
51
  markets_field.conditionId,
52
52
  markets_field.marketName,
53
- markets_field.outcomesSupply,
54
53
  markets_field.parentOutcome,
55
54
  markets_field.outcomes,
56
55
  markets_field.payoutReported,
@@ -122,16 +121,12 @@ class SeerSubgraphHandler(BaseSubgraphHandler):
122
121
  match sort_by:
123
122
  case SortBy.NEWEST:
124
123
  sort_direction = "desc"
125
- sort_by_field = self.seer_subgraph.Market.blockTimestamp
124
+ sort_by_field = self.seer_subgraph.Market.block_timestamp
126
125
  case SortBy.CLOSING_SOONEST:
127
126
  sort_direction = "asc"
128
- sort_by_field = self.seer_subgraph.Market.openingTs
129
- case SortBy.HIGHEST_LIQUIDITY | SortBy.LOWEST_LIQUIDITY:
130
- sort_direction = (
131
- "desc" if sort_by == SortBy.HIGHEST_LIQUIDITY else "asc"
132
- )
133
- sort_by_field = self.seer_subgraph.Market.outcomesSupply
134
- case SortBy.NONE:
127
+ sort_by_field = self.seer_subgraph.Market.opening_ts
128
+ # ToDo - Implement liquidity conditions by looking up Swapr subgraph.
129
+ case SortBy.NONE | SortBy.HIGHEST_LIQUIDITY | SortBy.LOWEST_LIQUIDITY:
135
130
  sort_direction = None
136
131
  sort_by_field = None
137
132
  case _:
@@ -164,7 +159,7 @@ class SeerSubgraphHandler(BaseSubgraphHandler):
164
159
  first=(
165
160
  limit if limit else sys.maxsize
166
161
  ), # if not limit, we fetch all possible markets,
167
- where=where_stms,
162
+ where=unwrap_generic_value(where_stms),
168
163
  **optional_params,
169
164
  )
170
165
  fields = self._get_fields_for_markets(markets_field)
@@ -206,9 +201,6 @@ class SeerSubgraphHandler(BaseSubgraphHandler):
206
201
  fields = [
207
202
  pools_field.id,
208
203
  pools_field.liquidity,
209
- pools_field.sqrtPrice,
210
- pools_field.token0Price,
211
- pools_field.token1Price,
212
204
  pools_field.token0.id,
213
205
  pools_field.token0.name,
214
206
  pools_field.token0.symbol,
@@ -218,19 +210,19 @@ class SeerSubgraphHandler(BaseSubgraphHandler):
218
210
  ]
219
211
  return fields
220
212
 
221
- def get_pool_by_token(self, token_address: ChecksumAddress) -> SeerPool | None:
213
+ def get_swapr_pools_for_market(self, market: SeerMarket) -> list[SeerPool]:
222
214
  # We iterate through the wrapped tokens and put them in a where clause so that we hit the subgraph endpoint just once.
223
215
  wheres = []
224
- wheres.extend(
225
- [
226
- {"token0": token_address.lower()},
227
- {"token1": token_address.lower()},
228
- ]
216
+ for wrapped_token in market.wrapped_tokens:
217
+ wheres.extend(
218
+ [
219
+ {"token0": wrapped_token.lower()},
220
+ {"token1": wrapped_token.lower()},
221
+ ]
222
+ )
223
+ pools_field = self.swapr_algebra_subgraph.Query.pools(
224
+ where=unwrap_generic_value({"or": wheres})
229
225
  )
230
- pools_field = self.swapr_algebra_subgraph.Query.pools(where={"or": wheres})
231
226
  fields = self._get_fields_for_pools(pools_field)
232
227
  pools = self.do_query(fields=fields, pydantic_model=SeerPool)
233
- # We assume there is only one pool for outcomeToken/sDAI.
234
- if pools:
235
- return pools[0]
236
- return None
228
+ return pools
@@ -186,12 +186,12 @@ def monitor_agent(agent: DeployedAgent) -> None:
186
186
  return
187
187
  bets_info = {
188
188
  "Market Question": [bet.market_question for bet in agent_bets],
189
- "Bet Amount": [bet.amount.amount for bet in agent_bets],
189
+ "Bet Amount": [bet.amount for bet in agent_bets],
190
190
  "Bet Outcome": [bet.outcome for bet in agent_bets],
191
191
  "Created Time": [bet.created_time for bet in agent_bets],
192
192
  "Resolved Time": [bet.resolved_time for bet in agent_bets],
193
193
  "Is Correct": [bet.is_correct for bet in agent_bets],
194
- "Profit": [round(bet.profit.amount, 2) for bet in agent_bets],
194
+ "Profit": [round(bet.profit, 2) for bet in agent_bets],
195
195
  }
196
196
 
197
197
  # Time column to use for x-axes and sorting