olas-operate-middleware 0.11.1__py3-none-any.whl → 0.11.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.
- {olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/METADATA +1 -1
- {olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/RECORD +11 -11
- operate/ledger/__init__.py +16 -20
- operate/quickstart/reset_configs.py +1 -1
- operate/quickstart/run_service.py +9 -4
- operate/quickstart/utils.py +8 -8
- operate/services/funding_manager.py +21 -1
- operate/services/service.py +25 -1
- {olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/entry_points.txt +0 -0
- {olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/licenses/LICENSE +0 -0
{olas_operate_middleware-0.11.1.dist-info → olas_operate_middleware-0.11.3.dist-info}/RECORD
RENAMED
|
@@ -58,7 +58,7 @@ operate/data/contracts/uniswap_v2_erc20/contract.yaml,sha256=XUdz-XtKtmZgLfItbO8
|
|
|
58
58
|
operate/data/contracts/uniswap_v2_erc20/tests/__init__.py,sha256=3Arw8dsCsJz6hVOl0t9UjFASHXbV9yp3hw6x4HqgXpU,847
|
|
59
59
|
operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py,sha256=FzZbw9OTcr_yvjOXpk9YcO-K40eyDARyybcfSHDg2Ps,13392
|
|
60
60
|
operate/keys.py,sha256=IyXbKQkcH33021VaOfQC_ub0lHD6uCJaGtwGvjOMRs8,5650
|
|
61
|
-
operate/ledger/__init__.py,sha256=
|
|
61
|
+
operate/ledger/__init__.py,sha256=G0iWcA0Rc-Um8NwpwPJWsQNUQb2tWKyDjzirxPhGc98,6517
|
|
62
62
|
operate/ledger/profiles.py,sha256=7dxUFzjlT-VNpu9z45qeqPGyz5fDz0bM3LUK9VLcgJk,14272
|
|
63
63
|
operate/migration.py,sha256=TJhztfHUVhZ2buKHx10vXeVo1rRAORdbqGE8fLHL15I,17305
|
|
64
64
|
operate/operate_http/__init__.py,sha256=dxCIVSUos23M4R-PFZZG6k5QrOlEiK0SxhCYSFNxh7U,4711
|
|
@@ -67,22 +67,22 @@ operate/operate_types.py,sha256=hGzYW47MPxOQuvDQAD_TqyIHxNReTeDYQI_uKrfJ1Jc,1557
|
|
|
67
67
|
operate/pearl.py,sha256=yrTpSXLu_ML3qT-uNxq3kScOyo31JyxBujiSMfMUbcg,1690
|
|
68
68
|
operate/quickstart/analyse_logs.py,sha256=K11AWWevkddUIUzTe75J3fYVS6aLfi6kT_dAI9OjrX8,4195
|
|
69
69
|
operate/quickstart/claim_staking_rewards.py,sha256=K7X1Yq0mxe3qWmFLb1Xu9-Jghhml95lS_LpM_BXii0o,3533
|
|
70
|
-
operate/quickstart/reset_configs.py,sha256=
|
|
70
|
+
operate/quickstart/reset_configs.py,sha256=DVPM4mh6Djunwq16hf8lD9-nGkkm7wVtwr2JUXr1if8,3380
|
|
71
71
|
operate/quickstart/reset_password.py,sha256=78riP7zyFM2JMa1H8Dh6pg-PtLJLQS7PFzx9SECPACQ,2571
|
|
72
72
|
operate/quickstart/reset_staking.py,sha256=SB5LZq9EctG4SYn2M6oPZ7R7ARHSFLRGzAqfKkpRcy0,5111
|
|
73
|
-
operate/quickstart/run_service.py,sha256=
|
|
73
|
+
operate/quickstart/run_service.py,sha256=yej4VRYcOaBJfT-LLqOe6VQ7i38PrRoAarr-U74CkvA,27653
|
|
74
74
|
operate/quickstart/stop_service.py,sha256=CNcCucI4sqfZG0wTxxh-k14xGcbOh50UGyXqTZVQJP0,2048
|
|
75
75
|
operate/quickstart/terminate_on_chain_service.py,sha256=5ENU8_mkj06i80lKUX-v1QbLU0YzKeOZDUL1e_jzySE,2914
|
|
76
|
-
operate/quickstart/utils.py,sha256=
|
|
76
|
+
operate/quickstart/utils.py,sha256=jvi7IgPtJEWf7-ciZFyEh_jgNthhv3Pus4VZa_Ha_ms,9221
|
|
77
77
|
operate/resource.py,sha256=E59oIVqf6B6nN4LTmf_o2iCgLFAogTLPjm_cK6kMVxg,6305
|
|
78
78
|
operate/services/__init__.py,sha256=isrThS-Ccu5Sc15JZgkN4uTAVaSg-NwUUSDeTyJEqLk,855
|
|
79
79
|
operate/services/agent_runner.py,sha256=IIN77vD_2lq_hCkai-3dJQ3Ae64GUOQncvv0wxb3qUE,7629
|
|
80
80
|
operate/services/deployment_runner.py,sha256=iT3gVZvz94kvd7vwtqJgPv74OJliz5XrgjJ_SNFiuEk,27191
|
|
81
|
-
operate/services/funding_manager.py,sha256=
|
|
81
|
+
operate/services/funding_manager.py,sha256=Oei9uOSIvPvmbYotOndqjK5xxeiUG2qV-ejcA5MJmIE,38404
|
|
82
82
|
operate/services/health_checker.py,sha256=r_lMlRZu-UNfqaM-Zo5_cWjsigdqYTAty4h-ISpM7RE,9859
|
|
83
83
|
operate/services/manage.py,sha256=PyjrcH46bMtSalbpl25roGZlwg7ZEuGkw8gEbahUzj8,112710
|
|
84
84
|
operate/services/protocol.py,sha256=KJK4jpwWbVqXaCNZNo84Sqxo32SFaxUQ_O8Jwq7im4g,71871
|
|
85
|
-
operate/services/service.py,sha256=
|
|
85
|
+
operate/services/service.py,sha256=u_l9nWcfWAqm4lQsHuyXQnOHdZiFvuxaQd1no5IbDV8,43723
|
|
86
86
|
operate/services/utils/__init__.py,sha256=TvioaZ1mfTRUSCtrQoLNAp4WMVXyqEJqFJM4PxSQCRU,24
|
|
87
87
|
operate/services/utils/mech.py,sha256=W2x4dqodivNKXjWU-Brp40QhoUHsIMyNAO7-caMoR0Q,3821
|
|
88
88
|
operate/services/utils/tendermint.py,sha256=3h9nDb2Z89T0RwUr_AaVjqtymQmsu3u6DAVCfL_k1U0,25591
|
|
@@ -94,8 +94,8 @@ operate/utils/ssl.py,sha256=O5DrDoZD4T4qQuHP8GLwWUVxQ-1qXeefGp6uDJiF2lM,4308
|
|
|
94
94
|
operate/wallet/__init__.py,sha256=NGiozD3XhvkBi7_FaOWQ8x1thZPK4uGpokJaeDY_o2w,813
|
|
95
95
|
operate/wallet/master.py,sha256=gcax6M8_KT2IkL0kGZP4lF4f2updoP5r6ix5e72ZrL4,33674
|
|
96
96
|
operate/wallet/wallet_recovery_manager.py,sha256=ZOLq0B9irux_og8pLBzaxlRA1r6RqJfZA4j4RX0kzoU,7775
|
|
97
|
-
olas_operate_middleware-0.11.
|
|
98
|
-
olas_operate_middleware-0.11.
|
|
99
|
-
olas_operate_middleware-0.11.
|
|
100
|
-
olas_operate_middleware-0.11.
|
|
101
|
-
olas_operate_middleware-0.11.
|
|
97
|
+
olas_operate_middleware-0.11.3.dist-info/METADATA,sha256=pr-OBOx0J1xjI3ONXU8Ey_YlM7KLuLtZD21N_68-Wjc,2139
|
|
98
|
+
olas_operate_middleware-0.11.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
99
|
+
olas_operate_middleware-0.11.3.dist-info/entry_points.txt,sha256=dM1g2I7ODApKQFcgl5J4NGA7pfBTo6qsUTXM-j2OLlw,44
|
|
100
|
+
olas_operate_middleware-0.11.3.dist-info/licenses/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
|
|
101
|
+
olas_operate_middleware-0.11.3.dist-info/RECORD,,
|
operate/ledger/__init__.py
CHANGED
|
@@ -119,31 +119,27 @@ def make_chain_ledger_api(
|
|
|
119
119
|
rpc: t.Optional[str] = None,
|
|
120
120
|
) -> LedgerApi:
|
|
121
121
|
"""Get default RPC chain type."""
|
|
122
|
+
if chain == Chain.SOLANA: # TODO: Complete when Solana is supported
|
|
123
|
+
raise NotImplementedError("Solana not yet supported.")
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
gas_price_strategies = deepcopy(DEFAULT_GAS_PRICE_STRATEGIES)
|
|
128
|
-
if chain in (Chain.BASE, Chain.MODE, Chain.OPTIMISM):
|
|
129
|
-
gas_price_strategies[EIP1559]["fallback_estimate"]["maxFeePerGas"] = to_wei(
|
|
130
|
-
5, GWEI
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
ledger_api = make_ledger_api(
|
|
134
|
-
chain.ledger_type.name.lower(),
|
|
135
|
-
address=rpc or get_default_rpc(chain=chain),
|
|
136
|
-
chain_id=chain.id,
|
|
137
|
-
gas_price_strategies=gas_price_strategies,
|
|
138
|
-
poa_chain=chain == Chain.POLYGON,
|
|
125
|
+
gas_price_strategies = deepcopy(DEFAULT_GAS_PRICE_STRATEGIES)
|
|
126
|
+
if chain in (Chain.BASE, Chain.MODE, Chain.OPTIMISM):
|
|
127
|
+
gas_price_strategies[EIP1559]["fallback_estimate"]["maxFeePerGas"] = to_wei(
|
|
128
|
+
5, GWEI
|
|
139
129
|
)
|
|
140
130
|
|
|
141
|
-
|
|
142
|
-
|
|
131
|
+
ledger_api = make_ledger_api(
|
|
132
|
+
chain.ledger_type.name.lower(),
|
|
133
|
+
address=rpc or get_default_rpc(chain=chain),
|
|
134
|
+
chain_id=chain.id,
|
|
135
|
+
gas_price_strategies=gas_price_strategies,
|
|
136
|
+
poa_chain=chain == Chain.POLYGON,
|
|
137
|
+
)
|
|
143
138
|
|
|
144
|
-
|
|
139
|
+
if chain == Chain.OPTIMISM:
|
|
140
|
+
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
145
141
|
|
|
146
|
-
return
|
|
142
|
+
return ledger_api
|
|
147
143
|
|
|
148
144
|
|
|
149
145
|
def get_default_ledger_api(chain: Chain) -> LedgerApi:
|
|
@@ -89,7 +89,7 @@ def reset_configs(operate: "OperateApp", config_path: str) -> None:
|
|
|
89
89
|
env_var=f"{chain_name.upper()}_LEDGER_RPC",
|
|
90
90
|
old_value=config.rpc[chain_name],
|
|
91
91
|
hidden=True,
|
|
92
|
-
validator=check_rpc,
|
|
92
|
+
validator=lambda x: check_rpc(chain_name, x), # noqa: B023
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
if config.user_provided_args is None:
|
|
@@ -198,7 +198,7 @@ def configure_local_config(
|
|
|
198
198
|
config.rpc = {}
|
|
199
199
|
|
|
200
200
|
for chain in template["configurations"]:
|
|
201
|
-
while not check_rpc(config.rpc.get(chain)):
|
|
201
|
+
while not check_rpc(chain, config.rpc.get(chain)):
|
|
202
202
|
config.rpc[chain] = ask_or_get_from_env(
|
|
203
203
|
f"Enter a {CHAIN_TO_METADATA[chain]['name']} RPC that supports eth_newFilter [hidden input]: ",
|
|
204
204
|
True,
|
|
@@ -495,7 +495,10 @@ def get_service(manager: ServiceManager, template: ServiceTemplate) -> Service:
|
|
|
495
495
|
service_template=template,
|
|
496
496
|
)
|
|
497
497
|
|
|
498
|
-
|
|
498
|
+
for env_var_name, env_var_data in template["env_variables"].items():
|
|
499
|
+
if env_var_name not in service.env_variables:
|
|
500
|
+
service.env_variables[env_var_name] = env_var_data
|
|
501
|
+
|
|
499
502
|
service.update_user_params_from_template(service_template=template)
|
|
500
503
|
service.store()
|
|
501
504
|
break
|
|
@@ -556,7 +559,7 @@ def _ask_funds_from_requirements(
|
|
|
556
559
|
"""Ask for funds from requirements."""
|
|
557
560
|
spinner = Halo(text="Calculating funds requirements...", spinner="dots")
|
|
558
561
|
spinner.start()
|
|
559
|
-
requirements = manager.
|
|
562
|
+
requirements = manager.funding_requirements(
|
|
560
563
|
service_config_id=service.service_config_id
|
|
561
564
|
)
|
|
562
565
|
spinner.stop()
|
|
@@ -635,6 +638,7 @@ def ensure_enough_funds(operate: "OperateApp", service: Service) -> None:
|
|
|
635
638
|
_maybe_create_master_eoa(operate)
|
|
636
639
|
wallet = operate.wallet_manager.load(ledger_type=LedgerType.ETHEREUM)
|
|
637
640
|
manager = operate.service_manager()
|
|
641
|
+
manager.funding_manager.is_for_quickstart = True
|
|
638
642
|
|
|
639
643
|
backup_owner = None
|
|
640
644
|
while not _ask_funds_from_requirements(manager, wallet, service):
|
|
@@ -692,7 +696,8 @@ def run_service(
|
|
|
692
696
|
)
|
|
693
697
|
|
|
694
698
|
print_section("Funding the service")
|
|
695
|
-
|
|
699
|
+
service = get_service(manager, template)
|
|
700
|
+
manager.funding_manager.topup_service_initial(service=service)
|
|
696
701
|
|
|
697
702
|
print_section("Deploying the service")
|
|
698
703
|
manager.deploy_service_locally(
|
operate/quickstart/utils.py
CHANGED
|
@@ -208,12 +208,12 @@ def ask_or_get_from_env(
|
|
|
208
208
|
return ""
|
|
209
209
|
|
|
210
210
|
|
|
211
|
-
def check_rpc(rpc_url: Optional[str] = None) -> bool:
|
|
211
|
+
def check_rpc(chain: str, rpc_url: Optional[str] = None) -> bool:
|
|
212
212
|
"""Check RPC."""
|
|
213
213
|
if rpc_url is None:
|
|
214
214
|
return False
|
|
215
215
|
|
|
216
|
-
spinner = Halo(text="Checking RPC...", spinner="dots")
|
|
216
|
+
spinner = Halo(text=f"[{chain}] Checking RPC...", spinner="dots")
|
|
217
217
|
spinner.start()
|
|
218
218
|
|
|
219
219
|
rpc_data = {
|
|
@@ -230,7 +230,7 @@ def check_rpc(rpc_url: Optional[str] = None) -> bool:
|
|
|
230
230
|
response.raise_for_status()
|
|
231
231
|
rpc_response = response.json()
|
|
232
232
|
except (requests.exceptions.RequestException, ValueError, TypeError) as e:
|
|
233
|
-
spinner.fail(f"Error: Failed to send RPC request: {e}")
|
|
233
|
+
spinner.fail(f"Error: Failed to send {chain} RPC request: {e}")
|
|
234
234
|
return False
|
|
235
235
|
|
|
236
236
|
rpc_error_message = (
|
|
@@ -246,24 +246,24 @@ def check_rpc(rpc_url: Optional[str] = None) -> bool:
|
|
|
246
246
|
print(" Received response:")
|
|
247
247
|
print(" ", rpc_response)
|
|
248
248
|
print("")
|
|
249
|
-
spinner.fail("Terminating script.")
|
|
249
|
+
spinner.fail(f"[{chain}] Terminating script.")
|
|
250
250
|
elif rpc_error_message == "out of requests":
|
|
251
251
|
print("Error: The provided rpc is out of requests.")
|
|
252
|
-
spinner.fail("Terminating script.")
|
|
252
|
+
spinner.fail(f"[{chain}] Terminating script.")
|
|
253
253
|
elif (
|
|
254
254
|
rpc_error_message == "the method eth_newfilter does not exist/is not available"
|
|
255
255
|
):
|
|
256
256
|
print("Error: The provided RPC does not support 'eth_newFilter'.")
|
|
257
|
-
spinner.fail("Terminating script.")
|
|
257
|
+
spinner.fail(f"[{chain}] Terminating script.")
|
|
258
258
|
elif "invalid" in rpc_error_message or "params" in rpc_error_message:
|
|
259
|
-
spinner.succeed("RPC checks passed.")
|
|
259
|
+
spinner.succeed(f"[{chain}] RPC checks passed.")
|
|
260
260
|
return True
|
|
261
261
|
else:
|
|
262
262
|
print("Error: Unknown rpc error.")
|
|
263
263
|
print(" Received response:")
|
|
264
264
|
print(" ", rpc_response)
|
|
265
265
|
print("")
|
|
266
|
-
spinner.fail("Terminating script.")
|
|
266
|
+
spinner.fail(f"[{chain}] Terminating script.")
|
|
267
267
|
|
|
268
268
|
return False
|
|
269
269
|
|
|
@@ -90,6 +90,7 @@ class FundingManager:
|
|
|
90
90
|
self._lock = threading.Lock()
|
|
91
91
|
self._funding_in_progress: t.Dict[str, bool] = {}
|
|
92
92
|
self._funding_requests_cooldown_until: t.Dict[str, float] = {}
|
|
93
|
+
self.is_for_quickstart = False
|
|
93
94
|
|
|
94
95
|
def drain_agents_eoas(
|
|
95
96
|
self, service: Service, withdrawal_address: str, chain: Chain
|
|
@@ -650,7 +651,11 @@ class FundingManager:
|
|
|
650
651
|
# We assume that if the service safe is created in any chain,
|
|
651
652
|
# we have requested the funding already.
|
|
652
653
|
service_initial_topup = service.get_initial_funding_amounts()
|
|
653
|
-
if
|
|
654
|
+
if self.is_for_quickstart:
|
|
655
|
+
service_initial_shortfalls = self.compute_service_initial_shortfalls(
|
|
656
|
+
service
|
|
657
|
+
)
|
|
658
|
+
elif not all(
|
|
654
659
|
SERVICE_SAFE_PLACEHOLDER in addresses
|
|
655
660
|
for addresses in service_initial_topup.values()
|
|
656
661
|
):
|
|
@@ -795,6 +800,21 @@ class FundingManager:
|
|
|
795
800
|
"""Fund service initially"""
|
|
796
801
|
self.fund_chain_amounts(service.get_initial_funding_amounts())
|
|
797
802
|
|
|
803
|
+
def compute_service_initial_shortfalls(self, service: Service) -> ChainAmounts:
|
|
804
|
+
"""Compute service initial shortfalls"""
|
|
805
|
+
initial_funding_amounts = service.get_initial_funding_amounts()
|
|
806
|
+
service_balances = service.get_balances()
|
|
807
|
+
return self._compute_shortfalls(
|
|
808
|
+
balances=service_balances,
|
|
809
|
+
thresholds=initial_funding_amounts,
|
|
810
|
+
topups=initial_funding_amounts,
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
def topup_service_initial(self, service: Service) -> None:
|
|
814
|
+
"""Fund service enough to reach initial funding amounts"""
|
|
815
|
+
service_initial_shortfalls = self.compute_service_initial_shortfalls(service)
|
|
816
|
+
self.fund_chain_amounts(service_initial_shortfalls)
|
|
817
|
+
|
|
798
818
|
def fund_chain_amounts(self, amounts: ChainAmounts) -> None:
|
|
799
819
|
"""Fund chain amounts"""
|
|
800
820
|
required = self._aggregate_as_master_safe_amounts(amounts)
|
operate/services/service.py
CHANGED
|
@@ -76,7 +76,7 @@ from operate.constants import (
|
|
|
76
76
|
ZERO_ADDRESS,
|
|
77
77
|
)
|
|
78
78
|
from operate.keys import KeysManager
|
|
79
|
-
from operate.ledger import get_default_rpc
|
|
79
|
+
from operate.ledger import get_default_ledger_api, get_default_rpc
|
|
80
80
|
from operate.operate_http.exceptions import NotAllowed
|
|
81
81
|
from operate.operate_types import (
|
|
82
82
|
Chain,
|
|
@@ -97,6 +97,7 @@ from operate.operate_types import (
|
|
|
97
97
|
from operate.resource import LocalResource
|
|
98
98
|
from operate.services.deployment_runner import run_host_deployment, stop_host_deployment
|
|
99
99
|
from operate.services.utils import tendermint
|
|
100
|
+
from operate.utils.gnosis import get_asset_balance
|
|
100
101
|
from operate.utils.ssl import create_ssl_certificate
|
|
101
102
|
|
|
102
103
|
|
|
@@ -1148,6 +1149,29 @@ class Service(LocalResource):
|
|
|
1148
1149
|
|
|
1149
1150
|
return amounts
|
|
1150
1151
|
|
|
1152
|
+
def get_balances(self) -> ChainAmounts:
|
|
1153
|
+
"""Get balances of the agent addresses and service safe."""
|
|
1154
|
+
initial_funding_amounts = self.get_initial_funding_amounts()
|
|
1155
|
+
return ChainAmounts(
|
|
1156
|
+
{
|
|
1157
|
+
chain_str: {
|
|
1158
|
+
address: {
|
|
1159
|
+
asset: get_asset_balance(
|
|
1160
|
+
ledger_api=get_default_ledger_api(
|
|
1161
|
+
Chain.from_string(chain_str)
|
|
1162
|
+
),
|
|
1163
|
+
asset_address=asset,
|
|
1164
|
+
address=address,
|
|
1165
|
+
raise_on_invalid_address=False,
|
|
1166
|
+
)
|
|
1167
|
+
for asset in tokens
|
|
1168
|
+
}
|
|
1169
|
+
for address, tokens in addresses.items()
|
|
1170
|
+
}
|
|
1171
|
+
for chain_str, addresses in initial_funding_amounts.items()
|
|
1172
|
+
}
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1151
1175
|
def get_funding_requests(self) -> ChainAmounts:
|
|
1152
1176
|
"""Get funding amounts requested by the agent."""
|
|
1153
1177
|
agent_response = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|