olas-operate-middleware 0.12.1__py3-none-any.whl → 0.13.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.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/METADATA +1 -1
- {olas_operate_middleware-0.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/RECORD +20 -20
- operate/cli.py +73 -18
- operate/keys.py +9 -3
- operate/ledger/profiles.py +11 -0
- operate/migration.py +46 -12
- operate/operate_types.py +16 -0
- operate/quickstart/reset_password.py +1 -2
- operate/quickstart/run_service.py +17 -3
- operate/quickstart/stop_service.py +9 -2
- operate/services/agent_runner.py +19 -29
- operate/services/deployment_runner.py +83 -49
- operate/services/funding_manager.py +5 -3
- operate/services/manage.py +22 -7
- operate/services/service.py +66 -34
- operate/wallet/master.py +2 -2
- operate/wallet/wallet_recovery_manager.py +281 -36
- {olas_operate_middleware-0.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/entry_points.txt +0 -0
- {olas_operate_middleware-0.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/licenses/LICENSE +0 -0
{olas_operate_middleware-0.12.1.dist-info → olas_operate_middleware-0.13.0.dist-info}/RECORD
RENAMED
|
@@ -6,7 +6,7 @@ operate/bridge/providers/lifi_provider.py,sha256=UzAeEnX9FGpnCYYml5lcICeEZeHHqNR
|
|
|
6
6
|
operate/bridge/providers/native_bridge_provider.py,sha256=vAx0MtVPIAxIdQ5OKSUDhnGurYVkC8tKVJRFK9NkIdk,25088
|
|
7
7
|
operate/bridge/providers/provider.py,sha256=KXp5CITCQ-fSOv2iFMOt8Wer1QGhBvJG0HN5Tnh5Qns,17287
|
|
8
8
|
operate/bridge/providers/relay_provider.py,sha256=4D2U8jrugh2DJZeSoxLCTVSZe8xMEwdCimqFDtfwWwc,17422
|
|
9
|
-
operate/cli.py,sha256=
|
|
9
|
+
operate/cli.py,sha256=REYysEoQ_gBIGS_s3JBIQMe1ZHVy84TS6pIQmyi3H84,70116
|
|
10
10
|
operate/constants.py,sha256=FxQL9MmGHD-nNr7UBPb6ItltWtrCLB2fnT6fb4XNlKg,3849
|
|
11
11
|
operate/data/README.md,sha256=jGPyZTvg2LCGdllvmYxmFMkkkiXb6YWatbqIkcX3kv4,879
|
|
12
12
|
operate/data/__init__.py,sha256=ttC51Yqk9c4ehpIgs1Qbe7aJvzkrbbdZ1ClaCxJYByE,864
|
|
@@ -57,32 +57,32 @@ operate/data/contracts/uniswap_v2_erc20/contract.py,sha256=MwBks4QmZ3XouMT_TqWLn
|
|
|
57
57
|
operate/data/contracts/uniswap_v2_erc20/contract.yaml,sha256=XUdz-XtKtmZgLfItbO8usP-QPbtUkAxKGn0hL7OftAg,741
|
|
58
58
|
operate/data/contracts/uniswap_v2_erc20/tests/__init__.py,sha256=3Arw8dsCsJz6hVOl0t9UjFASHXbV9yp3hw6x4HqgXpU,847
|
|
59
59
|
operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py,sha256=FzZbw9OTcr_yvjOXpk9YcO-K40eyDARyybcfSHDg2Ps,13392
|
|
60
|
-
operate/keys.py,sha256=
|
|
60
|
+
operate/keys.py,sha256=DqwEnHwGx6XfQKRS86znJ_-Q63AbIYyAx5AT2pSieUk,6139
|
|
61
61
|
operate/ledger/__init__.py,sha256=G0iWcA0Rc-Um8NwpwPJWsQNUQb2tWKyDjzirxPhGc98,6517
|
|
62
|
-
operate/ledger/profiles.py,sha256=
|
|
63
|
-
operate/migration.py,sha256=
|
|
62
|
+
operate/ledger/profiles.py,sha256=ldmpzmvhic6MOvDqslbqbNnLqct-P4EGhym7vbGCvU4,14761
|
|
63
|
+
operate/migration.py,sha256=hdZlhhdkoPPzkOD0CFyNYAp-eqUrVu_PJnw8_PoxpWk,21015
|
|
64
64
|
operate/operate_http/__init__.py,sha256=dxCIVSUos23M4R-PFZZG6k5QrOlEiK0SxhCYSFNxh7U,4711
|
|
65
65
|
operate/operate_http/exceptions.py,sha256=4UFzrn-GyDD71RhkaOyFPBynL6TrrtP3eywaaU3o4fc,1339
|
|
66
|
-
operate/operate_types.py,sha256=
|
|
66
|
+
operate/operate_types.py,sha256=lO9mOT76CHIxt9UjcMq-wd2ZMCVtPxSLOAWMWSF1QZU,15843
|
|
67
67
|
operate/pearl.py,sha256=yrTpSXLu_ML3qT-uNxq3kScOyo31JyxBujiSMfMUbcg,1690
|
|
68
68
|
operate/quickstart/analyse_logs.py,sha256=cAeAL2iUy0Po8Eor70tq54-Ibg-Dn8rkuaS167yjE_I,4198
|
|
69
69
|
operate/quickstart/claim_staking_rewards.py,sha256=K7X1Yq0mxe3qWmFLb1Xu9-Jghhml95lS_LpM_BXii0o,3533
|
|
70
70
|
operate/quickstart/reset_configs.py,sha256=DVPM4mh6Djunwq16hf8lD9-nGkkm7wVtwr2JUXr1if8,3380
|
|
71
|
-
operate/quickstart/reset_password.py,sha256=
|
|
71
|
+
operate/quickstart/reset_password.py,sha256=jEBk2ROR1q8PkTIHlqum7E8PRQtXHwrauiy0_bik3RQ,2394
|
|
72
72
|
operate/quickstart/reset_staking.py,sha256=SB5LZq9EctG4SYn2M6oPZ7R7ARHSFLRGzAqfKkpRcy0,5111
|
|
73
|
-
operate/quickstart/run_service.py,sha256=
|
|
74
|
-
operate/quickstart/stop_service.py,sha256=
|
|
73
|
+
operate/quickstart/run_service.py,sha256=eyMrUK5pL1uPilRHE_IfK6Uhrx1qNyslU2ubDAErpL0,28123
|
|
74
|
+
operate/quickstart/stop_service.py,sha256=a3-1vVyZma2UtFUPKMvVrOso1Iwpz5Rzpus9VAI4qOc,2169
|
|
75
75
|
operate/quickstart/terminate_on_chain_service.py,sha256=5ENU8_mkj06i80lKUX-v1QbLU0YzKeOZDUL1e_jzySE,2914
|
|
76
76
|
operate/quickstart/utils.py,sha256=jvi7IgPtJEWf7-ciZFyEh_jgNthhv3Pus4VZa_Ha_ms,9221
|
|
77
77
|
operate/resource.py,sha256=MnLdoEV68vQkaoClMFEJqkuxvqBQSIySuKym6h61Pk4,5741
|
|
78
78
|
operate/services/__init__.py,sha256=isrThS-Ccu5Sc15JZgkN4uTAVaSg-NwUUSDeTyJEqLk,855
|
|
79
|
-
operate/services/agent_runner.py,sha256=
|
|
80
|
-
operate/services/deployment_runner.py,sha256=
|
|
81
|
-
operate/services/funding_manager.py,sha256=
|
|
79
|
+
operate/services/agent_runner.py,sha256=IQ9DAirYZAqWIk30CdU9mO0tVMymdj5LW5O3l8Uhj2w,7433
|
|
80
|
+
operate/services/deployment_runner.py,sha256=bJr0u9yW8pku_46q9bUFFLnM9b9SKliDi0BzKr_gd3U,29336
|
|
81
|
+
operate/services/funding_manager.py,sha256=S9jYnRQe2m6QDVrkvGS11KFYkbTPrZc0zNygahukHVs,38621
|
|
82
82
|
operate/services/health_checker.py,sha256=r_lMlRZu-UNfqaM-Zo5_cWjsigdqYTAty4h-ISpM7RE,9859
|
|
83
|
-
operate/services/manage.py,sha256=
|
|
83
|
+
operate/services/manage.py,sha256=uifx-VJTPzqLj0N7qlHzTcjMrzqF2RH2PM0kIdieMfA,113270
|
|
84
84
|
operate/services/protocol.py,sha256=DHu3TzaDuwTtidoEp7kGlbTAWw8pPbLjbyvanuyyjJs,72285
|
|
85
|
-
operate/services/service.py,sha256=
|
|
85
|
+
operate/services/service.py,sha256=GqeS8Fm-iA8UPb4QdDWSHa5uZ-Or0G7po7qT0WfUJWI,45348
|
|
86
86
|
operate/services/utils/__init__.py,sha256=TvioaZ1mfTRUSCtrQoLNAp4WMVXyqEJqFJM4PxSQCRU,24
|
|
87
87
|
operate/services/utils/mech.py,sha256=W2x4dqodivNKXjWU-Brp40QhoUHsIMyNAO7-caMoR0Q,3821
|
|
88
88
|
operate/services/utils/tendermint.py,sha256=3h9nDb2Z89T0RwUr_AaVjqtymQmsu3u6DAVCfL_k1U0,25591
|
|
@@ -92,10 +92,10 @@ operate/utils/gnosis.py,sha256=iyaFw3ZMlNnd1lDulhXfcYxQunPL4Zfhnk1fy20ga7g,19843
|
|
|
92
92
|
operate/utils/single_instance.py,sha256=pmtumg0fFDWWcGzXFXQdLXSW54Zq9qBKgJTEPF6pVW8,9092
|
|
93
93
|
operate/utils/ssl.py,sha256=O5DrDoZD4T4qQuHP8GLwWUVxQ-1qXeefGp6uDJiF2lM,4308
|
|
94
94
|
operate/wallet/__init__.py,sha256=NGiozD3XhvkBi7_FaOWQ8x1thZPK4uGpokJaeDY_o2w,813
|
|
95
|
-
operate/wallet/master.py,sha256=
|
|
96
|
-
operate/wallet/wallet_recovery_manager.py,sha256=
|
|
97
|
-
olas_operate_middleware-0.
|
|
98
|
-
olas_operate_middleware-0.
|
|
99
|
-
olas_operate_middleware-0.
|
|
100
|
-
olas_operate_middleware-0.
|
|
101
|
-
olas_operate_middleware-0.
|
|
95
|
+
operate/wallet/master.py,sha256=Wr6TsEqG3hQBDNeubGHZ2tZvaqFCfJ-nn8mTl7yQaXs,33698
|
|
96
|
+
operate/wallet/wallet_recovery_manager.py,sha256=hG8qjWOqHuVaXn1puGQ3BpdUBMVx3LZtDzsPK-OeRqY,17515
|
|
97
|
+
olas_operate_middleware-0.13.0.dist-info/METADATA,sha256=WpoR1HzlCM-7DQCghYHVElir0yGA7SDxxEocPrq-3Fc,2139
|
|
98
|
+
olas_operate_middleware-0.13.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
99
|
+
olas_operate_middleware-0.13.0.dist-info/entry_points.txt,sha256=dM1g2I7ODApKQFcgl5J4NGA7pfBTo6qsUTXM-j2OLlw,44
|
|
100
|
+
olas_operate_middleware-0.13.0.dist-info/licenses/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
|
|
101
|
+
olas_operate_middleware-0.13.0.dist-info/RECORD,,
|
operate/cli.py
CHANGED
|
@@ -159,7 +159,6 @@ class OperateApp: # pylint: disable=too-many-instance-attributes
|
|
|
159
159
|
self._backup_operate_if_new_version()
|
|
160
160
|
|
|
161
161
|
self._password: t.Optional[str] = os.environ.get("OPERATE_USER_PASSWORD")
|
|
162
|
-
KeysManager._instances.clear() # reset singleton instance
|
|
163
162
|
self._keys_manager: KeysManager = KeysManager(
|
|
164
163
|
path=self._keys,
|
|
165
164
|
logger=logger,
|
|
@@ -173,6 +172,7 @@ class OperateApp: # pylint: disable=too-many-instance-attributes
|
|
|
173
172
|
)
|
|
174
173
|
self._wallet_manager.setup()
|
|
175
174
|
self._funding_manager = FundingManager(
|
|
175
|
+
keys_manager=self._keys_manager,
|
|
176
176
|
wallet_manager=self._wallet_manager,
|
|
177
177
|
logger=logger,
|
|
178
178
|
)
|
|
@@ -284,6 +284,7 @@ class OperateApp: # pylint: disable=too-many-instance-attributes
|
|
|
284
284
|
"""Load service manager."""
|
|
285
285
|
return services.manage.ServiceManager(
|
|
286
286
|
path=self._services,
|
|
287
|
+
keys_manager=self.keys_manager,
|
|
287
288
|
wallet_manager=self.wallet_manager,
|
|
288
289
|
funding_manager=self.funding_manager,
|
|
289
290
|
logger=logger,
|
|
@@ -302,17 +303,23 @@ class OperateApp: # pylint: disable=too-many-instance-attributes
|
|
|
302
303
|
return UserAccount.load(self._path / USER_JSON)
|
|
303
304
|
return None
|
|
304
305
|
|
|
306
|
+
@property
|
|
307
|
+
def keys_manager(self) -> KeysManager:
|
|
308
|
+
"""Load keys manager."""
|
|
309
|
+
return self._keys_manager
|
|
310
|
+
|
|
305
311
|
@property
|
|
306
312
|
def wallet_manager(self) -> MasterWalletManager:
|
|
307
313
|
"""Load wallet manager."""
|
|
308
314
|
return self._wallet_manager
|
|
309
315
|
|
|
310
316
|
@property
|
|
311
|
-
def
|
|
317
|
+
def wallet_recovery_manager(self) -> WalletRecoveryManager:
|
|
312
318
|
"""Load wallet recovery manager."""
|
|
313
319
|
manager = WalletRecoveryManager(
|
|
314
320
|
path=self._path / WALLET_RECOVERY_DIR,
|
|
315
321
|
wallet_manager=self.wallet_manager,
|
|
322
|
+
service_manager=self.service_manager(),
|
|
316
323
|
logger=logger,
|
|
317
324
|
)
|
|
318
325
|
return manager
|
|
@@ -730,7 +737,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
730
737
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
731
738
|
)
|
|
732
739
|
|
|
733
|
-
@app.get("/api/extended
|
|
740
|
+
@app.get("/api/wallet/extended")
|
|
734
741
|
async def _get_wallet_safe(request: Request) -> t.List[t.Dict]:
|
|
735
742
|
"""Get wallets."""
|
|
736
743
|
wallets = []
|
|
@@ -1512,9 +1519,9 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1512
1519
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1513
1520
|
)
|
|
1514
1521
|
|
|
1515
|
-
@app.post("/api/wallet/recovery/
|
|
1516
|
-
async def
|
|
1517
|
-
"""
|
|
1522
|
+
@app.post("/api/wallet/recovery/prepare")
|
|
1523
|
+
async def _wallet_recovery_prepare(request: Request) -> JSONResponse:
|
|
1524
|
+
"""Prepare wallet recovery."""
|
|
1518
1525
|
if operate.user_account is None:
|
|
1519
1526
|
return ACCOUNT_NOT_FOUND_ERROR
|
|
1520
1527
|
|
|
@@ -1533,7 +1540,7 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1533
1540
|
)
|
|
1534
1541
|
|
|
1535
1542
|
try:
|
|
1536
|
-
output = operate.
|
|
1543
|
+
output = operate.wallet_recovery_manager.prepare_recovery(
|
|
1537
1544
|
new_password=new_password
|
|
1538
1545
|
)
|
|
1539
1546
|
return JSONResponse(
|
|
@@ -1541,16 +1548,54 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1541
1548
|
status_code=HTTPStatus.OK,
|
|
1542
1549
|
)
|
|
1543
1550
|
except (ValueError, WalletRecoveryError) as e:
|
|
1544
|
-
logger.error(f"
|
|
1551
|
+
logger.error(f"_recovery_prepare error: {e}")
|
|
1545
1552
|
return JSONResponse(
|
|
1546
|
-
content={"error": f"Failed to
|
|
1553
|
+
content={"error": f"Failed to prepare recovery: {e}"},
|
|
1547
1554
|
status_code=HTTPStatus.BAD_REQUEST,
|
|
1548
1555
|
)
|
|
1549
1556
|
except Exception as e: # pylint: disable=broad-except
|
|
1550
|
-
logger.error(f"
|
|
1557
|
+
logger.error(f"_recovery_prepare error: {e}\n{traceback.format_exc()}")
|
|
1558
|
+
return JSONResponse(
|
|
1559
|
+
content={"error": "Failed to prepare recovery. Please check the logs."},
|
|
1560
|
+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1561
|
+
)
|
|
1562
|
+
|
|
1563
|
+
@app.get("/api/wallet/recovery/funding_requirements")
|
|
1564
|
+
async def _get_recovery_funding_requirements(request: Request) -> JSONResponse:
|
|
1565
|
+
"""Get recovery funding requirements."""
|
|
1566
|
+
|
|
1567
|
+
try:
|
|
1568
|
+
output = operate.wallet_recovery_manager.recovery_requirements()
|
|
1569
|
+
return JSONResponse(
|
|
1570
|
+
content=output,
|
|
1571
|
+
status_code=HTTPStatus.OK,
|
|
1572
|
+
)
|
|
1573
|
+
except Exception as e: # pylint: disable=broad-except
|
|
1574
|
+
logger.error(
|
|
1575
|
+
f"_recovery_funding_requirements error: {e}\n{traceback.format_exc()}"
|
|
1576
|
+
)
|
|
1551
1577
|
return JSONResponse(
|
|
1552
1578
|
content={
|
|
1553
|
-
"error": "Failed to
|
|
1579
|
+
"error": "Failed to retrieve recovery funding requirements. Please check the logs."
|
|
1580
|
+
},
|
|
1581
|
+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1582
|
+
)
|
|
1583
|
+
|
|
1584
|
+
@app.get("/api/wallet/recovery/status")
|
|
1585
|
+
async def _get_recovery_status(request: Request) -> JSONResponse:
|
|
1586
|
+
"""Get recovery status."""
|
|
1587
|
+
|
|
1588
|
+
try:
|
|
1589
|
+
output = operate.wallet_recovery_manager.status()
|
|
1590
|
+
return JSONResponse(
|
|
1591
|
+
content=output,
|
|
1592
|
+
status_code=HTTPStatus.OK,
|
|
1593
|
+
)
|
|
1594
|
+
except Exception as e: # pylint: disable=broad-except
|
|
1595
|
+
logger.error(f"_recovery_status error: {e}\n{traceback.format_exc()}")
|
|
1596
|
+
return JSONResponse(
|
|
1597
|
+
content={
|
|
1598
|
+
"error": "Failed to retrieve recovery status. Please check the logs."
|
|
1554
1599
|
},
|
|
1555
1600
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
1556
1601
|
)
|
|
@@ -1564,15 +1609,16 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1564
1609
|
if operate.password:
|
|
1565
1610
|
return USER_LOGGED_IN_ERROR
|
|
1566
1611
|
|
|
1567
|
-
data =
|
|
1568
|
-
|
|
1569
|
-
|
|
1612
|
+
data = {}
|
|
1613
|
+
if request.headers.get("content-type", "").startswith("application/json"):
|
|
1614
|
+
body = await request.body()
|
|
1615
|
+
if body:
|
|
1616
|
+
data = await request.json()
|
|
1617
|
+
|
|
1570
1618
|
raise_if_inconsistent_owners = data.get("require_consistent_owners", True)
|
|
1571
1619
|
|
|
1572
1620
|
try:
|
|
1573
|
-
operate.
|
|
1574
|
-
bundle_id=bundle_id,
|
|
1575
|
-
password=password,
|
|
1621
|
+
operate.wallet_recovery_manager.complete_recovery(
|
|
1576
1622
|
raise_if_inconsistent_owners=raise_if_inconsistent_owners,
|
|
1577
1623
|
)
|
|
1578
1624
|
return JSONResponse(
|
|
@@ -1664,6 +1710,10 @@ def qs_start(
|
|
|
1664
1710
|
bool,
|
|
1665
1711
|
params.Boolean(help="Will skip the dependencies check for minting the service"),
|
|
1666
1712
|
] = False,
|
|
1713
|
+
use_binary: Annotated[
|
|
1714
|
+
bool,
|
|
1715
|
+
params.Boolean(help="Will use the released binary to run the service"),
|
|
1716
|
+
] = False,
|
|
1667
1717
|
) -> None:
|
|
1668
1718
|
"""Quickstart."""
|
|
1669
1719
|
os.environ["ATTENDED"] = attended.lower()
|
|
@@ -1674,12 +1724,17 @@ def qs_start(
|
|
|
1674
1724
|
config_path=config,
|
|
1675
1725
|
build_only=build_only,
|
|
1676
1726
|
skip_dependency_check=skip_dependency_check,
|
|
1727
|
+
use_binary=use_binary,
|
|
1677
1728
|
)
|
|
1678
1729
|
|
|
1679
1730
|
|
|
1680
1731
|
@_operate.command(name="quickstop")
|
|
1681
1732
|
def qs_stop(
|
|
1682
1733
|
config: Annotated[str, params.String(help="Quickstart config file path")],
|
|
1734
|
+
use_binary: Annotated[
|
|
1735
|
+
bool,
|
|
1736
|
+
params.Boolean(help="Will use the released binary to run the service"),
|
|
1737
|
+
] = False,
|
|
1683
1738
|
attended: Annotated[
|
|
1684
1739
|
str, params.String(help="Run in attended/unattended mode (default: true")
|
|
1685
1740
|
] = "true",
|
|
@@ -1688,7 +1743,7 @@ def qs_stop(
|
|
|
1688
1743
|
os.environ["ATTENDED"] = attended.lower()
|
|
1689
1744
|
operate = OperateApp()
|
|
1690
1745
|
operate.setup()
|
|
1691
|
-
stop_service(operate=operate, config_path=config)
|
|
1746
|
+
stop_service(operate=operate, config_path=config, use_binary=use_binary)
|
|
1692
1747
|
|
|
1693
1748
|
|
|
1694
1749
|
@_operate.command(name="terminate")
|
operate/keys.py
CHANGED
|
@@ -31,7 +31,7 @@ from aea_ledger_ethereum.ethereum import EthereumCrypto
|
|
|
31
31
|
|
|
32
32
|
from operate.operate_types import LedgerType
|
|
33
33
|
from operate.resource import LocalResource
|
|
34
|
-
from operate.utils import
|
|
34
|
+
from operate.utils import unrecoverable_delete
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
@dataclass
|
|
@@ -42,7 +42,7 @@ class Key(LocalResource):
|
|
|
42
42
|
address: str
|
|
43
43
|
private_key: str
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def get_decrypted_json(self, password: str) -> dict:
|
|
46
46
|
"""Get decrypted key json."""
|
|
47
47
|
return {
|
|
48
48
|
"ledger": self.ledger.value,
|
|
@@ -57,7 +57,7 @@ class Key(LocalResource):
|
|
|
57
57
|
return super().load(path) # type: ignore
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
class KeysManager
|
|
60
|
+
class KeysManager:
|
|
61
61
|
"""Keys manager."""
|
|
62
62
|
|
|
63
63
|
def __init__(self, **kwargs: Any) -> None:
|
|
@@ -113,6 +113,12 @@ class KeysManager(metaclass=SingletonMeta):
|
|
|
113
113
|
)
|
|
114
114
|
)
|
|
115
115
|
|
|
116
|
+
def get_decrypted(self, key: str) -> dict:
|
|
117
|
+
"""Get key json."""
|
|
118
|
+
if self.password is not None:
|
|
119
|
+
return self.get(key).get_decrypted_json(self.password)
|
|
120
|
+
return self.get(key).json
|
|
121
|
+
|
|
116
122
|
def get_private_key_file(self, address: str) -> Path:
|
|
117
123
|
"""Get the path to the private key file for the given address."""
|
|
118
124
|
path = self.path / f"{address}_private_key"
|
operate/ledger/profiles.py
CHANGED
|
@@ -246,6 +246,17 @@ DEFAULT_EOA_TOPUPS_WITHOUT_SAFE = {
|
|
|
246
246
|
for chain, amounts in DEFAULT_EOA_TOPUPS.items()
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
DEFAULT_RECOVERY_TOPUPS = {
|
|
250
|
+
Chain.ARBITRUM_ONE: {ZERO_ADDRESS: 625_000_000_000_000},
|
|
251
|
+
Chain.BASE: {ZERO_ADDRESS: 625_000_000_000_000},
|
|
252
|
+
Chain.CELO: {ZERO_ADDRESS: 187_500_000_000_000_000},
|
|
253
|
+
Chain.ETHEREUM: {ZERO_ADDRESS: 2_500_000_000_000_000},
|
|
254
|
+
Chain.GNOSIS: {ZERO_ADDRESS: 187_500_000_000_000_000},
|
|
255
|
+
Chain.MODE: {ZERO_ADDRESS: 62_500_000_000_000},
|
|
256
|
+
Chain.OPTIMISM: {ZERO_ADDRESS: 625_000_000_000_000},
|
|
257
|
+
Chain.POLYGON: {ZERO_ADDRESS: 187_500_000_000_000_000},
|
|
258
|
+
}
|
|
259
|
+
|
|
249
260
|
DEFAULT_EOA_THRESHOLD = 0.5
|
|
250
261
|
|
|
251
262
|
EXPLORER_URL = {
|
operate/migration.py
CHANGED
|
@@ -33,7 +33,9 @@ from web3 import Web3
|
|
|
33
33
|
|
|
34
34
|
from operate.constants import USER_JSON, ZERO_ADDRESS
|
|
35
35
|
from operate.keys import KeysManager
|
|
36
|
-
from operate.operate_types import
|
|
36
|
+
from operate.operate_types import AgentRelease as AgentReleaseType
|
|
37
|
+
from operate.operate_types import AgentReleaseRepo, Chain, LedgerType
|
|
38
|
+
from operate.services.agent_runner import AgentRelease
|
|
37
39
|
from operate.services.manage import ServiceManager
|
|
38
40
|
from operate.services.service import (
|
|
39
41
|
NON_EXISTENT_MULTISIG,
|
|
@@ -160,7 +162,7 @@ class MigrationManager:
|
|
|
160
162
|
|
|
161
163
|
self.logger.info("Migrating wallet configs done.")
|
|
162
164
|
|
|
163
|
-
def _migrate_service( # pylint: disable=too-many-statements,too-many-locals
|
|
165
|
+
def _migrate_service( # pylint: disable=too-many-statements,too-many-locals,too-many-branches
|
|
164
166
|
self,
|
|
165
167
|
path: Path,
|
|
166
168
|
) -> bool:
|
|
@@ -250,12 +252,6 @@ class MigrationManager:
|
|
|
250
252
|
"nft": data.get("chain_data", {})
|
|
251
253
|
.get("user_params", {})
|
|
252
254
|
.get("nft"),
|
|
253
|
-
"threshold": data.get("chain_data", {})
|
|
254
|
-
.get("user_params", {})
|
|
255
|
-
.get("threshold"),
|
|
256
|
-
"use_staking": data.get("chain_data", {})
|
|
257
|
-
.get("user_params", {})
|
|
258
|
-
.get("use_staking"),
|
|
259
255
|
"cost_of_bond": data.get("chain_data", {})
|
|
260
256
|
.get("user_params", {})
|
|
261
257
|
.get("cost_of_bond"),
|
|
@@ -277,9 +273,6 @@ class MigrationManager:
|
|
|
277
273
|
if version < 4:
|
|
278
274
|
# Add missing fields introduced in later versions, if necessary.
|
|
279
275
|
for _, chain_data in data.get("chain_configs", {}).items():
|
|
280
|
-
chain_data.setdefault("chain_data", {}).setdefault(
|
|
281
|
-
"user_params", {}
|
|
282
|
-
).setdefault("use_mech_marketplace", False)
|
|
283
276
|
service_name = data.get("name", "")
|
|
284
277
|
agent_id = Service.determine_agent_id(service_name)
|
|
285
278
|
chain_data.setdefault("chain_data", {}).setdefault("user_params", {})[
|
|
@@ -342,6 +335,12 @@ class MigrationManager:
|
|
|
342
335
|
new_chain_configs[chain] = chain_data # type: ignore
|
|
343
336
|
data["chain_configs"] = new_chain_configs
|
|
344
337
|
|
|
338
|
+
if version < 6 and "service_path" in data:
|
|
339
|
+
# Redownload service path
|
|
340
|
+
package_absolute_path = path / Path(data["service_path"]).name
|
|
341
|
+
data.pop("service_path")
|
|
342
|
+
data["package_path"] = str(package_absolute_path.name)
|
|
343
|
+
|
|
345
344
|
if version < 7:
|
|
346
345
|
for _, chain_data in data.get("chain_configs", {}).items():
|
|
347
346
|
if chain_data["chain_data"]["multisig"] == "0xm":
|
|
@@ -371,6 +370,39 @@ class MigrationManager:
|
|
|
371
370
|
if chain_config["ledger_config"]["chain"] == "optimistic":
|
|
372
371
|
chain_config["ledger_config"]["chain"] = Chain.OPTIMISM.value
|
|
373
372
|
|
|
373
|
+
if version < 9:
|
|
374
|
+
agents_supported = {
|
|
375
|
+
"trader_pearl": AgentRelease(
|
|
376
|
+
is_aea=True, owner="valory-xyz", repo="trader", release="v0.0.101"
|
|
377
|
+
),
|
|
378
|
+
"optimus": AgentRelease(
|
|
379
|
+
is_aea=True, owner="valory-xyz", repo="optimus", release="v0.0.103"
|
|
380
|
+
),
|
|
381
|
+
"memeooorr": AgentRelease(
|
|
382
|
+
is_aea=True,
|
|
383
|
+
owner="valory-xyz",
|
|
384
|
+
repo="meme-ooorr",
|
|
385
|
+
release="v0.0.101",
|
|
386
|
+
),
|
|
387
|
+
}
|
|
388
|
+
package_path = data["package_path"]
|
|
389
|
+
try:
|
|
390
|
+
release_data = agents_supported[package_path]
|
|
391
|
+
except KeyError as e:
|
|
392
|
+
raise RuntimeError(f"Found unsupported {package_path=}") from e
|
|
393
|
+
|
|
394
|
+
data["agent_release"] = AgentReleaseType(
|
|
395
|
+
is_aea=release_data.is_aea,
|
|
396
|
+
repository=AgentReleaseRepo(
|
|
397
|
+
owner=release_data.owner,
|
|
398
|
+
name=release_data.repo,
|
|
399
|
+
version=release_data.release,
|
|
400
|
+
),
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
if data["name"] is None:
|
|
404
|
+
data["name"] = release_data.repo
|
|
405
|
+
|
|
374
406
|
data["version"] = SERVICE_CONFIG_VERSION
|
|
375
407
|
|
|
376
408
|
# Redownload service path
|
|
@@ -468,7 +500,9 @@ class MigrationManager:
|
|
|
468
500
|
or key_file.suffix == ".bak"
|
|
469
501
|
or not Web3.is_address(key_file.name)
|
|
470
502
|
):
|
|
471
|
-
|
|
503
|
+
if not key_file.suffix == ".bak":
|
|
504
|
+
self.logger.warning(f"Skipping non-key file: {key_file}")
|
|
505
|
+
|
|
472
506
|
continue
|
|
473
507
|
|
|
474
508
|
migrated = False
|
operate/operate_types.py
CHANGED
|
@@ -223,6 +223,21 @@ class EnvVariableAttributes(TypedDict):
|
|
|
223
223
|
provision_type: ServiceEnvProvisionType
|
|
224
224
|
|
|
225
225
|
|
|
226
|
+
class AgentReleaseRepo(TypedDict):
|
|
227
|
+
"""Agent release repo template."""
|
|
228
|
+
|
|
229
|
+
owner: str
|
|
230
|
+
name: str
|
|
231
|
+
version: str
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class AgentRelease(TypedDict):
|
|
235
|
+
"""Agent release template."""
|
|
236
|
+
|
|
237
|
+
is_aea: bool
|
|
238
|
+
repository: AgentReleaseRepo
|
|
239
|
+
|
|
240
|
+
|
|
226
241
|
ConfigurationTemplates = t.Dict[str, ConfigurationTemplate]
|
|
227
242
|
EnvVariables = t.Dict[str, EnvVariableAttributes]
|
|
228
243
|
|
|
@@ -235,6 +250,7 @@ class ServiceTemplate(TypedDict, total=False):
|
|
|
235
250
|
image: str
|
|
236
251
|
description: str
|
|
237
252
|
service_version: str
|
|
253
|
+
agent_release: AgentRelease
|
|
238
254
|
home_chain: str
|
|
239
255
|
configurations: ConfigurationTemplates
|
|
240
256
|
env_variables: EnvVariables
|
|
@@ -22,7 +22,6 @@ from typing import TYPE_CHECKING
|
|
|
22
22
|
|
|
23
23
|
from operate.account.user import UserAccount
|
|
24
24
|
from operate.constants import USER_JSON
|
|
25
|
-
from operate.keys import KeysManager
|
|
26
25
|
from operate.quickstart.run_service import ask_confirm_password
|
|
27
26
|
from operate.quickstart.utils import ask_or_get_from_env, print_section, print_title
|
|
28
27
|
|
|
@@ -66,6 +65,6 @@ def reset_password(operate: "OperateApp") -> None:
|
|
|
66
65
|
print('Resetting password of "ethereum" wallet...')
|
|
67
66
|
operate.password = old_password
|
|
68
67
|
operate.wallet_manager.update_password(new_password=new_password)
|
|
69
|
-
|
|
68
|
+
operate.keys_manager.update_password(new_password=new_password)
|
|
70
69
|
|
|
71
70
|
print_section("Password reset done!")
|
|
@@ -37,6 +37,7 @@ from operate.account.user import UserAccount
|
|
|
37
37
|
from operate.constants import IPFS_ADDRESS, NO_STAKING_PROGRAM_ID, USER_JSON
|
|
38
38
|
from operate.data import DATA_DIR
|
|
39
39
|
from operate.data.contracts.staking_token.contract import StakingTokenContract
|
|
40
|
+
from operate.ledger import DEFAULT_RPCS
|
|
40
41
|
from operate.ledger.profiles import STAKING, get_staking_contract
|
|
41
42
|
from operate.operate_types import (
|
|
42
43
|
Chain,
|
|
@@ -205,6 +206,7 @@ def configure_local_config(
|
|
|
205
206
|
f"{chain.upper()}_LEDGER_RPC",
|
|
206
207
|
)
|
|
207
208
|
os.environ[f"{chain.upper()}_LEDGER_RPC"] = config.rpc[chain]
|
|
209
|
+
DEFAULT_RPCS[Chain.from_string(chain)] = config.rpc[chain]
|
|
208
210
|
|
|
209
211
|
config.principal_chain = template["home_chain"]
|
|
210
212
|
|
|
@@ -483,7 +485,11 @@ def get_service(manager: ServiceManager, template: ServiceTemplate) -> Service:
|
|
|
483
485
|
for service in manager.json:
|
|
484
486
|
if service["name"] == template["name"]:
|
|
485
487
|
old_hash = service["hash"]
|
|
486
|
-
|
|
488
|
+
old_version = service["agent_release"]["repository"]["version"]
|
|
489
|
+
if (
|
|
490
|
+
old_hash == template["hash"]
|
|
491
|
+
and old_version == template["agent_release"]["repository"]["version"]
|
|
492
|
+
):
|
|
487
493
|
print(f'Loading service {template["hash"]}')
|
|
488
494
|
service = manager.load(
|
|
489
495
|
service_config_id=service["service_config_id"],
|
|
@@ -666,6 +672,7 @@ def run_service(
|
|
|
666
672
|
config_path: str,
|
|
667
673
|
build_only: bool = False,
|
|
668
674
|
skip_dependency_check: bool = False,
|
|
675
|
+
use_binary: bool = False,
|
|
669
676
|
) -> None:
|
|
670
677
|
"""Run service."""
|
|
671
678
|
|
|
@@ -700,10 +707,17 @@ def run_service(
|
|
|
700
707
|
manager.funding_manager.topup_service_initial(service=service)
|
|
701
708
|
|
|
702
709
|
print_section("Deploying the service")
|
|
710
|
+
if use_binary:
|
|
711
|
+
use_docker = False
|
|
712
|
+
use_k8s = False
|
|
713
|
+
else:
|
|
714
|
+
use_docker = True
|
|
715
|
+
use_k8s = True
|
|
716
|
+
|
|
703
717
|
manager.deploy_service_locally(
|
|
704
718
|
service_config_id=service.service_config_id,
|
|
705
|
-
use_docker=
|
|
706
|
-
use_kubernetes=
|
|
719
|
+
use_docker=use_docker,
|
|
720
|
+
use_kubernetes=use_k8s,
|
|
707
721
|
build_only=build_only,
|
|
708
722
|
)
|
|
709
723
|
if build_only:
|
|
@@ -37,7 +37,9 @@ if TYPE_CHECKING:
|
|
|
37
37
|
warnings.filterwarnings("ignore", category=UserWarning)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def stop_service(
|
|
40
|
+
def stop_service(
|
|
41
|
+
operate: "OperateApp", config_path: str, use_binary: bool = False
|
|
42
|
+
) -> None:
|
|
41
43
|
"""Stop service."""
|
|
42
44
|
|
|
43
45
|
with open(config_path, "r") as config_file:
|
|
@@ -57,8 +59,13 @@ def stop_service(operate: "OperateApp", config_path: str) -> None:
|
|
|
57
59
|
configure_local_config(template, operate)
|
|
58
60
|
manager = operate.service_manager()
|
|
59
61
|
service = get_service(manager, template)
|
|
62
|
+
if use_binary:
|
|
63
|
+
use_docker = False
|
|
64
|
+
else:
|
|
65
|
+
use_docker = True
|
|
66
|
+
|
|
60
67
|
manager.stop_service_locally(
|
|
61
|
-
service_config_id=service.service_config_id, use_docker=
|
|
68
|
+
service_config_id=service.service_config_id, use_docker=use_docker, force=True
|
|
62
69
|
)
|
|
63
70
|
|
|
64
71
|
print()
|