Skip to content

Commit 0fa885e

Browse files
committed
Merge branch 'feat/next' into set-log-level
2 parents d148401 + 21c77d3 commit 0fa885e

18 files changed

Lines changed: 296 additions & 139 deletions

CLI.md.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ generate() {
207207

208208
group "Get" "get"
209209
command "Get.Account" "get account"
210-
command "Get.Keys" "get keys"
210+
command "Get.Storage" "get storage"
211211
command "Get.StorageEntry" "get storage-entry"
212212
command "Get.Token" "get token"
213213
command "Get.Transaction" "get transaction"
Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33
from typing import Any
44

5+
from multiversx_sdk_cli.constants import SDK_PATH
56
from multiversx_sdk_cli.errors import (
67
AliasAlreadyExistsError,
78
AliasProtectedError,
@@ -10,18 +11,38 @@
1011
)
1112
from multiversx_sdk_cli.utils import read_json_file, write_json_file
1213

13-
SDK_PATH = Path("~/multiversx-sdk").expanduser().resolve()
1414
LOCAL_ADDRESS_CONFIG_PATH = Path("addresses.mxpy.json").resolve()
1515
GLOBAL_ADDRESS_CONFIG_PATH = SDK_PATH / "addresses.mxpy.json"
1616

1717

1818
def get_defaults() -> dict[str, str]:
19+
"""
20+
Not all values are required for a config to be valid.
21+
22+
Valid config for PEM wallets:
23+
```
24+
{
25+
"kind": "pem",
26+
"path": "/path/to/wallet.pem",
27+
"index": "0" # optional, defaults to 0
28+
}
29+
```
30+
31+
Valid config for KEYSTORE wallets:
32+
```
33+
{
34+
"kind": "keystore",
35+
"path": "/path/to/wallet.json",
36+
"index": "0" # optional, defaults to 0
37+
}
38+
```
39+
40+
For keystore wallets, you'll be prompted to enter the password when using the wallet.
41+
"""
1942
return {
2043
"kind": "",
2144
"path": "",
2245
"index": "",
23-
"password": "",
24-
"passwordPath": "",
2546
}
2647

2748

@@ -41,6 +62,7 @@ def _guard_valid_name(name: str):
4162

4263

4364
def get_active_address() -> dict[str, str]:
65+
"""Returns the active address configuration."""
4466
data = read_address_config_file()
4567
addresses: dict[str, Any] = data.get("addresses", {})
4668
active_address: str = data.get("active", "default")
@@ -65,25 +87,27 @@ def resolve_address_config_path() -> Path:
6587

6688

6789
def set_value(name: str, value: Any):
90+
"""Sets a key-value pair in the active address config."""
6891
_guard_valid_name(name)
6992
data = read_address_config_file()
7093
active_env = data.get("active", "default")
7194
data.setdefault("addresses", {})
7295
data["addresses"].setdefault(active_env, {})
7396
data["addresses"][active_env][name] = value
74-
write_file(data)
97+
_write_file(data)
7598

7699

77-
def write_file(data: dict[str, Any]):
100+
def _write_file(data: dict[str, Any]):
78101
env_path = resolve_address_config_path()
79102
write_json_file(str(env_path), data)
80103

81104

82105
def set_active(name: str):
106+
"""Switches to the address configuration with the given name."""
83107
data = read_address_config_file()
84108
_guard_valid_address_name(data, name)
85109
data["active"] = name
86-
write_file(data)
110+
_write_file(data)
87111

88112

89113
def _guard_valid_address_name(env: Any, name: str):
@@ -93,6 +117,7 @@ def _guard_valid_address_name(env: Any, name: str):
93117

94118

95119
def create_new_address_config(name: str, template: str):
120+
"""Creates a new address config with the given name and optional template."""
96121
data = read_address_config_file()
97122
_guard_alias_unique(data, name)
98123
new_address = {}
@@ -103,7 +128,7 @@ def create_new_address_config(name: str, template: str):
103128
data["active"] = name
104129
data.setdefault("addresses", {})
105130
data["addresses"][name] = new_address
106-
write_file(data)
131+
_write_file(data)
107132

108133

109134
def _guard_alias_unique(env: Any, name: str):
@@ -120,16 +145,17 @@ def delete_config_value(name: str):
120145
data.setdefault("addresses", {})
121146
data["addresses"].setdefault(active_env, {})
122147
del data["addresses"][active_env][name]
123-
write_file(data)
148+
_write_file(data)
124149

125150

126151
def delete_alias(name: str):
152+
"""Deletes the address configuration with the given name."""
127153
_guard_valid_alias_deletion(name)
128154
data = read_address_config_file()
129155
data["addresses"].pop(name, None)
130156
if data["active"] == name:
131157
data["active"] = "default"
132-
write_file(data)
158+
_write_file(data)
133159

134160

135161
def _guard_valid_alias_deletion(name: str):

multiversx_sdk_cli/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import multiversx_sdk_cli.version
3131
from multiversx_sdk_cli import config, errors, utils, ux
3232
from multiversx_sdk_cli.cli_shared import set_proxy_from_config_if_not_provided
33+
from multiversx_sdk_cli.constants import SDK_PATH
3334
from multiversx_sdk_cli.env import get_address_hrp
3435

3536
logger = logging.getLogger("cli")
@@ -49,7 +50,7 @@ def main(cli_args: list[str] = sys.argv[1:]):
4950

5051

5152
def _do_main(cli_args: list[str]):
52-
utils.ensure_folder(config.SDK_PATH)
53+
utils.ensure_folder(SDK_PATH)
5354
parser = setup_parser(cli_args)
5455
argcomplete.autocomplete(parser)
5556

multiversx_sdk_cli/cli_address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Any
44

55
from multiversx_sdk_cli import cli_shared
6-
from multiversx_sdk_cli.address import (
6+
from multiversx_sdk_cli.address_config import (
77
create_new_address_config,
88
delete_alias,
99
delete_config_value,

multiversx_sdk_cli/cli_get.py

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
import logging
22
from typing import Any, Optional
33

4-
from multiversx_sdk import Address, ProxyNetworkProvider, Token, TokenComputer
4+
from multiversx_sdk import Address
5+
from multiversx_sdk import NetworkProviderError as SDKNetworkProviderError
6+
from multiversx_sdk import ProxyNetworkProvider, Token, TokenComputer
57

68
from multiversx_sdk_cli import cli_shared
7-
from multiversx_sdk_cli.address import (
8-
get_active_address,
9-
read_address_config_file,
10-
resolve_address_config_path,
11-
)
129
from multiversx_sdk_cli.config import get_config_for_network_providers
1310
from multiversx_sdk_cli.env import MxpyEnv
1411
from multiversx_sdk_cli.errors import (
15-
AddressConfigFileError,
1612
ArgumentsNotProvidedError,
1713
BadUsage,
18-
NoWalletProvided,
19-
UnknownAddressAliasError,
14+
NetworkProviderError,
2015
)
2116
from multiversx_sdk_cli.utils import dump_out_json
2217

@@ -41,12 +36,12 @@ def setup_parser(subparsers: Any) -> Any:
4136
sub.set_defaults(func=get_account)
4237

4338
sub = cli_shared.add_command_subparser(
44-
subparsers, "get", "keys", "Get the storage (key-value pairs) of an account."
39+
subparsers, "get", "storage", "Get the storage (key-value pairs) of an account."
4540
)
4641
_add_alias_arg(sub)
4742
_add_address_arg(sub)
4843
_add_proxy_arg(sub)
49-
sub.set_defaults(func=get_keys)
44+
sub.set_defaults(func=get_storage)
5045

5146
sub = cli_shared.add_command_subparser(
5247
subparsers, "get", "storage-entry", "Get a specific storage entry (key-value pair) of an account."
@@ -74,6 +69,21 @@ def setup_parser(subparsers: Any) -> Any:
7469
sub.add_argument("--hash", type=str, required=True, help="the transaction hash")
7570
sub.set_defaults(func=get_transaction)
7671

72+
sub = cli_shared.add_command_subparser(subparsers, "get", "network-config", "Get the network configuration.")
73+
_add_proxy_arg(sub)
74+
sub.set_defaults(func=get_network_config)
75+
76+
sub = cli_shared.add_command_subparser(subparsers, "get", "network-status", "Get the network status.")
77+
_add_proxy_arg(sub)
78+
sub.add_argument(
79+
"--shard",
80+
type=int,
81+
choices=[0, 1, 2, 4294967295],
82+
default=4294967295,
83+
help="the shard to get the status for (default: %(default)s, which is methachain)",
84+
)
85+
sub.set_defaults(func=get_network_status)
86+
7787
parser.epilog = cli_shared.build_group_epilog(subparsers)
7888
return subparsers
7989

@@ -111,7 +121,7 @@ def get_account(args: Any):
111121
dump_out_json(response.raw)
112122

113123

114-
def get_keys(args: Any):
124+
def get_storage(args: Any):
115125
if args.alias and args.address:
116126
raise BadUsage("Provide either '--alias' or '--address'")
117127

@@ -142,7 +152,10 @@ def get_key(args: Any):
142152
proxy = _get_proxy(args)
143153

144154
logger.info(f"Fetching details about {address.to_bech32()}")
145-
response = proxy.get_account_storage_entry(address, args.key)
155+
try:
156+
response = proxy.get_account_storage_entry(address, args.key)
157+
except SDKNetworkProviderError as e:
158+
raise NetworkProviderError(e.url, e.data)
146159

147160
dump_out_json(response.raw)
148161

@@ -173,39 +186,36 @@ def get_token(args: Any):
173186

174187
def get_transaction(args: Any):
175188
proxy = _get_proxy(args)
176-
response = proxy.get_transaction(args.hash)
189+
try:
190+
response = proxy.get_transaction(args.hash)
191+
except SDKNetworkProviderError as e:
192+
raise NetworkProviderError(e.url, e.data)
193+
except Exception as e:
194+
raise NetworkProviderError("", str(e))
177195

178196
dump_out_json(response.raw)
179197

180198

181-
def _get_address_from_alias_or_config(alias: Optional[str], hrp: str) -> Address:
182-
if alias:
183-
file_path = resolve_address_config_path()
184-
if not file_path.is_file():
185-
raise AddressConfigFileError("The address config file was not found")
199+
def get_network_config(args: Any):
200+
proxy = _get_proxy(args)
201+
config = proxy.get_network_config()
186202

187-
file = read_address_config_file()
188-
if file == dict():
189-
raise AddressConfigFileError("Address config file is empty")
203+
dump_out_json(config.raw)
190204

191-
addresses: dict[str, Any] = file["addresses"]
192-
wallet = addresses.get(alias, None)
193-
if not wallet:
194-
raise UnknownAddressAliasError(alias)
195205

196-
logger.info(f"Using address of [{alias}] from address config.")
197-
account = cli_shared.load_wallet_from_address_config(wallet=wallet, hrp=hrp)
198-
return account.address
199-
else:
200-
active_address = get_active_address()
201-
if active_address == dict():
202-
logger.info("No default wallet found in address config.")
203-
raise NoWalletProvided()
206+
def get_network_status(args: Any):
207+
proxy = _get_proxy(args)
208+
status = proxy.get_network_status()
209+
210+
dump_out_json(status.raw)
204211

205-
alias_of_default_wallet = read_address_config_file().get("active", "")
206-
logger.info(f"Using address of [{alias_of_default_wallet}] from address config.")
207212

208-
account = cli_shared.load_wallet_from_address_config(wallet=active_address, hrp=hrp)
213+
def _get_address_from_alias_or_config(alias: Optional[str], hrp: str) -> Address:
214+
if alias:
215+
account = cli_shared.load_wallet_by_alias(alias=alias, hrp=hrp)
216+
return account.address
217+
else:
218+
account = cli_shared.load_default_wallet(hrp=hrp)
209219
return account.address
210220

211221

multiversx_sdk_cli/cli_multisig.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
189189
sub.add_argument(
190190
"--opt-gas-limit",
191191
type=int,
192-
help="the size of the new quorum (number of signatures required to approve a proposal)",
192+
help="optional gas limit for the async call",
193193
)
194194
sub.add_argument("--contract-abi", type=str, help="the ABI file of the contract to call")
195195
sub.add_argument("--function", type=str, help="the function to call")
@@ -208,7 +208,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
208208
sub.add_argument(
209209
"--opt-gas-limit",
210210
type=int,
211-
help="the size of the new quorum (number of signatures required to approve a proposal)",
211+
help="optional gas limit for the async call",
212212
)
213213
sub.add_argument("--contract-abi", type=str, help="the ABI file of the contract to call")
214214
sub.add_argument("--function", type=str, help="the function to call")
@@ -227,7 +227,7 @@ def setup_parser(args: list[str], subparsers: Any) -> Any:
227227
sub.add_argument(
228228
"--opt-gas-limit",
229229
type=int,
230-
help="the size of the new quorum (number of signatures required to approve a proposal)",
230+
help="optional gas limit for the async call",
231231
)
232232
sub.add_argument("--contract-abi", type=str, help="the ABI file of the contract to call")
233233
sub.add_argument("--function", type=str, help="the function to call")

multiversx_sdk_cli/cli_password.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
1+
import logging
12
from getpass import getpass
23
from typing import Any
34

5+
logger = logging.getLogger("cli.password")
6+
47

58
def load_password(args: Any) -> str:
69
if args.passfile:
10+
logger.warning(
11+
"Using a password file is DEPRECATED and will be removed in a future version. Instead, you'll be prompted to enter the password when using keystore wallets."
12+
)
713
with open(args.passfile) as pass_file:
814
return pass_file.read().strip()
915
return getpass("Keyfile's password: ")
1016

1117

1218
def load_guardian_password(args: Any) -> str:
1319
if args.guardian_passfile:
20+
logger.warning(
21+
"Using a password file is DEPRECATED and will be removed in a future version. Instead, you'll be prompted to enter the password when using keystore wallets."
22+
)
1423
with open(args.guardian_passfile) as pass_file:
1524
return pass_file.read().strip()
1625
return getpass("Keyfile's password: ")
1726

1827

1928
def load_relayer_password(args: Any) -> str:
2029
if args.relayer_passfile:
30+
logger.warning(
31+
"Using a password file is DEPRECATED and will be removed in a future version. Instead, you'll be prompted to enter the password when using keystore wallets."
32+
)
2133
with open(args.relayer_passfile) as pass_file:
2234
return pass_file.read().strip()
2335
return getpass("Keyfile's password: ")

0 commit comments

Comments
 (0)