prediction-market-agent-tooling 0.68.1__tar.gz → 0.69.1__tar.gz

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 (138) hide show
  1. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/PKG-INFO +1 -1
  2. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/agent.py +13 -2
  3. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/betting_strategy.py +132 -29
  4. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/jobs/omen/omen_jobs.py +14 -17
  5. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/agent_market.py +11 -0
  6. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/markets.py +16 -0
  7. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/data_models.py +40 -5
  8. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/seer.py +44 -8
  9. prediction_market_agent_tooling-0.69.1/prediction_market_agent_tooling/markets/seer/seer_api.py +28 -0
  10. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +68 -21
  11. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/subgraph_data_models.py +41 -4
  12. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +17 -22
  13. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/datetime_utc.py +14 -2
  14. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/langfuse_client_utils.py +17 -5
  15. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/auto_deposit.py +1 -1
  16. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/pyproject.toml +1 -1
  17. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/LICENSE +0 -0
  18. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/README.md +0 -0
  19. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/agentresultmapping.abi.json +0 -0
  20. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/debuggingcontract.abi.json +0 -0
  21. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +0 -0
  22. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/erc1155.abi.json +0 -0
  23. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  24. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/erc4626.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/erc721.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/gvp2_settlement.abi.json +0 -0
  27. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  28. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  29. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  30. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  31. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  32. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  33. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  34. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  35. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/ownable.abi.json +0 -0
  36. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/ownable_erc721.abi.json +0 -0
  37. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/proxy.abi.json +0 -0
  38. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/seer_gnosis_router.abi.json +0 -0
  39. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/seer_market_factory.abi.json +0 -0
  40. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/abis/swapr_router.abi.json +0 -0
  41. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  42. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  43. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  44. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  45. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/chains.py +0 -0
  46. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/config.py +0 -0
  47. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/data_download/langfuse_data_downloader.py +0 -0
  48. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  49. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  50. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  51. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  52. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  53. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/deploy/trade_interval.py +0 -0
  54. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/gtypes.py +0 -0
  55. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/jobs/__init__.py +0 -0
  56. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/jobs/jobs_models.py +0 -0
  57. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/loggers.py +0 -0
  58. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/logprobs_parser.py +0 -0
  59. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/base_subgraph_handler.py +0 -0
  60. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/blockchain_utils.py +0 -0
  61. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  62. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/data_models.py +0 -0
  63. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  64. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  65. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  66. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/manifold/manifold.py +0 -0
  67. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  68. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/market_fees.py +0 -0
  69. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  70. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  71. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +0 -0
  72. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  73. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/cow_contracts.py +0 -0
  74. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/data_models.py +0 -0
  75. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/omen.py +0 -0
  76. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/omen_constants.py +0 -0
  77. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
  78. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  79. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +0 -0
  80. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  81. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/clob_manager.py +0 -0
  82. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/constants.py +0 -0
  83. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  84. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
  85. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/polymarket_contracts.py +0 -0
  86. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/polymarket_subgraph_handler.py +0 -0
  87. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  88. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/exceptions.py +0 -0
  89. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/price_manager.py +0 -0
  90. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/seer_contracts.py +0 -0
  91. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/markets/seer/swap_pool_handler.py +0 -0
  92. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/py.typed +0 -0
  93. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/_generic_value.py +0 -0
  94. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/balances.py +0 -0
  95. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  96. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/betting_strategies/utils.py +0 -0
  97. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/caches/db_cache.py +0 -0
  98. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/caches/inmemory_cache.py +0 -0
  99. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/caches/serializers.py +0 -0
  100. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/contract.py +0 -0
  101. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/costs.py +0 -0
  102. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/cow/cow_order.py +0 -0
  103. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/cow/models.py +0 -0
  104. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/cow/semaphore.py +0 -0
  105. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/custom_exceptions.py +0 -0
  106. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/db/db_manager.py +0 -0
  107. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/google_utils.py +0 -0
  108. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  109. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/httpx_cached_client.py +0 -0
  110. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  111. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +0 -0
  112. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py +0 -0
  113. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/is_invalid.py +0 -0
  114. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
  115. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/langfuse_.py +0 -0
  116. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/omen/reality_accuracy.py +0 -0
  117. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/omen/sell_positions.py +0 -0
  118. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  119. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/perplexity/perplexity_client.py +0 -0
  120. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/perplexity/perplexity_models.py +0 -0
  121. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/perplexity/perplexity_search.py +0 -0
  122. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py +0 -0
  123. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py +0 -0
  124. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +0 -0
  125. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/rephrase.py +0 -0
  126. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/safe.py +0 -0
  127. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  128. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  129. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tavily/tavily_models.py +0 -0
  130. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tavily/tavily_search.py +0 -0
  131. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +0 -0
  132. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/main_token.py +0 -0
  133. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/slippage.py +0 -0
  134. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/token_utils.py +0 -0
  135. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/tokens/usd.py +0 -0
  136. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/transaction_cache.py +0 -0
  137. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/utils.py +0 -0
  138. {prediction_market_agent_tooling-0.68.1 → prediction_market_agent_tooling-0.69.1}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.68.1
3
+ Version: 0.69.1
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -630,7 +630,7 @@ class DeployableTraderAgent(DeployablePredictionAgent):
630
630
  api_keys = APIKeys()
631
631
 
632
632
  # Get the strategy to know how much it will bet.
633
- strategy = self.get_betting_strategy(market)
633
+ strategy = self.get_betting_strategy_supported(market)
634
634
  # Have a little bandwidth after the bet.
635
635
  min_required_balance_to_trade = strategy.maximum_possible_bet_amount * 1.01
636
636
 
@@ -658,13 +658,24 @@ class DeployableTraderAgent(DeployablePredictionAgent):
658
658
  total_amount = self.get_total_amount_to_bet(market)
659
659
  return CategoricalMaxAccuracyBettingStrategy(max_position_amount=total_amount)
660
660
 
661
+ def get_betting_strategy_supported(self, market: AgentMarket) -> BettingStrategy:
662
+ """
663
+ Use this class internally to assert that the configured betting strategy works with the given market.
664
+ """
665
+ strategy = self.get_betting_strategy(market=market)
666
+ if not strategy.is_market_supported(market):
667
+ raise ValueError(
668
+ f"Market {market.url} is not supported by the strategy {strategy}."
669
+ )
670
+ return strategy
671
+
661
672
  def build_trades(
662
673
  self,
663
674
  market: AgentMarket,
664
675
  answer: CategoricalProbabilisticAnswer,
665
676
  existing_position: ExistingPosition | None,
666
677
  ) -> list[Trade]:
667
- strategy = self.get_betting_strategy(market=market)
678
+ strategy = self.get_betting_strategy_supported(market=market)
668
679
  trades = strategy.calculate_trades(existing_position, answer, market)
669
680
  return trades
670
681
 
@@ -16,7 +16,11 @@ from prediction_market_agent_tooling.gtypes import (
16
16
  Probability,
17
17
  )
18
18
  from prediction_market_agent_tooling.loggers import logger
19
- from prediction_market_agent_tooling.markets.agent_market import AgentMarket, MarketFees
19
+ from prediction_market_agent_tooling.markets.agent_market import (
20
+ AgentMarket,
21
+ MarketFees,
22
+ QuestionType,
23
+ )
20
24
  from prediction_market_agent_tooling.markets.data_models import (
21
25
  CategoricalProbabilisticAnswer,
22
26
  ExistingPosition,
@@ -24,10 +28,12 @@ from prediction_market_agent_tooling.markets.data_models import (
24
28
  Trade,
25
29
  TradeType,
26
30
  )
31
+ from prediction_market_agent_tooling.markets.markets import MarketType
27
32
  from prediction_market_agent_tooling.markets.omen.omen import (
28
33
  get_buy_outcome_token_amount,
29
34
  )
30
35
  from prediction_market_agent_tooling.tools.betting_strategies.kelly_criterion import (
36
+ KellyType,
31
37
  get_kelly_bet_full,
32
38
  get_kelly_bet_simplified,
33
39
  get_kelly_bets_categorical_full,
@@ -45,9 +51,21 @@ class GuaranteedLossError(RuntimeError):
45
51
 
46
52
 
47
53
  class BettingStrategy(ABC):
54
+ supported_question_types: set[QuestionType]
55
+ supported_market_types: set[MarketType]
56
+
48
57
  def __init__(self, take_profit: bool = True) -> None:
49
58
  self.take_profit = take_profit
50
59
 
60
+ def is_market_supported(self, market: AgentMarket) -> bool:
61
+ if market.question_type not in self.supported_question_types:
62
+ return False
63
+
64
+ if MarketType.from_market(market) not in self.supported_market_types:
65
+ return False
66
+
67
+ return True
68
+
51
69
  @abstractmethod
52
70
  def calculate_trades(
53
71
  self,
@@ -251,6 +269,13 @@ class BettingStrategy(ABC):
251
269
 
252
270
 
253
271
  class CategoricalMaxAccuracyBettingStrategy(BettingStrategy):
272
+ supported_question_types = {
273
+ QuestionType.BINARY,
274
+ QuestionType.CATEGORICAL,
275
+ QuestionType.SCALAR,
276
+ }
277
+ supported_market_types = {x for x in MarketType if x.is_trading_market}
278
+
254
279
  def __init__(self, max_position_amount: USD, take_profit: bool = True):
255
280
  super().__init__(take_profit=take_profit)
256
281
  self.max_position_amount = max_position_amount
@@ -362,18 +387,20 @@ class MaxExpectedValueBettingStrategy(CategoricalMaxAccuracyBettingStrategy):
362
387
  return f"MaxExpectedValueBettingStrategy(max_position_amount={self.max_position_amount}, take_profit={self.take_profit})"
363
388
 
364
389
 
365
- class BinaryKellyBettingStrategy(BettingStrategy):
390
+ class _BinaryKellyBettingStrategy(BettingStrategy):
391
+ supported_question_types = {QuestionType.BINARY}
392
+
366
393
  def __init__(
367
394
  self,
395
+ kelly_type: KellyType,
368
396
  max_position_amount: USD,
369
397
  max_price_impact: float | None = None,
370
398
  take_profit: bool = True,
371
- force_simplified_calculation: bool = False,
372
399
  ):
373
400
  super().__init__(take_profit=take_profit)
401
+ self.kelly_type = kelly_type
374
402
  self.max_position_amount = max_position_amount
375
403
  self.max_price_impact = max_price_impact
376
- self.force_simplified_calculation = force_simplified_calculation
377
404
 
378
405
  @property
379
406
  def maximum_possible_bet_amount(self) -> USD:
@@ -396,7 +423,7 @@ class BinaryKellyBettingStrategy(BettingStrategy):
396
423
  else override_p_yes
397
424
  )
398
425
 
399
- if market.outcome_token_pool is None or self.force_simplified_calculation:
426
+ if self.kelly_type == KellyType.SIMPLE:
400
427
  kelly_bet = get_kelly_bet_simplified(
401
428
  max_bet=market.get_usd_in_token(self.max_position_amount),
402
429
  market_p_yes=market.probability_for_market_outcome(direction),
@@ -447,7 +474,6 @@ class BinaryKellyBettingStrategy(BettingStrategy):
447
474
  # Adjust amount
448
475
  max_price_impact_bet_amount = self.calculate_bet_amount_for_price_impact(
449
476
  market,
450
- kelly_bet.size,
451
477
  direction=direction,
452
478
  max_price_impact=self.max_price_impact,
453
479
  )
@@ -492,7 +518,6 @@ class BinaryKellyBettingStrategy(BettingStrategy):
492
518
  @staticmethod
493
519
  def calculate_bet_amount_for_price_impact(
494
520
  market: AgentMarket,
495
- kelly_bet_size: CollateralToken,
496
521
  direction: OutcomeStr,
497
522
  max_price_impact: float,
498
523
  ) -> CollateralToken:
@@ -501,7 +526,7 @@ class BinaryKellyBettingStrategy(BettingStrategy):
501
526
  ) -> float:
502
527
  outcome_idx = market.get_outcome_index(direction)
503
528
  price_impact = (
504
- BinaryKellyBettingStrategy.calculate_price_impact_for_bet_amount(
529
+ _BinaryKellyBettingStrategy.calculate_price_impact_for_bet_amount(
505
530
  outcome_idx=outcome_idx,
506
531
  bet_amount=CollateralToken(bet_amount_collateral),
507
532
  pool_balances=pool_balances,
@@ -512,20 +537,13 @@ class BinaryKellyBettingStrategy(BettingStrategy):
512
537
  return abs(price_impact - max_price_impact)
513
538
 
514
539
  if not market.outcome_token_pool:
515
- logger.warning(
540
+ raise ValueError(
516
541
  "Market outcome_token_pool is None, cannot calculate bet amount"
517
542
  )
518
- return kelly_bet_size
519
-
520
- filtered_pool = {
521
- outcome: pool_value
522
- for outcome, pool_value in market.outcome_token_pool.items()
523
- if INVALID_OUTCOME_LOWERCASE_IDENTIFIER not in outcome.lower()
524
- }
525
543
 
526
- pool_balances = [i.as_outcome_wei for i in filtered_pool.values()]
544
+ pool_balances = [i.as_outcome_wei for i in market.outcome_token_pool.values()]
527
545
  # stay float for compatibility with `minimize_scalar`
528
- total_pool_balance = sum([i.value for i in filtered_pool.values()])
546
+ total_pool_balance = sum([i.value for i in market.outcome_token_pool.values()])
529
547
 
530
548
  # The bounds below have been found to work heuristically.
531
549
  optimized_bet_amount = minimize_scalar(
@@ -538,10 +556,47 @@ class BinaryKellyBettingStrategy(BettingStrategy):
538
556
  return CollateralToken(optimized_bet_amount.x)
539
557
 
540
558
  def __repr__(self) -> str:
541
- return f"{self.__class__.__name__}(max_position_amount={self.max_position_amount}, max_price_impact={self.max_price_impact}, take_profit={self.take_profit}, force_simplified_calculation={self.force_simplified_calculation})"
559
+ return f"{self.__class__.__name__}(max_position_amount={self.max_position_amount}, max_price_impact={self.max_price_impact}, take_profit={self.take_profit})"
560
+
561
+
562
+ class SimpleBinaryKellyBettingStrategy(_BinaryKellyBettingStrategy):
563
+ supported_market_types = {x for x in MarketType if x.is_trading_market}
564
+
565
+ def __init__(
566
+ self,
567
+ max_position_amount: USD,
568
+ take_profit: bool = True,
569
+ ):
570
+ super().__init__(
571
+ kelly_type=KellyType.SIMPLE,
572
+ max_position_amount=max_position_amount,
573
+ max_price_impact=None,
574
+ take_profit=take_profit,
575
+ )
576
+
577
+
578
+ class FullBinaryKellyBettingStrategy(_BinaryKellyBettingStrategy):
579
+ # Supports only OMEN because it uses closed-form formula derived from a binary FPMM.
580
+ supported_market_types = {MarketType.OMEN}
581
+
582
+ def __init__(
583
+ self,
584
+ max_position_amount: USD,
585
+ max_price_impact: float | None = None,
586
+ take_profit: bool = True,
587
+ ):
588
+ super().__init__(
589
+ kelly_type=KellyType.FULL,
590
+ max_position_amount=max_position_amount,
591
+ max_price_impact=max_price_impact,
592
+ take_profit=take_profit,
593
+ )
542
594
 
543
595
 
544
596
  class MaxAccuracyWithKellyScaledBetsStrategy(BettingStrategy):
597
+ supported_question_types = {QuestionType.BINARY}
598
+ supported_market_types = {MarketType.OMEN}
599
+
545
600
  def __init__(
546
601
  self,
547
602
  max_position_amount: USD,
@@ -573,7 +628,7 @@ class MaxAccuracyWithKellyScaledBetsStrategy(BettingStrategy):
573
628
  # We ignore the direction nudge given by Kelly, hence we assume we have a perfect prediction.
574
629
  estimated_p_yes = 1.0
575
630
 
576
- kelly_bet = BinaryKellyBettingStrategy(
631
+ kelly_bet = FullBinaryKellyBettingStrategy(
577
632
  max_position_amount=self.max_position_amount
578
633
  ).get_kelly_bet(
579
634
  market=market,
@@ -601,24 +656,27 @@ class MaxAccuracyWithKellyScaledBetsStrategy(BettingStrategy):
601
656
  return f"{self.__class__.__name__}(max_position_amount={self.max_position_amount}, take_profit={self.take_profit})"
602
657
 
603
658
 
604
- class CategoricalKellyBettingStrategy(BettingStrategy):
659
+ class _CategoricalKellyBettingStrategy(BettingStrategy):
660
+ supported_question_types = {QuestionType.BINARY, QuestionType.CATEGORICAL}
661
+ supported_market_types = {x for x in MarketType if x.is_trading_market}
662
+
605
663
  def __init__(
606
664
  self,
665
+ kelly_type: KellyType,
607
666
  max_position_amount: USD,
608
667
  max_price_impact: float | None,
609
668
  allow_multiple_bets: bool,
610
669
  allow_shorting: bool,
611
670
  multicategorical: bool,
612
671
  take_profit: bool = True,
613
- force_simplified_calculation: bool = False,
614
672
  ):
615
673
  super().__init__(take_profit=take_profit)
674
+ self.kelly_type = kelly_type
616
675
  self.max_position_amount = max_position_amount
617
676
  self.max_price_impact = max_price_impact
618
677
  self.allow_multiple_bets = allow_multiple_bets
619
678
  self.allow_shorting = allow_shorting
620
679
  self.multicategorical = multicategorical
621
- self.force_simplified_calculation = force_simplified_calculation
622
680
 
623
681
  @property
624
682
  def maximum_possible_bet_amount(self) -> USD:
@@ -632,7 +690,7 @@ class CategoricalKellyBettingStrategy(BettingStrategy):
632
690
  ) -> list[CategoricalKellyBet]:
633
691
  max_bet = market.get_usd_in_token(max_bet_amount)
634
692
 
635
- if market.outcome_token_pool is None or self.force_simplified_calculation:
693
+ if self.kelly_type == KellyType.SIMPLE:
636
694
  kelly_bets = get_kelly_bets_categorical_simplified(
637
695
  market_probabilities=[market.probabilities[o] for o in market.outcomes],
638
696
  estimated_probabilities=[
@@ -647,8 +705,8 @@ class CategoricalKellyBettingStrategy(BettingStrategy):
647
705
 
648
706
  else:
649
707
  kelly_bets = get_kelly_bets_categorical_full(
650
- outcome_pool_sizes=[
651
- market.outcome_token_pool[o] for o in market.outcomes
708
+ market_probabilities=[
709
+ market.probability_for_market_outcome(o) for o in market.outcomes
652
710
  ],
653
711
  estimated_probabilities=[
654
712
  answer.probability_for_market_outcome(o) for o in market.outcomes
@@ -659,6 +717,11 @@ class CategoricalKellyBettingStrategy(BettingStrategy):
659
717
  allow_multiple_bets=self.allow_multiple_bets,
660
718
  allow_shorting=self.allow_shorting,
661
719
  multicategorical=self.multicategorical,
720
+ get_buy_token_amount=lambda bet_amount, outcome_index: check_not_none(
721
+ market.get_buy_token_amount(
722
+ bet_amount, market.get_outcome_str(outcome_index)
723
+ )
724
+ ),
662
725
  )
663
726
 
664
727
  return kelly_bets
@@ -689,9 +752,8 @@ class CategoricalKellyBettingStrategy(BettingStrategy):
689
752
  if self.max_price_impact:
690
753
  # Adjust amount
691
754
  max_price_impact_bet_amount = (
692
- BinaryKellyBettingStrategy.calculate_bet_amount_for_price_impact(
755
+ _BinaryKellyBettingStrategy.calculate_bet_amount_for_price_impact(
693
756
  market,
694
- best_kelly_bet.size,
695
757
  direction=market.get_outcome_str(best_kelly_bet.index),
696
758
  max_price_impact=self.max_price_impact,
697
759
  )
@@ -712,4 +774,45 @@ class CategoricalKellyBettingStrategy(BettingStrategy):
712
774
  return trades
713
775
 
714
776
  def __repr__(self) -> str:
715
- return f"{self.__class__.__name__}(max_position_amount={self.max_position_amount}, max_price_impact={self.max_price_impact}, allow_multiple_bets={self.allow_multiple_bets}, allow_shorting={self.allow_shorting}, take_profit={self.take_profit}, force_simplified_calculation={self.force_simplified_calculation})"
777
+ return f"{self.__class__.__name__}(max_position_amount={self.max_position_amount}, max_price_impact={self.max_price_impact}, allow_multiple_bets={self.allow_multiple_bets}, allow_shorting={self.allow_shorting}, take_profit={self.take_profit})"
778
+
779
+
780
+ class SimpleCategoricalKellyBettingStrategy(_CategoricalKellyBettingStrategy):
781
+ def __init__(
782
+ self,
783
+ max_position_amount: USD,
784
+ allow_multiple_bets: bool,
785
+ allow_shorting: bool,
786
+ multicategorical: bool,
787
+ take_profit: bool = True,
788
+ ):
789
+ super().__init__(
790
+ kelly_type=KellyType.SIMPLE,
791
+ max_position_amount=max_position_amount,
792
+ max_price_impact=None,
793
+ allow_multiple_bets=allow_multiple_bets,
794
+ allow_shorting=allow_shorting,
795
+ multicategorical=multicategorical,
796
+ take_profit=take_profit,
797
+ )
798
+
799
+
800
+ class FullCategoricalKellyBettingStrategy(_CategoricalKellyBettingStrategy):
801
+ def __init__(
802
+ self,
803
+ max_position_amount: USD,
804
+ max_price_impact: float | None,
805
+ allow_multiple_bets: bool,
806
+ allow_shorting: bool,
807
+ multicategorical: bool,
808
+ take_profit: bool = True,
809
+ ):
810
+ super().__init__(
811
+ kelly_type=KellyType.FULL,
812
+ max_position_amount=max_position_amount,
813
+ max_price_impact=max_price_impact,
814
+ allow_multiple_bets=allow_multiple_bets,
815
+ allow_shorting=allow_shorting,
816
+ multicategorical=multicategorical,
817
+ take_profit=take_profit,
818
+ )
@@ -1,10 +1,6 @@
1
1
  import typing as t
2
2
 
3
3
  from prediction_market_agent_tooling.config import APIKeys
4
- from prediction_market_agent_tooling.deploy.betting_strategy import (
5
- BinaryKellyBettingStrategy,
6
- TradeType,
7
- )
8
4
  from prediction_market_agent_tooling.gtypes import USD
9
5
  from prediction_market_agent_tooling.jobs.jobs_models import JobAgentMarket
10
6
  from prediction_market_agent_tooling.markets.agent_market import ProcessedMarket
@@ -92,20 +88,21 @@ class OmenJobAgentMarket(OmenAgentMarket, JobAgentMarket):
92
88
  return processed_traded_market
93
89
 
94
90
  def get_job_trade(self, max_bond: USD, result: str) -> Trade:
91
+ raise NotImplementedError("TODO: Refactor to avoid circular imports.")
95
92
  # Because jobs are powered by prediction markets, potentional reward depends on job's liquidity and our will to bond (bet) our xDai into our job completion.
96
- strategy = BinaryKellyBettingStrategy(max_position_amount=max_bond)
97
- required_trades = strategy.calculate_trades(
98
- existing_position=None,
99
- answer=self.get_job_answer(result),
100
- market=self,
101
- )
102
- assert (
103
- len(required_trades) == 1
104
- ), f"Shouldn't process same job twice: {required_trades}"
105
- trade = required_trades[0]
106
- assert trade.trade_type == TradeType.BUY, "Should only buy on job markets."
107
- assert trade.outcome, "Should buy only YES on job markets."
108
- return required_trades[0]
93
+ # strategy = FullBinaryKellyBettingStrategy(max_position_amount=max_bond)
94
+ # required_trades = strategy.calculate_trades(
95
+ # existing_position=None,
96
+ # answer=self.get_job_answer(result),
97
+ # market=self,
98
+ # )
99
+ # assert (
100
+ # len(required_trades) == 1
101
+ # ), f"Shouldn't process same job twice: {required_trades}"
102
+ # trade = required_trades[0]
103
+ # assert trade.trade_type == TradeType.BUY, "Should only buy on job markets."
104
+ # assert trade.outcome, "Should buy only YES on job markets."
105
+ # return required_trades[0]
109
106
 
110
107
  @staticmethod
111
108
  def from_omen_market(market: OmenMarket) -> "OmenJobAgentMarket":
@@ -188,6 +188,17 @@ class AgentMarket(BaseModel):
188
188
  f"Could not find probability for market outcome {market_outcome}"
189
189
  )
190
190
 
191
+ @property
192
+ def question_type(self) -> QuestionType:
193
+ if self.is_binary:
194
+ return QuestionType.BINARY
195
+
196
+ elif self.is_scalar:
197
+ return QuestionType.SCALAR
198
+
199
+ else:
200
+ return QuestionType.CATEGORICAL
201
+
191
202
  @property
192
203
  def is_binary(self) -> bool:
193
204
  # 3 outcomes can also be binary if 3rd outcome is invalid (Seer)
@@ -31,6 +31,10 @@ class MarketType(str, Enum):
31
31
  METACULUS = "metaculus"
32
32
  SEER = "seer"
33
33
 
34
+ @staticmethod
35
+ def from_market(market: AgentMarket) -> "MarketType":
36
+ return AGENT_MARKET_TO_MARKET_TYPE[type(market)]
37
+
34
38
  @property
35
39
  def market_class(self) -> type[AgentMarket]:
36
40
  if self not in MARKET_TYPE_TO_AGENT_MARKET:
@@ -43,6 +47,15 @@ class MarketType(str, Enum):
43
47
  raise ValueError(f"Unknown market type: {self}")
44
48
  return JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET[self]
45
49
 
50
+ @property
51
+ def is_trading_market(self) -> bool:
52
+ return self in [
53
+ MarketType.OMEN,
54
+ MarketType.POLYMARKET,
55
+ MarketType.SEER,
56
+ MarketType.MANIFOLD,
57
+ ]
58
+
46
59
  @property
47
60
  def is_blockchain_market(self) -> bool:
48
61
  return self in [MarketType.OMEN, MarketType.POLYMARKET, MarketType.SEER]
@@ -56,6 +69,9 @@ MARKET_TYPE_TO_AGENT_MARKET: dict[MarketType, type[AgentMarket]] = {
56
69
  MarketType.SEER: SeerAgentMarket,
57
70
  }
58
71
 
72
+ AGENT_MARKET_TO_MARKET_TYPE: dict[type[AgentMarket], MarketType] = {
73
+ v: k for k, v in MARKET_TYPE_TO_AGENT_MARKET.items()
74
+ }
59
75
 
60
76
  JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET: dict[MarketType, type[JobAgentMarket]] = {
61
77
  MarketType.OMEN: OmenJobAgentMarket,
@@ -1,5 +1,6 @@
1
1
  import typing as t
2
2
  from datetime import timedelta
3
+ from enum import Enum
3
4
  from typing import Annotated
4
5
  from urllib.parse import urljoin
5
6
 
@@ -139,11 +140,6 @@ class SeerMarket(BaseModel):
139
140
  for token in self.wrapped_tokens
140
141
  ]
141
142
 
142
- @property
143
- def is_binary(self) -> bool:
144
- # 3 because Seer has also third, `Invalid` outcome.
145
- return len(self.outcomes) == 3
146
-
147
143
  @property
148
144
  def collateral_token_contract_address_checksummed(self) -> ChecksumAddress:
149
145
  return Web3.to_checksum_address(self.collateral_token)
@@ -188,3 +184,42 @@ class ExactInputSingleParams(BaseModel):
188
184
  limit_sqrt_price: Wei = Field(
189
185
  alias="limitSqrtPrice", default_factory=lambda: Wei(0)
190
186
  ) # 0 for convenience, we also don't expect major price shifts
187
+
188
+
189
+ class SeerTransactionType(str, Enum):
190
+ SWAP = "swap"
191
+ SPLIT = "split"
192
+
193
+
194
+ class SeerTransaction(BaseModel):
195
+ model_config = ConfigDict(populate_by_name=True)
196
+
197
+ market_name: str = Field(alias="marketName")
198
+ market_id: HexBytes = Field(alias="marketId")
199
+ type: SeerTransactionType
200
+ block_number: int = Field(alias="blockNumber")
201
+ transaction_hash: HexBytes = Field(alias="transactionHash")
202
+ collateral: HexAddress
203
+ collateral_symbol: str = Field(alias="collateralSymbol")
204
+
205
+ token_in: HexAddress = Field(alias="tokenIn")
206
+ token_out: HexAddress = Field(alias="tokenOut")
207
+ amount_in: Wei = Field(alias="amountIn")
208
+ amount_out: Wei = Field(alias="amountOut")
209
+ token_in_symbol: str = Field(alias="tokenInSymbol")
210
+ token_out_symbol: str = Field(alias="tokenOutSymbol")
211
+ timestamp: int | None = None
212
+
213
+ amount: Wei | None = None
214
+
215
+ @property
216
+ def timestamp_dt(self) -> DatetimeUTC | None:
217
+ return DatetimeUTC.to_datetime_utc(self.timestamp) if self.timestamp else None
218
+
219
+ @property
220
+ def token_in_checksum(self) -> ChecksumAddress:
221
+ return Web3.to_checksum_address(self.token_in)
222
+
223
+ @property
224
+ def token_out_checksum(self) -> ChecksumAddress:
225
+ return Web3.to_checksum_address(self.token_out)
@@ -35,6 +35,7 @@ from prediction_market_agent_tooling.markets.blockchain_utils import store_trade
35
35
  from prediction_market_agent_tooling.markets.data_models import (
36
36
  ExistingPosition,
37
37
  Resolution,
38
+ ResolvedBet,
38
39
  )
39
40
  from prediction_market_agent_tooling.markets.market_fees import MarketFees
40
41
  from prediction_market_agent_tooling.markets.omen.omen import (
@@ -56,6 +57,7 @@ from prediction_market_agent_tooling.markets.seer.exceptions import (
56
57
  PriceCalculationError,
57
58
  )
58
59
  from prediction_market_agent_tooling.markets.seer.price_manager import PriceManager
60
+ from prediction_market_agent_tooling.markets.seer.seer_api import get_seer_transactions
59
61
  from prediction_market_agent_tooling.markets.seer.seer_contracts import (
60
62
  GnosisRouter,
61
63
  SeerMarketFactory,
@@ -81,7 +83,6 @@ from prediction_market_agent_tooling.tools.cow.cow_order import (
81
83
  OrderStatusError,
82
84
  get_orders_by_owner,
83
85
  get_trades_by_order_uid,
84
- get_trades_by_owner,
85
86
  swap_tokens_waiting,
86
87
  wait_for_order_completion,
87
88
  )
@@ -272,10 +273,12 @@ class SeerAgentMarket(AgentMarket):
272
273
  """
273
274
  We filter the markets using previous trades by the user so that we don't have to process all Seer markets.
274
275
  """
275
- trades_by_user = get_trades_by_owner(api_keys.bet_from_address)
276
+ trades_by_user = get_seer_transactions(
277
+ api_keys.bet_from_address, RPCConfig().CHAIN_ID
278
+ )
276
279
 
277
- traded_tokens = {t.buyToken for t in trades_by_user}.union(
278
- [t.sellToken for t in trades_by_user]
280
+ traded_tokens = {t.token_in_checksum for t in trades_by_user}.union(
281
+ [t.token_out_checksum for t in trades_by_user]
279
282
  )
280
283
  filtered_markets: list[SeerMarket] = []
281
284
  for market in markets:
@@ -313,19 +316,43 @@ class SeerAgentMarket(AgentMarket):
313
316
  for market in filtered_markets
314
317
  if market.is_redeemable(owner=api_keys.bet_from_address, web3=web3)
315
318
  ]
319
+ logger.info(f"Got {len(markets_to_redeem)} markets to redeem on Seer.")
316
320
 
317
321
  gnosis_router = GnosisRouter()
318
322
  for market in markets_to_redeem:
319
323
  try:
324
+ # GnosisRouter needs approval to use our outcome tokens
325
+ for i, token in enumerate(market.wrapped_tokens):
326
+ ContractERC20OnGnosisChain(
327
+ address=Web3.to_checksum_address(token)
328
+ ).approve(
329
+ api_keys,
330
+ for_address=gnosis_router.address,
331
+ amount_wei=market_balances[market.id][i].as_wei,
332
+ web3=web3,
333
+ )
334
+
335
+ # We can only ask for redeem of outcome tokens on correct outcomes
336
+ # TODO: Implement more complex use-cases: https://github.com/gnosis/prediction-market-agent-tooling/issues/850
337
+ amounts_to_redeem = [
338
+ (amount if numerator > 0 else OutcomeWei(0))
339
+ for amount, numerator in zip(
340
+ market_balances[market.id], market.payout_numerators
341
+ )
342
+ ]
343
+
344
+ # Redeem!
320
345
  params = RedeemParams(
321
346
  market=Web3.to_checksum_address(market.id),
322
347
  outcome_indices=list(range(len(market.payout_numerators))),
323
- amounts=market_balances[market.id],
348
+ amounts=amounts_to_redeem,
324
349
  )
325
350
  gnosis_router.redeem_to_base(api_keys, params=params, web3=web3)
326
- logger.info(f"Redeemed market {market.id.to_0x_hex()}")
327
- except Exception as e:
328
- logger.error(f"Failed to redeem market {market.id.to_0x_hex()}, {e}")
351
+ logger.info(f"Redeemed market {market.url}.")
352
+ except Exception:
353
+ logger.exception(
354
+ f"Failed to redeem market {market.url}, {market.outcomes}, with amounts {market_balances[market.id]} and payout numerators {market.payout_numerators}, and wrapped tokens {market.wrapped_tokens}."
355
+ )
329
356
 
330
357
  # GnosisRouter withdraws sDai into wxDAI/xDai on its own, so no auto-withdraw needed by us.
331
358
 
@@ -464,6 +491,15 @@ class SeerAgentMarket(AgentMarket):
464
491
 
465
492
  return market
466
493
 
494
+ @staticmethod
495
+ def get_resolved_bets_made_since(
496
+ better_address: ChecksumAddress,
497
+ start_time: DatetimeUTC,
498
+ end_time: DatetimeUTC | None,
499
+ ) -> list[ResolvedBet]:
500
+ # TODO: https://github.com/gnosis/prediction-market-agent-tooling/issues/841
501
+ raise NotImplementedError()
502
+
467
503
  @staticmethod
468
504
  def get_markets(
469
505
  limit: int,
@@ -0,0 +1,28 @@
1
+ import httpx
2
+
3
+ from prediction_market_agent_tooling.gtypes import ChainID, ChecksumAddress
4
+ from prediction_market_agent_tooling.markets.seer.data_models import SeerTransaction
5
+ from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
6
+ from prediction_market_agent_tooling.tools.utils import to_int_timestamp, utcnow
7
+
8
+
9
+ def get_seer_transactions(
10
+ account: ChecksumAddress,
11
+ chain_id: ChainID,
12
+ start_time: DatetimeUTC | None = None,
13
+ end_time: DatetimeUTC | None = None,
14
+ timeout: int = 60, # The endpoint is pretty slow to respond atm.
15
+ ) -> list[SeerTransaction]:
16
+ url = "https://app.seer.pm/.netlify/functions/get-transactions"
17
+ params: dict[str, str | int] = {
18
+ "account": account,
19
+ "chainId": chain_id,
20
+ "startTime": to_int_timestamp(start_time) if start_time else 0,
21
+ "endTime": to_int_timestamp(end_time if end_time else utcnow()),
22
+ }
23
+ response = httpx.get(url, params=params, timeout=timeout)
24
+ response.raise_for_status()
25
+ response_json = response.json()
26
+
27
+ transactions = [SeerTransaction.model_validate(tx) for tx in response_json]
28
+ return transactions