bittensor-cli 9.9.0__tar.gz → 9.10.1__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.
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/PKG-INFO +13 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/README.md +9 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/cli.py +174 -58
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/__init__.py +4 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/chain_data.py +2 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/extrinsics/registration.py +29 -25
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/extrinsics/root.py +6 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/extrinsics/transfer.py +1 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/subtensor_interface.py +2 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/utils.py +16 -2
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/add.py +4 -3
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/children_hotkeys.py +16 -14
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/move.py +6 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/remove.py +5 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/subnets/price.py +126 -30
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/subnets/subnets.py +3 -2
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/sudo.py +36 -32
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/wallets.py +73 -19
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/weights.py +2 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/PKG-INFO +13 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/requires.txt +3 -3
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/pyproject.toml +4 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/MANIFEST.in +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/doc_generation_helper.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/balances.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/minigraph.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/networking.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/main-filters.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/main-header.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/neuron-details.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/price-multi.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/price-single.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/subnet-details-header.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/subnet-details.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/subnet-metrics.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/subnets-table.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/view.css +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/view.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/bittensor/templates/view.js +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/liquidity/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/liquidity/liquidity.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/liquidity/utils.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/stake/list.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/subnets/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/src/commands/view.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli/version.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/SOURCES.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/dependency_links.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/entry_points.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/bittensor_cli.egg-info/top_level.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: bittensor-cli
|
3
|
-
Version: 9.
|
3
|
+
Version: 9.10.1
|
4
4
|
Summary: Bittensor CLI
|
5
5
|
Author: bittensor.com
|
6
6
|
Project-URL: homepage, https://github.com/opentensor/btcli
|
@@ -11,7 +11,6 @@ Requires-Dist: wheel
|
|
11
11
|
Requires-Dist: async-substrate-interface>=1.4.2
|
12
12
|
Requires-Dist: aiohttp~=3.10.2
|
13
13
|
Requires-Dist: backoff~=2.2.1
|
14
|
-
Requires-Dist: click<8.2.0
|
15
14
|
Requires-Dist: GitPython>=3.0.0
|
16
15
|
Requires-Dist: netaddr~=1.3.0
|
17
16
|
Requires-Dist: numpy<3.0.0,>=2.0.1
|
@@ -20,8 +19,9 @@ Requires-Dist: pycryptodome<4.0.0,>=3.0.0
|
|
20
19
|
Requires-Dist: PyYAML~=6.0.1
|
21
20
|
Requires-Dist: rich<15.0,>=13.7
|
22
21
|
Requires-Dist: scalecodec==1.2.11
|
23
|
-
Requires-Dist: typer
|
24
|
-
Requires-Dist: bittensor-wallet>=
|
22
|
+
Requires-Dist: typer>=0.16
|
23
|
+
Requires-Dist: bittensor-wallet>=4.0.0
|
24
|
+
Requires-Dist: packaging
|
25
25
|
Requires-Dist: plotille>=5.0.0
|
26
26
|
Requires-Dist: plotly>=6.0.0
|
27
27
|
Provides-Extra: cuda
|
@@ -71,7 +71,15 @@ Installation steps are described below. For a full documentation on how to use `
|
|
71
71
|
|
72
72
|
## Install on macOS and Linux
|
73
73
|
|
74
|
-
You can install `btcli` on your local machine directly from source, PyPI, or Homebrew.
|
74
|
+
You can install `btcli` on your local machine directly from source, PyPI, or Homebrew.
|
75
|
+
**Make sure you verify your installation after you install**.
|
76
|
+
|
77
|
+
### For macOS users
|
78
|
+
Note that the macOS preinstalled CPython installation is compiled with LibreSSL instead of OpenSSL. There are a number
|
79
|
+
of issues with LibreSSL, and as such is not fully supported by the libraries used by btcli. Thus we highly recommend, if
|
80
|
+
you are using a Mac, to first install Python from [Homebrew](https://brew.sh/). Additionally, the Rust FFI bindings
|
81
|
+
[if installing from precompiled wheels (default)] require the Homebrew-installed OpenSSL pacakge. If you choose to use
|
82
|
+
the preinstalled Python version from macOS, things may not work completely.
|
75
83
|
|
76
84
|
|
77
85
|
### Install from [PyPI](https://pypi.org/project/bittensor/)
|
@@ -38,7 +38,15 @@ Installation steps are described below. For a full documentation on how to use `
|
|
38
38
|
|
39
39
|
## Install on macOS and Linux
|
40
40
|
|
41
|
-
You can install `btcli` on your local machine directly from source, PyPI, or Homebrew.
|
41
|
+
You can install `btcli` on your local machine directly from source, PyPI, or Homebrew.
|
42
|
+
**Make sure you verify your installation after you install**.
|
43
|
+
|
44
|
+
### For macOS users
|
45
|
+
Note that the macOS preinstalled CPython installation is compiled with LibreSSL instead of OpenSSL. There are a number
|
46
|
+
of issues with LibreSSL, and as such is not fully supported by the libraries used by btcli. Thus we highly recommend, if
|
47
|
+
you are using a Mac, to first install Python from [Homebrew](https://brew.sh/). Additionally, the Rust FFI bindings
|
48
|
+
[if installing from precompiled wheels (default)] require the Homebrew-installed OpenSSL pacakge. If you choose to use
|
49
|
+
the preinstalled Python version from macOS, things may not work completely.
|
42
50
|
|
43
51
|
|
44
52
|
### Install from [PyPI](https://pypi.org/project/bittensor/)
|
@@ -58,6 +58,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
58
58
|
validate_uri,
|
59
59
|
prompt_for_subnet_identity,
|
60
60
|
validate_rate_tolerance,
|
61
|
+
get_hotkey_pub_ss58,
|
61
62
|
)
|
62
63
|
from bittensor_cli.src.commands import sudo, wallets, view
|
63
64
|
from bittensor_cli.src.commands import weights as weights_cmds
|
@@ -250,7 +251,7 @@ class Options:
|
|
250
251
|
True,
|
251
252
|
"--prompt/--no-prompt",
|
252
253
|
" /--yes",
|
253
|
-
"
|
254
|
+
" /--no_prompt",
|
254
255
|
" /-y",
|
255
256
|
help="Enable or disable interactive prompts.",
|
256
257
|
)
|
@@ -409,10 +410,15 @@ def get_optional_netuid(netuid: Optional[int], all_netuids: bool) -> Optional[in
|
|
409
410
|
)
|
410
411
|
if answer is None:
|
411
412
|
return None
|
413
|
+
answer = answer.strip()
|
412
414
|
if answer.lower() == "all":
|
413
415
|
return None
|
414
416
|
else:
|
415
|
-
|
417
|
+
try:
|
418
|
+
return int(answer)
|
419
|
+
except ValueError:
|
420
|
+
err_console.print(f"Invalid netuid: {answer}")
|
421
|
+
return get_optional_netuid(None, False)
|
416
422
|
else:
|
417
423
|
return netuid
|
418
424
|
|
@@ -643,8 +649,21 @@ class CLIManager:
|
|
643
649
|
# },
|
644
650
|
}
|
645
651
|
self.subtensor = None
|
652
|
+
|
653
|
+
if sys.version_info < (3, 10):
|
654
|
+
# For Python 3.9 or lower
|
655
|
+
self.event_loop = asyncio.new_event_loop()
|
656
|
+
else:
|
657
|
+
try:
|
658
|
+
uvloop = importlib.import_module("uvloop")
|
659
|
+
self.event_loop = uvloop.new_event_loop()
|
660
|
+
except ModuleNotFoundError:
|
661
|
+
self.event_loop = asyncio.new_event_loop()
|
662
|
+
|
646
663
|
self.config_base_path = os.path.expanduser(defaults.config.base_path)
|
647
|
-
self.config_path = os.path.expanduser(
|
664
|
+
self.config_path = os.getenv("BTCLI_CONFIG_PATH") or os.path.expanduser(
|
665
|
+
defaults.config.path
|
666
|
+
)
|
648
667
|
|
649
668
|
self.app = typer.Typer(
|
650
669
|
rich_markup_mode="rich",
|
@@ -652,7 +671,12 @@ class CLIManager:
|
|
652
671
|
epilog=_epilog,
|
653
672
|
no_args_is_help=True,
|
654
673
|
)
|
655
|
-
self.config_app = typer.Typer(
|
674
|
+
self.config_app = typer.Typer(
|
675
|
+
epilog=_epilog,
|
676
|
+
help=f"Allows for getting/setting the config. "
|
677
|
+
f"Default path for the config file is [{COLORS.G.ARG}]{defaults.config.path}[/{COLORS.G.ARG}]. "
|
678
|
+
f"You can set your own with the env var [{COLORS.G.ARG}]BTCLI_CONFIG_PATH[/{COLORS.G.ARG}]",
|
679
|
+
)
|
656
680
|
self.wallet_app = typer.Typer(epilog=_epilog)
|
657
681
|
self.stake_app = typer.Typer(epilog=_epilog)
|
658
682
|
self.sudo_app = typer.Typer(epilog=_epilog)
|
@@ -773,6 +797,9 @@ class CLIManager:
|
|
773
797
|
self.wallet_app.command(
|
774
798
|
"regen-hotkey", rich_help_panel=HELP_PANELS["WALLET"]["SECURITY"]
|
775
799
|
)(self.wallet_regen_hotkey)
|
800
|
+
self.wallet_app.command(
|
801
|
+
"regen-hotkeypub", rich_help_panel=HELP_PANELS["WALLET"]["SECURITY"]
|
802
|
+
)(self.wallet_regen_hotkey_pub)
|
776
803
|
self.wallet_app.command(
|
777
804
|
"new-hotkey", rich_help_panel=HELP_PANELS["WALLET"]["MANAGEMENT"]
|
778
805
|
)(self.wallet_new_hotkey)
|
@@ -955,6 +982,10 @@ class CLIManager:
|
|
955
982
|
"regen_hotkey",
|
956
983
|
hidden=True,
|
957
984
|
)(self.wallet_regen_hotkey)
|
985
|
+
self.wallet_app.command(
|
986
|
+
"regen_hotkeypub",
|
987
|
+
hidden=True,
|
988
|
+
)(self.wallet_regen_hotkey_pub)
|
958
989
|
self.wallet_app.command(
|
959
990
|
"new_hotkey",
|
960
991
|
hidden=True,
|
@@ -1079,11 +1110,11 @@ class CLIManager:
|
|
1079
1110
|
|
1080
1111
|
self.subtensor = SubtensorInterface(network_)
|
1081
1112
|
elif self.config["network"]:
|
1082
|
-
self.subtensor = SubtensorInterface(self.config["network"])
|
1083
1113
|
console.print(
|
1084
1114
|
f"Using the specified network [{COLORS.G.LINKS}]{self.config['network']}"
|
1085
1115
|
f"[/{COLORS.G.LINKS}] from config"
|
1086
1116
|
)
|
1117
|
+
self.subtensor = SubtensorInterface(self.config["network"])
|
1087
1118
|
else:
|
1088
1119
|
self.subtensor = SubtensorInterface(defaults.subtensor.network)
|
1089
1120
|
return self.subtensor
|
@@ -1097,12 +1128,9 @@ class CLIManager:
|
|
1097
1128
|
initiated = False
|
1098
1129
|
try:
|
1099
1130
|
if self.subtensor:
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
else:
|
1104
|
-
initiated = True
|
1105
|
-
result = await cmd
|
1131
|
+
await self.subtensor.substrate.initialize()
|
1132
|
+
initiated = True
|
1133
|
+
result = await cmd
|
1106
1134
|
return result
|
1107
1135
|
except (ConnectionRefusedError, ssl.SSLError, InvalidHandshake):
|
1108
1136
|
err_console.print(f"Unable to connect to the chain: {self.subtensor}")
|
@@ -1128,12 +1156,14 @@ class CLIManager:
|
|
1128
1156
|
exit_early is True
|
1129
1157
|
): # temporarily to handle multiple run commands in one session
|
1130
1158
|
try:
|
1159
|
+
if self.subtensor:
|
1160
|
+
await self.subtensor.substrate.close()
|
1131
1161
|
raise typer.Exit()
|
1132
1162
|
except Exception as e: # ensures we always exit cleanly
|
1133
1163
|
if not isinstance(e, (typer.Exit, RuntimeError)):
|
1134
1164
|
err_console.print(f"An unknown error has occurred: {e}")
|
1135
1165
|
|
1136
|
-
return self.
|
1166
|
+
return self.event_loop.run_until_complete(_run())
|
1137
1167
|
|
1138
1168
|
def main_callback(
|
1139
1169
|
self,
|
@@ -1184,20 +1214,6 @@ class CLIManager:
|
|
1184
1214
|
if k in self.config.keys():
|
1185
1215
|
self.config[k] = v
|
1186
1216
|
|
1187
|
-
if sys.version_info < (3, 10):
|
1188
|
-
# For Python 3.9 or lower
|
1189
|
-
self.asyncio_runner = asyncio.get_event_loop().run_until_complete
|
1190
|
-
else:
|
1191
|
-
try:
|
1192
|
-
uvloop = importlib.import_module("uvloop")
|
1193
|
-
if sys.version_info >= (3, 11):
|
1194
|
-
self.asyncio_runner = uvloop.run
|
1195
|
-
else:
|
1196
|
-
uvloop.install()
|
1197
|
-
self.asyncio_runner = asyncio.run
|
1198
|
-
except ModuleNotFoundError:
|
1199
|
-
self.asyncio_runner = asyncio.run
|
1200
|
-
|
1201
1217
|
def verbosity_handler(
|
1202
1218
|
self, quiet: bool, verbose: bool, json_output: bool = False
|
1203
1219
|
) -> None:
|
@@ -1253,7 +1269,7 @@ class CLIManager:
|
|
1253
1269
|
use_cache: Optional[bool] = typer.Option(
|
1254
1270
|
None,
|
1255
1271
|
"--cache/--no-cache",
|
1256
|
-
"
|
1272
|
+
" /--no_cache",
|
1257
1273
|
help="Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on "
|
1258
1274
|
"commands such as `subnets metagraph`, `stake show` and `subnets list`.",
|
1259
1275
|
),
|
@@ -1502,6 +1518,8 @@ class CLIManager:
|
|
1502
1518
|
Column("[bold white]Value", style="gold1"),
|
1503
1519
|
Column("", style="medium_purple"),
|
1504
1520
|
box=box.SIMPLE_HEAD,
|
1521
|
+
title=f"[{COLORS.G.HEADER}]BTCLI Config[/{COLORS.G.HEADER}]: "
|
1522
|
+
f"[{COLORS.G.ARG}]{self.config_path}[/{COLORS.G.ARG}]",
|
1505
1523
|
)
|
1506
1524
|
|
1507
1525
|
for key, value in self.config.items():
|
@@ -1722,7 +1740,7 @@ class CLIManager:
|
|
1722
1740
|
if return_wallet_and_hotkey:
|
1723
1741
|
valid = utils.is_valid_wallet(wallet)
|
1724
1742
|
if valid[1]:
|
1725
|
-
return wallet, wallet
|
1743
|
+
return wallet, get_hotkey_pub_ss58(wallet)
|
1726
1744
|
else:
|
1727
1745
|
if wallet_hotkey and is_valid_ss58_address(wallet_hotkey):
|
1728
1746
|
return wallet, wallet_hotkey
|
@@ -2229,14 +2247,15 @@ class CLIManager:
|
|
2229
2247
|
|
2230
2248
|
if not wallet_path:
|
2231
2249
|
wallet_path = Prompt.ask(
|
2232
|
-
"Enter the path for the wallets directory",
|
2250
|
+
"Enter the path for the wallets directory",
|
2251
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2233
2252
|
)
|
2234
2253
|
wallet_path = os.path.expanduser(wallet_path)
|
2235
2254
|
|
2236
2255
|
if not wallet_name:
|
2237
2256
|
wallet_name = Prompt.ask(
|
2238
2257
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2239
|
-
default=defaults.wallet.name,
|
2258
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2240
2259
|
)
|
2241
2260
|
|
2242
2261
|
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
@@ -2280,7 +2299,7 @@ class CLIManager:
|
|
2280
2299
|
|
2281
2300
|
EXAMPLE
|
2282
2301
|
|
2283
|
-
[green]$[/green] btcli wallet
|
2302
|
+
[green]$[/green] btcli wallet regen-coldkeypub --ss58_address 5DkQ4...
|
2284
2303
|
|
2285
2304
|
[bold]Note[/bold]: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities.
|
2286
2305
|
"""
|
@@ -2288,13 +2307,14 @@ class CLIManager:
|
|
2288
2307
|
|
2289
2308
|
if not wallet_path:
|
2290
2309
|
wallet_path = Prompt.ask(
|
2291
|
-
"Enter the path to the wallets directory",
|
2310
|
+
"Enter the path to the wallets directory",
|
2311
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2292
2312
|
)
|
2293
2313
|
wallet_path = os.path.expanduser(wallet_path)
|
2294
2314
|
|
2295
2315
|
if not wallet_name:
|
2296
2316
|
wallet_name = Prompt.ask(
|
2297
|
-
f"Enter the name of the [{COLORS.G.CK}]new
|
2317
|
+
f"Enter the name of the [{COLORS.G.CK}]wallet for the new coldkeypub",
|
2298
2318
|
default=defaults.wallet.name,
|
2299
2319
|
)
|
2300
2320
|
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
@@ -2311,7 +2331,7 @@ class CLIManager:
|
|
2311
2331
|
address=ss58_address if ss58_address else public_key_hex
|
2312
2332
|
):
|
2313
2333
|
rich.print("[red]Error: Invalid SS58 address or public key![/red]")
|
2314
|
-
|
2334
|
+
return
|
2315
2335
|
return self._run_command(
|
2316
2336
|
wallets.regen_coldkey_pub(
|
2317
2337
|
wallet, ss58_address, public_key_hex, overwrite, json_output
|
@@ -2377,6 +2397,68 @@ class CLIManager:
|
|
2377
2397
|
)
|
2378
2398
|
)
|
2379
2399
|
|
2400
|
+
def wallet_regen_hotkey_pub(
|
2401
|
+
self,
|
2402
|
+
wallet_name: Optional[str] = Options.wallet_name,
|
2403
|
+
wallet_path: Optional[str] = Options.wallet_path,
|
2404
|
+
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
2405
|
+
public_key_hex: Optional[str] = Options.public_hex_key,
|
2406
|
+
ss58_address: Optional[str] = Options.ss58_address,
|
2407
|
+
overwrite: bool = Options.overwrite,
|
2408
|
+
quiet: bool = Options.quiet,
|
2409
|
+
verbose: bool = Options.verbose,
|
2410
|
+
json_output: bool = Options.json_output,
|
2411
|
+
):
|
2412
|
+
"""
|
2413
|
+
Regenerates the public part of a hotkey (hotkeypub.txt) for a wallet.
|
2414
|
+
|
2415
|
+
Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your hotkeypub.txt that you have on another machine to regenerate the hotkeypub.txt on this new machine.
|
2416
|
+
|
2417
|
+
USAGE
|
2418
|
+
|
2419
|
+
The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing hotkeypub.txt from old machine to regenerate the coldkeypub on the new machine.
|
2420
|
+
|
2421
|
+
EXAMPLE
|
2422
|
+
|
2423
|
+
[green]$[/green] btcli wallet regen-hotkeypub --ss58_address 5DkQ4...
|
2424
|
+
|
2425
|
+
[bold]Note[/bold]: This command is particularly useful for users who need to regenerate their hotkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old hotkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities.
|
2426
|
+
"""
|
2427
|
+
self.verbosity_handler(quiet, verbose, json_output)
|
2428
|
+
|
2429
|
+
if not wallet_path:
|
2430
|
+
wallet_path = Prompt.ask(
|
2431
|
+
"Enter the path to the wallets directory",
|
2432
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2433
|
+
)
|
2434
|
+
wallet_path = os.path.expanduser(wallet_path)
|
2435
|
+
|
2436
|
+
if not wallet_name:
|
2437
|
+
wallet_name = Prompt.ask(
|
2438
|
+
f"Enter the name of the [{COLORS.G.CK}]wallet for the new hotkeypub",
|
2439
|
+
default=defaults.wallet.name,
|
2440
|
+
)
|
2441
|
+
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
2442
|
+
|
2443
|
+
if not ss58_address and not public_key_hex:
|
2444
|
+
prompt_answer = typer.prompt(
|
2445
|
+
"Enter the ss58_address or the public key in hex"
|
2446
|
+
)
|
2447
|
+
if prompt_answer.startswith("0x"):
|
2448
|
+
public_key_hex = prompt_answer
|
2449
|
+
else:
|
2450
|
+
ss58_address = prompt_answer
|
2451
|
+
if not utils.is_valid_bittensor_address_or_public_key(
|
2452
|
+
address=ss58_address if ss58_address else public_key_hex
|
2453
|
+
):
|
2454
|
+
rich.print("[red]Error: Invalid SS58 address or public key![/red]")
|
2455
|
+
return False
|
2456
|
+
return self._run_command(
|
2457
|
+
wallets.regen_hotkey_pub(
|
2458
|
+
wallet, ss58_address, public_key_hex, overwrite, json_output
|
2459
|
+
)
|
2460
|
+
)
|
2461
|
+
|
2380
2462
|
def wallet_new_hotkey(
|
2381
2463
|
self,
|
2382
2464
|
wallet_name: Optional[str] = Options.wallet_name,
|
@@ -2417,7 +2499,7 @@ class CLIManager:
|
|
2417
2499
|
if not wallet_name:
|
2418
2500
|
wallet_name = Prompt.ask(
|
2419
2501
|
f"Enter the [{COLORS.G.CK}]wallet name",
|
2420
|
-
default=defaults.wallet.name,
|
2502
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2421
2503
|
)
|
2422
2504
|
|
2423
2505
|
if not wallet_hotkey:
|
@@ -2472,11 +2554,11 @@ class CLIManager:
|
|
2472
2554
|
if not wallet_hotkey:
|
2473
2555
|
wallet_hotkey = Prompt.ask(
|
2474
2556
|
"Enter the [blue]hotkey[/blue] name or "
|
2475
|
-
"[blue]hotkey ss58 address[/blue] [dim](to associate with your coldkey)[/dim]"
|
2557
|
+
"[blue]hotkey ss58 address[/blue] [dim](to associate with your coldkey)[/dim]",
|
2558
|
+
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
|
2476
2559
|
)
|
2477
2560
|
|
2478
|
-
|
2479
|
-
if is_valid_ss58_address(wallet_hotkey):
|
2561
|
+
if wallet_hotkey and is_valid_ss58_address(wallet_hotkey):
|
2480
2562
|
hotkey_ss58 = wallet_hotkey
|
2481
2563
|
wallet = self.wallet_ask(
|
2482
2564
|
wallet_name,
|
@@ -2496,8 +2578,11 @@ class CLIManager:
|
|
2496
2578
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
2497
2579
|
validate=WV.WALLET_AND_HOTKEY,
|
2498
2580
|
)
|
2499
|
-
hotkey_ss58 = wallet
|
2500
|
-
hotkey_display =
|
2581
|
+
hotkey_ss58 = get_hotkey_pub_ss58(wallet)
|
2582
|
+
hotkey_display = (
|
2583
|
+
f"hotkey [blue]{wallet_hotkey}[/blue] "
|
2584
|
+
f"[{COLORS.GENERAL.HK}]({hotkey_ss58})[/{COLORS.GENERAL.HK}]"
|
2585
|
+
)
|
2501
2586
|
|
2502
2587
|
return self._run_command(
|
2503
2588
|
wallets.associate_hotkey(
|
@@ -2544,13 +2629,14 @@ class CLIManager:
|
|
2544
2629
|
|
2545
2630
|
if not wallet_path:
|
2546
2631
|
wallet_path = Prompt.ask(
|
2547
|
-
"Enter the path to the wallets directory",
|
2632
|
+
"Enter the path to the wallets directory",
|
2633
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2548
2634
|
)
|
2549
2635
|
|
2550
2636
|
if not wallet_name:
|
2551
2637
|
wallet_name = Prompt.ask(
|
2552
2638
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2553
|
-
default=defaults.wallet.name,
|
2639
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2554
2640
|
)
|
2555
2641
|
|
2556
2642
|
wallet = self.wallet_ask(
|
@@ -2623,7 +2709,8 @@ class CLIManager:
|
|
2623
2709
|
|
2624
2710
|
if not wallet_ss58_address:
|
2625
2711
|
wallet_ss58_address = Prompt.ask(
|
2626
|
-
"Enter [blue]wallet name[/blue] or [blue]SS58 address[/blue] [dim]
|
2712
|
+
"Enter [blue]wallet name[/blue] or [blue]SS58 address[/blue] [dim]"
|
2713
|
+
"(leave blank to show all pending swaps)[/dim]"
|
2627
2714
|
)
|
2628
2715
|
if not wallet_ss58_address:
|
2629
2716
|
return self._run_command(
|
@@ -2687,18 +2774,18 @@ class CLIManager:
|
|
2687
2774
|
self.verbosity_handler(quiet, verbose, json_output)
|
2688
2775
|
if not wallet_path:
|
2689
2776
|
wallet_path = Prompt.ask(
|
2690
|
-
"Enter the path of wallets directory",
|
2777
|
+
"Enter the path of wallets directory",
|
2778
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2691
2779
|
)
|
2692
2780
|
|
2693
2781
|
if not wallet_name:
|
2694
2782
|
wallet_name = Prompt.ask(
|
2695
2783
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2696
|
-
default=defaults.wallet.name,
|
2697
2784
|
)
|
2698
2785
|
if not wallet_hotkey:
|
2699
2786
|
wallet_hotkey = Prompt.ask(
|
2700
2787
|
f"Enter the the name of the [{COLORS.G.HK}]new hotkey",
|
2701
|
-
default=defaults.wallet.hotkey,
|
2788
|
+
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
|
2702
2789
|
)
|
2703
2790
|
|
2704
2791
|
wallet = self.wallet_ask(
|
@@ -3507,7 +3594,7 @@ class CLIManager:
|
|
3507
3594
|
ask_for=[WO.NAME, WO.HOTKEY, WO.PATH],
|
3508
3595
|
validate=WV.WALLET_AND_HOTKEY,
|
3509
3596
|
)
|
3510
|
-
include_hotkeys = wallet
|
3597
|
+
include_hotkeys = get_hotkey_pub_ss58(wallet)
|
3511
3598
|
|
3512
3599
|
elif all_hotkeys or include_hotkeys or exclude_hotkeys:
|
3513
3600
|
wallet = self.wallet_ask(
|
@@ -3971,7 +4058,7 @@ class CLIManager:
|
|
3971
4058
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3972
4059
|
validate=WV.WALLET_AND_HOTKEY,
|
3973
4060
|
)
|
3974
|
-
destination_hotkey = destination_wallet
|
4061
|
+
destination_hotkey = get_hotkey_pub_ss58(destination_wallet)
|
3975
4062
|
else:
|
3976
4063
|
if is_valid_ss58_address(destination_hotkey):
|
3977
4064
|
destination_hotkey = destination_hotkey
|
@@ -4010,7 +4097,7 @@ class CLIManager:
|
|
4010
4097
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
4011
4098
|
validate=WV.WALLET_AND_HOTKEY,
|
4012
4099
|
)
|
4013
|
-
origin_hotkey = wallet
|
4100
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4014
4101
|
else:
|
4015
4102
|
if is_valid_ss58_address(wallet_hotkey):
|
4016
4103
|
origin_hotkey = wallet_hotkey
|
@@ -4022,7 +4109,7 @@ class CLIManager:
|
|
4022
4109
|
ask_for=[],
|
4023
4110
|
validate=WV.WALLET_AND_HOTKEY,
|
4024
4111
|
)
|
4025
|
-
origin_hotkey = wallet
|
4112
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4026
4113
|
|
4027
4114
|
if not interactive_selection:
|
4028
4115
|
if origin_netuid is None:
|
@@ -4158,7 +4245,8 @@ class CLIManager:
|
|
4158
4245
|
interactive_selection = False
|
4159
4246
|
if not wallet_hotkey:
|
4160
4247
|
origin_hotkey = Prompt.ask(
|
4161
|
-
"Enter the [blue]origin hotkey[/blue] name or ss58 address [bold]
|
4248
|
+
"Enter the [blue]origin hotkey[/blue] name or ss58 address [bold]"
|
4249
|
+
"(stake will be transferred FROM here)[/bold] "
|
4162
4250
|
"[dim](or press Enter to select from existing stakes)[/dim]"
|
4163
4251
|
)
|
4164
4252
|
if origin_hotkey == "":
|
@@ -4174,7 +4262,7 @@ class CLIManager:
|
|
4174
4262
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
4175
4263
|
validate=WV.WALLET_AND_HOTKEY,
|
4176
4264
|
)
|
4177
|
-
origin_hotkey = wallet
|
4265
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4178
4266
|
else:
|
4179
4267
|
if is_valid_ss58_address(wallet_hotkey):
|
4180
4268
|
origin_hotkey = wallet_hotkey
|
@@ -4186,7 +4274,7 @@ class CLIManager:
|
|
4186
4274
|
ask_for=[],
|
4187
4275
|
validate=WV.WALLET_AND_HOTKEY,
|
4188
4276
|
)
|
4189
|
-
origin_hotkey = wallet
|
4277
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4190
4278
|
|
4191
4279
|
if not interactive_selection:
|
4192
4280
|
if origin_netuid is None:
|
@@ -4733,7 +4821,7 @@ class CLIManager:
|
|
4733
4821
|
wallet = self.wallet_ask(
|
4734
4822
|
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
4735
4823
|
)
|
4736
|
-
result = self._run_command(
|
4824
|
+
result, err_msg = self._run_command(
|
4737
4825
|
sudo.sudo_set_hyperparameter(
|
4738
4826
|
wallet,
|
4739
4827
|
self.initialize_chain(network),
|
@@ -4745,7 +4833,7 @@ class CLIManager:
|
|
4745
4833
|
)
|
4746
4834
|
)
|
4747
4835
|
if json_output:
|
4748
|
-
json_console.print(json.dumps({"success": result}))
|
4836
|
+
json_console.print(json.dumps({"success": result, "err_msg": err_msg}))
|
4749
4837
|
return result
|
4750
4838
|
|
4751
4839
|
def sudo_get(
|
@@ -5009,7 +5097,7 @@ class CLIManager:
|
|
5009
5097
|
"Netuids to show the price for. Separate multiple netuids with a comma, for example: `-n 0,1,2`.",
|
5010
5098
|
),
|
5011
5099
|
interval_hours: int = typer.Option(
|
5012
|
-
|
5100
|
+
4,
|
5013
5101
|
"--interval-hours",
|
5014
5102
|
"--interval",
|
5015
5103
|
help="The number of hours to show the historical price for.",
|
@@ -5026,6 +5114,11 @@ class CLIManager:
|
|
5026
5114
|
"--log",
|
5027
5115
|
help="Show the price in log scale.",
|
5028
5116
|
),
|
5117
|
+
current_only: bool = typer.Option(
|
5118
|
+
False,
|
5119
|
+
"--current",
|
5120
|
+
help="Show only the current data, and no historical data.",
|
5121
|
+
),
|
5029
5122
|
html_output: bool = Options.html_output,
|
5030
5123
|
quiet: bool = Options.quiet,
|
5031
5124
|
verbose: bool = Options.verbose,
|
@@ -5048,9 +5141,31 @@ class CLIManager:
|
|
5048
5141
|
[green]$[/green] btcli subnets price --netuids 1,2,3,4 --html
|
5049
5142
|
"""
|
5050
5143
|
if json_output and html_output:
|
5051
|
-
print_error(
|
5144
|
+
print_error(
|
5145
|
+
f"Cannot specify both [{COLORS.G.ARG}]--json-output[/{COLORS.G.ARG}] "
|
5146
|
+
f"and [{COLORS.G.ARG}]--html[/{COLORS.G.ARG}]"
|
5147
|
+
)
|
5148
|
+
return
|
5149
|
+
if current_only and html_output:
|
5150
|
+
print_error(
|
5151
|
+
f"Cannot specify both [{COLORS.G.ARG}]--current[/{COLORS.G.ARG}] "
|
5152
|
+
f"and [{COLORS.G.ARG}]--html[/{COLORS.G.ARG}]"
|
5153
|
+
)
|
5052
5154
|
return
|
5053
5155
|
self.verbosity_handler(quiet=quiet, verbose=verbose, json_output=json_output)
|
5156
|
+
|
5157
|
+
subtensor = self.initialize_chain(network)
|
5158
|
+
non_archives = ["finney", "latent-lite", "subvortex"]
|
5159
|
+
if not current_only and subtensor.network in non_archives + [
|
5160
|
+
Constants.network_map[x] for x in non_archives
|
5161
|
+
]:
|
5162
|
+
err_console.print(
|
5163
|
+
f"[red]Error[/red] Running this command without [{COLORS.G.ARG}]--current[/{COLORS.G.ARG}] requires "
|
5164
|
+
"use of an archive node. "
|
5165
|
+
f"Try running again with the [{COLORS.G.ARG}]--network archive[/{COLORS.G.ARG}] flag."
|
5166
|
+
)
|
5167
|
+
return False
|
5168
|
+
|
5054
5169
|
if netuids:
|
5055
5170
|
netuids = parse_to_list(
|
5056
5171
|
netuids,
|
@@ -5080,10 +5195,11 @@ class CLIManager:
|
|
5080
5195
|
|
5081
5196
|
return self._run_command(
|
5082
5197
|
price.price(
|
5083
|
-
|
5198
|
+
subtensor,
|
5084
5199
|
netuids,
|
5085
5200
|
all_netuids,
|
5086
5201
|
interval_hours,
|
5202
|
+
current_only,
|
5087
5203
|
html_output,
|
5088
5204
|
log_scale,
|
5089
5205
|
json_output,
|
@@ -631,10 +631,10 @@ HYPERPARAMS = {
|
|
631
631
|
"min_allowed_weights": ("sudo_set_min_allowed_weights", False),
|
632
632
|
"max_weights_limit": ("sudo_set_max_weight_limit", False),
|
633
633
|
"tempo": ("sudo_set_tempo", True),
|
634
|
-
"min_difficulty": ("sudo_set_min_difficulty",
|
634
|
+
"min_difficulty": ("sudo_set_min_difficulty", True),
|
635
635
|
"max_difficulty": ("sudo_set_max_difficulty", False),
|
636
636
|
"weights_version": ("sudo_set_weights_version_key", False),
|
637
|
-
"weights_rate_limit": ("sudo_set_weights_set_rate_limit",
|
637
|
+
"weights_rate_limit": ("sudo_set_weights_set_rate_limit", True),
|
638
638
|
"adjustment_interval": ("sudo_set_adjustment_interval", True),
|
639
639
|
"activity_cutoff": ("sudo_set_activity_cutoff", False),
|
640
640
|
"target_regs_per_interval": ("sudo_set_target_registrations_per_interval", True),
|
@@ -645,7 +645,7 @@ HYPERPARAMS = {
|
|
645
645
|
"serving_rate_limit": ("sudo_set_serving_rate_limit", False),
|
646
646
|
"max_validators": ("sudo_set_max_allowed_validators", True),
|
647
647
|
"adjustment_alpha": ("sudo_set_adjustment_alpha", False),
|
648
|
-
"difficulty": ("sudo_set_difficulty",
|
648
|
+
"difficulty": ("sudo_set_difficulty", True),
|
649
649
|
"commit_reveal_period": (
|
650
650
|
"sudo_set_commit_reveal_weights_interval",
|
651
651
|
False,
|
@@ -653,7 +653,7 @@ HYPERPARAMS = {
|
|
653
653
|
"commit_reveal_weights_enabled": ("sudo_set_commit_reveal_weights_enabled", False),
|
654
654
|
"alpha_values": ("sudo_set_alpha_values", False),
|
655
655
|
"liquid_alpha_enabled": ("sudo_set_liquid_alpha_enabled", False),
|
656
|
-
"registration_allowed": ("sudo_set_network_registration_allowed",
|
656
|
+
"registration_allowed": ("sudo_set_network_registration_allowed", True),
|
657
657
|
"network_pow_registration_allowed": (
|
658
658
|
"sudo_set_network_pow_registration_allowed",
|
659
659
|
False,
|
@@ -718,6 +718,7 @@ class DynamicInfo(InfoBase):
|
|
718
718
|
network_registered_at: int
|
719
719
|
subnet_identity: Optional[SubnetIdentity]
|
720
720
|
subnet_volume: Balance
|
721
|
+
moving_price: float
|
721
722
|
|
722
723
|
@classmethod
|
723
724
|
def _fix_decoded(cls, decoded: Any) -> "DynamicInfo":
|
@@ -786,6 +787,7 @@ class DynamicInfo(InfoBase):
|
|
786
787
|
network_registered_at=int(decoded.get("network_registered_at")),
|
787
788
|
subnet_identity=subnet_identity,
|
788
789
|
subnet_volume=subnet_volume,
|
790
|
+
moving_price=fixed_to_float(decoded["moving_price"], 32),
|
789
791
|
)
|
790
792
|
|
791
793
|
def tao_to_alpha(self, tao: Balance) -> Balance:
|