bittensor-cli 8.2.0rc7__tar.gz → 8.2.0rc14__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-8.2.0rc7 → bittensor-cli-8.2.0rc14}/PKG-INFO +1 -1
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/__init__.py +1 -1
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/cli.py +436 -38
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/__init__.py +1 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/balances.py +29 -1
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/chain_data.py +25 -8
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/subtensor_interface.py +64 -77
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/utils.py +25 -5
- bittensor-cli-8.2.0rc14/bittensor_cli/src/commands/stake/move.py +992 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/stake/stake.py +45 -1156
- bittensor-cli-8.2.0rc14/bittensor_cli/src/commands/subnets/__init__.py +0 -0
- bittensor-cli-8.2.0rc14/bittensor_cli/src/commands/subnets/price.py +867 -0
- {bittensor-cli-8.2.0rc7/bittensor_cli/src/commands → bittensor-cli-8.2.0rc14/bittensor_cli/src/commands/subnets}/subnets.py +55 -50
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/sudo.py +18 -9
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/wallets.py +71 -232
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/PKG-INFO +1 -1
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/SOURCES.txt +5 -2
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/requires.txt +3 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/README.md +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/doc_generation_helper.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/__init__.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/async_substrate_interface.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/extrinsics/registration.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/extrinsics/root.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/extrinsics/transfer.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/minigraph.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/networking.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/__init__.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/stake/__init__.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/stake/children_hotkeys.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli/src/commands/weights.py +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/dependency_links.txt +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/entry_points.txt +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/bittensor_cli.egg-info/top_level.txt +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/setup.cfg +0 -0
- {bittensor-cli-8.2.0rc7 → bittensor-cli-8.2.0rc14}/setup.py +0 -0
@@ -29,9 +29,10 @@ from bittensor_cli.src.bittensor.balances import Balance
|
|
29
29
|
from bittensor_cli.src.bittensor.async_substrate_interface import (
|
30
30
|
SubstrateRequestException,
|
31
31
|
)
|
32
|
-
from bittensor_cli.src.commands import
|
32
|
+
from bittensor_cli.src.commands import sudo, wallets
|
33
33
|
from bittensor_cli.src.commands import weights as weights_cmds
|
34
|
-
from bittensor_cli.src.commands.
|
34
|
+
from bittensor_cli.src.commands.subnets import price, subnets
|
35
|
+
from bittensor_cli.src.commands.stake import children_hotkeys, stake, move
|
35
36
|
from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface
|
36
37
|
from bittensor_cli.src.bittensor.chain_data import SubnetHyperparameters
|
37
38
|
from bittensor_cli.src.bittensor.utils import (
|
@@ -41,13 +42,14 @@ from bittensor_cli.src.bittensor.utils import (
|
|
41
42
|
is_valid_ss58_address,
|
42
43
|
print_error,
|
43
44
|
validate_chain_endpoint,
|
44
|
-
retry_prompt,
|
45
45
|
validate_netuid,
|
46
46
|
is_rao_network,
|
47
47
|
get_effective_network,
|
48
48
|
prompt_for_identity,
|
49
49
|
validate_uri,
|
50
50
|
prompt_for_subnet_identity,
|
51
|
+
print_linux_dependency_message,
|
52
|
+
is_linux,
|
51
53
|
)
|
52
54
|
from typing_extensions import Annotated
|
53
55
|
from textwrap import dedent
|
@@ -62,7 +64,7 @@ except ImportError:
|
|
62
64
|
pass
|
63
65
|
|
64
66
|
|
65
|
-
__version__ = "8.2.
|
67
|
+
__version__ = "8.2.0rc14"
|
66
68
|
|
67
69
|
|
68
70
|
_core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
|
@@ -645,12 +647,13 @@ class CLIManager:
|
|
645
647
|
"balance", rich_help_panel=HELP_PANELS["WALLET"]["INFORMATION"]
|
646
648
|
)(self.wallet_balance)
|
647
649
|
self.wallet_app.command(
|
648
|
-
"history",
|
650
|
+
"history",
|
651
|
+
rich_help_panel=HELP_PANELS["WALLET"]["INFORMATION"],
|
652
|
+
hidden=True,
|
649
653
|
)(self.wallet_history)
|
650
654
|
self.wallet_app.command(
|
651
655
|
"overview",
|
652
656
|
rich_help_panel=HELP_PANELS["WALLET"]["INFORMATION"],
|
653
|
-
hidden=True,
|
654
657
|
)(self.wallet_overview)
|
655
658
|
self.wallet_app.command(
|
656
659
|
"transfer", rich_help_panel=HELP_PANELS["WALLET"]["OPERATIONS"]
|
@@ -684,8 +687,14 @@ class CLIManager:
|
|
684
687
|
"list", rich_help_panel=HELP_PANELS["STAKE"]["STAKE_MGMT"]
|
685
688
|
)(self.stake_list)
|
686
689
|
self.stake_app.command(
|
687
|
-
"move", rich_help_panel=HELP_PANELS["STAKE"]["
|
690
|
+
"move", rich_help_panel=HELP_PANELS["STAKE"]["MOVEMENT"]
|
688
691
|
)(self.stake_move)
|
692
|
+
self.stake_app.command(
|
693
|
+
"transfer", rich_help_panel=HELP_PANELS["STAKE"]["MOVEMENT"]
|
694
|
+
)(self.stake_transfer)
|
695
|
+
self.stake_app.command(
|
696
|
+
"swap", rich_help_panel=HELP_PANELS["STAKE"]["MOVEMENT"]
|
697
|
+
)(self.stake_swap)
|
689
698
|
|
690
699
|
# stake-children commands
|
691
700
|
children_app = typer.Typer()
|
@@ -748,10 +757,13 @@ class CLIManager:
|
|
748
757
|
)(self.subnets_register)
|
749
758
|
self.subnets_app.command(
|
750
759
|
"metagraph", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"], hidden=True
|
751
|
-
)(self.subnets_show)
|
760
|
+
)(self.subnets_show) # Aliased to `s show` for now
|
752
761
|
self.subnets_app.command(
|
753
762
|
"show", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"]
|
754
763
|
)(self.subnets_show)
|
764
|
+
self.subnets_app.command(
|
765
|
+
"price", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"]
|
766
|
+
)(self.subnets_price)
|
755
767
|
|
756
768
|
# weights commands
|
757
769
|
self.weights_app.command(
|
@@ -1409,12 +1421,6 @@ class CLIManager:
|
|
1409
1421
|
"Hotkeys names must be a comma-separated list, e.g., `--exclude-hotkeys hk1,hk2`.",
|
1410
1422
|
)
|
1411
1423
|
|
1412
|
-
# For Rao games
|
1413
|
-
effective_network = get_effective_network(self.config, network)
|
1414
|
-
if is_rao_network(effective_network):
|
1415
|
-
print_error("This command is disabled on the 'rao' network.")
|
1416
|
-
raise typer.Exit()
|
1417
|
-
|
1418
1424
|
return self._run_command(
|
1419
1425
|
wallets.overview(
|
1420
1426
|
wallet,
|
@@ -1425,6 +1431,7 @@ class CLIManager:
|
|
1425
1431
|
include_hotkeys,
|
1426
1432
|
exclude_hotkeys,
|
1427
1433
|
netuids_filter=netuids,
|
1434
|
+
verbose=verbose,
|
1428
1435
|
)
|
1429
1436
|
)
|
1430
1437
|
|
@@ -1600,6 +1607,8 @@ class CLIManager:
|
|
1600
1607
|
|
1601
1608
|
[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.
|
1602
1609
|
"""
|
1610
|
+
print_error("This command is disabled on the 'rao' network.")
|
1611
|
+
raise typer.Exit()
|
1603
1612
|
self.verbosity_handler(quiet, verbose)
|
1604
1613
|
|
1605
1614
|
if netuids:
|
@@ -1615,11 +1624,6 @@ class CLIManager:
|
|
1615
1624
|
wallet = self.wallet_ask(
|
1616
1625
|
wallet_name, wallet_path, wallet_hotkey, ask_for=ask_for, validate=validate
|
1617
1626
|
)
|
1618
|
-
# For Rao games
|
1619
|
-
effective_network = get_effective_network(self.config, network)
|
1620
|
-
if is_rao_network(effective_network):
|
1621
|
-
print_error("This command is disabled on the 'rao' network.")
|
1622
|
-
raise typer.Exit()
|
1623
1627
|
|
1624
1628
|
self.initialize_chain(network)
|
1625
1629
|
return self._run_command(
|
@@ -2791,7 +2795,7 @@ class CLIManager:
|
|
2791
2795
|
[blue bold]Note[/blue bold]: This command is for users who wish to reallocate their stake or withdraw them from the network. It allows for flexible management of TAO stake across different neurons (hotkeys) on the network.
|
2792
2796
|
"""
|
2793
2797
|
self.verbosity_handler(quiet, verbose)
|
2794
|
-
# TODO: Coldkey related unstakes need to be updated. Patching for now.
|
2798
|
+
# TODO: Coldkey related unstakes need to be updated. Patching for now.
|
2795
2799
|
unstake_all_alpha = False
|
2796
2800
|
unstake_all = False
|
2797
2801
|
|
@@ -2930,14 +2934,18 @@ class CLIManager:
|
|
2930
2934
|
|
2931
2935
|
def stake_move(
|
2932
2936
|
self,
|
2933
|
-
network=Options.network,
|
2937
|
+
network: Optional[list[str]] = Options.network,
|
2934
2938
|
wallet_name=Options.wallet_name,
|
2935
2939
|
wallet_path=Options.wallet_path,
|
2936
2940
|
wallet_hotkey=Options.wallet_hotkey,
|
2937
|
-
origin_netuid: int = typer.Option(
|
2938
|
-
|
2941
|
+
origin_netuid: Optional[int] = typer.Option(
|
2942
|
+
None, "--origin-netuid", help="Origin netuid"
|
2943
|
+
),
|
2944
|
+
destination_netuid: Optional[int] = typer.Option(
|
2945
|
+
None, "--dest-netuid", help="Destination netuid"
|
2946
|
+
),
|
2939
2947
|
destination_hotkey: Optional[str] = typer.Option(
|
2940
|
-
None, help="Destination hotkey", prompt=False
|
2948
|
+
None, "--dest-ss58", "--dest", help="Destination hotkey", prompt=False
|
2941
2949
|
),
|
2942
2950
|
amount: float = typer.Option(
|
2943
2951
|
None,
|
@@ -2951,40 +2959,343 @@ class CLIManager:
|
|
2951
2959
|
prompt: bool = Options.prompt,
|
2952
2960
|
):
|
2953
2961
|
"""
|
2954
|
-
Move
|
2962
|
+
Move staked TAO between hotkeys while keeping the same coldkey ownership.
|
2955
2963
|
|
2956
|
-
|
2964
|
+
This command allows you to:
|
2965
|
+
- Move stake from one hotkey to another hotkey
|
2966
|
+
- Move stake between different subnets
|
2967
|
+
- Keep the same coldkey ownership
|
2968
|
+
|
2969
|
+
You can specify:
|
2970
|
+
- The origin subnet (--origin-netuid)
|
2971
|
+
- The destination subnet (--dest-netuid)
|
2972
|
+
- The destination hotkey (--dest-hotkey)
|
2973
|
+
- The amount to move (--amount)
|
2974
|
+
|
2975
|
+
If no arguments are provided, an interactive selection menu will be shown.
|
2957
2976
|
|
2958
2977
|
EXAMPLE
|
2959
2978
|
|
2960
2979
|
[green]$[/green] btcli stake move
|
2961
2980
|
"""
|
2962
|
-
|
2963
|
-
|
2964
|
-
[WO.NAME, WO.PATH] if destination_hotkey else [WO.NAME, WO.HOTKEY, WO.PATH]
|
2981
|
+
console.print(
|
2982
|
+
"[dim]This command moves stake from one hotkey to another hotkey while keeping the same coldkey.[/dim]"
|
2965
2983
|
)
|
2966
|
-
|
2984
|
+
if not destination_hotkey:
|
2985
|
+
dest_wallet_or_ss58 = Prompt.ask(
|
2986
|
+
"Enter the [blue]destination wallet[/blue] where destination hotkey is located or [blue]ss58 address[/blue]"
|
2987
|
+
)
|
2988
|
+
if is_valid_ss58_address(dest_wallet_or_ss58):
|
2989
|
+
destination_hotkey = dest_wallet_or_ss58
|
2990
|
+
else:
|
2991
|
+
dest_wallet = self.wallet_ask(
|
2992
|
+
dest_wallet_or_ss58,
|
2993
|
+
wallet_path,
|
2994
|
+
None,
|
2995
|
+
ask_for=[WO.NAME, WO.PATH],
|
2996
|
+
validate=WV.WALLET,
|
2997
|
+
)
|
2998
|
+
destination_hotkey = Prompt.ask(
|
2999
|
+
"Enter the [blue]destination hotkey[/blue] name",
|
3000
|
+
default=dest_wallet.hotkey_str,
|
3001
|
+
)
|
3002
|
+
destination_wallet = self.wallet_ask(
|
3003
|
+
dest_wallet_or_ss58,
|
3004
|
+
wallet_path,
|
3005
|
+
destination_hotkey,
|
3006
|
+
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3007
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3008
|
+
)
|
3009
|
+
destination_hotkey = destination_wallet.hotkey.ss58_address
|
3010
|
+
else:
|
3011
|
+
if is_valid_ss58_address(destination_hotkey):
|
3012
|
+
destination_hotkey = destination_hotkey
|
3013
|
+
else:
|
3014
|
+
print_error(
|
3015
|
+
"Invalid destination hotkey ss58 address. Please enter a valid ss58 address or wallet name."
|
3016
|
+
)
|
3017
|
+
raise typer.Exit()
|
2967
3018
|
|
3019
|
+
if not wallet_name:
|
3020
|
+
wallet_name = Prompt.ask(
|
3021
|
+
"Enter the [blue]origin wallet name[/blue]",
|
3022
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
3023
|
+
)
|
2968
3024
|
wallet = self.wallet_ask(
|
2969
|
-
wallet_name,
|
2970
|
-
wallet_path,
|
2971
|
-
wallet_hotkey,
|
2972
|
-
ask_for=ask_for,
|
2973
|
-
validate=validate,
|
3025
|
+
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
2974
3026
|
)
|
2975
|
-
|
2976
|
-
|
3027
|
+
|
3028
|
+
interactive_selection = False
|
3029
|
+
if not wallet_hotkey:
|
3030
|
+
origin_hotkey = Prompt.ask(
|
3031
|
+
"Enter the [blue]origin hotkey[/blue] name or "
|
3032
|
+
"[blue]ss58 address[/blue] where the stake will be moved from "
|
3033
|
+
"[dim](or Press Enter to view existing stakes)[/dim]"
|
3034
|
+
)
|
3035
|
+
if origin_hotkey == "":
|
3036
|
+
interactive_selection = True
|
3037
|
+
|
3038
|
+
elif is_valid_ss58_address(origin_hotkey):
|
3039
|
+
origin_hotkey = origin_hotkey
|
3040
|
+
else:
|
3041
|
+
wallet = self.wallet_ask(
|
3042
|
+
wallet_name,
|
3043
|
+
wallet_path,
|
3044
|
+
origin_hotkey,
|
3045
|
+
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3046
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3047
|
+
)
|
3048
|
+
origin_hotkey = wallet.hotkey.ss58_address
|
3049
|
+
else:
|
3050
|
+
wallet = self.wallet_ask(
|
3051
|
+
wallet_name,
|
3052
|
+
wallet_path,
|
3053
|
+
wallet_hotkey,
|
3054
|
+
ask_for=[],
|
3055
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3056
|
+
)
|
3057
|
+
origin_hotkey = wallet.hotkey.ss58_address
|
3058
|
+
|
3059
|
+
if not interactive_selection:
|
3060
|
+
if not origin_netuid:
|
3061
|
+
origin_netuid = IntPrompt.ask(
|
3062
|
+
"Enter the [blue]origin subnet[/blue] (netuid) to move stake from"
|
3063
|
+
)
|
3064
|
+
|
3065
|
+
if not destination_netuid:
|
3066
|
+
destination_netuid = IntPrompt.ask(
|
3067
|
+
"Enter the [blue]destination subnet[/blue] (netuid) to move stake to"
|
3068
|
+
)
|
2977
3069
|
|
2978
3070
|
return self._run_command(
|
2979
|
-
|
3071
|
+
move.move_stake(
|
2980
3072
|
subtensor=self.initialize_chain(network),
|
2981
3073
|
wallet=wallet,
|
2982
3074
|
origin_netuid=origin_netuid,
|
3075
|
+
origin_hotkey=origin_hotkey,
|
2983
3076
|
destination_netuid=destination_netuid,
|
2984
3077
|
destination_hotkey=destination_hotkey,
|
2985
3078
|
amount=amount,
|
2986
3079
|
stake_all=stake_all,
|
3080
|
+
interactive_selection=interactive_selection,
|
3081
|
+
prompt=prompt,
|
3082
|
+
)
|
3083
|
+
)
|
3084
|
+
|
3085
|
+
def stake_transfer(
|
3086
|
+
self,
|
3087
|
+
network: Optional[list[str]] = Options.network,
|
3088
|
+
wallet_name: Optional[str] = Options.wallet_name,
|
3089
|
+
wallet_path: Optional[str] = Options.wallet_path,
|
3090
|
+
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
3091
|
+
origin_netuid: Optional[int] = typer.Option(
|
3092
|
+
None,
|
3093
|
+
"--origin-netuid",
|
3094
|
+
help="The netuid to transfer stake from",
|
3095
|
+
),
|
3096
|
+
dest_netuid: Optional[int] = typer.Option(
|
3097
|
+
None,
|
3098
|
+
"--dest-netuid",
|
3099
|
+
help="The netuid to transfer stake to",
|
3100
|
+
),
|
3101
|
+
dest_ss58: Optional[str] = typer.Option(
|
3102
|
+
None,
|
3103
|
+
"--dest-ss58",
|
3104
|
+
"--dest",
|
3105
|
+
"--dest-coldkey",
|
3106
|
+
help="The destination wallet name or SS58 address to transfer stake to",
|
3107
|
+
),
|
3108
|
+
amount: float = typer.Option(
|
3109
|
+
None,
|
3110
|
+
"--amount",
|
3111
|
+
"-a",
|
3112
|
+
help="Amount of stake to transfer",
|
3113
|
+
),
|
3114
|
+
prompt: bool = Options.prompt,
|
3115
|
+
quiet: bool = Options.quiet,
|
3116
|
+
verbose: bool = Options.verbose,
|
3117
|
+
):
|
3118
|
+
"""
|
3119
|
+
Transfer stake between coldkeys while keeping the same hotkey ownership.
|
3120
|
+
|
3121
|
+
This command allows you to:
|
3122
|
+
- Transfer stake from one coldkey to another coldkey
|
3123
|
+
- Keep the same hotkey ownership
|
3124
|
+
- Transfer stake between different subnets
|
3125
|
+
|
3126
|
+
You can specify:
|
3127
|
+
- The origin subnet (--origin-netuid)
|
3128
|
+
- The destination subnet (--dest-netuid)
|
3129
|
+
- The destination wallet/address (--dest)
|
3130
|
+
- The amount to transfer (--amount)
|
3131
|
+
|
3132
|
+
If no arguments are provided, an interactive selection menu will be shown.
|
3133
|
+
|
3134
|
+
EXAMPLE
|
3135
|
+
|
3136
|
+
Transfer 100 TAO from subnet 1 to subnet 2:
|
3137
|
+
[green]$[/green] btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest wallet2 --amount 100
|
3138
|
+
|
3139
|
+
Using SS58 address:
|
3140
|
+
[green]$[/green] btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest 5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngEP9H7qjkKgHLcK --amount 100
|
3141
|
+
"""
|
3142
|
+
console.print(
|
3143
|
+
"[dim]This command transfers stake from one coldkey to another while keeping the same hotkey.[/dim]"
|
3144
|
+
)
|
3145
|
+
self.verbosity_handler(quiet, verbose)
|
3146
|
+
|
3147
|
+
wallet = self.wallet_ask(
|
3148
|
+
wallet_name,
|
3149
|
+
wallet_path,
|
3150
|
+
wallet_hotkey,
|
3151
|
+
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3152
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3153
|
+
)
|
3154
|
+
|
3155
|
+
if not dest_ss58:
|
3156
|
+
dest_ss58 = Prompt.ask(
|
3157
|
+
"Enter the [blue]destination wallet name[/blue] or [blue]coldkey SS58 address[/blue]"
|
3158
|
+
)
|
3159
|
+
|
3160
|
+
if is_valid_ss58_address(dest_ss58):
|
3161
|
+
dest_ss58 = dest_ss58
|
3162
|
+
else:
|
3163
|
+
dest_wallet = self.wallet_ask(
|
3164
|
+
dest_ss58,
|
3165
|
+
wallet_path,
|
3166
|
+
None,
|
3167
|
+
ask_for=[WO.NAME, WO.PATH],
|
3168
|
+
validate=WV.WALLET,
|
3169
|
+
)
|
3170
|
+
dest_ss58 = dest_wallet.coldkeypub.ss58_address
|
3171
|
+
|
3172
|
+
interactive_selection = False
|
3173
|
+
if origin_netuid is None and dest_netuid is None and not amount:
|
3174
|
+
interactive_selection = True
|
3175
|
+
else:
|
3176
|
+
if origin_netuid is None:
|
3177
|
+
origin_netuid = IntPrompt.ask(
|
3178
|
+
"Enter the [blue]origin subnet[/blue] (netuid)"
|
3179
|
+
)
|
3180
|
+
if not amount:
|
3181
|
+
amount = FloatPrompt.ask("Enter the [blue]amount[/blue] to transfer")
|
3182
|
+
|
3183
|
+
if dest_netuid is None:
|
3184
|
+
dest_netuid = IntPrompt.ask(
|
3185
|
+
"Enter the [blue]destination subnet[/blue] (netuid)"
|
3186
|
+
)
|
3187
|
+
|
3188
|
+
return self._run_command(
|
3189
|
+
move.transfer_stake(
|
3190
|
+
wallet=wallet,
|
3191
|
+
subtensor=self.initialize_chain(network),
|
3192
|
+
origin_netuid=origin_netuid,
|
3193
|
+
dest_netuid=dest_netuid,
|
3194
|
+
dest_coldkey_ss58=dest_ss58,
|
3195
|
+
amount=amount,
|
3196
|
+
interactive_selection=interactive_selection,
|
3197
|
+
prompt=prompt,
|
3198
|
+
)
|
3199
|
+
)
|
3200
|
+
|
3201
|
+
def stake_swap(
|
3202
|
+
self,
|
3203
|
+
network: Optional[list[str]] = Options.network,
|
3204
|
+
wallet_name: Optional[str] = Options.wallet_name,
|
3205
|
+
wallet_path: Optional[str] = Options.wallet_path,
|
3206
|
+
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
3207
|
+
origin_netuid: Optional[int] = typer.Option(
|
3208
|
+
None,
|
3209
|
+
"--origin-netuid",
|
3210
|
+
"-o",
|
3211
|
+
"--origin",
|
3212
|
+
help="The netuid to swap stake from",
|
3213
|
+
),
|
3214
|
+
dest_netuid: Optional[int] = typer.Option(
|
3215
|
+
None,
|
3216
|
+
"--dest-netuid",
|
3217
|
+
"-d",
|
3218
|
+
"--dest",
|
3219
|
+
help="The netuid to swap stake to",
|
3220
|
+
),
|
3221
|
+
amount: float = typer.Option(
|
3222
|
+
None,
|
3223
|
+
"--amount",
|
3224
|
+
"-a",
|
3225
|
+
help="Amount of stake to swap",
|
3226
|
+
),
|
3227
|
+
swap_all: bool = typer.Option(
|
3228
|
+
False,
|
3229
|
+
"--swap-all",
|
3230
|
+
"--all",
|
3231
|
+
help="Swap all available stake",
|
3232
|
+
),
|
3233
|
+
prompt: bool = Options.prompt,
|
3234
|
+
wait_for_inclusion: bool = Options.wait_for_inclusion,
|
3235
|
+
wait_for_finalization: bool = Options.wait_for_finalization,
|
3236
|
+
quiet: bool = Options.quiet,
|
3237
|
+
verbose: bool = Options.verbose,
|
3238
|
+
):
|
3239
|
+
"""
|
3240
|
+
Swap stake between different subnets while keeping the same coldkey-hotkey pair ownership.
|
3241
|
+
|
3242
|
+
This command allows you to:
|
3243
|
+
- Move stake from one subnet to another subnet
|
3244
|
+
- Keep the same coldkey ownership
|
3245
|
+
- Keep the same hotkey ownership
|
3246
|
+
|
3247
|
+
You can specify:
|
3248
|
+
- The origin subnet (--origin-netuid)
|
3249
|
+
- The destination subnet (--dest-netuid)
|
3250
|
+
- The amount to swap (--amount)
|
3251
|
+
|
3252
|
+
If no arguments are provided, an interactive selection menu will be shown.
|
3253
|
+
|
3254
|
+
EXAMPLE
|
3255
|
+
|
3256
|
+
Swap 100 TAO from subnet 1 to subnet 2:
|
3257
|
+
[green]$[/green] btcli stake swap --wallet-name default --wallet-hotkey default --origin-netuid 1 --dest-netuid 2 --amount 100
|
3258
|
+
"""
|
3259
|
+
console.print(
|
3260
|
+
"[dim]This command moves stake from one subnet to another subnet while keeping the same coldkey-hotkey pair.[/dim]"
|
3261
|
+
)
|
3262
|
+
self.verbosity_handler(quiet, verbose)
|
3263
|
+
|
3264
|
+
wallet = self.wallet_ask(
|
3265
|
+
wallet_name,
|
3266
|
+
wallet_path,
|
3267
|
+
wallet_hotkey,
|
3268
|
+
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3269
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3270
|
+
)
|
3271
|
+
|
3272
|
+
interactive_selection = False
|
3273
|
+
if origin_netuid is None and dest_netuid is None and not amount:
|
3274
|
+
interactive_selection = True
|
3275
|
+
else:
|
3276
|
+
if origin_netuid is None:
|
3277
|
+
origin_netuid = IntPrompt.ask(
|
3278
|
+
"Enter the [blue]origin subnet[/blue] (netuid)"
|
3279
|
+
)
|
3280
|
+
if dest_netuid is None:
|
3281
|
+
dest_netuid = IntPrompt.ask(
|
3282
|
+
"Enter the [blue]destination subnet[/blue] (netuid)"
|
3283
|
+
)
|
3284
|
+
if not amount and not swap_all:
|
3285
|
+
amount = FloatPrompt.ask("Enter the [blue]amount[/blue] to swap")
|
3286
|
+
|
3287
|
+
return self._run_command(
|
3288
|
+
move.swap_stake(
|
3289
|
+
wallet=wallet,
|
3290
|
+
subtensor=self.initialize_chain(network),
|
3291
|
+
origin_netuid=origin_netuid,
|
3292
|
+
destination_netuid=dest_netuid,
|
3293
|
+
amount=amount,
|
3294
|
+
swap_all=swap_all,
|
3295
|
+
interactive_selection=interactive_selection,
|
2987
3296
|
prompt=prompt,
|
3297
|
+
wait_for_inclusion=wait_for_inclusion,
|
3298
|
+
wait_for_finalization=wait_for_finalization,
|
2988
3299
|
)
|
2989
3300
|
)
|
2990
3301
|
|
@@ -3562,6 +3873,93 @@ class CLIManager:
|
|
3562
3873
|
)
|
3563
3874
|
)
|
3564
3875
|
|
3876
|
+
def subnets_price(
|
3877
|
+
self,
|
3878
|
+
network: Optional[list[str]] = Options.network,
|
3879
|
+
netuids: str = typer.Option(
|
3880
|
+
None,
|
3881
|
+
"--netuids",
|
3882
|
+
"--netuid",
|
3883
|
+
"-n",
|
3884
|
+
help="Netuid(s) to show the price for.",
|
3885
|
+
),
|
3886
|
+
interval_hours: int = typer.Option(
|
3887
|
+
24,
|
3888
|
+
"--interval-hours",
|
3889
|
+
"--interval",
|
3890
|
+
help="The number of hours to show the historical price for.",
|
3891
|
+
),
|
3892
|
+
all_netuids: bool = typer.Option(
|
3893
|
+
False,
|
3894
|
+
"--all-netuids",
|
3895
|
+
"--all",
|
3896
|
+
help="Show the price for all subnets.",
|
3897
|
+
),
|
3898
|
+
log_scale: bool = typer.Option(
|
3899
|
+
False,
|
3900
|
+
"--log-scale",
|
3901
|
+
"--log",
|
3902
|
+
help="Show the price in log scale.",
|
3903
|
+
),
|
3904
|
+
html_output: bool = Options.html_output,
|
3905
|
+
):
|
3906
|
+
"""
|
3907
|
+
Shows the historical price of a subnet for the past 24 hours.
|
3908
|
+
|
3909
|
+
This command displays the historical price of a subnet for the past 24 hours.
|
3910
|
+
If the `--all` flag is used, the command will display the price for all subnets in html format.
|
3911
|
+
If the `--html` flag is used, the command will display the price in an HTML chart.
|
3912
|
+
If the `--log-scale` flag is used, the command will display the price in log scale.
|
3913
|
+
If no html flag is used, the command will display the price in the cli.
|
3914
|
+
|
3915
|
+
EXAMPLE
|
3916
|
+
|
3917
|
+
[green]$[/green] btcli subnets price --netuid 1
|
3918
|
+
[green]$[/green] btcli subnets price --netuid 1 --html --log
|
3919
|
+
[green]$[/green] btcli subnets price --all --html
|
3920
|
+
[green]$[/green] btcli subnets price --netuids 1,2,3,4 --html
|
3921
|
+
"""
|
3922
|
+
if netuids:
|
3923
|
+
netuids = parse_to_list(
|
3924
|
+
netuids,
|
3925
|
+
int,
|
3926
|
+
"Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
|
3927
|
+
)
|
3928
|
+
if all_netuids and netuids:
|
3929
|
+
print_error("Cannot specify both --netuid and --all-netuids")
|
3930
|
+
raise typer.Exit()
|
3931
|
+
|
3932
|
+
if not netuids and not all_netuids:
|
3933
|
+
netuids = Prompt.ask(
|
3934
|
+
"Enter the [blue]netuid(s)[/blue] to view the price of in comma-separated format [dim](or Press Enter to view all subnets)[/dim]",
|
3935
|
+
)
|
3936
|
+
if not netuids:
|
3937
|
+
all_netuids = True
|
3938
|
+
html_output = True
|
3939
|
+
else:
|
3940
|
+
netuids = parse_to_list(
|
3941
|
+
netuids,
|
3942
|
+
int,
|
3943
|
+
"Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
|
3944
|
+
)
|
3945
|
+
|
3946
|
+
if all_netuids:
|
3947
|
+
html_output = True
|
3948
|
+
|
3949
|
+
if html_output and is_linux():
|
3950
|
+
print_linux_dependency_message()
|
3951
|
+
|
3952
|
+
return self._run_command(
|
3953
|
+
price.price(
|
3954
|
+
self.initialize_chain(network),
|
3955
|
+
netuids,
|
3956
|
+
all_netuids,
|
3957
|
+
interval_hours,
|
3958
|
+
html_output,
|
3959
|
+
log_scale,
|
3960
|
+
)
|
3961
|
+
)
|
3962
|
+
|
3565
3963
|
def subnets_show(
|
3566
3964
|
self,
|
3567
3965
|
network: Optional[list[str]] = Options.network,
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
18
18
|
# DEALINGS IN THE SOFTWARE.
|
19
19
|
|
20
|
-
from typing import Union
|
20
|
+
from typing import Union, TypedDict
|
21
21
|
from bittensor_cli.src import UNITS
|
22
22
|
|
23
23
|
|
@@ -301,3 +301,31 @@ class Balance:
|
|
301
301
|
self.unit = Balance.get_unit(netuid)
|
302
302
|
self.rao_unit = Balance.get_unit(netuid)
|
303
303
|
return self
|
304
|
+
|
305
|
+
|
306
|
+
class FixedPoint(TypedDict):
|
307
|
+
"""
|
308
|
+
Represents a fixed point ``U64F64`` number.
|
309
|
+
Where ``bits`` is a U128 representation of the fixed point number.
|
310
|
+
|
311
|
+
This matches the type of the Alpha shares.
|
312
|
+
"""
|
313
|
+
|
314
|
+
bits: int
|
315
|
+
|
316
|
+
|
317
|
+
def fixed_to_float(fixed: FixedPoint) -> float:
|
318
|
+
# Currently this is stored as a U64F64
|
319
|
+
# which is 64 bits of integer and 64 bits of fractional
|
320
|
+
uint_bits = 64
|
321
|
+
frac_bits = 64
|
322
|
+
|
323
|
+
data: int = fixed["bits"]
|
324
|
+
|
325
|
+
# Shift bits to extract integer part (assuming 64 bits for integer part)
|
326
|
+
integer_part = data >> frac_bits
|
327
|
+
fractional_part = data & (2**frac_bits - 1)
|
328
|
+
|
329
|
+
frac_float = fractional_part / (2**frac_bits)
|
330
|
+
|
331
|
+
return integer_part + frac_float
|