prediction-market-agent-tooling 0.67.1__py3-none-any.whl → 0.67.3__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/abis/erc1155.abi.json +352 -0
- prediction_market_agent_tooling/deploy/agent.py +109 -47
- prediction_market_agent_tooling/deploy/betting_strategy.py +1 -1
- prediction_market_agent_tooling/markets/agent_market.py +16 -3
- prediction_market_agent_tooling/markets/manifold/manifold.py +4 -3
- prediction_market_agent_tooling/markets/markets.py +6 -5
- prediction_market_agent_tooling/markets/metaculus/metaculus.py +4 -3
- prediction_market_agent_tooling/markets/omen/omen.py +5 -4
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +5 -4
- prediction_market_agent_tooling/markets/seer/data_models.py +30 -8
- prediction_market_agent_tooling/markets/seer/seer.py +79 -20
- prediction_market_agent_tooling/markets/seer/seer_contracts.py +18 -0
- prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +149 -20
- prediction_market_agent_tooling/markets/seer/subgraph_data_models.py +0 -4
- prediction_market_agent_tooling/markets/seer/swap_pool_handler.py +0 -10
- prediction_market_agent_tooling/tools/contract.py +59 -0
- prediction_market_agent_tooling/tools/cow/cow_order.py +4 -1
- prediction_market_agent_tooling/tools/rephrase.py +71 -0
- prediction_market_agent_tooling/tools/tokens/auto_deposit.py +57 -0
- {prediction_market_agent_tooling-0.67.1.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/METADATA +2 -1
- {prediction_market_agent_tooling-0.67.1.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/RECORD +24 -22
- {prediction_market_agent_tooling-0.67.1.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.67.1.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.67.1.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/entry_points.txt +0 -0
@@ -3,11 +3,12 @@ from enum import Enum
|
|
3
3
|
|
4
4
|
from prediction_market_agent_tooling.jobs.jobs_models import JobAgentMarket
|
5
5
|
from prediction_market_agent_tooling.jobs.omen.omen_jobs import OmenJobAgentMarket
|
6
|
-
from prediction_market_agent_tooling.markets.agent_market import AgentMarket, FilterBy
|
7
6
|
from prediction_market_agent_tooling.markets.agent_market import (
|
8
|
-
|
7
|
+
AgentMarket,
|
8
|
+
FilterBy,
|
9
|
+
QuestionType,
|
10
|
+
SortBy,
|
9
11
|
)
|
10
|
-
from prediction_market_agent_tooling.markets.agent_market import SortBy
|
11
12
|
from prediction_market_agent_tooling.markets.manifold.manifold import (
|
12
13
|
ManifoldAgentMarket,
|
13
14
|
)
|
@@ -68,7 +69,7 @@ def get_binary_markets(
|
|
68
69
|
sort_by: SortBy = SortBy.NONE,
|
69
70
|
excluded_questions: set[str] | None = None,
|
70
71
|
created_after: DatetimeUTC | None = None,
|
71
|
-
|
72
|
+
question_type: QuestionType = QuestionType.BINARY,
|
72
73
|
) -> t.Sequence[AgentMarket]:
|
73
74
|
agent_market_class = MARKET_TYPE_TO_AGENT_MARKET[market_type]
|
74
75
|
markets = agent_market_class.get_markets(
|
@@ -77,6 +78,6 @@ def get_binary_markets(
|
|
77
78
|
filter_by=filter_by,
|
78
79
|
created_after=created_after,
|
79
80
|
excluded_questions=excluded_questions,
|
80
|
-
|
81
|
+
question_type=question_type,
|
81
82
|
)
|
82
83
|
return markets
|
@@ -7,10 +7,11 @@ from prediction_market_agent_tooling.config import APIKeys
|
|
7
7
|
from prediction_market_agent_tooling.gtypes import OutcomeStr, Probability
|
8
8
|
from prediction_market_agent_tooling.markets.agent_market import (
|
9
9
|
AgentMarket,
|
10
|
+
ConditionalFilterType,
|
10
11
|
FilterBy,
|
11
12
|
MarketFees,
|
12
|
-
MarketType,
|
13
13
|
ProcessedMarket,
|
14
|
+
QuestionType,
|
14
15
|
SortBy,
|
15
16
|
)
|
16
17
|
from prediction_market_agent_tooling.markets.metaculus.api import (
|
@@ -73,8 +74,8 @@ class MetaculusAgentMarket(AgentMarket):
|
|
73
74
|
filter_by: FilterBy = FilterBy.OPEN,
|
74
75
|
created_after: t.Optional[DatetimeUTC] = None,
|
75
76
|
excluded_questions: set[str] | None = None,
|
76
|
-
|
77
|
-
|
77
|
+
question_type: QuestionType = QuestionType.ALL,
|
78
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
78
79
|
tournament_id: int | None = None,
|
79
80
|
) -> t.Sequence["MetaculusAgentMarket"]:
|
80
81
|
order_by: str | None
|
@@ -23,11 +23,12 @@ from prediction_market_agent_tooling.gtypes import (
|
|
23
23
|
from prediction_market_agent_tooling.loggers import logger
|
24
24
|
from prediction_market_agent_tooling.markets.agent_market import (
|
25
25
|
AgentMarket,
|
26
|
+
ConditionalFilterType,
|
26
27
|
FilterBy,
|
27
28
|
MarketFees,
|
28
|
-
MarketType,
|
29
29
|
ProcessedMarket,
|
30
30
|
ProcessedTradedMarket,
|
31
|
+
QuestionType,
|
31
32
|
SortBy,
|
32
33
|
)
|
33
34
|
from prediction_market_agent_tooling.markets.blockchain_utils import store_trades
|
@@ -380,10 +381,10 @@ class OmenAgentMarket(AgentMarket):
|
|
380
381
|
filter_by: FilterBy = FilterBy.OPEN,
|
381
382
|
created_after: t.Optional[DatetimeUTC] = None,
|
382
383
|
excluded_questions: set[str] | None = None,
|
383
|
-
|
384
|
-
|
384
|
+
question_type: QuestionType = QuestionType.ALL,
|
385
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
385
386
|
) -> t.Sequence["OmenAgentMarket"]:
|
386
|
-
fetch_categorical_markets =
|
387
|
+
fetch_categorical_markets = question_type == QuestionType.CATEGORICAL
|
387
388
|
|
388
389
|
return [
|
389
390
|
OmenAgentMarket.from_data_model(m)
|
@@ -9,9 +9,10 @@ from prediction_market_agent_tooling.gtypes import (
|
|
9
9
|
)
|
10
10
|
from prediction_market_agent_tooling.markets.agent_market import (
|
11
11
|
AgentMarket,
|
12
|
+
ConditionalFilterType,
|
12
13
|
FilterBy,
|
13
14
|
MarketFees,
|
14
|
-
|
15
|
+
QuestionType,
|
15
16
|
SortBy,
|
16
17
|
)
|
17
18
|
from prediction_market_agent_tooling.markets.data_models import Resolution
|
@@ -123,8 +124,8 @@ class PolymarketAgentMarket(AgentMarket):
|
|
123
124
|
filter_by: FilterBy = FilterBy.OPEN,
|
124
125
|
created_after: t.Optional[DatetimeUTC] = None,
|
125
126
|
excluded_questions: set[str] | None = None,
|
126
|
-
|
127
|
-
|
127
|
+
question_type: QuestionType = QuestionType.ALL,
|
128
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
128
129
|
) -> t.Sequence["PolymarketAgentMarket"]:
|
129
130
|
closed: bool | None
|
130
131
|
|
@@ -159,7 +160,7 @@ class PolymarketAgentMarket(AgentMarket):
|
|
159
160
|
ascending=ascending,
|
160
161
|
created_after=created_after,
|
161
162
|
excluded_questions=excluded_questions,
|
162
|
-
only_binary=
|
163
|
+
only_binary=question_type is not QuestionType.CATEGORICAL,
|
163
164
|
)
|
164
165
|
|
165
166
|
condition_models = PolymarketSubgraphHandler().get_conditions(
|
@@ -3,7 +3,7 @@ from datetime import timedelta
|
|
3
3
|
from typing import Annotated
|
4
4
|
from urllib.parse import urljoin
|
5
5
|
|
6
|
-
from pydantic import BaseModel, BeforeValidator, ConfigDict, Field
|
6
|
+
from pydantic import BaseModel, BeforeValidator, ConfigDict, Field, computed_field
|
7
7
|
from web3 import Web3
|
8
8
|
from web3.constants import ADDRESS_ZERO
|
9
9
|
|
@@ -17,9 +17,6 @@ from prediction_market_agent_tooling.gtypes import (
|
|
17
17
|
Web3Wei,
|
18
18
|
Wei,
|
19
19
|
)
|
20
|
-
from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
|
21
|
-
SeerParentMarket,
|
22
|
-
)
|
23
20
|
from prediction_market_agent_tooling.tools.contract import ContractERC20OnGnosisChain
|
24
21
|
from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
|
25
22
|
from prediction_market_agent_tooling.tools.utils import utcnow
|
@@ -51,10 +48,14 @@ class CreateCategoricalMarketsParams(BaseModel):
|
|
51
48
|
SEER_BASE_URL = "https://app.seer.pm"
|
52
49
|
|
53
50
|
|
54
|
-
def seer_normalize_wei(value: int | None) -> int | None:
|
51
|
+
def seer_normalize_wei(value: int | dict[str, t.Any] | None) -> int | None:
|
55
52
|
# See https://github.com/seer-pm/demo/blob/main/web/netlify/edge-functions/utils/common.ts#L22
|
56
53
|
if value is None:
|
57
54
|
return value
|
55
|
+
elif isinstance(value, dict):
|
56
|
+
if value.get("value") is None:
|
57
|
+
raise ValueError(f"Expected a dictionary with a value key, but got {value}")
|
58
|
+
value = int(value["value"])
|
58
59
|
is_in_wei = value > 1e10
|
59
60
|
return value if is_in_wei else value * 10**18
|
60
61
|
|
@@ -62,6 +63,21 @@ def seer_normalize_wei(value: int | None) -> int | None:
|
|
62
63
|
SeerNormalizedWei = Annotated[Wei | None, BeforeValidator(seer_normalize_wei)]
|
63
64
|
|
64
65
|
|
66
|
+
class MarketId(BaseModel):
|
67
|
+
id: HexBytes
|
68
|
+
|
69
|
+
|
70
|
+
class SeerQuestion(BaseModel):
|
71
|
+
id: str
|
72
|
+
best_answer: HexBytes
|
73
|
+
finalize_ts: int
|
74
|
+
|
75
|
+
|
76
|
+
class SeerMarketQuestions(BaseModel):
|
77
|
+
question: SeerQuestion
|
78
|
+
market: MarketId
|
79
|
+
|
80
|
+
|
65
81
|
class SeerMarket(BaseModel):
|
66
82
|
model_config = ConfigDict(populate_by_name=True)
|
67
83
|
|
@@ -70,10 +86,11 @@ class SeerMarket(BaseModel):
|
|
70
86
|
title: str = Field(alias="marketName")
|
71
87
|
outcomes: t.Sequence[OutcomeStr]
|
72
88
|
wrapped_tokens: list[HexAddress] = Field(alias="wrappedTokens")
|
73
|
-
parent_outcome: int = Field(
|
74
|
-
|
75
|
-
alias="parentMarket", default=None
|
89
|
+
parent_outcome: int = Field(
|
90
|
+
alias="parentOutcome", description="It comes as 0 from non-conditioned markets."
|
76
91
|
)
|
92
|
+
parent_market: t.Optional["SeerMarket"] = Field(alias="parentMarket", default=None)
|
93
|
+
template_id: int = Field(alias="templateId")
|
77
94
|
collateral_token: HexAddress = Field(alias="collateralToken")
|
78
95
|
condition_id: HexBytes = Field(alias="conditionId")
|
79
96
|
opening_ts: int = Field(alias="openingTs")
|
@@ -139,12 +156,17 @@ class SeerMarket(BaseModel):
|
|
139
156
|
def created_time(self) -> DatetimeUTC:
|
140
157
|
return DatetimeUTC.to_datetime_utc(self.block_timestamp)
|
141
158
|
|
159
|
+
@computed_field # type: ignore[prop-decorator]
|
142
160
|
@property
|
143
161
|
def url(self) -> str:
|
144
162
|
chain_id = RPCConfig().chain_id
|
145
163
|
return urljoin(SEER_BASE_URL, f"markets/{chain_id}/{self.id.hex()}")
|
146
164
|
|
147
165
|
|
166
|
+
class SeerMarketWithQuestions(SeerMarket):
|
167
|
+
questions: list[SeerMarketQuestions]
|
168
|
+
|
169
|
+
|
148
170
|
class RedeemParams(BaseModel):
|
149
171
|
model_config = ConfigDict(populate_by_name=True)
|
150
172
|
market: ChecksumAddress
|
@@ -23,15 +23,19 @@ from prediction_market_agent_tooling.gtypes import (
|
|
23
23
|
from prediction_market_agent_tooling.loggers import logger
|
24
24
|
from prediction_market_agent_tooling.markets.agent_market import (
|
25
25
|
AgentMarket,
|
26
|
+
ConditionalFilterType,
|
26
27
|
FilterBy,
|
27
|
-
|
28
|
-
MarketType,
|
28
|
+
ParentMarket,
|
29
29
|
ProcessedMarket,
|
30
30
|
ProcessedTradedMarket,
|
31
|
+
QuestionType,
|
31
32
|
SortBy,
|
32
33
|
)
|
33
34
|
from prediction_market_agent_tooling.markets.blockchain_utils import store_trades
|
34
|
-
from prediction_market_agent_tooling.markets.data_models import
|
35
|
+
from prediction_market_agent_tooling.markets.data_models import (
|
36
|
+
ExistingPosition,
|
37
|
+
Resolution,
|
38
|
+
)
|
35
39
|
from prediction_market_agent_tooling.markets.market_fees import MarketFees
|
36
40
|
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
37
41
|
from prediction_market_agent_tooling.markets.omen.omen_constants import (
|
@@ -43,6 +47,7 @@ from prediction_market_agent_tooling.markets.omen.omen_contracts import (
|
|
43
47
|
from prediction_market_agent_tooling.markets.seer.data_models import (
|
44
48
|
RedeemParams,
|
45
49
|
SeerMarket,
|
50
|
+
SeerMarketWithQuestions,
|
46
51
|
)
|
47
52
|
from prediction_market_agent_tooling.markets.seer.exceptions import (
|
48
53
|
PriceCalculationError,
|
@@ -53,7 +58,9 @@ from prediction_market_agent_tooling.markets.seer.seer_contracts import (
|
|
53
58
|
SeerMarketFactory,
|
54
59
|
)
|
55
60
|
from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
|
61
|
+
SeerQuestionsCache,
|
56
62
|
SeerSubgraphHandler,
|
63
|
+
TemplateId,
|
57
64
|
)
|
58
65
|
from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
|
59
66
|
NewMarketEvent,
|
@@ -86,7 +93,7 @@ from prediction_market_agent_tooling.tools.tokens.usd import (
|
|
86
93
|
get_token_in_usd,
|
87
94
|
get_usd_in_token,
|
88
95
|
)
|
89
|
-
from prediction_market_agent_tooling.tools.utils import utcnow
|
96
|
+
from prediction_market_agent_tooling.tools.utils import check_not_none, utcnow
|
90
97
|
|
91
98
|
# We place a larger bet amount by default than Omen so that cow presents valid quotes.
|
92
99
|
SEER_TINY_BET_AMOUNT = USD(0.1)
|
@@ -256,7 +263,7 @@ class SeerAgentMarket(AgentMarket):
|
|
256
263
|
@staticmethod
|
257
264
|
def _filter_markets_contained_in_trades(
|
258
265
|
api_keys: APIKeys,
|
259
|
-
markets:
|
266
|
+
markets: t.Sequence[SeerMarket],
|
260
267
|
) -> list[SeerMarket]:
|
261
268
|
"""
|
262
269
|
We filter the markets using previous trades by the user so that we don't have to process all Seer markets.
|
@@ -266,7 +273,7 @@ class SeerAgentMarket(AgentMarket):
|
|
266
273
|
traded_tokens = {t.buyToken for t in trades_by_user}.union(
|
267
274
|
[t.sellToken for t in trades_by_user]
|
268
275
|
)
|
269
|
-
filtered_markets = []
|
276
|
+
filtered_markets: list[SeerMarket] = []
|
270
277
|
for market in markets:
|
271
278
|
if any(
|
272
279
|
[
|
@@ -337,9 +344,64 @@ class SeerAgentMarket(AgentMarket):
|
|
337
344
|
return OmenAgentMarket.verify_operational_balance(api_keys=api_keys)
|
338
345
|
|
339
346
|
@staticmethod
|
340
|
-
def
|
347
|
+
def build_resolution(
|
348
|
+
model: SeerMarketWithQuestions,
|
349
|
+
) -> Resolution | None:
|
350
|
+
if model.questions[0].question.finalize_ts == 0:
|
351
|
+
# resolution not yet finalized
|
352
|
+
return None
|
353
|
+
|
354
|
+
if model.template_id != TemplateId.CATEGORICAL:
|
355
|
+
logger.warning("Resolution can only be built for categorical markets.")
|
356
|
+
# Future note - for scalar markets, simply fetch best_answer and convert
|
357
|
+
# from hex into int and divide by 1e18 (because Wei).
|
358
|
+
return None
|
359
|
+
|
360
|
+
if len(model.questions) != 1:
|
361
|
+
raise ValueError("Seer categorical markets must have 1 question.")
|
362
|
+
|
363
|
+
question = model.questions[0]
|
364
|
+
outcome = model.outcomes[int(question.question.best_answer.hex(), 16)]
|
365
|
+
return Resolution(outcome=outcome, invalid=False)
|
366
|
+
|
367
|
+
@staticmethod
|
368
|
+
def convert_seer_market_into_market_with_questions(
|
369
|
+
seer_market: SeerMarket, seer_subgraph: SeerSubgraphHandler
|
370
|
+
) -> "SeerMarketWithQuestions":
|
371
|
+
q = SeerQuestionsCache(seer_subgraph_handler=seer_subgraph)
|
372
|
+
q.fetch_questions([seer_market.id])
|
373
|
+
questions = q.market_id_to_questions[seer_market.id]
|
374
|
+
return SeerMarketWithQuestions(**seer_market.model_dump(), questions=questions)
|
375
|
+
|
376
|
+
@staticmethod
|
377
|
+
def get_parent(
|
341
378
|
model: SeerMarket,
|
342
379
|
seer_subgraph: SeerSubgraphHandler,
|
380
|
+
) -> t.Optional["ParentMarket"]:
|
381
|
+
if not model.parent_market:
|
382
|
+
return None
|
383
|
+
|
384
|
+
# turn into a market with questions
|
385
|
+
parent_market_with_questions = (
|
386
|
+
SeerAgentMarket.convert_seer_market_into_market_with_questions(
|
387
|
+
model.parent_market, seer_subgraph=seer_subgraph
|
388
|
+
)
|
389
|
+
)
|
390
|
+
|
391
|
+
market_with_questions = check_not_none(
|
392
|
+
SeerAgentMarket.from_data_model_with_subgraph(
|
393
|
+
parent_market_with_questions, seer_subgraph, False
|
394
|
+
)
|
395
|
+
)
|
396
|
+
|
397
|
+
return ParentMarket(
|
398
|
+
market=market_with_questions, parent_outcome=model.parent_outcome
|
399
|
+
)
|
400
|
+
|
401
|
+
@staticmethod
|
402
|
+
def from_data_model_with_subgraph(
|
403
|
+
model: SeerMarketWithQuestions,
|
404
|
+
seer_subgraph: SeerSubgraphHandler,
|
343
405
|
must_have_prices: bool,
|
344
406
|
) -> t.Optional["SeerAgentMarket"]:
|
345
407
|
price_manager = PriceManager(seer_market=model, seer_subgraph=seer_subgraph)
|
@@ -355,6 +417,10 @@ class SeerAgentMarket(AgentMarket):
|
|
355
417
|
# Price calculation failed, so don't return the market
|
356
418
|
return None
|
357
419
|
|
420
|
+
resolution = SeerAgentMarket.build_resolution(model=model)
|
421
|
+
|
422
|
+
parent = SeerAgentMarket.get_parent(model=model, seer_subgraph=seer_subgraph)
|
423
|
+
|
358
424
|
market = SeerAgentMarket(
|
359
425
|
id=model.id.hex(),
|
360
426
|
question=model.title,
|
@@ -369,11 +435,12 @@ class SeerAgentMarket(AgentMarket):
|
|
369
435
|
fees=MarketFees.get_zero_fees(),
|
370
436
|
outcome_token_pool=None,
|
371
437
|
outcomes_supply=model.outcomes_supply,
|
372
|
-
resolution=
|
438
|
+
resolution=resolution,
|
373
439
|
volume=None,
|
374
440
|
probabilities=probability_map,
|
375
441
|
upper_bound=model.upper_bound,
|
376
442
|
lower_bound=model.lower_bound,
|
443
|
+
parent=parent,
|
377
444
|
)
|
378
445
|
|
379
446
|
return market
|
@@ -385,8 +452,8 @@ class SeerAgentMarket(AgentMarket):
|
|
385
452
|
filter_by: FilterBy = FilterBy.OPEN,
|
386
453
|
created_after: t.Optional[DatetimeUTC] = None,
|
387
454
|
excluded_questions: set[str] | None = None,
|
388
|
-
|
389
|
-
|
455
|
+
question_type: QuestionType = QuestionType.ALL,
|
456
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
390
457
|
) -> t.Sequence["SeerAgentMarket"]:
|
391
458
|
seer_subgraph = SeerSubgraphHandler()
|
392
459
|
|
@@ -394,8 +461,8 @@ class SeerAgentMarket(AgentMarket):
|
|
394
461
|
limit=limit,
|
395
462
|
sort_by=sort_by,
|
396
463
|
filter_by=filter_by,
|
397
|
-
|
398
|
-
|
464
|
+
question_type=question_type,
|
465
|
+
conditional_filter_type=conditional_filter_type,
|
399
466
|
)
|
400
467
|
|
401
468
|
# We exclude the None values below because `from_data_model_with_subgraph` can return None, which
|
@@ -585,14 +652,6 @@ class SeerAgentMarket(AgentMarket):
|
|
585
652
|
collateral_contract, amount_wei, api_keys, web3
|
586
653
|
)
|
587
654
|
|
588
|
-
collateral_balance = collateral_contract.balanceOf(
|
589
|
-
api_keys.bet_from_address, web3=web3
|
590
|
-
)
|
591
|
-
if collateral_balance < amount_wei:
|
592
|
-
raise ValueError(
|
593
|
-
f"Balance {collateral_balance} not enough for bet size {amount}"
|
594
|
-
)
|
595
|
-
|
596
655
|
return self._swap_tokens_with_fallback(
|
597
656
|
sell_token=collateral_contract.address,
|
598
657
|
buy_token=outcome_token,
|
@@ -9,6 +9,7 @@ from prediction_market_agent_tooling.gtypes import (
|
|
9
9
|
ChecksumAddress,
|
10
10
|
OutcomeStr,
|
11
11
|
TxReceipt,
|
12
|
+
Wei,
|
12
13
|
xDai,
|
13
14
|
)
|
14
15
|
from prediction_market_agent_tooling.markets.seer.data_models import (
|
@@ -115,6 +116,23 @@ class GnosisRouter(ContractOnGnosisChain):
|
|
115
116
|
)
|
116
117
|
return receipt_tx
|
117
118
|
|
119
|
+
def split_position(
|
120
|
+
self,
|
121
|
+
api_keys: APIKeys,
|
122
|
+
collateral_token: ChecksumAddress,
|
123
|
+
market_id: ChecksumAddress,
|
124
|
+
amount: Wei,
|
125
|
+
web3: Web3 | None = None,
|
126
|
+
) -> TxReceipt:
|
127
|
+
"""Splits collateral token into full set of outcome tokens."""
|
128
|
+
receipt_tx = self.send(
|
129
|
+
api_keys=api_keys,
|
130
|
+
function_name="splitPosition",
|
131
|
+
function_params=[collateral_token, market_id, amount],
|
132
|
+
web3=web3,
|
133
|
+
)
|
134
|
+
return receipt_tx
|
135
|
+
|
118
136
|
|
119
137
|
class SwaprRouterContract(ContractOnGnosisChain):
|
120
138
|
# File content taken from https://github.com/protofire/omen-exchange/blob/master/app/src/abi/marketMaker.json.
|