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