olas-operate-middleware 0.8.2__py3-none-any.whl → 0.10.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.
Files changed (34) hide show
  1. {olas_operate_middleware-0.8.2.dist-info → olas_operate_middleware-0.10.0.dist-info}/METADATA +2 -2
  2. {olas_operate_middleware-0.8.2.dist-info → olas_operate_middleware-0.10.0.dist-info}/RECORD +34 -34
  3. operate/bridge/bridge_manager.py +5 -6
  4. operate/bridge/providers/native_bridge_provider.py +1 -1
  5. operate/bridge/providers/provider.py +4 -5
  6. operate/bridge/providers/relay_provider.py +1 -1
  7. operate/cli.py +128 -48
  8. operate/constants.py +9 -9
  9. operate/keys.py +26 -14
  10. operate/ledger/__init__.py +4 -4
  11. operate/ledger/profiles.py +9 -11
  12. operate/migration.py +326 -0
  13. operate/operate_types.py +9 -27
  14. operate/quickstart/analyse_logs.py +3 -6
  15. operate/quickstart/claim_staking_rewards.py +1 -4
  16. operate/quickstart/reset_configs.py +0 -3
  17. operate/quickstart/reset_password.py +0 -3
  18. operate/quickstart/reset_staking.py +3 -5
  19. operate/quickstart/run_service.py +5 -7
  20. operate/quickstart/stop_service.py +3 -4
  21. operate/quickstart/terminate_on_chain_service.py +1 -4
  22. operate/quickstart/utils.py +4 -7
  23. operate/resource.py +37 -5
  24. operate/services/deployment_runner.py +170 -38
  25. operate/services/health_checker.py +5 -8
  26. operate/services/manage.py +103 -164
  27. operate/services/protocol.py +5 -5
  28. operate/services/service.py +42 -242
  29. operate/utils/__init__.py +44 -0
  30. operate/utils/gnosis.py +25 -17
  31. operate/wallet/master.py +20 -24
  32. {olas_operate_middleware-0.8.2.dist-info → olas_operate_middleware-0.10.0.dist-info}/LICENSE +0 -0
  33. {olas_operate_middleware-0.8.2.dist-info → olas_operate_middleware-0.10.0.dist-info}/WHEEL +0 -0
  34. {olas_operate_middleware-0.8.2.dist-info → olas_operate_middleware-0.10.0.dist-info}/entry_points.txt +0 -0
@@ -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.OPTIMISTIC: OPTIMISM_PUBLIC_RPC,
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.OPTIMISTIC: OPTIMISM_RPC,
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.OPTIMISTIC: "ETH",
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.OPTIMISTIC: "Wei",
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.OPTIMISTIC: ContractAddresses(
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.OPTIMISTIC: {
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.OPTIMISTIC: "0xFC2E6e6BCbd49ccf3A5f029c79984372DcBFE527",
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.OPTIMISTIC: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
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.OPTIMISTIC: "0x4200000000000000000000000000000000000006",
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.OPTIMISTIC: {
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.OPTIMISTIC: {ZERO_ADDRESS: 5_000_000_000_000_000},
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.OPTIMISTIC: {
240
+ Chain.OPTIMISM: {
243
241
  "tx": "https://optimistic.etherscan.io/tx/{tx_hash}",
244
242
  "address": "https://optimistic.etherscan.io/address/{address}",
245
243
  },
operate/migration.py CHANGED
@@ -22,9 +22,25 @@
22
22
 
23
23
  import json
24
24
  import logging
25
+ import shutil
26
+ import traceback
25
27
  from pathlib import Path
28
+ from time import time
26
29
 
30
+ from aea_cli_ipfs.ipfs_utils import IPFSTool
31
+
32
+ from operate.constants import ZERO_ADDRESS
33
+ from operate.operate_types import Chain, LedgerType
34
+ from operate.services.manage import ServiceManager
35
+ from operate.services.service import (
36
+ DEFAULT_TRADER_ENV_VARS,
37
+ NON_EXISTENT_MULTISIG,
38
+ SERVICE_CONFIG_PREFIX,
39
+ SERVICE_CONFIG_VERSION,
40
+ Service,
41
+ )
27
42
  from operate.utils import create_backup
43
+ from operate.wallet.master import LEDGER_TYPE_TO_WALLET_CLASS, MasterWalletManager
28
44
 
29
45
 
30
46
  class MigrationManager:
@@ -42,6 +58,12 @@ class MigrationManager:
42
58
  self._path = home
43
59
  self.logger = logger
44
60
 
61
+ def log_directories(self, path: Path) -> None:
62
+ """Log directories present in `path`."""
63
+ directories = [f" - {str(p)}" for p in path.iterdir() if p.is_dir()]
64
+ directories_str = "\n".join(directories)
65
+ self.logger.info(f"Directories in {path}\n: {directories_str}")
66
+
45
67
  def migrate_user_account(self) -> None:
46
68
  """Migrates user.json"""
47
69
 
@@ -61,3 +83,307 @@ class MigrationManager:
61
83
  json.dump(new_data, f, indent=4)
62
84
 
63
85
  self.logger.info("[MIGRATION MANAGER] Migrated user.json.")
86
+
87
+ def migrate_wallets(self, wallet_manager: MasterWalletManager) -> None:
88
+ """Migrate old wallet config formats to new ones, if applies."""
89
+ self.logger.info("Migrating wallet configs...")
90
+
91
+ for ledger_type in LedgerType:
92
+ if not wallet_manager.exists(ledger_type=ledger_type):
93
+ continue
94
+
95
+ wallet_class = LEDGER_TYPE_TO_WALLET_CLASS.get(ledger_type)
96
+ if wallet_class is None:
97
+ continue
98
+
99
+ migrated = wallet_class.migrate_format(path=wallet_manager.path)
100
+ if migrated:
101
+ self.logger.info(f"Wallet {wallet_class} has been migrated.")
102
+
103
+ self.logger.info("Migrating wallet configs done.")
104
+
105
+ @staticmethod
106
+ def _migrate_service( # pylint: disable=too-many-statements,too-many-locals
107
+ path: Path,
108
+ ) -> bool:
109
+ """Migrate the JSON file format if needed."""
110
+
111
+ if not path.is_dir():
112
+ return False
113
+
114
+ if not path.name.startswith(SERVICE_CONFIG_PREFIX) and not path.name.startswith(
115
+ "bafybei"
116
+ ):
117
+ return False
118
+
119
+ if path.name.startswith("bafybei"):
120
+ backup_name = f"backup_{int(time())}_{path.name}"
121
+ backup_path = path.parent / backup_name
122
+ shutil.copytree(path, backup_path)
123
+ deployment_path = backup_path / "deployment"
124
+ if deployment_path.is_dir():
125
+ shutil.rmtree(deployment_path)
126
+
127
+ with open(
128
+ path / Service._file, # pylint: disable=protected-access
129
+ "r",
130
+ encoding="utf-8",
131
+ ) as file:
132
+ data = json.load(file)
133
+
134
+ version = data.get("version", 0)
135
+ if version > SERVICE_CONFIG_VERSION:
136
+ raise RuntimeError(
137
+ f"Service configuration in {path} has version {version}, which means it was created with a newer version of olas-operate-middleware. Only configuration versions <= {SERVICE_CONFIG_VERSION} are supported by this version of olas-operate-middleware."
138
+ )
139
+
140
+ # Complete missing env vars for trader
141
+ if "trader" in data["name"].lower():
142
+ data.setdefault("env_variables", {})
143
+
144
+ for key, value in DEFAULT_TRADER_ENV_VARS.items():
145
+ if key not in data["env_variables"]:
146
+ data["env_variables"][key] = value
147
+
148
+ with open(
149
+ path / Service._file, # pylint: disable=protected-access
150
+ "w",
151
+ encoding="utf-8",
152
+ ) as file:
153
+ json.dump(data, file, indent=2)
154
+
155
+ if version == SERVICE_CONFIG_VERSION:
156
+ return False
157
+
158
+ # Migration steps for older versions
159
+ if version == 0:
160
+ new_data = {
161
+ "version": 2,
162
+ "hash": data.get("hash"),
163
+ "keys": data.get("keys"),
164
+ "home_chain_id": "100", # This is the default value for version 2 - do not change, will be corrected below
165
+ "chain_configs": {
166
+ "100": { # This is the default value for version 2 - do not change, will be corrected below
167
+ "ledger_config": {
168
+ "rpc": data.get("ledger_config", {}).get("rpc"),
169
+ "type": data.get("ledger_config", {}).get("type"),
170
+ "chain": data.get("ledger_config", {}).get("chain"),
171
+ },
172
+ "chain_data": {
173
+ "instances": data.get("chain_data", {}).get(
174
+ "instances", []
175
+ ),
176
+ "token": data.get("chain_data", {}).get("token"),
177
+ "multisig": data.get("chain_data", {}).get("multisig"),
178
+ "staked": data.get("chain_data", {}).get("staked", False),
179
+ "on_chain_state": data.get("chain_data", {}).get(
180
+ "on_chain_state", 3
181
+ ),
182
+ "user_params": {
183
+ "staking_program_id": "pearl_alpha",
184
+ "nft": data.get("chain_data", {})
185
+ .get("user_params", {})
186
+ .get("nft"),
187
+ "threshold": data.get("chain_data", {})
188
+ .get("user_params", {})
189
+ .get("threshold"),
190
+ "use_staking": data.get("chain_data", {})
191
+ .get("user_params", {})
192
+ .get("use_staking"),
193
+ "cost_of_bond": data.get("chain_data", {})
194
+ .get("user_params", {})
195
+ .get("cost_of_bond"),
196
+ "fund_requirements": data.get("chain_data", {})
197
+ .get("user_params", {})
198
+ .get("fund_requirements", {}),
199
+ "agent_id": data.get("chain_data", {})
200
+ .get("user_params", {})
201
+ .get("agent_id", "14"),
202
+ },
203
+ },
204
+ }
205
+ },
206
+ "service_path": data.get("service_path", ""),
207
+ "name": data.get("name", ""),
208
+ }
209
+ data = new_data
210
+
211
+ if version < 4:
212
+ # Add missing fields introduced in later versions, if necessary.
213
+ for _, chain_data in data.get("chain_configs", {}).items():
214
+ chain_data.setdefault("chain_data", {}).setdefault(
215
+ "user_params", {}
216
+ ).setdefault("use_mech_marketplace", False)
217
+ service_name = data.get("name", "")
218
+ agent_id = Service.determine_agent_id(service_name)
219
+ chain_data.setdefault("chain_data", {}).setdefault("user_params", {})[
220
+ "agent_id"
221
+ ] = agent_id
222
+
223
+ data["description"] = data.setdefault("description", data.get("name"))
224
+ data["hash_history"] = data.setdefault(
225
+ "hash_history", {int(time()): data["hash"]}
226
+ )
227
+
228
+ if "service_config_id" not in data:
229
+ service_config_id = Service.get_new_service_config_id(path)
230
+ new_path = path.parent / service_config_id
231
+ data["service_config_id"] = service_config_id
232
+ path = path.rename(new_path)
233
+
234
+ old_to_new_ledgers = ["ethereum", "solana"]
235
+ for key_data in data["keys"]:
236
+ key_data["ledger"] = old_to_new_ledgers[key_data["ledger"]]
237
+
238
+ old_to_new_chains = [
239
+ "ethereum",
240
+ "goerli",
241
+ "gnosis",
242
+ "solana",
243
+ "optimism",
244
+ "base",
245
+ "mode",
246
+ ]
247
+ new_chain_configs = {}
248
+ for chain_id, chain_data in data["chain_configs"].items():
249
+ chain_data["ledger_config"]["chain"] = old_to_new_chains[
250
+ chain_data["ledger_config"]["chain"]
251
+ ]
252
+ del chain_data["ledger_config"]["type"]
253
+ new_chain_configs[Chain.from_id(int(chain_id)).value] = chain_data # type: ignore
254
+
255
+ data["chain_configs"] = new_chain_configs
256
+ data["home_chain"] = data.setdefault("home_chain", Chain.from_id(int(data.get("home_chain_id", "100"))).value) # type: ignore
257
+ del data["home_chain_id"]
258
+
259
+ if "env_variables" not in data:
260
+ if data["name"] == "valory/trader_pearl":
261
+ data["env_variables"] = DEFAULT_TRADER_ENV_VARS
262
+ else:
263
+ data["env_variables"] = {}
264
+
265
+ if version < 5:
266
+ new_chain_configs = {}
267
+ for chain, chain_data in data["chain_configs"].items():
268
+ fund_requirements = chain_data["chain_data"]["user_params"][
269
+ "fund_requirements"
270
+ ]
271
+ if ZERO_ADDRESS not in fund_requirements:
272
+ chain_data["chain_data"]["user_params"]["fund_requirements"] = {
273
+ ZERO_ADDRESS: fund_requirements
274
+ }
275
+
276
+ new_chain_configs[chain] = chain_data # type: ignore
277
+ data["chain_configs"] = new_chain_configs
278
+
279
+ if version < 7:
280
+ for _, chain_data in data.get("chain_configs", {}).items():
281
+ if chain_data["chain_data"]["multisig"] == "0xm":
282
+ chain_data["chain_data"]["multisig"] = NON_EXISTENT_MULTISIG
283
+
284
+ data["agent_addresses"] = [key["address"] for key in data["keys"]]
285
+ del data["keys"]
286
+
287
+ if version < 8:
288
+ if data["home_chain"] == "optimistic":
289
+ data["home_chain"] = Chain.OPTIMISM.value
290
+
291
+ if "optimistic" in data["chain_configs"]:
292
+ data["chain_configs"]["optimism"] = data["chain_configs"].pop(
293
+ "optimistic"
294
+ )
295
+
296
+ for _, chain_config in data["chain_configs"].items():
297
+ if chain_config["ledger_config"]["chain"] == "optimistic":
298
+ chain_config["ledger_config"]["chain"] = Chain.OPTIMISM.value
299
+
300
+ data["version"] = SERVICE_CONFIG_VERSION
301
+
302
+ # Redownload service path
303
+ if "service_path" in data:
304
+ package_absolute_path = path / Path(data["service_path"]).name
305
+ data.pop("service_path")
306
+ else:
307
+ package_absolute_path = path / data["package_path"]
308
+
309
+ if package_absolute_path.exists() and package_absolute_path.is_dir():
310
+ shutil.rmtree(package_absolute_path)
311
+
312
+ package_absolute_path = Path(
313
+ IPFSTool().download(
314
+ hash_id=data["hash"],
315
+ target_dir=path,
316
+ )
317
+ )
318
+ data["package_path"] = str(package_absolute_path.name)
319
+
320
+ with open(
321
+ path / Service._file, # pylint: disable=protected-access
322
+ "w",
323
+ encoding="utf-8",
324
+ ) as file:
325
+ json.dump(data, file, indent=2)
326
+
327
+ return True
328
+
329
+ def migrate_services(self, service_manager: ServiceManager) -> None:
330
+ """Migrate old service config formats to new ones, if applies."""
331
+ self.log_directories(service_manager.path)
332
+ self.logger.info("Migrating service configs...")
333
+
334
+ bafybei_count = sum(
335
+ 1
336
+ for path in service_manager.path.iterdir()
337
+ if path.name.startswith("bafybei")
338
+ )
339
+ if bafybei_count > 1:
340
+ raise RuntimeError(
341
+ f"Your services folder contains {bafybei_count} folders starting with 'bafybei'. This is an unintended situation. Please contact support."
342
+ )
343
+
344
+ paths = list(service_manager.path.iterdir())
345
+ for path in paths:
346
+ try:
347
+ if path.name.startswith(SERVICE_CONFIG_PREFIX) or path.name.startswith(
348
+ "bafybei"
349
+ ):
350
+ self.logger.info(f"migrate_service_configs {str(path)}")
351
+ migrated = self._migrate_service(path)
352
+ if migrated:
353
+ self.logger.info(f"Folder {str(path)} has been migrated.")
354
+ except Exception as e: # pylint: disable=broad-except
355
+ self.logger.error(
356
+ f"Failed to migrate service: {path.name}. Exception {e}: {traceback.format_exc()}"
357
+ )
358
+
359
+ self.logger.info("Migrating service configs done.")
360
+ self.log_directories(service_manager.path)
361
+
362
+ def migrate_qs_configs(self) -> None:
363
+ """Migrates quickstart configs."""
364
+
365
+ for qs_config in self._path.glob("*-quickstart-config.json"):
366
+ if not qs_config.exists():
367
+ continue
368
+
369
+ migrated = False
370
+ with open(qs_config, "r", encoding="utf-8") as f:
371
+ data = json.load(f)
372
+
373
+ if "optimistic" in data.get("rpc", {}):
374
+ data["rpc"]["optimism"] = data["rpc"].pop("optimistic")
375
+ migrated = True
376
+
377
+ if "optimistic" == data.get("principal_chain", ""):
378
+ data["principal_chain"] = "optimism"
379
+ migrated = True
380
+
381
+ if not migrated:
382
+ continue
383
+
384
+ with open(qs_config, "w", encoding="utf-8") as f:
385
+ json.dump(data, f, indent=2)
386
+
387
+ self.logger.info(
388
+ "[MIGRATION MANAGER] Migrated quickstart config: %s.", qs_config.name
389
+ )
operate/operate_types.py CHANGED
@@ -28,16 +28,10 @@ from autonomy.chain.config import ChainType
28
28
  from autonomy.chain.constants import CHAIN_NAME_TO_CHAIN_ID
29
29
  from typing_extensions import TypedDict
30
30
 
31
+ from operate.constants import NO_STAKING_PROGRAM_ID
31
32
  from operate.resource import LocalResource
32
33
 
33
34
 
34
- _ACTIONS = {
35
- "status": 0,
36
- "build": 1,
37
- "deploy": 2,
38
- "stop": 3,
39
- }
40
-
41
35
  CHAIN_NAME_TO_CHAIN_ID["solana"] = 900
42
36
 
43
37
  _CHAIN_ID_TO_CHAIN_NAME = {
@@ -127,20 +121,6 @@ for name in dir(ChainMixin):
127
121
  setattr(Chain, name, getattr(ChainMixin, name))
128
122
 
129
123
 
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
124
  class DeploymentStatus(enum.IntEnum):
145
125
  """Status payload."""
146
126
 
@@ -208,9 +188,6 @@ class ConfigurationTemplate(TypedDict):
208
188
  nft: str
209
189
  rpc: str
210
190
  agent_id: int
211
- threshold: int
212
- use_staking: bool
213
- use_mech_marketplace: bool
214
191
  cost_of_bond: int
215
192
  fund_requirements: t.Dict[str, FundRequirementsTemplate]
216
193
  fallback_chain_params: t.Optional[t.Dict]
@@ -275,13 +252,18 @@ class OnChainUserParams(LocalResource):
275
252
 
276
253
  staking_program_id: str
277
254
  nft: str
278
- threshold: int
279
255
  agent_id: int
280
- use_staking: bool
281
- use_mech_marketplace: bool
282
256
  cost_of_bond: int
283
257
  fund_requirements: OnChainTokenRequirements
284
258
 
259
+ @property
260
+ def use_staking(self) -> bool:
261
+ """Check if staking is used."""
262
+ return (
263
+ self.staking_program_id is not None
264
+ and self.staking_program_id != NO_STAKING_PROGRAM_ID
265
+ )
266
+
285
267
  @classmethod
286
268
  def from_json(cls, obj: t.Dict) -> "OnChainUserParams":
287
269
  """Load a service"""
@@ -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 DEPLOYMENT
28
+ from operate.constants import DEPLOYMENT_DIR
29
29
 
30
30
 
31
31
  if TYPE_CHECKING:
@@ -38,10 +38,10 @@ def find_build_directory(config_file: Path, operate: "OperateApp") -> Path:
38
38
  config = json.load(f)
39
39
  config_service_hash = config.get("hash")
40
40
 
41
- services = operate.service_manager()._get_all_services()
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 / DEPLOYMENT
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)
@@ -107,9 +107,6 @@ def analyse_logs(
107
107
  print(f"Config file '{config_file}' not found.")
108
108
  sys.exit(1)
109
109
 
110
- operate.service_manager().migrate_service_configs()
111
- operate.wallet_manager.migrate_wallet_configs()
112
-
113
110
  # Auto-detect the logs directory
114
111
  build_dir = find_build_directory(config_file, operate)
115
112
  logs_dir = build_dir / "persistent_data" / "logs"
@@ -48,9 +48,6 @@ def claim_staking_rewards(operate: "OperateApp", config_path: str) -> None:
48
48
 
49
49
  print_section(f"Claim staking rewards for {template['name']}")
50
50
 
51
- operate.service_manager().migrate_service_configs()
52
- operate.wallet_manager.migrate_wallet_configs()
53
-
54
51
  # check if agent was started before
55
52
  config = load_local_config(
56
53
  operate=operate, service_name=cast(str, template["name"])
@@ -70,10 +67,10 @@ def claim_staking_rewards(operate: "OperateApp", config_path: str) -> None:
70
67
 
71
68
  print("")
72
69
 
70
+ ask_password_if_needed(operate)
73
71
  config = configure_local_config(template, operate)
74
72
  manager = operate.service_manager()
75
73
  service = get_service(manager, template)
76
- ask_password_if_needed(operate)
77
74
 
78
75
  # reload manger and config after setting operate.password
79
76
  manager = operate.service_manager()
@@ -70,9 +70,6 @@ def reset_configs(operate: "OperateApp", config_path: str) -> None:
70
70
  with open(config_path, "r") as config_file:
71
71
  template = json.load(config_file)
72
72
 
73
- operate.service_manager().migrate_service_configs()
74
- operate.wallet_manager.migrate_wallet_configs()
75
-
76
73
  print_title(f"Reset your {template['name']} configurations")
77
74
 
78
75
  # check if agent was started before
@@ -35,9 +35,6 @@ def reset_password(operate: "OperateApp") -> None:
35
35
  """Reset password."""
36
36
  print_title("Reset your password")
37
37
 
38
- operate.service_manager().migrate_service_configs()
39
- operate.wallet_manager.migrate_wallet_configs()
40
-
41
38
  # check if agent was started before
42
39
  if not (operate._path / "user.json").exists():
43
40
  print("No previous agent setup found. Exiting.")
@@ -22,7 +22,8 @@ import json
22
22
  import os
23
23
  from typing import TYPE_CHECKING, cast
24
24
 
25
- from operate.ledger.profiles import NO_STAKING_PROGRAM_ID, get_staking_contract
25
+ from operate.constants import NO_STAKING_PROGRAM_ID
26
+ from operate.ledger.profiles import get_staking_contract
26
27
  from operate.quickstart.run_service import (
27
28
  CUSTOM_PROGRAM_ID,
28
29
  ask_password_if_needed,
@@ -44,9 +45,6 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
44
45
  with open(config_path, "r") as config_file:
45
46
  template = json.load(config_file)
46
47
 
47
- operate.service_manager().migrate_service_configs()
48
- operate.wallet_manager.migrate_wallet_configs()
49
-
50
48
  print_title("Reset your staking program preference")
51
49
 
52
50
  # check if agent was started before
@@ -57,6 +55,7 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
57
55
  print("No previous agent setup found. Exiting.")
58
56
  return
59
57
 
58
+ ask_password_if_needed(operate)
60
59
  config = configure_local_config(template, operate)
61
60
  assert ( # nosec
62
61
  config.principal_chain is not None
@@ -82,7 +81,6 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
82
81
  print("Cancelled.")
83
82
  return
84
83
 
85
- ask_password_if_needed(operate)
86
84
  manager = operate.service_manager()
87
85
  service = get_service(manager, template)
88
86