olas-operate-middleware 0.13.2__py3-none-any.whl → 0.13.4__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.
- {olas_operate_middleware-0.13.2.dist-info → olas_operate_middleware-0.13.4.dist-info}/METADATA +8 -27
- {olas_operate_middleware-0.13.2.dist-info → olas_operate_middleware-0.13.4.dist-info}/RECORD +40 -40
- operate/bridge/providers/provider.py +23 -31
- operate/cli.py +4 -17
- operate/constants.py +1 -0
- operate/data/contracts/dual_staking_token/contract.py +3 -3
- operate/data/contracts/dual_staking_token/contract.yaml +2 -2
- operate/data/contracts/foreign_omnibridge/contract.yaml +1 -1
- operate/data/contracts/home_omnibridge/contract.py +2 -2
- operate/data/contracts/home_omnibridge/contract.yaml +2 -2
- operate/data/contracts/l1_standard_bridge/contract.yaml +1 -1
- operate/data/contracts/l2_standard_bridge/contract.py +4 -4
- operate/data/contracts/l2_standard_bridge/contract.yaml +2 -2
- operate/data/contracts/mech_activity/contract.yaml +1 -1
- operate/data/contracts/optimism_mintable_erc20/contract.yaml +1 -1
- operate/data/contracts/recovery_module/contract.yaml +1 -1
- operate/data/contracts/requester_activity_checker/contract.yaml +1 -1
- operate/data/contracts/staking_token/contract.py +3 -3
- operate/data/contracts/staking_token/contract.yaml +2 -2
- operate/data/contracts/uniswap_v2_erc20/contract.yaml +3 -3
- operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +5 -5
- operate/keys.py +5 -3
- operate/ledger/__init__.py +1 -7
- operate/ledger/profiles.py +0 -1
- operate/operate_http/__init__.py +0 -2
- operate/operate_types.py +3 -93
- operate/quickstart/run_service.py +63 -6
- operate/quickstart/utils.py +8 -4
- operate/resource.py +2 -2
- operate/services/agent_runner.py +3 -3
- operate/services/manage.py +14 -17
- operate/services/protocol.py +124 -169
- operate/services/utils/mech.py +3 -3
- operate/services/utils/tendermint.py +5 -3
- operate/utils/gnosis.py +76 -101
- operate/wallet/master.py +42 -47
- operate/wallet/wallet_recovery_manager.py +8 -6
- {olas_operate_middleware-0.13.2.dist-info → olas_operate_middleware-0.13.4.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.13.2.dist-info → olas_operate_middleware-0.13.4.dist-info}/entry_points.txt +0 -0
- {olas_operate_middleware-0.13.2.dist-info → olas_operate_middleware-0.13.4.dist-info}/licenses/LICENSE +0 -0
operate/keys.py
CHANGED
|
@@ -144,9 +144,11 @@ class KeysManager:
|
|
|
144
144
|
key = Key(
|
|
145
145
|
ledger=LedgerType.ETHEREUM,
|
|
146
146
|
address=crypto.address,
|
|
147
|
-
private_key=
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
private_key=(
|
|
148
|
+
crypto.encrypt(password=self.password)
|
|
149
|
+
if self.password is not None
|
|
150
|
+
else crypto.private_key
|
|
151
|
+
),
|
|
150
152
|
)
|
|
151
153
|
for path in (
|
|
152
154
|
self.path / f"{crypto.address}.bak",
|
operate/ledger/__init__.py
CHANGED
|
@@ -27,7 +27,6 @@ from math import ceil
|
|
|
27
27
|
from aea.crypto.base import LedgerApi
|
|
28
28
|
from aea.crypto.registries import make_ledger_api
|
|
29
29
|
from aea_ledger_ethereum import DEFAULT_GAS_PRICE_STRATEGIES, EIP1559, GWEI, to_wei
|
|
30
|
-
from web3.middleware import geth_poa_middleware
|
|
31
30
|
|
|
32
31
|
from operate.operate_types import Chain
|
|
33
32
|
|
|
@@ -133,12 +132,9 @@ def make_chain_ledger_api(
|
|
|
133
132
|
address=rpc or get_default_rpc(chain=chain),
|
|
134
133
|
chain_id=chain.id,
|
|
135
134
|
gas_price_strategies=gas_price_strategies,
|
|
136
|
-
poa_chain=chain
|
|
135
|
+
poa_chain=chain in (Chain.OPTIMISM, Chain.POLYGON),
|
|
137
136
|
)
|
|
138
137
|
|
|
139
|
-
if chain == Chain.OPTIMISM:
|
|
140
|
-
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
141
|
-
|
|
142
138
|
return ledger_api
|
|
143
139
|
|
|
144
140
|
|
|
@@ -183,7 +179,6 @@ def update_tx_with_gas_pricing(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
|
183
179
|
# TODO This gas management should be done at a lower level in the library
|
|
184
180
|
def update_tx_with_gas_estimate(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
185
181
|
"""Update transaction with gas estimate."""
|
|
186
|
-
print(f"[LEDGER] Trying to update transaction gas {tx['from']=} {tx['gas']=}.")
|
|
187
182
|
original_from = tx["from"]
|
|
188
183
|
original_gas = tx.get("gas", 1)
|
|
189
184
|
|
|
@@ -192,7 +187,6 @@ def update_tx_with_gas_estimate(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
|
192
187
|
tx["gas"] = 1
|
|
193
188
|
ledger_api.update_with_gas_estimate(tx)
|
|
194
189
|
if tx["gas"] > 1:
|
|
195
|
-
print(f"[LEDGER] Gas estimated successfully {tx['from']=} {tx['gas']=}.")
|
|
196
190
|
break
|
|
197
191
|
|
|
198
192
|
tx["from"] = original_from
|
operate/ledger/profiles.py
CHANGED
|
@@ -46,7 +46,6 @@ for _chain in CHAINS:
|
|
|
46
46
|
"service_registry_token_utility": profile[
|
|
47
47
|
"service_registry_token_utility"
|
|
48
48
|
],
|
|
49
|
-
"service_manager": profile["service_manager_token"],
|
|
50
49
|
"gnosis_safe_proxy_factory": profile["gnosis_safe_proxy_factory"],
|
|
51
50
|
"gnosis_safe_same_address_multisig": profile[
|
|
52
51
|
"gnosis_safe_same_address_multisig"
|
operate/operate_http/__init__.py
CHANGED
|
@@ -32,8 +32,6 @@ from starlette.types import Receive, Scope, Send
|
|
|
32
32
|
from operate.operate_http.exceptions import NotAllowed, ResourceException
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
# pylint: disable=no-self-use
|
|
36
|
-
|
|
37
35
|
GenericResource = t.TypeVar("GenericResource")
|
|
38
36
|
PostPayload = t.TypeVar("PostPayload")
|
|
39
37
|
PostResponse = t.TypeVar("PostResponse")
|
operate/operate_types.py
CHANGED
|
@@ -30,7 +30,7 @@ from pathlib import Path
|
|
|
30
30
|
import argon2
|
|
31
31
|
from aea_ledger_ethereum import cast
|
|
32
32
|
from autonomy.chain.config import ChainType
|
|
33
|
-
from autonomy.chain.
|
|
33
|
+
from autonomy.chain.config import LedgerType as LedgerTypeOA
|
|
34
34
|
from cryptography.fernet import Fernet
|
|
35
35
|
from typing_extensions import TypedDict
|
|
36
36
|
|
|
@@ -38,98 +38,8 @@ from operate.constants import FERNET_KEY_LENGTH, NO_STAKING_PROGRAM_ID
|
|
|
38
38
|
from operate.resource import LocalResource
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
_CHAIN_ID_TO_CHAIN_NAME = {
|
|
44
|
-
chain_id: chain_name for chain_name, chain_id in CHAIN_NAME_TO_CHAIN_ID.items()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class LedgerType(str, enum.Enum):
|
|
49
|
-
"""Ledger type enum."""
|
|
50
|
-
|
|
51
|
-
ETHEREUM = "ethereum"
|
|
52
|
-
SOLANA = "solana"
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def config_file(self) -> str:
|
|
56
|
-
"""Config filename."""
|
|
57
|
-
return f"{self.name.lower()}.json"
|
|
58
|
-
|
|
59
|
-
@property
|
|
60
|
-
def key_file(self) -> str:
|
|
61
|
-
"""Key filename."""
|
|
62
|
-
return f"{self.name.lower()}.txt"
|
|
63
|
-
|
|
64
|
-
@property
|
|
65
|
-
def mnemonic_file(self) -> str:
|
|
66
|
-
"""Mnemonic filename."""
|
|
67
|
-
return f"{self.name.lower()}.mnemonic.json"
|
|
68
|
-
|
|
69
|
-
@classmethod
|
|
70
|
-
def from_id(cls, chain_id: int) -> "LedgerType":
|
|
71
|
-
"""Load from chain ID."""
|
|
72
|
-
return Chain(_CHAIN_ID_TO_CHAIN_NAME[chain_id]).ledger_type
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
# Dynamically create the Chain enum from the ChainType
|
|
76
|
-
# TODO: Migrate this to open-autonomy and remove this modified version of Chain here and use the one from open-autonomy
|
|
77
|
-
# This version of open-autonomy must support the LedgerType to support SOLANA in the future
|
|
78
|
-
# If solana support is not fuly implemented, decide to keep this half-baked feature.
|
|
79
|
-
#
|
|
80
|
-
# TODO: Once the above issue is properly implemented in Open Autonomy, remove the following
|
|
81
|
-
# lines from tox.ini:
|
|
82
|
-
#
|
|
83
|
-
# exclude = ^(operate/operate_types\.py|scripts/setup_wallet\.py|operate/ledger/profiles\.py|operate/ledger/__init__\.py|operate/wallet/master\.py|operate/services/protocol\.py|operate/services/manage\.py|operate/cli\.py)$
|
|
84
|
-
#
|
|
85
|
-
# [mypy-operate.*]
|
|
86
|
-
# follow_imports = skip # noqa
|
|
87
|
-
#
|
|
88
|
-
# These lines were itroduced to resolve mypy issues with the temporary Chain/ChainType solution.
|
|
89
|
-
Chain = enum.Enum(
|
|
90
|
-
"Chain",
|
|
91
|
-
[(member.name, member.value) for member in ChainType]
|
|
92
|
-
+ [
|
|
93
|
-
("SOLANA", "solana"),
|
|
94
|
-
],
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class ChainMixin:
|
|
99
|
-
"""Mixin for some new functions in the ChainType class."""
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def id(self) -> t.Optional[int]:
|
|
103
|
-
"""Chain ID"""
|
|
104
|
-
if self == Chain.CUSTOM:
|
|
105
|
-
chain_id = os.environ.get("CUSTOM_CHAIN_ID")
|
|
106
|
-
if chain_id is None:
|
|
107
|
-
return None
|
|
108
|
-
return int(chain_id)
|
|
109
|
-
return CHAIN_NAME_TO_CHAIN_ID[self.value]
|
|
110
|
-
|
|
111
|
-
@property
|
|
112
|
-
def ledger_type(self) -> LedgerType:
|
|
113
|
-
"""Ledger type."""
|
|
114
|
-
if self in (Chain.SOLANA,):
|
|
115
|
-
return LedgerType.SOLANA
|
|
116
|
-
return LedgerType.ETHEREUM
|
|
117
|
-
|
|
118
|
-
@classmethod
|
|
119
|
-
def from_string(cls, chain: str) -> "Chain":
|
|
120
|
-
"""Load from string."""
|
|
121
|
-
return Chain(chain.lower())
|
|
122
|
-
|
|
123
|
-
@classmethod
|
|
124
|
-
def from_id(cls, chain_id: int) -> "Chain":
|
|
125
|
-
"""Load from chain ID."""
|
|
126
|
-
return Chain(_CHAIN_ID_TO_CHAIN_NAME[chain_id])
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
# Add the ChainMixin methods to the Chain enum
|
|
130
|
-
for name in dir(ChainMixin):
|
|
131
|
-
if not name.startswith("__"):
|
|
132
|
-
setattr(Chain, name, getattr(ChainMixin, name))
|
|
41
|
+
LedgerType = LedgerTypeOA
|
|
42
|
+
Chain = ChainType
|
|
133
43
|
|
|
134
44
|
|
|
135
45
|
class DeploymentStatus(enum.IntEnum):
|
|
@@ -34,7 +34,12 @@ from halo import Halo # type: ignore[import]
|
|
|
34
34
|
from web3.exceptions import Web3Exception
|
|
35
35
|
|
|
36
36
|
from operate.account.user import UserAccount
|
|
37
|
-
from operate.constants import
|
|
37
|
+
from operate.constants import (
|
|
38
|
+
DEFAULT_TIMEOUT,
|
|
39
|
+
IPFS_ADDRESS,
|
|
40
|
+
NO_STAKING_PROGRAM_ID,
|
|
41
|
+
USER_JSON,
|
|
42
|
+
)
|
|
38
43
|
from operate.data import DATA_DIR
|
|
39
44
|
from operate.data.contracts.staking_token.contract import StakingTokenContract
|
|
40
45
|
from operate.ledger import DEFAULT_RPCS
|
|
@@ -49,6 +54,7 @@ from operate.quickstart.utils import (
|
|
|
49
54
|
CHAIN_TO_METADATA,
|
|
50
55
|
QuickstartConfig,
|
|
51
56
|
ask_or_get_from_env,
|
|
57
|
+
ask_yes_or_no,
|
|
52
58
|
check_rpc,
|
|
53
59
|
print_box,
|
|
54
60
|
print_section,
|
|
@@ -124,6 +130,42 @@ QS_STAKING_PROGRAMS: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
124
130
|
},
|
|
125
131
|
}
|
|
126
132
|
|
|
133
|
+
DEPRECATED_QS_STAKING_PROGRAMS = {
|
|
134
|
+
"quickstart_beta_hobbyist",
|
|
135
|
+
"quickstart_beta_hobbyist_2",
|
|
136
|
+
"quickstart_beta_expert",
|
|
137
|
+
"quickstart_beta_expert_2",
|
|
138
|
+
"quickstart_beta_expert_3",
|
|
139
|
+
"quickstart_beta_expert_4",
|
|
140
|
+
"quickstart_beta_expert_5",
|
|
141
|
+
"quickstart_beta_expert_6",
|
|
142
|
+
"quickstart_beta_expert_7",
|
|
143
|
+
"quickstart_beta_expert_8",
|
|
144
|
+
"quickstart_beta_expert_9",
|
|
145
|
+
"quickstart_beta_expert_10",
|
|
146
|
+
"quickstart_beta_expert_11",
|
|
147
|
+
"quickstart_beta_expert_12",
|
|
148
|
+
"quickstart_beta_expert_15_mech_marketplace",
|
|
149
|
+
"quickstart_beta_expert_16_mech_marketplace",
|
|
150
|
+
"quickstart_beta_expert_17_mech_marketplace",
|
|
151
|
+
"quickstart_beta_expert_18_mech_marketplace",
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _deprecated_program_warning(program_id: str) -> bool:
|
|
156
|
+
"""Confirm deprecated program warning."""
|
|
157
|
+
if program_id not in DEPRECATED_QS_STAKING_PROGRAMS:
|
|
158
|
+
return True
|
|
159
|
+
|
|
160
|
+
print_box(
|
|
161
|
+
"""
|
|
162
|
+
WARNING
|
|
163
|
+
The selected staking program is deprecated.
|
|
164
|
+
Using it may prevent your agent from earning staking rewards.
|
|
165
|
+
"""
|
|
166
|
+
)
|
|
167
|
+
return ask_yes_or_no("Do you want to proceed anyway?")
|
|
168
|
+
|
|
127
169
|
|
|
128
170
|
def ask_confirm_password() -> str:
|
|
129
171
|
"""Ask for password confirmation."""
|
|
@@ -221,6 +263,7 @@ def configure_local_config(
|
|
|
221
263
|
LedgerType.ETHEREUM.lower(),
|
|
222
264
|
address=config.rpc[config.principal_chain], # type: ignore[index]
|
|
223
265
|
chain_id=home_chain.id,
|
|
266
|
+
poa_chain=chain in (Chain.OPTIMISM.value, Chain.POLYGON.value),
|
|
224
267
|
)
|
|
225
268
|
|
|
226
269
|
if config.staking_program_id is None:
|
|
@@ -253,7 +296,7 @@ def configure_local_config(
|
|
|
253
296
|
try:
|
|
254
297
|
metadata_hash = instance.functions.metadataHash().call().hex()
|
|
255
298
|
ipfs_address = IPFS_ADDRESS.format(hash=metadata_hash)
|
|
256
|
-
response = requests.get(ipfs_address)
|
|
299
|
+
response = requests.get(ipfs_address, timeout=DEFAULT_TIMEOUT)
|
|
257
300
|
if response.status_code != HTTPStatus.OK:
|
|
258
301
|
raise requests.RequestException(
|
|
259
302
|
f"Failed to fetch data from {ipfs_address}: {response.status_code}"
|
|
@@ -276,7 +319,10 @@ def configure_local_config(
|
|
|
276
319
|
except Web3Exception:
|
|
277
320
|
metadata["available_staking_slots"] = "?"
|
|
278
321
|
|
|
279
|
-
|
|
322
|
+
deprecated_str = (
|
|
323
|
+
"[DEPRECATED] " if program_id in DEPRECATED_QS_STAKING_PROGRAMS else ""
|
|
324
|
+
)
|
|
325
|
+
name = deprecated_str + metadata["name"]
|
|
280
326
|
description = metadata["description"]
|
|
281
327
|
if "available_staking_slots" in metadata:
|
|
282
328
|
available_slots_str = (
|
|
@@ -313,12 +359,23 @@ def configure_local_config(
|
|
|
313
359
|
for idx, prog in available_choices.items():
|
|
314
360
|
print(f"{idx}) {prog['name']} : {prog['slots']}")
|
|
315
361
|
continue
|
|
362
|
+
|
|
363
|
+
if not _deprecated_program_warning(
|
|
364
|
+
available_choices[choice]["program_id"]
|
|
365
|
+
):
|
|
366
|
+
continue
|
|
367
|
+
|
|
316
368
|
selected_program = available_choices[choice]
|
|
317
369
|
config.staking_program_id = selected_program["program_id"]
|
|
318
370
|
print(f"Selected staking program: {selected_program['name']}")
|
|
319
371
|
break
|
|
320
372
|
except ValueError:
|
|
321
373
|
if input_value in ids:
|
|
374
|
+
if not _deprecated_program_warning(
|
|
375
|
+
available_choices[choice]["program_id"]
|
|
376
|
+
):
|
|
377
|
+
continue
|
|
378
|
+
|
|
322
379
|
config.staking_program_id = input_value
|
|
323
380
|
break
|
|
324
381
|
else:
|
|
@@ -431,9 +488,9 @@ def configure_local_config(
|
|
|
431
488
|
|
|
432
489
|
print()
|
|
433
490
|
|
|
434
|
-
template["env_variables"][env_var_name][
|
|
435
|
-
|
|
436
|
-
|
|
491
|
+
template["env_variables"][env_var_name]["value"] = (
|
|
492
|
+
config.user_provided_args[env_var_name]
|
|
493
|
+
)
|
|
437
494
|
|
|
438
495
|
# TODO: Handle it in a more generic way
|
|
439
496
|
if (
|
operate/quickstart/utils.py
CHANGED
|
@@ -27,9 +27,10 @@ from pathlib import Path
|
|
|
27
27
|
from typing import Dict, Optional, Union, get_args, get_origin
|
|
28
28
|
|
|
29
29
|
import requests
|
|
30
|
-
from halo import Halo
|
|
30
|
+
from halo import Halo
|
|
31
|
+
from web3.exceptions import Web3RPCError
|
|
31
32
|
|
|
32
|
-
from operate.constants import ZERO_ADDRESS
|
|
33
|
+
from operate.constants import DEFAULT_TIMEOUT, ZERO_ADDRESS
|
|
33
34
|
from operate.ledger.profiles import OLAS, USDC
|
|
34
35
|
from operate.operate_types import Chain
|
|
35
36
|
from operate.resource import LocalResource, deserialize
|
|
@@ -225,11 +226,14 @@ def check_rpc(chain: str, rpc_url: Optional[str] = None) -> bool:
|
|
|
225
226
|
|
|
226
227
|
try:
|
|
227
228
|
response = requests.post(
|
|
228
|
-
rpc_url,
|
|
229
|
+
rpc_url,
|
|
230
|
+
json=rpc_data,
|
|
231
|
+
headers={"Content-Type": "application/json"},
|
|
232
|
+
timeout=DEFAULT_TIMEOUT,
|
|
229
233
|
)
|
|
230
234
|
response.raise_for_status()
|
|
231
235
|
rpc_response = response.json()
|
|
232
|
-
except (requests.exceptions.RequestException,
|
|
236
|
+
except (requests.exceptions.RequestException, Web3RPCError, TypeError) as e:
|
|
233
237
|
spinner.fail(f"Error: Failed to send {chain} RPC request: {e}")
|
|
234
238
|
return False
|
|
235
239
|
|
operate/resource.py
CHANGED
|
@@ -40,7 +40,7 @@ N_BACKUPS = 5
|
|
|
40
40
|
|
|
41
41
|
def serialize(obj: t.Any) -> t.Any:
|
|
42
42
|
"""Serialize object."""
|
|
43
|
-
if is_dataclass(obj):
|
|
43
|
+
if is_dataclass(obj) and not isinstance(obj, type):
|
|
44
44
|
return serialize(asdict(obj))
|
|
45
45
|
if isinstance(obj, Path):
|
|
46
46
|
return str(obj)
|
|
@@ -88,7 +88,7 @@ def deserialize(obj: t.Any, otype: t.Any) -> t.Any:
|
|
|
88
88
|
return otype(obj)
|
|
89
89
|
if otype is Path:
|
|
90
90
|
return Path(obj)
|
|
91
|
-
if is_dataclass(otype):
|
|
91
|
+
if is_dataclass(otype) and hasattr(otype, "from_json"):
|
|
92
92
|
return otype.from_json(obj)
|
|
93
93
|
if otype is bytes:
|
|
94
94
|
return bytes.fromhex(obj)
|
operate/services/agent_runner.py
CHANGED
|
@@ -33,7 +33,7 @@ import requests
|
|
|
33
33
|
from aea.configurations.data_types import PublicId
|
|
34
34
|
from aea.helpers.logging import setup_logger
|
|
35
35
|
|
|
36
|
-
from operate.constants import AGENT_RUNNER_PREFIX, CONFIG_JSON
|
|
36
|
+
from operate.constants import AGENT_RUNNER_PREFIX, CONFIG_JSON, DEFAULT_TIMEOUT
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
@dataclass
|
|
@@ -52,7 +52,7 @@ class AgentRelease:
|
|
|
52
52
|
|
|
53
53
|
def get_url_and_hash(self, asset_name: str) -> tuple[str, str]:
|
|
54
54
|
"""Get download url and asset sha256 hash."""
|
|
55
|
-
release_data = requests.get(self.release_url).json()
|
|
55
|
+
release_data = requests.get(self.release_url, timeout=DEFAULT_TIMEOUT).json()
|
|
56
56
|
|
|
57
57
|
assets_filtered = [i for i in release_data["assets"] if i["name"] == asset_name]
|
|
58
58
|
if not assets_filtered:
|
|
@@ -106,7 +106,7 @@ class AgentRunnerManager:
|
|
|
106
106
|
"""Download file of agent runner."""
|
|
107
107
|
try:
|
|
108
108
|
# Send a GET request to the URL
|
|
109
|
-
response = requests.get(url, stream=True)
|
|
109
|
+
response = requests.get(url, stream=True, timeout=DEFAULT_TIMEOUT)
|
|
110
110
|
response.raise_for_status() # Raise an error for bad status codes (4xx or 5xx)
|
|
111
111
|
|
|
112
112
|
# Open the file in binary write mode and save the content
|
operate/services/manage.py
CHANGED
|
@@ -1551,7 +1551,7 @@ class ServiceManager:
|
|
|
1551
1551
|
f"Cannot enable recovery module. Safe {service_safe_address} has inconsistent owners."
|
|
1552
1552
|
)
|
|
1553
1553
|
|
|
1554
|
-
def _get_current_staking_program(
|
|
1554
|
+
def _get_current_staking_program(
|
|
1555
1555
|
self, service: Service, chain: str
|
|
1556
1556
|
) -> t.Optional[str]:
|
|
1557
1557
|
staking_manager = StakingManager(Chain(chain))
|
|
@@ -1940,7 +1940,7 @@ class ServiceManager:
|
|
|
1940
1940
|
|
|
1941
1941
|
# transfer claimed amount from agents safe to master safe
|
|
1942
1942
|
# TODO: remove after staking contract directly starts sending the rewards to master safe
|
|
1943
|
-
amount_claimed = int(receipt["logs"][0]["data"].
|
|
1943
|
+
amount_claimed = int(receipt["logs"][0]["data"].to_0x_hex(), 16)
|
|
1944
1944
|
self.logger.info(f"Claimed amount: {amount_claimed}")
|
|
1945
1945
|
ethereum_crypto = self.keys_manager.get_crypto_instance(
|
|
1946
1946
|
service.agent_addresses[0]
|
|
@@ -2352,9 +2352,9 @@ class ServiceManager:
|
|
|
2352
2352
|
allow_start_agent = False
|
|
2353
2353
|
|
|
2354
2354
|
# Protocol asset requirements
|
|
2355
|
-
protocol_asset_requirements[
|
|
2356
|
-
chain
|
|
2357
|
-
|
|
2355
|
+
protocol_asset_requirements[chain] = (
|
|
2356
|
+
self._compute_protocol_asset_requirements(service_config_id, chain)
|
|
2357
|
+
)
|
|
2358
2358
|
service_asset_requirements = chain_data.user_params.fund_requirements
|
|
2359
2359
|
|
|
2360
2360
|
# Bonded assets
|
|
@@ -2461,15 +2461,12 @@ class ServiceManager:
|
|
|
2461
2461
|
asset_address
|
|
2462
2462
|
] = recommended_refill
|
|
2463
2463
|
|
|
2464
|
-
total_requirements[chain].setdefault(master_safe, {})[
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
chain
|
|
2471
|
-
].get(
|
|
2472
|
-
asset_address, 0
|
|
2464
|
+
total_requirements[chain].setdefault(master_safe, {})[asset_address] = (
|
|
2465
|
+
sum(
|
|
2466
|
+
agent_asset_funding_values[address]["topup"]
|
|
2467
|
+
for address in agent_asset_funding_values
|
|
2468
|
+
)
|
|
2469
|
+
+ protocol_asset_requirements[chain].get(asset_address, 0)
|
|
2473
2470
|
)
|
|
2474
2471
|
|
|
2475
2472
|
if asset_address == ZERO_ADDRESS and any(
|
|
@@ -2498,9 +2495,9 @@ class ServiceManager:
|
|
|
2498
2495
|
ZERO_ADDRESS
|
|
2499
2496
|
] = eoa_recommended_refill
|
|
2500
2497
|
|
|
2501
|
-
total_requirements[chain].setdefault(master_eoa, {})[
|
|
2502
|
-
|
|
2503
|
-
|
|
2498
|
+
total_requirements[chain].setdefault(master_eoa, {})[ZERO_ADDRESS] = (
|
|
2499
|
+
eoa_funding_values["topup"]
|
|
2500
|
+
)
|
|
2504
2501
|
|
|
2505
2502
|
is_refill_required = any(
|
|
2506
2503
|
amount > 0
|