bittensor-cli 9.0.0rc4__py3-none-any.whl → 9.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bittensor_cli/__init__.py +2 -3
- bittensor_cli/cli.py +254 -99
- bittensor_cli/src/__init__.py +50 -25
- bittensor_cli/src/bittensor/balances.py +1 -1
- bittensor_cli/src/bittensor/chain_data.py +20 -8
- bittensor_cli/src/bittensor/extrinsics/registration.py +26 -34
- bittensor_cli/src/bittensor/extrinsics/root.py +5 -11
- bittensor_cli/src/bittensor/extrinsics/transfer.py +15 -13
- bittensor_cli/src/bittensor/subtensor_interface.py +20 -20
- bittensor_cli/src/bittensor/utils.py +129 -19
- bittensor_cli/src/commands/stake/add.py +4 -8
- bittensor_cli/src/commands/stake/children_hotkeys.py +13 -19
- bittensor_cli/src/commands/stake/list.py +44 -77
- bittensor_cli/src/commands/stake/move.py +3 -3
- bittensor_cli/src/commands/stake/remove.py +216 -101
- bittensor_cli/src/commands/subnets/subnets.py +147 -5
- bittensor_cli/src/commands/sudo.py +192 -70
- bittensor_cli/src/commands/wallets.py +102 -52
- bittensor_cli/src/commands/weights.py +9 -13
- bittensor_cli/version.py +18 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/METADATA +3 -3
- bittensor_cli-9.0.2.dist-info/RECORD +35 -0
- bittensor_cli-9.0.0rc4.dist-info/RECORD +0 -34
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/WHEEL +0 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/top_level.txt +0 -0
bittensor_cli/cli.py
CHANGED
@@ -26,7 +26,9 @@ from bittensor_cli.src import (
|
|
26
26
|
WalletValidationTypes as WV,
|
27
27
|
Constants,
|
28
28
|
COLOR_PALETTE,
|
29
|
+
HYPERPARAMS,
|
29
30
|
)
|
31
|
+
from bittensor_cli.version import __version__, __version_as_int__
|
30
32
|
from bittensor_cli.src.bittensor import utils
|
31
33
|
from bittensor_cli.src.bittensor.balances import Balance
|
32
34
|
from async_substrate_interface.errors import SubstrateRequestException
|
@@ -72,21 +74,8 @@ except ImportError:
|
|
72
74
|
pass
|
73
75
|
|
74
76
|
|
75
|
-
__version__ = "9.0.0rc4"
|
76
77
|
|
77
78
|
|
78
|
-
_core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
|
79
|
-
_version_split = _core_version.split(".")
|
80
|
-
__version_info__ = tuple(int(part) for part in _version_split)
|
81
|
-
_version_int_base = 1000
|
82
|
-
assert max(__version_info__) < _version_int_base
|
83
|
-
|
84
|
-
__version_as_int__: int = sum(
|
85
|
-
e * (_version_int_base**i) for i, e in enumerate(reversed(__version_info__))
|
86
|
-
)
|
87
|
-
assert __version_as_int__ < 2**31 # fits in int32
|
88
|
-
__new_signature_version__ = 360
|
89
|
-
|
90
79
|
_epilog = "Made with [bold red]:heart:[/bold red] by The Openτensor Foundaτion"
|
91
80
|
|
92
81
|
np.set_printoptions(precision=8, suppress=True, floatmode="fixed")
|
@@ -124,7 +113,7 @@ class Options:
|
|
124
113
|
)
|
125
114
|
mnemonic = typer.Option(
|
126
115
|
None,
|
127
|
-
help=
|
116
|
+
help='Mnemonic used to regenerate your key. For example: "horse cart dog ..."',
|
128
117
|
)
|
129
118
|
seed = typer.Option(
|
130
119
|
None, help="Seed hex string used to regenerate your key. For example: 0x1234..."
|
@@ -141,22 +130,15 @@ class Options:
|
|
141
130
|
use_password = typer.Option(
|
142
131
|
True,
|
143
132
|
help="Set this to `True` to protect the generated Bittensor key with a password.",
|
144
|
-
is_flag=True,
|
145
|
-
flag_value=False,
|
146
133
|
)
|
147
134
|
public_hex_key = typer.Option(None, help="The public key in hex format.")
|
148
135
|
ss58_address = typer.Option(
|
149
136
|
None, "--ss58", "--ss58-address", help="The SS58 address of the coldkey."
|
150
137
|
)
|
151
|
-
|
152
|
-
False,
|
153
|
-
help="Overwrite the old coldkey with the newly generated coldkey.",
|
154
|
-
prompt=True,
|
155
|
-
)
|
156
|
-
overwrite_hotkey = typer.Option(
|
138
|
+
overwrite = typer.Option(
|
157
139
|
False,
|
158
|
-
|
159
|
-
|
140
|
+
"--overwrite/--no-overwrite",
|
141
|
+
help="Overwrite the existing wallet file with the new one.",
|
160
142
|
)
|
161
143
|
network = typer.Option(
|
162
144
|
None,
|
@@ -663,7 +645,7 @@ class CLIManager:
|
|
663
645
|
self.config_app.command("set")(self.set_config)
|
664
646
|
self.config_app.command("get")(self.get_config)
|
665
647
|
self.config_app.command("clear")(self.del_config)
|
666
|
-
self.config_app.command("metagraph", hidden=True)(self.metagraph_config)
|
648
|
+
# self.config_app.command("metagraph", hidden=True)(self.metagraph_config)
|
667
649
|
|
668
650
|
# wallet commands
|
669
651
|
self.wallet_app.command(
|
@@ -811,6 +793,12 @@ class CLIManager:
|
|
811
793
|
self.subnets_app.command(
|
812
794
|
"price", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"]
|
813
795
|
)(self.subnets_price)
|
796
|
+
self.subnets_app.command(
|
797
|
+
"set-identity", rich_help_panel=HELP_PANELS["SUBNETS"]["IDENTITY"]
|
798
|
+
)(self.subnets_set_identity)
|
799
|
+
self.subnets_app.command(
|
800
|
+
"get-identity", rich_help_panel=HELP_PANELS["SUBNETS"]["IDENTITY"]
|
801
|
+
)(self.subnets_get_identity)
|
814
802
|
|
815
803
|
# weights commands
|
816
804
|
self.weights_app.command(
|
@@ -970,13 +958,13 @@ class CLIManager:
|
|
970
958
|
finally:
|
971
959
|
if initiated is False:
|
972
960
|
asyncio.create_task(cmd).cancel()
|
973
|
-
if
|
961
|
+
if (
|
962
|
+
exit_early is True
|
963
|
+
): # temporarily to handle multiple run commands in one session
|
974
964
|
try:
|
975
965
|
raise typer.Exit()
|
976
966
|
except Exception as e: # ensures we always exit cleanly
|
977
|
-
if not isinstance(
|
978
|
-
e, (typer.Exit, RuntimeError)
|
979
|
-
): # temporarily to handle multiple run commands in one session
|
967
|
+
if not isinstance(e, (typer.Exit, RuntimeError)):
|
980
968
|
err_console.print(f"An unknown error has occurred: {e}")
|
981
969
|
|
982
970
|
return self.asyncio_runner(_run())
|
@@ -1563,7 +1551,7 @@ class CLIManager:
|
|
1563
1551
|
"""
|
1564
1552
|
Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config.
|
1565
1553
|
|
1566
|
-
The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that
|
1554
|
+
The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address (or an `<ENCRYPTED>` marker, for encrypted hotkeys) is displayed for each coldkey and hotkey that exists on the device.
|
1567
1555
|
|
1568
1556
|
Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the
|
1569
1557
|
public keys are available (`?` denotes unavailable or encrypted keys).
|
@@ -1648,7 +1636,7 @@ class CLIManager:
|
|
1648
1636
|
"Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
|
1649
1637
|
)
|
1650
1638
|
|
1651
|
-
ask_for = [WO.NAME
|
1639
|
+
ask_for = [WO.NAME] if not all_wallets else []
|
1652
1640
|
validate = WV.WALLET if not all_wallets else WV.NONE
|
1653
1641
|
wallet = self.wallet_ask(
|
1654
1642
|
wallet_name, wallet_path, wallet_hotkey, ask_for=ask_for, validate=validate
|
@@ -1696,9 +1684,11 @@ class CLIManager:
|
|
1696
1684
|
None,
|
1697
1685
|
"--amount",
|
1698
1686
|
"-a",
|
1699
|
-
prompt=True,
|
1700
1687
|
help="Amount (in TAO) to transfer.",
|
1701
1688
|
),
|
1689
|
+
transfer_all: bool = typer.Option(
|
1690
|
+
False, "--all", prompt=False, help="Transfer all available balance."
|
1691
|
+
),
|
1702
1692
|
wallet_name: str = Options.wallet_name,
|
1703
1693
|
wallet_path: str = Options.wallet_path,
|
1704
1694
|
wallet_hotkey: str = Options.wallet_hotkey,
|
@@ -1734,20 +1724,25 @@ class CLIManager:
|
|
1734
1724
|
wallet_name,
|
1735
1725
|
wallet_path,
|
1736
1726
|
wallet_hotkey,
|
1737
|
-
ask_for=[WO.NAME
|
1727
|
+
ask_for=[WO.NAME],
|
1738
1728
|
validate=WV.WALLET,
|
1739
1729
|
)
|
1740
|
-
|
1741
|
-
# For Rao games - temporarily commented out
|
1742
|
-
# effective_network = get_effective_network(self.config, network)
|
1743
|
-
# if is_rao_network(effective_network):
|
1744
|
-
# print_error("This command is disabled on the 'rao' network.")
|
1745
|
-
# raise typer.Exit()
|
1746
|
-
|
1747
1730
|
subtensor = self.initialize_chain(network)
|
1731
|
+
if transfer_all and amount:
|
1732
|
+
print_error("Cannot specify an amount and '--all' flag.")
|
1733
|
+
raise typer.Exit()
|
1734
|
+
elif transfer_all:
|
1735
|
+
amount = 0
|
1736
|
+
elif not amount:
|
1737
|
+
amount = FloatPrompt.ask("Enter amount (in TAO) to transfer.")
|
1748
1738
|
return self._run_command(
|
1749
1739
|
wallets.transfer(
|
1750
|
-
wallet,
|
1740
|
+
wallet,
|
1741
|
+
subtensor,
|
1742
|
+
destination_ss58_address,
|
1743
|
+
amount,
|
1744
|
+
transfer_all,
|
1745
|
+
prompt,
|
1751
1746
|
)
|
1752
1747
|
)
|
1753
1748
|
|
@@ -1933,6 +1928,7 @@ class CLIManager:
|
|
1933
1928
|
"--max-successes",
|
1934
1929
|
help="Set the maximum number of times to successfully run the faucet for this command.",
|
1935
1930
|
),
|
1931
|
+
prompt: bool = Options.prompt,
|
1936
1932
|
):
|
1937
1933
|
"""
|
1938
1934
|
Obtain test TAO tokens by performing Proof of Work (PoW).
|
@@ -1971,6 +1967,7 @@ class CLIManager:
|
|
1971
1967
|
output_in_place,
|
1972
1968
|
verbose,
|
1973
1969
|
max_successes,
|
1970
|
+
prompt,
|
1974
1971
|
)
|
1975
1972
|
)
|
1976
1973
|
|
@@ -1984,6 +1981,7 @@ class CLIManager:
|
|
1984
1981
|
json: Optional[str] = Options.json,
|
1985
1982
|
json_password: Optional[str] = Options.json_password,
|
1986
1983
|
use_password: Optional[bool] = Options.use_password,
|
1984
|
+
overwrite: bool = Options.overwrite,
|
1987
1985
|
quiet: bool = Options.quiet,
|
1988
1986
|
verbose: bool = Options.verbose,
|
1989
1987
|
):
|
@@ -2030,6 +2028,7 @@ class CLIManager:
|
|
2030
2028
|
json,
|
2031
2029
|
json_password,
|
2032
2030
|
use_password,
|
2031
|
+
overwrite,
|
2033
2032
|
)
|
2034
2033
|
)
|
2035
2034
|
|
@@ -2040,6 +2039,7 @@ class CLIManager:
|
|
2040
2039
|
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
2041
2040
|
public_key_hex: Optional[str] = Options.public_hex_key,
|
2042
2041
|
ss58_address: Optional[str] = Options.ss58_address,
|
2042
|
+
overwrite: bool = Options.overwrite,
|
2043
2043
|
quiet: bool = Options.quiet,
|
2044
2044
|
verbose: bool = Options.verbose,
|
2045
2045
|
):
|
@@ -2087,7 +2087,7 @@ class CLIManager:
|
|
2087
2087
|
rich.print("[red]Error: Invalid SS58 address or public key![/red]")
|
2088
2088
|
raise typer.Exit()
|
2089
2089
|
return self._run_command(
|
2090
|
-
wallets.regen_coldkey_pub(wallet, ss58_address, public_key_hex)
|
2090
|
+
wallets.regen_coldkey_pub(wallet, ss58_address, public_key_hex, overwrite)
|
2091
2091
|
)
|
2092
2092
|
|
2093
2093
|
def wallet_regen_hotkey(
|
@@ -2102,9 +2102,8 @@ class CLIManager:
|
|
2102
2102
|
use_password: bool = typer.Option(
|
2103
2103
|
False, # Overriden to False
|
2104
2104
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
2105
|
-
is_flag=True,
|
2106
|
-
flag_value=True,
|
2107
2105
|
),
|
2106
|
+
overwrite: bool = Options.overwrite,
|
2108
2107
|
quiet: bool = Options.quiet,
|
2109
2108
|
verbose: bool = Options.verbose,
|
2110
2109
|
):
|
@@ -2120,6 +2119,7 @@ class CLIManager:
|
|
2120
2119
|
# Example usage:
|
2121
2120
|
|
2122
2121
|
[green]$[/green] btcli wallet regen_hotkey --seed 0x1234...
|
2122
|
+
[green]$[/green] btcli wallet regen-hotkey --mnemonic "word1 word2 ... word12"
|
2123
2123
|
|
2124
2124
|
[bold]Note[/bold]: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery.
|
2125
2125
|
It should be used with caution to avoid accidental overwriting of existing keys.
|
@@ -2143,6 +2143,7 @@ class CLIManager:
|
|
2143
2143
|
json,
|
2144
2144
|
json_password,
|
2145
2145
|
use_password,
|
2146
|
+
overwrite,
|
2146
2147
|
)
|
2147
2148
|
)
|
2148
2149
|
|
@@ -2160,10 +2161,9 @@ class CLIManager:
|
|
2160
2161
|
use_password: bool = typer.Option(
|
2161
2162
|
False, # Overriden to False
|
2162
2163
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
2163
|
-
is_flag=True,
|
2164
|
-
flag_value=True,
|
2165
2164
|
),
|
2166
2165
|
uri: Optional[str] = Options.uri,
|
2166
|
+
overwrite: bool = Options.overwrite,
|
2167
2167
|
quiet: bool = Options.quiet,
|
2168
2168
|
verbose: bool = Options.verbose,
|
2169
2169
|
):
|
@@ -2204,7 +2204,9 @@ class CLIManager:
|
|
2204
2204
|
)
|
2205
2205
|
if not uri:
|
2206
2206
|
n_words = get_n_words(n_words)
|
2207
|
-
return self._run_command(
|
2207
|
+
return self._run_command(
|
2208
|
+
wallets.new_hotkey(wallet, n_words, use_password, uri, overwrite)
|
2209
|
+
)
|
2208
2210
|
|
2209
2211
|
def wallet_new_coldkey(
|
2210
2212
|
self,
|
@@ -2219,6 +2221,7 @@ class CLIManager:
|
|
2219
2221
|
),
|
2220
2222
|
use_password: Optional[bool] = Options.use_password,
|
2221
2223
|
uri: Optional[str] = Options.uri,
|
2224
|
+
overwrite: bool = Options.overwrite,
|
2222
2225
|
quiet: bool = Options.quiet,
|
2223
2226
|
verbose: bool = Options.verbose,
|
2224
2227
|
):
|
@@ -2258,7 +2261,7 @@ class CLIManager:
|
|
2258
2261
|
if not uri:
|
2259
2262
|
n_words = get_n_words(n_words)
|
2260
2263
|
return self._run_command(
|
2261
|
-
wallets.new_coldkey(wallet, n_words, use_password, uri)
|
2264
|
+
wallets.new_coldkey(wallet, n_words, use_password, uri, overwrite)
|
2262
2265
|
)
|
2263
2266
|
|
2264
2267
|
def wallet_check_ck_swap(
|
@@ -2294,6 +2297,7 @@ class CLIManager:
|
|
2294
2297
|
n_words: Optional[int] = None,
|
2295
2298
|
use_password: bool = Options.use_password,
|
2296
2299
|
uri: Optional[str] = Options.uri,
|
2300
|
+
overwrite: bool = Options.overwrite,
|
2297
2301
|
quiet: bool = Options.quiet,
|
2298
2302
|
verbose: bool = Options.verbose,
|
2299
2303
|
):
|
@@ -2337,12 +2341,7 @@ class CLIManager:
|
|
2337
2341
|
if not uri:
|
2338
2342
|
n_words = get_n_words(n_words)
|
2339
2343
|
return self._run_command(
|
2340
|
-
wallets.wallet_create(
|
2341
|
-
wallet,
|
2342
|
-
n_words,
|
2343
|
-
use_password,
|
2344
|
-
uri,
|
2345
|
-
)
|
2344
|
+
wallets.wallet_create(wallet, n_words, use_password, uri, overwrite)
|
2346
2345
|
)
|
2347
2346
|
|
2348
2347
|
def wallet_balance(
|
@@ -2873,7 +2872,7 @@ class CLIManager:
|
|
2873
2872
|
netuid = get_optional_netuid(netuid, all_netuids)
|
2874
2873
|
|
2875
2874
|
if stake_all and amount:
|
2876
|
-
|
2875
|
+
print_error(
|
2877
2876
|
"Cannot specify an amount and 'stake-all'. Choose one or the other."
|
2878
2877
|
)
|
2879
2878
|
raise typer.Exit()
|
@@ -2883,14 +2882,14 @@ class CLIManager:
|
|
2883
2882
|
raise typer.Exit()
|
2884
2883
|
|
2885
2884
|
if all_hotkeys and include_hotkeys:
|
2886
|
-
|
2885
|
+
print_error(
|
2887
2886
|
"You have specified hotkeys to include and also the `--all-hotkeys` flag. The flag"
|
2888
2887
|
"should only be used standalone (to use all hotkeys) or with `--exclude-hotkeys`."
|
2889
2888
|
)
|
2890
2889
|
raise typer.Exit()
|
2891
2890
|
|
2892
2891
|
if include_hotkeys and exclude_hotkeys:
|
2893
|
-
|
2892
|
+
print_error(
|
2894
2893
|
"You have specified options for both including and excluding hotkeys. Select one or the other."
|
2895
2894
|
)
|
2896
2895
|
raise typer.Exit()
|
@@ -2960,24 +2959,24 @@ class CLIManager:
|
|
2960
2959
|
)
|
2961
2960
|
|
2962
2961
|
if include_hotkeys:
|
2963
|
-
|
2962
|
+
include_hotkeys = parse_to_list(
|
2964
2963
|
include_hotkeys,
|
2965
2964
|
str,
|
2966
2965
|
"Hotkeys must be a comma-separated list of ss58s, e.g., `--include-hotkeys 5Grw....,5Grw....`.",
|
2967
2966
|
is_ss58=True,
|
2968
2967
|
)
|
2969
2968
|
else:
|
2970
|
-
|
2969
|
+
include_hotkeys = []
|
2971
2970
|
|
2972
2971
|
if exclude_hotkeys:
|
2973
|
-
|
2972
|
+
exclude_hotkeys = parse_to_list(
|
2974
2973
|
exclude_hotkeys,
|
2975
2974
|
str,
|
2976
2975
|
"Hotkeys must be a comma-separated list of ss58s, e.g., `--exclude-hotkeys 5Grw....,5Grw....`.",
|
2977
2976
|
is_ss58=True,
|
2978
2977
|
)
|
2979
2978
|
else:
|
2980
|
-
|
2979
|
+
exclude_hotkeys = []
|
2981
2980
|
|
2982
2981
|
# TODO: Ask amount for each subnet explicitly if more than one
|
2983
2982
|
if not stake_all and not amount:
|
@@ -3017,8 +3016,8 @@ class CLIManager:
|
|
3017
3016
|
amount,
|
3018
3017
|
prompt,
|
3019
3018
|
all_hotkeys,
|
3020
|
-
|
3021
|
-
|
3019
|
+
include_hotkeys,
|
3020
|
+
exclude_hotkeys,
|
3022
3021
|
safe_staking,
|
3023
3022
|
rate_tolerance,
|
3024
3023
|
allow_partial_stake,
|
@@ -3126,32 +3125,32 @@ class CLIManager:
|
|
3126
3125
|
if interactive and any(
|
3127
3126
|
[hotkey_ss58_address, include_hotkeys, exclude_hotkeys, all_hotkeys]
|
3128
3127
|
):
|
3129
|
-
|
3128
|
+
print_error(
|
3130
3129
|
"Interactive mode cannot be used with hotkey selection options like --include-hotkeys, --exclude-hotkeys, --all-hotkeys, or --hotkey."
|
3131
3130
|
)
|
3132
3131
|
raise typer.Exit()
|
3133
3132
|
|
3134
3133
|
if unstake_all and unstake_all_alpha:
|
3135
|
-
|
3134
|
+
print_error("Cannot specify both unstake-all and unstake-all-alpha.")
|
3136
3135
|
raise typer.Exit()
|
3137
3136
|
|
3138
3137
|
if not interactive and not unstake_all and not unstake_all_alpha:
|
3139
3138
|
netuid = get_optional_netuid(netuid, all_netuids)
|
3140
3139
|
if all_hotkeys and include_hotkeys:
|
3141
|
-
|
3140
|
+
print_error(
|
3142
3141
|
"You have specified hotkeys to include and also the `--all-hotkeys` flag. The flag"
|
3143
3142
|
" should only be used standalone (to use all hotkeys) or with `--exclude-hotkeys`."
|
3144
3143
|
)
|
3145
3144
|
raise typer.Exit()
|
3146
3145
|
|
3147
3146
|
if include_hotkeys and exclude_hotkeys:
|
3148
|
-
|
3147
|
+
print_error(
|
3149
3148
|
"You have specified both including and excluding hotkeys options. Select one or the other."
|
3150
3149
|
)
|
3151
3150
|
raise typer.Exit()
|
3152
3151
|
|
3153
3152
|
if unstake_all and amount:
|
3154
|
-
|
3153
|
+
print_error(
|
3155
3154
|
"Cannot specify both a specific amount and 'unstake-all'. Choose one or the other."
|
3156
3155
|
)
|
3157
3156
|
raise typer.Exit()
|
@@ -3212,11 +3211,23 @@ class CLIManager:
|
|
3212
3211
|
else:
|
3213
3212
|
print_error("Invalid hotkey ss58 address.")
|
3214
3213
|
raise typer.Exit()
|
3215
|
-
|
3216
|
-
|
3217
|
-
|
3218
|
-
|
3214
|
+
elif all_hotkeys:
|
3215
|
+
wallet = self.wallet_ask(
|
3216
|
+
wallet_name,
|
3217
|
+
wallet_path,
|
3218
|
+
wallet_hotkey,
|
3219
|
+
ask_for=[WO.NAME, WO.PATH],
|
3219
3220
|
)
|
3221
|
+
else:
|
3222
|
+
if not hotkey_ss58_address and not wallet_hotkey:
|
3223
|
+
hotkey_or_ss58 = Prompt.ask(
|
3224
|
+
"Enter the [blue]hotkey[/blue] name or [blue]ss58 address[/blue] to unstake all from [dim](or enter 'all' to unstake from all hotkeys)[/dim]",
|
3225
|
+
default=self.config.get("wallet_hotkey")
|
3226
|
+
or defaults.wallet.hotkey,
|
3227
|
+
)
|
3228
|
+
else:
|
3229
|
+
hotkey_or_ss58 = hotkey_ss58_address or wallet_hotkey
|
3230
|
+
|
3220
3231
|
if is_valid_ss58_address(hotkey_or_ss58):
|
3221
3232
|
hotkey_ss58_address = hotkey_or_ss58
|
3222
3233
|
wallet = self.wallet_ask(
|
@@ -3225,6 +3236,14 @@ class CLIManager:
|
|
3225
3236
|
wallet_hotkey,
|
3226
3237
|
ask_for=[WO.NAME, WO.PATH],
|
3227
3238
|
)
|
3239
|
+
elif hotkey_or_ss58 == "all":
|
3240
|
+
all_hotkeys = True
|
3241
|
+
wallet = self.wallet_ask(
|
3242
|
+
wallet_name,
|
3243
|
+
wallet_path,
|
3244
|
+
wallet_hotkey,
|
3245
|
+
ask_for=[WO.NAME, WO.PATH],
|
3246
|
+
)
|
3228
3247
|
else:
|
3229
3248
|
wallet_hotkey = hotkey_or_ss58
|
3230
3249
|
wallet = self.wallet_ask(
|
@@ -3240,6 +3259,9 @@ class CLIManager:
|
|
3240
3259
|
subtensor=self.initialize_chain(network),
|
3241
3260
|
hotkey_ss58_address=hotkey_ss58_address,
|
3242
3261
|
unstake_all_alpha=unstake_all_alpha,
|
3262
|
+
all_hotkeys=all_hotkeys,
|
3263
|
+
include_hotkeys=include_hotkeys,
|
3264
|
+
exclude_hotkeys=exclude_hotkeys,
|
3243
3265
|
prompt=prompt,
|
3244
3266
|
)
|
3245
3267
|
)
|
@@ -3265,24 +3287,20 @@ class CLIManager:
|
|
3265
3287
|
)
|
3266
3288
|
|
3267
3289
|
if include_hotkeys:
|
3268
|
-
|
3290
|
+
include_hotkeys = parse_to_list(
|
3269
3291
|
include_hotkeys,
|
3270
3292
|
str,
|
3271
3293
|
"Hotkeys must be a comma-separated list of ss58s or names, e.g., `--include-hotkeys hk1,hk2`.",
|
3272
3294
|
is_ss58=False,
|
3273
3295
|
)
|
3274
|
-
else:
|
3275
|
-
included_hotkeys = []
|
3276
3296
|
|
3277
3297
|
if exclude_hotkeys:
|
3278
|
-
|
3298
|
+
exclude_hotkeys = parse_to_list(
|
3279
3299
|
exclude_hotkeys,
|
3280
3300
|
str,
|
3281
3301
|
"Hotkeys must be a comma-separated list of ss58s or names, e.g., `--exclude-hotkeys hk3,hk4`.",
|
3282
3302
|
is_ss58=False,
|
3283
3303
|
)
|
3284
|
-
else:
|
3285
|
-
excluded_hotkeys = []
|
3286
3304
|
|
3287
3305
|
return self._run_command(
|
3288
3306
|
remove_stake.unstake(
|
@@ -3290,8 +3308,8 @@ class CLIManager:
|
|
3290
3308
|
subtensor=self.initialize_chain(network),
|
3291
3309
|
hotkey_ss58_address=hotkey_ss58_address,
|
3292
3310
|
all_hotkeys=all_hotkeys,
|
3293
|
-
include_hotkeys=
|
3294
|
-
exclude_hotkeys=
|
3311
|
+
include_hotkeys=include_hotkeys,
|
3312
|
+
exclude_hotkeys=exclude_hotkeys,
|
3295
3313
|
amount=amount,
|
3296
3314
|
prompt=prompt,
|
3297
3315
|
interactive=interactive,
|
@@ -3745,7 +3763,6 @@ class CLIManager:
|
|
3745
3763
|
[],
|
3746
3764
|
"--proportions",
|
3747
3765
|
"--prop",
|
3748
|
-
"-p",
|
3749
3766
|
help="Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1)",
|
3750
3767
|
prompt=False,
|
3751
3768
|
),
|
@@ -3753,9 +3770,10 @@ class CLIManager:
|
|
3753
3770
|
wait_for_finalization: bool = Options.wait_for_finalization,
|
3754
3771
|
quiet: bool = Options.quiet,
|
3755
3772
|
verbose: bool = Options.verbose,
|
3773
|
+
prompt: bool = Options.prompt,
|
3756
3774
|
):
|
3757
3775
|
"""
|
3758
|
-
Set child hotkeys on specified
|
3776
|
+
Set child hotkeys on a specified subnet (or all). Overrides currently set children.
|
3759
3777
|
|
3760
3778
|
Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1.
|
3761
3779
|
|
@@ -3792,7 +3810,7 @@ class CLIManager:
|
|
3792
3810
|
wallet_name,
|
3793
3811
|
wallet_path,
|
3794
3812
|
wallet_hotkey,
|
3795
|
-
ask_for=[WO.NAME, WO.
|
3813
|
+
ask_for=[WO.NAME, WO.HOTKEY],
|
3796
3814
|
validate=WV.WALLET_AND_HOTKEY,
|
3797
3815
|
)
|
3798
3816
|
return self._run_command(
|
@@ -3804,6 +3822,7 @@ class CLIManager:
|
|
3804
3822
|
proportions=proportions,
|
3805
3823
|
wait_for_finalization=wait_for_finalization,
|
3806
3824
|
wait_for_inclusion=wait_for_inclusion,
|
3825
|
+
prompt=prompt,
|
3807
3826
|
)
|
3808
3827
|
)
|
3809
3828
|
|
@@ -3829,9 +3848,10 @@ class CLIManager:
|
|
3829
3848
|
wait_for_finalization: bool = Options.wait_for_finalization,
|
3830
3849
|
quiet: bool = Options.quiet,
|
3831
3850
|
verbose: bool = Options.verbose,
|
3851
|
+
prompt: bool = Options.prompt,
|
3832
3852
|
):
|
3833
3853
|
"""
|
3834
|
-
Remove all children hotkeys on a specified subnet.
|
3854
|
+
Remove all children hotkeys on a specified subnet (or all).
|
3835
3855
|
|
3836
3856
|
This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet.
|
3837
3857
|
|
@@ -3844,7 +3864,7 @@ class CLIManager:
|
|
3844
3864
|
wallet_name,
|
3845
3865
|
wallet_path,
|
3846
3866
|
wallet_hotkey,
|
3847
|
-
ask_for=[WO.NAME, WO.
|
3867
|
+
ask_for=[WO.NAME, WO.HOTKEY],
|
3848
3868
|
validate=WV.WALLET_AND_HOTKEY,
|
3849
3869
|
)
|
3850
3870
|
if all_netuids and netuid:
|
@@ -3863,6 +3883,7 @@ class CLIManager:
|
|
3863
3883
|
netuid,
|
3864
3884
|
wait_for_inclusion,
|
3865
3885
|
wait_for_finalization,
|
3886
|
+
prompt=prompt,
|
3866
3887
|
)
|
3867
3888
|
)
|
3868
3889
|
|
@@ -3918,7 +3939,7 @@ class CLIManager:
|
|
3918
3939
|
wallet_name,
|
3919
3940
|
wallet_path,
|
3920
3941
|
wallet_hotkey,
|
3921
|
-
ask_for=[WO.NAME, WO.
|
3942
|
+
ask_for=[WO.NAME, WO.HOTKEY],
|
3922
3943
|
validate=WV.WALLET_AND_HOTKEY,
|
3923
3944
|
)
|
3924
3945
|
if all_netuids and netuid:
|
@@ -3953,7 +3974,7 @@ class CLIManager:
|
|
3953
3974
|
param_name: str = typer.Option(
|
3954
3975
|
"", "--param", "--parameter", help="The subnet hyperparameter to set"
|
3955
3976
|
),
|
3956
|
-
param_value: str = typer.Option(
|
3977
|
+
param_value: Optional[str] = typer.Option(
|
3957
3978
|
"", "--value", help="Value to set the hyperparameter to."
|
3958
3979
|
),
|
3959
3980
|
quiet: bool = Options.quiet,
|
@@ -3970,13 +3991,13 @@ class CLIManager:
|
|
3970
3991
|
"""
|
3971
3992
|
self.verbosity_handler(quiet, verbose)
|
3972
3993
|
|
3973
|
-
|
3974
|
-
|
3975
|
-
|
3976
|
-
|
3977
|
-
|
3978
|
-
|
3979
|
-
|
3994
|
+
if not param_name or not param_value:
|
3995
|
+
hyperparams = self._run_command(
|
3996
|
+
sudo.get_hyperparameters(self.initialize_chain(network), netuid),
|
3997
|
+
exit_early=False,
|
3998
|
+
)
|
3999
|
+
if not hyperparams:
|
4000
|
+
raise typer.Exit()
|
3980
4001
|
|
3981
4002
|
if not param_name:
|
3982
4003
|
hyperparam_list = [field.name for field in fields(SubnetHyperparameters)]
|
@@ -3991,10 +4012,23 @@ class CLIManager:
|
|
3991
4012
|
)
|
3992
4013
|
param_name = hyperparam_list[choice - 1]
|
3993
4014
|
|
3994
|
-
if
|
3995
|
-
|
3996
|
-
|
4015
|
+
if param_name in ["alpha_high", "alpha_low"]:
|
4016
|
+
param_name = "alpha_values"
|
4017
|
+
low_val = FloatPrompt.ask(
|
4018
|
+
"Enter the new value for [dark_orange]alpha_low[/dark_orange]"
|
4019
|
+
)
|
4020
|
+
high_val = FloatPrompt.ask(
|
4021
|
+
"Enter the new value for [dark_orange]alpha_high[/dark_orange]"
|
3997
4022
|
)
|
4023
|
+
param_value = f"{low_val},{high_val}"
|
4024
|
+
|
4025
|
+
if not param_value:
|
4026
|
+
if HYPERPARAMS.get(param_name):
|
4027
|
+
param_value = Prompt.ask(
|
4028
|
+
f"Enter the new value for [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{param_name}[/{COLOR_PALETTE['GENERAL']['SUBHEADING']}] in the VALUE column format"
|
4029
|
+
)
|
4030
|
+
else:
|
4031
|
+
param_value = None
|
3998
4032
|
|
3999
4033
|
wallet = self.wallet_ask(
|
4000
4034
|
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
@@ -4060,7 +4094,9 @@ class CLIManager:
|
|
4060
4094
|
[green]$[/green] btcli sudo proposals
|
4061
4095
|
"""
|
4062
4096
|
self.verbosity_handler(quiet, verbose)
|
4063
|
-
return self._run_command(
|
4097
|
+
return self._run_command(
|
4098
|
+
sudo.proposals(self.initialize_chain(network), verbose)
|
4099
|
+
)
|
4064
4100
|
|
4065
4101
|
def sudo_senate_vote(
|
4066
4102
|
self,
|
@@ -4438,6 +4474,7 @@ class CLIManager:
|
|
4438
4474
|
validate=WV.WALLET_AND_HOTKEY,
|
4439
4475
|
)
|
4440
4476
|
identity = prompt_for_subnet_identity(
|
4477
|
+
current_identity={},
|
4441
4478
|
subnet_name=subnet_name,
|
4442
4479
|
github_repo=github_repo,
|
4443
4480
|
subnet_contact=subnet_contact,
|
@@ -4468,6 +4505,118 @@ class CLIManager:
|
|
4468
4505
|
verbose=verbose,
|
4469
4506
|
)
|
4470
4507
|
|
4508
|
+
def subnets_get_identity(
|
4509
|
+
self,
|
4510
|
+
network: Optional[list[str]] = Options.network,
|
4511
|
+
netuid: int = Options.netuid,
|
4512
|
+
quiet: bool = Options.quiet,
|
4513
|
+
verbose: bool = Options.verbose,
|
4514
|
+
):
|
4515
|
+
"""
|
4516
|
+
Get the identity information for a subnet.
|
4517
|
+
|
4518
|
+
This command displays the identity information of a subnet including name, GitHub repo, contact details, etc.
|
4519
|
+
|
4520
|
+
[green]$[/green] btcli subnets get-identity --netuid 1
|
4521
|
+
"""
|
4522
|
+
self.verbosity_handler(quiet, verbose)
|
4523
|
+
return self._run_command(
|
4524
|
+
subnets.get_identity(
|
4525
|
+
self.initialize_chain(network),
|
4526
|
+
netuid,
|
4527
|
+
)
|
4528
|
+
)
|
4529
|
+
|
4530
|
+
def subnets_set_identity(
|
4531
|
+
self,
|
4532
|
+
wallet_name: str = Options.wallet_name,
|
4533
|
+
wallet_path: str = Options.wallet_path,
|
4534
|
+
wallet_hotkey: str = Options.wallet_hotkey,
|
4535
|
+
network: Optional[list[str]] = Options.network,
|
4536
|
+
netuid: int = Options.netuid,
|
4537
|
+
subnet_name: Optional[str] = typer.Option(
|
4538
|
+
None, "--subnet-name", "--name", help="Name of the subnet"
|
4539
|
+
),
|
4540
|
+
github_repo: Optional[str] = typer.Option(
|
4541
|
+
None, "--github-repo", "--repo", help="GitHub repository URL"
|
4542
|
+
),
|
4543
|
+
subnet_contact: Optional[str] = typer.Option(
|
4544
|
+
None,
|
4545
|
+
"--subnet-contact",
|
4546
|
+
"--contact",
|
4547
|
+
"--email",
|
4548
|
+
help="Contact email for subnet",
|
4549
|
+
),
|
4550
|
+
subnet_url: Optional[str] = typer.Option(
|
4551
|
+
None, "--subnet-url", "--url", help="Subnet URL"
|
4552
|
+
),
|
4553
|
+
discord: Optional[str] = typer.Option(
|
4554
|
+
None, "--discord-handle", "--discord", help="Discord handle"
|
4555
|
+
),
|
4556
|
+
description: Optional[str] = typer.Option(
|
4557
|
+
None, "--description", help="Description"
|
4558
|
+
),
|
4559
|
+
additional_info: Optional[str] = typer.Option(
|
4560
|
+
None, "--additional-info", help="Additional information"
|
4561
|
+
),
|
4562
|
+
prompt: bool = Options.prompt,
|
4563
|
+
quiet: bool = Options.quiet,
|
4564
|
+
verbose: bool = Options.verbose,
|
4565
|
+
):
|
4566
|
+
"""
|
4567
|
+
Set or update the identity information for a subnet.
|
4568
|
+
|
4569
|
+
This command allows subnet owners to set or update identity information like name, GitHub repo, contact details, etc.
|
4570
|
+
|
4571
|
+
[bold]Common Examples:[/bold]
|
4572
|
+
|
4573
|
+
1. Interactive subnet identity setting:
|
4574
|
+
[green]$[/green] btcli subnets set-identity --netuid 1
|
4575
|
+
|
4576
|
+
2. Set subnet identity with specific values:
|
4577
|
+
[green]$[/green] btcli subnets set-identity --netuid 1 --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net
|
4578
|
+
"""
|
4579
|
+
self.verbosity_handler(quiet, verbose)
|
4580
|
+
wallet = self.wallet_ask(
|
4581
|
+
wallet_name,
|
4582
|
+
wallet_path,
|
4583
|
+
wallet_hotkey,
|
4584
|
+
ask_for=[WO.NAME],
|
4585
|
+
validate=WV.WALLET,
|
4586
|
+
)
|
4587
|
+
|
4588
|
+
current_identity = self._run_command(
|
4589
|
+
subnets.get_identity(
|
4590
|
+
self.initialize_chain(network),
|
4591
|
+
netuid,
|
4592
|
+
f"Current Subnet {netuid}'s Identity",
|
4593
|
+
),
|
4594
|
+
exit_early=False,
|
4595
|
+
)
|
4596
|
+
if current_identity is None:
|
4597
|
+
raise typer.Exit()
|
4598
|
+
|
4599
|
+
identity = prompt_for_subnet_identity(
|
4600
|
+
current_identity=current_identity,
|
4601
|
+
subnet_name=subnet_name,
|
4602
|
+
github_repo=github_repo,
|
4603
|
+
subnet_contact=subnet_contact,
|
4604
|
+
subnet_url=subnet_url,
|
4605
|
+
discord=discord,
|
4606
|
+
description=description,
|
4607
|
+
additional=additional_info,
|
4608
|
+
)
|
4609
|
+
|
4610
|
+
return self._run_command(
|
4611
|
+
subnets.set_identity(
|
4612
|
+
wallet,
|
4613
|
+
self.initialize_chain(network),
|
4614
|
+
netuid,
|
4615
|
+
identity,
|
4616
|
+
prompt,
|
4617
|
+
)
|
4618
|
+
)
|
4619
|
+
|
4471
4620
|
def subnets_pow_register(
|
4472
4621
|
self,
|
4473
4622
|
wallet_name: Optional[str] = Options.wallet_name,
|
@@ -4515,6 +4664,7 @@ class CLIManager:
|
|
4515
4664
|
"-tbp",
|
4516
4665
|
help="Set the number of threads per block for CUDA.",
|
4517
4666
|
),
|
4667
|
+
prompt: bool = Options.prompt,
|
4518
4668
|
):
|
4519
4669
|
"""
|
4520
4670
|
Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW).
|
@@ -4552,6 +4702,7 @@ class CLIManager:
|
|
4552
4702
|
use_cuda,
|
4553
4703
|
dev_id,
|
4554
4704
|
threads_per_block,
|
4705
|
+
prompt=prompt,
|
4555
4706
|
)
|
4556
4707
|
)
|
4557
4708
|
|
@@ -4582,7 +4733,7 @@ class CLIManager:
|
|
4582
4733
|
wallet_name,
|
4583
4734
|
wallet_path,
|
4584
4735
|
wallet_hotkey,
|
4585
|
-
ask_for=[WO.NAME, WO.
|
4736
|
+
ask_for=[WO.NAME, WO.HOTKEY],
|
4586
4737
|
validate=WV.WALLET_AND_HOTKEY,
|
4587
4738
|
)
|
4588
4739
|
return self._run_command(
|
@@ -4717,6 +4868,7 @@ class CLIManager:
|
|
4717
4868
|
),
|
4718
4869
|
quiet: bool = Options.quiet,
|
4719
4870
|
verbose: bool = Options.verbose,
|
4871
|
+
prompt: bool = Options.prompt,
|
4720
4872
|
):
|
4721
4873
|
"""
|
4722
4874
|
Reveal weights for a specific subnet.
|
@@ -4788,6 +4940,7 @@ class CLIManager:
|
|
4788
4940
|
weights,
|
4789
4941
|
salt,
|
4790
4942
|
__version_as_int__,
|
4943
|
+
prompt=prompt,
|
4791
4944
|
)
|
4792
4945
|
)
|
4793
4946
|
|
@@ -4813,6 +4966,7 @@ class CLIManager:
|
|
4813
4966
|
),
|
4814
4967
|
quiet: bool = Options.quiet,
|
4815
4968
|
verbose: bool = Options.verbose,
|
4969
|
+
prompt: bool = Options.prompt,
|
4816
4970
|
):
|
4817
4971
|
"""
|
4818
4972
|
|
@@ -4883,6 +5037,7 @@ class CLIManager:
|
|
4883
5037
|
weights,
|
4884
5038
|
salt,
|
4885
5039
|
__version_as_int__,
|
5040
|
+
prompt=prompt,
|
4886
5041
|
)
|
4887
5042
|
)
|
4888
5043
|
|