prediction-market-agent-tooling 0.56.3__tar.gz → 0.57.0__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 (108) hide show
  1. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/PKG-INFO +1 -1
  2. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/config.py +29 -0
  3. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/agent.py +67 -40
  4. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/data_models.py +21 -0
  5. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -1
  6. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/data_models.py +4 -7
  7. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +8 -4
  8. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +1 -1
  9. prediction_market_agent_tooling-0.57.0/prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py +66 -0
  10. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/contract.py +3 -7
  11. prediction_market_agent_tooling-0.56.3/prediction_market_agent_tooling/tools/google.py → prediction_market_agent_tooling-0.57.0/prediction_market_agent_tooling/tools/google_utils.py +28 -1
  12. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +1 -1
  13. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/is_invalid.py +1 -1
  14. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/is_predictable.py +8 -3
  15. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/langfuse_client_utils.py +1 -0
  16. prediction_market_agent_tooling-0.57.0/prediction_market_agent_tooling/tools/transaction_cache.py +48 -0
  17. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/utils.py +1 -23
  18. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/web3_utils.py +5 -1
  19. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/pyproject.toml +2 -1
  20. prediction_market_agent_tooling-0.56.3/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -6
  21. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/LICENSE +0 -0
  22. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/README.md +0 -0
  23. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/debuggingcontract.abi.json +0 -0
  24. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/erc4626.abi.json +0 -0
  27. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_agentresultmapping.abi.json +0 -0
  28. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  29. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  30. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  31. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  32. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  33. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  34. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  35. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  36. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/abis/proxy.abi.json +0 -0
  37. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  38. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  39. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  40. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  41. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  42. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/betting_strategy.py +0 -0
  43. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  44. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  45. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  46. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  47. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/deploy/trade_interval.py +0 -0
  48. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/gtypes.py +0 -0
  49. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/jobs/__init__.py +0 -0
  50. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/jobs/jobs_models.py +0 -0
  51. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/jobs/omen/omen_jobs.py +0 -0
  52. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/loggers.py +0 -0
  53. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/agent_market.py +0 -0
  54. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/base_subgraph_handler.py +0 -0
  55. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  56. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  57. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  58. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +0 -0
  59. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  60. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/market_fees.py +0 -0
  61. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
  62. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  63. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  64. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +0 -0
  65. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  66. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/omen.py +0 -0
  67. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
  68. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  69. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  70. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  71. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  72. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
  73. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/seer/data_models.py +0 -0
  74. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +0 -0
  75. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
  76. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/markets/metaculus.py +0 -0
  77. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/markets/omen.py +0 -0
  78. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/markets/polymarket.py +0 -0
  79. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/monitor.py +0 -0
  80. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/monitor_app.py +0 -0
  81. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
  82. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/py.typed +0 -0
  83. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
  84. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  85. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
  86. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +0 -0
  87. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  88. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/betting_strategies/utils.py +0 -0
  89. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/caches/db_cache.py +0 -0
  90. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/caches/inmemory_cache.py +0 -0
  91. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/costs.py +0 -0
  92. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/custom_exceptions.py +0 -0
  93. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/datetime_utc.py +0 -0
  94. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  95. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/httpx_cached_client.py +0 -0
  96. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  97. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py +0 -0
  98. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/langfuse_.py +0 -0
  99. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/omen/reality_accuracy.py +0 -0
  100. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  101. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py +0 -0
  102. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py +0 -0
  103. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +0 -0
  104. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/safe.py +0 -0
  105. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  106. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  107. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/tavily/tavily_models.py +0 -0
  108. {prediction_market_agent_tooling-0.56.3 → prediction_market_agent_tooling-0.57.0}/prediction_market_agent_tooling/tools/tavily/tavily_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.56.3
3
+ Version: 0.57.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -1,5 +1,6 @@
1
1
  import typing as t
2
2
 
3
+ from pydantic import Field
3
4
  from pydantic.types import SecretStr
4
5
  from pydantic.v1.types import SecretStr as SecretStrV1
5
6
  from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -7,6 +8,7 @@ from safe_eth.eth import EthereumClient
7
8
  from safe_eth.safe.safe import SafeV141
8
9
 
9
10
  from prediction_market_agent_tooling.gtypes import (
11
+ ChainID,
10
12
  ChecksumAddress,
11
13
  PrivateKey,
12
14
  secretstr_to_v1_secretstr,
@@ -203,3 +205,30 @@ class APIKeys(BaseSettings):
203
205
  s = SafeV141(self.SAFE_ADDRESS, ethereum_client)
204
206
  public_key_from_signer = private_key_to_public_key(self.bet_from_private_key)
205
207
  return s.retrieve_is_owner(public_key_from_signer)
208
+
209
+
210
+ class RPCConfig(BaseSettings):
211
+ model_config = SettingsConfigDict(
212
+ env_file=".env", env_file_encoding="utf-8", extra="ignore"
213
+ )
214
+
215
+ GNOSIS_RPC_URL: str = Field(default="https://rpc.gnosischain.com")
216
+ CHAIN_ID: ChainID = Field(default=ChainID(100))
217
+
218
+ @property
219
+ def gnosis_rpc_url(self) -> str:
220
+ return check_not_none(
221
+ self.GNOSIS_RPC_URL, "GNOSIS_RPC_URL missing in the environment."
222
+ )
223
+
224
+ @property
225
+ def chain_id(self) -> ChainID:
226
+ return check_not_none(self.CHAIN_ID, "CHAIN_ID missing in the environment.")
227
+
228
+
229
+ class CloudCredentials(BaseSettings):
230
+ model_config = SettingsConfigDict(
231
+ env_file=".env", env_file_encoding="utf-8", extra="ignore"
232
+ )
233
+
234
+ GOOGLE_APPLICATION_CREDENTIALS: t.Optional[str] = None
@@ -8,8 +8,7 @@ from datetime import timedelta
8
8
  from enum import Enum
9
9
  from functools import cached_property
10
10
 
11
- from pydantic import BeforeValidator, computed_field
12
- from typing_extensions import Annotated
11
+ from pydantic import computed_field
13
12
 
14
13
  from prediction_market_agent_tooling.config import APIKeys
15
14
  from prediction_market_agent_tooling.deploy.betting_strategy import (
@@ -69,27 +68,6 @@ from prediction_market_agent_tooling.tools.langfuse_ import langfuse_context, ob
69
68
  from prediction_market_agent_tooling.tools.utils import DatetimeUTC, utcnow
70
69
 
71
70
  MAX_AVAILABLE_MARKETS = 20
72
- TRADER_TAG = "trader"
73
-
74
-
75
- def to_boolean_outcome(value: str | bool) -> bool:
76
- if isinstance(value, bool):
77
- return value
78
-
79
- elif isinstance(value, str):
80
- value = value.lower().strip()
81
-
82
- if value in {"true", "yes", "y", "1"}:
83
- return True
84
-
85
- elif value in {"false", "no", "n", "0"}:
86
- return False
87
-
88
- else:
89
- raise ValueError(f"Expected a boolean string, but got {value}")
90
-
91
- else:
92
- raise ValueError(f"Expected a boolean or a string, but got {value}")
93
71
 
94
72
 
95
73
  def initialize_langfuse(enable_langfuse: bool) -> None:
@@ -107,15 +85,21 @@ def initialize_langfuse(enable_langfuse: bool) -> None:
107
85
  langfuse_context.configure(enabled=enable_langfuse)
108
86
 
109
87
 
110
- Decision = Annotated[bool, BeforeValidator(to_boolean_outcome)]
111
-
112
-
113
88
  class AnsweredEnum(str, Enum):
114
89
  ANSWERED = "answered"
115
90
  NOT_ANSWERED = "not_answered"
116
91
 
117
92
 
93
+ class AgentTagEnum(str, Enum):
94
+ PREDICTOR = "predictor"
95
+ TRADER = "trader"
96
+
97
+
118
98
  class DeployableAgent:
99
+ """
100
+ Subclass this class to create agent with standardized interface.
101
+ """
102
+
119
103
  def __init__(
120
104
  self,
121
105
  enable_langfuse: bool = APIKeys().default_enable_langfuse,
@@ -176,20 +160,25 @@ class DeployableAgent:
176
160
  )
177
161
 
178
162
  def load(self) -> None:
179
- pass
163
+ """
164
+ Implement this method to load arbitrary instances needed across the whole run of the agent.
165
+
166
+ Do not customize __init__ method.
167
+ """
180
168
 
181
169
  def deploy_local(
182
170
  self,
183
171
  market_type: MarketType,
184
172
  sleep_time: float,
185
- timeout: float,
173
+ run_time: float | None,
186
174
  ) -> None:
175
+ """
176
+ Run the agent in the forever cycle every `sleep_time` seconds, until the `run_time` is met.
177
+ """
187
178
  start_time = time.time()
188
- while True:
179
+ while run_time is None or time.time() - start_time < run_time:
189
180
  self.run(market_type=market_type)
190
181
  time.sleep(sleep_time)
191
- if time.time() - start_time > timeout:
192
- break
193
182
 
194
183
  def deploy_gcp(
195
184
  self,
@@ -205,6 +194,9 @@ class DeployableAgent:
205
194
  start_time: DatetimeUTC | None = None,
206
195
  timeout: int = 180,
207
196
  ) -> None:
197
+ """
198
+ Deploy the agent as GCP Function.
199
+ """
208
200
  path_to_agent_file = os.path.relpath(inspect.getfile(self.__class__))
209
201
 
210
202
  entrypoint_function_name = "main"
@@ -271,6 +263,9 @@ def {entrypoint_function_name}(request) -> str:
271
263
  schedule_deployed_gcp_function(fname, cron_schedule=cron_schedule)
272
264
 
273
265
  def run(self, market_type: MarketType) -> None:
266
+ """
267
+ Run single iteration of the agent.
268
+ """
274
269
  raise NotImplementedError("This method must be implemented by the subclass.")
275
270
 
276
271
  def get_gcloud_fname(self, market_type: MarketType) -> str:
@@ -278,6 +273,14 @@ def {entrypoint_function_name}(request) -> str:
278
273
 
279
274
 
280
275
  class DeployablePredictionAgent(DeployableAgent):
276
+ """
277
+ Subclass this class to create your own prediction market agent.
278
+
279
+ The agent will process markets and make predictions.
280
+ """
281
+
282
+ AGENT_TAG: AgentTagEnum = AgentTagEnum.PREDICTOR
283
+
281
284
  bet_on_n_markets_per_run: int = 1
282
285
 
283
286
  # Agent behaviour when fetching markets
@@ -297,10 +300,10 @@ class DeployablePredictionAgent(DeployableAgent):
297
300
  def __init__(
298
301
  self,
299
302
  enable_langfuse: bool = APIKeys().default_enable_langfuse,
300
- store_prediction: bool = True,
303
+ store_predictions: bool = True,
301
304
  ) -> None:
302
305
  super().__init__(enable_langfuse=enable_langfuse)
303
- self.store_prediction = store_prediction
306
+ self.store_predictions = store_predictions
304
307
 
305
308
  def initialize_langfuse(self) -> None:
306
309
  super().initialize_langfuse()
@@ -328,7 +331,7 @@ class DeployablePredictionAgent(DeployableAgent):
328
331
  ) -> None:
329
332
  self.langfuse_update_current_trace(
330
333
  tags=[
331
- TRADER_TAG,
334
+ self.AGENT_TAG,
332
335
  (
333
336
  AnsweredEnum.ANSWERED
334
337
  if processed_market is not None
@@ -386,6 +389,9 @@ class DeployablePredictionAgent(DeployableAgent):
386
389
  self,
387
390
  market_type: MarketType,
388
391
  ) -> t.Sequence[AgentMarket]:
392
+ """
393
+ Override this method to customize what markets will fetch for processing.
394
+ """
389
395
  cls = market_type.market_class
390
396
  # Fetch the soonest closing markets to choose from
391
397
  available_markets = cls.get_binary_markets(
@@ -399,6 +405,9 @@ class DeployablePredictionAgent(DeployableAgent):
399
405
  def before_process_market(
400
406
  self, market_type: MarketType, market: AgentMarket
401
407
  ) -> None:
408
+ """
409
+ Executed before processing of each market.
410
+ """
402
411
  api_keys = APIKeys()
403
412
 
404
413
  if market_type.is_blockchain_market:
@@ -442,19 +451,22 @@ class DeployablePredictionAgent(DeployableAgent):
442
451
  market: AgentMarket,
443
452
  processed_market: ProcessedMarket | None,
444
453
  ) -> None:
454
+ """
455
+ Executed after processing of each market.
456
+ """
445
457
  keys = APIKeys()
446
- if self.store_prediction:
458
+ if self.store_predictions:
447
459
  market.store_prediction(
448
460
  processed_market=processed_market, keys=keys, agent_name=self.agent_name
449
461
  )
450
462
  else:
451
463
  logger.info(
452
- f"Prediction {processed_market} not stored because {self.store_prediction=}."
464
+ f"Prediction {processed_market} not stored because {self.store_predictions=}."
453
465
  )
454
466
 
455
467
  def before_process_markets(self, market_type: MarketType) -> None:
456
468
  """
457
- Executes actions that occur before bets are placed.
469
+ Executed before market processing loop starts.
458
470
  """
459
471
  api_keys = APIKeys()
460
472
  self.check_min_required_balance_to_operate(market_type)
@@ -485,7 +497,9 @@ class DeployablePredictionAgent(DeployableAgent):
485
497
  logger.info("All markets processed.")
486
498
 
487
499
  def after_process_markets(self, market_type: MarketType) -> None:
488
- "Executes actions that occur after bets are placed."
500
+ """
501
+ Executed after market processing loop ends.
502
+ """
489
503
 
490
504
  def run(self, market_type: MarketType) -> None:
491
505
  if market_type not in self.supported_markets:
@@ -498,6 +512,14 @@ class DeployablePredictionAgent(DeployableAgent):
498
512
 
499
513
 
500
514
  class DeployableTraderAgent(DeployablePredictionAgent):
515
+ """
516
+ Subclass this class to create your own prediction market trading agent.
517
+
518
+ The agent will process markets, make predictions and place trades (bets) based off these predictions.
519
+ """
520
+
521
+ AGENT_TAG: AgentTagEnum = AgentTagEnum.TRADER
522
+
501
523
  # These markets require place of bet, not just predictions.
502
524
  supported_markets: t.Sequence[MarketType] = [
503
525
  MarketType.OMEN,
@@ -508,12 +530,12 @@ class DeployableTraderAgent(DeployablePredictionAgent):
508
530
  def __init__(
509
531
  self,
510
532
  enable_langfuse: bool = APIKeys().default_enable_langfuse,
511
- store_prediction: bool = True,
533
+ store_predictions: bool = True,
512
534
  store_trades: bool = True,
513
535
  place_trades: bool = True,
514
536
  ) -> None:
515
537
  super().__init__(
516
- enable_langfuse=enable_langfuse, store_prediction=store_prediction
538
+ enable_langfuse=enable_langfuse, store_predictions=store_predictions
517
539
  )
518
540
  self.store_trades = store_trades
519
541
  self.place_trades = place_trades
@@ -537,6 +559,11 @@ class DeployableTraderAgent(DeployablePredictionAgent):
537
559
  )
538
560
 
539
561
  def get_betting_strategy(self, market: AgentMarket) -> BettingStrategy:
562
+ """
563
+ Override this method to customize betting strategy of your agent.
564
+
565
+ Given the market and prediction, agent uses this method to calculate optimal outcome and bet size.
566
+ """
540
567
  user_id = market.get_user_id(api_keys=APIKeys())
541
568
 
542
569
  total_amount = market.get_tiny_bet_amount().amount
@@ -140,3 +140,24 @@ class PlacedTrade(Trade):
140
140
  amount=trade.amount,
141
141
  id=id,
142
142
  )
143
+
144
+
145
+ class SimulationDetail(BaseModel):
146
+ strategy: str
147
+ url: str
148
+ market_p_yes: float
149
+ agent_p_yes: float
150
+ agent_conf: float
151
+ org_bet: float
152
+ sim_bet: float
153
+ org_dir: bool
154
+ sim_dir: bool
155
+ org_profit: float
156
+ sim_profit: float
157
+ timestamp: DatetimeUTC
158
+
159
+
160
+ class SharpeOutput(BaseModel):
161
+ annualized_volatility: float
162
+ mean_daily_return: float
163
+ annualized_sharpe_ratio: float
@@ -200,7 +200,6 @@ class ManifoldBet(BaseModel):
200
200
  if self.get_resolved_boolean_outcome() == market_outcome
201
201
  else -self.amount
202
202
  )
203
- profit -= self.fees.get_total()
204
203
  return ProfitAmount(
205
204
  amount=profit,
206
205
  currency=Currency.Mana,
@@ -531,7 +531,6 @@ class OmenBet(BaseModel):
531
531
  if self.boolean_outcome == self.fpmm.boolean_outcome
532
532
  else -bet_amount_xdai
533
533
  )
534
- profit -= wei_to_xdai(self.feeAmount)
535
534
  return ProfitAmount(
536
535
  amount=profit,
537
536
  currency=Currency.xDai,
@@ -539,9 +538,8 @@ class OmenBet(BaseModel):
539
538
 
540
539
  def to_bet(self) -> Bet:
541
540
  return Bet(
542
- id=str(
543
- self.transactionHash
544
- ), # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
541
+ id=str(self.transactionHash),
542
+ # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
545
543
  amount=BetAmount(amount=self.collateralAmountUSD, currency=Currency.xDai),
546
544
  outcome=self.boolean_outcome,
547
545
  created_time=self.creation_datetime,
@@ -556,9 +554,8 @@ class OmenBet(BaseModel):
556
554
  )
557
555
 
558
556
  return ResolvedBet(
559
- id=str(
560
- self.transactionHash
561
- ), # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
557
+ id=self.transactionHash.hex(),
558
+ # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
562
559
  amount=BetAmount(amount=self.collateralAmountUSD, currency=Currency.xDai),
563
560
  outcome=self.boolean_outcome,
564
561
  created_time=self.creation_datetime,
@@ -435,10 +435,14 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
435
435
  omen_markets = self.do_query(fields=fields, pydantic_model=OmenMarket)
436
436
  return omen_markets
437
437
 
438
- def get_omen_market_by_market_id(self, market_id: HexAddress) -> OmenMarket:
439
- markets = self.trades_subgraph.Query.fixedProductMarketMaker(
440
- id=market_id.lower()
441
- )
438
+ def get_omen_market_by_market_id(
439
+ self, market_id: HexAddress, block_number: int | None = None
440
+ ) -> OmenMarket:
441
+ query_filters: dict[str, t.Any] = {"id": market_id.lower()}
442
+ if block_number:
443
+ query_filters["block"] = {"number": block_number}
444
+
445
+ markets = self.trades_subgraph.Query.fixedProductMarketMaker(**query_filters)
442
446
 
443
447
  fields = self._get_fields_for_markets(markets)
444
448
  omen_markets = self.do_query(fields=fields, pydantic_model=OmenMarket)
@@ -3,7 +3,7 @@ from prediction_market_agent_tooling.markets.markets import MarketType
3
3
  from prediction_market_agent_tooling.markets.polymarket.data_models_web import (
4
4
  PolymarketFullMarket,
5
5
  )
6
- from prediction_market_agent_tooling.tools.google import search_google
6
+ from prediction_market_agent_tooling.tools.google_utils import search_google
7
7
 
8
8
 
9
9
  def find_resolution_on_polymarket(question: str) -> Resolution | None:
@@ -0,0 +1,66 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ from prediction_market_agent_tooling.markets.data_models import (
5
+ SharpeOutput,
6
+ SimulationDetail,
7
+ )
8
+
9
+
10
+ class SharpeRatioCalculator:
11
+ def __init__(
12
+ self, details: list[SimulationDetail], risk_free_rate: float = 0.0
13
+ ) -> None:
14
+ self.details = details
15
+ self.df = pd.DataFrame([d.model_dump() for d in self.details])
16
+ self.risk_free_rate = risk_free_rate
17
+
18
+ def __has_df_valid_columns_else_exception(
19
+ self, required_columns: list[str]
20
+ ) -> None:
21
+ if not set(required_columns).issubset(self.df.columns):
22
+ raise ValueError("Dataframe doesn't contain all the required columns.")
23
+
24
+ def prepare_wallet_daily_balance_df(
25
+ self, timestamp_col_name: str, profit_col_name: str
26
+ ) -> pd.DataFrame:
27
+ self.__has_df_valid_columns_else_exception(
28
+ [timestamp_col_name, profit_col_name]
29
+ )
30
+ df = self.df.copy()
31
+ df[timestamp_col_name] = pd.to_datetime(df[timestamp_col_name])
32
+ df.sort_values(timestamp_col_name, ascending=True, inplace=True)
33
+
34
+ df["profit_cumsum"] = df[profit_col_name].cumsum()
35
+ df["profit_cumsum"] = df["profit_cumsum"] + 50
36
+
37
+ df = df.drop_duplicates(subset=timestamp_col_name, keep="last")
38
+ df.set_index(timestamp_col_name, inplace=True)
39
+ # We generate a new Dataframe with daily wallet balances, derived by the final wallet balance
40
+ # from the previous day.
41
+ wallet_balance_daily_df = df[["profit_cumsum"]].resample("D").ffill()
42
+ wallet_balance_daily_df.dropna(inplace=True)
43
+ wallet_balance_daily_df["returns"] = wallet_balance_daily_df[
44
+ "profit_cumsum"
45
+ ].pct_change()
46
+ return wallet_balance_daily_df
47
+
48
+ def calculate_annual_sharpe_ratio(
49
+ self, timestamp_col_name: str = "timestamp", profit_col_name: str = "sim_profit"
50
+ ) -> SharpeOutput:
51
+ wallet_daily_balance_df = self.prepare_wallet_daily_balance_df(
52
+ timestamp_col_name=timestamp_col_name, profit_col_name=profit_col_name
53
+ )
54
+
55
+ daily_volatility = wallet_daily_balance_df["returns"].std()
56
+ annualized_volatility = daily_volatility * np.sqrt(365)
57
+ mean_daily_return = wallet_daily_balance_df["returns"].mean()
58
+ daily_sharpe_ratio = (
59
+ mean_daily_return - self.risk_free_rate
60
+ ) / daily_volatility
61
+ annualized_sharpe_ratio = daily_sharpe_ratio * np.sqrt(365)
62
+ return SharpeOutput(
63
+ annualized_volatility=annualized_volatility,
64
+ mean_daily_return=mean_daily_return,
65
+ annualized_sharpe_ratio=annualized_sharpe_ratio,
66
+ )
@@ -8,7 +8,7 @@ from pydantic import BaseModel, field_validator
8
8
  from web3 import Web3
9
9
  from web3.contract.contract import Contract as Web3Contract
10
10
 
11
- from prediction_market_agent_tooling.config import APIKeys
11
+ from prediction_market_agent_tooling.config import APIKeys, RPCConfig
12
12
  from prediction_market_agent_tooling.gtypes import (
13
13
  ABI,
14
14
  ChainID,
@@ -18,10 +18,6 @@ from prediction_market_agent_tooling.gtypes import (
18
18
  TxReceipt,
19
19
  Wei,
20
20
  )
21
- from prediction_market_agent_tooling.tools.gnosis_rpc import (
22
- GNOSIS_NETWORK_ID,
23
- GNOSIS_RPC_URL,
24
- )
25
21
  from prediction_market_agent_tooling.tools.utils import DatetimeUTC, should_not_happen
26
22
  from prediction_market_agent_tooling.tools.web3_utils import (
27
23
  call_function_on_contract,
@@ -391,8 +387,8 @@ class ContractOnGnosisChain(ContractBaseClass):
391
387
  Contract base class with Gnosis Chain configuration.
392
388
  """
393
389
 
394
- CHAIN_ID = GNOSIS_NETWORK_ID
395
- CHAIN_RPC_URL = GNOSIS_RPC_URL
390
+ CHAIN_ID = RPCConfig().chain_id
391
+ CHAIN_RPC_URL = RPCConfig().gnosis_rpc_url
396
392
 
397
393
 
398
394
  class ContractProxyOnGnosisChain(ContractProxyBaseClass, ContractOnGnosisChain):
@@ -1,10 +1,14 @@
1
+ import json
1
2
  import typing as t
2
3
  from datetime import timedelta
3
4
 
4
5
  import tenacity
6
+ from google.cloud import secretmanager
5
7
  from googleapiclient.discovery import build
8
+ from pydantic import SecretStr
6
9
 
7
- from prediction_market_agent_tooling.config import APIKeys
10
+ from prediction_market_agent_tooling.config import APIKeys, CloudCredentials
11
+ from prediction_market_agent_tooling.gtypes import PrivateKey
8
12
  from prediction_market_agent_tooling.loggers import logger
9
13
  from prediction_market_agent_tooling.tools.caches.db_cache import db_cache
10
14
 
@@ -51,3 +55,26 @@ def search_google(
51
55
  )
52
56
  except KeyError as e:
53
57
  raise ValueError(f"Can not parse results: {search}") from e
58
+
59
+
60
+ def get_private_key_from_gcp_secret(
61
+ secret_id: str,
62
+ project_id: str = "582587111398", # Gnosis AI default project_id
63
+ version_id: str = "latest",
64
+ ) -> PrivateKey:
65
+ # If credentials filename specified, use that, else read using default credentials path.
66
+ google_application_credentials_filename = (
67
+ CloudCredentials().GOOGLE_APPLICATION_CREDENTIALS
68
+ )
69
+ if google_application_credentials_filename is not None:
70
+ # mypy interprets incorrectly that from_service_account_json requires further args.
71
+ client = secretmanager.SecretManagerServiceClient.from_service_account_json(filename=google_application_credentials_filename) # type: ignore [call-arg]
72
+ else:
73
+ client = secretmanager.SecretManagerServiceClient()
74
+ name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
75
+ response = client.access_secret_version(request={"name": name})
76
+ secret_payload = response.payload.data.decode("UTF-8")
77
+ secret_json = json.loads(secret_payload)
78
+ if "private_key" not in secret_json:
79
+ raise ValueError(f"Private key not found in gcp secret {secret_id}")
80
+ return PrivateKey(SecretStr(secret_json["private_key"]))
@@ -17,7 +17,7 @@ def rewrite_question_into_image_generation_prompt(question: str) -> str:
17
17
  "openai not installed, please install extras `langchain` to use this function."
18
18
  )
19
19
  llm = ChatOpenAI(
20
- model="gpt-4-turbo",
20
+ model="gpt-4o-2024-08-06",
21
21
  temperature=0.0,
22
22
  api_key=APIKeys().openai_api_key_secretstr_v1,
23
23
  )
@@ -60,7 +60,7 @@ Finally, write your final decision, write `decision: ` followed by either "yes i
60
60
  @db_cache
61
61
  def is_invalid(
62
62
  question: str,
63
- engine: str = "gpt-4o",
63
+ engine: str = "gpt-4o-2024-08-06",
64
64
  temperature: float = LLM_SUPER_LOW_TEMPERATURE,
65
65
  seed: int = LLM_SEED,
66
66
  prompt_template: str = QUESTION_IS_INVALID_PROMPT,
@@ -7,7 +7,10 @@ from prediction_market_agent_tooling.tools.langfuse_ import (
7
7
  get_langfuse_langchain_config,
8
8
  observe,
9
9
  )
10
- from prediction_market_agent_tooling.tools.utils import LLM_SUPER_LOW_TEMPERATURE
10
+ from prediction_market_agent_tooling.tools.utils import (
11
+ LLM_SEED,
12
+ LLM_SUPER_LOW_TEMPERATURE,
13
+ )
11
14
 
12
15
  # I tried to make it return a JSON, but it didn't work well in combo with asking it to do chain of thought.
13
16
  QUESTION_IS_PREDICTABLE_BINARY_PROMPT = """Main signs about a fully qualified question (sometimes referred to as a "market"):
@@ -81,7 +84,7 @@ Finally, write your final decision, write `decision: ` followed by either "yes i
81
84
  @db_cache
82
85
  def is_predictable_binary(
83
86
  question: str,
84
- engine: str = "gpt-4-1106-preview",
87
+ engine: str = "gpt-4o-2024-08-06",
85
88
  prompt_template: str = QUESTION_IS_PREDICTABLE_BINARY_PROMPT,
86
89
  max_tokens: int = 1024,
87
90
  ) -> bool:
@@ -98,6 +101,7 @@ def is_predictable_binary(
98
101
  llm = ChatOpenAI(
99
102
  model=engine,
100
103
  temperature=LLM_SUPER_LOW_TEMPERATURE,
104
+ seed=LLM_SEED,
101
105
  api_key=APIKeys().openai_api_key_secretstr_v1,
102
106
  )
103
107
 
@@ -118,7 +122,7 @@ def is_predictable_binary(
118
122
  def is_predictable_without_description(
119
123
  question: str,
120
124
  description: str,
121
- engine: str = "gpt-4-1106-preview",
125
+ engine: str = "gpt-4o-2024-08-06",
122
126
  prompt_template: str = QUESTION_IS_PREDICTABLE_WITHOUT_DESCRIPTION_PROMPT,
123
127
  max_tokens: int = 1024,
124
128
  ) -> bool:
@@ -137,6 +141,7 @@ def is_predictable_without_description(
137
141
  llm = ChatOpenAI(
138
142
  model=engine,
139
143
  temperature=LLM_SUPER_LOW_TEMPERATURE,
144
+ seed=LLM_SEED,
140
145
  api_key=APIKeys().openai_api_key_secretstr_v1,
141
146
  )
142
147
 
@@ -70,6 +70,7 @@ def get_traces_for_agent(
70
70
  page = 1 # index starts from 1
71
71
  all_agent_traces = []
72
72
  while True:
73
+ logger.debug(f"fetching page {page}")
73
74
  traces = client.fetch_traces(
74
75
  name=trace_name,
75
76
  limit=100,
@@ -0,0 +1,48 @@
1
+ import diskcache as dc
2
+ import tenacity
3
+ from eth_typing import HexStr
4
+ from tenacity import wait_exponential
5
+ from web3 import Web3
6
+
7
+ from prediction_market_agent_tooling.loggers import logger
8
+
9
+
10
+ class TransactionBlockCache:
11
+ def __init__(self, web3: Web3):
12
+ self.block_number_cache = dc.Cache("block_cache_dir")
13
+ self.block_timestamp_cache = dc.Cache("timestamp_cache_dir")
14
+ self.web3 = web3
15
+
16
+ @tenacity.retry(
17
+ wait=wait_exponential(multiplier=1, min=1, max=4),
18
+ stop=tenacity.stop_after_attempt(7),
19
+ after=lambda x: logger.debug(f"fetch tx failed, {x.attempt_number=}."),
20
+ )
21
+ def fetch_block_number(self, transaction_hash: str) -> int:
22
+ tx = self.web3.eth.get_transaction(HexStr(transaction_hash))
23
+ return tx["blockNumber"]
24
+
25
+ @tenacity.retry(
26
+ wait=wait_exponential(multiplier=1, min=1, max=4),
27
+ stop=tenacity.stop_after_attempt(7),
28
+ after=lambda x: logger.debug(f"fetch tx failed, {x.attempt_number=}."),
29
+ )
30
+ def fetch_block_timestamp(self, block_number: int) -> int:
31
+ block = self.web3.eth.get_block(block_number)
32
+ return block["timestamp"]
33
+
34
+ def get_block_number(self, tx_hash: str) -> int:
35
+ if tx_hash in self.block_number_cache:
36
+ return int(self.block_number_cache[tx_hash])
37
+
38
+ block_number = self.fetch_block_number(tx_hash)
39
+ self.block_number_cache[tx_hash] = block_number
40
+ return block_number
41
+
42
+ def get_block_timestamp(self, block_number: int) -> int:
43
+ if block_number in self.block_timestamp_cache:
44
+ return int(self.block_timestamp_cache[block_number])
45
+
46
+ block_timestamp = self.fetch_block_timestamp(block_number)
47
+ self.block_timestamp_cache[block_number] = block_timestamp
48
+ return block_timestamp
@@ -1,4 +1,3 @@
1
- import json
2
1
  import os
3
2
  import subprocess
4
3
  from datetime import datetime
@@ -6,17 +5,11 @@ from typing import Any, NoReturn, Optional, Type, TypeVar
6
5
 
7
6
  import pytz
8
7
  import requests
9
- from google.cloud import secretmanager
10
8
  from pydantic import BaseModel, ValidationError
11
9
  from scipy.optimize import newton
12
10
  from scipy.stats import entropy
13
11
 
14
- from prediction_market_agent_tooling.gtypes import (
15
- DatetimeUTC,
16
- PrivateKey,
17
- Probability,
18
- SecretStr,
19
- )
12
+ from prediction_market_agent_tooling.gtypes import DatetimeUTC, Probability, SecretStr
20
13
  from prediction_market_agent_tooling.loggers import logger
21
14
  from prediction_market_agent_tooling.markets.market_fees import MarketFees
22
15
 
@@ -214,18 +207,3 @@ def calculate_sell_amount_in_collateral(
214
207
 
215
208
  amount_to_sell = newton(f, 0)
216
209
  return float(amount_to_sell) * 0.999999 # Avoid rounding errors
217
-
218
-
219
- def get_private_key_from_gcp_secret(
220
- secret_id: str,
221
- project_id: str = "582587111398", # Gnosis AI default project_id
222
- version_id: str = "latest",
223
- ) -> PrivateKey:
224
- client = secretmanager.SecretManagerServiceClient()
225
- name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
226
- response = client.access_secret_version(request={"name": name})
227
- secret_payload = response.payload.data.decode("UTF-8")
228
- secret_json = json.loads(secret_payload)
229
- if "private_key" not in secret_json:
230
- raise ValueError(f"Private key not found in gcp secret {secret_id}")
231
- return PrivateKey(SecretStr(secret_json["private_key"]))
@@ -263,7 +263,11 @@ def send_function_on_contract_tx_using_safe(
263
263
  )
264
264
  safe_tx.sign(from_private_key.get_secret_value())
265
265
  safe_tx.call() # simulate call
266
- tx_hash, tx = safe_tx.execute(from_private_key.get_secret_value())
266
+ eoa_nonce = web3.eth.get_transaction_count(eoa_public_key)
267
+ tx_hash, tx = safe_tx.execute(
268
+ from_private_key.get_secret_value(),
269
+ tx_nonce=eoa_nonce,
270
+ )
267
271
  receipt_tx = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=timeout)
268
272
  check_tx_receipt(receipt_tx)
269
273
  return receipt_tx
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "prediction-market-agent-tooling"
3
- version = "0.56.3"
3
+ version = "0.57.0"
4
4
  description = "Tools to benchmark, deploy and monitor prediction market agents."
5
5
  authors = ["Gnosis"]
6
6
  readme = "README.md"
@@ -65,6 +65,7 @@ mypy = "^1.11.1"
65
65
  black = "^23.12.1"
66
66
  ape-foundry = "^0.8.2"
67
67
  eth-ape = "^0.8.10,<0.8.17" # 0.8.17 doesn't work with the current configuration and needs a fix, see https://github.com/gnosis/prediction-market-agent-tooling/issues/518.
68
+ diskcache = "^5.6.3"
68
69
 
69
70
  [build-system]
70
71
  requires = ["poetry-core"]
@@ -1,6 +0,0 @@
1
- import os
2
-
3
- from prediction_market_agent_tooling.gtypes import ChainID
4
-
5
- GNOSIS_NETWORK_ID = ChainID(100) # xDai network.
6
- GNOSIS_RPC_URL = os.getenv("GNOSIS_RPC_URL", "https://rpc.gnosischain.com")