From fb06daf67f5fcfb0fdad9e8babb0afa113ab9080 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Tue, 29 Oct 2024 18:57:16 -0300 Subject: [PATCH 01/11] Added pools call --- .../markets/base_subgraph_handler.py | 60 +++++++++++++++++ .../markets/omen/omen_subgraph_handler.py | 64 ++++--------------- .../markets/seer/data_models.py | 30 +++++++++ .../seer/test_seer_subgraph_handler.py | 43 +++++++++++++ 4 files changed, 147 insertions(+), 50 deletions(-) create mode 100644 prediction_market_agent_tooling/markets/base_subgraph_handler.py create mode 100644 prediction_market_agent_tooling/markets/seer/data_models.py create mode 100644 tests_integration/markets/seer/test_seer_subgraph_handler.py diff --git a/prediction_market_agent_tooling/markets/base_subgraph_handler.py b/prediction_market_agent_tooling/markets/base_subgraph_handler.py new file mode 100644 index 00000000..5ac38ab3 --- /dev/null +++ b/prediction_market_agent_tooling/markets/base_subgraph_handler.py @@ -0,0 +1,60 @@ +import typing as t +from abc import ABC + +import tenacity +from pydantic import BaseModel +from subgrounds import Subgrounds, FieldPath + +from prediction_market_agent_tooling.config import APIKeys +from prediction_market_agent_tooling.loggers import logger +from prediction_market_agent_tooling.tools.singleton import SingletonMeta + + +class SingletonABCMeta(SingletonMeta, ABC): + pass + + +T = t.TypeVar("T", bound=BaseModel) + + +class BaseSubgraphHandler(metaclass=SingletonABCMeta): + sg: Subgrounds + keys: APIKeys + + def __init__(self): + self.sg = Subgrounds() + # Patch methods to retry on failure. + self.sg.query_json = tenacity.retry( + stop=tenacity.stop_after_attempt(3), + wait=tenacity.wait_fixed(1), + after=lambda x: logger.debug(f"query_json failed, {x.attempt_number=}."), + )(self.sg.query_json) + self.sg.load_subgraph = tenacity.retry( + stop=tenacity.stop_after_attempt(3), + wait=tenacity.wait_fixed(1), + after=lambda x: logger.debug(f"load_subgraph failed, {x.attempt_number=}."), + )(self.sg.load_subgraph) + + self.keys = APIKeys() + + def _parse_items_from_json( + self, result: list[dict[str, t.Any]] + ) -> list[dict[str, t.Any]]: + """subgrounds return a weird key as a dict key""" + items = [] + for result_chunk in result: + for k, v in result_chunk.items(): + # subgrounds might pack all items as a list, indexed by a key, or pack it as a dictionary (if one single element) + if v is None: + continue + elif isinstance(v, dict): + items.extend([v]) + else: + items.extend(v) + return items + + def do_query(self, fields: list[FieldPath], pydantic_model: t.Type[T]) -> list[T]: + result = self.sg.query_json(fields) + items = self._parse_items_from_json(result) + models = [pydantic_model.model_validate(i) for i in items] + return models diff --git a/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py b/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py index e1513c5f..ebd662ed 100644 --- a/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py @@ -2,12 +2,10 @@ import typing as t import requests -import tenacity from PIL import Image from PIL.Image import Image as ImageType -from subgrounds import FieldPath, Subgrounds +from subgrounds import FieldPath -from prediction_market_agent_tooling.config import APIKeys from prediction_market_agent_tooling.gtypes import ( ChecksumAddress, HexAddress, @@ -15,8 +13,10 @@ Wei, wei_type, ) -from prediction_market_agent_tooling.loggers import logger from prediction_market_agent_tooling.markets.agent_market import FilterBy, SortBy +from prediction_market_agent_tooling.markets.base_subgraph_handler import ( + BaseSubgraphHandler, +) from prediction_market_agent_tooling.markets.omen.data_models import ( OMEN_BINARY_MARKET_OUTCOMES, ContractPrediction, @@ -33,7 +33,6 @@ WrappedxDaiContract, sDaiContract, ) -from prediction_market_agent_tooling.tools.singleton import SingletonMeta from prediction_market_agent_tooling.tools.utils import ( DatetimeUTC, to_int_timestamp, @@ -51,7 +50,7 @@ ) -class OmenSubgraphHandler(metaclass=SingletonMeta): +class OmenSubgraphHandler(BaseSubgraphHandler): """ Class responsible for handling interactions with Omen subgraphs (trades, conditionalTokens). """ @@ -69,47 +68,33 @@ class OmenSubgraphHandler(metaclass=SingletonMeta): INVALID_ANSWER = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" def __init__(self) -> None: - self.sg = Subgrounds() - - # Patch methods to retry on failure. - self.sg.query_json = tenacity.retry( - stop=tenacity.stop_after_attempt(3), - wait=tenacity.wait_fixed(1), - after=lambda x: logger.debug(f"query_json failed, {x.attempt_number=}."), - )(self.sg.query_json) - self.sg.load_subgraph = tenacity.retry( - stop=tenacity.stop_after_attempt(3), - wait=tenacity.wait_fixed(1), - after=lambda x: logger.debug(f"load_subgraph failed, {x.attempt_number=}."), - )(self.sg.load_subgraph) - - keys = APIKeys() + super().__init__() # Load the subgraph self.trades_subgraph = self.sg.load_subgraph( self.OMEN_TRADES_SUBGRAPH.format( - graph_api_key=keys.graph_api_key.get_secret_value() + graph_api_key=self.keys.graph_api_key.get_secret_value() ) ) self.conditional_tokens_subgraph = self.sg.load_subgraph( self.CONDITIONAL_TOKENS_SUBGRAPH.format( - graph_api_key=keys.graph_api_key.get_secret_value() + graph_api_key=self.keys.graph_api_key.get_secret_value() ) ) self.realityeth_subgraph = self.sg.load_subgraph( self.REALITYETH_GRAPH_URL.format( - graph_api_key=keys.graph_api_key.get_secret_value() + graph_api_key=self.keys.graph_api_key.get_secret_value() ) ) self.omen_image_mapping_subgraph = self.sg.load_subgraph( self.OMEN_IMAGE_MAPPING_GRAPH_URL.format( - graph_api_key=keys.graph_api_key.get_secret_value() + graph_api_key=self.keys.graph_api_key.get_secret_value() ) ) self.omen_agent_result_mapping_subgraph = self.sg.load_subgraph( self.OMEN_AGENT_RESULT_MAPPING_GRAPH_URL.format( - graph_api_key=keys.graph_api_key.get_secret_value() + graph_api_key=self.keys.graph_api_key.get_secret_value() ) ) @@ -446,14 +431,8 @@ def get_omen_binary_markets( **optional_params, ) - omen_markets = self.do_markets_query(markets) - return omen_markets - - def do_markets_query(self, markets: FieldPath) -> list[OmenMarket]: fields = self._get_fields_for_markets(markets) - result = self.sg.query_json(fields) - items = self._parse_items_from_json(result) - omen_markets = [OmenMarket.model_validate(i) for i in items] + omen_markets = self.do_query(fields=fields, pydantic_model=OmenMarket) return omen_markets def get_omen_market_by_market_id(self, market_id: HexAddress) -> OmenMarket: @@ -461,7 +440,8 @@ def get_omen_market_by_market_id(self, market_id: HexAddress) -> OmenMarket: id=market_id.lower() ) - omen_markets = self.do_markets_query(markets) + fields = self._get_fields_for_markets(markets) + omen_markets = self.do_query(fields=fields, pydantic_model=OmenMarket) if len(omen_markets) != 1: raise ValueError( @@ -470,22 +450,6 @@ def get_omen_market_by_market_id(self, market_id: HexAddress) -> OmenMarket: return omen_markets[0] - def _parse_items_from_json( - self, result: list[dict[str, t.Any]] - ) -> list[dict[str, t.Any]]: - """subgrounds return a weird key as a dict key""" - items = [] - for result_chunk in result: - for k, v in result_chunk.items(): - # subgrounds might pack all items as a list, indexed by a key, or pack it as a dictionary (if one single element) - if v is None: - continue - elif isinstance(v, dict): - items.extend([v]) - else: - items.extend(v) - return items - def _get_fields_for_user_positions( self, user_positions: FieldPath ) -> list[FieldPath]: diff --git a/prediction_market_agent_tooling/markets/seer/data_models.py b/prediction_market_agent_tooling/markets/seer/data_models.py new file mode 100644 index 00000000..1130a203 --- /dev/null +++ b/prediction_market_agent_tooling/markets/seer/data_models.py @@ -0,0 +1,30 @@ +# ToDo - Inherit from same BaseClass as OmenMarket +from pydantic import ConfigDict, Field, BaseModel + +from prediction_market_agent_tooling.gtypes import ( + HexBytes, +) + + +class SeerMarket(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + id: HexBytes + title: str = Field(alias="marketName") + outcomes: list[str] + parent_market: HexBytes = Field(alias="parentMarket") + wrapped_tokens: list[HexBytes] = Field(alias="wrappedTokens") + + +class SeerToken(BaseModel): + id: HexBytes + name: str + symbol: str + + +class SeerPool(BaseModel): + model_config = ConfigDict(populate_by_name=True) + id: HexBytes + liquidity: int + token0: SeerToken + token1: SeerToken diff --git a/tests_integration/markets/seer/test_seer_subgraph_handler.py b/tests_integration/markets/seer/test_seer_subgraph_handler.py new file mode 100644 index 00000000..c749311e --- /dev/null +++ b/tests_integration/markets/seer/test_seer_subgraph_handler.py @@ -0,0 +1,43 @@ +import typing as t + +import pytest + +from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import ( + SeerSubgraphHandler, +) +from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes + + +@pytest.fixture(scope="module") +def handler() -> t.Generator[SeerSubgraphHandler, None, None]: + yield SeerSubgraphHandler() + + +def test_get_all_seer_markets(handler: SeerSubgraphHandler) -> None: + markets = handler.get_binary_markets() + assert len(markets) > 1 + + +def test_get_seer_market_by_id(handler: SeerSubgraphHandler) -> None: + market_id = HexBytes("0x03cbd8e3a45c727643b015318fff883e13937fdd") + market = handler.get_market_by_id(market_id) + assert market is not None + assert market.id == market_id + + +def test_conditional_market_not_retrieved(handler: SeerSubgraphHandler) -> None: + conditional_market_id = HexBytes("0xe12f48ecdd6e64d95d1d8f1d5d7aa37e14f2888b") + markets = handler.get_binary_markets() + market_ids = [m.id for m in markets] + assert conditional_market_id not in market_ids + + +def test_get_pools_for_market(handler: SeerSubgraphHandler) -> None: + us_election_market_id = HexBytes("0x43d881f5920ed29fc5cd4917d6817496abbba6d9") + market = handler.get_market_by_id(us_election_market_id) + + pools = handler.get_pools_for_market(market) + assert len(pools) > 1 + for pool in pools: + assert pool.token0.id in market.wrapped_tokens + assert pool.token1.id in market.wrapped_tokens From 38311fc3e07fd396439c5fb147c45693dc6dedca Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Tue, 29 Oct 2024 18:59:11 -0300 Subject: [PATCH 02/11] Fixed test --- .../markets/seer/test_seer_subgraph_handler.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests_integration/markets/seer/test_seer_subgraph_handler.py b/tests_integration/markets/seer/test_seer_subgraph_handler.py index c749311e..e21822fe 100644 --- a/tests_integration/markets/seer/test_seer_subgraph_handler.py +++ b/tests_integration/markets/seer/test_seer_subgraph_handler.py @@ -39,5 +39,8 @@ def test_get_pools_for_market(handler: SeerSubgraphHandler) -> None: pools = handler.get_pools_for_market(market) assert len(pools) > 1 for pool in pools: - assert pool.token0.id in market.wrapped_tokens - assert pool.token1.id in market.wrapped_tokens + # one of the tokens must be a wrapped token + assert ( + pool.token0.id in market.wrapped_tokens + or pool.token1.id in market.wrapped_tokens + ) From 0506ea03a4ba4bb73cf86d6e6f7af87f80fcad08 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Wed, 30 Oct 2024 15:30:51 -0300 Subject: [PATCH 03/11] Small fixes --- .../markets/base_subgraph_handler.py | 12 +++--------- .../markets/seer/data_models.py | 7 ++----- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/prediction_market_agent_tooling/markets/base_subgraph_handler.py b/prediction_market_agent_tooling/markets/base_subgraph_handler.py index 5ac38ab3..d171740d 100644 --- a/prediction_market_agent_tooling/markets/base_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/base_subgraph_handler.py @@ -1,27 +1,21 @@ import typing as t -from abc import ABC import tenacity from pydantic import BaseModel -from subgrounds import Subgrounds, FieldPath +from subgrounds import FieldPath, Subgrounds from prediction_market_agent_tooling.config import APIKeys from prediction_market_agent_tooling.loggers import logger from prediction_market_agent_tooling.tools.singleton import SingletonMeta - -class SingletonABCMeta(SingletonMeta, ABC): - pass - - T = t.TypeVar("T", bound=BaseModel) -class BaseSubgraphHandler(metaclass=SingletonABCMeta): +class BaseSubgraphHandler(metaclass=SingletonMeta): sg: Subgrounds keys: APIKeys - def __init__(self): + def __init__(self) -> None: self.sg = Subgrounds() # Patch methods to retry on failure. self.sg.query_json = tenacity.retry( diff --git a/prediction_market_agent_tooling/markets/seer/data_models.py b/prediction_market_agent_tooling/markets/seer/data_models.py index 1130a203..a0a45838 100644 --- a/prediction_market_agent_tooling/markets/seer/data_models.py +++ b/prediction_market_agent_tooling/markets/seer/data_models.py @@ -1,9 +1,6 @@ -# ToDo - Inherit from same BaseClass as OmenMarket -from pydantic import ConfigDict, Field, BaseModel +from pydantic import BaseModel, ConfigDict, Field -from prediction_market_agent_tooling.gtypes import ( - HexBytes, -) +from prediction_market_agent_tooling.gtypes import HexBytes class SeerMarket(BaseModel): From 59bf45a5c175d8151301e8c6a243b14216641d42 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Wed, 30 Oct 2024 17:16:38 -0300 Subject: [PATCH 04/11] Added missing file --- .../markets/seer/seer_subgraph_handler.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py new file mode 100644 index 00000000..2d40e533 --- /dev/null +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -0,0 +1,96 @@ +from subgrounds import FieldPath +from web3.constants import ADDRESS_ZERO + +from prediction_market_agent_tooling.markets.base_subgraph_handler import ( + BaseSubgraphHandler, +) +from prediction_market_agent_tooling.markets.seer.data_models import ( + SeerMarket, + SeerPool, +) +from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes + +BINARY_MARKETS_FILTER = {"parentMarket": ADDRESS_ZERO.lower()} + + +class SeerSubgraphHandler(BaseSubgraphHandler): + """ + Class responsible for handling interactions with Seer subgraphs. + """ + + SEER_SUBGRAPH = "https://gateway-arbitrum.network.thegraph.com/api/{graph_api_key}/subgraphs/id/B4vyRqJaSHD8dRDb3BFRoAzuBK18c1QQcXq94JbxDxWH" + + SWAPR_ALGEBRA_SUBGRAPH = "https://gateway-arbitrum.network.thegraph.com/api/{graph_api_key}/subgraphs/id/AAA1vYjxwFHzbt6qKwLHNcDSASyr1J1xVViDH8gTMFMR" + + INVALID_ANSWER = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + + def __init__(self) -> None: + super().__init__() + + self.seer_subgraph = self.sg.load_subgraph( + self.SEER_SUBGRAPH.format( + graph_api_key=self.keys.graph_api_key.get_secret_value() + ) + ) + self.swapr_algebra_subgraph = self.sg.load_subgraph( + self.SWAPR_ALGEBRA_SUBGRAPH.format( + graph_api_key=self.keys.graph_api_key.get_secret_value() + ) + ) + + def _get_fields_for_markets(self, markets_field: FieldPath) -> list[FieldPath]: + fields = [ + markets_field.id, + markets_field.factory, + markets_field.creator, + markets_field.marketName, + markets_field.outcomes, + markets_field.parentMarket, + markets_field.finalizeTs, + markets_field.wrappedTokens, + ] + return fields + + def get_binary_markets(self) -> list[SeerMarket]: + markets_field = self.seer_subgraph.Query.markets(where=BINARY_MARKETS_FILTER) + fields = self._get_fields_for_markets(markets_field) + markets = self.do_query(fields=fields, pydantic_model=SeerMarket) + return markets + + def get_market_by_id(self, market_id: HexBytes) -> SeerMarket: + markets_field = self.seer_subgraph.Query.market(id=market_id.hex().lower()) + fields = self._get_fields_for_markets(markets_field) + markets = self.do_query(fields=fields, pydantic_model=SeerMarket) + if len(markets) != 1: + raise ValueError( + f"Fetched wrong number of markets. Expected 1 but got {len(markets)}" + ) + return markets[0] + + def _get_fields_for_pools(self, pools_field: FieldPath) -> list[FieldPath]: + fields = [ + pools_field.id, + pools_field.liquidity, + pools_field.token0.id, + pools_field.token0.name, + pools_field.token0.symbol, + pools_field.token1.id, + pools_field.token1.name, + pools_field.token1.symbol, + ] + return fields + + def get_pools_for_market(self, market: SeerMarket) -> list[SeerPool]: + # We iterate through the wrapped tokens and put them in a where clause so that we hit the subgraph endpoint just once. + wheres = [] + for wrapped_token in market.wrapped_tokens: + wheres.extend( + [ + {"token0": wrapped_token.hex().lower()}, + {"token1": wrapped_token.hex().lower()}, + ] + ) + pools_field = self.swapr_algebra_subgraph.Query.pools(where={"or": wheres}) + fields = self._get_fields_for_pools(pools_field) + pools = self.do_query(fields=fields, pydantic_model=SeerPool) + return pools From 43db0388e5129dc529faf2c21b0259746d422d2f Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 12:12:25 -0300 Subject: [PATCH 05/11] Added method for retrieving seer binary markets more precisely --- .../markets/base_subgraph_handler.py | 3 -- .../markets/seer/seer_subgraph_handler.py | 50 +++++++++++++++++-- .../seer/test_seer_subgraph_handler.py | 24 +++++++-- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/prediction_market_agent_tooling/markets/base_subgraph_handler.py b/prediction_market_agent_tooling/markets/base_subgraph_handler.py index d171740d..0fc93a6c 100644 --- a/prediction_market_agent_tooling/markets/base_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/base_subgraph_handler.py @@ -12,9 +12,6 @@ class BaseSubgraphHandler(metaclass=SingletonMeta): - sg: Subgrounds - keys: APIKeys - def __init__(self) -> None: self.sg = Subgrounds() # Patch methods to retry on failure. diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index 2d40e533..a1d18537 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -1,3 +1,5 @@ +from typing import Any + from subgrounds import FieldPath from web3.constants import ADDRESS_ZERO @@ -10,7 +12,7 @@ ) from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes -BINARY_MARKETS_FILTER = {"parentMarket": ADDRESS_ZERO.lower()} +INVALID_OUTCOME = "Invalid result" class SeerSubgraphHandler(BaseSubgraphHandler): @@ -51,11 +53,51 @@ def _get_fields_for_markets(self, markets_field: FieldPath) -> list[FieldPath]: ] return fields - def get_binary_markets(self) -> list[SeerMarket]: - markets_field = self.seer_subgraph.Query.markets(where=BINARY_MARKETS_FILTER) + @staticmethod + def filter_bicategorical_markets(markets: list[SeerMarket]) -> list[SeerMarket]: + # We do an extra check for the invalid outcome for safety. + return [ + m for m in markets if len(m.outcomes) == 3 and INVALID_OUTCOME in m.outcomes + ] + + @staticmethod + def filter_binary_markets(markets: list[SeerMarket]) -> list[SeerMarket]: + return [ + market + for market in markets + if {"yes", "no"}.issubset({o.lower() for o in market.outcomes}) + ] + + @staticmethod + def build_filter_for_conditional_markets( + include_conditional_markets: bool = True, + ) -> dict[Any, Any]: + return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO} + + def get_bicategorical_markets( + self, include_conditional_markets: bool = True + ) -> list[SeerMarket]: + """Returns markets that contain 2 categories plus an invalid outcome.""" + # Binary markets on Seer contain 3 outcomes: OutcomeA, outcomeB and an Invalid option. + query_filter = self.build_filter_for_conditional_markets( + include_conditional_markets + ) + query_filter["outcomes_contains"] = INVALID_OUTCOME + markets_field = self.seer_subgraph.Query.markets(where=query_filter) fields = self._get_fields_for_markets(markets_field) markets = self.do_query(fields=fields, pydantic_model=SeerMarket) - return markets + two_category_markets = self.filter_bicategorical_markets(markets) + return two_category_markets + + def get_binary_markets( + self, include_conditional_markets: bool = True + ) -> list[SeerMarket]: + two_category_markets = self.get_bicategorical_markets( + include_conditional_markets=include_conditional_markets + ) + # Now we additionally filter markets based on YES/NO being the only outcomes. + binary_markets = self.filter_binary_markets(two_category_markets) + return binary_markets def get_market_by_id(self, market_id: HexBytes) -> SeerMarket: markets_field = self.seer_subgraph.Query.market(id=market_id.hex().lower()) diff --git a/tests_integration/markets/seer/test_seer_subgraph_handler.py b/tests_integration/markets/seer/test_seer_subgraph_handler.py index e21822fe..0ca3aa69 100644 --- a/tests_integration/markets/seer/test_seer_subgraph_handler.py +++ b/tests_integration/markets/seer/test_seer_subgraph_handler.py @@ -7,6 +7,10 @@ ) from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes +CONDITIONAL_MARKET_ID = HexBytes("0xe12f48ecdd6e64d95d1d8f1d5d7aa37e14f2888b") +BINARY_MARKET_ID = HexBytes("0x7d72aa56ecdda207005fd7a02dbfd33f92d0def7") +BINARY_CONDITIONAL_MARKET_ID = HexBytes("0xbc82402814f7db8736980c0debb01df6aad8846e") + @pytest.fixture(scope="module") def handler() -> t.Generator[SeerSubgraphHandler, None, None]: @@ -14,7 +18,7 @@ def handler() -> t.Generator[SeerSubgraphHandler, None, None]: def test_get_all_seer_markets(handler: SeerSubgraphHandler) -> None: - markets = handler.get_binary_markets() + markets = handler.get_bicategorical_markets() assert len(markets) > 1 @@ -26,10 +30,22 @@ def test_get_seer_market_by_id(handler: SeerSubgraphHandler) -> None: def test_conditional_market_not_retrieved(handler: SeerSubgraphHandler) -> None: - conditional_market_id = HexBytes("0xe12f48ecdd6e64d95d1d8f1d5d7aa37e14f2888b") - markets = handler.get_binary_markets() + markets = handler.get_bicategorical_markets(include_conditional_markets=False) + market_ids = [m.id for m in markets] + assert CONDITIONAL_MARKET_ID not in market_ids + + +def test_conditional_market__retrieved(handler: SeerSubgraphHandler) -> None: + markets = handler.get_bicategorical_markets(include_conditional_markets=True) + market_ids = [m.id for m in markets] + assert CONDITIONAL_MARKET_ID not in market_ids + + +def test_binary_market_retrieved(handler: SeerSubgraphHandler) -> None: + markets = handler.get_binary_markets(include_conditional_markets=True) market_ids = [m.id for m in markets] - assert conditional_market_id not in market_ids + assert BINARY_MARKET_ID in market_ids + assert BINARY_CONDITIONAL_MARKET_ID in market_ids def test_get_pools_for_market(handler: SeerSubgraphHandler) -> None: From 496c159247e5d8f60254159deb082f336449494d Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 13:39:28 -0300 Subject: [PATCH 06/11] Fixing filter --- .idea/.gitignore | 3 +++ .idea/inspectionProfiles/Project_Default.xml | 6 ++++++ .idea/inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 8 ++++++++ .idea/modules.xml | 8 ++++++++ .idea/prediction-market-agent-tooling.iml | 15 +++++++++++++++ .idea/vcs.xml | 6 ++++++ .python-version | 1 + .../markets/seer/seer_subgraph_handler.py | 6 +++++- run_all.sh | 1 + scripts/or_query.py | 8 ++++++++ 11 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/prediction-market-agent-tooling.iml create mode 100644 .idea/vcs.xml create mode 100644 .python-version create mode 100644 run_all.sh create mode 100644 scripts/or_query.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..65ac2db7 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..105ce2da --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..a3c91fde --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..e1057446 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/prediction-market-agent-tooling.iml b/.idea/prediction-market-agent-tooling.iml new file mode 100644 index 00000000..ccb73e22 --- /dev/null +++ b/.idea/prediction-market-agent-tooling.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..30291cba --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10.0 diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index a1d18537..99b52535 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -72,7 +72,11 @@ def filter_binary_markets(markets: list[SeerMarket]) -> list[SeerMarket]: def build_filter_for_conditional_markets( include_conditional_markets: bool = True, ) -> dict[Any, Any]: - return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO} + return ( + {} + if include_conditional_markets + else {"parentMarket": ADDRESS_ZERO.lower()} + ) def get_bicategorical_markets( self, include_conditional_markets: bool = True diff --git a/run_all.sh b/run_all.sh new file mode 100644 index 00000000..e8340d29 --- /dev/null +++ b/run_all.sh @@ -0,0 +1 @@ +poetry run black --check . & poetry run autoflake --in-place --remove-all-unused-imports --remove-unused-variables --recursive . & git diff --exit-code --quiet || exit 1 & poetry run isort black . & git diff --exit-code --quiet || exit 1 diff --git a/scripts/or_query.py b/scripts/or_query.py new file mode 100644 index 00000000..070b91cd --- /dev/null +++ b/scripts/or_query.py @@ -0,0 +1,8 @@ +from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import ( + OmenSubgraphHandler, +) + +if __name__ == "__main__": + sh = OmenSubgraphHandler() + q = sh.get_questions(claimed=True, limit=2) + print(q) From 26a1c3e69b3a02cfde4fc400c9521bf33dff6101 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 13:39:52 -0300 Subject: [PATCH 07/11] Revert "Fixing filter" This reverts commit 496c159247e5d8f60254159deb082f336449494d. --- .idea/.gitignore | 3 --- .idea/inspectionProfiles/Project_Default.xml | 6 ------ .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 8 -------- .idea/modules.xml | 8 -------- .idea/prediction-market-agent-tooling.iml | 15 --------------- .idea/vcs.xml | 6 ------ .python-version | 1 - .../markets/seer/seer_subgraph_handler.py | 6 +----- run_all.sh | 1 - scripts/or_query.py | 8 -------- 11 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/prediction-market-agent-tooling.iml delete mode 100644 .idea/vcs.xml delete mode 100644 .python-version delete mode 100644 run_all.sh delete mode 100644 scripts/or_query.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 65ac2db7..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da..00000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index a3c91fde..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index e1057446..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/prediction-market-agent-tooling.iml b/.idea/prediction-market-agent-tooling.iml deleted file mode 100644 index ccb73e22..00000000 --- a/.idea/prediction-market-agent-tooling.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.python-version b/.python-version deleted file mode 100644 index 30291cba..00000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.10.0 diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index 99b52535..a1d18537 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -72,11 +72,7 @@ def filter_binary_markets(markets: list[SeerMarket]) -> list[SeerMarket]: def build_filter_for_conditional_markets( include_conditional_markets: bool = True, ) -> dict[Any, Any]: - return ( - {} - if include_conditional_markets - else {"parentMarket": ADDRESS_ZERO.lower()} - ) + return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO} def get_bicategorical_markets( self, include_conditional_markets: bool = True diff --git a/run_all.sh b/run_all.sh deleted file mode 100644 index e8340d29..00000000 --- a/run_all.sh +++ /dev/null @@ -1 +0,0 @@ -poetry run black --check . & poetry run autoflake --in-place --remove-all-unused-imports --remove-unused-variables --recursive . & git diff --exit-code --quiet || exit 1 & poetry run isort black . & git diff --exit-code --quiet || exit 1 diff --git a/scripts/or_query.py b/scripts/or_query.py deleted file mode 100644 index 070b91cd..00000000 --- a/scripts/or_query.py +++ /dev/null @@ -1,8 +0,0 @@ -from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import ( - OmenSubgraphHandler, -) - -if __name__ == "__main__": - sh = OmenSubgraphHandler() - q = sh.get_questions(claimed=True, limit=2) - print(q) From 0562232e6b43cc0309d7ac2e6d74f5674d47f4c4 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 13:40:41 -0300 Subject: [PATCH 08/11] Fixing filter (2) --- .../markets/seer/seer_subgraph_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index a1d18537..93348398 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -72,7 +72,7 @@ def filter_binary_markets(markets: list[SeerMarket]) -> list[SeerMarket]: def build_filter_for_conditional_markets( include_conditional_markets: bool = True, ) -> dict[Any, Any]: - return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO} + return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO.lower()} def get_bicategorical_markets( self, include_conditional_markets: bool = True From 05ad44e626fb897e383e2a291b4d534913cf5c15 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 13:43:14 -0300 Subject: [PATCH 09/11] Fixed outcome filter --- .../markets/seer/seer_subgraph_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index 93348398..e91e8c87 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -82,7 +82,7 @@ def get_bicategorical_markets( query_filter = self.build_filter_for_conditional_markets( include_conditional_markets ) - query_filter["outcomes_contains"] = INVALID_OUTCOME + query_filter["outcomes_contains"] = [INVALID_OUTCOME] markets_field = self.seer_subgraph.Query.markets(where=query_filter) fields = self._get_fields_for_markets(markets_field) markets = self.do_query(fields=fields, pydantic_model=SeerMarket) From 546c840a701e16de7f35f0794c7345cd29b4ffe1 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 16:08:21 -0300 Subject: [PATCH 10/11] Fixed test --- tests_integration/markets/seer/test_seer_subgraph_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_integration/markets/seer/test_seer_subgraph_handler.py b/tests_integration/markets/seer/test_seer_subgraph_handler.py index 0ca3aa69..a4c30fb2 100644 --- a/tests_integration/markets/seer/test_seer_subgraph_handler.py +++ b/tests_integration/markets/seer/test_seer_subgraph_handler.py @@ -35,10 +35,10 @@ def test_conditional_market_not_retrieved(handler: SeerSubgraphHandler) -> None: assert CONDITIONAL_MARKET_ID not in market_ids -def test_conditional_market__retrieved(handler: SeerSubgraphHandler) -> None: +def test_conditional_market_retrieved(handler: SeerSubgraphHandler) -> None: markets = handler.get_bicategorical_markets(include_conditional_markets=True) market_ids = [m.id for m in markets] - assert CONDITIONAL_MARKET_ID not in market_ids + assert CONDITIONAL_MARKET_ID in market_ids def test_binary_market_retrieved(handler: SeerSubgraphHandler) -> None: From 2d903d4c39484bf7d11840e77069b429f5132ba4 Mon Sep 17 00:00:00 2001 From: gabrielfior Date: Thu, 31 Oct 2024 16:39:27 -0300 Subject: [PATCH 11/11] Fixed CI --- .../markets/seer/seer_subgraph_handler.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py index e91e8c87..69845fbe 100644 --- a/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +++ b/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py @@ -72,7 +72,11 @@ def filter_binary_markets(markets: list[SeerMarket]) -> list[SeerMarket]: def build_filter_for_conditional_markets( include_conditional_markets: bool = True, ) -> dict[Any, Any]: - return {} if include_conditional_markets else {"parentMarket": ADDRESS_ZERO.lower()} + return ( + {} + if include_conditional_markets + else {"parentMarket": ADDRESS_ZERO.lower()} + ) def get_bicategorical_markets( self, include_conditional_markets: bool = True