prediction-market-agent-tooling 0.69.11.dev1122__py3-none-any.whl → 0.69.17.dev1149__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/processor.abi.json +16 -0
- prediction_market_agent_tooling/gtypes.py +1 -1
- prediction_market_agent_tooling/tools/_generic_value.py +7 -1
- prediction_market_agent_tooling/tools/caches/db_cache.py +14 -14
- prediction_market_agent_tooling/tools/caches/serializers.py +4 -1
- prediction_market_agent_tooling/tools/contract.py +108 -3
- prediction_market_agent_tooling/tools/cow/models.py +5 -2
- prediction_market_agent_tooling/tools/db/db_manager.py +59 -0
- prediction_market_agent_tooling/tools/web3_utils.py +10 -2
- {prediction_market_agent_tooling-0.69.11.dev1122.dist-info → prediction_market_agent_tooling-0.69.17.dev1149.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.69.11.dev1122.dist-info → prediction_market_agent_tooling-0.69.17.dev1149.dist-info}/RECORD +14 -13
- {prediction_market_agent_tooling-0.69.11.dev1122.dist-info → prediction_market_agent_tooling-0.69.17.dev1149.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.69.11.dev1122.dist-info → prediction_market_agent_tooling-0.69.17.dev1149.dist-info}/entry_points.txt +0 -0
- {prediction_market_agent_tooling-0.69.11.dev1122.dist-info → prediction_market_agent_tooling-0.69.17.dev1149.dist-info}/licenses/LICENSE +0 -0
|
@@ -33,7 +33,7 @@ VerifiedChecksumAddress: TypeAlias = Annotated[
|
|
|
33
33
|
]
|
|
34
34
|
VerifiedChecksumAddressOrNone: TypeAlias = Annotated[
|
|
35
35
|
ChecksumAddress | None,
|
|
36
|
-
BeforeValidator(lambda x: Web3.to_checksum_address(x) if x
|
|
36
|
+
BeforeValidator(lambda x: Web3.to_checksum_address(x) if x else None),
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
|
|
@@ -60,6 +60,10 @@ class _GenericValue(
|
|
|
60
60
|
cls.parser = parser
|
|
61
61
|
|
|
62
62
|
def __init__(self, value: InputValueType) -> None:
|
|
63
|
+
if isinstance(value, str) and (
|
|
64
|
+
value.startswith("0x") or value.startswith("-0x")
|
|
65
|
+
):
|
|
66
|
+
value = int(value, 16) # type: ignore[assignment] # mypy is confused but if `parser` below can process it, it should be fine, and if it cannot, it should be catched by mypy earlier than here.
|
|
63
67
|
self.value: InternalValueType = self.parser(value)
|
|
64
68
|
super().__init__({"value": self.value, "type": self.__class__.__name__})
|
|
65
69
|
|
|
@@ -187,9 +191,11 @@ class _GenericValue(
|
|
|
187
191
|
raise TypeError("Cannot compare different types")
|
|
188
192
|
return bool(self.value >= other.value)
|
|
189
193
|
|
|
190
|
-
def __eq__(self: GenericValueType, other: GenericValueType | t.Literal[0]) -> bool: # type: ignore
|
|
194
|
+
def __eq__(self: GenericValueType, other: GenericValueType | t.Literal[0] | None) -> bool: # type: ignore
|
|
191
195
|
if other == 0:
|
|
192
196
|
other = self.zero()
|
|
197
|
+
if other is None:
|
|
198
|
+
return False
|
|
193
199
|
if not isinstance(other, _GenericValue):
|
|
194
200
|
raise TypeError("Cannot compare different types")
|
|
195
201
|
if type(self) is not type(other):
|
|
@@ -28,7 +28,10 @@ from sqlmodel import Field, SQLModel, desc, select
|
|
|
28
28
|
from prediction_market_agent_tooling.config import APIKeys
|
|
29
29
|
from prediction_market_agent_tooling.loggers import logger
|
|
30
30
|
from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
|
|
31
|
-
from prediction_market_agent_tooling.tools.db.db_manager import
|
|
31
|
+
from prediction_market_agent_tooling.tools.db.db_manager import (
|
|
32
|
+
DBManager,
|
|
33
|
+
EnsureTableManager,
|
|
34
|
+
)
|
|
32
35
|
from prediction_market_agent_tooling.tools.utils import utcnow
|
|
33
36
|
|
|
34
37
|
DB_CACHE_LOG_PREFIX = "[db-cache]"
|
|
@@ -49,6 +52,10 @@ class FunctionCache(SQLModel, table=True):
|
|
|
49
52
|
created_at: DatetimeUTC = Field(default_factory=utcnow, index=True)
|
|
50
53
|
|
|
51
54
|
|
|
55
|
+
# Global instance of the table manager for FunctionCache
|
|
56
|
+
_table_manager = EnsureTableManager([FunctionCache])
|
|
57
|
+
|
|
58
|
+
|
|
52
59
|
@overload
|
|
53
60
|
def db_cache(
|
|
54
61
|
func: None = None,
|
|
@@ -113,10 +120,8 @@ def db_cache(
|
|
|
113
120
|
if not api_keys.ENABLE_CACHE:
|
|
114
121
|
return await func(*args, **kwargs)
|
|
115
122
|
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
# Ensure tables in thread pool
|
|
119
|
-
await asyncio.to_thread(_ensure_tables, api_keys)
|
|
123
|
+
# Ensure tables are created before accessing cache
|
|
124
|
+
await _table_manager.ensure_tables_async(api_keys)
|
|
120
125
|
|
|
121
126
|
ctx = _build_context(func, args, kwargs, ignore_args, ignore_arg_types)
|
|
122
127
|
|
|
@@ -155,7 +160,8 @@ def db_cache(
|
|
|
155
160
|
if not api_keys.ENABLE_CACHE:
|
|
156
161
|
return func(*args, **kwargs)
|
|
157
162
|
|
|
158
|
-
|
|
163
|
+
# Ensure tables are created before accessing cache
|
|
164
|
+
_table_manager.ensure_tables_sync(api_keys)
|
|
159
165
|
|
|
160
166
|
ctx = _build_context(func, args, kwargs, ignore_args, ignore_arg_types)
|
|
161
167
|
lookup = _fetch_cached(api_keys, ctx, max_age)
|
|
@@ -200,12 +206,6 @@ class CacheLookup:
|
|
|
200
206
|
value: Any | None = None
|
|
201
207
|
|
|
202
208
|
|
|
203
|
-
def _ensure_tables(api_keys: APIKeys) -> None:
|
|
204
|
-
DBManager(api_keys.sqlalchemy_db_url.get_secret_value()).create_tables(
|
|
205
|
-
[FunctionCache]
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
|
|
209
209
|
def _build_context(
|
|
210
210
|
func: Callable[..., Any],
|
|
211
211
|
args: tuple[Any, ...],
|
|
@@ -363,8 +363,8 @@ def convert_cached_output_to_pydantic(return_type: Any, data: Any) -> Any:
|
|
|
363
363
|
if origin is None:
|
|
364
364
|
if inspect.isclass(return_type) and issubclass(return_type, BaseModel):
|
|
365
365
|
# Convert the dictionary to a Pydantic model
|
|
366
|
-
return return_type(
|
|
367
|
-
|
|
366
|
+
return return_type.model_validate(
|
|
367
|
+
{
|
|
368
368
|
k: convert_cached_output_to_pydantic(
|
|
369
369
|
getattr(return_type, k, None), v
|
|
370
370
|
)
|
|
@@ -29,7 +29,10 @@ def json_serializer_default_fn(
|
|
|
29
29
|
elif isinstance(y, HexBytes):
|
|
30
30
|
return f"HexBytes::{y.to_0x_hex()}"
|
|
31
31
|
elif isinstance(y, BaseModel):
|
|
32
|
-
|
|
32
|
+
# For some reason, Pydantic by default serializes using the field names (not alias),
|
|
33
|
+
# but also by default, deserializes only using the aliased names.
|
|
34
|
+
# `by_alias=True` here to work by default with models that have some fields with aliased names.
|
|
35
|
+
return y.model_dump(by_alias=True)
|
|
33
36
|
raise TypeError(
|
|
34
37
|
f"Unsupported type for the default json serialize function, value is {y}."
|
|
35
38
|
)
|
|
@@ -5,11 +5,14 @@ import typing as t
|
|
|
5
5
|
from contextlib import contextmanager
|
|
6
6
|
|
|
7
7
|
import eth_abi
|
|
8
|
+
import tenacity
|
|
8
9
|
from eth_abi.exceptions import DecodingError
|
|
9
10
|
from pydantic import BaseModel, field_validator
|
|
10
11
|
from web3 import Web3
|
|
11
12
|
from web3.constants import CHECKSUM_ADDRESSS_ZERO, HASH_ZERO
|
|
12
13
|
from web3.contract.contract import Contract as Web3Contract
|
|
14
|
+
from web3.exceptions import ContractCustomError, ContractLogicError
|
|
15
|
+
from web3.types import BlockIdentifier
|
|
13
16
|
|
|
14
17
|
from prediction_market_agent_tooling.chains import POLYGON_CHAIN_ID
|
|
15
18
|
from prediction_market_agent_tooling.config import APIKeys, RPCConfig
|
|
@@ -95,6 +98,7 @@ class ContractBaseClass(BaseModel):
|
|
|
95
98
|
function_name: str,
|
|
96
99
|
function_params: t.Optional[list[t.Any] | dict[str, t.Any]] = None,
|
|
97
100
|
web3: Web3 | None = None,
|
|
101
|
+
block_identifier: BlockIdentifier | None = None,
|
|
98
102
|
) -> t.Any:
|
|
99
103
|
"""
|
|
100
104
|
Used for reading from the contract.
|
|
@@ -106,6 +110,7 @@ class ContractBaseClass(BaseModel):
|
|
|
106
110
|
contract_abi=self.abi,
|
|
107
111
|
function_name=function_name,
|
|
108
112
|
function_params=function_params,
|
|
113
|
+
block_identifier=block_identifier,
|
|
109
114
|
)
|
|
110
115
|
|
|
111
116
|
def send(
|
|
@@ -194,6 +199,22 @@ class ContractProxyBaseClass(ContractBaseClass):
|
|
|
194
199
|
return Web3.to_checksum_address(address)
|
|
195
200
|
|
|
196
201
|
|
|
202
|
+
class ContractProcessorBaseClass(ContractBaseClass):
|
|
203
|
+
"""
|
|
204
|
+
Contract base class for processor contracts.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
abi: ABI = abi_field_validator(
|
|
208
|
+
os.path.join(
|
|
209
|
+
os.path.dirname(os.path.realpath(__file__)), "../abis/processor.abi.json"
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
def processor(self, web3: Web3 | None = None) -> ChecksumAddress:
|
|
214
|
+
address = self.call("processor", web3=web3)
|
|
215
|
+
return Web3.to_checksum_address(address)
|
|
216
|
+
|
|
217
|
+
|
|
197
218
|
class ContractERC20BaseClass(ContractBaseClass):
|
|
198
219
|
"""
|
|
199
220
|
Contract base class extended by ERC-20 standard methods.
|
|
@@ -205,10 +226,18 @@ class ContractERC20BaseClass(ContractBaseClass):
|
|
|
205
226
|
)
|
|
206
227
|
)
|
|
207
228
|
|
|
229
|
+
def name(self, web3: Web3 | None = None) -> str:
|
|
230
|
+
name: str = self.call("name", web3=web3)
|
|
231
|
+
return name
|
|
232
|
+
|
|
208
233
|
def symbol(self, web3: Web3 | None = None) -> str:
|
|
209
234
|
symbol: str = self.call("symbol", web3=web3)
|
|
210
235
|
return symbol
|
|
211
236
|
|
|
237
|
+
def decimals(self, web3: Web3 | None = None) -> int:
|
|
238
|
+
decimals = int(self.call("decimals", web3=web3))
|
|
239
|
+
return decimals
|
|
240
|
+
|
|
212
241
|
def symbol_cached(self, web3: Web3 | None = None) -> str:
|
|
213
242
|
web3 = web3 or self.get_web3()
|
|
214
243
|
cache_key = create_contract_method_cache_key(self.symbol, web3)
|
|
@@ -264,8 +293,17 @@ class ContractERC20BaseClass(ContractBaseClass):
|
|
|
264
293
|
web3=web3,
|
|
265
294
|
)
|
|
266
295
|
|
|
267
|
-
def balanceOf(
|
|
268
|
-
|
|
296
|
+
def balanceOf(
|
|
297
|
+
self,
|
|
298
|
+
for_address: ChecksumAddress,
|
|
299
|
+
web3: Web3 | None = None,
|
|
300
|
+
block_identifier: BlockIdentifier | None = None,
|
|
301
|
+
) -> Wei:
|
|
302
|
+
balance = Wei(
|
|
303
|
+
self.call(
|
|
304
|
+
"balanceOf", [for_address], web3=web3, block_identifier=block_identifier
|
|
305
|
+
)
|
|
306
|
+
)
|
|
269
307
|
return balance
|
|
270
308
|
|
|
271
309
|
def balance_of_in_tokens(
|
|
@@ -938,8 +976,11 @@ def uni_implementation_address(
|
|
|
938
976
|
# TODO: Fix the above, and afterwards assert that only 1 imp address is returned from this function. Or prove that this could indeed happen (although we are very pretty sure it shouldn't).
|
|
939
977
|
addresses = [
|
|
940
978
|
implementation_proxy_address(contract_address, web3),
|
|
979
|
+
processor_proxy_address(contract_address, web3),
|
|
941
980
|
minimal_proxy_address(contract_address, web3),
|
|
942
981
|
seer_minimal_proxy_address(contract_address, web3),
|
|
982
|
+
eip_1967_proxy_address(contract_address, web3),
|
|
983
|
+
zeppelinos_unstructured_storage_proxy_address(contract_address, web3),
|
|
943
984
|
]
|
|
944
985
|
return [addr for addr in addresses if addr is not None]
|
|
945
986
|
|
|
@@ -951,7 +992,43 @@ def implementation_proxy_address(
|
|
|
951
992
|
contract_address, "implementation", web3, look_for_proxy_contract=False
|
|
952
993
|
):
|
|
953
994
|
return None
|
|
954
|
-
|
|
995
|
+
try:
|
|
996
|
+
return ContractProxyOnGnosisChain(address=contract_address).implementation(web3)
|
|
997
|
+
except (ContractCustomError, ContractLogicError, tenacity.RetryError) as e:
|
|
998
|
+
if isinstance(e, tenacity.RetryError) and not isinstance(
|
|
999
|
+
e.last_attempt.exception(), (ContractCustomError, ContractLogicError)
|
|
1000
|
+
):
|
|
1001
|
+
raise
|
|
1002
|
+
|
|
1003
|
+
# For example https://gnosisscan.io/address/0x3221a28ed2b2e955da64d1d299956f277562c95c#code,
|
|
1004
|
+
# it has the implementation method, but it's only for admins.
|
|
1005
|
+
logger.warning(
|
|
1006
|
+
f"Failed to get implementation for {contract_address=} even though it has the method: {e}"
|
|
1007
|
+
)
|
|
1008
|
+
return None
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
def processor_proxy_address(
|
|
1012
|
+
contract_address: ChecksumAddress, web3: Web3
|
|
1013
|
+
) -> ChecksumAddress | None:
|
|
1014
|
+
if not contract_implements_function(
|
|
1015
|
+
contract_address, "processor", web3, look_for_proxy_contract=False
|
|
1016
|
+
):
|
|
1017
|
+
return None
|
|
1018
|
+
try:
|
|
1019
|
+
return ContractProcessorBaseClass(address=contract_address).processor(web3)
|
|
1020
|
+
except (ContractCustomError, ContractLogicError, tenacity.RetryError) as e:
|
|
1021
|
+
if isinstance(e, tenacity.RetryError) and not isinstance(
|
|
1022
|
+
e.last_attempt.exception(), (ContractCustomError, ContractLogicError)
|
|
1023
|
+
):
|
|
1024
|
+
raise
|
|
1025
|
+
|
|
1026
|
+
# For example https://gnosisscan.io/address/0x3221a28ed2b2e955da64d1d299956f277562c95c#code,
|
|
1027
|
+
# it has the processor method, but it's only for admins.
|
|
1028
|
+
logger.warning(
|
|
1029
|
+
f"Failed to get processor for {contract_address=} even though it has the method: {e}"
|
|
1030
|
+
)
|
|
1031
|
+
return None
|
|
955
1032
|
|
|
956
1033
|
|
|
957
1034
|
def minimal_proxy_address(
|
|
@@ -982,6 +1059,34 @@ def seer_minimal_proxy_address(
|
|
|
982
1059
|
return None
|
|
983
1060
|
|
|
984
1061
|
|
|
1062
|
+
def eip_1967_proxy_address(
|
|
1063
|
+
contract_address: ChecksumAddress, web3: Web3
|
|
1064
|
+
) -> ChecksumAddress | None:
|
|
1065
|
+
try:
|
|
1066
|
+
slot = HexBytes(Web3.keccak(text="eip1967.proxy.implementation")).as_int() - 1
|
|
1067
|
+
raw_slot = web3.eth.get_storage_at(contract_address, slot)
|
|
1068
|
+
address = eth_abi.decode(["address"], raw_slot)[0]
|
|
1069
|
+
return Web3.to_checksum_address(address)
|
|
1070
|
+
except DecodingError:
|
|
1071
|
+
logger.info("Error decoding contract address for eip 1967 proxy")
|
|
1072
|
+
return None
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
def zeppelinos_unstructured_storage_proxy_address(
|
|
1076
|
+
contract_address: ChecksumAddress, web3: Web3
|
|
1077
|
+
) -> ChecksumAddress | None:
|
|
1078
|
+
try:
|
|
1079
|
+
slot = HexBytes(
|
|
1080
|
+
Web3.keccak(text="org.zeppelinos.proxy.implementation")
|
|
1081
|
+
).as_int()
|
|
1082
|
+
raw_slot = web3.eth.get_storage_at(contract_address, slot)
|
|
1083
|
+
address = eth_abi.decode(["address"], raw_slot)[0]
|
|
1084
|
+
return Web3.to_checksum_address(address)
|
|
1085
|
+
except DecodingError:
|
|
1086
|
+
logger.info("Error decoding contract address for zeppelinos proxy")
|
|
1087
|
+
return None
|
|
1088
|
+
|
|
1089
|
+
|
|
985
1090
|
def init_collateral_token_contract(
|
|
986
1091
|
address: ChecksumAddress, web3: Web3 | None
|
|
987
1092
|
) -> ContractERC20BaseClass:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from typing import Optional
|
|
2
|
+
from typing import Optional, TypeAlias
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, ConfigDict
|
|
5
5
|
from sqlmodel import Field, SQLModel
|
|
@@ -74,10 +74,13 @@ class OrderStatus(str, Enum):
|
|
|
74
74
|
expired = "expired"
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
CowOrderUID: TypeAlias = HexBytes
|
|
78
|
+
|
|
79
|
+
|
|
77
80
|
class Order(BaseModel):
|
|
78
81
|
model_config = ConfigDict(validate_by_name=True, validate_by_alias=True)
|
|
79
82
|
|
|
80
|
-
uid:
|
|
83
|
+
uid: CowOrderUID
|
|
81
84
|
quoteId: int | None = None
|
|
82
85
|
validTo: int
|
|
83
86
|
sellAmount: Wei
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import hashlib
|
|
3
|
+
import threading
|
|
2
4
|
from contextlib import contextmanager
|
|
3
5
|
from typing import Generator, Sequence
|
|
4
6
|
|
|
7
|
+
from pydantic import SecretStr
|
|
5
8
|
from sqlalchemy import Connection
|
|
6
9
|
from sqlmodel import Session, SQLModel, create_engine
|
|
7
10
|
|
|
@@ -79,3 +82,59 @@ class DBManager:
|
|
|
79
82
|
if tables_to_create:
|
|
80
83
|
for table in tables_to_create:
|
|
81
84
|
self.cache_table_initialized[table.name] = True
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class EnsureTableManager:
|
|
88
|
+
"""
|
|
89
|
+
Manages database table initialization with thread-safe and async-safe locking.
|
|
90
|
+
Ensures tables are created only once per database URL.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
def __init__(self, tables: Sequence[type[SQLModel]]) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Initialize the table manager with the tables to manage.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
tables: Sequence of SQLModel table classes to ensure in the database.
|
|
99
|
+
"""
|
|
100
|
+
# Ensure tables only once, as it's a time costly operation.
|
|
101
|
+
self._tables = tables
|
|
102
|
+
self._lock_thread = threading.Lock()
|
|
103
|
+
self._lock_async = asyncio.Lock()
|
|
104
|
+
self._ensured: dict[SecretStr, bool] = {}
|
|
105
|
+
|
|
106
|
+
def is_ensured(self, db_url: SecretStr) -> bool:
|
|
107
|
+
"""Check if tables have been ensured for the given database URL."""
|
|
108
|
+
return self._ensured.get(db_url, False)
|
|
109
|
+
|
|
110
|
+
def mark_ensured(self, db_url: SecretStr) -> None:
|
|
111
|
+
"""Mark tables as ensured for the given database URL."""
|
|
112
|
+
self._ensured[db_url] = True
|
|
113
|
+
|
|
114
|
+
def ensure_tables_sync(self, api_keys: APIKeys) -> None:
|
|
115
|
+
"""
|
|
116
|
+
Ensure tables exist for the given API keys (synchronous version).
|
|
117
|
+
Thread-safe with double-checked locking pattern.
|
|
118
|
+
"""
|
|
119
|
+
if not self.is_ensured(api_keys.sqlalchemy_db_url):
|
|
120
|
+
with self._lock_thread:
|
|
121
|
+
if not self.is_ensured(api_keys.sqlalchemy_db_url):
|
|
122
|
+
self._create_tables(api_keys)
|
|
123
|
+
self.mark_ensured(api_keys.sqlalchemy_db_url)
|
|
124
|
+
|
|
125
|
+
async def ensure_tables_async(self, api_keys: APIKeys) -> None:
|
|
126
|
+
"""
|
|
127
|
+
Ensure tables exist for the given API keys (asynchronous version).
|
|
128
|
+
Async-safe with double-checked locking pattern.
|
|
129
|
+
"""
|
|
130
|
+
if not self.is_ensured(api_keys.sqlalchemy_db_url):
|
|
131
|
+
async with self._lock_async:
|
|
132
|
+
if not self.is_ensured(api_keys.sqlalchemy_db_url):
|
|
133
|
+
await asyncio.to_thread(self._create_tables, api_keys)
|
|
134
|
+
self.mark_ensured(api_keys.sqlalchemy_db_url)
|
|
135
|
+
|
|
136
|
+
def _create_tables(self, api_keys: APIKeys) -> None:
|
|
137
|
+
"""Create the database tables."""
|
|
138
|
+
DBManager(api_keys.sqlalchemy_db_url.get_secret_value()).create_tables(
|
|
139
|
+
list(self._tables)
|
|
140
|
+
)
|
|
@@ -16,7 +16,14 @@ from safe_eth.safe.safe import SafeV141
|
|
|
16
16
|
from web3 import Web3
|
|
17
17
|
from web3.constants import HASH_ZERO
|
|
18
18
|
from web3.contract.contract import ContractFunction as Web3ContractFunction
|
|
19
|
-
from web3.types import
|
|
19
|
+
from web3.types import (
|
|
20
|
+
AccessList,
|
|
21
|
+
AccessListEntry,
|
|
22
|
+
BlockIdentifier,
|
|
23
|
+
Nonce,
|
|
24
|
+
TxParams,
|
|
25
|
+
TxReceipt,
|
|
26
|
+
)
|
|
20
27
|
|
|
21
28
|
from prediction_market_agent_tooling.gtypes import (
|
|
22
29
|
ABI,
|
|
@@ -106,11 +113,12 @@ def call_function_on_contract(
|
|
|
106
113
|
contract_abi: ABI,
|
|
107
114
|
function_name: str,
|
|
108
115
|
function_params: Optional[list[Any] | dict[str, Any]] = None,
|
|
116
|
+
block_identifier: Optional[BlockIdentifier] = None,
|
|
109
117
|
) -> Any:
|
|
110
118
|
contract = web3.eth.contract(address=contract_address, abi=contract_abi)
|
|
111
119
|
output = contract.functions[function_name](
|
|
112
120
|
*parse_function_params(function_params)
|
|
113
|
-
).call()
|
|
121
|
+
).call(block_identifier=block_identifier)
|
|
114
122
|
return output
|
|
115
123
|
|
|
116
124
|
|
|
@@ -16,6 +16,7 @@ prediction_market_agent_tooling/abis/omen_realitio.abi.json,sha256=7HmFkBF_rq83U
|
|
|
16
16
|
prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json,sha256=u1-3B8FB3Ys9KVJCH-lw9ArkicdxbNMf34dV-VEGMMU,930
|
|
17
17
|
prediction_market_agent_tooling/abis/ownable.abi.json,sha256=DeTy_7VmsMhFl7jwI8MIlmjy2jORauYxrGm7wC_Alxw,1528
|
|
18
18
|
prediction_market_agent_tooling/abis/ownable_erc721.abi.json,sha256=9sxm588MAQmqCV_S0D3eYC7l9grbeALsd0Da_AHxdEI,8506
|
|
19
|
+
prediction_market_agent_tooling/abis/processor.abi.json,sha256=VGMyBblTPO3I6AoKQFMgTylgJLl6-6FquUbejICDEAw,242
|
|
19
20
|
prediction_market_agent_tooling/abis/proxy.abi.json,sha256=h24GXZ6Q0bSZlwh7zOv0EiDvbqUz_PHtWfKHTyPJ1w4,644
|
|
20
21
|
prediction_market_agent_tooling/abis/seer_gnosis_router.abi.json,sha256=DyADzOXhy9MDS31ReVrG7ibpWbw1jVy19nExZ80xfRY,6839
|
|
21
22
|
prediction_market_agent_tooling/abis/seer_market_factory.abi.json,sha256=g7RVxZVUWlTXIgTV2W6kO4twQM909Qv58zAr7Dk4XIc,13553
|
|
@@ -36,7 +37,7 @@ prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5
|
|
|
36
37
|
prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=OsPboCFGiZKsvGyntGZHwdqPlLTthITkNF5rJFvGgU8,2582
|
|
37
38
|
prediction_market_agent_tooling/deploy/gcp/utils.py,sha256=WI2ycX1X-IlTRoNoG4ggFlRwPL28kwM9VGDFD2fePLo,5699
|
|
38
39
|
prediction_market_agent_tooling/deploy/trade_interval.py,sha256=Xk9j45alQ_vrasGvsNyuW70XHIQ7wfvjoxNR3F6HYCw,1155
|
|
39
|
-
prediction_market_agent_tooling/gtypes.py,sha256=
|
|
40
|
+
prediction_market_agent_tooling/gtypes.py,sha256=Uf6nvnsZnpXCESRrEdwT3Q8h9bt19XP-jn2rt-kqGJg,6457
|
|
40
41
|
prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
42
|
prediction_market_agent_tooling/jobs/jobs_models.py,sha256=4KZ0iaKZx5zEZBBiEo9CHk0OpX3bKjoYA0wmptR0Wyk,2455
|
|
42
43
|
prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=CojpgghRs0lFEf5wl-oWhGaQozG616YD0cXdlmFO-U0,5116
|
|
@@ -84,23 +85,23 @@ prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=nme
|
|
|
84
85
|
prediction_market_agent_tooling/markets/seer/subgraph_data_models.py,sha256=96v41jdNNxBqTCp5g8SLMSrIgeeITVx5IsBjVgm-qdo,2920
|
|
85
86
|
prediction_market_agent_tooling/markets/seer/swap_pool_handler.py,sha256=24RVIppztXXFkZp0df7GR_GUSslwR42XsPJhDZ-jphs,2612
|
|
86
87
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
|
-
prediction_market_agent_tooling/tools/_generic_value.py,sha256=
|
|
88
|
+
prediction_market_agent_tooling/tools/_generic_value.py,sha256=7F-hzWkBhySEseczJZTZKTpyPHWWLENu908Ude1fGiQ,10993
|
|
88
89
|
prediction_market_agent_tooling/tools/balances.py,sha256=Osab21btfJDw2Y-jT_TV-KHGrseCRxcsYeW6WcOMB8E,1050
|
|
89
90
|
prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py,sha256=o5ba633gKiDqV4t_C2d9FWwH-HkRAOZd8FcZTYvbj6g,14451
|
|
90
91
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
|
91
92
|
prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=MpS3FOMn0C7nbmbQRUT9QwSh3UzzsgGczP91iSMr9wo,261
|
|
92
|
-
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=
|
|
93
|
+
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=NT6pOv7UXretZtebcuVQSfoN6GWxDOqBFGvD1apitQY,13840
|
|
93
94
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjqeAebu5T7ftRnlkxiL02IC-MxCfDB80x7w,1506
|
|
94
|
-
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=
|
|
95
|
-
prediction_market_agent_tooling/tools/contract.py,sha256=
|
|
95
|
+
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=pa0LpQjtv6TRBobbSgRIfh14T1CqwfzoIXdmEk4BSOA,2711
|
|
96
|
+
prediction_market_agent_tooling/tools/contract.py,sha256=XbdegY4dVdiJkNbtXLKtR2GsqGLMYbvc5lTpIIOcWLw,37785
|
|
96
97
|
prediction_market_agent_tooling/tools/contract_utils.py,sha256=9X9raICUZkPDShilt02aYzS_ILZ62u0vG5081uWLdqk,2152
|
|
97
98
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
|
98
99
|
prediction_market_agent_tooling/tools/cow/cow_order.py,sha256=DN_8cPrr4jWVpXdS4D0j1QB19nB8fxDoSheo2BFMc8M,14523
|
|
99
|
-
prediction_market_agent_tooling/tools/cow/models.py,sha256=
|
|
100
|
+
prediction_market_agent_tooling/tools/cow/models.py,sha256=t91mG-ZN-KxWt3qZbWfu0lS8iKdWoRToH3GiZ0q2YdI,3060
|
|
100
101
|
prediction_market_agent_tooling/tools/cow/semaphore.py,sha256=LPB-4wNQf7El7dgBD4Tmol6vr5j1CP9qMeDm8dcs6RI,3741
|
|
101
102
|
prediction_market_agent_tooling/tools/custom_exceptions.py,sha256=Fh8z1fbwONvP4-j7AmV_PuEcoqb6-QXa9PJ9m7guMcM,93
|
|
102
103
|
prediction_market_agent_tooling/tools/datetime_utc.py,sha256=_oO6mMc28C9aSmQfrG-S7UQy5uMHVEQqia8arnscVCk,3213
|
|
103
|
-
prediction_market_agent_tooling/tools/db/db_manager.py,sha256=
|
|
104
|
+
prediction_market_agent_tooling/tools/db/db_manager.py,sha256=dSahH8yTgGnFMfdNKKyyPlwNP5dntUpU_8vCH6JpeII,5337
|
|
104
105
|
prediction_market_agent_tooling/tools/google_utils.py,sha256=D-6FB2HRtmxaKZJ_Za-qj6VZCp5XU18rF4wLMMrqEUg,2557
|
|
105
106
|
prediction_market_agent_tooling/tools/hexbytes_custom.py,sha256=0Y1n8MChjWJmE4w6kgIJPiqbrGULui0m3TQzUBgZDHs,2206
|
|
106
107
|
prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=1mqOWC2-Ch2ibT63GAk0npsVR-4bR1T9WN9eU_SEhkE,634
|
|
@@ -136,9 +137,9 @@ prediction_market_agent_tooling/tools/tokens/token_utils.py,sha256=fhs-FH9m9IbzG
|
|
|
136
137
|
prediction_market_agent_tooling/tools/tokens/usd.py,sha256=DPO-4HBTy1-TZHKL_9CnHQ8p9W7ivPfcRlUkRO0nKJ8,3259
|
|
137
138
|
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
|
|
138
139
|
prediction_market_agent_tooling/tools/utils.py,sha256=ruq6P5TFs8CBHxeBLj1Plpx7kuNFPpDgMsJGQgDiRNs,8785
|
|
139
|
-
prediction_market_agent_tooling/tools/web3_utils.py,sha256=
|
|
140
|
-
prediction_market_agent_tooling-0.69.
|
|
141
|
-
prediction_market_agent_tooling-0.69.
|
|
142
|
-
prediction_market_agent_tooling-0.69.
|
|
143
|
-
prediction_market_agent_tooling-0.69.
|
|
144
|
-
prediction_market_agent_tooling-0.69.
|
|
140
|
+
prediction_market_agent_tooling/tools/web3_utils.py,sha256=1G8uu33p4zNhGKSiyyueROtMau4YoMR3N1QDRFQ3TjE,14098
|
|
141
|
+
prediction_market_agent_tooling-0.69.17.dev1149.dist-info/METADATA,sha256=AFE3Z25DPyWW_T5sgdAwS13pNY02p1BzPtmm9kTSogQ,8899
|
|
142
|
+
prediction_market_agent_tooling-0.69.17.dev1149.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
143
|
+
prediction_market_agent_tooling-0.69.17.dev1149.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
|
144
|
+
prediction_market_agent_tooling-0.69.17.dev1149.dist-info/licenses/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
|
145
|
+
prediction_market_agent_tooling-0.69.17.dev1149.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|