prediction-market-agent-tooling 0.43.2__py3-none-any.whl → 0.44.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 (20) hide show
  1. prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +279 -0
  2. prediction_market_agent_tooling/abis/erc20.abi.json +221 -314
  3. prediction_market_agent_tooling/abis/erc4626.abi.json +623 -0
  4. prediction_market_agent_tooling/abis/proxy.abi.json +24 -0
  5. prediction_market_agent_tooling/gtypes.py +1 -1
  6. prediction_market_agent_tooling/markets/agent_market.py +2 -1
  7. prediction_market_agent_tooling/markets/manifold/manifold.py +3 -2
  8. prediction_market_agent_tooling/markets/omen/data_models.py +2 -1
  9. prediction_market_agent_tooling/markets/omen/omen.py +81 -62
  10. prediction_market_agent_tooling/markets/omen/omen_contracts.py +37 -12
  11. prediction_market_agent_tooling/markets/omen/omen_resolving.py +15 -5
  12. prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +15 -0
  13. prediction_market_agent_tooling/markets/polymarket/polymarket.py +2 -1
  14. prediction_market_agent_tooling/tools/contract.py +360 -10
  15. {prediction_market_agent_tooling-0.43.2.dist-info → prediction_market_agent_tooling-0.44.0.dist-info}/METADATA +1 -1
  16. {prediction_market_agent_tooling-0.43.2.dist-info → prediction_market_agent_tooling-0.44.0.dist-info}/RECORD +19 -17
  17. prediction_market_agent_tooling/abis/wxdai.abi.json +0 -279
  18. {prediction_market_agent_tooling-0.43.2.dist-info → prediction_market_agent_tooling-0.44.0.dist-info}/LICENSE +0 -0
  19. {prediction_market_agent_tooling-0.43.2.dist-info → prediction_market_agent_tooling-0.44.0.dist-info}/WHEEL +0 -0
  20. {prediction_market_agent_tooling-0.43.2.dist-info → prediction_market_agent_tooling-0.44.0.dist-info}/entry_points.txt +0 -0
@@ -32,6 +32,7 @@ OMEN_TRUE_OUTCOME = "Yes"
32
32
  OMEN_FALSE_OUTCOME = "No"
33
33
  INVALID_ANSWER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
34
34
  OMEN_BASE_URL = "https://aiomen.eth.limo"
35
+ PRESAGIO_BASE_URL = "https://presagio.pages.dev"
35
36
 
36
37
 
37
38
  def get_boolean_outcome(outcome_str: str) -> bool:
@@ -325,7 +326,7 @@ class OmenMarket(BaseModel):
325
326
 
326
327
  @property
327
328
  def url(self) -> str:
328
- return f"{OMEN_BASE_URL}/#/{self.id}"
329
+ return f"{PRESAGIO_BASE_URL}/markets?id={self.id}"
329
330
 
330
331
 
331
332
  class OmenBetCreator(BaseModel):
@@ -2,6 +2,7 @@ import sys
2
2
  import typing as t
3
3
  from datetime import datetime
4
4
 
5
+ import tenacity
5
6
  from web3 import Web3
6
7
  from web3.constants import HASH_ZERO
7
8
 
@@ -32,9 +33,9 @@ from prediction_market_agent_tooling.markets.data_models import (
32
33
  TokenAmount,
33
34
  )
34
35
  from prediction_market_agent_tooling.markets.omen.data_models import (
35
- OMEN_BASE_URL,
36
36
  OMEN_FALSE_OUTCOME,
37
37
  OMEN_TRUE_OUTCOME,
38
+ PRESAGIO_BASE_URL,
38
39
  Condition,
39
40
  OmenBet,
40
41
  OmenMarket,
@@ -43,17 +44,24 @@ from prediction_market_agent_tooling.markets.omen.data_models import (
43
44
  from prediction_market_agent_tooling.markets.omen.omen_contracts import (
44
45
  OMEN_DEFAULT_MARKET_FEE,
45
46
  Arbitrator,
46
- OmenCollateralTokenContract,
47
47
  OmenConditionalTokenContract,
48
48
  OmenFixedProductMarketMakerContract,
49
49
  OmenFixedProductMarketMakerFactoryContract,
50
50
  OmenOracleContract,
51
51
  OmenRealitioContract,
52
+ WrappedxDaiContract,
52
53
  )
53
54
  from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
54
55
  OmenSubgraphHandler,
55
56
  )
56
57
  from prediction_market_agent_tooling.tools.balances import get_balances
58
+ from prediction_market_agent_tooling.tools.contract import (
59
+ ContractDepositableWrapperERC20BaseClass,
60
+ ContractERC4626BaseClass,
61
+ auto_deposit_collateral_token,
62
+ init_collateral_token_contract,
63
+ to_gnosis_chain_contract,
64
+ )
57
65
  from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
58
66
  from prediction_market_agent_tooling.tools.utils import (
59
67
  calculate_sell_amount_in_collateral,
@@ -75,7 +83,7 @@ class OmenAgentMarket(AgentMarket):
75
83
  """
76
84
 
77
85
  currency: t.ClassVar[Currency] = Currency.xDai
78
- base_url: t.ClassVar[str] = OMEN_BASE_URL
86
+ base_url: t.ClassVar[str] = PRESAGIO_BASE_URL
79
87
  creator: HexAddress
80
88
 
81
89
  collateral_token_contract_address_checksummed: ChecksumAddress
@@ -134,11 +142,12 @@ class OmenAgentMarket(AgentMarket):
134
142
  def get_liquidity(self) -> TokenAmount:
135
143
  return TokenAmount(
136
144
  amount=self.get_liquidity_in_xdai(),
137
- currency=Currency.xDai,
145
+ currency=self.currency,
138
146
  )
139
147
 
140
- def get_tiny_bet_amount(self) -> BetAmount:
141
- return BetAmount(amount=0.00001, currency=self.currency)
148
+ @classmethod
149
+ def get_tiny_bet_amount(cls) -> BetAmount:
150
+ return BetAmount(amount=0.00001, currency=cls.currency)
142
151
 
143
152
  def place_bet(
144
153
  self,
@@ -381,7 +390,7 @@ class OmenAgentMarket(AgentMarket):
381
390
  )
382
391
  return TokenAmount(
383
392
  amount=wei_to_xdai(balances[index_set]),
384
- currency=Currency.xDai,
393
+ currency=self.currency,
385
394
  )
386
395
 
387
396
  @classmethod
@@ -437,7 +446,7 @@ class OmenAgentMarket(AgentMarket):
437
446
 
438
447
  amounts[outecome_str] = TokenAmount(
439
448
  amount=wei_to_xdai(omen_position.totalBalance),
440
- currency=Currency.xDai,
449
+ currency=cls.currency,
441
450
  )
442
451
 
443
452
  positions.append(Position(market_id=market.id, amounts=amounts))
@@ -503,7 +512,7 @@ class OmenAgentMarket(AgentMarket):
503
512
  no_price = check_not_none(market.get_last_trade_no_outcome_price())
504
513
  total_position_value += no_tokens * no_price
505
514
 
506
- return BetAmount(amount=total_position_value, currency=Currency.xDai)
515
+ return BetAmount(amount=total_position_value, currency=cls.currency)
507
516
 
508
517
  @classmethod
509
518
  def get_user_url(cls, keys: APIKeys) -> str:
@@ -523,6 +532,11 @@ def pick_binary_market(
523
532
  )[0]
524
533
 
525
534
 
535
+ @tenacity.retry(
536
+ stop=tenacity.stop_after_attempt(3),
537
+ wait=tenacity.wait_fixed(1),
538
+ after=lambda x: logger.debug(f"omen_buy_outcome_tx failed, {x.attempt_number=}."),
539
+ )
526
540
  def omen_buy_outcome_tx(
527
541
  api_keys: APIKeys,
528
542
  amount: xDai,
@@ -535,11 +549,9 @@ def omen_buy_outcome_tx(
535
549
  Bets the given amount of xDai for the given outcome in the given market.
536
550
  """
537
551
  amount_wei = xdai_to_wei(amount)
538
- from_address_checksummed = api_keys.bet_from_address
539
552
 
540
553
  market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
541
-
542
- collateral_token_contract = OmenCollateralTokenContract()
554
+ collateral_token_contract = market_contract.get_collateral_token_contract()
543
555
 
544
556
  # Get the index of the outcome we want to buy.
545
557
  outcome_index: int = market.get_outcome_index(outcome)
@@ -557,16 +569,12 @@ def omen_buy_outcome_tx(
557
569
  amount_wei=amount_wei,
558
570
  web3=web3,
559
571
  )
560
- # Deposit xDai to the collateral token,
561
- # this can be skipped, if we know we already have enough collateral tokens.
562
- collateral_token_balance = collateral_token_contract.balanceOf(
563
- for_address=from_address_checksummed, web3=web3
564
- )
565
- if auto_deposit and collateral_token_balance < amount_wei:
566
- deposit_amount_wei = Wei(amount_wei - collateral_token_balance)
567
- collateral_token_contract.deposit(
568
- api_keys=api_keys, amount_wei=deposit_amount_wei, web3=web3
572
+
573
+ if auto_deposit:
574
+ auto_deposit_collateral_token(
575
+ collateral_token_contract, amount_wei, api_keys, web3
569
576
  )
577
+
570
578
  # Buy shares using the deposited xDai in the collateral token.
571
579
  market_contract.buy(
572
580
  api_keys=api_keys,
@@ -614,7 +622,7 @@ def omen_sell_outcome_tx(
614
622
 
615
623
  market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
616
624
  conditional_token_contract = OmenConditionalTokenContract()
617
- collateral_token = OmenCollateralTokenContract()
625
+ collateral_token_contract = market_contract.get_collateral_token_contract()
618
626
 
619
627
  # Verify, that markets uses conditional tokens that we expect.
620
628
  if (
@@ -650,9 +658,20 @@ def omen_sell_outcome_tx(
650
658
  max_outcome_tokens_to_sell,
651
659
  web3=web3,
652
660
  )
653
- if auto_withdraw:
654
- # Optionally, withdraw from the collateral token back to the `from_address` wallet.
655
- collateral_token.withdraw(api_keys=api_keys, amount_wei=amount_wei, web3=web3)
661
+ if auto_withdraw and (
662
+ isinstance(collateral_token_contract, ContractERC4626BaseClass)
663
+ or isinstance(
664
+ collateral_token_contract, ContractDepositableWrapperERC20BaseClass
665
+ )
666
+ ):
667
+ collateral_token_contract.withdraw(
668
+ api_keys,
669
+ remove_fraction(
670
+ amount_wei,
671
+ 0.001, # Allow 0.1% slippage.
672
+ ),
673
+ web3,
674
+ )
656
675
 
657
676
 
658
677
  def binary_omen_sell_outcome_tx(
@@ -683,17 +702,22 @@ def omen_create_market_tx(
683
702
  outcomes: list[str],
684
703
  auto_deposit: bool,
685
704
  fee: float = OMEN_DEFAULT_MARKET_FEE,
705
+ collateral_token_address: ChecksumAddress = WrappedxDaiContract().address,
686
706
  web3: Web3 | None = None,
687
707
  ) -> ChecksumAddress:
688
708
  """
689
709
  Based on omen-exchange TypeScript code: https://github.com/protofire/omen-exchange/blob/b0b9a3e71b415d6becf21fe428e1c4fc0dad2e80/app/src/services/cpk/cpk.ts#L308
690
710
  """
691
- from_address = api_keys.bet_from_address
711
+ web3 = (
712
+ web3 or OmenFixedProductMarketMakerFactoryContract.get_web3()
713
+ ) # Default to Gnosis web3.
692
714
  initial_funds_wei = xdai_to_wei(initial_funds)
693
715
 
694
716
  realitio_contract = OmenRealitioContract()
695
717
  conditional_token_contract = OmenConditionalTokenContract()
696
- collateral_token_contract = OmenCollateralTokenContract()
718
+ collateral_token_contract = to_gnosis_chain_contract(
719
+ init_collateral_token_contract(collateral_token_address, web3)
720
+ )
697
721
  factory_contract = OmenFixedProductMarketMakerFactoryContract()
698
722
  oracle_contract = OmenOracleContract()
699
723
 
@@ -709,25 +733,13 @@ def omen_create_market_tx(
709
733
  "The oracle's conditional tokens address is not the same as we are using."
710
734
  )
711
735
 
712
- # Approve the market maker to withdraw our collateral token.
713
- collateral_token_contract.approve(
714
- api_keys=api_keys,
715
- for_address=factory_contract.address,
716
- amount_wei=initial_funds_wei,
717
- web3=web3,
718
- )
719
-
720
- # Deposit xDai to the collateral token,
721
- # this can be skipped, if we know we already have enough collateral tokens.
722
- collateral_token_balance = collateral_token_contract.balanceOf(
723
- for_address=from_address, web3=web3
724
- )
725
- if (
726
- auto_deposit
727
- and initial_funds_wei > 0
728
- and collateral_token_balance < initial_funds_wei
729
- ):
730
- collateral_token_contract.deposit(api_keys, initial_funds_wei, web3=web3)
736
+ if auto_deposit:
737
+ auto_deposit_collateral_token(
738
+ collateral_token_contract=collateral_token_contract,
739
+ api_keys=api_keys,
740
+ amount_wei=initial_funds_wei,
741
+ web3=web3,
742
+ )
731
743
 
732
744
  # Create the question on Realitio.
733
745
  question_id = realitio_contract.askQuestion(
@@ -757,12 +769,25 @@ def omen_create_market_tx(
757
769
  web3=web3,
758
770
  )
759
771
 
772
+ initial_funds_in_shares = collateral_token_contract.get_in_shares(
773
+ amount=initial_funds_wei, web3=web3
774
+ )
775
+
776
+ # Approve the market maker to withdraw our collateral token.
777
+ collateral_token_contract.approve(
778
+ api_keys=api_keys,
779
+ for_address=factory_contract.address,
780
+ amount_wei=initial_funds_in_shares,
781
+ web3=web3,
782
+ )
783
+
760
784
  # Create the market.
761
785
  create_market_receipt_tx = factory_contract.create2FixedProductMarketMaker(
762
786
  api_keys=api_keys,
763
787
  condition_id=condition_id,
764
788
  fee=fee,
765
- initial_funds_wei=initial_funds_wei,
789
+ initial_funds_wei=initial_funds_in_shares,
790
+ collateral_token_address=collateral_token_contract.address,
766
791
  web3=web3,
767
792
  )
768
793
 
@@ -784,18 +809,11 @@ def omen_fund_market_tx(
784
809
  auto_deposit: bool,
785
810
  web3: Web3 | None = None,
786
811
  ) -> None:
787
- from_address = api_keys.bet_from_address
788
812
  market_contract = market.get_contract()
789
- collateral_token_contract = OmenCollateralTokenContract()
813
+ collateral_token_contract = market_contract.get_collateral_token_contract()
790
814
 
791
- # Deposit xDai to the collateral token,
792
- # this can be skipped, if we know we already have enough collateral tokens.
793
- if (
794
- auto_deposit
795
- and collateral_token_contract.balanceOf(for_address=from_address, web3=web3)
796
- < funds
797
- ):
798
- collateral_token_contract.deposit(api_keys, funds, web3=web3)
815
+ if auto_deposit:
816
+ auto_deposit_collateral_token(collateral_token_contract, funds, api_keys, web3)
799
817
 
800
818
  collateral_token_contract.approve(
801
819
  api_keys=api_keys,
@@ -907,7 +925,8 @@ def omen_remove_fund_market_tx(
907
925
  """
908
926
  from_address = api_keys.bet_from_address
909
927
  market_contract = market.get_contract()
910
- original_balances = get_balances(from_address, web3=web3)
928
+ market_collateral_token_contract = market_contract.get_collateral_token_contract()
929
+ original_balance = market_collateral_token_contract.balanceOf(from_address)
911
930
 
912
931
  total_shares = market_contract.balanceOf(from_address, web3=web3)
913
932
  if total_shares == 0:
@@ -942,11 +961,11 @@ def omen_remove_fund_market_tx(
942
961
  web3=web3,
943
962
  )
944
963
 
945
- new_balances = get_balances(from_address, web3)
964
+ new_balance = market_collateral_token_contract.balanceOf(from_address)
946
965
 
947
966
  logger.debug(f"Result from merge positions {result}")
948
967
  logger.info(
949
- f"Withdrawn {new_balances.wxdai - original_balances.wxdai} wxDai from liquidity at {market.url=}."
968
+ f"Withdrawn {new_balance - original_balance} {market_collateral_token_contract.symbol_cached()} from liquidity at {market.url=}."
950
969
  )
951
970
 
952
971
 
@@ -1052,8 +1071,8 @@ def withdraw_wxdai_to_xdai_to_keep_balance(
1052
1071
  f"Current wxDai balance {current_balances.wxdai} is less than the required minimum wxDai to withdraw {need_to_withdraw}."
1053
1072
  )
1054
1073
 
1055
- collateral_token_contract = OmenCollateralTokenContract()
1056
- collateral_token_contract.withdraw(
1074
+ wxdai_contract = WrappedxDaiContract()
1075
+ wxdai_contract.withdraw(
1057
1076
  api_keys=api_keys, amount_wei=xdai_to_wei(need_to_withdraw), web3=web3
1058
1077
  )
1059
1078
  logger.info(
@@ -23,9 +23,13 @@ from prediction_market_agent_tooling.gtypes import (
23
23
  xdai_type,
24
24
  )
25
25
  from prediction_market_agent_tooling.tools.contract import (
26
+ ContractDepositableWrapperERC20OnGnosisChain,
26
27
  ContractERC20OnGnosisChain,
28
+ ContractERC4626OnGnosisChain,
27
29
  ContractOnGnosisChain,
28
30
  abi_field_validator,
31
+ init_collateral_token_contract,
32
+ to_gnosis_chain_contract,
29
33
  )
30
34
  from prediction_market_agent_tooling.tools.web3_utils import (
31
35
  ZERO_BYTES,
@@ -291,9 +295,13 @@ class OmenFixedProductMarketMakerContract(ContractOnGnosisChain):
291
295
  )
292
296
  return calculated_shares
293
297
 
294
- def conditionalTokens(self, web3: Web3 | None = None) -> HexAddress:
298
+ def conditionalTokens(self, web3: Web3 | None = None) -> ChecksumAddress:
295
299
  address: HexAddress = self.call("conditionalTokens", web3=web3)
296
- return address
300
+ return Web3.to_checksum_address(address)
301
+
302
+ def collateralToken(self, web3: Web3 | None = None) -> ChecksumAddress:
303
+ address: HexAddress = self.call("collateralToken", web3=web3)
304
+ return Web3.to_checksum_address(address)
297
305
 
298
306
  def buy(
299
307
  self,
@@ -380,21 +388,26 @@ class OmenFixedProductMarketMakerContract(ContractOnGnosisChain):
380
388
  total_supply: Wei = self.call("totalSupply", web3=web3)
381
389
  return total_supply
382
390
 
383
-
384
- class WrappedxDaiContract(ContractERC20OnGnosisChain):
385
- # File content taken from https://gnosisscan.io/address/0xe91d153e0b41518a2ce8dd3d7944fa863463a97d#code.
386
- abi: ABI = abi_field_validator(
387
- os.path.join(
388
- os.path.dirname(os.path.realpath(__file__)), "../../abis/wxdai.abi.json"
391
+ def get_collateral_token_contract(
392
+ self, web3: Web3 | None = None
393
+ ) -> ContractERC20OnGnosisChain:
394
+ web3 = web3 or self.get_web3()
395
+ return to_gnosis_chain_contract(
396
+ init_collateral_token_contract(self.collateralToken(web3=web3), web3)
389
397
  )
390
- )
398
+
399
+
400
+ class WrappedxDaiContract(ContractDepositableWrapperERC20OnGnosisChain):
391
401
  address: ChecksumAddress = Web3.to_checksum_address(
392
402
  "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d"
393
403
  )
394
404
 
395
405
 
396
- # Collateral token used on Omen is wrapped xDai.
397
- OmenCollateralTokenContract = WrappedxDaiContract
406
+ class sDaiContract(ContractERC4626OnGnosisChain):
407
+ address: ChecksumAddress = Web3.to_checksum_address(
408
+ "0xaf204776c7245bF4147c2612BF6e5972Ee483701"
409
+ )
410
+
398
411
 
399
412
  OMEN_DEFAULT_MARKET_FEE = 0.02 # 2% fee from the buying shares amount.
400
413
 
@@ -416,6 +429,7 @@ class OmenFixedProductMarketMakerFactoryContract(ContractOnGnosisChain):
416
429
  api_keys: APIKeys,
417
430
  condition_id: HexBytes,
418
431
  initial_funds_wei: Wei,
432
+ collateral_token_address: ChecksumAddress,
419
433
  fee: float = OMEN_DEFAULT_MARKET_FEE,
420
434
  tx_params: t.Optional[TxParams] = None,
421
435
  web3: Web3 | None = None,
@@ -431,7 +445,7 @@ class OmenFixedProductMarketMakerFactoryContract(ContractOnGnosisChain):
431
445
  0, 1000000
432
446
  ), # See https://github.com/protofire/omen-exchange/blob/923756c3a9ac370f8e89af8193393a53531e2c0f/app/src/services/cpk/fns.ts#L942.
433
447
  conditionalTokens=OmenConditionalTokenContract().address,
434
- collateralToken=OmenCollateralTokenContract().address,
448
+ collateralToken=collateral_token_address,
435
449
  conditionIds=[condition_id],
436
450
  fee=fee_wei,
437
451
  initialFunds=initial_funds_wei,
@@ -678,3 +692,14 @@ class OmenThumbnailMapping(ContractOnGnosisChain):
678
692
  function_params=[market_address],
679
693
  web3=web3,
680
694
  )
695
+
696
+
697
+ class CollateralTokenChoice(str, Enum):
698
+ wxdai = "wxdai"
699
+ sdai = "sdai"
700
+
701
+
702
+ COLLATERAL_TOKEN_CHOICE_TO_ADDRESS = {
703
+ CollateralTokenChoice.wxdai: WrappedxDaiContract().address,
704
+ CollateralTokenChoice.sdai: sDaiContract().address,
705
+ }
@@ -40,6 +40,7 @@ def claim_bonds_on_realitio_questions(
40
40
  questions: list[RealityQuestion],
41
41
  auto_withdraw: bool,
42
42
  web3: Web3 | None = None,
43
+ silent_errors: bool = False,
43
44
  ) -> list[HexBytes]:
44
45
  claimed_questions: list[HexBytes] = []
45
46
 
@@ -47,10 +48,19 @@ def claim_bonds_on_realitio_questions(
47
48
  logger.info(
48
49
  f"[{idx+1} / {len(questions)}] Claiming bond for {question.questionId=} {question.url=}"
49
50
  )
50
- claim_bonds_on_realitio_question(
51
- api_keys, question, auto_withdraw=auto_withdraw, web3=web3
52
- )
53
- claimed_questions.append(question.questionId)
51
+ try:
52
+ claim_bonds_on_realitio_question(
53
+ api_keys, question, auto_withdraw=auto_withdraw, web3=web3
54
+ )
55
+ claimed_questions.append(question.questionId)
56
+ except Exception as e:
57
+ # TODO: This shouldn't be required once `claim_bonds_on_realitio_question` below is fixed.
58
+ if silent_errors:
59
+ logger.warning(
60
+ f"Error while claiming bond for {question.questionId=} {question.url=}: {e}"
61
+ )
62
+ else:
63
+ raise
54
64
 
55
65
  return claimed_questions
56
66
 
@@ -140,7 +150,7 @@ def finalize_markets(
140
150
  )
141
151
 
142
152
  if resolution is None:
143
- logger.error(f"No resolution provided for {market.url=}")
153
+ logger.warning(f"No resolution provided for {market.url=}")
144
154
 
145
155
  elif resolution in (Resolution.YES, Resolution.NO):
146
156
  logger.info(f"Found resolution {resolution.value=} for {market.url=}")
@@ -25,6 +25,8 @@ from prediction_market_agent_tooling.markets.omen.data_models import (
25
25
  )
26
26
  from prediction_market_agent_tooling.markets.omen.omen_contracts import (
27
27
  OmenThumbnailMapping,
28
+ WrappedxDaiContract,
29
+ sDaiContract,
28
30
  )
29
31
  from prediction_market_agent_tooling.tools.singleton import SingletonMeta
30
32
  from prediction_market_agent_tooling.tools.utils import to_int_timestamp, utcnow
@@ -184,6 +186,7 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
184
186
  condition_id_in: list[HexBytes] | None = None,
185
187
  id_in: list[str] | None = None,
186
188
  excluded_questions: set[str] | None = None,
189
+ collateral_token_address_in: tuple[ChecksumAddress, ...] | None = None,
187
190
  ) -> dict[str, t.Any]:
188
191
  where_stms: dict[str, t.Any] = {
189
192
  "isPendingArbitration": False,
@@ -193,6 +196,11 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
193
196
  "condition_": {},
194
197
  }
195
198
 
199
+ if collateral_token_address_in:
200
+ where_stms["collateralToken_in"] = [
201
+ x.lower() for x in collateral_token_address_in
202
+ ]
203
+
196
204
  if creator:
197
205
  where_stms["creator"] = creator
198
206
 
@@ -333,6 +341,12 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
333
341
  sort_by_field: FieldPath | None = None,
334
342
  sort_direction: str | None = None,
335
343
  outcomes: list[str] = [OMEN_TRUE_OUTCOME, OMEN_FALSE_OUTCOME],
344
+ # TODO: Agents don't know how to convert value between other tokens, we assume 1 unit = 1xDai = $1 (for example if market would be in wETH, betting 1 unit of wETH would be crazy :D)
345
+ collateral_token_address_in: tuple[ChecksumAddress, ...]
346
+ | None = (
347
+ WrappedxDaiContract().address,
348
+ sDaiContract().address,
349
+ ),
336
350
  ) -> t.List[OmenMarket]:
337
351
  """
338
352
  Complete method to fetch Omen binary markets with various filters, use `get_omen_binary_markets_simple` for simplified version that uses FilterBy and SortBy enums.
@@ -350,6 +364,7 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
350
364
  id_in=id_in,
351
365
  excluded_questions=excluded_questions,
352
366
  liquidity_bigger_than=liquidity_bigger_than,
367
+ collateral_token_address_in=collateral_token_address_in,
353
368
  )
354
369
 
355
370
  # These values can not be set to `None`, but they can be omitted.
@@ -41,7 +41,8 @@ class PolymarketAgentMarket(AgentMarket):
41
41
  volume=None,
42
42
  )
43
43
 
44
- def get_tiny_bet_amount(self) -> BetAmount:
44
+ @classmethod
45
+ def get_tiny_bet_amount(cls) -> BetAmount:
45
46
  raise NotImplementedError("TODO: Implement to allow betting on Polymarket.")
46
47
 
47
48
  def place_bet(self, outcome: bool, amount: BetAmount) -> None: