From fc4540c1055d5d714fb5b7ee2290e071e7904710 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Tue, 25 Feb 2025 18:14:12 +0200 Subject: [PATCH 1/2] Adds `origin_hotkey` for `transfer_stake` to allow users to specify the SS58 rather than requiring the hotkey to be in the wallet. --- bittensor_cli/cli.py | 42 +++++++++++++++++++----- bittensor_cli/src/commands/stake/move.py | 17 +++++----- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 419fd8c32..e0a9d9a15 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -3321,9 +3321,9 @@ def stake_remove( def stake_move( self, network: Optional[list[str]] = Options.network, - wallet_name=Options.wallet_name, - wallet_path=Options.wallet_path, - wallet_hotkey=Options.wallet_hotkey, + wallet_name: Optional[str] = Options.wallet_name, + wallet_path: Optional[str] = Options.wallet_path, + wallet_hotkey: Optional[str] = Options.wallet_hotkey, origin_netuid: Optional[int] = typer.Option( None, "--origin-netuid", help="Origin netuid" ), @@ -3534,13 +3534,38 @@ def stake_transfer( self.verbosity_handler(quiet, verbose) wallet = self.wallet_ask( - wallet_name, - wallet_path, - wallet_hotkey, - ask_for=[WO.NAME, WO.PATH, WO.HOTKEY], - validate=WV.WALLET_AND_HOTKEY, + wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH] ) + if not wallet_hotkey: + origin_hotkey = Prompt.ask( + "Enter the [blue]origin hotkey[/blue] name or " + "[blue]ss58 address[/blue] where the stake will be moved from " + ) + if is_valid_ss58_address(origin_hotkey): + origin_hotkey = origin_hotkey + else: + wallet = self.wallet_ask( + wallet_name, + wallet_path, + origin_hotkey, + ask_for=[WO.NAME, WO.PATH, WO.HOTKEY], + validate=WV.WALLET_AND_HOTKEY, + ) + origin_hotkey = wallet.hotkey.ss58_address + else: + if is_valid_ss58_address(wallet_hotkey): + origin_hotkey = wallet_hotkey + else: + wallet = self.wallet_ask( + wallet_name, + wallet_path, + wallet_hotkey, + ask_for=[], + validate=WV.WALLET_AND_HOTKEY, + ) + origin_hotkey = wallet.hotkey.ss58_address + if not dest_ss58: dest_ss58 = Prompt.ask( "Enter the [blue]destination wallet name[/blue] or [blue]coldkey SS58 address[/blue]" @@ -3578,6 +3603,7 @@ def stake_transfer( move_stake.transfer_stake( wallet=wallet, subtensor=self.initialize_chain(network), + origin_hotkey=origin_hotkey, origin_netuid=origin_netuid, dest_netuid=dest_netuid, dest_coldkey_ss58=dest_ss58, diff --git a/bittensor_cli/src/commands/stake/move.py b/bittensor_cli/src/commands/stake/move.py index 964f0ed1b..d8b6360e6 100644 --- a/bittensor_cli/src/commands/stake/move.py +++ b/bittensor_cli/src/commands/stake/move.py @@ -697,6 +697,7 @@ async def transfer_stake( wallet: Wallet, subtensor: "SubtensorInterface", amount: float, + origin_hotkey: str, origin_netuid: int, dest_netuid: int, dest_coldkey_ss58: str, @@ -709,6 +710,7 @@ async def transfer_stake( wallet (Wallet): Bittensor wallet object. subtensor (SubtensorInterface): Subtensor interface instance. amount (float): Amount to transfer. + origin_hotkey (str): The hotkey SS58 to transfer the stake from. origin_netuid (int): The netuid to transfer stake from. dest_netuid (int): The netuid to transfer stake to. dest_coldkey_ss58 (str): The destination coldkey to transfer stake to. @@ -739,16 +741,15 @@ async def transfer_stake( return False # Get current stake balances - hotkey_ss58 = wallet.hotkey.ss58_address with console.status(f"Retrieving stake data from {subtensor.network}..."): current_stake = await subtensor.get_stake( coldkey_ss58=wallet.coldkeypub.ss58_address, - hotkey_ss58=hotkey_ss58, + hotkey_ss58=origin_hotkey, netuid=origin_netuid, ) current_dest_stake = await subtensor.get_stake( coldkey_ss58=dest_coldkey_ss58, - hotkey_ss58=hotkey_ss58, + hotkey_ss58=origin_hotkey, netuid=dest_netuid, ) amount_to_transfer = Balance.from_tao(amount).set_unit(origin_netuid) @@ -768,8 +769,8 @@ async def transfer_stake( subtensor=subtensor, origin_netuid=origin_netuid, destination_netuid=dest_netuid, - origin_hotkey=hotkey_ss58, - destination_hotkey=hotkey_ss58, + origin_hotkey=origin_hotkey, + destination_hotkey=origin_hotkey, amount_to_move=amount_to_transfer, ) @@ -789,7 +790,7 @@ async def transfer_stake( call_function="transfer_stake", call_params={ "destination_coldkey": dest_coldkey_ss58, - "hotkey": hotkey_ss58, + "hotkey": origin_hotkey, "origin_netuid": origin_netuid, "destination_netuid": dest_netuid, "alpha_amount": amount_to_transfer.rao, @@ -820,12 +821,12 @@ async def transfer_stake( new_stake, new_dest_stake = await asyncio.gather( subtensor.get_stake( coldkey_ss58=wallet.coldkeypub.ss58_address, - hotkey_ss58=hotkey_ss58, + hotkey_ss58=origin_hotkey, netuid=origin_netuid, ), subtensor.get_stake( coldkey_ss58=dest_coldkey_ss58, - hotkey_ss58=hotkey_ss58, + hotkey_ss58=origin_hotkey, netuid=dest_netuid, ), ) From 8c7077165f23085b9226979710126c94d5619847 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 25 Feb 2025 09:47:35 -0800 Subject: [PATCH 2/2] Edge case: avoid 2 prompts for wallet --- bittensor_cli/cli.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index e0a9d9a15..39f105757 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -3533,14 +3533,20 @@ def stake_transfer( ) self.verbosity_handler(quiet, verbose) + if not wallet_name: + wallet_name = Prompt.ask( + "Enter the [blue]origin wallet name[/blue]", + default=self.config.get("wallet_name") or defaults.wallet.name, + ) wallet = self.wallet_ask( - wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH] + wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME] ) if not wallet_hotkey: origin_hotkey = Prompt.ask( "Enter the [blue]origin hotkey[/blue] name or " - "[blue]ss58 address[/blue] where the stake will be moved from " + "[blue]ss58 address[/blue] where the stake will be moved from", + default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey, ) if is_valid_ss58_address(origin_hotkey): origin_hotkey = origin_hotkey