olas-operate-middleware 0.1.0rc59__py3-none-any.whl → 0.13.2__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 (98) hide show
  1. olas_operate_middleware-0.13.2.dist-info/METADATA +75 -0
  2. olas_operate_middleware-0.13.2.dist-info/RECORD +101 -0
  3. {olas_operate_middleware-0.1.0rc59.dist-info → olas_operate_middleware-0.13.2.dist-info}/WHEEL +1 -1
  4. operate/__init__.py +17 -0
  5. operate/account/user.py +35 -9
  6. operate/bridge/bridge_manager.py +470 -0
  7. operate/bridge/providers/lifi_provider.py +377 -0
  8. operate/bridge/providers/native_bridge_provider.py +677 -0
  9. operate/bridge/providers/provider.py +469 -0
  10. operate/bridge/providers/relay_provider.py +457 -0
  11. operate/cli.py +1565 -417
  12. operate/constants.py +60 -12
  13. operate/data/README.md +19 -0
  14. operate/data/contracts/{service_staking_token → dual_staking_token}/__init__.py +2 -2
  15. operate/data/contracts/dual_staking_token/build/DualStakingToken.json +443 -0
  16. operate/data/contracts/dual_staking_token/contract.py +132 -0
  17. operate/data/contracts/dual_staking_token/contract.yaml +23 -0
  18. operate/{ledger/base.py → data/contracts/foreign_omnibridge/__init__.py} +2 -19
  19. operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json +1372 -0
  20. operate/data/contracts/foreign_omnibridge/contract.py +130 -0
  21. operate/data/contracts/foreign_omnibridge/contract.yaml +23 -0
  22. operate/{ledger/solana.py → data/contracts/home_omnibridge/__init__.py} +2 -20
  23. operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json +1421 -0
  24. operate/data/contracts/home_omnibridge/contract.py +80 -0
  25. operate/data/contracts/home_omnibridge/contract.yaml +23 -0
  26. operate/data/contracts/l1_standard_bridge/__init__.py +20 -0
  27. operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json +831 -0
  28. operate/data/contracts/l1_standard_bridge/contract.py +158 -0
  29. operate/data/contracts/l1_standard_bridge/contract.yaml +23 -0
  30. operate/data/contracts/l2_standard_bridge/__init__.py +20 -0
  31. operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json +626 -0
  32. operate/data/contracts/l2_standard_bridge/contract.py +130 -0
  33. operate/data/contracts/l2_standard_bridge/contract.yaml +23 -0
  34. operate/data/contracts/mech_activity/__init__.py +20 -0
  35. operate/data/contracts/mech_activity/build/MechActivity.json +111 -0
  36. operate/data/contracts/mech_activity/contract.py +44 -0
  37. operate/data/contracts/mech_activity/contract.yaml +23 -0
  38. operate/data/contracts/optimism_mintable_erc20/__init__.py +20 -0
  39. operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json +491 -0
  40. operate/data/contracts/optimism_mintable_erc20/contract.py +45 -0
  41. operate/data/contracts/optimism_mintable_erc20/contract.yaml +23 -0
  42. operate/data/contracts/recovery_module/__init__.py +20 -0
  43. operate/data/contracts/recovery_module/build/RecoveryModule.json +811 -0
  44. operate/data/contracts/recovery_module/contract.py +61 -0
  45. operate/data/contracts/recovery_module/contract.yaml +23 -0
  46. operate/data/contracts/requester_activity_checker/__init__.py +20 -0
  47. operate/data/contracts/requester_activity_checker/build/RequesterActivityChecker.json +111 -0
  48. operate/data/contracts/requester_activity_checker/contract.py +33 -0
  49. operate/data/contracts/requester_activity_checker/contract.yaml +23 -0
  50. operate/data/contracts/staking_token/__init__.py +20 -0
  51. operate/data/contracts/staking_token/build/StakingToken.json +1336 -0
  52. operate/data/contracts/{service_staking_token → staking_token}/contract.py +27 -13
  53. operate/data/contracts/staking_token/contract.yaml +23 -0
  54. operate/data/contracts/uniswap_v2_erc20/contract.yaml +3 -1
  55. operate/data/contracts/uniswap_v2_erc20/tests/__init__.py +20 -0
  56. operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +363 -0
  57. operate/keys.py +118 -33
  58. operate/ledger/__init__.py +159 -56
  59. operate/ledger/profiles.py +321 -18
  60. operate/migration.py +555 -0
  61. operate/{http → operate_http}/__init__.py +3 -2
  62. operate/{http → operate_http}/exceptions.py +6 -4
  63. operate/operate_types.py +544 -0
  64. operate/pearl.py +13 -1
  65. operate/quickstart/analyse_logs.py +118 -0
  66. operate/quickstart/claim_staking_rewards.py +104 -0
  67. operate/quickstart/reset_configs.py +106 -0
  68. operate/quickstart/reset_password.py +70 -0
  69. operate/quickstart/reset_staking.py +145 -0
  70. operate/quickstart/run_service.py +726 -0
  71. operate/quickstart/stop_service.py +72 -0
  72. operate/quickstart/terminate_on_chain_service.py +83 -0
  73. operate/quickstart/utils.py +298 -0
  74. operate/resource.py +62 -3
  75. operate/services/agent_runner.py +202 -0
  76. operate/services/deployment_runner.py +868 -0
  77. operate/services/funding_manager.py +929 -0
  78. operate/services/health_checker.py +280 -0
  79. operate/services/manage.py +2356 -620
  80. operate/services/protocol.py +1246 -340
  81. operate/services/service.py +756 -391
  82. operate/services/utils/mech.py +103 -0
  83. operate/services/utils/tendermint.py +86 -12
  84. operate/settings.py +70 -0
  85. operate/utils/__init__.py +135 -0
  86. operate/utils/gnosis.py +407 -80
  87. operate/utils/single_instance.py +226 -0
  88. operate/utils/ssl.py +133 -0
  89. operate/wallet/master.py +708 -123
  90. operate/wallet/wallet_recovery_manager.py +507 -0
  91. olas_operate_middleware-0.1.0rc59.dist-info/METADATA +0 -304
  92. olas_operate_middleware-0.1.0rc59.dist-info/RECORD +0 -41
  93. operate/data/contracts/service_staking_token/build/ServiceStakingToken.json +0 -1273
  94. operate/data/contracts/service_staking_token/contract.yaml +0 -23
  95. operate/ledger/ethereum.py +0 -48
  96. operate/types.py +0 -260
  97. {olas_operate_middleware-0.1.0rc59.dist-info → olas_operate_middleware-0.13.2.dist-info}/entry_points.txt +0 -0
  98. {olas_operate_middleware-0.1.0rc59.dist-info → olas_operate_middleware-0.13.2.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ------------------------------------------------------------------------------
4
+ #
5
+ # Copyright 2024 Valory AG
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # -------------------------------------------------------------
20
+ """Source dode to download and run agent from the repos."""
21
+ import hashlib
22
+ import json
23
+ import os
24
+ import platform
25
+ import shutil
26
+ import stat
27
+ from dataclasses import dataclass
28
+ from pathlib import Path
29
+ from tempfile import TemporaryDirectory
30
+ from typing import Tuple
31
+
32
+ import requests
33
+ from aea.configurations.data_types import PublicId
34
+ from aea.helpers.logging import setup_logger
35
+
36
+ from operate.constants import AGENT_RUNNER_PREFIX, CONFIG_JSON
37
+
38
+
39
+ @dataclass
40
+ class AgentRelease:
41
+ """Agent release dataclass."""
42
+
43
+ owner: str
44
+ repo: str
45
+ release: str
46
+ is_aea: bool
47
+
48
+ @property
49
+ def release_url(self) -> str:
50
+ """Get release api url."""
51
+ return f"https://api.github.com/repos/{self.owner}/{self.repo}/releases/tags/{self.release}"
52
+
53
+ def get_url_and_hash(self, asset_name: str) -> tuple[str, str]:
54
+ """Get download url and asset sha256 hash."""
55
+ release_data = requests.get(self.release_url).json()
56
+
57
+ assets_filtered = [i for i in release_data["assets"] if i["name"] == asset_name]
58
+ if not assets_filtered:
59
+ raise ValueError(
60
+ f"Asset {asset_name} not found in release {self.release_url}"
61
+ )
62
+ asset = assets_filtered[0]
63
+ file_hash = asset["digest"]
64
+ file_url = asset["browser_download_url"]
65
+
66
+ return file_url, file_hash
67
+
68
+
69
+ class AgentRunnerManager:
70
+ """Agent Runner Manager."""
71
+
72
+ logger = setup_logger(name="operate.agent_runner_manager")
73
+
74
+ @staticmethod
75
+ def get_agent_runner_executable_name() -> str:
76
+ """Get runner executable name by platform running."""
77
+ if platform.system() == "Darwin":
78
+ os_name = "macos"
79
+ elif platform.system() == "Windows":
80
+ os_name = "windows"
81
+ else:
82
+ raise ValueError("Platform not supported!")
83
+
84
+ if platform.machine().lower() in ("x86_64", "amd64"):
85
+ arch = "x64"
86
+ elif platform.machine().lower() == "arm64":
87
+ arch = "arm64"
88
+ if os_name == "windows":
89
+ raise ValueError("Windows arm64 is not supported!")
90
+ else:
91
+ raise ValueError(f"unsupported arch: {platform.machine()}")
92
+
93
+ exec_name = f"{AGENT_RUNNER_PREFIX}_{os_name}_{arch}"
94
+ if platform.system() == "Windows":
95
+ exec_name += ".exe"
96
+ return exec_name
97
+
98
+ @staticmethod
99
+ def parse_agent(public_id_str: str) -> Tuple[str, str]:
100
+ """Get authorn and name from agent public string id."""
101
+ public_id = PublicId.from_str(public_id_string=public_id_str)
102
+ return (public_id.author, public_id.name)
103
+
104
+ @classmethod
105
+ def download_file(cls, url: str, save_path: Path) -> None:
106
+ """Download file of agent runner."""
107
+ try:
108
+ # Send a GET request to the URL
109
+ response = requests.get(url, stream=True)
110
+ response.raise_for_status() # Raise an error for bad status codes (4xx or 5xx)
111
+
112
+ # Open the file in binary write mode and save the content
113
+ with open(save_path, "wb") as file:
114
+ for chunk in response.iter_content(chunk_size=8192):
115
+ file.write(chunk)
116
+
117
+ cls.logger.info(f"File downloaded and saved to {save_path}")
118
+ except requests.exceptions.RequestException as e:
119
+ cls.logger.error(f"Error downloading file: {e}")
120
+ raise
121
+
122
+ @classmethod
123
+ def get_agent_release_from_service_dir(cls, service_dir: Path) -> AgentRelease:
124
+ """Get agent release object according to public id."""
125
+ service_config_file = service_dir / CONFIG_JSON
126
+ service_config = json.loads(service_config_file.read_text())
127
+ if "agent_release" not in service_config:
128
+ raise ValueError(f"Agent release details are not found in {service_config}")
129
+ agent_release_data = service_config["agent_release"]
130
+ agent_release = AgentRelease(
131
+ is_aea=agent_release_data["is_aea"],
132
+ owner=agent_release_data["repository"]["owner"],
133
+ repo=agent_release_data["repository"]["name"],
134
+ release=agent_release_data["repository"]["version"],
135
+ )
136
+ return agent_release
137
+
138
+ @staticmethod
139
+ def get_local_file_sha256(path: Path) -> str:
140
+ """Get local file sha256."""
141
+ sha256_hash = hashlib.sha256()
142
+ with open(path, "rb") as f:
143
+ for byte_block in iter(lambda: f.read(4096), b""):
144
+ sha256_hash.update(byte_block)
145
+ return "sha256:" + sha256_hash.hexdigest()
146
+
147
+ @classmethod
148
+ def update_agent_runner(
149
+ cls, target_path: Path, agent_runner_name: str, agent_release: AgentRelease
150
+ ) -> None:
151
+ """Download agent runner."""
152
+ download_url, remote_file_hash = agent_release.get_url_and_hash(
153
+ agent_runner_name
154
+ )
155
+
156
+ if target_path.exists():
157
+ # check sha
158
+ current_file_hash = cls.get_local_file_sha256(target_path)
159
+ if remote_file_hash == current_file_hash:
160
+ cls.logger.info(
161
+ "local and remote files hashes are match, nothing to download"
162
+ )
163
+ return
164
+ cls.logger.info(
165
+ "local and remote files hashes does not match, go to download"
166
+ )
167
+ else:
168
+ cls.logger.info("local file not found, go to download")
169
+
170
+ try:
171
+ with TemporaryDirectory() as tmp_dir:
172
+ tmp_file = Path(tmp_dir) / "agent_runner"
173
+ cls.download_file(download_url, tmp_file)
174
+ shutil.copy2(tmp_file, target_path)
175
+ if os.name == "posix":
176
+ target_path.chmod(target_path.stat().st_mode | stat.S_IEXEC)
177
+ except Exception:
178
+ # remove in caae of errors
179
+ if target_path.exists():
180
+ target_path.unlink(missing_ok=True)
181
+ raise
182
+
183
+ @classmethod
184
+ def get_agent_runner_path(cls, service_dir: Path) -> str:
185
+ """Get path to the agent runner bin palced."""
186
+ agent_runner_name = cls.get_agent_runner_executable_name()
187
+ agent_runner_path: Path = service_dir / agent_runner_name
188
+ agent_release = cls.get_agent_release_from_service_dir(service_dir=service_dir)
189
+
190
+ cls.update_agent_runner(
191
+ target_path=agent_runner_path,
192
+ agent_runner_name=agent_runner_name,
193
+ agent_release=agent_release,
194
+ )
195
+ return str(agent_runner_path)
196
+
197
+
198
+ def get_agent_runner_path(service_dir: Path) -> str:
199
+ """Get path to the agent runner bin placed."""
200
+ return AgentRunnerManager.get_agent_runner_path(
201
+ service_dir=service_dir,
202
+ )