genlayer-test 0.1.3__py3-none-any.whl → 0.3.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.
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/METADATA +77 -10
- genlayer_test-0.3.0.dist-info/RECORD +65 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/entry_points.txt +1 -1
- gltest/__init__.py +4 -4
- gltest/artifacts/__init__.py +5 -2
- gltest/artifacts/contract.py +94 -14
- gltest/glchain/__init__.py +3 -3
- gltest/glchain/account.py +15 -11
- gltest/glchain/client.py +39 -3
- gltest/glchain/contract.py +98 -31
- gltest/helpers/fixture_snapshot.py +3 -2
- gltest_cli/config/__init__.py +0 -0
- gltest_cli/config/constants.py +10 -0
- gltest_cli/config/general.py +10 -0
- gltest_cli/config/plugin.py +102 -0
- gltest_cli/config/types.py +137 -0
- gltest_cli/config/user.py +222 -0
- gltest_cli/logging.py +51 -0
- tests/__init__.py +0 -0
- tests/examples/tests/test_llm_erc20.py +2 -2
- tests/examples/tests/test_multi_read_erc20.py +13 -3
- tests/examples/tests/test_multi_tenant_storage.py +12 -3
- tests/examples/tests/test_read_erc20.py +2 -2
- tests/examples/tests/test_storage.py +4 -2
- tests/examples/tests/test_user_storage.py +17 -3
- tests/gltest/__init__.py +0 -0
- tests/gltest/artifact/__init__.py +0 -0
- tests/gltest/artifact/contracts/duplicate_ic_contract_1.py +22 -0
- tests/gltest/artifact/contracts/duplicate_ic_contract_2.py +22 -0
- tests/{artifact → gltest/artifact}/test_contract_definition.py +29 -30
- tests/gltest_cli/__init__.py +0 -0
- tests/gltest_cli/config/test_plugin.py +127 -0
- tests/gltest_cli/config/test_user.py +351 -0
- genlayer_test-0.1.3.dist-info/RECORD +0 -53
- gltest/plugin_config.py +0 -42
- gltest/plugin_hooks.py +0 -51
- tests/plugin/test_plugin_hooks.py +0 -78
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/top_level.txt +0 -0
- /tests/{plugin/conftest.py → conftest.py} +0 -0
- /tests/{artifact → gltest/artifact}/contracts/not_ic_contract.py +0 -0
- /tests/{assertions → gltest/assertions}/test_assertions.py +0 -0
gltest/glchain/contract.py
CHANGED
@@ -4,15 +4,20 @@ from eth_typing import (
|
|
4
4
|
)
|
5
5
|
from eth_account.signers.local import LocalAccount
|
6
6
|
from typing import Union
|
7
|
+
from pathlib import Path
|
7
8
|
from dataclasses import dataclass
|
8
|
-
from gltest.artifacts import
|
9
|
+
from gltest.artifacts import (
|
10
|
+
find_contract_definition_from_name,
|
11
|
+
find_contract_definition_from_path,
|
12
|
+
)
|
9
13
|
from gltest.assertions import tx_execution_failed
|
10
14
|
from gltest.exceptions import DeploymentError
|
11
|
-
from .client import get_gl_client
|
15
|
+
from .client import get_gl_client, get_gl_hosted_studio_client, get_local_client
|
12
16
|
from gltest.types import CalldataEncodable, GenLayerTransaction, TransactionStatus
|
13
17
|
from typing import List, Any, Type, Optional, Dict, Callable
|
14
18
|
import types
|
15
|
-
from
|
19
|
+
from gltest_cli.config.general import get_general_config
|
20
|
+
from gltest_cli.logging import logger
|
16
21
|
|
17
22
|
|
18
23
|
@dataclass
|
@@ -97,15 +102,16 @@ class Contract:
|
|
97
102
|
wait_interval: Optional[int] = None,
|
98
103
|
wait_retries: Optional[int] = None,
|
99
104
|
wait_triggered_transactions: bool = True,
|
100
|
-
wait_triggered_transactions_status: TransactionStatus = TransactionStatus.
|
105
|
+
wait_triggered_transactions_status: TransactionStatus = TransactionStatus.FINALIZED,
|
101
106
|
) -> GenLayerTransaction:
|
102
107
|
"""
|
103
108
|
Wrapper to the contract write method.
|
104
109
|
"""
|
110
|
+
general_config = get_general_config()
|
105
111
|
if wait_interval is None:
|
106
|
-
wait_interval = get_default_wait_interval()
|
112
|
+
wait_interval = general_config.get_default_wait_interval()
|
107
113
|
if wait_retries is None:
|
108
|
-
wait_retries = get_default_wait_retries()
|
114
|
+
wait_retries = general_config.get_default_wait_retries()
|
109
115
|
client = get_gl_client()
|
110
116
|
tx_hash = client.write_contract(
|
111
117
|
address=self.address,
|
@@ -146,13 +152,13 @@ class ContractFactory:
|
|
146
152
|
contract_code: str
|
147
153
|
|
148
154
|
@classmethod
|
149
|
-
def
|
155
|
+
def from_name(
|
150
156
|
cls: Type["ContractFactory"], contract_name: str
|
151
157
|
) -> "ContractFactory":
|
152
158
|
"""
|
153
159
|
Create a ContractFactory instance given the contract name.
|
154
160
|
"""
|
155
|
-
contract_info =
|
161
|
+
contract_info = find_contract_definition_from_name(contract_name)
|
156
162
|
if contract_info is None:
|
157
163
|
raise ValueError(
|
158
164
|
f"Contract {contract_name} not found in the contracts directory"
|
@@ -161,6 +167,44 @@ class ContractFactory:
|
|
161
167
|
contract_name=contract_name, contract_code=contract_info.contract_code
|
162
168
|
)
|
163
169
|
|
170
|
+
@classmethod
|
171
|
+
def from_file_path(
|
172
|
+
cls: Type["ContractFactory"], contract_file_path: Union[str, Path]
|
173
|
+
) -> "ContractFactory":
|
174
|
+
"""
|
175
|
+
Create a ContractFactory instance given the contract file path.
|
176
|
+
"""
|
177
|
+
contract_info = find_contract_definition_from_path(contract_file_path)
|
178
|
+
return cls(
|
179
|
+
contract_name=contract_info.contract_name,
|
180
|
+
contract_code=contract_info.contract_code,
|
181
|
+
)
|
182
|
+
|
183
|
+
def _get_schema_with_fallback(self):
|
184
|
+
"""Attempts to get the contract schema using multiple clients in a fallback pattern.
|
185
|
+
|
186
|
+
This method tries to get the contract schema in the following order:
|
187
|
+
1. Hosted studio client
|
188
|
+
2. Local client
|
189
|
+
3. Regular client
|
190
|
+
|
191
|
+
Returns:
|
192
|
+
Optional[Dict[str, Any]]: The contract schema if successful, None if all attempts fail.
|
193
|
+
"""
|
194
|
+
clients = (
|
195
|
+
("hosted studio", get_gl_hosted_studio_client()),
|
196
|
+
("local", get_local_client()),
|
197
|
+
("default", get_gl_client()),
|
198
|
+
)
|
199
|
+
for label, client in clients:
|
200
|
+
try:
|
201
|
+
return client.get_contract_schema_for_code(
|
202
|
+
contract_code=self.contract_code
|
203
|
+
)
|
204
|
+
except Exception as e:
|
205
|
+
logger.warning("Schema fetch via %s client failed: %s", label, e)
|
206
|
+
return None
|
207
|
+
|
164
208
|
def build_contract(
|
165
209
|
self,
|
166
210
|
contract_address: Union[Address, ChecksumAddress],
|
@@ -169,16 +213,13 @@ class ContractFactory:
|
|
169
213
|
"""
|
170
214
|
Build contract from address
|
171
215
|
"""
|
172
|
-
|
173
|
-
|
174
|
-
schema = client.get_contract_schema(address=contract_address)
|
175
|
-
return Contract.new(
|
176
|
-
address=contract_address, schema=schema, account=account
|
177
|
-
)
|
178
|
-
except Exception as e:
|
216
|
+
schema = self._get_schema_with_fallback()
|
217
|
+
if schema is None:
|
179
218
|
raise ValueError(
|
180
|
-
|
181
|
-
)
|
219
|
+
"Failed to get schema from all clients (hosted studio, local, and regular)"
|
220
|
+
)
|
221
|
+
|
222
|
+
return Contract.new(address=contract_address, schema=schema, account=account)
|
182
223
|
|
183
224
|
def deploy(
|
184
225
|
self,
|
@@ -193,10 +234,12 @@ class ContractFactory:
|
|
193
234
|
"""
|
194
235
|
Deploy the contract
|
195
236
|
"""
|
237
|
+
general_config = get_general_config()
|
196
238
|
if wait_interval is None:
|
197
|
-
wait_interval = get_default_wait_interval()
|
239
|
+
wait_interval = general_config.get_default_wait_interval()
|
198
240
|
if wait_retries is None:
|
199
|
-
wait_retries = get_default_wait_retries()
|
241
|
+
wait_retries = general_config.get_default_wait_retries()
|
242
|
+
|
200
243
|
client = get_gl_client()
|
201
244
|
try:
|
202
245
|
tx_hash = client.deploy_contract(
|
@@ -212,22 +255,27 @@ class ContractFactory:
|
|
212
255
|
interval=wait_interval,
|
213
256
|
retries=wait_retries,
|
214
257
|
)
|
215
|
-
if (
|
216
|
-
not tx_receipt
|
217
|
-
or "data" not in tx_receipt
|
218
|
-
or "contract_address" not in tx_receipt["data"]
|
219
|
-
):
|
258
|
+
if tx_execution_failed(tx_receipt):
|
220
259
|
raise ValueError(
|
221
|
-
"
|
260
|
+
f"Deployment transaction finalized with error: {tx_receipt}"
|
222
261
|
)
|
223
262
|
|
224
|
-
if
|
263
|
+
if (
|
264
|
+
"tx_data_decoded" in tx_receipt
|
265
|
+
and "contract_address" in tx_receipt["tx_data_decoded"]
|
266
|
+
):
|
267
|
+
contract_address = tx_receipt["tx_data_decoded"]["contract_address"]
|
268
|
+
elif "data" in tx_receipt and "contract_address" in tx_receipt["data"]:
|
269
|
+
contract_address = tx_receipt["data"]["contract_address"]
|
270
|
+
else:
|
271
|
+
raise ValueError("Transaction receipt missing contract address")
|
272
|
+
|
273
|
+
schema = self._get_schema_with_fallback()
|
274
|
+
if schema is None:
|
225
275
|
raise ValueError(
|
226
|
-
|
276
|
+
"Failed to get schema from all clients (hosted studio, local, and regular)"
|
227
277
|
)
|
228
278
|
|
229
|
-
contract_address = tx_receipt["data"]["contract_address"]
|
230
|
-
schema = client.get_contract_schema(address=contract_address)
|
231
279
|
return Contract.new(
|
232
280
|
address=contract_address, schema=schema, account=account
|
233
281
|
)
|
@@ -237,8 +285,27 @@ class ContractFactory:
|
|
237
285
|
) from e
|
238
286
|
|
239
287
|
|
240
|
-
def get_contract_factory(
|
288
|
+
def get_contract_factory(
|
289
|
+
contract_name: Optional[str] = None,
|
290
|
+
contract_file_path: Optional[Union[str, Path]] = None,
|
291
|
+
) -> ContractFactory:
|
241
292
|
"""
|
242
293
|
Get a ContractFactory instance for a contract.
|
294
|
+
|
295
|
+
Args:
|
296
|
+
contract_name: Name of the contract to load from artifacts
|
297
|
+
contract_file_path: Path to the contract file to load directly
|
298
|
+
|
299
|
+
Note: Exactly one of contract_name or contract_file_path must be provided.
|
243
300
|
"""
|
244
|
-
|
301
|
+
if contract_name is not None and contract_file_path is not None:
|
302
|
+
raise ValueError(
|
303
|
+
"Only one of contract_name or contract_file_path should be provided"
|
304
|
+
)
|
305
|
+
|
306
|
+
if contract_name is None and contract_file_path is None:
|
307
|
+
raise ValueError("Either contract_name or contract_file_path must be provided")
|
308
|
+
|
309
|
+
if contract_name is not None:
|
310
|
+
return ContractFactory.from_name(contract_name)
|
311
|
+
return ContractFactory.from_file_path(contract_file_path)
|
@@ -7,7 +7,7 @@ from gltest.exceptions import (
|
|
7
7
|
InvalidSnapshotError,
|
8
8
|
FixtureAnonymousFunctionError,
|
9
9
|
)
|
10
|
-
from
|
10
|
+
from gltest_cli.config.general import get_general_config
|
11
11
|
|
12
12
|
SUPPORTED_RPC_DOMAINS = ["localhost", "127.0.0.1"]
|
13
13
|
|
@@ -34,7 +34,8 @@ def load_fixture(fixture: Callable[[], T]) -> T:
|
|
34
34
|
if fixture.__name__ == "<lambda>":
|
35
35
|
raise FixtureAnonymousFunctionError("Fixtures must be named functions")
|
36
36
|
|
37
|
-
|
37
|
+
general_config = get_general_config()
|
38
|
+
rpc_url = general_config.get_rpc_url()
|
38
39
|
domain = urlparse(rpc_url).netloc.split(":")[0] # Extract domain without port
|
39
40
|
if domain not in SUPPORTED_RPC_DOMAINS:
|
40
41
|
return fixture()
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from genlayer_py.chains.localnet import SIMULATOR_JSON_RPC_URL
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
GLTEST_CONFIG_FILE = "gltest.config.yaml"
|
6
|
+
DEFAULT_NETWORK = "localnet"
|
7
|
+
DEFAULT_RPC_URL = SIMULATOR_JSON_RPC_URL
|
8
|
+
DEFAULT_ENVIRONMENT = ".env"
|
9
|
+
DEFAULT_CONTRACTS_DIR = Path("contracts")
|
10
|
+
DEFAULT_NETWORK_ID = 61999
|
@@ -0,0 +1,102 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from gltest_cli.logging import logger
|
3
|
+
from gltest_cli.config.user import (
|
4
|
+
user_config_exists,
|
5
|
+
load_user_config,
|
6
|
+
get_default_user_config,
|
7
|
+
)
|
8
|
+
from gltest_cli.config.general import (
|
9
|
+
get_general_config,
|
10
|
+
)
|
11
|
+
from gltest_cli.config.types import PluginConfig
|
12
|
+
|
13
|
+
|
14
|
+
def pytest_addoption(parser):
|
15
|
+
group = parser.getgroup("gltest")
|
16
|
+
group.addoption(
|
17
|
+
"--contracts-dir",
|
18
|
+
action="store",
|
19
|
+
default=None,
|
20
|
+
help="Path to directory containing contract files",
|
21
|
+
)
|
22
|
+
|
23
|
+
group.addoption(
|
24
|
+
"--default-wait-interval",
|
25
|
+
action="store",
|
26
|
+
default=10000,
|
27
|
+
help="Default interval (ms) between transaction receipt checks",
|
28
|
+
)
|
29
|
+
|
30
|
+
group.addoption(
|
31
|
+
"--default-wait-retries",
|
32
|
+
action="store",
|
33
|
+
default=15,
|
34
|
+
help="Default number of retries for transaction receipt checks",
|
35
|
+
)
|
36
|
+
|
37
|
+
group.addoption(
|
38
|
+
"--rpc-url",
|
39
|
+
action="store",
|
40
|
+
default=None,
|
41
|
+
help="RPC endpoint URL for the GenLayer network",
|
42
|
+
)
|
43
|
+
|
44
|
+
group.addoption(
|
45
|
+
"--network",
|
46
|
+
action="store",
|
47
|
+
default=None,
|
48
|
+
help="Target network (defaults to 'localnet' if no config file)",
|
49
|
+
)
|
50
|
+
|
51
|
+
|
52
|
+
def pytest_configure(config):
|
53
|
+
general_config = get_general_config()
|
54
|
+
|
55
|
+
# Handle user config from gltest.config.yaml
|
56
|
+
if not user_config_exists():
|
57
|
+
logger.warning(
|
58
|
+
"File `gltest.config.yaml` not found in the current directory, using default config"
|
59
|
+
)
|
60
|
+
logger.info("Create a `gltest.config.yaml` file to manage multiple networks")
|
61
|
+
user_config = get_default_user_config()
|
62
|
+
else:
|
63
|
+
logger.info(
|
64
|
+
"File `gltest.config.yaml` found in the current directory, using it"
|
65
|
+
)
|
66
|
+
user_config = load_user_config("gltest.config.yaml")
|
67
|
+
|
68
|
+
general_config.user_config = user_config
|
69
|
+
|
70
|
+
# Handle plugin config from command line
|
71
|
+
contracts_dir = config.getoption("--contracts-dir")
|
72
|
+
default_wait_interval = config.getoption("--default-wait-interval")
|
73
|
+
default_wait_retries = config.getoption("--default-wait-retries")
|
74
|
+
rpc_url = config.getoption("--rpc-url")
|
75
|
+
network = config.getoption("--network")
|
76
|
+
|
77
|
+
plugin_config = PluginConfig()
|
78
|
+
plugin_config.contracts_dir = (
|
79
|
+
Path(contracts_dir) if contracts_dir is not None else None
|
80
|
+
)
|
81
|
+
plugin_config.default_wait_interval = int(default_wait_interval)
|
82
|
+
plugin_config.default_wait_retries = int(default_wait_retries)
|
83
|
+
plugin_config.rpc_url = rpc_url
|
84
|
+
plugin_config.network_name = network
|
85
|
+
|
86
|
+
general_config.plugin_config = plugin_config
|
87
|
+
|
88
|
+
|
89
|
+
def pytest_sessionstart(session):
|
90
|
+
general_config = get_general_config()
|
91
|
+
logger.info("Using the following configuration:")
|
92
|
+
logger.info(f" RPC URL: {general_config.get_rpc_url()}")
|
93
|
+
logger.info(f" Selected Network: {general_config.get_network_name()}")
|
94
|
+
logger.info(
|
95
|
+
f" Available networks: {list(general_config.user_config.networks.keys())}"
|
96
|
+
)
|
97
|
+
logger.info(f" Contracts directory: {general_config.get_contracts_dir()}")
|
98
|
+
logger.info(f" Environment: {general_config.user_config.environment}")
|
99
|
+
logger.info(
|
100
|
+
f" Default wait interval: {general_config.get_default_wait_interval()} ms"
|
101
|
+
)
|
102
|
+
logger.info(f" Default wait retries: {general_config.get_default_wait_retries()}")
|
@@ -0,0 +1,137 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Dict, List, Optional
|
5
|
+
from genlayer_py.chains import localnet, testnet_asimov
|
6
|
+
from genlayer_py.types import GenLayerChain
|
7
|
+
|
8
|
+
|
9
|
+
class NetworkConfig(str, Enum):
|
10
|
+
LOCALNET = "localnet"
|
11
|
+
TESTNET_ASIMOV = "testnet_asimov"
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class PluginConfig:
|
16
|
+
contracts_dir: Optional[Path] = None
|
17
|
+
rpc_url: Optional[str] = None
|
18
|
+
default_wait_interval: Optional[int] = None
|
19
|
+
default_wait_retries: Optional[int] = None
|
20
|
+
network_name: Optional[str] = None
|
21
|
+
|
22
|
+
|
23
|
+
@dataclass
|
24
|
+
class NetworkConfigData:
|
25
|
+
id: Optional[int] = None
|
26
|
+
url: Optional[str] = None
|
27
|
+
accounts: Optional[List[str]] = None
|
28
|
+
from_account: Optional[str] = None
|
29
|
+
|
30
|
+
def __post_init__(self):
|
31
|
+
if self.id is not None and not isinstance(self.id, int):
|
32
|
+
raise ValueError("id must be an integer")
|
33
|
+
if self.url is not None and not isinstance(self.url, str):
|
34
|
+
raise ValueError("url must be a string")
|
35
|
+
if self.accounts is not None:
|
36
|
+
if not isinstance(self.accounts, list):
|
37
|
+
raise ValueError("accounts must be a list")
|
38
|
+
if not all(isinstance(acc, str) for acc in self.accounts):
|
39
|
+
raise ValueError("accounts must be strings")
|
40
|
+
if self.from_account is not None and not isinstance(self.from_account, str):
|
41
|
+
raise ValueError("from_account must be a string")
|
42
|
+
|
43
|
+
|
44
|
+
@dataclass
|
45
|
+
class PathConfig:
|
46
|
+
contracts: Optional[Path] = None
|
47
|
+
|
48
|
+
def __post_init__(self):
|
49
|
+
if self.contracts is not None and not isinstance(self.contracts, (str, Path)):
|
50
|
+
raise ValueError("contracts must be a string or Path")
|
51
|
+
|
52
|
+
|
53
|
+
@dataclass
|
54
|
+
class UserConfig:
|
55
|
+
networks: Dict[str, NetworkConfigData] = field(default_factory=dict)
|
56
|
+
paths: PathConfig = field(default_factory=PathConfig)
|
57
|
+
environment: Optional[str] = None
|
58
|
+
default_network: Optional[str] = None
|
59
|
+
|
60
|
+
def __post_init__(self):
|
61
|
+
if not isinstance(self.networks, dict):
|
62
|
+
raise ValueError("networks must be a dictionary")
|
63
|
+
|
64
|
+
if not isinstance(self.paths, PathConfig):
|
65
|
+
raise ValueError("paths must be a PathConfig instance")
|
66
|
+
|
67
|
+
if self.environment is not None and not isinstance(self.environment, str):
|
68
|
+
raise ValueError("environment must be a string")
|
69
|
+
|
70
|
+
if self.default_network is not None and not isinstance(
|
71
|
+
self.default_network, str
|
72
|
+
):
|
73
|
+
raise ValueError("default_network must be a string")
|
74
|
+
|
75
|
+
# Validate network configurations
|
76
|
+
for name, network_config in self.networks.items():
|
77
|
+
if not isinstance(network_config, NetworkConfigData):
|
78
|
+
raise ValueError(f"network {name} must be a NetworkConfigData instance")
|
79
|
+
|
80
|
+
|
81
|
+
@dataclass
|
82
|
+
class GeneralConfig:
|
83
|
+
user_config: UserConfig = field(default_factory=UserConfig)
|
84
|
+
plugin_config: PluginConfig = field(default_factory=PluginConfig)
|
85
|
+
|
86
|
+
def get_contracts_dir(self) -> Path:
|
87
|
+
if self.plugin_config.contracts_dir is not None:
|
88
|
+
return self.plugin_config.contracts_dir
|
89
|
+
return self.user_config.paths.contracts
|
90
|
+
|
91
|
+
def set_contracts_dir(self, contracts_dir: Path):
|
92
|
+
self.plugin_config.contracts_dir = contracts_dir
|
93
|
+
|
94
|
+
def get_rpc_url(self) -> str:
|
95
|
+
if self.plugin_config.rpc_url is not None:
|
96
|
+
return self.plugin_config.rpc_url
|
97
|
+
network_name = self.get_network_name()
|
98
|
+
return self.user_config.networks[network_name].url
|
99
|
+
|
100
|
+
def get_default_account_key(self, network_name: Optional[str] = None) -> str:
|
101
|
+
if network_name is not None:
|
102
|
+
return self.user_config.networks[network_name].from_account
|
103
|
+
return self.user_config.networks[self.user_config.default_network].from_account
|
104
|
+
|
105
|
+
def get_accounts_keys(self, network_name: Optional[str] = None) -> List[str]:
|
106
|
+
if network_name is not None:
|
107
|
+
return self.user_config.networks[network_name].accounts
|
108
|
+
return self.user_config.networks[self.user_config.default_network].accounts
|
109
|
+
|
110
|
+
def get_chain(self) -> GenLayerChain:
|
111
|
+
chain_map_by_id = {
|
112
|
+
61999: localnet,
|
113
|
+
4221: testnet_asimov,
|
114
|
+
}
|
115
|
+
network_name = self.get_network_name()
|
116
|
+
network_id = self.user_config.networks[network_name].id
|
117
|
+
if network_id not in chain_map_by_id:
|
118
|
+
known = ", ".join(map(str, chain_map_by_id.keys()))
|
119
|
+
raise ValueError(
|
120
|
+
f"Unknown network: {network_name}, possible values: {known}"
|
121
|
+
)
|
122
|
+
return chain_map_by_id[network_id]
|
123
|
+
|
124
|
+
def get_default_wait_interval(self) -> int:
|
125
|
+
if self.plugin_config.default_wait_interval is not None:
|
126
|
+
return self.plugin_config.default_wait_interval
|
127
|
+
raise ValueError("default_wait_interval is not set")
|
128
|
+
|
129
|
+
def get_default_wait_retries(self) -> int:
|
130
|
+
if self.plugin_config.default_wait_retries is not None:
|
131
|
+
return self.plugin_config.default_wait_retries
|
132
|
+
raise ValueError("default_wait_retries is not set")
|
133
|
+
|
134
|
+
def get_network_name(self) -> str:
|
135
|
+
if self.plugin_config.network_name is not None:
|
136
|
+
return self.plugin_config.network_name
|
137
|
+
return self.user_config.default_network
|