bittensor-cli 9.19.0rc2__tar.gz → 9.20.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.19.0rc2 → bittensor_cli-9.20.1}/PKG-INFO +4 -3
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/cli.py +144 -57
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/__init__.py +7 -43
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/chain_data.py +18 -6
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/registration.py +5 -3
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/transfer.py +2 -2
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/subtensor_interface.py +124 -105
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/utils.py +21 -2
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/proxy.py +46 -19
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/add.py +165 -53
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/auto_staking.py +6 -30
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/list.py +24 -26
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/move.py +71 -56
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/remove.py +249 -71
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/wizard.py +6 -15
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/subnets.py +3 -28
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/sudo.py +20 -22
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/view.py +17 -26
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/wallets.py +373 -119
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/pyproject.toml +4 -3
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/README.md +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/doc_generation_helper.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/balances.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/mev_shield.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/root.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/serving.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/minigraph.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/networking.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/main-filters.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/main-header.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/neuron-details.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/price-multi.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/price-single.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-details-header.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-details.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-metrics.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnets-table.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.css +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.j2 +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.js +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/axon/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/axon/axon.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/contribute.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/contributors.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/create.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/dissolve.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/refund.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/update.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/utils.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/view.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/liquidity.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/utils.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/children_hotkeys.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/claim.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/__init__.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/mechanisms.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/price.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/weights.py +0 -0
- {bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bittensor-cli
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.20.1
|
|
4
4
|
Summary: Bittensor CLI
|
|
5
5
|
Author: bittensor.com
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
19
19
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
20
|
Classifier: Topic :: Utilities
|
|
21
21
|
Requires-Dist: wheel
|
|
22
|
-
Requires-Dist: async-substrate-interface>=1.6.2
|
|
22
|
+
Requires-Dist: async-substrate-interface>=1.6.2,<2.0.0
|
|
23
23
|
Requires-Dist: aiohttp~=3.13
|
|
24
24
|
Requires-Dist: backoff~=2.2.1
|
|
25
25
|
Requires-Dist: bittensor-drand>=1.3.0
|
|
@@ -32,7 +32,8 @@ Requires-Dist: PyYAML~=6.0
|
|
|
32
32
|
Requires-Dist: rich>=13.7,<15.0
|
|
33
33
|
Requires-Dist: scalecodec==1.2.12
|
|
34
34
|
Requires-Dist: typer>=0.16
|
|
35
|
-
Requires-Dist:
|
|
35
|
+
Requires-Dist: typing_extensions>4.0.0; python_version<'3.11'
|
|
36
|
+
Requires-Dist: bittensor-wallet==4.0.1
|
|
36
37
|
Requires-Dist: packaging
|
|
37
38
|
Requires-Dist: plotille>=5.0.0
|
|
38
39
|
Requires-Dist: plotly>=6.0.0
|
|
@@ -641,8 +641,8 @@ def get_creation_data(
|
|
|
641
641
|
return mnemonic, seed, json_path, json_password
|
|
642
642
|
|
|
643
643
|
|
|
644
|
-
def config_selector(conf: dict, title: str):
|
|
645
|
-
def curses_selector(stdscr):
|
|
644
|
+
def config_selector(conf: dict[str, bool], title: str) -> dict[str, bool]:
|
|
645
|
+
def curses_selector(stdscr) -> dict[str, bool]:
|
|
646
646
|
"""
|
|
647
647
|
Enhanced Curses TUI to make selections.
|
|
648
648
|
"""
|
|
@@ -698,7 +698,7 @@ def config_selector(conf: dict, title: str):
|
|
|
698
698
|
return curses.wrapper(curses_selector)
|
|
699
699
|
|
|
700
700
|
|
|
701
|
-
def version_callback(value: bool):
|
|
701
|
+
def version_callback(value: bool) -> None:
|
|
702
702
|
"""
|
|
703
703
|
Prints the current version/branch-name
|
|
704
704
|
"""
|
|
@@ -716,7 +716,7 @@ def version_callback(value: bool):
|
|
|
716
716
|
raise typer.Exit()
|
|
717
717
|
|
|
718
718
|
|
|
719
|
-
def commands_callback(value: bool):
|
|
719
|
+
def commands_callback(value: bool) -> None:
|
|
720
720
|
"""
|
|
721
721
|
Prints a tree of commands for the app
|
|
722
722
|
"""
|
|
@@ -726,7 +726,7 @@ def commands_callback(value: bool):
|
|
|
726
726
|
raise typer.Exit()
|
|
727
727
|
|
|
728
728
|
|
|
729
|
-
def debug_callback(value: bool):
|
|
729
|
+
def debug_callback(value: bool) -> None:
|
|
730
730
|
if value:
|
|
731
731
|
debug_file_loc = Path(
|
|
732
732
|
os.getenv("BTCLI_DEBUG_FILE")
|
|
@@ -1389,7 +1389,7 @@ class CLIManager:
|
|
|
1389
1389
|
Generates a rich.Tree of the commands, subcommands, and groups of this app
|
|
1390
1390
|
"""
|
|
1391
1391
|
|
|
1392
|
-
def build_rich_tree(data: dict, parent: Tree):
|
|
1392
|
+
def build_rich_tree(data: dict, parent: Tree) -> None:
|
|
1393
1393
|
for group, content in data.get("groups", {}).items():
|
|
1394
1394
|
group_node = parent.add(
|
|
1395
1395
|
f"[bold cyan]{group}[/]"
|
|
@@ -1943,7 +1943,7 @@ class CLIManager:
|
|
|
1943
1943
|
with open(self.config_path, "w") as f:
|
|
1944
1944
|
safe_dump(self.config, f)
|
|
1945
1945
|
|
|
1946
|
-
def get_config(self):
|
|
1946
|
+
def get_config(self) -> None:
|
|
1947
1947
|
"""
|
|
1948
1948
|
Prints the current config file in a table.
|
|
1949
1949
|
"""
|
|
@@ -2079,7 +2079,7 @@ class CLIManager:
|
|
|
2079
2079
|
print_error(f"Proxy {name} not found in address book.")
|
|
2080
2080
|
self.config_get_proxies()
|
|
2081
2081
|
|
|
2082
|
-
def config_get_proxies(self):
|
|
2082
|
+
def config_get_proxies(self) -> None:
|
|
2083
2083
|
"""
|
|
2084
2084
|
Displays the current proxies address book
|
|
2085
2085
|
|
|
@@ -2228,7 +2228,7 @@ class CLIManager:
|
|
|
2228
2228
|
console.print("Proxy updated")
|
|
2229
2229
|
self.config_get_proxies()
|
|
2230
2230
|
|
|
2231
|
-
def config_clear_proxy_book(self):
|
|
2231
|
+
def config_clear_proxy_book(self) -> None:
|
|
2232
2232
|
"""
|
|
2233
2233
|
Clears the proxy address book. Use with caution.
|
|
2234
2234
|
Really only useful if you have corrupted your proxy address book.
|
|
@@ -2913,7 +2913,17 @@ class CLIManager:
|
|
|
2913
2913
|
),
|
|
2914
2914
|
wallet_name: str = Options.wallet_name,
|
|
2915
2915
|
wallet_path: str = Options.wallet_path,
|
|
2916
|
-
wallet_hotkey: str = Options.
|
|
2916
|
+
wallet_hotkey: str = Options.edit_help(
|
|
2917
|
+
"wallet_hotkey",
|
|
2918
|
+
help_text="Deprecated option, "
|
|
2919
|
+
"preserved for backwards compatibility to not break workflows which utilise it.",
|
|
2920
|
+
),
|
|
2921
|
+
ss58_address: Optional[str] = typer.Option(
|
|
2922
|
+
None,
|
|
2923
|
+
"--ss58-address",
|
|
2924
|
+
"--ss58",
|
|
2925
|
+
help="SS58 address of the coldkey to inspect. Allows inspecting any coldkey without a local wallet file.",
|
|
2926
|
+
),
|
|
2917
2927
|
network: Optional[list[str]] = Options.network,
|
|
2918
2928
|
netuids: str = Options.netuids,
|
|
2919
2929
|
quiet: bool = Options.quiet,
|
|
@@ -2921,9 +2931,11 @@ class CLIManager:
|
|
|
2921
2931
|
json_output: bool = Options.json_output,
|
|
2922
2932
|
):
|
|
2923
2933
|
"""
|
|
2924
|
-
Displays the details of the user's wallet
|
|
2934
|
+
Displays the details of the user's wallet (coldkey) on the Bittensor network.
|
|
2925
2935
|
|
|
2926
|
-
The output is presented as
|
|
2936
|
+
The output is presented as two separate tables:
|
|
2937
|
+
|
|
2938
|
+
[bold]Coldkey Overview[/bold]:
|
|
2927
2939
|
|
|
2928
2940
|
- [blue bold]Coldkey[/blue bold]: The coldkey associated with the user's wallet.
|
|
2929
2941
|
|
|
@@ -2931,14 +2943,22 @@ class CLIManager:
|
|
|
2931
2943
|
|
|
2932
2944
|
- [blue bold]Delegate[/blue bold]: The name of the delegate to which the coldkey has staked TAO.
|
|
2933
2945
|
|
|
2934
|
-
- [blue bold]Stake[/blue bold]: The amount of stake
|
|
2946
|
+
- [blue bold]Stake[/blue bold]: The amount of stake delegated.
|
|
2935
2947
|
|
|
2936
|
-
- [blue bold]Emission[/blue bold]: The emission
|
|
2948
|
+
- [blue bold]Emission[/blue bold]: The daily emission earned from delegation.
|
|
2949
|
+
|
|
2950
|
+
[bold]Hotkey Details[/bold]:
|
|
2937
2951
|
|
|
2938
|
-
- [blue bold]
|
|
2952
|
+
- [blue bold]Coldkey[/blue bold]: The parent coldkey of the hotkey.
|
|
2953
|
+
|
|
2954
|
+
- [blue bold]Netuid[/blue bold]: The network unique identifier of the subnet where the hotkey is active.
|
|
2939
2955
|
|
|
2940
2956
|
- [blue bold]Hotkey[/blue bold]: The hotkey associated with the neuron on the network.
|
|
2941
2957
|
|
|
2958
|
+
- [blue bold]Stake[/blue bold]: The amount of stake held by the hotkey.
|
|
2959
|
+
|
|
2960
|
+
- [blue bold]Emission[/blue bold]: The emission or rewards earned from staking.
|
|
2961
|
+
|
|
2942
2962
|
USAGE
|
|
2943
2963
|
|
|
2944
2964
|
This command can be used to inspect a single wallet or all the wallets located at a specified path. It is useful for a comprehensive overview of a user's participation and performance in the Bittensor network.
|
|
@@ -2949,10 +2969,10 @@ class CLIManager:
|
|
|
2949
2969
|
|
|
2950
2970
|
[green]$[/green] btcli wallet inspect --all -n 1 -n 2 -n 3
|
|
2951
2971
|
|
|
2972
|
+
[green]$[/green] btcli wallet inspect --ss58-address 5FHneW46...
|
|
2973
|
+
|
|
2952
2974
|
[bold]Note[/bold]: The `inspect` command is for displaying information only and does not perform any transactions or state changes on the blockchain. It is intended to be used with Bittensor CLI and not as a standalone function in user code.
|
|
2953
2975
|
"""
|
|
2954
|
-
print_error("This command is disabled on the 'rao' network.")
|
|
2955
|
-
raise typer.Exit()
|
|
2956
2976
|
self.verbosity_handler(quiet, verbose, json_output, False)
|
|
2957
2977
|
|
|
2958
2978
|
if netuids:
|
|
@@ -2962,18 +2982,28 @@ class CLIManager:
|
|
|
2962
2982
|
"Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
|
|
2963
2983
|
)
|
|
2964
2984
|
|
|
2985
|
+
if ss58_address:
|
|
2986
|
+
return self._run_command(
|
|
2987
|
+
wallets.inspect(
|
|
2988
|
+
None,
|
|
2989
|
+
self.initialize_chain(network),
|
|
2990
|
+
netuids_filter=netuids,
|
|
2991
|
+
all_wallets=False,
|
|
2992
|
+
ss58_address=ss58_address,
|
|
2993
|
+
)
|
|
2994
|
+
)
|
|
2995
|
+
|
|
2965
2996
|
# if all-wallets is entered, ask for path
|
|
2966
2997
|
ask_for = [WO.NAME, WO.PATH] if not all_wallets else [WO.PATH]
|
|
2967
2998
|
validate = WV.WALLET if not all_wallets else WV.NONE
|
|
2968
2999
|
wallet = self.wallet_ask(
|
|
2969
|
-
wallet_name, wallet_path,
|
|
3000
|
+
wallet_name, wallet_path, None, ask_for=ask_for, validate=validate
|
|
2970
3001
|
)
|
|
2971
3002
|
|
|
2972
|
-
self.initialize_chain(network)
|
|
2973
3003
|
return self._run_command(
|
|
2974
3004
|
wallets.inspect(
|
|
2975
3005
|
wallet,
|
|
2976
|
-
self.
|
|
3006
|
+
self.initialize_chain(network),
|
|
2977
3007
|
netuids_filter=netuids,
|
|
2978
3008
|
all_wallets=all_wallets,
|
|
2979
3009
|
)
|
|
@@ -4144,7 +4174,11 @@ class CLIManager:
|
|
|
4144
4174
|
self,
|
|
4145
4175
|
action: str = typer.Argument(
|
|
4146
4176
|
None,
|
|
4147
|
-
help=
|
|
4177
|
+
help=(
|
|
4178
|
+
"Action to perform: 'announce' to announce intent, "
|
|
4179
|
+
"'execute' to complete swap after delay, 'dispute' to freeze the swap, "
|
|
4180
|
+
"'clear' to withdraw announcement, 'check' to view status."
|
|
4181
|
+
),
|
|
4148
4182
|
),
|
|
4149
4183
|
wallet_name: Optional[str] = Options.wallet_name,
|
|
4150
4184
|
wallet_path: Optional[str] = Options.wallet_path,
|
|
@@ -4176,6 +4210,9 @@ class CLIManager:
|
|
|
4176
4210
|
If you suspect compromise, you can [bold]Dispute[/bold] an active announcement to freeze
|
|
4177
4211
|
all activity for the coldkey until the triumvirate can intervene.
|
|
4178
4212
|
|
|
4213
|
+
If you want to withdraw your announcement, you can [bold]Clear[/bold] (withdraw) an announcement once the
|
|
4214
|
+
reannouncement delay has elapsed.
|
|
4215
|
+
|
|
4179
4216
|
EXAMPLES
|
|
4180
4217
|
|
|
4181
4218
|
Step 1 - Announce your intent to swap:
|
|
@@ -4190,9 +4227,13 @@ class CLIManager:
|
|
|
4190
4227
|
|
|
4191
4228
|
[green]$[/green] btcli wallet swap-coldkey dispute
|
|
4192
4229
|
|
|
4193
|
-
|
|
4230
|
+
Clear (withdraw) an announcement:
|
|
4231
|
+
|
|
4232
|
+
[green]$[/green] btcli wallet swap-coldkey clear
|
|
4194
4233
|
|
|
4195
|
-
|
|
4234
|
+
Check status of your swap:
|
|
4235
|
+
|
|
4236
|
+
[green]$[/green] btcli wallet swap-coldkey check
|
|
4196
4237
|
"""
|
|
4197
4238
|
self.verbosity_handler(quiet, verbose, prompt=False, json_output=False)
|
|
4198
4239
|
|
|
@@ -4201,18 +4242,19 @@ class CLIManager:
|
|
|
4201
4242
|
"\n[bold][blue]Coldkey Swap Actions:[/blue][/bold]\n"
|
|
4202
4243
|
" [dark_sea_green3]announce[/dark_sea_green3] - Start the swap process (pays fee, starts delay timer)\n"
|
|
4203
4244
|
" [dark_sea_green3]execute[/dark_sea_green3] - Complete the swap (after delay period)\n"
|
|
4204
|
-
" [dark_sea_green3]dispute[/dark_sea_green3] - Freeze the swap process if you suspect compromise\n
|
|
4205
|
-
" [
|
|
4245
|
+
" [dark_sea_green3]dispute[/dark_sea_green3] - Freeze the swap process if you suspect compromise\n"
|
|
4246
|
+
" [dark_sea_green3]clear[/dark_sea_green3] - Withdraw your swap announcement\n"
|
|
4247
|
+
" [dark_sea_green3]check[/dark_sea_green3] - Check the status of your swap\n\n"
|
|
4206
4248
|
)
|
|
4207
4249
|
action = Prompt.ask(
|
|
4208
4250
|
"Select action",
|
|
4209
|
-
choices=["announce", "execute", "dispute"],
|
|
4251
|
+
choices=["announce", "execute", "dispute", "clear", "check"],
|
|
4210
4252
|
default="announce",
|
|
4211
4253
|
)
|
|
4212
4254
|
|
|
4213
|
-
if action.lower() not in ("announce", "execute", "dispute"):
|
|
4255
|
+
if action.lower() not in ("announce", "execute", "dispute", "clear", "check"):
|
|
4214
4256
|
print_error(
|
|
4215
|
-
f"Invalid action: {action}. Must be 'announce', 'execute', or '
|
|
4257
|
+
f"Invalid action: {action}. Must be 'announce', 'execute', 'dispute', 'clear', or 'check'."
|
|
4216
4258
|
)
|
|
4217
4259
|
raise typer.Exit(1)
|
|
4218
4260
|
|
|
@@ -4233,7 +4275,7 @@ class CLIManager:
|
|
|
4233
4275
|
)
|
|
4234
4276
|
|
|
4235
4277
|
new_wallet_coldkey_ss58 = None
|
|
4236
|
-
if action
|
|
4278
|
+
if action not in ("dispute", "clear", "check"):
|
|
4237
4279
|
if not new_wallet_or_ss58:
|
|
4238
4280
|
new_wallet_or_ss58 = Prompt.ask(
|
|
4239
4281
|
"Enter the [blue]new wallet name[/blue] or [blue]SS58 address[/blue] of the new coldkey",
|
|
@@ -4285,6 +4327,24 @@ class CLIManager:
|
|
|
4285
4327
|
mev_protection=mev_protection,
|
|
4286
4328
|
)
|
|
4287
4329
|
)
|
|
4330
|
+
elif action == "clear":
|
|
4331
|
+
return self._run_command(
|
|
4332
|
+
wallets.clear_coldkey_swap_announcement(
|
|
4333
|
+
wallet=wallet,
|
|
4334
|
+
subtensor=self.initialize_chain(network),
|
|
4335
|
+
decline=decline,
|
|
4336
|
+
quiet=quiet,
|
|
4337
|
+
prompt=prompt,
|
|
4338
|
+
mev_protection=mev_protection,
|
|
4339
|
+
)
|
|
4340
|
+
)
|
|
4341
|
+
elif action == "check":
|
|
4342
|
+
return self._run_command(
|
|
4343
|
+
wallets.check_swap_status(
|
|
4344
|
+
subtensor=self.initialize_chain(network),
|
|
4345
|
+
origin_ss58=wallet.coldkeypub.ss58_address,
|
|
4346
|
+
)
|
|
4347
|
+
)
|
|
4288
4348
|
else:
|
|
4289
4349
|
return self._run_command(
|
|
4290
4350
|
wallets.execute_coldkey_swap(
|
|
@@ -5452,33 +5512,20 @@ class CLIManager:
|
|
|
5452
5512
|
console.print(
|
|
5453
5513
|
"[dim]This command moves stake from one hotkey to another hotkey while keeping the same coldkey.[/dim]"
|
|
5454
5514
|
)
|
|
5515
|
+
interactive_selection = False
|
|
5455
5516
|
if not destination_hotkey:
|
|
5456
5517
|
dest_wallet_or_ss58 = Prompt.ask(
|
|
5457
|
-
"Enter the [blue]
|
|
5458
|
-
"[blue]ss58 address[/blue]"
|
|
5518
|
+
"Enter the [blue]ss58 address[/blue] of the hotkey to move the stake to, leave blank for other options"
|
|
5459
5519
|
)
|
|
5460
5520
|
if is_valid_ss58_address(dest_wallet_or_ss58):
|
|
5461
5521
|
destination_hotkey = dest_wallet_or_ss58
|
|
5522
|
+
elif dest_wallet_or_ss58.strip() == "":
|
|
5523
|
+
interactive_selection = True
|
|
5462
5524
|
else:
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
wallet_path,
|
|
5466
|
-
None,
|
|
5467
|
-
ask_for=[WO.NAME, WO.PATH],
|
|
5468
|
-
validate=WV.WALLET,
|
|
5469
|
-
)
|
|
5470
|
-
destination_hotkey = Prompt.ask(
|
|
5471
|
-
"Enter the [blue]destination hotkey[/blue] name",
|
|
5472
|
-
default=dest_wallet.hotkey_str,
|
|
5473
|
-
)
|
|
5474
|
-
destination_wallet = self.wallet_ask(
|
|
5475
|
-
dest_wallet_or_ss58,
|
|
5476
|
-
wallet_path,
|
|
5477
|
-
destination_hotkey,
|
|
5478
|
-
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
|
5479
|
-
validate=WV.WALLET_AND_HOTKEY,
|
|
5525
|
+
print_error(
|
|
5526
|
+
"Invalid destination hotkey ss58 address. Please enter a valid ss58 address."
|
|
5480
5527
|
)
|
|
5481
|
-
|
|
5528
|
+
raise typer.Exit()
|
|
5482
5529
|
else:
|
|
5483
5530
|
if is_valid_ss58_address(destination_hotkey):
|
|
5484
5531
|
destination_hotkey = destination_hotkey
|
|
@@ -5497,7 +5544,6 @@ class CLIManager:
|
|
|
5497
5544
|
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
|
5498
5545
|
)
|
|
5499
5546
|
|
|
5500
|
-
interactive_selection = False
|
|
5501
5547
|
if not wallet_hotkey:
|
|
5502
5548
|
origin_hotkey = Prompt.ask(
|
|
5503
5549
|
"Enter the [blue]origin hotkey[/blue] name or "
|
|
@@ -9807,13 +9853,18 @@ class CLIManager:
|
|
|
9807
9853
|
def proxy_remove(
|
|
9808
9854
|
self,
|
|
9809
9855
|
delegate: Annotated[
|
|
9810
|
-
str,
|
|
9856
|
+
Optional[str],
|
|
9811
9857
|
typer.Option(
|
|
9812
9858
|
callback=is_valid_ss58_address_param,
|
|
9813
|
-
prompt=
|
|
9814
|
-
help="The SS58 address of the delegate to remove",
|
|
9859
|
+
prompt=False,
|
|
9860
|
+
help="The SS58 address of the delegate to remove (required if --all is not used)",
|
|
9815
9861
|
),
|
|
9816
|
-
] =
|
|
9862
|
+
] = None,
|
|
9863
|
+
all_: bool = typer.Option(
|
|
9864
|
+
False,
|
|
9865
|
+
"--all",
|
|
9866
|
+
help="Remove all proxies associated with this account",
|
|
9867
|
+
),
|
|
9817
9868
|
network: Optional[list[str]] = Options.network,
|
|
9818
9869
|
proxy_type: ProxyType = Options.proxy_type,
|
|
9819
9870
|
delay: int = typer.Option(0, help="Delay, in number of blocks"),
|
|
@@ -9840,10 +9891,10 @@ class CLIManager:
|
|
|
9840
9891
|
[green]$[/green] btcli proxy remove --delegate 5GDel... --proxy-type Transfer
|
|
9841
9892
|
|
|
9842
9893
|
"""
|
|
9843
|
-
# TODO should add a --all flag to call Proxy.remove_proxies ?
|
|
9844
9894
|
logger.debug(
|
|
9845
9895
|
"args:\n"
|
|
9846
9896
|
f"delegate: {delegate}\n"
|
|
9897
|
+
f"all: {all_}\n"
|
|
9847
9898
|
f"network: {network}\n"
|
|
9848
9899
|
f"proxy_type: {proxy_type}\n"
|
|
9849
9900
|
f"delay: {delay}\n"
|
|
@@ -9851,6 +9902,41 @@ class CLIManager:
|
|
|
9851
9902
|
f"wait_for_inclusion: {wait_for_inclusion}\n"
|
|
9852
9903
|
f"era: {period}\n"
|
|
9853
9904
|
)
|
|
9905
|
+
# Validate that --delegate and --all are not used together
|
|
9906
|
+
if all_ and delegate:
|
|
9907
|
+
if not json_output:
|
|
9908
|
+
print_error("--delegate cannot be used together with --all flag.")
|
|
9909
|
+
else:
|
|
9910
|
+
json_console.print_json(
|
|
9911
|
+
data={
|
|
9912
|
+
"success": False,
|
|
9913
|
+
"message": "--delegate cannot be used together with --all flag.",
|
|
9914
|
+
"extrinsic_identifier": None,
|
|
9915
|
+
}
|
|
9916
|
+
)
|
|
9917
|
+
return
|
|
9918
|
+
|
|
9919
|
+
# If --all is not used and delegate is not provided, prompt or error
|
|
9920
|
+
if not all_ and not delegate:
|
|
9921
|
+
if not prompt:
|
|
9922
|
+
if not json_output:
|
|
9923
|
+
print_error(
|
|
9924
|
+
"Either --delegate must be provided or --all flag must be used."
|
|
9925
|
+
)
|
|
9926
|
+
else:
|
|
9927
|
+
json_console.print_json(
|
|
9928
|
+
data={
|
|
9929
|
+
"success": False,
|
|
9930
|
+
"message": "Either --delegate must be provided or --all flag must be used.",
|
|
9931
|
+
"extrinsic_identifier": None,
|
|
9932
|
+
}
|
|
9933
|
+
)
|
|
9934
|
+
return
|
|
9935
|
+
delegate = Prompt.ask(
|
|
9936
|
+
"Enter the SS58 address of the delegate to remove, e.g. 5dxds..."
|
|
9937
|
+
)
|
|
9938
|
+
delegate = is_valid_ss58_address_param(delegate)
|
|
9939
|
+
|
|
9854
9940
|
self.verbosity_handler(quiet, verbose, json_output, prompt)
|
|
9855
9941
|
wallet = self.wallet_ask(
|
|
9856
9942
|
wallet_name=wallet_name,
|
|
@@ -9873,6 +9959,7 @@ class CLIManager:
|
|
|
9873
9959
|
wait_for_finalization=wait_for_finalization,
|
|
9874
9960
|
period=period,
|
|
9875
9961
|
json_output=json_output,
|
|
9962
|
+
remove_all=all_,
|
|
9876
9963
|
)
|
|
9877
9964
|
)
|
|
9878
9965
|
|
|
@@ -10275,11 +10362,11 @@ class CLIManager:
|
|
|
10275
10362
|
)
|
|
10276
10363
|
return True
|
|
10277
10364
|
|
|
10278
|
-
def run(self):
|
|
10365
|
+
def run(self) -> None:
|
|
10279
10366
|
self.app()
|
|
10280
10367
|
|
|
10281
10368
|
|
|
10282
|
-
def main():
|
|
10369
|
+
def main() -> None:
|
|
10283
10370
|
manager = CLIManager()
|
|
10284
10371
|
manager.run()
|
|
10285
10372
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from dataclasses import dataclass
|
|
3
|
-
from typing import Any, Optional
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class Constants:
|
|
@@ -37,47 +35,6 @@ class Constants:
|
|
|
37
35
|
delegates_detail_url = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json"
|
|
38
36
|
|
|
39
37
|
|
|
40
|
-
@dataclass
|
|
41
|
-
class DelegatesDetails:
|
|
42
|
-
display: str
|
|
43
|
-
additional: list[tuple[str, str]]
|
|
44
|
-
web: str
|
|
45
|
-
legal: Optional[str] = None
|
|
46
|
-
riot: Optional[str] = None
|
|
47
|
-
email: Optional[str] = None
|
|
48
|
-
pgp_fingerprint: Optional[str] = None
|
|
49
|
-
image: Optional[str] = None
|
|
50
|
-
twitter: Optional[str] = None
|
|
51
|
-
|
|
52
|
-
@classmethod
|
|
53
|
-
def from_chain_data(cls, data: dict[str, Any]) -> "DelegatesDetails":
|
|
54
|
-
def decode(key: str, default=""):
|
|
55
|
-
try:
|
|
56
|
-
if isinstance(data.get(key), dict):
|
|
57
|
-
value = next(data.get(key).values())
|
|
58
|
-
return bytes(value[0]).decode("utf-8")
|
|
59
|
-
elif isinstance(data.get(key), int):
|
|
60
|
-
return data.get(key)
|
|
61
|
-
elif isinstance(data.get(key), tuple):
|
|
62
|
-
return bytes(data.get(key)[0]).decode("utf-8")
|
|
63
|
-
else:
|
|
64
|
-
return default
|
|
65
|
-
except (UnicodeDecodeError, TypeError):
|
|
66
|
-
return default
|
|
67
|
-
|
|
68
|
-
return cls(
|
|
69
|
-
display=decode("display"),
|
|
70
|
-
additional=decode("additional", []),
|
|
71
|
-
web=decode("web"),
|
|
72
|
-
legal=decode("legal"),
|
|
73
|
-
riot=decode("riot"),
|
|
74
|
-
email=decode("email"),
|
|
75
|
-
pgp_fingerprint=decode("pgp_fingerprint", None),
|
|
76
|
-
image=decode("image"),
|
|
77
|
-
twitter=decode("twitter"),
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
|
|
81
38
|
class Defaults:
|
|
82
39
|
netuid = 1
|
|
83
40
|
rate_tolerance = 0.005
|
|
@@ -692,6 +649,7 @@ HYPERPARAMS = {
|
|
|
692
649
|
"alpha_low": ("", RootSudoOnly.FALSE), # Derived from alpha_values
|
|
693
650
|
"subnet_is_active": ("", RootSudoOnly.FALSE), # Set via btcli subnets start
|
|
694
651
|
"yuma_version": ("", RootSudoOnly.FALSE), # Related to yuma3_enabled
|
|
652
|
+
"max_allowed_uids": ("sudo_set_max_allowed_uids", RootSudoOnly.FALSE),
|
|
695
653
|
}
|
|
696
654
|
|
|
697
655
|
HYPERPARAMS_MODULE = {
|
|
@@ -941,6 +899,12 @@ HYPERPARAMS_METADATA = {
|
|
|
941
899
|
"owner_settable": True,
|
|
942
900
|
"docs_link": "docs.learnbittensor.org/subnets/subnet-hyperparameters#yuma3",
|
|
943
901
|
},
|
|
902
|
+
"max_allowed_uids": {
|
|
903
|
+
"description": "Maximum number of UIDs (neurons) on the subnet, essentially 'untrimming'.",
|
|
904
|
+
"side_effects": "See description for min_allowed_uids",
|
|
905
|
+
"owner_settable": True,
|
|
906
|
+
"docs_link": "docs.learnbittensor.org/subnets/subnet-hyperparameters#maxalloweduids",
|
|
907
|
+
},
|
|
944
908
|
}
|
|
945
909
|
|
|
946
910
|
# Help Panels for cli help
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
+
from collections.abc import Sequence
|
|
3
4
|
from enum import Enum
|
|
4
|
-
from typing import Optional, Any, Union
|
|
5
|
+
from typing import Optional, Any, Union, Callable, Hashable
|
|
5
6
|
|
|
6
7
|
import netaddr
|
|
7
8
|
from scalecodec.utils.ss58 import ss58_encode
|
|
@@ -16,6 +17,11 @@ from bittensor_cli.src.bittensor.utils import (
|
|
|
16
17
|
get_netuid_and_subuid_by_storage_index,
|
|
17
18
|
)
|
|
18
19
|
|
|
20
|
+
try:
|
|
21
|
+
from typing import Self
|
|
22
|
+
except ImportError:
|
|
23
|
+
from typing_extensions import Self
|
|
24
|
+
|
|
19
25
|
|
|
20
26
|
class ChainDataType(Enum):
|
|
21
27
|
NeuronInfo = 1
|
|
@@ -69,9 +75,12 @@ def _chr_str(codes: tuple[int]) -> str:
|
|
|
69
75
|
return "".join(map(chr, codes))
|
|
70
76
|
|
|
71
77
|
|
|
72
|
-
def process_nested(
|
|
78
|
+
def process_nested(
|
|
79
|
+
data: Sequence[dict[Hashable, tuple[int]]] | dict | Any,
|
|
80
|
+
chr_transform: Callable[[tuple[int]], str],
|
|
81
|
+
) -> list[dict[Hashable, str]] | dict[Hashable, str] | Any:
|
|
73
82
|
"""Processes nested data structures by applying a transformation function to their elements."""
|
|
74
|
-
if isinstance(data,
|
|
83
|
+
if isinstance(data, Sequence):
|
|
75
84
|
if len(data) > 0 and isinstance(data[0], dict):
|
|
76
85
|
return [
|
|
77
86
|
{k: chr_transform(v) for k, v in item.items()}
|
|
@@ -79,9 +88,12 @@ def process_nested(data: Union[tuple, dict], chr_transform):
|
|
|
79
88
|
else None
|
|
80
89
|
for item in data
|
|
81
90
|
]
|
|
91
|
+
# TODO @abe why do we kind of silently fail here?
|
|
82
92
|
return {}
|
|
83
93
|
elif isinstance(data, dict):
|
|
84
94
|
return {k: chr_transform(v) for k, v in data.items()}
|
|
95
|
+
else:
|
|
96
|
+
return data
|
|
85
97
|
|
|
86
98
|
|
|
87
99
|
@dataclass
|
|
@@ -127,17 +139,17 @@ class InfoBase:
|
|
|
127
139
|
"""Base dataclass for info objects."""
|
|
128
140
|
|
|
129
141
|
@abstractmethod
|
|
130
|
-
def _fix_decoded(self, decoded: Any) ->
|
|
142
|
+
def _fix_decoded(self, decoded: Any) -> Self:
|
|
131
143
|
raise NotImplementedError(
|
|
132
144
|
"This is an abstract method and must be implemented in a subclass."
|
|
133
145
|
)
|
|
134
146
|
|
|
135
147
|
@classmethod
|
|
136
|
-
def from_any(cls, data: Any) ->
|
|
148
|
+
def from_any(cls, data: Any) -> Self:
|
|
137
149
|
return cls._fix_decoded(data)
|
|
138
150
|
|
|
139
151
|
@classmethod
|
|
140
|
-
def list_from_any(cls, data_list: list[Any]) -> list[
|
|
152
|
+
def list_from_any(cls, data_list: list[Any]) -> list[Self]:
|
|
141
153
|
return [cls.from_any(data) for data in data_list]
|
|
142
154
|
|
|
143
155
|
def __getitem__(self, item):
|
|
@@ -708,11 +708,13 @@ async def burned_register_extrinsic(
|
|
|
708
708
|
f":satellite: Checking Account on [bold]subnet:{netuid}[/bold]...",
|
|
709
709
|
spinner="aesthetic",
|
|
710
710
|
) as status:
|
|
711
|
+
block_hash = await subtensor.substrate.get_chain_head()
|
|
711
712
|
my_uid = await subtensor.query(
|
|
712
|
-
"SubtensorModule",
|
|
713
|
+
module="SubtensorModule",
|
|
714
|
+
storage_function="Uids",
|
|
715
|
+
params=[netuid, get_hotkey_pub_ss58(wallet)],
|
|
716
|
+
block_hash=block_hash,
|
|
713
717
|
)
|
|
714
|
-
block_hash = await subtensor.substrate.get_chain_head()
|
|
715
|
-
|
|
716
718
|
print_verbose("Checking if already registered", status)
|
|
717
719
|
neuron = await subtensor.neuron_for_uid(
|
|
718
720
|
uid=my_uid, netuid=netuid, block_hash=block_hash
|
{bittensor_cli-9.19.0rc2 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/transfer.py
RENAMED
|
@@ -156,10 +156,10 @@ async def transfer_extrinsic(
|
|
|
156
156
|
f" would bring you under the existential deposit: [bright_cyan]{existential_deposit}[/bright_cyan].\n"
|
|
157
157
|
)
|
|
158
158
|
return False, None
|
|
159
|
-
if
|
|
159
|
+
if proxy_balance < amount and allow_death:
|
|
160
160
|
print_error(
|
|
161
161
|
"[bold red]Not enough balance[/bold red]:\n\n"
|
|
162
|
-
f" balance: [bright_red]{
|
|
162
|
+
f" balance: [bright_red]{proxy_balance}[/bright_red]\n"
|
|
163
163
|
f" amount: [bright_red]{amount}[/bright_red]\n"
|
|
164
164
|
)
|
|
165
165
|
return False, None
|