olas-operate-middleware 0.8.2__tar.gz → 0.10.0__tar.gz
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.8.2 → olas_operate_middleware-0.10.0}/PKG-INFO +2 -2
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/bridge_manager.py +5 -6
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/providers/native_bridge_provider.py +1 -1
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/providers/provider.py +4 -5
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/providers/relay_provider.py +1 -1
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/cli.py +128 -48
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/constants.py +9 -9
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/keys.py +26 -14
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/ledger/__init__.py +4 -4
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/ledger/profiles.py +9 -11
- olas_operate_middleware-0.10.0/operate/migration.py +389 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/operate_types.py +9 -27
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/analyse_logs.py +3 -6
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/claim_staking_rewards.py +1 -4
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/reset_configs.py +0 -3
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/reset_password.py +0 -3
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/reset_staking.py +3 -5
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/run_service.py +5 -7
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/stop_service.py +3 -4
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/terminate_on_chain_service.py +1 -4
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/quickstart/utils.py +4 -7
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/resource.py +37 -5
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/deployment_runner.py +170 -38
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/health_checker.py +5 -8
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/manage.py +103 -164
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/protocol.py +5 -5
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/service.py +42 -242
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/utils/__init__.py +44 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/utils/gnosis.py +25 -17
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/wallet/master.py +20 -24
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/pyproject.toml +2 -2
- olas_operate_middleware-0.8.2/operate/migration.py +0 -63
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/LICENSE +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/README.md +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/account/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/account/user.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/providers/lifi_provider.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/README.md +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/dual_staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/dual_staking_token/build/DualStakingToken.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/dual_staking_token/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/dual_staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/foreign_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/foreign_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/foreign_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/home_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/home_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/home_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l1_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l1_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l1_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l2_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l2_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/l2_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/mech_activity/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/mech_activity/build/MechActivity.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/mech_activity/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/mech_activity/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/optimism_mintable_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/optimism_mintable_erc20/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/optimism_mintable_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/requester_activity_checker/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/requester_activity_checker/build/RequesterActivityChecker.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/requester_activity_checker/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/requester_activity_checker/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/staking_token/build/StakingToken.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/staking_token/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/build/IUniswapV2ERC20.json +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/tests/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/operate_http/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/operate_http/exceptions.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/pearl.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/agent_runner.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/utils/__init__.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/utils/mech.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/services/utils/tendermint.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/utils/ssl.py +0 -0
- {olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/wallet/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: olas-operate-middleware
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: David Vilela
|
|
6
6
|
Author-email: dvilelaf@gmail.com
|
|
@@ -34,7 +34,7 @@ Requires-Dist: open-aea-cli-ipfs (==1.65.0)
|
|
|
34
34
|
Requires-Dist: open-aea-ledger-cosmos (==1.65.0)
|
|
35
35
|
Requires-Dist: open-aea-ledger-ethereum (==1.65.0)
|
|
36
36
|
Requires-Dist: open-aea-ledger-ethereum-flashbots (==1.65.0)
|
|
37
|
-
Requires-Dist: open-autonomy (>=0.
|
|
37
|
+
Requires-Dist: open-autonomy (>=0.20.0,<0.21.0)
|
|
38
38
|
Requires-Dist: psutil (>=5.9.8,<6.0.0)
|
|
39
39
|
Requires-Dist: pyinstaller (>=6.8.0,<7.0.0)
|
|
40
40
|
Requires-Dist: requests-toolbelt (==1.0.0)
|
{olas_operate_middleware-0.8.2 → olas_operate_middleware-0.10.0}/operate/bridge/bridge_manager.py
RENAMED
|
@@ -29,7 +29,6 @@ from dataclasses import dataclass
|
|
|
29
29
|
from pathlib import Path
|
|
30
30
|
from typing import cast
|
|
31
31
|
|
|
32
|
-
from aea.helpers.logging import setup_logger
|
|
33
32
|
from deepdiff import DeepDiff
|
|
34
33
|
from web3 import Web3
|
|
35
34
|
|
|
@@ -77,7 +76,7 @@ NATIVE_BRIDGE_PROVIDER_CONFIGS: t.Dict[str, t.Any] = {
|
|
|
77
76
|
"native-ethereum-to-optimism": {
|
|
78
77
|
"from_chain": "ethereum",
|
|
79
78
|
"from_bridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1",
|
|
80
|
-
"to_chain": "
|
|
79
|
+
"to_chain": "optimism",
|
|
81
80
|
"to_bridge": "0x4200000000000000000000000000000000000010",
|
|
82
81
|
"bridge_eta": 300,
|
|
83
82
|
"bridge_contract_adaptor_class": OptimismContractAdaptor,
|
|
@@ -97,8 +96,8 @@ ROUTES = {
|
|
|
97
96
|
(
|
|
98
97
|
Chain.ETHEREUM, # from_chain
|
|
99
98
|
USDC[Chain.ETHEREUM], # from_token
|
|
100
|
-
Chain.
|
|
101
|
-
USDC[Chain.
|
|
99
|
+
Chain.OPTIMISM, # to_chain
|
|
100
|
+
USDC[Chain.OPTIMISM], # to_token
|
|
102
101
|
): LIFI_PROVIDER_ID,
|
|
103
102
|
(
|
|
104
103
|
Chain.ETHEREUM, # from_chain
|
|
@@ -187,13 +186,13 @@ class BridgeManager:
|
|
|
187
186
|
self,
|
|
188
187
|
path: Path,
|
|
189
188
|
wallet_manager: MasterWalletManager,
|
|
190
|
-
logger:
|
|
189
|
+
logger: logging.Logger,
|
|
191
190
|
quote_validity_period: int = DEFAULT_BUNDLE_VALIDITY_PERIOD,
|
|
192
191
|
) -> None:
|
|
193
192
|
"""Initialize bridge manager."""
|
|
194
193
|
self.path = path
|
|
195
194
|
self.wallet_manager = wallet_manager
|
|
196
|
-
self.logger = logger
|
|
195
|
+
self.logger = logger
|
|
197
196
|
self.quote_validity_period = quote_validity_period
|
|
198
197
|
self.path.mkdir(exist_ok=True)
|
|
199
198
|
(self.path / EXECUTED_BUNDLES_PATH).mkdir(exist_ok=True)
|
|
@@ -417,7 +417,7 @@ class NativeBridgeProvider(Provider):
|
|
|
417
417
|
bridge_contract_adaptor: BridgeContractAdaptor,
|
|
418
418
|
provider_id: str,
|
|
419
419
|
wallet_manager: MasterWalletManager,
|
|
420
|
-
logger:
|
|
420
|
+
logger: logging.Logger,
|
|
421
421
|
) -> None:
|
|
422
422
|
"""Initialize the provider."""
|
|
423
423
|
self.bridge_contract_adaptor = bridge_contract_adaptor
|
|
@@ -31,7 +31,6 @@ from dataclasses import dataclass
|
|
|
31
31
|
from math import ceil
|
|
32
32
|
|
|
33
33
|
from aea.crypto.base import LedgerApi
|
|
34
|
-
from aea.helpers.logging import setup_logger
|
|
35
34
|
from autonomy.chain.tx import TxSettler
|
|
36
35
|
from web3 import Web3
|
|
37
36
|
from web3.middleware import geth_poa_middleware
|
|
@@ -145,12 +144,12 @@ class Provider(ABC):
|
|
|
145
144
|
self,
|
|
146
145
|
wallet_manager: MasterWalletManager,
|
|
147
146
|
provider_id: str,
|
|
148
|
-
logger:
|
|
147
|
+
logger: logging.Logger,
|
|
149
148
|
) -> None:
|
|
150
149
|
"""Initialize the provider."""
|
|
151
150
|
self.wallet_manager = wallet_manager
|
|
152
151
|
self.provider_id = provider_id
|
|
153
|
-
self.logger = logger
|
|
152
|
+
self.logger = logger
|
|
154
153
|
|
|
155
154
|
def description(self) -> str:
|
|
156
155
|
"""Get a human-readable description of the provider."""
|
|
@@ -231,7 +230,7 @@ class Provider(ABC):
|
|
|
231
230
|
ledger_api = wallet.ledger_api(chain)
|
|
232
231
|
|
|
233
232
|
# TODO: Backport to open aea/autonomy
|
|
234
|
-
if chain == Chain.
|
|
233
|
+
if chain == Chain.OPTIMISM:
|
|
235
234
|
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
236
235
|
|
|
237
236
|
return ledger_api
|
|
@@ -244,7 +243,7 @@ class Provider(ABC):
|
|
|
244
243
|
ledger_api = wallet.ledger_api(chain)
|
|
245
244
|
|
|
246
245
|
# TODO: Backport to open aea/autonomy
|
|
247
|
-
if chain == Chain.
|
|
246
|
+
if chain == Chain.OPTIMISM:
|
|
248
247
|
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
249
248
|
|
|
250
249
|
return ledger_api
|
|
@@ -28,10 +28,13 @@ import traceback
|
|
|
28
28
|
import typing as t
|
|
29
29
|
import uuid
|
|
30
30
|
from concurrent.futures import ThreadPoolExecutor
|
|
31
|
+
from contextlib import asynccontextmanager, suppress
|
|
31
32
|
from http import HTTPStatus
|
|
32
33
|
from pathlib import Path
|
|
33
34
|
from types import FrameType
|
|
34
35
|
|
|
36
|
+
import psutil
|
|
37
|
+
import requests
|
|
35
38
|
from aea.helpers.logging import setup_logger
|
|
36
39
|
from clea import group, params, run
|
|
37
40
|
from compose.project import ProjectError
|
|
@@ -47,11 +50,10 @@ from operate import services
|
|
|
47
50
|
from operate.account.user import UserAccount
|
|
48
51
|
from operate.bridge.bridge_manager import BridgeManager
|
|
49
52
|
from operate.constants import (
|
|
50
|
-
|
|
51
|
-
KEYS,
|
|
53
|
+
KEYS_DIR,
|
|
52
54
|
MIN_PASSWORD_LENGTH,
|
|
53
55
|
OPERATE_HOME,
|
|
54
|
-
|
|
56
|
+
SERVICES_DIR,
|
|
55
57
|
ZERO_ADDRESS,
|
|
56
58
|
)
|
|
57
59
|
from operate.ledger.profiles import (
|
|
@@ -69,6 +71,7 @@ from operate.quickstart.reset_staking import reset_staking
|
|
|
69
71
|
from operate.quickstart.run_service import run_service
|
|
70
72
|
from operate.quickstart.stop_service import stop_service
|
|
71
73
|
from operate.quickstart.terminate_on_chain_service import terminate_service
|
|
74
|
+
from operate.services.deployment_runner import stop_deployment_manager
|
|
72
75
|
from operate.services.health_checker import HealthChecker
|
|
73
76
|
from operate.utils import subtract_dicts
|
|
74
77
|
from operate.utils.gnosis import get_assets_balances
|
|
@@ -83,6 +86,7 @@ ACCOUNT_NOT_FOUND_ERROR = JSONResponse(
|
|
|
83
86
|
content={"error": "User account not found."},
|
|
84
87
|
status_code=HTTPStatus.NOT_FOUND,
|
|
85
88
|
)
|
|
89
|
+
TRY_TO_SHUTDOWN_PREVIOUS_INSTANCE = True
|
|
86
90
|
|
|
87
91
|
|
|
88
92
|
def service_not_found_error(service_config_id: str) -> JSONResponse:
|
|
@@ -104,13 +108,12 @@ class OperateApp:
|
|
|
104
108
|
"""Initialize object."""
|
|
105
109
|
super().__init__()
|
|
106
110
|
self._path = (home or OPERATE_HOME).resolve()
|
|
107
|
-
self._services = self._path /
|
|
108
|
-
self._keys = self._path /
|
|
109
|
-
self._master_key = self._path / KEY
|
|
111
|
+
self._services = self._path / SERVICES_DIR
|
|
112
|
+
self._keys = self._path / KEYS_DIR
|
|
110
113
|
self.setup()
|
|
111
114
|
|
|
112
115
|
self.logger = logger or setup_logger(name="operate")
|
|
113
|
-
|
|
116
|
+
services.manage.KeysManager(
|
|
114
117
|
path=self._keys,
|
|
115
118
|
logger=self.logger,
|
|
116
119
|
)
|
|
@@ -118,6 +121,9 @@ class OperateApp:
|
|
|
118
121
|
|
|
119
122
|
mm = MigrationManager(self._path, self.logger)
|
|
120
123
|
mm.migrate_user_account()
|
|
124
|
+
mm.migrate_services(self.service_manager())
|
|
125
|
+
mm.migrate_wallets(self.wallet_manager)
|
|
126
|
+
mm.migrate_qs_configs()
|
|
121
127
|
|
|
122
128
|
def create_user_account(self, password: str) -> UserAccount:
|
|
123
129
|
"""Create a user account."""
|
|
@@ -164,7 +170,6 @@ class OperateApp:
|
|
|
164
170
|
"""Load service manager."""
|
|
165
171
|
return services.manage.ServiceManager(
|
|
166
172
|
path=self._services,
|
|
167
|
-
keys_manager=self.keys_manager,
|
|
168
173
|
wallet_manager=self.wallet_manager,
|
|
169
174
|
logger=self.logger,
|
|
170
175
|
skip_dependency_check=skip_dependency_check,
|
|
@@ -185,6 +190,7 @@ class OperateApp:
|
|
|
185
190
|
manager = MasterWalletManager(
|
|
186
191
|
path=self._path / "wallets",
|
|
187
192
|
password=self.password,
|
|
193
|
+
logger=self.logger,
|
|
188
194
|
)
|
|
189
195
|
manager.setup()
|
|
190
196
|
return manager
|
|
@@ -195,6 +201,7 @@ class OperateApp:
|
|
|
195
201
|
manager = BridgeManager(
|
|
196
202
|
path=self._path / "bridge",
|
|
197
203
|
wallet_manager=self.wallet_manager,
|
|
204
|
+
logger=self.logger,
|
|
198
205
|
)
|
|
199
206
|
return manager
|
|
200
207
|
|
|
@@ -230,26 +237,16 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
230
237
|
logger.warning("Healthchecker is off!!!")
|
|
231
238
|
operate = OperateApp(home=home, logger=logger)
|
|
232
239
|
|
|
233
|
-
operate.service_manager().log_directories()
|
|
234
|
-
logger.info("Migrating service configs...")
|
|
235
|
-
operate.service_manager().migrate_service_configs()
|
|
236
|
-
logger.info("Migrating service configs done.")
|
|
237
|
-
operate.service_manager().log_directories()
|
|
238
|
-
|
|
239
|
-
logger.info("Migrating wallet configs...")
|
|
240
|
-
operate.wallet_manager.migrate_wallet_configs()
|
|
241
|
-
logger.info("Migrating wallet configs done.")
|
|
242
|
-
|
|
243
240
|
funding_jobs: t.Dict[str, asyncio.Task] = {}
|
|
244
241
|
health_checker = HealthChecker(
|
|
245
|
-
operate.service_manager(), number_of_fails=number_of_fails
|
|
242
|
+
operate.service_manager(), number_of_fails=number_of_fails, logger=logger
|
|
246
243
|
)
|
|
247
244
|
# Create shutdown endpoint
|
|
248
245
|
shutdown_endpoint = uuid.uuid4().hex
|
|
249
246
|
(operate._path / "operate.kill").write_text( # pylint: disable=protected-access
|
|
250
247
|
shutdown_endpoint
|
|
251
248
|
)
|
|
252
|
-
thread_pool_executor = ThreadPoolExecutor()
|
|
249
|
+
thread_pool_executor = ThreadPoolExecutor(max_workers=12)
|
|
253
250
|
|
|
254
251
|
async def run_in_executor(fn: t.Callable, *args: t.Any) -> t.Any:
|
|
255
252
|
loop = asyncio.get_event_loop()
|
|
@@ -301,6 +298,12 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
301
298
|
logger.info("Stopping services on startup done.")
|
|
302
299
|
|
|
303
300
|
def pause_all_services() -> None:
|
|
301
|
+
service_manager = operate.service_manager()
|
|
302
|
+
if not service_manager.validate_services():
|
|
303
|
+
logger.error(
|
|
304
|
+
"Some services are not valid. Only pausing the valid services."
|
|
305
|
+
)
|
|
306
|
+
|
|
304
307
|
service_config_ids = [
|
|
305
308
|
i["service_config_id"] for i in operate.service_manager().json
|
|
306
309
|
]
|
|
@@ -319,7 +322,12 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
319
322
|
if deployment.status == DeploymentStatus.DELETED:
|
|
320
323
|
continue
|
|
321
324
|
logger.info(f"stopping service {service_config_id}")
|
|
322
|
-
|
|
325
|
+
try:
|
|
326
|
+
deployment.stop(force=True)
|
|
327
|
+
except Exception: # pylint: disable=broad-except
|
|
328
|
+
logger.exception(
|
|
329
|
+
f"Deployment {service_config_id} stopping failed. but continue"
|
|
330
|
+
)
|
|
323
331
|
logger.info(f"Cancelling funding job for {service_config_id}")
|
|
324
332
|
cancel_funding_job(service_config_id=service_config_id)
|
|
325
333
|
health_checker.stop_for_service(service_config_id=service_config_id)
|
|
@@ -338,7 +346,51 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
338
346
|
# stop all services at middleware exit
|
|
339
347
|
atexit.register(pause_all_services)
|
|
340
348
|
|
|
341
|
-
|
|
349
|
+
@asynccontextmanager
|
|
350
|
+
async def lifespan(app: FastAPI):
|
|
351
|
+
# Load the ML model
|
|
352
|
+
watchdog_task = set_parent_watchdog(app)
|
|
353
|
+
yield
|
|
354
|
+
# Clean up the ML models and release the resources
|
|
355
|
+
|
|
356
|
+
with suppress(Exception):
|
|
357
|
+
watchdog_task.cancel()
|
|
358
|
+
|
|
359
|
+
with suppress(Exception):
|
|
360
|
+
await watchdog_task
|
|
361
|
+
|
|
362
|
+
app = FastAPI(lifespan=lifespan)
|
|
363
|
+
|
|
364
|
+
def set_parent_watchdog(app):
|
|
365
|
+
async def stop_app():
|
|
366
|
+
logger.info("Stopping services on demand...")
|
|
367
|
+
|
|
368
|
+
stop_deployment_manager() # TODO: make it async?
|
|
369
|
+
await run_in_executor(pause_all_services)
|
|
370
|
+
|
|
371
|
+
logger.info("Stopping services on demand done.")
|
|
372
|
+
app._server.should_exit = True # pylint: disable=protected-access
|
|
373
|
+
logger.info("Stopping app.")
|
|
374
|
+
|
|
375
|
+
async def check_parent_alive():
|
|
376
|
+
try:
|
|
377
|
+
logger.info(
|
|
378
|
+
f"Parent alive check task started: ppid is {os.getppid()} and own pid is {os.getpid()}"
|
|
379
|
+
)
|
|
380
|
+
while True:
|
|
381
|
+
parent = psutil.Process(os.getpid()).parent()
|
|
382
|
+
if not parent:
|
|
383
|
+
logger.info("Parent is not alive, going to stop")
|
|
384
|
+
await stop_app()
|
|
385
|
+
return
|
|
386
|
+
await asyncio.sleep(3)
|
|
387
|
+
|
|
388
|
+
except Exception: # pylint: disable=broad-except
|
|
389
|
+
logger.exception("Parent alive check crashed!")
|
|
390
|
+
|
|
391
|
+
loop = asyncio.get_running_loop()
|
|
392
|
+
task = loop.create_task(check_parent_alive())
|
|
393
|
+
return task
|
|
342
394
|
|
|
343
395
|
app.add_middleware(
|
|
344
396
|
CORSMiddleware,
|
|
@@ -382,16 +434,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
382
434
|
async def _kill_server(request: Request) -> JSONResponse:
|
|
383
435
|
"""Kill backend server from inside."""
|
|
384
436
|
os.kill(os.getpid(), signal.SIGINT)
|
|
437
|
+
return JSONResponse(content={})
|
|
385
438
|
|
|
386
439
|
@app.get("/shutdown")
|
|
387
440
|
async def _shutdown(request: Request) -> JSONResponse:
|
|
388
441
|
"""Kill backend server from inside."""
|
|
389
442
|
logger.info("Stopping services on demand...")
|
|
390
|
-
pause_all_services
|
|
443
|
+
await run_in_executor(pause_all_services)
|
|
391
444
|
logger.info("Stopping services on demand done.")
|
|
392
445
|
app._server.should_exit = True # pylint: disable=protected-access
|
|
393
446
|
await asyncio.sleep(0.3)
|
|
394
|
-
return {"stopped": True}
|
|
447
|
+
return JSONResponse(content={"stopped": True})
|
|
395
448
|
|
|
396
449
|
@app.get("/api")
|
|
397
450
|
@with_retries
|
|
@@ -777,6 +830,21 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
777
830
|
"""Get all services."""
|
|
778
831
|
return JSONResponse(content=operate.service_manager().json)
|
|
779
832
|
|
|
833
|
+
@app.get("/api/v2/services/validate")
|
|
834
|
+
@with_retries
|
|
835
|
+
async def _validate_services(request: Request) -> JSONResponse:
|
|
836
|
+
"""Validate all services."""
|
|
837
|
+
service_manager = operate.service_manager()
|
|
838
|
+
service_ids = service_manager.get_all_service_ids()
|
|
839
|
+
_services = [
|
|
840
|
+
service.service_config_id
|
|
841
|
+
for service in service_manager.get_all_services()[0]
|
|
842
|
+
]
|
|
843
|
+
|
|
844
|
+
return JSONResponse(
|
|
845
|
+
content={service_id: service_id in _services for service_id in service_ids}
|
|
846
|
+
)
|
|
847
|
+
|
|
780
848
|
@app.get("/api/v2/service/{service_config_id}")
|
|
781
849
|
@with_retries
|
|
782
850
|
async def _get_service(request: Request) -> JSONResponse:
|
|
@@ -954,38 +1022,40 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
954
1022
|
service = service_manager.load(service_config_id=service_config_id)
|
|
955
1023
|
|
|
956
1024
|
# terminate the service on chain
|
|
957
|
-
for chain in service.chain_configs:
|
|
1025
|
+
for chain, chain_config in service.chain_configs.items():
|
|
958
1026
|
service_manager.terminate_service_on_chain_from_safe(
|
|
959
1027
|
service_config_id=service_config_id,
|
|
960
1028
|
chain=chain,
|
|
961
1029
|
withdrawal_address=withdrawal_address,
|
|
962
1030
|
)
|
|
963
1031
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1032
|
+
# drain the master safe and master signer for the home chain
|
|
1033
|
+
chain = Chain(service.home_chain)
|
|
1034
|
+
master_wallet = service_manager.wallet_manager.load(
|
|
1035
|
+
ledger_type=chain.ledger_type
|
|
1036
|
+
)
|
|
969
1037
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1038
|
+
# drain the master safe
|
|
1039
|
+
logger.info(
|
|
1040
|
+
f"Draining the Master Safe {master_wallet.safes[chain]} on chain {chain.value} (withdrawal address {withdrawal_address})."
|
|
1041
|
+
)
|
|
1042
|
+
master_wallet.drain(
|
|
1043
|
+
withdrawal_address=withdrawal_address,
|
|
1044
|
+
chain=chain,
|
|
1045
|
+
from_safe=True,
|
|
1046
|
+
rpc=chain_config.ledger_config.rpc,
|
|
1047
|
+
)
|
|
979
1048
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1049
|
+
# drain the master signer
|
|
1050
|
+
logger.info(
|
|
1051
|
+
f"Draining the Master Signer {master_wallet.address} on chain {chain.value} (withdrawal address {withdrawal_address})."
|
|
1052
|
+
)
|
|
1053
|
+
master_wallet.drain(
|
|
1054
|
+
withdrawal_address=withdrawal_address,
|
|
1055
|
+
chain=chain,
|
|
1056
|
+
from_safe=False,
|
|
1057
|
+
rpc=chain_config.ledger_config.rpc,
|
|
1058
|
+
)
|
|
989
1059
|
except Exception as e: # pylint: disable=broad-except
|
|
990
1060
|
logger.error(f"Withdrawal failed: {e}\n{traceback.format_exc()}")
|
|
991
1061
|
return JSONResponse(
|
|
@@ -1136,6 +1206,16 @@ def _daemon(
|
|
|
1136
1206
|
}
|
|
1137
1207
|
)
|
|
1138
1208
|
|
|
1209
|
+
# try automatically shutdown previous instance
|
|
1210
|
+
if TRY_TO_SHUTDOWN_PREVIOUS_INSTANCE:
|
|
1211
|
+
url = f"http{'s' if ssl_keyfile and ssl_certfile else ''}://{host}:{port}/shutdown"
|
|
1212
|
+
logger.info(f"trying to stop previous instance with {url}")
|
|
1213
|
+
try:
|
|
1214
|
+
requests.get(url, timeout=3, verify=False) # nosec
|
|
1215
|
+
logger.info("previous instance stopped")
|
|
1216
|
+
except Exception: # pylint: disable=broad-except
|
|
1217
|
+
logger.exception("failed to stop previous instance. probably not running")
|
|
1218
|
+
|
|
1139
1219
|
server = Server(Config(**config_kwargs))
|
|
1140
1220
|
app._server = server # pylint: disable=protected-access
|
|
1141
1221
|
server.run()
|
|
@@ -24,16 +24,11 @@ from pathlib import Path
|
|
|
24
24
|
|
|
25
25
|
OPERATE = ".operate"
|
|
26
26
|
OPERATE_HOME = Path.cwd() / OPERATE
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
DEPLOYMENT = "deployment"
|
|
27
|
+
SERVICES_DIR = "services"
|
|
28
|
+
KEYS_DIR = "keys"
|
|
29
|
+
DEPLOYMENT_DIR = "deployment"
|
|
31
30
|
DEPLOYMENT_JSON = "deployment.json"
|
|
32
|
-
|
|
33
|
-
KEY = "key"
|
|
34
|
-
KEYS_JSON = "keys.json"
|
|
35
|
-
DOCKER_COMPOSE_YAML = "docker-compose.yaml"
|
|
36
|
-
SERVICE_YAML = "service.yaml"
|
|
31
|
+
CONFIG_JSON = "config.json"
|
|
37
32
|
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
|
|
38
33
|
|
|
39
34
|
ON_CHAIN_INTERACT_TIMEOUT = 120.0
|
|
@@ -53,3 +48,8 @@ MECH_ACTIVITY_CHECKER_JSON_URL = "https://raw.githubusercontent.com/valory-xyz/a
|
|
|
53
48
|
SERVICE_REGISTRY_TOKEN_UTILITY_JSON_URL = "https://raw.githubusercontent.com/valory-xyz/open-autonomy/refs/tags/v0.18.4/packages/valory/contracts/service_registry_token_utility/build/ServiceRegistryTokenUtility.json" # nosec
|
|
54
49
|
MECH_AGENT_FACTORY_JSON_URL = "https://raw.githubusercontent.com/valory-xyz/ai-registry-mech/main/abis/0.8.25/AgentFactory.json"
|
|
55
50
|
MECH_MARKETPLACE_JSON_URL = "https://raw.githubusercontent.com/valory-xyz/mech-quickstart/refs/heads/main/contracts/MechMarketplace.json"
|
|
51
|
+
NO_STAKING_PROGRAM_ID = "no_staking"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
DEPLOYMENT_START_TRIES_NUM = 3
|
|
55
|
+
IPFS_CHECK_URL = "https://gateway.autonolas.tech/ipfs/bafybeigcllaxn4ycjjvika3zd6eicksuriez2wtg67gx7pamhcazl3tv54/echo/README.md"
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"""Keys manager."""
|
|
21
21
|
|
|
22
22
|
import json
|
|
23
|
-
import logging
|
|
24
23
|
import os
|
|
25
24
|
import shutil
|
|
26
|
-
import
|
|
25
|
+
import tempfile
|
|
27
26
|
from dataclasses import dataclass
|
|
28
27
|
from pathlib import Path
|
|
28
|
+
from typing import Any
|
|
29
29
|
|
|
30
|
-
from aea.helpers.logging import setup_logger
|
|
31
30
|
from aea_ledger_ethereum.ethereum import EthereumCrypto
|
|
32
31
|
|
|
33
32
|
from operate.operate_types import LedgerType
|
|
34
33
|
from operate.resource import LocalResource
|
|
34
|
+
from operate.utils import SingletonMeta
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
@dataclass
|
|
@@ -48,25 +48,21 @@ class Key(LocalResource):
|
|
|
48
48
|
return super().load(path) # type: ignore
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class KeysManager:
|
|
51
|
+
class KeysManager(metaclass=SingletonMeta):
|
|
55
52
|
"""Keys manager."""
|
|
56
53
|
|
|
57
|
-
def __init__(
|
|
58
|
-
self,
|
|
59
|
-
path: Path,
|
|
60
|
-
logger: t.Optional[logging.Logger] = None,
|
|
61
|
-
) -> None:
|
|
54
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
62
55
|
"""
|
|
63
56
|
Initialize keys manager
|
|
64
57
|
|
|
65
58
|
:param path: Path to keys storage.
|
|
66
59
|
:param logger: logging.Logger object.
|
|
67
60
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
if "path" not in kwargs:
|
|
62
|
+
raise ValueError("Path must be provided for KeysManager")
|
|
63
|
+
|
|
64
|
+
self.path = kwargs["path"]
|
|
65
|
+
self.logger = kwargs["logger"]
|
|
70
66
|
|
|
71
67
|
def setup(self) -> None:
|
|
72
68
|
"""Setup service manager."""
|
|
@@ -83,6 +79,22 @@ class KeysManager:
|
|
|
83
79
|
)
|
|
84
80
|
)
|
|
85
81
|
|
|
82
|
+
def get_crypto_instance(self, address: str) -> EthereumCrypto:
|
|
83
|
+
"""Get EthereumCrypto instance for the given address."""
|
|
84
|
+
key: Key = Key.from_json( # type: ignore
|
|
85
|
+
obj=json.loads(
|
|
86
|
+
(self.path / address).read_text(
|
|
87
|
+
encoding="utf-8",
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as temp_file:
|
|
92
|
+
temp_file.write(key.private_key)
|
|
93
|
+
temp_file.flush()
|
|
94
|
+
crypto = EthereumCrypto(private_key_path=temp_file.name)
|
|
95
|
+
|
|
96
|
+
return crypto
|
|
97
|
+
|
|
86
98
|
def create(self) -> str:
|
|
87
99
|
"""Creates new key."""
|
|
88
100
|
crypto = EthereumCrypto()
|
|
@@ -46,7 +46,7 @@ PUBLIC_RPCS = {
|
|
|
46
46
|
Chain.SOLANA: SOLANA_PUBLIC_RPC,
|
|
47
47
|
Chain.BASE: BASE_PUBLIC_RPC,
|
|
48
48
|
Chain.CELO: CELO_PUBLIC_RPC,
|
|
49
|
-
Chain.
|
|
49
|
+
Chain.OPTIMISM: OPTIMISM_PUBLIC_RPC,
|
|
50
50
|
Chain.MODE: MODE_PUBLIC_RPC,
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -56,7 +56,7 @@ DEFAULT_RPCS = {
|
|
|
56
56
|
Chain.SOLANA: SOLANA_RPC,
|
|
57
57
|
Chain.BASE: BASE_RPC,
|
|
58
58
|
Chain.CELO: CELO_RPC,
|
|
59
|
-
Chain.
|
|
59
|
+
Chain.OPTIMISM: OPTIMISM_RPC,
|
|
60
60
|
Chain.MODE: MODE_RPC,
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -67,7 +67,7 @@ CURRENCY_DENOMS = {
|
|
|
67
67
|
Chain.SOLANA: "SOL",
|
|
68
68
|
Chain.BASE: "ETH",
|
|
69
69
|
Chain.CELO: "CELO",
|
|
70
|
-
Chain.
|
|
70
|
+
Chain.OPTIMISM: "ETH",
|
|
71
71
|
Chain.MODE: "ETH",
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -78,7 +78,7 @@ CURRENCY_SMALLEST_UNITS = {
|
|
|
78
78
|
Chain.SOLANA: "Lamport",
|
|
79
79
|
Chain.BASE: "Wei",
|
|
80
80
|
Chain.CELO: "Wei",
|
|
81
|
-
Chain.
|
|
81
|
+
Chain.OPTIMISM: "Wei",
|
|
82
82
|
Chain.MODE: "Wei",
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -21,12 +21,10 @@
|
|
|
21
21
|
|
|
22
22
|
import typing as t
|
|
23
23
|
|
|
24
|
-
from operate.constants import ZERO_ADDRESS
|
|
24
|
+
from operate.constants import NO_STAKING_PROGRAM_ID, ZERO_ADDRESS
|
|
25
25
|
from operate.operate_types import Chain, ContractAddresses
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
NO_STAKING_PROGRAM_ID = "no_staking"
|
|
29
|
-
|
|
30
28
|
CONTRACTS: t.Dict[Chain, ContractAddresses] = {
|
|
31
29
|
Chain.GNOSIS: ContractAddresses(
|
|
32
30
|
{
|
|
@@ -38,7 +36,7 @@ CONTRACTS: t.Dict[Chain, ContractAddresses] = {
|
|
|
38
36
|
"multisend": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
39
37
|
}
|
|
40
38
|
),
|
|
41
|
-
Chain.
|
|
39
|
+
Chain.OPTIMISM: ContractAddresses(
|
|
42
40
|
{
|
|
43
41
|
"service_manager": "0xFbBEc0C8b13B38a9aC0499694A69a10204c5E2aB",
|
|
44
42
|
"service_registry": "0x3d77596beb0f130a4415df3D2D8232B3d3D31e44",
|
|
@@ -123,7 +121,7 @@ STAKING: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
123
121
|
"marketplace_demand_alpha_1": "0x9d6e7aB0B5B48aE5c146936147C639fEf4575231",
|
|
124
122
|
"marketplace_demand_alpha_2": "0x9fb17E549FefcCA630dd92Ea143703CeE4Ea4340",
|
|
125
123
|
},
|
|
126
|
-
Chain.
|
|
124
|
+
Chain.OPTIMISM: {
|
|
127
125
|
"optimus_alpha_1": "0x88996bbdE7f982D93214881756840cE2c77C4992",
|
|
128
126
|
"optimus_alpha_2": "0xBCA056952D2A7a8dD4A002079219807CFDF9fd29",
|
|
129
127
|
"optimus_alpha_3": "0x0f69f35652B1acdbD769049334f1AC580927E139",
|
|
@@ -170,7 +168,7 @@ DEFAULT_PRIORITY_MECH = { # maps mech marketplace address to its default priori
|
|
|
170
168
|
# ERC20 token addresses
|
|
171
169
|
OLAS: t.Dict[Chain, str] = {
|
|
172
170
|
Chain.GNOSIS: "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f",
|
|
173
|
-
Chain.
|
|
171
|
+
Chain.OPTIMISM: "0xFC2E6e6BCbd49ccf3A5f029c79984372DcBFE527",
|
|
174
172
|
Chain.BASE: "0x54330d28ca3357F294334BDC454a032e7f353416",
|
|
175
173
|
Chain.ETHEREUM: "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0",
|
|
176
174
|
Chain.MODE: "0xcfD1D50ce23C46D3Cf6407487B2F8934e96DC8f9",
|
|
@@ -178,7 +176,7 @@ OLAS: t.Dict[Chain, str] = {
|
|
|
178
176
|
|
|
179
177
|
USDC: t.Dict[Chain, str] = {
|
|
180
178
|
Chain.GNOSIS: "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83",
|
|
181
|
-
Chain.
|
|
179
|
+
Chain.OPTIMISM: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
|
|
182
180
|
Chain.BASE: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
183
181
|
Chain.ETHEREUM: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
184
182
|
Chain.MODE: "0xd988097fb8612cc24eeC14542bC03424c656005f",
|
|
@@ -186,7 +184,7 @@ USDC: t.Dict[Chain, str] = {
|
|
|
186
184
|
|
|
187
185
|
WRAPPED_NATIVE_ASSET = {
|
|
188
186
|
Chain.GNOSIS: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d",
|
|
189
|
-
Chain.
|
|
187
|
+
Chain.OPTIMISM: "0x4200000000000000000000000000000000000006",
|
|
190
188
|
Chain.BASE: "0x4200000000000000000000000000000000000006",
|
|
191
189
|
Chain.ETHEREUM: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
192
190
|
Chain.MODE: "0x4200000000000000000000000000000000000006",
|
|
@@ -209,7 +207,7 @@ DEFAULT_NEW_SAFE_FUNDS: t.Dict[Chain, t.Dict[str, int]] = {
|
|
|
209
207
|
Chain.MODE: {
|
|
210
208
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
211
209
|
},
|
|
212
|
-
Chain.
|
|
210
|
+
Chain.OPTIMISM: {
|
|
213
211
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
214
212
|
},
|
|
215
213
|
}
|
|
@@ -219,7 +217,7 @@ DEFAULT_MASTER_EOA_FUNDS = {
|
|
|
219
217
|
Chain.ETHEREUM: {ZERO_ADDRESS: 20_000_000_000_000_000},
|
|
220
218
|
Chain.GNOSIS: {ZERO_ADDRESS: 1_500_000_000_000_000_000},
|
|
221
219
|
Chain.MODE: {ZERO_ADDRESS: 500_000_000_000_000},
|
|
222
|
-
Chain.
|
|
220
|
+
Chain.OPTIMISM: {ZERO_ADDRESS: 5_000_000_000_000_000},
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
EXPLORER_URL = {
|
|
@@ -239,7 +237,7 @@ EXPLORER_URL = {
|
|
|
239
237
|
"tx": "https://modescan.io/tx/{tx_hash}",
|
|
240
238
|
"address": "https://modescan.io/address/{address}",
|
|
241
239
|
},
|
|
242
|
-
Chain.
|
|
240
|
+
Chain.OPTIMISM: {
|
|
243
241
|
"tx": "https://optimistic.etherscan.io/tx/{tx_hash}",
|
|
244
242
|
"address": "https://optimistic.etherscan.io/address/{address}",
|
|
245
243
|
},
|