olas-operate-middleware 0.7.0__tar.gz → 0.8.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.7.0 → olas_operate_middleware-0.8.0}/PKG-INFO +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/bridge/providers/relay_provider.py +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/cli.py +114 -105
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/ledger/profiles.py +9 -35
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/operate_types.py +10 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/claim_staking_rewards.py +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/reset_staking.py +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/run_service.py +19 -26
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/terminate_on_chain_service.py +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/utils.py +0 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/agent_runner.py +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/manage.py +126 -99
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/pyproject.toml +1 -1
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/LICENSE +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/README.md +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/account/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/account/user.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/bridge/bridge_manager.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/bridge/providers/lifi_provider.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/bridge/providers/native_bridge_provider.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/bridge/providers/provider.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/constants.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/README.md +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/dual_staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/dual_staking_token/build/DualStakingToken.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/dual_staking_token/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/dual_staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/foreign_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/foreign_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/foreign_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/home_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/home_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/home_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l1_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l1_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l1_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l2_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l2_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/l2_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/mech_activity/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/mech_activity/build/MechActivity.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/mech_activity/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/mech_activity/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/optimism_mintable_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/optimism_mintable_erc20/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/optimism_mintable_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/requester_activity_checker/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/requester_activity_checker/build/RequesterActivityChecker.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/requester_activity_checker/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/requester_activity_checker/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/staking_token/build/StakingToken.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/staking_token/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/build/IUniswapV2ERC20.json +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/tests/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/keys.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/ledger/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/migration.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/operate_http/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/operate_http/exceptions.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/pearl.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/analyse_logs.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/reset_configs.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/reset_password.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/stop_service.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/resource.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/deployment_runner.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/health_checker.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/protocol.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/service.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/utils/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/utils/mech.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/services/utils/tendermint.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/utils/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/utils/gnosis.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/wallet/__init__.py +0 -0
- {olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/wallet/master.py +0 -0
|
@@ -173,7 +173,7 @@ class RelayProvider(Provider):
|
|
|
173
173
|
"destinationChainId": Chain(to_chain).id,
|
|
174
174
|
"recipient": to_address,
|
|
175
175
|
"destinationCurrency": to_token,
|
|
176
|
-
"amount": to_amount,
|
|
176
|
+
"amount": str(to_amount),
|
|
177
177
|
"tradeType": "EXACT_OUTPUT",
|
|
178
178
|
"enableTrueExactOutput": False,
|
|
179
179
|
}
|
|
@@ -75,12 +75,13 @@ from operate.utils.gnosis import get_assets_balances
|
|
|
75
75
|
from operate.wallet.master import MasterWalletManager
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
DEFAULT_HARDHAT_KEY = (
|
|
79
|
-
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
|
|
80
|
-
).encode()
|
|
81
78
|
DEFAULT_MAX_RETRIES = 3
|
|
82
79
|
USER_NOT_LOGGED_IN_ERROR = JSONResponse(
|
|
83
|
-
content={"error": "User not logged in
|
|
80
|
+
content={"error": "User not logged in."}, status_code=HTTPStatus.UNAUTHORIZED
|
|
81
|
+
)
|
|
82
|
+
ACCOUNT_NOT_FOUND_ERROR = JSONResponse(
|
|
83
|
+
content={"error": "User account not found."},
|
|
84
|
+
status_code=HTTPStatus.NOT_FOUND,
|
|
84
85
|
)
|
|
85
86
|
|
|
86
87
|
|
|
@@ -130,7 +131,7 @@ class OperateApp:
|
|
|
130
131
|
"""Updates current password"""
|
|
131
132
|
|
|
132
133
|
if not new_password:
|
|
133
|
-
raise ValueError("
|
|
134
|
+
raise ValueError("'password' is required.")
|
|
134
135
|
|
|
135
136
|
if not (
|
|
136
137
|
self.user_account.is_valid(old_password)
|
|
@@ -147,7 +148,7 @@ class OperateApp:
|
|
|
147
148
|
"""Updates current password using the mnemonic"""
|
|
148
149
|
|
|
149
150
|
if not new_password:
|
|
150
|
-
raise ValueError("
|
|
151
|
+
raise ValueError("'password' is required.")
|
|
151
152
|
|
|
152
153
|
mnemonic = mnemonic.strip().lower()
|
|
153
154
|
if not self.wallet_manager.is_mnemonic_valid(mnemonic):
|
|
@@ -352,30 +353,27 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
352
353
|
"""Call the endpoint."""
|
|
353
354
|
logger.info(f"Calling `{f.__name__}` with retries enabled")
|
|
354
355
|
retries = 0
|
|
355
|
-
errors = []
|
|
356
356
|
while retries < DEFAULT_MAX_RETRIES:
|
|
357
357
|
try:
|
|
358
358
|
return await f(request)
|
|
359
359
|
except (APIError, ProjectError) as e:
|
|
360
360
|
logger.error(f"Error {e}\n{traceback.format_exc()}")
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
error["error"] = "Service is already running"
|
|
361
|
+
if "has active endpoints" in str(e):
|
|
362
|
+
error_msg = "Service is already running."
|
|
364
363
|
else:
|
|
365
|
-
|
|
366
|
-
errors.append(error)
|
|
364
|
+
error_msg = "Service deployment failed. Please check the logs."
|
|
367
365
|
return JSONResponse(
|
|
368
|
-
content={"
|
|
366
|
+
content={"error": error_msg},
|
|
369
367
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
370
368
|
)
|
|
371
369
|
except Exception as e: # pylint: disable=broad-except
|
|
372
|
-
|
|
373
|
-
{"error": str(e.args[0]), "traceback": traceback.format_exc()}
|
|
374
|
-
)
|
|
375
|
-
logger.error(f"Error {str(e.args[0])}\n{traceback.format_exc()}")
|
|
370
|
+
logger.error(f"Error {str(e)}\n{traceback.format_exc()}")
|
|
376
371
|
retries += 1
|
|
377
372
|
return JSONResponse(
|
|
378
|
-
content={
|
|
373
|
+
content={
|
|
374
|
+
"error": "Operation failed after multiple attempts. Please try again later."
|
|
375
|
+
},
|
|
376
|
+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
379
377
|
)
|
|
380
378
|
|
|
381
379
|
return _call
|
|
@@ -413,7 +411,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
413
411
|
"""Setup account."""
|
|
414
412
|
if operate.user_account is not None:
|
|
415
413
|
return JSONResponse(
|
|
416
|
-
content={"error": "Account already exists"},
|
|
414
|
+
content={"error": "Account already exists."},
|
|
417
415
|
status_code=HTTPStatus.CONFLICT,
|
|
418
416
|
)
|
|
419
417
|
|
|
@@ -436,10 +434,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
436
434
|
) -> t.Dict:
|
|
437
435
|
"""Update password."""
|
|
438
436
|
if operate.user_account is None:
|
|
439
|
-
return
|
|
440
|
-
content={"error": "Account does not exist."},
|
|
441
|
-
status_code=HTTPStatus.CONFLICT,
|
|
442
|
-
)
|
|
437
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
443
438
|
|
|
444
439
|
data = await request.json()
|
|
445
440
|
old_password = data.get("old_password")
|
|
@@ -449,7 +444,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
449
444
|
if not old_password and not mnemonic:
|
|
450
445
|
return JSONResponse(
|
|
451
446
|
content={
|
|
452
|
-
"error": "
|
|
447
|
+
"error": "Exactly one of 'old_password' or 'mnemonic' (seed phrase) is required.",
|
|
453
448
|
},
|
|
454
449
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
455
450
|
)
|
|
@@ -457,7 +452,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
457
452
|
if old_password and mnemonic:
|
|
458
453
|
return JSONResponse(
|
|
459
454
|
content={
|
|
460
|
-
"error": "
|
|
455
|
+
"error": "Exactly one of 'old_password' or 'mnemonic' (seed phrase) is required.",
|
|
461
456
|
},
|
|
462
457
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
463
458
|
)
|
|
@@ -465,7 +460,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
465
460
|
if not new_password or len(new_password) < MIN_PASSWORD_LENGTH:
|
|
466
461
|
return JSONResponse(
|
|
467
462
|
content={
|
|
468
|
-
"error": f"
|
|
463
|
+
"error": f"New password must be at least {MIN_PASSWORD_LENGTH} characters long."
|
|
469
464
|
},
|
|
470
465
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
471
466
|
)
|
|
@@ -474,27 +469,31 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
474
469
|
if old_password:
|
|
475
470
|
operate.update_password(old_password, new_password)
|
|
476
471
|
return JSONResponse(
|
|
477
|
-
content={"error": None, "message": "Password updated."}
|
|
472
|
+
content={"error": None, "message": "Password updated successfully."}
|
|
478
473
|
)
|
|
479
474
|
if mnemonic:
|
|
480
475
|
operate.update_password_with_mnemonic(mnemonic, new_password)
|
|
481
476
|
return JSONResponse(
|
|
482
477
|
content={
|
|
483
478
|
"error": None,
|
|
484
|
-
"message": "Password updated using seed phrase.",
|
|
479
|
+
"message": "Password updated successfully using seed phrase.",
|
|
485
480
|
}
|
|
486
481
|
)
|
|
487
482
|
|
|
488
483
|
return JSONResponse(
|
|
489
|
-
content={"error":
|
|
484
|
+
content={"error": "Password update failed."},
|
|
485
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
490
486
|
)
|
|
491
487
|
except ValueError as e:
|
|
488
|
+
logger.error(f"Password update error: {e}\n{traceback.format_exc()}")
|
|
492
489
|
return JSONResponse(
|
|
493
|
-
content={"error": str(e)},
|
|
490
|
+
content={"error": f"Failed to update password: {str(e)}"},
|
|
491
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
494
492
|
)
|
|
495
493
|
except Exception as e: # pylint: disable=broad-except
|
|
494
|
+
logger.error(f"Password update error: {e}\n{traceback.format_exc()}")
|
|
496
495
|
return JSONResponse(
|
|
497
|
-
content={"error":
|
|
496
|
+
content={"error": "Failed to update password. Please check the logs."},
|
|
498
497
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
499
498
|
)
|
|
500
499
|
|
|
@@ -503,21 +502,18 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
503
502
|
async def _validate_password(request: Request) -> t.Dict:
|
|
504
503
|
"""Validate password."""
|
|
505
504
|
if operate.user_account is None:
|
|
506
|
-
return
|
|
507
|
-
content={"error": "Account does not exist"},
|
|
508
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
509
|
-
)
|
|
505
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
510
506
|
|
|
511
507
|
data = await request.json()
|
|
512
508
|
if not operate.user_account.is_valid(password=data["password"]):
|
|
513
509
|
return JSONResponse(
|
|
514
|
-
content={"error": "Password is not valid"},
|
|
510
|
+
content={"error": "Password is not valid."},
|
|
515
511
|
status_code=HTTPStatus.UNAUTHORIZED,
|
|
516
512
|
)
|
|
517
513
|
|
|
518
514
|
operate.password = data["password"]
|
|
519
515
|
return JSONResponse(
|
|
520
|
-
content={"message": "Login successful"},
|
|
516
|
+
content={"message": "Login successful."},
|
|
521
517
|
status_code=HTTPStatus.OK,
|
|
522
518
|
)
|
|
523
519
|
|
|
@@ -535,16 +531,10 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
535
531
|
async def _create_wallet(request: Request) -> t.List[t.Dict]:
|
|
536
532
|
"""Create wallet"""
|
|
537
533
|
if operate.user_account is None:
|
|
538
|
-
return
|
|
539
|
-
content={"error": "Cannot create wallet; User account does not exist!"},
|
|
540
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
541
|
-
)
|
|
534
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
542
535
|
|
|
543
536
|
if operate.password is None:
|
|
544
|
-
return
|
|
545
|
-
content={"error": "You need to login before creating a wallet"},
|
|
546
|
-
status_code=HTTPStatus.UNAUTHORIZED,
|
|
547
|
-
)
|
|
537
|
+
return USER_NOT_LOGGED_IN_ERROR
|
|
548
538
|
|
|
549
539
|
data = await request.json()
|
|
550
540
|
ledger_type = LedgerType(data["ledger_type"])
|
|
@@ -564,23 +554,15 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
564
554
|
async def _get_private_key(request: Request) -> t.List[t.Dict]:
|
|
565
555
|
"""Get Master EOA private key."""
|
|
566
556
|
if operate.user_account is None:
|
|
567
|
-
return
|
|
568
|
-
content={
|
|
569
|
-
"error": "Cannot retrieve private key; User account does not exist!"
|
|
570
|
-
},
|
|
571
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
572
|
-
)
|
|
557
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
573
558
|
|
|
574
559
|
data = await request.json()
|
|
575
560
|
password = data.get("password")
|
|
576
|
-
error = None
|
|
577
561
|
if operate.password is None:
|
|
578
|
-
|
|
562
|
+
return USER_NOT_LOGGED_IN_ERROR
|
|
579
563
|
if operate.password != password:
|
|
580
|
-
error = {"error": "Password is not valid"}
|
|
581
|
-
if error is not None:
|
|
582
564
|
return JSONResponse(
|
|
583
|
-
content=error,
|
|
565
|
+
content={"error": "Password is not valid."},
|
|
584
566
|
status_code=HTTPStatus.UNAUTHORIZED,
|
|
585
567
|
)
|
|
586
568
|
|
|
@@ -618,12 +600,15 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
618
600
|
manager = operate.wallet_manager
|
|
619
601
|
if not manager.exists(ledger_type=ledger_type):
|
|
620
602
|
return JSONResponse(
|
|
621
|
-
content={"error": "
|
|
603
|
+
content={"error": "No Master EOA found for this chain."},
|
|
622
604
|
status_code=HTTPStatus.NOT_FOUND,
|
|
623
605
|
)
|
|
624
606
|
safes = manager.load(ledger_type=ledger_type).safes
|
|
625
607
|
if safes is None or safes.get(chain) is None:
|
|
626
|
-
return JSONResponse(
|
|
608
|
+
return JSONResponse(
|
|
609
|
+
content={"error": "No Master Safe found for this chain."},
|
|
610
|
+
status_code=HTTPStatus.NOT_FOUND,
|
|
611
|
+
)
|
|
627
612
|
|
|
628
613
|
return JSONResponse(
|
|
629
614
|
content={
|
|
@@ -637,23 +622,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
637
622
|
) -> t.List[t.Dict]:
|
|
638
623
|
"""Create wallet safe"""
|
|
639
624
|
if operate.user_account is None:
|
|
640
|
-
return
|
|
641
|
-
content={"error": "Cannot create safe; User account does not exist!"},
|
|
642
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
643
|
-
)
|
|
625
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
644
626
|
|
|
645
627
|
if operate.password is None:
|
|
646
|
-
return
|
|
647
|
-
content={"error": "You need to login before creating a safe"},
|
|
648
|
-
status_code=HTTPStatus.UNAUTHORIZED,
|
|
649
|
-
)
|
|
628
|
+
return USER_NOT_LOGGED_IN_ERROR
|
|
650
629
|
|
|
651
630
|
data = await request.json()
|
|
652
631
|
|
|
653
632
|
if "initial_funds" in data and "transfer_excess_assets" in data:
|
|
654
633
|
return JSONResponse(
|
|
655
634
|
content={
|
|
656
|
-
"error": "
|
|
635
|
+
"error": "Only specify one of 'initial_funds' or 'transfer_excess_assets', but not both."
|
|
657
636
|
},
|
|
658
637
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
659
638
|
)
|
|
@@ -664,14 +643,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
664
643
|
ledger_type = chain.ledger_type
|
|
665
644
|
manager = operate.wallet_manager
|
|
666
645
|
if not manager.exists(ledger_type=ledger_type):
|
|
667
|
-
return JSONResponse(
|
|
646
|
+
return JSONResponse(
|
|
647
|
+
content={"error": "No Master EOA found for this chain."},
|
|
648
|
+
status_code=HTTPStatus.NOT_FOUND,
|
|
649
|
+
)
|
|
668
650
|
|
|
669
651
|
wallet = manager.load(ledger_type=ledger_type)
|
|
670
652
|
if wallet.safes is not None and wallet.safes.get(chain) is not None:
|
|
671
653
|
return JSONResponse(
|
|
672
654
|
content={
|
|
673
655
|
"safe": wallet.safes.get(chain),
|
|
674
|
-
"message":
|
|
656
|
+
"message": "Safe already exists for this chain.",
|
|
675
657
|
}
|
|
676
658
|
)
|
|
677
659
|
|
|
@@ -725,14 +707,15 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
725
707
|
"create_tx": create_tx,
|
|
726
708
|
"transfer_txs": transfer_txs,
|
|
727
709
|
"safe": safes.get(chain),
|
|
728
|
-
"message": "Safe created
|
|
729
|
-
}
|
|
710
|
+
"message": "Safe created successfully",
|
|
711
|
+
},
|
|
712
|
+
status_code=HTTPStatus.CREATED,
|
|
730
713
|
)
|
|
731
714
|
except Exception as e: # pylint: disable=broad-except
|
|
732
|
-
logger.error(traceback.format_exc())
|
|
715
|
+
logger.error(f"Safe creation failed: {e}\n{traceback.format_exc()}")
|
|
733
716
|
return JSONResponse(
|
|
734
717
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
735
|
-
content={"error":
|
|
718
|
+
content={"error": "Failed to create safe. Please check the logs."},
|
|
736
719
|
)
|
|
737
720
|
|
|
738
721
|
@app.put("/api/wallet/safe")
|
|
@@ -741,22 +724,16 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
741
724
|
"""Update wallet safe"""
|
|
742
725
|
# TODO: Extract login check as decorator
|
|
743
726
|
if operate.user_account is None:
|
|
744
|
-
return
|
|
745
|
-
content={"error": "Cannot update safe; User account does not exist!"},
|
|
746
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
747
|
-
)
|
|
727
|
+
return ACCOUNT_NOT_FOUND_ERROR
|
|
748
728
|
|
|
749
729
|
if operate.password is None:
|
|
750
|
-
return
|
|
751
|
-
content={"error": "You need to login before updating a safe."},
|
|
752
|
-
status_code=HTTPStatus.UNAUTHORIZED,
|
|
753
|
-
)
|
|
730
|
+
return USER_NOT_LOGGED_IN_ERROR
|
|
754
731
|
|
|
755
732
|
data = await request.json()
|
|
756
733
|
|
|
757
734
|
if "chain" not in data:
|
|
758
735
|
return JSONResponse(
|
|
759
|
-
content={"error": "
|
|
736
|
+
content={"error": "'chain' is required."},
|
|
760
737
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
761
738
|
)
|
|
762
739
|
|
|
@@ -765,7 +742,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
765
742
|
manager = operate.wallet_manager
|
|
766
743
|
if not manager.exists(ledger_type=ledger_type):
|
|
767
744
|
return JSONResponse(
|
|
768
|
-
content={"error": "
|
|
745
|
+
content={"error": "No Master EOA found for this chain."},
|
|
769
746
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
770
747
|
)
|
|
771
748
|
|
|
@@ -778,12 +755,12 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
778
755
|
|
|
779
756
|
backup_owner_updated = wallet.update_backup_owner(
|
|
780
757
|
chain=chain,
|
|
781
|
-
backup_owner=backup_owner,
|
|
758
|
+
backup_owner=backup_owner,
|
|
782
759
|
)
|
|
783
760
|
message = (
|
|
784
|
-
"Backup owner updated
|
|
761
|
+
"Backup owner updated successfully"
|
|
785
762
|
if backup_owner_updated
|
|
786
|
-
else "
|
|
763
|
+
else "Backup owner is already set to this address"
|
|
787
764
|
)
|
|
788
765
|
return JSONResponse(
|
|
789
766
|
content={
|
|
@@ -968,7 +945,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
968
945
|
withdrawal_address = (await request.json()).get("withdrawal_address")
|
|
969
946
|
if withdrawal_address is None:
|
|
970
947
|
return JSONResponse(
|
|
971
|
-
content={"error": "withdrawal_address is required"},
|
|
948
|
+
content={"error": "'withdrawal_address' is required"},
|
|
972
949
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
973
950
|
)
|
|
974
951
|
|
|
@@ -1010,13 +987,13 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1010
987
|
from_safe=False,
|
|
1011
988
|
)
|
|
1012
989
|
except Exception as e: # pylint: disable=broad-except
|
|
1013
|
-
logger.error(traceback.format_exc())
|
|
990
|
+
logger.error(f"Withdrawal failed: {e}\n{traceback.format_exc()}")
|
|
1014
991
|
return JSONResponse(
|
|
1015
992
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1016
|
-
content={"error":
|
|
993
|
+
content={"error": "Failed to withdraw funds. Please check the logs."},
|
|
1017
994
|
)
|
|
1018
995
|
|
|
1019
|
-
return JSONResponse(content={"error": None})
|
|
996
|
+
return JSONResponse(content={"error": None, "message": "Withdrawal successful"})
|
|
1020
997
|
|
|
1021
998
|
@app.post("/api/bridge/bridge_refill_requirements")
|
|
1022
999
|
@with_retries
|
|
@@ -1037,19 +1014,26 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1037
1014
|
status_code=HTTPStatus.OK,
|
|
1038
1015
|
)
|
|
1039
1016
|
except ValueError as e:
|
|
1017
|
+
logger.error(f"Bridge refill requirements error: {e}")
|
|
1040
1018
|
return JSONResponse(
|
|
1041
|
-
content={"error":
|
|
1019
|
+
content={"error": "Invalid bridge request parameters."},
|
|
1020
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
1042
1021
|
)
|
|
1043
1022
|
except Exception as e: # pylint: disable=broad-except
|
|
1023
|
+
logger.error(
|
|
1024
|
+
f"Bridge refill requirements error: {e}\n{traceback.format_exc()}"
|
|
1025
|
+
)
|
|
1044
1026
|
return JSONResponse(
|
|
1045
|
-
content={
|
|
1027
|
+
content={
|
|
1028
|
+
"error": "Failed to get bridge requirements. Please check the logs."
|
|
1029
|
+
},
|
|
1046
1030
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1047
1031
|
)
|
|
1048
1032
|
|
|
1049
1033
|
@app.post("/api/bridge/execute")
|
|
1050
1034
|
@with_retries
|
|
1051
1035
|
async def _bridge_execute(request: Request) -> JSONResponse:
|
|
1052
|
-
"""
|
|
1036
|
+
"""Execute bridge transaction."""
|
|
1053
1037
|
if operate.password is None:
|
|
1054
1038
|
return USER_NOT_LOGGED_IN_ERROR
|
|
1055
1039
|
|
|
@@ -1062,12 +1046,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1062
1046
|
status_code=HTTPStatus.OK,
|
|
1063
1047
|
)
|
|
1064
1048
|
except ValueError as e:
|
|
1049
|
+
logger.error(f"Bridge execute error: {e}")
|
|
1065
1050
|
return JSONResponse(
|
|
1066
|
-
content={"error":
|
|
1051
|
+
content={"error": "Invalid bundle ID or transaction failed."},
|
|
1052
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
1067
1053
|
)
|
|
1068
1054
|
except Exception as e: # pylint: disable=broad-except
|
|
1055
|
+
logger.error(f"Bridge execute error: {e}\n{traceback.format_exc()}")
|
|
1069
1056
|
return JSONResponse(
|
|
1070
|
-
content={
|
|
1057
|
+
content={
|
|
1058
|
+
"error": "Failed to execute bridge transaction. Please check the logs."
|
|
1059
|
+
},
|
|
1071
1060
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1072
1061
|
)
|
|
1073
1062
|
|
|
@@ -1081,7 +1070,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1081
1070
|
@app.get("/api/bridge/status/{id}")
|
|
1082
1071
|
@with_retries
|
|
1083
1072
|
async def _bridge_status(request: Request) -> JSONResponse:
|
|
1084
|
-
"""Get
|
|
1073
|
+
"""Get bridge transaction status."""
|
|
1085
1074
|
|
|
1086
1075
|
quote_bundle_id = request.path_params["id"]
|
|
1087
1076
|
|
|
@@ -1093,12 +1082,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1093
1082
|
status_code=HTTPStatus.OK,
|
|
1094
1083
|
)
|
|
1095
1084
|
except ValueError as e:
|
|
1085
|
+
logger.error(f"Bridge status error: {e}")
|
|
1096
1086
|
return JSONResponse(
|
|
1097
|
-
content={"error":
|
|
1087
|
+
content={"error": "Invalid bundle ID."},
|
|
1088
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
1098
1089
|
)
|
|
1099
1090
|
except Exception as e: # pylint: disable=broad-except
|
|
1091
|
+
logger.error(f"Bridge status error: {e}\n{traceback.format_exc()}")
|
|
1100
1092
|
return JSONResponse(
|
|
1101
|
-
content={
|
|
1093
|
+
content={
|
|
1094
|
+
"error": "Failed to get bridge status. Please check the logs."
|
|
1095
|
+
},
|
|
1102
1096
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1103
1097
|
)
|
|
1104
1098
|
|
|
@@ -1114,20 +1108,35 @@ def _operate() -> None:
|
|
|
1114
1108
|
def _daemon(
|
|
1115
1109
|
host: Annotated[str, params.String(help="HTTP server host string")] = "localhost",
|
|
1116
1110
|
port: Annotated[int, params.Integer(help="HTTP server port")] = 8000,
|
|
1111
|
+
ssl_keyfile: Annotated[str, params.String(help="Path to SSL key file")] = "",
|
|
1112
|
+
ssl_certfile: Annotated[
|
|
1113
|
+
str, params.String(help="Path to SSL certificate file")
|
|
1114
|
+
] = "",
|
|
1117
1115
|
home: Annotated[
|
|
1118
1116
|
t.Optional[Path], params.Directory(long_flag="--home", help="Home directory")
|
|
1119
1117
|
] = None,
|
|
1120
1118
|
) -> None:
|
|
1121
1119
|
"""Launch operate daemon."""
|
|
1122
1120
|
app = create_app(home=home)
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1121
|
+
logger = setup_logger(name="daemon")
|
|
1122
|
+
|
|
1123
|
+
config_kwargs = {
|
|
1124
|
+
"app": app,
|
|
1125
|
+
"host": host,
|
|
1126
|
+
"port": port,
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
# Use SSL certificates if ssl_keyfile and ssl_certfile are provided
|
|
1130
|
+
if ssl_keyfile and ssl_certfile:
|
|
1131
|
+
logger.info(f"Using SSL certificates: {ssl_certfile}")
|
|
1132
|
+
config_kwargs.update(
|
|
1133
|
+
{
|
|
1134
|
+
"ssl_keyfile": ssl_keyfile,
|
|
1135
|
+
"ssl_certfile": ssl_certfile,
|
|
1136
|
+
}
|
|
1129
1137
|
)
|
|
1130
|
-
|
|
1138
|
+
|
|
1139
|
+
server = Server(Config(**config_kwargs))
|
|
1131
1140
|
app._server = server # pylint: disable=protected-access
|
|
1132
1141
|
server.run()
|
|
1133
1142
|
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
"""Chain profiles."""
|
|
21
21
|
|
|
22
|
-
import enum
|
|
23
22
|
import typing as t
|
|
24
23
|
|
|
25
24
|
from operate.constants import ZERO_ADDRESS
|
|
@@ -156,26 +155,15 @@ STAKING: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
156
155
|
}
|
|
157
156
|
|
|
158
157
|
|
|
159
|
-
|
|
160
|
-
""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return self.value
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
DEFAULT_PRIORITY_MECH_ADDRESS = {
|
|
172
|
-
StakingProgramMechType.LEGACY_MECH: "0x77af31De935740567Cf4fF1986D04B2c964A786a",
|
|
173
|
-
StakingProgramMechType.LEGACY_MECH_MARKETPLACE: "0x552cEA7Bc33CbBEb9f1D90c1D11D2C6daefFd053",
|
|
174
|
-
StakingProgramMechType.MECH_MARKETPLACE: "0xC05e7412439bD7e91730a6880E18d5D5873F632C",
|
|
175
|
-
}
|
|
176
|
-
DEFAULT_PRIORITY_MECH_SERVICE_ID = {
|
|
177
|
-
StakingProgramMechType.LEGACY_MECH_MARKETPLACE: 975,
|
|
178
|
-
StakingProgramMechType.MECH_MARKETPLACE: 2182,
|
|
158
|
+
DEFAULT_PRIORITY_MECH = { # maps mech marketplace address to its default priority mech address and service id
|
|
159
|
+
"0x4554fE75c1f5576c1d7F765B2A036c199Adae329": (
|
|
160
|
+
"0x552cEA7Bc33CbBEb9f1D90c1D11D2C6daefFd053",
|
|
161
|
+
975,
|
|
162
|
+
),
|
|
163
|
+
"0x735FAAb1c4Ec41128c367AFb5c3baC73509f70bB": (
|
|
164
|
+
"0xC05e7412439bD7e91730a6880E18d5D5873F632C",
|
|
165
|
+
2182,
|
|
166
|
+
),
|
|
179
167
|
}
|
|
180
168
|
|
|
181
169
|
|
|
@@ -269,17 +257,3 @@ def get_staking_contract(
|
|
|
269
257
|
staking_program_id,
|
|
270
258
|
staking_program_id,
|
|
271
259
|
)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
def get_staking_program_mech_type(
|
|
275
|
-
staking_program_id: t.Optional[str],
|
|
276
|
-
) -> StakingProgramMechType:
|
|
277
|
-
"""Get the staking program mech type based on the staking program ID."""
|
|
278
|
-
if staking_program_id is None:
|
|
279
|
-
return StakingProgramMechType.LEGACY_MECH
|
|
280
|
-
|
|
281
|
-
if staking_program_id.startswith("quickstart_beta_mech_marketplace_expert"):
|
|
282
|
-
return StakingProgramMechType.MECH_MARKETPLACE
|
|
283
|
-
if "mech_marketplace" in staking_program_id:
|
|
284
|
-
return StakingProgramMechType.LEGACY_MECH_MARKETPLACE
|
|
285
|
-
return StakingProgramMechType.LEGACY_MECH
|
|
@@ -329,3 +329,13 @@ class AssetFundingValues(TypedDict):
|
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
FundingValues = t.Dict[str, AssetFundingValues] # str is the asset address
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
@dataclass
|
|
335
|
+
class MechMarketplaceConfig:
|
|
336
|
+
"""Mech Marketplace config."""
|
|
337
|
+
|
|
338
|
+
use_mech_marketplace: bool
|
|
339
|
+
mech_marketplace_address: str
|
|
340
|
+
priority_mech_address: str
|
|
341
|
+
priority_mech_service_id: int
|
|
@@ -73,7 +73,7 @@ def claim_staking_rewards(operate: "OperateApp", config_path: str) -> None:
|
|
|
73
73
|
config = configure_local_config(template, operate)
|
|
74
74
|
manager = operate.service_manager()
|
|
75
75
|
service = get_service(manager, template)
|
|
76
|
-
ask_password_if_needed(operate
|
|
76
|
+
ask_password_if_needed(operate)
|
|
77
77
|
|
|
78
78
|
# reload manger and config after setting operate.password
|
|
79
79
|
manager = operate.service_manager()
|
{olas_operate_middleware-0.7.0 → olas_operate_middleware-0.8.0}/operate/quickstart/reset_staking.py
RENAMED
|
@@ -82,7 +82,7 @@ def reset_staking(operate: "OperateApp", config_path: str) -> None:
|
|
|
82
82
|
print("Cancelled.")
|
|
83
83
|
return
|
|
84
84
|
|
|
85
|
-
ask_password_if_needed(operate
|
|
85
|
+
ask_password_if_needed(operate)
|
|
86
86
|
manager = operate.service_manager()
|
|
87
87
|
service = get_service(manager, template)
|
|
88
88
|
|