3939 Constants ,
4040 COLORS ,
4141 HYPERPARAMS ,
42+ WalletOptions ,
4243)
4344from bittensor_cli .src .bittensor import utils
4445from bittensor_cli .src .bittensor .balances import Balance
9293 subnets ,
9394 mechanisms as subnet_mechanisms ,
9495)
96+ from bittensor_cli .src .commands .wallets import SortByBalance
9597from bittensor_cli .version import __version__ , __version_as_int__
9698
9799try :
@@ -1302,6 +1304,7 @@ def _run_command(self, cmd: Coroutine, exit_early: bool = True):
13021304
13031305 async def _run ():
13041306 initiated = False
1307+ exception_occurred = False
13051308 try :
13061309 if self .subtensor :
13071310 await self .subtensor .substrate .initialize ()
@@ -1311,6 +1314,7 @@ async def _run():
13111314 except (ConnectionRefusedError , ssl .SSLError , InvalidHandshake ):
13121315 err_console .print (f"Unable to connect to the chain: { self .subtensor } " )
13131316 verbose_console .print (traceback .format_exc ())
1317+ exception_occurred = True
13141318 except (
13151319 ConnectionClosed ,
13161320 SubstrateRequestException ,
@@ -1322,22 +1326,25 @@ async def _run():
13221326 elif isinstance (e , RuntimeError ):
13231327 pass # Temporarily to handle loop bound issues
13241328 verbose_console .print (traceback .format_exc ())
1329+ exception_occurred = True
13251330 except Exception as e :
13261331 err_console .print (f"An unknown error has occurred: { e } " )
13271332 verbose_console .print (traceback .format_exc ())
1333+ exception_occurred = True
13281334 finally :
13291335 if initiated is False :
13301336 asyncio .create_task (cmd ).cancel ()
13311337 if (
13321338 exit_early is True
13331339 ): # temporarily to handle multiple run commands in one session
1334- try :
1335- if self . subtensor :
1340+ if self . subtensor :
1341+ try :
13361342 await self .subtensor .substrate .close ()
1343+ except Exception as e : # ensures we always exit cleanly
1344+ if not isinstance (e , (typer .Exit , RuntimeError )):
1345+ err_console .print (f"An unknown error has occurred: { e } " )
1346+ if exception_occurred :
13371347 raise typer .Exit ()
1338- except Exception as e : # ensures we always exit cleanly
1339- if not isinstance (e , (typer .Exit , RuntimeError )):
1340- err_console .print (f"An unknown error has occurred: { e } " )
13411348
13421349 return self .event_loop .run_until_complete (_run ())
13431350
@@ -1910,7 +1917,7 @@ def wallet_ask(
19101917 wallet_name : Optional [str ],
19111918 wallet_path : Optional [str ],
19121919 wallet_hotkey : Optional [str ],
1913- ask_for : Optional [list [Literal [ WO . NAME , WO . PATH , WO . HOTKEY ] ]] = None ,
1920+ ask_for : Optional [list [WalletOptions ]] = None ,
19141921 validate : WV = WV .WALLET ,
19151922 return_wallet_and_hotkey : bool = False ,
19161923 ) -> Union [Wallet , tuple [Wallet , str ]]:
@@ -2286,15 +2293,44 @@ def wallet_swap_hotkey(
22862293
22872294 - Make sure that your original key pair (coldkeyA, hotkeyA) is already registered.
22882295 - Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command.
2289- - You can specify the netuid for which you want to swap the hotkey for. If it is not defined, the swap will be initiated for all subnets.
2296+ - If NO netuid is specified, the swap will be initiated for ALL subnets (recommended for most users).
2297+ - If a SPECIFIC netuid is specified (e.g., --netuid 1), the swap will only affect that particular subnet.
2298+ - WARNING: Using --netuid 0 will ONLY swap on the root network (netuid 0), NOT a full swap across all subnets. Use without --netuid for full swap.
22902299 - Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA).
22912300
22922301 EXAMPLE
22932302
2303+ Full swap across all subnets (recommended):
2304+ [green]$[/green] btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey
2305+
2306+ Swap for a specific subnet only:
22942307 [green]$[/green] btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey --netuid 1
22952308 """
22962309 netuid = get_optional_netuid (netuid , all_netuids )
22972310 self .verbosity_handler (quiet , verbose , json_output )
2311+
2312+ # Warning for netuid 0 - only swaps on root network, not a full swap
2313+ if netuid == 0 and prompt :
2314+ console .print (
2315+ "\n [bold yellow]⚠️ WARNING: Using --netuid 0 for swap_hotkey[/bold yellow]\n "
2316+ )
2317+ console .print (
2318+ "[yellow]Specifying --netuid 0 will ONLY swap the hotkey on the root network (netuid 0).[/yellow]\n "
2319+ )
2320+ console .print (
2321+ "[yellow]It will NOT move child hotkey delegation mappings on root.[/yellow]\n "
2322+ )
2323+ console .print (
2324+ f"[bold green]btcli wallet swap_hotkey { destination_hotkey_name or '<destination_hotkey>' } "
2325+ f"--wallet-name { wallet_name or '<wallet_name>' } "
2326+ f"--wallet-hotkey { wallet_hotkey or '<original_hotkey>' } [/bold green]\n "
2327+ )
2328+
2329+ if not Confirm .ask (
2330+ "Are you SURE you want to proceed with --netuid 0 (only root network swap)?" ,
2331+ default = False ,
2332+ ):
2333+ return
22982334 original_wallet = self .wallet_ask (
22992335 wallet_name ,
23002336 wallet_path ,
@@ -3132,6 +3168,11 @@ def wallet_balance(
31323168 "-a" ,
31333169 help = "Whether to display the balances for all the wallets." ,
31343170 ),
3171+ sort_by : Optional [wallets .SortByBalance ] = typer .Option (
3172+ None ,
3173+ "--sort" ,
3174+ help = "When using `--all`, sorts the wallets by a given column" ,
3175+ ),
31353176 network : Optional [list [str ]] = Options .network ,
31363177 quiet : bool = Options .quiet ,
31373178 verbose : bool = Options .verbose ,
@@ -3231,7 +3272,7 @@ def wallet_balance(
32313272 subtensor = self .initialize_chain (network )
32323273 return self ._run_command (
32333274 wallets .wallet_balance (
3234- wallet , subtensor , all_balances , ss58_addresses , json_output
3275+ wallet , subtensor , all_balances , ss58_addresses , sort_by , json_output
32353276 )
32363277 )
32373278
@@ -4573,9 +4614,17 @@ def stake_move(
45734614 [green]$[/green] btcli stake move
45744615 """
45754616 self .verbosity_handler (quiet , verbose , json_output )
4576- console .print (
4577- "[dim]This command moves stake from one hotkey to another hotkey while keeping the same coldkey.[/dim]"
4578- )
4617+ if prompt :
4618+ if not Confirm .ask (
4619+ "This transaction will [bold]move stake[/bold] to another hotkey while keeping the same "
4620+ "coldkey ownership. Do you wish to continue? " ,
4621+ default = False ,
4622+ ):
4623+ raise typer .Exit ()
4624+ else :
4625+ console .print (
4626+ "[dim]This command moves stake from one hotkey to another hotkey while keeping the same coldkey.[/dim]"
4627+ )
45794628 if not destination_hotkey :
45804629 dest_wallet_or_ss58 = Prompt .ask (
45814630 "Enter the [blue]destination wallet[/blue] where destination hotkey is located or "
@@ -4770,9 +4819,18 @@ def stake_transfer(
47704819 [green]$[/green] btcli stake transfer --all --origin-netuid 1 --dest-netuid 2
47714820 """
47724821 self .verbosity_handler (quiet , verbose , json_output )
4773- console .print (
4774- "[dim]This command transfers stake from one coldkey to another while keeping the same hotkey.[/dim]"
4775- )
4822+ if prompt :
4823+ if not Confirm .ask (
4824+ "This transaction will [bold]transfer ownership[/bold] from one coldkey to another, in subnets "
4825+ "which have enabled it. You should ensure that the destination coldkey is "
4826+ "[bold]not a validator hotkey[/bold] before continuing. Do you wish to continue?" ,
4827+ default = False ,
4828+ ):
4829+ raise typer .Exit ()
4830+ else :
4831+ console .print (
4832+ "[dim]This command transfers stake from one coldkey to another while keeping the same hotkey.[/dim]"
4833+ )
47764834
47774835 if not dest_ss58 :
47784836 dest_ss58 = Prompt .ask (
@@ -5229,7 +5287,7 @@ def stake_childkey_take(
52295287 network : Optional [list [str ]] = Options .network ,
52305288 child_hotkey_ss58 : Optional [str ] = typer .Option (
52315289 None ,
5232- "child-hotkey-ss58" ,
5290+ "-- child-hotkey-ss58" ,
52335291 help = "The hotkey SS58 to designate as child (not specifying will use the provided wallet's hotkey)" ,
52345292 prompt = False ,
52355293 ),
@@ -5306,7 +5364,7 @@ def stake_childkey_take(
53065364 subtensor = self .initialize_chain (network ),
53075365 netuid = netuid ,
53085366 take = take ,
5309- hotkey = hotkey ,
5367+ hotkey = child_hotkey_ss58 ,
53105368 wait_for_inclusion = wait_for_inclusion ,
53115369 wait_for_finalization = wait_for_finalization ,
53125370 prompt = prompt ,
@@ -7764,10 +7822,10 @@ def crowd_refund(
77647822 """
77657823 Refund contributors of a non-finalized crowdloan.
77667824
7767- Any account may call this once the crowdloan is no longer wanted. Each call
7768- refunds up to the on-chain `RefundContributorsLimit` contributors (currently
7769- 50) excluding the creator. Run it repeatedly until everyone except the creator
7770- has been reimbursed .
7825+ Only the creator may call this. Each call refunds up to the on-chain `RefundContributorsLimit` contributors
7826+ (currently 50) excluding the creator. Run it repeatedly until everyone except the creator has been reimbursed.
7827+
7828+ Contributors can call `btcli crowdloan withdraw` at will .
77717829 """
77727830 self .verbosity_handler (quiet , verbose , json_output )
77737831
0 commit comments