olas-operate-middleware 0.8.1__py3-none-any.whl → 0.9.0__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.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/METADATA +2 -2
- {olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/RECORD +28 -28
- operate/bridge/bridge_manager.py +3 -3
- operate/bridge/providers/provider.py +2 -2
- operate/bridge/providers/relay_provider.py +1 -1
- operate/cli.py +6 -6
- operate/constants.py +4 -9
- operate/ledger/__init__.py +4 -4
- operate/ledger/profiles.py +8 -8
- operate/migration.py +59 -0
- operate/operate_types.py +0 -21
- operate/quickstart/analyse_logs.py +2 -2
- operate/quickstart/claim_staking_rewards.py +1 -1
- operate/quickstart/reset_staking.py +1 -1
- operate/quickstart/run_service.py +2 -2
- operate/quickstart/stop_service.py +3 -1
- operate/quickstart/terminate_on_chain_service.py +1 -1
- operate/quickstart/utils.py +4 -7
- operate/resource.py +37 -5
- operate/services/health_checker.py +2 -6
- operate/services/manage.py +13 -41
- operate/services/protocol.py +5 -5
- operate/services/service.py +43 -33
- operate/utils/gnosis.py +4 -5
- operate/wallet/master.py +4 -4
- {olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/LICENSE +0 -0
- {olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/entry_points.txt +0 -0
{olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: olas-operate-middleware
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.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)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
operate/__init__.py,sha256=ZQhHXOo_1L9Q5Ub_2FrZ-vu3BvORBrKgK8QcJyAsYa4,870
|
|
2
2
|
operate/account/__init__.py,sha256=suJ_vBMO7hLCvLYe3MVDtLXTNDd6P03og7bvUN7fZsE,804
|
|
3
3
|
operate/account/user.py,sha256=y7DqqDpqgHjbVmnfL_cN0Me_JWl3Dh6GSVt2-9FdRVw,3044
|
|
4
|
-
operate/bridge/bridge_manager.py,sha256=
|
|
4
|
+
operate/bridge/bridge_manager.py,sha256=n6dZoG-mtegES_EqVraSW1LHhPPZ1Idhm2v7lrBMbJo,17236
|
|
5
5
|
operate/bridge/providers/lifi_provider.py,sha256=FpAlBAA_gOt-oOHKhGaOQhhTZIL-hgYYo4IIw1FN7mo,14153
|
|
6
6
|
operate/bridge/providers/native_bridge_provider.py,sha256=ZTLBdh9ttPWpX8IYvHyVU5y3pg1B1DG_vQ9DHVquDfw,24666
|
|
7
|
-
operate/bridge/providers/provider.py,sha256=
|
|
8
|
-
operate/bridge/providers/relay_provider.py,sha256=
|
|
9
|
-
operate/cli.py,sha256=
|
|
10
|
-
operate/constants.py,sha256=
|
|
7
|
+
operate/bridge/providers/provider.py,sha256=YGvTqp2wNgw4E35Gov8vidwbNcoaCmEOuFn20FK-QgI,19809
|
|
8
|
+
operate/bridge/providers/relay_provider.py,sha256=qfFiD655qZ9MK7duwOTRYCVTv1mD8u-XbqmcJMlm_ls,16748
|
|
9
|
+
operate/cli.py,sha256=H6Y3ewfE_96WyV8ldXJ9C9r1LrbXEUNyVVSZFptwHzY,47886
|
|
10
|
+
operate/constants.py,sha256=CWH2pw8YzCbl44HzbvKSaAAWgNB2-5yUgUP1VmlyNm8,2546
|
|
11
11
|
operate/data/README.md,sha256=jGPyZTvg2LCGdllvmYxmFMkkkiXb6YWatbqIkcX3kv4,879
|
|
12
12
|
operate/data/__init__.py,sha256=ttC51Yqk9c4ehpIgs1Qbe7aJvzkrbbdZ1ClaCxJYByE,864
|
|
13
13
|
operate/data/contracts/__init__.py,sha256=_th54_WvL0ibGy-b6St0Ne9DX-fyjsh-tNOKDn-cWrg,809
|
|
@@ -54,40 +54,40 @@ operate/data/contracts/uniswap_v2_erc20/contract.yaml,sha256=XUdz-XtKtmZgLfItbO8
|
|
|
54
54
|
operate/data/contracts/uniswap_v2_erc20/tests/__init__.py,sha256=3Arw8dsCsJz6hVOl0t9UjFASHXbV9yp3hw6x4HqgXpU,847
|
|
55
55
|
operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py,sha256=FzZbw9OTcr_yvjOXpk9YcO-K40eyDARyybcfSHDg2Ps,13392
|
|
56
56
|
operate/keys.py,sha256=soJfdXJvHo8ytWH6ShIndjUpkShPg3KzirLs7MoFe8I,3764
|
|
57
|
-
operate/ledger/__init__.py,sha256=
|
|
58
|
-
operate/ledger/profiles.py,sha256=
|
|
59
|
-
operate/migration.py,sha256=
|
|
57
|
+
operate/ledger/__init__.py,sha256=ksyctDd5PU_SToN9e-_N9fAap9ZNCHw48j5hHep-erA,3353
|
|
58
|
+
operate/ledger/profiles.py,sha256=Mvz2D-qoXmLzM0lBmPJGLmyNfrtXPdg_QjUeVfxLRBA,12358
|
|
59
|
+
operate/migration.py,sha256=yeNI6OZwuvJcnqdRTrRNMutyo9mj2gb0vRW0hTV9EFU,3659
|
|
60
60
|
operate/operate_http/__init__.py,sha256=dxCIVSUos23M4R-PFZZG6k5QrOlEiK0SxhCYSFNxh7U,4711
|
|
61
61
|
operate/operate_http/exceptions.py,sha256=4UFzrn-GyDD71RhkaOyFPBynL6TrrtP3eywaaU3o4fc,1339
|
|
62
|
-
operate/operate_types.py,sha256=
|
|
62
|
+
operate/operate_types.py,sha256=x4OHOGNFCRctTdGsq7WS_d5CzQ5Lfg75qHkfgaUOivc,7895
|
|
63
63
|
operate/pearl.py,sha256=yrTpSXLu_ML3qT-uNxq3kScOyo31JyxBujiSMfMUbcg,1690
|
|
64
|
-
operate/quickstart/analyse_logs.py,sha256=
|
|
65
|
-
operate/quickstart/claim_staking_rewards.py,sha256=
|
|
64
|
+
operate/quickstart/analyse_logs.py,sha256=ss9BdhNs2Yo_A5NUuXpfki_j-u53YklxidBecfDQJ1k,4305
|
|
65
|
+
operate/quickstart/claim_staking_rewards.py,sha256=i9vwUGFiFBlPMZHsRYbXj-lkf4fUpBotLQuFcQAPGyI,4135
|
|
66
66
|
operate/quickstart/reset_configs.py,sha256=t-gVt0_-Th-LADfVmjxxKXjE2if5w-MuEscGFyMw2u0,3450
|
|
67
67
|
operate/quickstart/reset_password.py,sha256=_HHnwX032WKNja5koegQIy4By0rFXGcdQRgVlusf5GA,2644
|
|
68
|
-
operate/quickstart/reset_staking.py,sha256=
|
|
69
|
-
operate/quickstart/run_service.py,sha256=
|
|
70
|
-
operate/quickstart/stop_service.py,sha256=
|
|
71
|
-
operate/quickstart/terminate_on_chain_service.py,sha256=
|
|
72
|
-
operate/quickstart/utils.py,sha256=
|
|
73
|
-
operate/resource.py,sha256=
|
|
68
|
+
operate/quickstart/reset_staking.py,sha256=yb293RdnVRWvFlglaG_DnMCBMY0lPKMzhpOdbXKjdvY,5157
|
|
69
|
+
operate/quickstart/run_service.py,sha256=16mw9oUR5Vx-Q5jwLvxs3eyl9fGrWqf1mOX8dwI9u30,27334
|
|
70
|
+
operate/quickstart/stop_service.py,sha256=V-0htRKo_P8zdI7Vk2FJEWmez8GDLbyAHKF1hREr_BI,2145
|
|
71
|
+
operate/quickstart/terminate_on_chain_service.py,sha256=X96p-0dCS-cDEduQnIboOLWaSjdvDU2ec_21nNkxJSk,3023
|
|
72
|
+
operate/quickstart/utils.py,sha256=rmd9e7whQIsYpRKqWBEQxMA_SHrivBg6DppFY5ECtQQ,9135
|
|
73
|
+
operate/resource.py,sha256=E59oIVqf6B6nN4LTmf_o2iCgLFAogTLPjm_cK6kMVxg,6305
|
|
74
74
|
operate/services/__init__.py,sha256=isrThS-Ccu5Sc15JZgkN4uTAVaSg-NwUUSDeTyJEqLk,855
|
|
75
75
|
operate/services/agent_runner.py,sha256=6tJePUJmlRxlIugT2fDaCJHSrQlDnl1t9pbg3-7EmCQ,7560
|
|
76
76
|
operate/services/deployment_runner.py,sha256=eP1bnT3PdkYtPxi-4sZ6-Wopz8u88NkeZx7vOB2vkzc,22217
|
|
77
|
-
operate/services/health_checker.py,sha256=
|
|
78
|
-
operate/services/manage.py,sha256=
|
|
79
|
-
operate/services/protocol.py,sha256=
|
|
80
|
-
operate/services/service.py,sha256=
|
|
77
|
+
operate/services/health_checker.py,sha256=bMmEHOUpVgKea9zocOBQdzw154XGztZ-hWB_8HkQoCI,9689
|
|
78
|
+
operate/services/manage.py,sha256=uc9hA3GQ5_Uny6yUv_2jaVYhV4SwqT2YrkOl4h7XNNc,109537
|
|
79
|
+
operate/services/protocol.py,sha256=RQssnJyjHc0k1CyZCj3jxHueyJyS3nmFYw4dVQaKXzA,60157
|
|
80
|
+
operate/services/service.py,sha256=hwc_gTqMig5C-9lNI2EwjNdp0BASTCmb466VhTmJlQg,48809
|
|
81
81
|
operate/services/utils/__init__.py,sha256=TvioaZ1mfTRUSCtrQoLNAp4WMVXyqEJqFJM4PxSQCRU,24
|
|
82
82
|
operate/services/utils/mech.py,sha256=W2x4dqodivNKXjWU-Brp40QhoUHsIMyNAO7-caMoR0Q,3821
|
|
83
83
|
operate/services/utils/tendermint.py,sha256=3h9nDb2Z89T0RwUr_AaVjqtymQmsu3u6DAVCfL_k1U0,25591
|
|
84
84
|
operate/utils/__init__.py,sha256=cFNP2XFpjJmDLskN0SzAk5FPdqaeN2Jn4MyVbFHmH2M,3075
|
|
85
|
-
operate/utils/gnosis.py,sha256=
|
|
85
|
+
operate/utils/gnosis.py,sha256=OxWq5zMW0fuShLZS6JAOlgB_TEsNvsZECa6EfzC4_SY,17678
|
|
86
86
|
operate/utils/ssl.py,sha256=O5DrDoZD4T4qQuHP8GLwWUVxQ-1qXeefGp6uDJiF2lM,4308
|
|
87
87
|
operate/wallet/__init__.py,sha256=NGiozD3XhvkBi7_FaOWQ8x1thZPK4uGpokJaeDY_o2w,813
|
|
88
|
-
operate/wallet/master.py,sha256=
|
|
89
|
-
olas_operate_middleware-0.
|
|
90
|
-
olas_operate_middleware-0.
|
|
91
|
-
olas_operate_middleware-0.
|
|
92
|
-
olas_operate_middleware-0.
|
|
93
|
-
olas_operate_middleware-0.
|
|
88
|
+
operate/wallet/master.py,sha256=lKtTHi278UWuATGSM3c2VdWHUEYg8pmvw7VzxGZ8u9I,31003
|
|
89
|
+
olas_operate_middleware-0.9.0.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
|
|
90
|
+
olas_operate_middleware-0.9.0.dist-info/METADATA,sha256=sFzHUFX9CCvAfzVtbZi00_IWsF-MxVQS5xPuhIcZmeQ,2033
|
|
91
|
+
olas_operate_middleware-0.9.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
92
|
+
olas_operate_middleware-0.9.0.dist-info/entry_points.txt,sha256=dM1g2I7ODApKQFcgl5J4NGA7pfBTo6qsUTXM-j2OLlw,44
|
|
93
|
+
olas_operate_middleware-0.9.0.dist-info/RECORD,,
|
operate/bridge/bridge_manager.py
CHANGED
|
@@ -77,7 +77,7 @@ NATIVE_BRIDGE_PROVIDER_CONFIGS: t.Dict[str, t.Any] = {
|
|
|
77
77
|
"native-ethereum-to-optimism": {
|
|
78
78
|
"from_chain": "ethereum",
|
|
79
79
|
"from_bridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1",
|
|
80
|
-
"to_chain": "
|
|
80
|
+
"to_chain": "optimism",
|
|
81
81
|
"to_bridge": "0x4200000000000000000000000000000000000010",
|
|
82
82
|
"bridge_eta": 300,
|
|
83
83
|
"bridge_contract_adaptor_class": OptimismContractAdaptor,
|
|
@@ -97,8 +97,8 @@ ROUTES = {
|
|
|
97
97
|
(
|
|
98
98
|
Chain.ETHEREUM, # from_chain
|
|
99
99
|
USDC[Chain.ETHEREUM], # from_token
|
|
100
|
-
Chain.
|
|
101
|
-
USDC[Chain.
|
|
100
|
+
Chain.OPTIMISM, # to_chain
|
|
101
|
+
USDC[Chain.OPTIMISM], # to_token
|
|
102
102
|
): LIFI_PROVIDER_ID,
|
|
103
103
|
(
|
|
104
104
|
Chain.ETHEREUM, # from_chain
|
|
@@ -231,7 +231,7 @@ class Provider(ABC):
|
|
|
231
231
|
ledger_api = wallet.ledger_api(chain)
|
|
232
232
|
|
|
233
233
|
# TODO: Backport to open aea/autonomy
|
|
234
|
-
if chain == Chain.
|
|
234
|
+
if chain == Chain.OPTIMISM:
|
|
235
235
|
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
236
236
|
|
|
237
237
|
return ledger_api
|
|
@@ -244,7 +244,7 @@ class Provider(ABC):
|
|
|
244
244
|
ledger_api = wallet.ledger_api(chain)
|
|
245
245
|
|
|
246
246
|
# TODO: Backport to open aea/autonomy
|
|
247
|
-
if chain == Chain.
|
|
247
|
+
if chain == Chain.OPTIMISM:
|
|
248
248
|
ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0)
|
|
249
249
|
|
|
250
250
|
return ledger_api
|
operate/cli.py
CHANGED
|
@@ -47,11 +47,10 @@ from operate import services
|
|
|
47
47
|
from operate.account.user import UserAccount
|
|
48
48
|
from operate.bridge.bridge_manager import BridgeManager
|
|
49
49
|
from operate.constants import (
|
|
50
|
-
|
|
51
|
-
KEYS,
|
|
50
|
+
KEYS_DIR,
|
|
52
51
|
MIN_PASSWORD_LENGTH,
|
|
53
52
|
OPERATE_HOME,
|
|
54
|
-
|
|
53
|
+
SERVICES_DIR,
|
|
55
54
|
ZERO_ADDRESS,
|
|
56
55
|
)
|
|
57
56
|
from operate.ledger.profiles import (
|
|
@@ -104,9 +103,8 @@ class OperateApp:
|
|
|
104
103
|
"""Initialize object."""
|
|
105
104
|
super().__init__()
|
|
106
105
|
self._path = (home or OPERATE_HOME).resolve()
|
|
107
|
-
self._services = self._path /
|
|
108
|
-
self._keys = self._path /
|
|
109
|
-
self._master_key = self._path / KEY
|
|
106
|
+
self._services = self._path / SERVICES_DIR
|
|
107
|
+
self._keys = self._path / KEYS_DIR
|
|
110
108
|
self.setup()
|
|
111
109
|
|
|
112
110
|
self.logger = logger or setup_logger(name="operate")
|
|
@@ -118,6 +116,8 @@ class OperateApp:
|
|
|
118
116
|
|
|
119
117
|
mm = MigrationManager(self._path, self.logger)
|
|
120
118
|
mm.migrate_user_account()
|
|
119
|
+
mm.migrate_wallets()
|
|
120
|
+
mm.migrate_qs_configs()
|
|
121
121
|
|
|
122
122
|
def create_user_account(self, password: str) -> UserAccount:
|
|
123
123
|
"""Create a user account."""
|
operate/constants.py
CHANGED
|
@@ -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
|
operate/ledger/__init__.py
CHANGED
|
@@ -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
|
|
operate/ledger/profiles.py
CHANGED
|
@@ -38,7 +38,7 @@ CONTRACTS: t.Dict[Chain, ContractAddresses] = {
|
|
|
38
38
|
"multisend": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
39
39
|
}
|
|
40
40
|
),
|
|
41
|
-
Chain.
|
|
41
|
+
Chain.OPTIMISM: ContractAddresses(
|
|
42
42
|
{
|
|
43
43
|
"service_manager": "0xFbBEc0C8b13B38a9aC0499694A69a10204c5E2aB",
|
|
44
44
|
"service_registry": "0x3d77596beb0f130a4415df3D2D8232B3d3D31e44",
|
|
@@ -123,7 +123,7 @@ STAKING: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
123
123
|
"marketplace_demand_alpha_1": "0x9d6e7aB0B5B48aE5c146936147C639fEf4575231",
|
|
124
124
|
"marketplace_demand_alpha_2": "0x9fb17E549FefcCA630dd92Ea143703CeE4Ea4340",
|
|
125
125
|
},
|
|
126
|
-
Chain.
|
|
126
|
+
Chain.OPTIMISM: {
|
|
127
127
|
"optimus_alpha_1": "0x88996bbdE7f982D93214881756840cE2c77C4992",
|
|
128
128
|
"optimus_alpha_2": "0xBCA056952D2A7a8dD4A002079219807CFDF9fd29",
|
|
129
129
|
"optimus_alpha_3": "0x0f69f35652B1acdbD769049334f1AC580927E139",
|
|
@@ -170,7 +170,7 @@ DEFAULT_PRIORITY_MECH = { # maps mech marketplace address to its default priori
|
|
|
170
170
|
# ERC20 token addresses
|
|
171
171
|
OLAS: t.Dict[Chain, str] = {
|
|
172
172
|
Chain.GNOSIS: "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f",
|
|
173
|
-
Chain.
|
|
173
|
+
Chain.OPTIMISM: "0xFC2E6e6BCbd49ccf3A5f029c79984372DcBFE527",
|
|
174
174
|
Chain.BASE: "0x54330d28ca3357F294334BDC454a032e7f353416",
|
|
175
175
|
Chain.ETHEREUM: "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0",
|
|
176
176
|
Chain.MODE: "0xcfD1D50ce23C46D3Cf6407487B2F8934e96DC8f9",
|
|
@@ -178,7 +178,7 @@ OLAS: t.Dict[Chain, str] = {
|
|
|
178
178
|
|
|
179
179
|
USDC: t.Dict[Chain, str] = {
|
|
180
180
|
Chain.GNOSIS: "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83",
|
|
181
|
-
Chain.
|
|
181
|
+
Chain.OPTIMISM: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
|
|
182
182
|
Chain.BASE: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
183
183
|
Chain.ETHEREUM: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
184
184
|
Chain.MODE: "0xd988097fb8612cc24eeC14542bC03424c656005f",
|
|
@@ -186,7 +186,7 @@ USDC: t.Dict[Chain, str] = {
|
|
|
186
186
|
|
|
187
187
|
WRAPPED_NATIVE_ASSET = {
|
|
188
188
|
Chain.GNOSIS: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d",
|
|
189
|
-
Chain.
|
|
189
|
+
Chain.OPTIMISM: "0x4200000000000000000000000000000000000006",
|
|
190
190
|
Chain.BASE: "0x4200000000000000000000000000000000000006",
|
|
191
191
|
Chain.ETHEREUM: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
192
192
|
Chain.MODE: "0x4200000000000000000000000000000000000006",
|
|
@@ -209,7 +209,7 @@ DEFAULT_NEW_SAFE_FUNDS: t.Dict[Chain, t.Dict[str, int]] = {
|
|
|
209
209
|
Chain.MODE: {
|
|
210
210
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
211
211
|
},
|
|
212
|
-
Chain.
|
|
212
|
+
Chain.OPTIMISM: {
|
|
213
213
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
214
214
|
},
|
|
215
215
|
}
|
|
@@ -219,7 +219,7 @@ DEFAULT_MASTER_EOA_FUNDS = {
|
|
|
219
219
|
Chain.ETHEREUM: {ZERO_ADDRESS: 20_000_000_000_000_000},
|
|
220
220
|
Chain.GNOSIS: {ZERO_ADDRESS: 1_500_000_000_000_000_000},
|
|
221
221
|
Chain.MODE: {ZERO_ADDRESS: 500_000_000_000_000},
|
|
222
|
-
Chain.
|
|
222
|
+
Chain.OPTIMISM: {ZERO_ADDRESS: 5_000_000_000_000_000},
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
EXPLORER_URL = {
|
|
@@ -239,7 +239,7 @@ EXPLORER_URL = {
|
|
|
239
239
|
"tx": "https://modescan.io/tx/{tx_hash}",
|
|
240
240
|
"address": "https://modescan.io/address/{address}",
|
|
241
241
|
},
|
|
242
|
-
Chain.
|
|
242
|
+
Chain.OPTIMISM: {
|
|
243
243
|
"tx": "https://optimistic.etherscan.io/tx/{tx_hash}",
|
|
244
244
|
"address": "https://optimistic.etherscan.io/address/{address}",
|
|
245
245
|
},
|
operate/migration.py
CHANGED
|
@@ -61,3 +61,62 @@ class MigrationManager:
|
|
|
61
61
|
json.dump(new_data, f, indent=4)
|
|
62
62
|
|
|
63
63
|
self.logger.info("[MIGRATION MANAGER] Migrated user.json.")
|
|
64
|
+
|
|
65
|
+
def migrate_wallets(self) -> None:
|
|
66
|
+
"""Migrates wallets."""
|
|
67
|
+
|
|
68
|
+
path = self._path / "wallets" / "ethereum.json"
|
|
69
|
+
if not path.exists():
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
migrated = False
|
|
73
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
74
|
+
data = json.load(f)
|
|
75
|
+
|
|
76
|
+
if "optimistic" in data.get("safes", {}):
|
|
77
|
+
data["safes"]["optimism"] = data["safes"].pop("optimistic")
|
|
78
|
+
migrated = True
|
|
79
|
+
|
|
80
|
+
if "optimistic" in data.get("safe_chains"):
|
|
81
|
+
data["safe_chains"] = [
|
|
82
|
+
"optimism" if chain == "optimistic" else chain
|
|
83
|
+
for chain in data["safe_chains"]
|
|
84
|
+
]
|
|
85
|
+
migrated = True
|
|
86
|
+
|
|
87
|
+
if not migrated:
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
91
|
+
json.dump(data, f, indent=4)
|
|
92
|
+
|
|
93
|
+
self.logger.info("[MIGRATION MANAGER] Migrated wallets.")
|
|
94
|
+
|
|
95
|
+
def migrate_qs_configs(self) -> None:
|
|
96
|
+
"""Migrates quickstart configs."""
|
|
97
|
+
|
|
98
|
+
for qs_config in self._path.glob("*-quickstart-config.json"):
|
|
99
|
+
if not qs_config.exists():
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
migrated = False
|
|
103
|
+
with open(qs_config, "r", encoding="utf-8") as f:
|
|
104
|
+
data = json.load(f)
|
|
105
|
+
|
|
106
|
+
if "optimistic" in data.get("rpc", {}):
|
|
107
|
+
data["rpc"]["optimism"] = data["rpc"].pop("optimistic")
|
|
108
|
+
migrated = True
|
|
109
|
+
|
|
110
|
+
if "optimistic" == data.get("principal_chain", ""):
|
|
111
|
+
data["principal_chain"] = "optimism"
|
|
112
|
+
migrated = True
|
|
113
|
+
|
|
114
|
+
if not migrated:
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
with open(qs_config, "w", encoding="utf-8") as f:
|
|
118
|
+
json.dump(data, f, indent=2)
|
|
119
|
+
|
|
120
|
+
self.logger.info(
|
|
121
|
+
"[MIGRATION MANAGER] Migrated quickstart config: %s.", qs_config.name
|
|
122
|
+
)
|
operate/operate_types.py
CHANGED
|
@@ -31,13 +31,6 @@ from typing_extensions import TypedDict
|
|
|
31
31
|
from operate.resource import LocalResource
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
_ACTIONS = {
|
|
35
|
-
"status": 0,
|
|
36
|
-
"build": 1,
|
|
37
|
-
"deploy": 2,
|
|
38
|
-
"stop": 3,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
34
|
CHAIN_NAME_TO_CHAIN_ID["solana"] = 900
|
|
42
35
|
|
|
43
36
|
_CHAIN_ID_TO_CHAIN_NAME = {
|
|
@@ -127,20 +120,6 @@ for name in dir(ChainMixin):
|
|
|
127
120
|
setattr(Chain, name, getattr(ChainMixin, name))
|
|
128
121
|
|
|
129
122
|
|
|
130
|
-
class Action(enum.IntEnum):
|
|
131
|
-
"""Action payload."""
|
|
132
|
-
|
|
133
|
-
STATUS = 0
|
|
134
|
-
BUILD = 1
|
|
135
|
-
DEPLOY = 2
|
|
136
|
-
STOP = 3
|
|
137
|
-
|
|
138
|
-
@classmethod
|
|
139
|
-
def from_string(cls, action: str) -> "Action":
|
|
140
|
-
"""Load from string."""
|
|
141
|
-
return cls(_ACTIONS[action])
|
|
142
|
-
|
|
143
|
-
|
|
144
123
|
class DeploymentStatus(enum.IntEnum):
|
|
145
124
|
"""Status payload."""
|
|
146
125
|
|
|
@@ -25,7 +25,7 @@ import sys
|
|
|
25
25
|
from pathlib import Path
|
|
26
26
|
from typing import List, TYPE_CHECKING, Union
|
|
27
27
|
|
|
28
|
-
from operate.constants import
|
|
28
|
+
from operate.constants import DEPLOYMENT_DIR
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
if TYPE_CHECKING:
|
|
@@ -41,7 +41,7 @@ def find_build_directory(config_file: Path, operate: "OperateApp") -> Path:
|
|
|
41
41
|
services = operate.service_manager()._get_all_services()
|
|
42
42
|
for service in services:
|
|
43
43
|
if service.hash == config_service_hash:
|
|
44
|
-
build_dir = service.path /
|
|
44
|
+
build_dir = service.path / DEPLOYMENT_DIR
|
|
45
45
|
if not build_dir.exists():
|
|
46
46
|
print(f"{config.get('name')} not deployed.")
|
|
47
47
|
sys.exit(1)
|
|
@@ -70,10 +70,10 @@ def claim_staking_rewards(operate: "OperateApp", config_path: str) -> None:
|
|
|
70
70
|
|
|
71
71
|
print("")
|
|
72
72
|
|
|
73
|
+
ask_password_if_needed(operate)
|
|
73
74
|
config = configure_local_config(template, operate)
|
|
74
75
|
manager = operate.service_manager()
|
|
75
76
|
service = get_service(manager, template)
|
|
76
|
-
ask_password_if_needed(operate)
|
|
77
77
|
|
|
78
78
|
# reload manger and config after setting operate.password
|
|
79
79
|
manager = operate.service_manager()
|
|
@@ -57,6 +57,7 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
|
|
|
57
57
|
print("No previous agent setup found. Exiting.")
|
|
58
58
|
return
|
|
59
59
|
|
|
60
|
+
ask_password_if_needed(operate)
|
|
60
61
|
config = configure_local_config(template, operate)
|
|
61
62
|
assert ( # nosec
|
|
62
63
|
config.principal_chain is not None
|
|
@@ -82,7 +83,6 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
|
|
|
82
83
|
print("Cancelled.")
|
|
83
84
|
return
|
|
84
85
|
|
|
85
|
-
ask_password_if_needed(operate)
|
|
86
86
|
manager = operate.service_manager()
|
|
87
87
|
service = get_service(manager, template)
|
|
88
88
|
|
|
@@ -100,7 +100,7 @@ QS_STAKING_PROGRAMS: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
100
100
|
"mech_marketplace": "mech",
|
|
101
101
|
"marketplace_supply_alpha": "mech",
|
|
102
102
|
},
|
|
103
|
-
Chain.
|
|
103
|
+
Chain.OPTIMISM: {
|
|
104
104
|
"optimus_alpha_2": "optimus",
|
|
105
105
|
"optimus_alpha_3": "optimus",
|
|
106
106
|
"optimus_alpha_4": "optimus",
|
|
@@ -414,7 +414,7 @@ def configure_local_config(
|
|
|
414
414
|
|
|
415
415
|
if env_var_name not in config.user_provided_args:
|
|
416
416
|
print(f"Description: {env_var_data['description']}")
|
|
417
|
-
if env_var_data["value"]:
|
|
417
|
+
if env_var_data["value"] is not None and env_var_data["value"] != "":
|
|
418
418
|
print(f"Default: {env_var_data['value']}")
|
|
419
419
|
|
|
420
420
|
user_provided_arg = ask_or_get_from_env(
|
|
@@ -23,6 +23,7 @@ import warnings
|
|
|
23
23
|
from typing import TYPE_CHECKING, cast
|
|
24
24
|
|
|
25
25
|
from operate.quickstart.run_service import (
|
|
26
|
+
ask_password_if_needed,
|
|
26
27
|
configure_local_config,
|
|
27
28
|
get_service,
|
|
28
29
|
load_local_config,
|
|
@@ -55,11 +56,12 @@ def stop_service(operate: "OperateApp", config_path: str) -> None:
|
|
|
55
56
|
print("No previous agent setup found. Exiting.")
|
|
56
57
|
return
|
|
57
58
|
|
|
59
|
+
ask_password_if_needed(operate)
|
|
58
60
|
configure_local_config(template, operate)
|
|
59
61
|
manager = operate.service_manager()
|
|
60
62
|
service = get_service(manager, template)
|
|
61
63
|
manager.stop_service_locally(
|
|
62
|
-
service_config_id=service.service_config_id,
|
|
64
|
+
service_config_id=service.service_config_id, use_docker=True
|
|
63
65
|
)
|
|
64
66
|
|
|
65
67
|
print()
|
|
@@ -61,8 +61,8 @@ def terminate_service(operate: "OperateApp", config_path: str) -> None:
|
|
|
61
61
|
print("Cancelled.")
|
|
62
62
|
return
|
|
63
63
|
|
|
64
|
-
config = configure_local_config(template, operate)
|
|
65
64
|
ask_password_if_needed(operate)
|
|
65
|
+
config = configure_local_config(template, operate)
|
|
66
66
|
manager = operate.service_manager()
|
|
67
67
|
service = get_service(manager, template)
|
|
68
68
|
ensure_enough_funds(operate, service)
|
operate/quickstart/utils.py
CHANGED
|
@@ -35,9 +35,6 @@ from operate.operate_types import Chain
|
|
|
35
35
|
from operate.resource import LocalResource, deserialize
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
MAX_QUICKSTART_VERSION = 1
|
|
39
|
-
|
|
40
|
-
|
|
41
38
|
def print_box(text: str, margin: int = 1, character: str = "=") -> None:
|
|
42
39
|
"""Print text centered within a box."""
|
|
43
40
|
|
|
@@ -119,20 +116,20 @@ CHAIN_TO_METADATA = {
|
|
|
119
116
|
"MAX_FEE_PER_GAS": "",
|
|
120
117
|
},
|
|
121
118
|
},
|
|
122
|
-
"
|
|
119
|
+
"optimism": {
|
|
123
120
|
"name": "Optimism",
|
|
124
121
|
"gasFundReq": unit_to_wei(0.005), # fund for master EOA
|
|
125
|
-
"staking_bonding_token": OLAS[Chain.
|
|
122
|
+
"staking_bonding_token": OLAS[Chain.OPTIMISM],
|
|
126
123
|
"token_data": {
|
|
127
124
|
ZERO_ADDRESS: {
|
|
128
125
|
"symbol": "ETH",
|
|
129
126
|
"decimals": 18,
|
|
130
127
|
},
|
|
131
|
-
USDC[Chain.
|
|
128
|
+
USDC[Chain.OPTIMISM]: {
|
|
132
129
|
"symbol": "USDC",
|
|
133
130
|
"decimals": 6,
|
|
134
131
|
},
|
|
135
|
-
OLAS[Chain.
|
|
132
|
+
OLAS[Chain.OPTIMISM]: {
|
|
136
133
|
"symbol": "OLAS",
|
|
137
134
|
"decimals": 18,
|
|
138
135
|
},
|
operate/resource.py
CHANGED
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
import enum
|
|
23
23
|
import json
|
|
24
24
|
import os
|
|
25
|
+
import platform
|
|
25
26
|
import shutil
|
|
27
|
+
import time
|
|
26
28
|
import types
|
|
27
29
|
import typing as t
|
|
28
30
|
from dataclasses import asdict, is_dataclass
|
|
@@ -92,6 +94,23 @@ def deserialize(obj: t.Any, otype: t.Any) -> t.Any:
|
|
|
92
94
|
return obj
|
|
93
95
|
|
|
94
96
|
|
|
97
|
+
def _safe_file_operation(operation: t.Callable, *args: t.Any, **kwargs: t.Any) -> None:
|
|
98
|
+
"""Safely perform file operation with retries on Windows."""
|
|
99
|
+
max_retries = 3 if platform.system() == "Windows" else 1
|
|
100
|
+
|
|
101
|
+
for attempt in range(max_retries):
|
|
102
|
+
try:
|
|
103
|
+
operation(*args, **kwargs)
|
|
104
|
+
return
|
|
105
|
+
except (PermissionError, FileNotFoundError, OSError) as e:
|
|
106
|
+
if attempt == max_retries - 1:
|
|
107
|
+
raise e
|
|
108
|
+
|
|
109
|
+
if platform.system() == "Windows":
|
|
110
|
+
# On Windows, wait a bit and retry
|
|
111
|
+
time.sleep(0.1)
|
|
112
|
+
|
|
113
|
+
|
|
95
114
|
class LocalResource:
|
|
96
115
|
"""Initialize local resource."""
|
|
97
116
|
|
|
@@ -144,9 +163,14 @@ class LocalResource:
|
|
|
144
163
|
bak0 = path.with_name(f"{path.name}.0.bak")
|
|
145
164
|
|
|
146
165
|
if path.exists() and not bak0.exists():
|
|
147
|
-
shutil.copy2
|
|
166
|
+
_safe_file_operation(shutil.copy2, path, bak0)
|
|
148
167
|
|
|
149
168
|
tmp_path = path.parent / f".{path.name}.tmp"
|
|
169
|
+
|
|
170
|
+
# Clean up any existing tmp file
|
|
171
|
+
if tmp_path.exists():
|
|
172
|
+
_safe_file_operation(tmp_path.unlink)
|
|
173
|
+
|
|
150
174
|
tmp_path.write_text(
|
|
151
175
|
json.dumps(
|
|
152
176
|
self.json,
|
|
@@ -155,15 +179,23 @@ class LocalResource:
|
|
|
155
179
|
encoding="utf-8",
|
|
156
180
|
)
|
|
157
181
|
|
|
158
|
-
|
|
182
|
+
# Atomic replace to avoid corruption
|
|
183
|
+
try:
|
|
184
|
+
_safe_file_operation(os.replace, tmp_path, path)
|
|
185
|
+
except (PermissionError, FileNotFoundError):
|
|
186
|
+
# On Windows, if the replace fails, clean up and skip
|
|
187
|
+
if platform.system() == "Windows":
|
|
188
|
+
_safe_file_operation(tmp_path.unlink)
|
|
189
|
+
|
|
159
190
|
self.load(self.path) # Validate before making backup
|
|
160
191
|
|
|
192
|
+
# Rotate backup files
|
|
161
193
|
for i in reversed(range(N_BACKUPS - 1)):
|
|
162
194
|
newer = path.with_name(f"{path.name}.{i}.bak")
|
|
163
195
|
older = path.with_name(f"{path.name}.{i + 1}.bak")
|
|
164
196
|
if newer.exists():
|
|
165
197
|
if older.exists():
|
|
166
|
-
older.unlink
|
|
167
|
-
newer.rename
|
|
198
|
+
_safe_file_operation(older.unlink)
|
|
199
|
+
_safe_file_operation(newer.rename, older)
|
|
168
200
|
|
|
169
|
-
shutil.copy2
|
|
201
|
+
_safe_file_operation(shutil.copy2, path, bak0)
|
|
@@ -33,9 +33,6 @@ from operate.constants import HEALTH_CHECK_URL
|
|
|
33
33
|
from operate.services.manage import ServiceManager # type: ignore
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
HTTP_OK = HTTPStatus.OK
|
|
37
|
-
|
|
38
|
-
|
|
39
36
|
class HealthChecker:
|
|
40
37
|
"""Health checker manager."""
|
|
41
38
|
|
|
@@ -43,7 +40,6 @@ class HealthChecker:
|
|
|
43
40
|
PORT_UP_TIMEOUT_DEFAULT = 300 # seconds
|
|
44
41
|
REQUEST_TIMEOUT_DEFAULT = 90
|
|
45
42
|
NUMBER_OF_FAILS_DEFAULT = 10
|
|
46
|
-
HEALTH_CHECK_URL = HEALTH_CHECK_URL
|
|
47
43
|
|
|
48
44
|
def __init__(
|
|
49
45
|
self,
|
|
@@ -95,11 +91,11 @@ class HealthChecker:
|
|
|
95
91
|
del service_config_id
|
|
96
92
|
timeout = aiohttp.ClientTimeout(total=self.REQUEST_TIMEOUT_DEFAULT)
|
|
97
93
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
98
|
-
async with session.get(
|
|
94
|
+
async with session.get(HEALTH_CHECK_URL) as resp:
|
|
99
95
|
try:
|
|
100
96
|
status = resp.status
|
|
101
97
|
|
|
102
|
-
if status !=
|
|
98
|
+
if status != HTTPStatus.OK:
|
|
103
99
|
# not HTTP OK -> not healthy for sure
|
|
104
100
|
content = await resp.text()
|
|
105
101
|
self.logger.warning(
|
operate/services/manage.py
CHANGED
|
@@ -23,7 +23,6 @@ import asyncio
|
|
|
23
23
|
import json
|
|
24
24
|
import logging
|
|
25
25
|
import os
|
|
26
|
-
import shutil
|
|
27
26
|
import time
|
|
28
27
|
import traceback
|
|
29
28
|
import typing as t
|
|
@@ -39,8 +38,9 @@ from aea.helpers.logging import setup_logger
|
|
|
39
38
|
from aea_ledger_ethereum import EthereumCrypto, LedgerApi
|
|
40
39
|
from autonomy.chain.base import registry_contracts
|
|
41
40
|
from autonomy.chain.config import CHAIN_PROFILES, ChainType
|
|
41
|
+
from autonomy.chain.metadata import IPFS_URI_PREFIX
|
|
42
42
|
|
|
43
|
-
from operate.constants import ZERO_ADDRESS
|
|
43
|
+
from operate.constants import IPFS_ADDRESS, ZERO_ADDRESS
|
|
44
44
|
from operate.data import DATA_DIR
|
|
45
45
|
from operate.data.contracts.mech_activity.contract import MechActivityContract
|
|
46
46
|
from operate.data.contracts.requester_activity_checker.contract import (
|
|
@@ -71,7 +71,6 @@ from operate.operate_types import (
|
|
|
71
71
|
from operate.services.protocol import EthSafeTxBuilder, OnChainManager, StakingState
|
|
72
72
|
from operate.services.service import (
|
|
73
73
|
ChainConfig,
|
|
74
|
-
DELETE_PREFIX,
|
|
75
74
|
Deployment,
|
|
76
75
|
NON_EXISTENT_MULTISIG,
|
|
77
76
|
NON_EXISTENT_TOKEN,
|
|
@@ -80,32 +79,13 @@ from operate.services.service import (
|
|
|
80
79
|
Service,
|
|
81
80
|
)
|
|
82
81
|
from operate.services.utils.mech import deploy_mech
|
|
83
|
-
from operate.utils.gnosis import
|
|
84
|
-
NULL_ADDRESS,
|
|
85
|
-
drain_eoa,
|
|
86
|
-
get_asset_balance,
|
|
87
|
-
get_assets_balances,
|
|
88
|
-
)
|
|
82
|
+
from operate.utils.gnosis import drain_eoa, get_asset_balance, get_assets_balances
|
|
89
83
|
from operate.utils.gnosis import transfer as transfer_from_safe
|
|
90
84
|
from operate.utils.gnosis import transfer_erc20_from_safe
|
|
91
85
|
from operate.wallet.master import MasterWalletManager
|
|
92
86
|
|
|
93
87
|
|
|
94
88
|
# pylint: disable=redefined-builtin
|
|
95
|
-
|
|
96
|
-
OPERATE = ".operate"
|
|
97
|
-
CONFIG = "config.json"
|
|
98
|
-
SERVICES = "services"
|
|
99
|
-
KEYS = "keys"
|
|
100
|
-
DEPLOYMENT = "deployment"
|
|
101
|
-
CONFIG = "config.json"
|
|
102
|
-
KEY = "master-key.txt"
|
|
103
|
-
KEYS_JSON = "keys.json"
|
|
104
|
-
DOCKER_COMPOSE_YAML = "docker-compose.yaml"
|
|
105
|
-
SERVICE_YAML = "service.yaml"
|
|
106
|
-
HTTP_OK = 200
|
|
107
|
-
URI_HASH_POSITION = 7
|
|
108
|
-
IPFS_GATEWAY = "https://gateway.autonolas.tech/ipfs/"
|
|
109
89
|
DEFAULT_TOPUP_THRESHOLD = 0.5
|
|
110
90
|
# At the moment, we only support running one agent per service locally on a machine.
|
|
111
91
|
# If multiple agents are provided in the service.yaml file, only the 0th index config will be used.
|
|
@@ -297,7 +277,7 @@ class ServiceManager:
|
|
|
297
277
|
sftxb = self.get_eth_safe_tx_builder(ledger_config=ledger_config)
|
|
298
278
|
info = sftxb.info(token_id=chain_data.token)
|
|
299
279
|
config_hash = info["config_hash"]
|
|
300
|
-
url =
|
|
280
|
+
url = IPFS_ADDRESS.format(hash=config_hash)
|
|
301
281
|
self.logger.info(f"Fetching {url=}...")
|
|
302
282
|
res = requests.get(url, timeout=30)
|
|
303
283
|
if res.status_code == HTTPStatus.OK:
|
|
@@ -403,7 +383,7 @@ class ServiceManager:
|
|
|
403
383
|
)
|
|
404
384
|
|
|
405
385
|
on_chain_metadata = self._get_on_chain_metadata(chain_config=chain_config)
|
|
406
|
-
on_chain_hash = on_chain_metadata.get("code_uri", "")[
|
|
386
|
+
on_chain_hash = on_chain_metadata.get("code_uri", "")[len(IPFS_URI_PREFIX) :]
|
|
407
387
|
on_chain_description = on_chain_metadata.get("description")
|
|
408
388
|
|
|
409
389
|
current_agent_bond = staking_params[
|
|
@@ -653,13 +633,13 @@ class ServiceManager:
|
|
|
653
633
|
|
|
654
634
|
current_staking_program = self._get_current_staking_program(service, chain)
|
|
655
635
|
fallback_params = dict( # nosec
|
|
656
|
-
staking_contract=
|
|
636
|
+
staking_contract=ZERO_ADDRESS,
|
|
657
637
|
agent_ids=[user_params.agent_id],
|
|
658
638
|
service_registry="0x9338b5153AE39BB89f50468E608eD9d764B755fD", # nosec
|
|
659
|
-
staking_token=
|
|
639
|
+
staking_token=ZERO_ADDRESS, # nosec
|
|
660
640
|
service_registry_token_utility="0xa45E64d13A30a51b91ae0eb182e88a40e9b18eD8", # nosec
|
|
661
641
|
min_staking_deposit=20000000000000000000,
|
|
662
|
-
activity_checker=
|
|
642
|
+
activity_checker=ZERO_ADDRESS, # nosec
|
|
663
643
|
)
|
|
664
644
|
|
|
665
645
|
current_staking_params = sftxb.get_staking_params(
|
|
@@ -710,7 +690,7 @@ class ServiceManager:
|
|
|
710
690
|
"GNOSIS_LEDGER_RPC": PUBLIC_RPCS[Chain.GNOSIS],
|
|
711
691
|
"BASE_LEDGER_RPC": PUBLIC_RPCS[Chain.BASE],
|
|
712
692
|
"CELO_LEDGER_RPC": PUBLIC_RPCS[Chain.CELO],
|
|
713
|
-
"OPTIMISM_LEDGER_RPC": PUBLIC_RPCS[Chain.
|
|
693
|
+
"OPTIMISM_LEDGER_RPC": PUBLIC_RPCS[Chain.OPTIMISM],
|
|
714
694
|
"MODE_LEDGER_RPC": PUBLIC_RPCS[Chain.MODE],
|
|
715
695
|
f"{chain.upper()}_LEDGER_RPC": ledger_config.rpc,
|
|
716
696
|
"STAKING_CONTRACT_ADDRESS": target_staking_params.get(
|
|
@@ -792,7 +772,7 @@ class ServiceManager:
|
|
|
792
772
|
target_staking_params["agent_ids"] = [agent_id]
|
|
793
773
|
|
|
794
774
|
on_chain_metadata = self._get_on_chain_metadata(chain_config=chain_config)
|
|
795
|
-
on_chain_hash = on_chain_metadata.get("code_uri", "")[
|
|
775
|
+
on_chain_hash = on_chain_metadata.get("code_uri", "")[len(IPFS_URI_PREFIX) :]
|
|
796
776
|
on_chain_description = on_chain_metadata.get("description")
|
|
797
777
|
|
|
798
778
|
current_agent_bond = sftxb.get_agent_bond(
|
|
@@ -1067,7 +1047,7 @@ class ServiceManager:
|
|
|
1067
1047
|
|
|
1068
1048
|
reuse_multisig = True
|
|
1069
1049
|
info = sftxb.info(token_id=chain_data.token)
|
|
1070
|
-
if info["multisig"] ==
|
|
1050
|
+
if info["multisig"] == ZERO_ADDRESS:
|
|
1071
1051
|
reuse_multisig = False
|
|
1072
1052
|
|
|
1073
1053
|
self.logger.info(f"{reuse_multisig=}")
|
|
@@ -1135,9 +1115,7 @@ class ServiceManager:
|
|
|
1135
1115
|
staking_chain = None
|
|
1136
1116
|
for chain_, config in service.chain_configs.items():
|
|
1137
1117
|
if config.chain_data.user_params.use_staking:
|
|
1138
|
-
staking_chain = chain_
|
|
1139
|
-
"optimistic", "optimism"
|
|
1140
|
-
) # TODO: remove this hack, when it's renamed in open-autonomy
|
|
1118
|
+
staking_chain = chain_
|
|
1141
1119
|
break
|
|
1142
1120
|
|
|
1143
1121
|
service.update_env_variables_values(
|
|
@@ -1148,9 +1126,7 @@ class ServiceManager:
|
|
|
1148
1126
|
for chain, config in service.chain_configs.items()
|
|
1149
1127
|
},
|
|
1150
1128
|
separators=(",", ":"),
|
|
1151
|
-
)
|
|
1152
|
-
"optimistic", "optimism"
|
|
1153
|
-
), # TODO: remove this hack, when it's renamed in open-autonomy
|
|
1129
|
+
),
|
|
1154
1130
|
"STAKING_CHAIN": staking_chain,
|
|
1155
1131
|
}
|
|
1156
1132
|
)
|
|
@@ -2210,10 +2186,6 @@ class ServiceManager:
|
|
|
2210
2186
|
paths = list(self.path.iterdir())
|
|
2211
2187
|
for path in paths:
|
|
2212
2188
|
try:
|
|
2213
|
-
if path.name.startswith(DELETE_PREFIX):
|
|
2214
|
-
shutil.rmtree(path)
|
|
2215
|
-
self.logger.info(f"Deleted folder: {path.name}")
|
|
2216
|
-
|
|
2217
2189
|
if path.name.startswith(SERVICE_CONFIG_PREFIX) or path.name.startswith(
|
|
2218
2190
|
"bafybei"
|
|
2219
2191
|
):
|
operate/services/protocol.py
CHANGED
|
@@ -61,6 +61,7 @@ from operate.constants import (
|
|
|
61
61
|
ON_CHAIN_INTERACT_RETRIES,
|
|
62
62
|
ON_CHAIN_INTERACT_SLEEP,
|
|
63
63
|
ON_CHAIN_INTERACT_TIMEOUT,
|
|
64
|
+
ZERO_ADDRESS,
|
|
64
65
|
)
|
|
65
66
|
from operate.data import DATA_DIR
|
|
66
67
|
from operate.data.contracts.dual_staking_token.contract import DualStakingTokenContract
|
|
@@ -69,7 +70,6 @@ from operate.operate_types import Chain as OperateChain
|
|
|
69
70
|
from operate.operate_types import ContractAddresses
|
|
70
71
|
from operate.utils.gnosis import (
|
|
71
72
|
MultiSendOperation,
|
|
72
|
-
NULL_ADDRESS,
|
|
73
73
|
SafeOperation,
|
|
74
74
|
hash_payload_to_hex,
|
|
75
75
|
skill_input_hex_to_payload,
|
|
@@ -710,7 +710,7 @@ class _ChainUtil:
|
|
|
710
710
|
token_id=service_id,
|
|
711
711
|
)
|
|
712
712
|
|
|
713
|
-
if multisig_address ==
|
|
713
|
+
if multisig_address == ZERO_ADDRESS:
|
|
714
714
|
return []
|
|
715
715
|
|
|
716
716
|
return registry_contracts.gnosis_safe.get_owners(
|
|
@@ -1605,7 +1605,7 @@ def get_reuse_multisig_from_safe_payload( # pylint: disable=too-many-locals
|
|
|
1605
1605
|
chain_type=chain_type,
|
|
1606
1606
|
token_id=service_id,
|
|
1607
1607
|
)
|
|
1608
|
-
if multisig_address ==
|
|
1608
|
+
if multisig_address == ZERO_ADDRESS:
|
|
1609
1609
|
return None, None, "Cannot reuse multisig, No previous deployment exist!"
|
|
1610
1610
|
|
|
1611
1611
|
multisend_address = ContractConfigs.get(MULTISEND_CONTRACT.name).contracts[
|
|
@@ -1723,8 +1723,8 @@ def get_reuse_multisig_from_safe_payload( # pylint: disable=too-many-locals
|
|
|
1723
1723
|
0, # safe tx gas
|
|
1724
1724
|
0, # bas gas
|
|
1725
1725
|
0, # safe gas price
|
|
1726
|
-
|
|
1727
|
-
|
|
1726
|
+
ZERO_ADDRESS, # gas token
|
|
1727
|
+
ZERO_ADDRESS, # refund receiver
|
|
1728
1728
|
signature_bytes, # signatures
|
|
1729
1729
|
],
|
|
1730
1730
|
)
|
operate/services/service.py
CHANGED
|
@@ -45,7 +45,9 @@ from aea.configurations.constants import (
|
|
|
45
45
|
from aea.helpers.yaml_utils import yaml_dump, yaml_load, yaml_load_all
|
|
46
46
|
from aea_cli_ipfs.ipfs_utils import IPFSTool
|
|
47
47
|
from autonomy.cli.helpers.deployment import run_deployment, stop_deployment
|
|
48
|
+
from autonomy.configurations.constants import DEFAULT_SERVICE_CONFIG_FILE
|
|
48
49
|
from autonomy.configurations.loader import apply_env_variables, load_service_config
|
|
50
|
+
from autonomy.constants import DEFAULT_KEYS_FILE, DOCKER_COMPOSE_YAML
|
|
49
51
|
from autonomy.deploy.base import BaseDeploymentGenerator
|
|
50
52
|
from autonomy.deploy.base import ServiceBuilder as BaseServiceBuilder
|
|
51
53
|
from autonomy.deploy.constants import (
|
|
@@ -61,13 +63,7 @@ from autonomy.deploy.generators.docker_compose.base import DockerComposeGenerato
|
|
|
61
63
|
from autonomy.deploy.generators.kubernetes.base import KubernetesGenerator
|
|
62
64
|
from docker import from_env
|
|
63
65
|
|
|
64
|
-
from operate.constants import
|
|
65
|
-
DEPLOYMENT,
|
|
66
|
-
DEPLOYMENT_JSON,
|
|
67
|
-
DOCKER_COMPOSE_YAML,
|
|
68
|
-
KEYS_JSON,
|
|
69
|
-
ZERO_ADDRESS,
|
|
70
|
-
)
|
|
66
|
+
from operate.constants import CONFIG_JSON, DEPLOYMENT_DIR, DEPLOYMENT_JSON, ZERO_ADDRESS
|
|
71
67
|
from operate.keys import Keys
|
|
72
68
|
from operate.operate_http.exceptions import NotAllowed
|
|
73
69
|
from operate.operate_types import (
|
|
@@ -96,8 +92,7 @@ from operate.utils.ssl import create_ssl_certificate
|
|
|
96
92
|
SAFE_CONTRACT_ADDRESS = "safe_contract_address"
|
|
97
93
|
ALL_PARTICIPANTS = "all_participants"
|
|
98
94
|
CONSENSUS_THRESHOLD = "consensus_threshold"
|
|
99
|
-
|
|
100
|
-
SERVICE_CONFIG_VERSION = 6
|
|
95
|
+
SERVICE_CONFIG_VERSION = 7
|
|
101
96
|
SERVICE_CONFIG_PREFIX = "sc-"
|
|
102
97
|
|
|
103
98
|
NON_EXISTENT_MULTISIG = "0xm"
|
|
@@ -410,7 +405,7 @@ class Deployment(LocalResource):
|
|
|
410
405
|
nodes: DeployedNodes
|
|
411
406
|
path: Path
|
|
412
407
|
|
|
413
|
-
_file =
|
|
408
|
+
_file = DEPLOYMENT_JSON
|
|
414
409
|
|
|
415
410
|
@staticmethod
|
|
416
411
|
def new(path: Path) -> "Deployment":
|
|
@@ -435,14 +430,14 @@ class Deployment(LocalResource):
|
|
|
435
430
|
|
|
436
431
|
def copy_previous_agent_run_logs(self) -> None:
|
|
437
432
|
"""Copy previous agent logs."""
|
|
438
|
-
source_path = self.path /
|
|
433
|
+
source_path = self.path / DEPLOYMENT_DIR / "agent" / "log.txt"
|
|
439
434
|
destination_path = self.path / "prev_log.txt"
|
|
440
435
|
if source_path.exists():
|
|
441
436
|
shutil.copy(source_path, destination_path)
|
|
442
437
|
|
|
443
438
|
def _build_kubernetes(self, force: bool = True) -> None:
|
|
444
439
|
"""Build kubernetes deployment."""
|
|
445
|
-
k8s_build = self.path /
|
|
440
|
+
k8s_build = self.path / DEPLOYMENT_DIR / "abci_build_k8s"
|
|
446
441
|
if k8s_build.exists() and force:
|
|
447
442
|
shutil.rmtree(k8s_build)
|
|
448
443
|
mkdirs(build_dir=k8s_build)
|
|
@@ -450,7 +445,7 @@ class Deployment(LocalResource):
|
|
|
450
445
|
service = Service.load(path=self.path)
|
|
451
446
|
builder = ServiceBuilder.from_dir(
|
|
452
447
|
path=service.package_absolute_path,
|
|
453
|
-
keys_file=self.path /
|
|
448
|
+
keys_file=self.path / DEFAULT_KEYS_FILE,
|
|
454
449
|
number_of_agents=len(service.keys),
|
|
455
450
|
)
|
|
456
451
|
builder.deplopyment_type = KubernetesGenerator.deployment_type
|
|
@@ -482,7 +477,7 @@ class Deployment(LocalResource):
|
|
|
482
477
|
force=force,
|
|
483
478
|
)
|
|
484
479
|
|
|
485
|
-
build = self.path /
|
|
480
|
+
build = self.path / DEPLOYMENT_DIR
|
|
486
481
|
if build.exists() and not force:
|
|
487
482
|
return
|
|
488
483
|
if build.exists() and force:
|
|
@@ -490,7 +485,7 @@ class Deployment(LocalResource):
|
|
|
490
485
|
shutil.rmtree(build)
|
|
491
486
|
mkdirs(build_dir=build)
|
|
492
487
|
|
|
493
|
-
keys_file = self.path /
|
|
488
|
+
keys_file = self.path / DEFAULT_KEYS_FILE
|
|
494
489
|
keys_file.write_text(
|
|
495
490
|
json.dumps(
|
|
496
491
|
[
|
|
@@ -588,7 +583,7 @@ class Deployment(LocalResource):
|
|
|
588
583
|
|
|
589
584
|
def _build_host(self, force: bool = True, chain: t.Optional[str] = None) -> None:
|
|
590
585
|
"""Build host depployment."""
|
|
591
|
-
build = self.path /
|
|
586
|
+
build = self.path / DEPLOYMENT_DIR
|
|
592
587
|
if build.exists() and not force:
|
|
593
588
|
return
|
|
594
589
|
|
|
@@ -617,7 +612,7 @@ class Deployment(LocalResource):
|
|
|
617
612
|
chain_config = service.chain_configs[chain]
|
|
618
613
|
chain_data = chain_config.chain_data
|
|
619
614
|
|
|
620
|
-
keys_file = self.path /
|
|
615
|
+
keys_file = self.path / DEFAULT_KEYS_FILE
|
|
621
616
|
keys_file.write_text(
|
|
622
617
|
json.dumps(
|
|
623
618
|
[
|
|
@@ -708,7 +703,7 @@ class Deployment(LocalResource):
|
|
|
708
703
|
self._build_kubernetes(force=force)
|
|
709
704
|
else:
|
|
710
705
|
ssl_key_path, ssl_cert_path = create_ssl_certificate(
|
|
711
|
-
ssl_dir=service.path /
|
|
706
|
+
ssl_dir=service.path / DEPLOYMENT_DIR / "ssl"
|
|
712
707
|
)
|
|
713
708
|
service.update_env_variables_values(
|
|
714
709
|
{
|
|
@@ -734,7 +729,11 @@ class Deployment(LocalResource):
|
|
|
734
729
|
|
|
735
730
|
try:
|
|
736
731
|
if use_docker:
|
|
737
|
-
run_deployment(
|
|
732
|
+
run_deployment(
|
|
733
|
+
build_dir=self.path / "deployment",
|
|
734
|
+
detach=True,
|
|
735
|
+
project_name=self.path.name,
|
|
736
|
+
)
|
|
738
737
|
else:
|
|
739
738
|
run_host_deployment(build_dir=self.path / "deployment")
|
|
740
739
|
except Exception:
|
|
@@ -754,7 +753,10 @@ class Deployment(LocalResource):
|
|
|
754
753
|
self.store()
|
|
755
754
|
|
|
756
755
|
if use_docker:
|
|
757
|
-
stop_deployment(
|
|
756
|
+
stop_deployment(
|
|
757
|
+
build_dir=self.path / "deployment",
|
|
758
|
+
project_name=self.path.name,
|
|
759
|
+
)
|
|
758
760
|
else:
|
|
759
761
|
stop_host_deployment(build_dir=self.path / "deployment")
|
|
760
762
|
|
|
@@ -763,7 +765,7 @@ class Deployment(LocalResource):
|
|
|
763
765
|
|
|
764
766
|
def delete(self) -> None:
|
|
765
767
|
"""Delete the deployment."""
|
|
766
|
-
build = self.path /
|
|
768
|
+
build = self.path / DEPLOYMENT_DIR
|
|
767
769
|
shutil.rmtree(build)
|
|
768
770
|
self.status = DeploymentStatus.DELETED
|
|
769
771
|
self.store()
|
|
@@ -791,7 +793,7 @@ class Service(LocalResource):
|
|
|
791
793
|
_helper: t.Optional[ServiceHelper] = None
|
|
792
794
|
_deployment: t.Optional[Deployment] = None
|
|
793
795
|
|
|
794
|
-
_file =
|
|
796
|
+
_file = CONFIG_JSON
|
|
795
797
|
|
|
796
798
|
@staticmethod
|
|
797
799
|
def _determine_agent_id(service_name: str) -> int:
|
|
@@ -933,7 +935,7 @@ class Service(LocalResource):
|
|
|
933
935
|
"goerli",
|
|
934
936
|
"gnosis",
|
|
935
937
|
"solana",
|
|
936
|
-
"
|
|
938
|
+
"optimism",
|
|
937
939
|
"base",
|
|
938
940
|
"mode",
|
|
939
941
|
]
|
|
@@ -969,6 +971,19 @@ class Service(LocalResource):
|
|
|
969
971
|
new_chain_configs[chain] = chain_data # type: ignore
|
|
970
972
|
data["chain_configs"] = new_chain_configs
|
|
971
973
|
|
|
974
|
+
if version < 7:
|
|
975
|
+
if data["home_chain"] == "optimistic":
|
|
976
|
+
data["home_chain"] = Chain.OPTIMISM.value
|
|
977
|
+
|
|
978
|
+
if "optimistic" in data["chain_configs"]:
|
|
979
|
+
data["chain_configs"]["optimism"] = data["chain_configs"].pop(
|
|
980
|
+
"optimistic"
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
for _, chain_config in data["chain_configs"].items():
|
|
984
|
+
if chain_config["ledger_config"]["chain"] == "optimistic":
|
|
985
|
+
chain_config["ledger_config"]["chain"] = Chain.OPTIMISM.value
|
|
986
|
+
|
|
972
987
|
data["version"] = SERVICE_CONFIG_VERSION
|
|
973
988
|
|
|
974
989
|
# Redownload service path
|
|
@@ -1028,7 +1043,7 @@ class Service(LocalResource):
|
|
|
1028
1043
|
package_absolute_path = self.path / self.package_path
|
|
1029
1044
|
if (
|
|
1030
1045
|
not package_absolute_path.exists()
|
|
1031
|
-
or not (package_absolute_path /
|
|
1046
|
+
or not (package_absolute_path / DEFAULT_SERVICE_CONFIG_FILE).exists()
|
|
1032
1047
|
):
|
|
1033
1048
|
with tempfile.TemporaryDirectory(dir=self.path) as temp_dir:
|
|
1034
1049
|
package_temp_path = Path(
|
|
@@ -1103,7 +1118,7 @@ class Service(LocalResource):
|
|
|
1103
1118
|
|
|
1104
1119
|
def service_public_id(self, include_version: bool = True) -> str:
|
|
1105
1120
|
"""Get the public id (based on the service hash)."""
|
|
1106
|
-
with (self.package_absolute_path /
|
|
1121
|
+
with (self.package_absolute_path / DEFAULT_SERVICE_CONFIG_FILE).open(
|
|
1107
1122
|
"r", encoding="utf-8"
|
|
1108
1123
|
) as fp:
|
|
1109
1124
|
service_yaml, *_ = yaml_load_all(fp)
|
|
@@ -1135,7 +1150,9 @@ class Service(LocalResource):
|
|
|
1135
1150
|
)
|
|
1136
1151
|
)
|
|
1137
1152
|
|
|
1138
|
-
with (package_path /
|
|
1153
|
+
with (package_path / DEFAULT_SERVICE_CONFIG_FILE).open(
|
|
1154
|
+
"r", encoding="utf-8"
|
|
1155
|
+
) as fp:
|
|
1139
1156
|
service_yaml, *_ = yaml_load_all(fp)
|
|
1140
1157
|
|
|
1141
1158
|
public_id = f"{service_yaml['author']}/{service_yaml['name']}"
|
|
@@ -1321,10 +1338,3 @@ class Service(LocalResource):
|
|
|
1321
1338
|
|
|
1322
1339
|
if updated:
|
|
1323
1340
|
self.store()
|
|
1324
|
-
|
|
1325
|
-
def delete(self) -> None:
|
|
1326
|
-
"""Delete a service."""
|
|
1327
|
-
parent_directory = self.path.parent
|
|
1328
|
-
new_path = parent_directory / f"{DELETE_PREFIX}{self.path.name}"
|
|
1329
|
-
shutil.move(self.path, new_path)
|
|
1330
|
-
shutil.rmtree(new_path)
|
operate/utils/gnosis.py
CHANGED
|
@@ -43,9 +43,7 @@ from operate.operate_types import Chain
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
logger = setup_logger(name="operate.manager")
|
|
46
|
-
NULL_ADDRESS: str = "0x" + "0" * 40
|
|
47
46
|
MAX_UINT256 = 2**256 - 1
|
|
48
|
-
ZERO_ETH = 0
|
|
49
47
|
SENTINEL_OWNERS = "0x0000000000000000000000000000000000000001"
|
|
50
48
|
|
|
51
49
|
|
|
@@ -73,8 +71,8 @@ def hash_payload_to_hex( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
73
71
|
operation: int = SafeOperation.CALL.value,
|
|
74
72
|
base_gas: int = 0,
|
|
75
73
|
safe_gas_price: int = 0,
|
|
76
|
-
gas_token: str =
|
|
77
|
-
refund_receiver: str =
|
|
74
|
+
gas_token: str = ZERO_ADDRESS,
|
|
75
|
+
refund_receiver: str = ZERO_ADDRESS,
|
|
78
76
|
use_flashbots: bool = False,
|
|
79
77
|
gas_limit: int = 0,
|
|
80
78
|
raise_on_failed_simulation: bool = False,
|
|
@@ -525,7 +523,8 @@ def drain_eoa(
|
|
|
525
523
|
if Chain.from_id(chain_id) in (
|
|
526
524
|
Chain.ARBITRUM_ONE,
|
|
527
525
|
Chain.BASE,
|
|
528
|
-
Chain.
|
|
526
|
+
Chain.OPTIMISM,
|
|
527
|
+
Chain.MODE,
|
|
529
528
|
):
|
|
530
529
|
chain_fee += ledger_api.get_l1_data_fee(tx)
|
|
531
530
|
|
operate/wallet/master.py
CHANGED
|
@@ -48,7 +48,7 @@ from operate.ledger.profiles import ERC20_TOKENS, OLAS, USDC
|
|
|
48
48
|
from operate.operate_types import Chain, LedgerType
|
|
49
49
|
from operate.resource import LocalResource
|
|
50
50
|
from operate.utils import create_backup
|
|
51
|
-
from operate.utils.gnosis import
|
|
51
|
+
from operate.utils.gnosis import add_owner
|
|
52
52
|
from operate.utils.gnosis import create_safe as create_gnosis_safe
|
|
53
53
|
from operate.utils.gnosis import (
|
|
54
54
|
drain_eoa,
|
|
@@ -110,7 +110,7 @@ class MasterWallet(LocalResource):
|
|
|
110
110
|
) -> LedgerApi:
|
|
111
111
|
"""Get ledger api object."""
|
|
112
112
|
gas_price_strategies = deepcopy(DEFAULT_GAS_PRICE_STRATEGIES)
|
|
113
|
-
if chain in (Chain.BASE, Chain.MODE, Chain.
|
|
113
|
+
if chain in (Chain.BASE, Chain.MODE, Chain.OPTIMISM):
|
|
114
114
|
gas_price_strategies[EIP1559]["fallback_estimate"]["maxFeePerGas"] = to_wei(
|
|
115
115
|
5, GWEI
|
|
116
116
|
)
|
|
@@ -717,7 +717,7 @@ class EthereumMasterWallet(MasterWallet):
|
|
|
717
717
|
owners.remove(self.address)
|
|
718
718
|
|
|
719
719
|
balances: t.Dict[str, int] = {}
|
|
720
|
-
balances[
|
|
720
|
+
balances[ZERO_ADDRESS] = ledger_api.get_balance(safe) or 0
|
|
721
721
|
for token in tokens:
|
|
722
722
|
balance = (
|
|
723
723
|
registry_contracts.erc20.get_instance(
|
|
@@ -781,7 +781,7 @@ class EthereumMasterWallet(MasterWallet):
|
|
|
781
781
|
"goerli",
|
|
782
782
|
"gnosis",
|
|
783
783
|
"solana",
|
|
784
|
-
"
|
|
784
|
+
"optimism",
|
|
785
785
|
"base",
|
|
786
786
|
"mode",
|
|
787
787
|
]
|
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.8.1.dist-info → olas_operate_middleware-0.9.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|