bittensor-cli 9.9.0__tar.gz → 9.10.0__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.0}/PKG-INFO +13 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/README.md +9 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/cli.py +165 -54
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/extrinsics/registration.py +29 -25
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/extrinsics/root.py +6 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/extrinsics/transfer.py +1 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/subtensor_interface.py +2 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/utils.py +13 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/add.py +4 -3
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/children_hotkeys.py +16 -14
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/move.py +6 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/remove.py +5 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/subnets/price.py +126 -30
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/subnets/subnets.py +3 -2
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/sudo.py +13 -11
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/wallets.py +68 -16
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/weights.py +2 -1
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/PKG-INFO +13 -5
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/requires.txt +3 -3
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/pyproject.toml +4 -4
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/MANIFEST.in +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/doc_generation_helper.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/balances.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/chain_data.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/minigraph.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/networking.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/main-filters.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/main-header.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/neuron-details.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/price-multi.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/price-single.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/subnet-details-header.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/subnet-details.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/subnet-metrics.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/subnets-table.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/view.css +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/view.j2 +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/bittensor/templates/view.js +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/liquidity/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/liquidity/liquidity.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/liquidity/utils.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/stake/list.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/subnets/__init__.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/src/commands/view.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli/version.py +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/SOURCES.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/dependency_links.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/entry_points.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/bittensor_cli.egg-info/top_level.txt +0 -0
- {bittensor_cli-9.9.0 → bittensor_cli-9.10.0}/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.0
|
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
|
)
|
@@ -643,8 +644,21 @@ class CLIManager:
|
|
643
644
|
# },
|
644
645
|
}
|
645
646
|
self.subtensor = None
|
647
|
+
|
648
|
+
if sys.version_info < (3, 10):
|
649
|
+
# For Python 3.9 or lower
|
650
|
+
self.event_loop = asyncio.new_event_loop()
|
651
|
+
else:
|
652
|
+
try:
|
653
|
+
uvloop = importlib.import_module("uvloop")
|
654
|
+
self.event_loop = uvloop.new_event_loop()
|
655
|
+
except ModuleNotFoundError:
|
656
|
+
self.event_loop = asyncio.new_event_loop()
|
657
|
+
|
646
658
|
self.config_base_path = os.path.expanduser(defaults.config.base_path)
|
647
|
-
self.config_path = os.path.expanduser(
|
659
|
+
self.config_path = os.getenv("BTCLI_CONFIG_PATH") or os.path.expanduser(
|
660
|
+
defaults.config.path
|
661
|
+
)
|
648
662
|
|
649
663
|
self.app = typer.Typer(
|
650
664
|
rich_markup_mode="rich",
|
@@ -652,7 +666,12 @@ class CLIManager:
|
|
652
666
|
epilog=_epilog,
|
653
667
|
no_args_is_help=True,
|
654
668
|
)
|
655
|
-
self.config_app = typer.Typer(
|
669
|
+
self.config_app = typer.Typer(
|
670
|
+
epilog=_epilog,
|
671
|
+
help=f"Allows for getting/setting the config. "
|
672
|
+
f"Default path for the config file is [{COLORS.G.ARG}]{defaults.config.path}[/{COLORS.G.ARG}]. "
|
673
|
+
f"You can set your own with the env var [{COLORS.G.ARG}]BTCLI_CONFIG_PATH[/{COLORS.G.ARG}]",
|
674
|
+
)
|
656
675
|
self.wallet_app = typer.Typer(epilog=_epilog)
|
657
676
|
self.stake_app = typer.Typer(epilog=_epilog)
|
658
677
|
self.sudo_app = typer.Typer(epilog=_epilog)
|
@@ -773,6 +792,9 @@ class CLIManager:
|
|
773
792
|
self.wallet_app.command(
|
774
793
|
"regen-hotkey", rich_help_panel=HELP_PANELS["WALLET"]["SECURITY"]
|
775
794
|
)(self.wallet_regen_hotkey)
|
795
|
+
self.wallet_app.command(
|
796
|
+
"regen-hotkeypub", rich_help_panel=HELP_PANELS["WALLET"]["SECURITY"]
|
797
|
+
)(self.wallet_regen_hotkey_pub)
|
776
798
|
self.wallet_app.command(
|
777
799
|
"new-hotkey", rich_help_panel=HELP_PANELS["WALLET"]["MANAGEMENT"]
|
778
800
|
)(self.wallet_new_hotkey)
|
@@ -955,6 +977,10 @@ class CLIManager:
|
|
955
977
|
"regen_hotkey",
|
956
978
|
hidden=True,
|
957
979
|
)(self.wallet_regen_hotkey)
|
980
|
+
self.wallet_app.command(
|
981
|
+
"regen_hotkeypub",
|
982
|
+
hidden=True,
|
983
|
+
)(self.wallet_regen_hotkey_pub)
|
958
984
|
self.wallet_app.command(
|
959
985
|
"new_hotkey",
|
960
986
|
hidden=True,
|
@@ -1079,11 +1105,11 @@ class CLIManager:
|
|
1079
1105
|
|
1080
1106
|
self.subtensor = SubtensorInterface(network_)
|
1081
1107
|
elif self.config["network"]:
|
1082
|
-
self.subtensor = SubtensorInterface(self.config["network"])
|
1083
1108
|
console.print(
|
1084
1109
|
f"Using the specified network [{COLORS.G.LINKS}]{self.config['network']}"
|
1085
1110
|
f"[/{COLORS.G.LINKS}] from config"
|
1086
1111
|
)
|
1112
|
+
self.subtensor = SubtensorInterface(self.config["network"])
|
1087
1113
|
else:
|
1088
1114
|
self.subtensor = SubtensorInterface(defaults.subtensor.network)
|
1089
1115
|
return self.subtensor
|
@@ -1097,12 +1123,9 @@ class CLIManager:
|
|
1097
1123
|
initiated = False
|
1098
1124
|
try:
|
1099
1125
|
if self.subtensor:
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
else:
|
1104
|
-
initiated = True
|
1105
|
-
result = await cmd
|
1126
|
+
await self.subtensor.substrate.initialize()
|
1127
|
+
initiated = True
|
1128
|
+
result = await cmd
|
1106
1129
|
return result
|
1107
1130
|
except (ConnectionRefusedError, ssl.SSLError, InvalidHandshake):
|
1108
1131
|
err_console.print(f"Unable to connect to the chain: {self.subtensor}")
|
@@ -1128,12 +1151,14 @@ class CLIManager:
|
|
1128
1151
|
exit_early is True
|
1129
1152
|
): # temporarily to handle multiple run commands in one session
|
1130
1153
|
try:
|
1154
|
+
if self.subtensor:
|
1155
|
+
await self.subtensor.substrate.close()
|
1131
1156
|
raise typer.Exit()
|
1132
1157
|
except Exception as e: # ensures we always exit cleanly
|
1133
1158
|
if not isinstance(e, (typer.Exit, RuntimeError)):
|
1134
1159
|
err_console.print(f"An unknown error has occurred: {e}")
|
1135
1160
|
|
1136
|
-
return self.
|
1161
|
+
return self.event_loop.run_until_complete(_run())
|
1137
1162
|
|
1138
1163
|
def main_callback(
|
1139
1164
|
self,
|
@@ -1184,20 +1209,6 @@ class CLIManager:
|
|
1184
1209
|
if k in self.config.keys():
|
1185
1210
|
self.config[k] = v
|
1186
1211
|
|
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
1212
|
def verbosity_handler(
|
1202
1213
|
self, quiet: bool, verbose: bool, json_output: bool = False
|
1203
1214
|
) -> None:
|
@@ -1502,6 +1513,8 @@ class CLIManager:
|
|
1502
1513
|
Column("[bold white]Value", style="gold1"),
|
1503
1514
|
Column("", style="medium_purple"),
|
1504
1515
|
box=box.SIMPLE_HEAD,
|
1516
|
+
title=f"[{COLORS.G.HEADER}]BTCLI Config[/{COLORS.G.HEADER}]: "
|
1517
|
+
f"[{COLORS.G.ARG}]{self.config_path}[/{COLORS.G.ARG}]",
|
1505
1518
|
)
|
1506
1519
|
|
1507
1520
|
for key, value in self.config.items():
|
@@ -1722,7 +1735,7 @@ class CLIManager:
|
|
1722
1735
|
if return_wallet_and_hotkey:
|
1723
1736
|
valid = utils.is_valid_wallet(wallet)
|
1724
1737
|
if valid[1]:
|
1725
|
-
return wallet, wallet
|
1738
|
+
return wallet, get_hotkey_pub_ss58(wallet)
|
1726
1739
|
else:
|
1727
1740
|
if wallet_hotkey and is_valid_ss58_address(wallet_hotkey):
|
1728
1741
|
return wallet, wallet_hotkey
|
@@ -2229,14 +2242,15 @@ class CLIManager:
|
|
2229
2242
|
|
2230
2243
|
if not wallet_path:
|
2231
2244
|
wallet_path = Prompt.ask(
|
2232
|
-
"Enter the path for the wallets directory",
|
2245
|
+
"Enter the path for the wallets directory",
|
2246
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2233
2247
|
)
|
2234
2248
|
wallet_path = os.path.expanduser(wallet_path)
|
2235
2249
|
|
2236
2250
|
if not wallet_name:
|
2237
2251
|
wallet_name = Prompt.ask(
|
2238
2252
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2239
|
-
default=defaults.wallet.name,
|
2253
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2240
2254
|
)
|
2241
2255
|
|
2242
2256
|
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
@@ -2280,7 +2294,7 @@ class CLIManager:
|
|
2280
2294
|
|
2281
2295
|
EXAMPLE
|
2282
2296
|
|
2283
|
-
[green]$[/green] btcli wallet
|
2297
|
+
[green]$[/green] btcli wallet regen-coldkeypub --ss58_address 5DkQ4...
|
2284
2298
|
|
2285
2299
|
[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
2300
|
"""
|
@@ -2288,13 +2302,14 @@ class CLIManager:
|
|
2288
2302
|
|
2289
2303
|
if not wallet_path:
|
2290
2304
|
wallet_path = Prompt.ask(
|
2291
|
-
"Enter the path to the wallets directory",
|
2305
|
+
"Enter the path to the wallets directory",
|
2306
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2292
2307
|
)
|
2293
2308
|
wallet_path = os.path.expanduser(wallet_path)
|
2294
2309
|
|
2295
2310
|
if not wallet_name:
|
2296
2311
|
wallet_name = Prompt.ask(
|
2297
|
-
f"Enter the name of the [{COLORS.G.CK}]new
|
2312
|
+
f"Enter the name of the [{COLORS.G.CK}]wallet for the new coldkeypub",
|
2298
2313
|
default=defaults.wallet.name,
|
2299
2314
|
)
|
2300
2315
|
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
@@ -2311,7 +2326,7 @@ class CLIManager:
|
|
2311
2326
|
address=ss58_address if ss58_address else public_key_hex
|
2312
2327
|
):
|
2313
2328
|
rich.print("[red]Error: Invalid SS58 address or public key![/red]")
|
2314
|
-
|
2329
|
+
return
|
2315
2330
|
return self._run_command(
|
2316
2331
|
wallets.regen_coldkey_pub(
|
2317
2332
|
wallet, ss58_address, public_key_hex, overwrite, json_output
|
@@ -2377,6 +2392,68 @@ class CLIManager:
|
|
2377
2392
|
)
|
2378
2393
|
)
|
2379
2394
|
|
2395
|
+
def wallet_regen_hotkey_pub(
|
2396
|
+
self,
|
2397
|
+
wallet_name: Optional[str] = Options.wallet_name,
|
2398
|
+
wallet_path: Optional[str] = Options.wallet_path,
|
2399
|
+
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
2400
|
+
public_key_hex: Optional[str] = Options.public_hex_key,
|
2401
|
+
ss58_address: Optional[str] = Options.ss58_address,
|
2402
|
+
overwrite: bool = Options.overwrite,
|
2403
|
+
quiet: bool = Options.quiet,
|
2404
|
+
verbose: bool = Options.verbose,
|
2405
|
+
json_output: bool = Options.json_output,
|
2406
|
+
):
|
2407
|
+
"""
|
2408
|
+
Regenerates the public part of a hotkey (hotkeypub.txt) for a wallet.
|
2409
|
+
|
2410
|
+
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.
|
2411
|
+
|
2412
|
+
USAGE
|
2413
|
+
|
2414
|
+
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.
|
2415
|
+
|
2416
|
+
EXAMPLE
|
2417
|
+
|
2418
|
+
[green]$[/green] btcli wallet regen-hotkeypub --ss58_address 5DkQ4...
|
2419
|
+
|
2420
|
+
[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.
|
2421
|
+
"""
|
2422
|
+
self.verbosity_handler(quiet, verbose, json_output)
|
2423
|
+
|
2424
|
+
if not wallet_path:
|
2425
|
+
wallet_path = Prompt.ask(
|
2426
|
+
"Enter the path to the wallets directory",
|
2427
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2428
|
+
)
|
2429
|
+
wallet_path = os.path.expanduser(wallet_path)
|
2430
|
+
|
2431
|
+
if not wallet_name:
|
2432
|
+
wallet_name = Prompt.ask(
|
2433
|
+
f"Enter the name of the [{COLORS.G.CK}]wallet for the new hotkeypub",
|
2434
|
+
default=defaults.wallet.name,
|
2435
|
+
)
|
2436
|
+
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
|
2437
|
+
|
2438
|
+
if not ss58_address and not public_key_hex:
|
2439
|
+
prompt_answer = typer.prompt(
|
2440
|
+
"Enter the ss58_address or the public key in hex"
|
2441
|
+
)
|
2442
|
+
if prompt_answer.startswith("0x"):
|
2443
|
+
public_key_hex = prompt_answer
|
2444
|
+
else:
|
2445
|
+
ss58_address = prompt_answer
|
2446
|
+
if not utils.is_valid_bittensor_address_or_public_key(
|
2447
|
+
address=ss58_address if ss58_address else public_key_hex
|
2448
|
+
):
|
2449
|
+
rich.print("[red]Error: Invalid SS58 address or public key![/red]")
|
2450
|
+
return False
|
2451
|
+
return self._run_command(
|
2452
|
+
wallets.regen_hotkey_pub(
|
2453
|
+
wallet, ss58_address, public_key_hex, overwrite, json_output
|
2454
|
+
)
|
2455
|
+
)
|
2456
|
+
|
2380
2457
|
def wallet_new_hotkey(
|
2381
2458
|
self,
|
2382
2459
|
wallet_name: Optional[str] = Options.wallet_name,
|
@@ -2417,7 +2494,7 @@ class CLIManager:
|
|
2417
2494
|
if not wallet_name:
|
2418
2495
|
wallet_name = Prompt.ask(
|
2419
2496
|
f"Enter the [{COLORS.G.CK}]wallet name",
|
2420
|
-
default=defaults.wallet.name,
|
2497
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2421
2498
|
)
|
2422
2499
|
|
2423
2500
|
if not wallet_hotkey:
|
@@ -2472,11 +2549,11 @@ class CLIManager:
|
|
2472
2549
|
if not wallet_hotkey:
|
2473
2550
|
wallet_hotkey = Prompt.ask(
|
2474
2551
|
"Enter the [blue]hotkey[/blue] name or "
|
2475
|
-
"[blue]hotkey ss58 address[/blue] [dim](to associate with your coldkey)[/dim]"
|
2552
|
+
"[blue]hotkey ss58 address[/blue] [dim](to associate with your coldkey)[/dim]",
|
2553
|
+
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
|
2476
2554
|
)
|
2477
2555
|
|
2478
|
-
|
2479
|
-
if is_valid_ss58_address(wallet_hotkey):
|
2556
|
+
if wallet_hotkey and is_valid_ss58_address(wallet_hotkey):
|
2480
2557
|
hotkey_ss58 = wallet_hotkey
|
2481
2558
|
wallet = self.wallet_ask(
|
2482
2559
|
wallet_name,
|
@@ -2496,8 +2573,11 @@ class CLIManager:
|
|
2496
2573
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
2497
2574
|
validate=WV.WALLET_AND_HOTKEY,
|
2498
2575
|
)
|
2499
|
-
hotkey_ss58 = wallet
|
2500
|
-
hotkey_display =
|
2576
|
+
hotkey_ss58 = get_hotkey_pub_ss58(wallet)
|
2577
|
+
hotkey_display = (
|
2578
|
+
f"hotkey [blue]{wallet_hotkey}[/blue] "
|
2579
|
+
f"[{COLORS.GENERAL.HK}]({hotkey_ss58})[/{COLORS.GENERAL.HK}]"
|
2580
|
+
)
|
2501
2581
|
|
2502
2582
|
return self._run_command(
|
2503
2583
|
wallets.associate_hotkey(
|
@@ -2544,13 +2624,14 @@ class CLIManager:
|
|
2544
2624
|
|
2545
2625
|
if not wallet_path:
|
2546
2626
|
wallet_path = Prompt.ask(
|
2547
|
-
"Enter the path to the wallets directory",
|
2627
|
+
"Enter the path to the wallets directory",
|
2628
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2548
2629
|
)
|
2549
2630
|
|
2550
2631
|
if not wallet_name:
|
2551
2632
|
wallet_name = Prompt.ask(
|
2552
2633
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2553
|
-
default=defaults.wallet.name,
|
2634
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
2554
2635
|
)
|
2555
2636
|
|
2556
2637
|
wallet = self.wallet_ask(
|
@@ -2623,7 +2704,8 @@ class CLIManager:
|
|
2623
2704
|
|
2624
2705
|
if not wallet_ss58_address:
|
2625
2706
|
wallet_ss58_address = Prompt.ask(
|
2626
|
-
"Enter [blue]wallet name[/blue] or [blue]SS58 address[/blue] [dim]
|
2707
|
+
"Enter [blue]wallet name[/blue] or [blue]SS58 address[/blue] [dim]"
|
2708
|
+
"(leave blank to show all pending swaps)[/dim]"
|
2627
2709
|
)
|
2628
2710
|
if not wallet_ss58_address:
|
2629
2711
|
return self._run_command(
|
@@ -2687,18 +2769,18 @@ class CLIManager:
|
|
2687
2769
|
self.verbosity_handler(quiet, verbose, json_output)
|
2688
2770
|
if not wallet_path:
|
2689
2771
|
wallet_path = Prompt.ask(
|
2690
|
-
"Enter the path of wallets directory",
|
2772
|
+
"Enter the path of wallets directory",
|
2773
|
+
default=self.config.get("wallet_path") or defaults.wallet.path,
|
2691
2774
|
)
|
2692
2775
|
|
2693
2776
|
if not wallet_name:
|
2694
2777
|
wallet_name = Prompt.ask(
|
2695
2778
|
f"Enter the name of the [{COLORS.G.CK}]new wallet (coldkey)",
|
2696
|
-
default=defaults.wallet.name,
|
2697
2779
|
)
|
2698
2780
|
if not wallet_hotkey:
|
2699
2781
|
wallet_hotkey = Prompt.ask(
|
2700
2782
|
f"Enter the the name of the [{COLORS.G.HK}]new hotkey",
|
2701
|
-
default=defaults.wallet.hotkey,
|
2783
|
+
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
|
2702
2784
|
)
|
2703
2785
|
|
2704
2786
|
wallet = self.wallet_ask(
|
@@ -3507,7 +3589,7 @@ class CLIManager:
|
|
3507
3589
|
ask_for=[WO.NAME, WO.HOTKEY, WO.PATH],
|
3508
3590
|
validate=WV.WALLET_AND_HOTKEY,
|
3509
3591
|
)
|
3510
|
-
include_hotkeys = wallet
|
3592
|
+
include_hotkeys = get_hotkey_pub_ss58(wallet)
|
3511
3593
|
|
3512
3594
|
elif all_hotkeys or include_hotkeys or exclude_hotkeys:
|
3513
3595
|
wallet = self.wallet_ask(
|
@@ -3971,7 +4053,7 @@ class CLIManager:
|
|
3971
4053
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3972
4054
|
validate=WV.WALLET_AND_HOTKEY,
|
3973
4055
|
)
|
3974
|
-
destination_hotkey = destination_wallet
|
4056
|
+
destination_hotkey = get_hotkey_pub_ss58(destination_wallet)
|
3975
4057
|
else:
|
3976
4058
|
if is_valid_ss58_address(destination_hotkey):
|
3977
4059
|
destination_hotkey = destination_hotkey
|
@@ -4010,7 +4092,7 @@ class CLIManager:
|
|
4010
4092
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
4011
4093
|
validate=WV.WALLET_AND_HOTKEY,
|
4012
4094
|
)
|
4013
|
-
origin_hotkey = wallet
|
4095
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4014
4096
|
else:
|
4015
4097
|
if is_valid_ss58_address(wallet_hotkey):
|
4016
4098
|
origin_hotkey = wallet_hotkey
|
@@ -4022,7 +4104,7 @@ class CLIManager:
|
|
4022
4104
|
ask_for=[],
|
4023
4105
|
validate=WV.WALLET_AND_HOTKEY,
|
4024
4106
|
)
|
4025
|
-
origin_hotkey = wallet
|
4107
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4026
4108
|
|
4027
4109
|
if not interactive_selection:
|
4028
4110
|
if origin_netuid is None:
|
@@ -4158,7 +4240,8 @@ class CLIManager:
|
|
4158
4240
|
interactive_selection = False
|
4159
4241
|
if not wallet_hotkey:
|
4160
4242
|
origin_hotkey = Prompt.ask(
|
4161
|
-
"Enter the [blue]origin hotkey[/blue] name or ss58 address [bold]
|
4243
|
+
"Enter the [blue]origin hotkey[/blue] name or ss58 address [bold]"
|
4244
|
+
"(stake will be transferred FROM here)[/bold] "
|
4162
4245
|
"[dim](or press Enter to select from existing stakes)[/dim]"
|
4163
4246
|
)
|
4164
4247
|
if origin_hotkey == "":
|
@@ -4174,7 +4257,7 @@ class CLIManager:
|
|
4174
4257
|
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
4175
4258
|
validate=WV.WALLET_AND_HOTKEY,
|
4176
4259
|
)
|
4177
|
-
origin_hotkey = wallet
|
4260
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4178
4261
|
else:
|
4179
4262
|
if is_valid_ss58_address(wallet_hotkey):
|
4180
4263
|
origin_hotkey = wallet_hotkey
|
@@ -4186,7 +4269,7 @@ class CLIManager:
|
|
4186
4269
|
ask_for=[],
|
4187
4270
|
validate=WV.WALLET_AND_HOTKEY,
|
4188
4271
|
)
|
4189
|
-
origin_hotkey = wallet
|
4272
|
+
origin_hotkey = get_hotkey_pub_ss58(wallet)
|
4190
4273
|
|
4191
4274
|
if not interactive_selection:
|
4192
4275
|
if origin_netuid is None:
|
@@ -5009,7 +5092,7 @@ class CLIManager:
|
|
5009
5092
|
"Netuids to show the price for. Separate multiple netuids with a comma, for example: `-n 0,1,2`.",
|
5010
5093
|
),
|
5011
5094
|
interval_hours: int = typer.Option(
|
5012
|
-
|
5095
|
+
4,
|
5013
5096
|
"--interval-hours",
|
5014
5097
|
"--interval",
|
5015
5098
|
help="The number of hours to show the historical price for.",
|
@@ -5026,6 +5109,11 @@ class CLIManager:
|
|
5026
5109
|
"--log",
|
5027
5110
|
help="Show the price in log scale.",
|
5028
5111
|
),
|
5112
|
+
current_only: bool = typer.Option(
|
5113
|
+
False,
|
5114
|
+
"--current",
|
5115
|
+
help="Show only the current data, and no historical data.",
|
5116
|
+
),
|
5029
5117
|
html_output: bool = Options.html_output,
|
5030
5118
|
quiet: bool = Options.quiet,
|
5031
5119
|
verbose: bool = Options.verbose,
|
@@ -5048,9 +5136,31 @@ class CLIManager:
|
|
5048
5136
|
[green]$[/green] btcli subnets price --netuids 1,2,3,4 --html
|
5049
5137
|
"""
|
5050
5138
|
if json_output and html_output:
|
5051
|
-
print_error(
|
5139
|
+
print_error(
|
5140
|
+
f"Cannot specify both [{COLORS.G.ARG}]--json-output[/{COLORS.G.ARG}] "
|
5141
|
+
f"and [{COLORS.G.ARG}]--html[/{COLORS.G.ARG}]"
|
5142
|
+
)
|
5143
|
+
return
|
5144
|
+
if current_only and html_output:
|
5145
|
+
print_error(
|
5146
|
+
f"Cannot specify both [{COLORS.G.ARG}]--current[/{COLORS.G.ARG}] "
|
5147
|
+
f"and [{COLORS.G.ARG}]--html[/{COLORS.G.ARG}]"
|
5148
|
+
)
|
5052
5149
|
return
|
5053
5150
|
self.verbosity_handler(quiet=quiet, verbose=verbose, json_output=json_output)
|
5151
|
+
|
5152
|
+
subtensor = self.initialize_chain(network)
|
5153
|
+
non_archives = ["finney", "latent-lite", "subvortex"]
|
5154
|
+
if not current_only and subtensor.network in non_archives + [
|
5155
|
+
Constants.network_map[x] for x in non_archives
|
5156
|
+
]:
|
5157
|
+
err_console.print(
|
5158
|
+
f"[red]Error[/red] Running this command without [{COLORS.G.ARG}]--current[/{COLORS.G.ARG}] requires "
|
5159
|
+
"use of an archive node. "
|
5160
|
+
f"Try running again with the [{COLORS.G.ARG}]--network archive[/{COLORS.G.ARG}] flag."
|
5161
|
+
)
|
5162
|
+
return False
|
5163
|
+
|
5054
5164
|
if netuids:
|
5055
5165
|
netuids = parse_to_list(
|
5056
5166
|
netuids,
|
@@ -5080,10 +5190,11 @@ class CLIManager:
|
|
5080
5190
|
|
5081
5191
|
return self._run_command(
|
5082
5192
|
price.price(
|
5083
|
-
|
5193
|
+
subtensor,
|
5084
5194
|
netuids,
|
5085
5195
|
all_netuids,
|
5086
5196
|
interval_hours,
|
5197
|
+
current_only,
|
5087
5198
|
html_output,
|
5088
5199
|
log_scale,
|
5089
5200
|
json_output,
|