bittensor-cli 9.20.1__tar.gz → 9.20.2rc1__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.
Files changed (67) hide show
  1. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/PKG-INFO +1 -1
  2. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/__init__.py +2 -2
  3. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/add.py +117 -119
  4. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/sudo.py +3 -1
  5. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/wallets.py +33 -4
  6. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/pyproject.toml +1 -1
  7. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/README.md +0 -0
  8. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/__init__.py +0 -0
  9. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/cli.py +0 -0
  10. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/doc_generation_helper.py +0 -0
  11. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/__init__.py +0 -0
  12. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/balances.py +0 -0
  13. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/chain_data.py +0 -0
  14. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
  15. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/mev_shield.py +0 -0
  16. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/registration.py +0 -0
  17. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/root.py +0 -0
  18. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/serving.py +0 -0
  19. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/extrinsics/transfer.py +0 -0
  20. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/minigraph.py +0 -0
  21. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/networking.py +0 -0
  22. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/subtensor_interface.py +0 -0
  23. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/main-filters.j2 +0 -0
  24. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/main-header.j2 +0 -0
  25. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/neuron-details.j2 +0 -0
  26. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/price-multi.j2 +0 -0
  27. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/price-single.j2 +0 -0
  28. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/subnet-details-header.j2 +0 -0
  29. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/subnet-details.j2 +0 -0
  30. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/subnet-metrics.j2 +0 -0
  31. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/subnets-table.j2 +0 -0
  32. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
  33. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/view.css +0 -0
  34. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/view.j2 +0 -0
  35. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/templates/view.js +0 -0
  36. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/bittensor/utils.py +0 -0
  37. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/__init__.py +0 -0
  38. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/axon/__init__.py +0 -0
  39. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/axon/axon.py +0 -0
  40. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/__init__.py +0 -0
  41. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/contribute.py +0 -0
  42. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/contributors.py +0 -0
  43. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/create.py +0 -0
  44. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/dissolve.py +0 -0
  45. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/refund.py +0 -0
  46. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/update.py +0 -0
  47. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/utils.py +0 -0
  48. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/crowd/view.py +0 -0
  49. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/liquidity/__init__.py +0 -0
  50. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/liquidity/liquidity.py +0 -0
  51. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/liquidity/utils.py +0 -0
  52. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/proxy.py +0 -0
  53. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/__init__.py +0 -0
  54. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/auto_staking.py +0 -0
  55. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/children_hotkeys.py +0 -0
  56. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/claim.py +0 -0
  57. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/list.py +0 -0
  58. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/move.py +0 -0
  59. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/remove.py +0 -0
  60. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/stake/wizard.py +0 -0
  61. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/subnets/__init__.py +0 -0
  62. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/subnets/mechanisms.py +0 -0
  63. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/subnets/price.py +0 -0
  64. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/subnets/subnets.py +0 -0
  65. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/view.py +0 -0
  66. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/src/commands/weights.py +0 -0
  67. {bittensor_cli-9.20.1 → bittensor_cli-9.20.2rc1}/bittensor_cli/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bittensor-cli
3
- Version: 9.20.1
3
+ Version: 9.20.2rc1
4
4
  Summary: Bittensor CLI
5
5
  Author: bittensor.com
6
6
  Requires-Python: >=3.10
@@ -609,7 +609,7 @@ HYPERPARAMS = {
609
609
  RootSudoOnly.TRUE,
610
610
  ),
611
611
  "min_burn": ("sudo_set_min_burn", RootSudoOnly.FALSE),
612
- "max_burn": ("sudo_set_max_burn", RootSudoOnly.TRUE),
612
+ "max_burn": ("sudo_set_max_burn", RootSudoOnly.COMPLICATED),
613
613
  "bonds_moving_avg": ("sudo_set_bonds_moving_average", RootSudoOnly.FALSE),
614
614
  "max_regs_per_block": ("sudo_set_max_registrations_per_block", RootSudoOnly.TRUE),
615
615
  "serving_rate_limit": ("sudo_set_serving_rate_limit", RootSudoOnly.FALSE),
@@ -745,7 +745,7 @@ HYPERPARAMS_METADATA = {
745
745
  "max_burn": {
746
746
  "description": "Maximum TAO burn amount cap for subnet registration.",
747
747
  "side_effects": "Caps registration costs, ensuring registration remains accessible even as difficulty increases.",
748
- "owner_settable": False,
748
+ "owner_settable": True,
749
749
  "docs_link": "docs.learnbittensor.org/subnets/subnet-hyperparameters#maxburn",
750
750
  },
751
751
  "bonds_moving_avg": {
@@ -339,13 +339,7 @@ async def stake_add(
339
339
  )
340
340
 
341
341
  # Determine the amount we are staking.
342
- rows = []
343
- amounts_to_stake = []
344
- current_stake_balances = []
345
- prices_with_tolerance = []
346
- remaining_wallet_balance = current_wallet_balance
347
- max_slippage = 0.0
348
-
342
+ operation_targets = []
349
343
  for hotkey in hotkeys_to_stake_to:
350
344
  for netuid in netuids:
351
345
  # Check that the subnet exists.
@@ -353,105 +347,126 @@ async def stake_add(
353
347
  if not subnet_info:
354
348
  print_error(f"Subnet with netuid: {netuid} does not exist.")
355
349
  continue
356
- current_stake_balances.append(hotkey_stake_map[hotkey[1]][netuid])
357
-
358
- # Get the amount.
359
- amount_to_stake = Balance(0)
360
- if amount:
361
- amount_to_stake = Balance.from_tao(amount)
362
- elif stake_all:
363
- amount_to_stake = current_wallet_balance / len(netuids)
364
- elif not amount:
365
- amount_to_stake, _ = _prompt_stake_amount(
366
- current_balance=remaining_wallet_balance,
367
- netuid=netuid,
368
- action_name="stake",
369
- )
370
- amounts_to_stake.append(amount_to_stake)
350
+ operation_targets.append(
351
+ (hotkey, netuid, subnet_info, hotkey_stake_map[hotkey[1]][netuid])
352
+ )
371
353
 
372
- # Check enough to stake.
373
- if amount_to_stake > remaining_wallet_balance:
374
- print_error(
375
- f"Not enough stake:[bold white]\n wallet balance:{remaining_wallet_balance} < "
376
- f"staking amount: {amount_to_stake}[/bold white]"
377
- )
378
- return
379
- remaining_wallet_balance -= amount_to_stake
380
-
381
- # Calculate slippage
382
- # TODO: Update for V3, slippage calculation is significantly different in v3
383
- # try:
384
- # received_amount, slippage_pct, slippage_pct_float, rate = (
385
- # _calculate_slippage(subnet_info, amount_to_stake, stake_fee)
386
- # )
387
- # except ValueError:
388
- # return False
389
- #
390
- # max_slippage = max(slippage_pct_float, max_slippage)
391
-
392
- # Temporary workaround - calculations without slippage
393
- current_price_float = float(subnet_info.price.tao)
394
- rate = _safe_inverse_rate(current_price_float)
395
-
396
- # If we are staking safe, add price tolerance
397
- if safe_staking:
398
- if subnet_info.is_dynamic:
399
- price_with_tolerance = current_price_float * (1 + rate_tolerance)
400
- _rate_with_tolerance = _safe_inverse_rate(
401
- price_with_tolerance
402
- ) # Rate only for display
403
- rate_with_tolerance = f"{_rate_with_tolerance:.4f}"
404
- price_with_tolerance = Balance.from_tao(
405
- price_with_tolerance
406
- ) # Actual price to pass to extrinsic
407
- else:
408
- rate_with_tolerance = "1"
409
- price_with_tolerance = Balance.from_rao(1)
410
- extrinsic_fee = await get_stake_extrinsic_fee(
411
- netuid_=netuid,
412
- amount_=amount_to_stake,
413
- staking_address_=hotkey[1],
414
- safe_staking_=safe_staking,
415
- price_limit=price_with_tolerance,
416
- )
417
- prices_with_tolerance.append(price_with_tolerance)
418
- row_extension = [
419
- f"{rate_with_tolerance} {Balance.get_unit(netuid)}/{Balance.get_unit(0)} ",
420
- f"[{'dark_sea_green3' if allow_partial_stake else 'red'}]"
421
- # safe staking
422
- f"{allow_partial_stake}[/{'dark_sea_green3' if allow_partial_stake else 'red'}]",
423
- ]
354
+ if stake_all and not operation_targets:
355
+ print_error("No valid staking operations to perform.")
356
+ return
357
+
358
+ rows = []
359
+ operations = []
360
+ remaining_wallet_balance = current_wallet_balance
361
+ max_slippage = 0.0
362
+
363
+ for hotkey, netuid, subnet_info, current_stake_balance in operation_targets:
364
+ staking_address = hotkey[1]
365
+
366
+ # Get the amount.
367
+ amount_to_stake = Balance(0)
368
+ if amount:
369
+ amount_to_stake = Balance.from_tao(amount)
370
+ elif stake_all:
371
+ amount_to_stake = current_wallet_balance / len(operation_targets)
372
+ elif not amount:
373
+ amount_to_stake, _ = _prompt_stake_amount(
374
+ current_balance=remaining_wallet_balance,
375
+ netuid=netuid,
376
+ action_name="stake",
377
+ )
378
+
379
+ # Check enough to stake.
380
+ if amount_to_stake > remaining_wallet_balance:
381
+ print_error(
382
+ f"Not enough stake:[bold white]\n wallet balance:{remaining_wallet_balance} < "
383
+ f"staking amount: {amount_to_stake}[/bold white]"
384
+ )
385
+ return
386
+ remaining_wallet_balance -= amount_to_stake
387
+
388
+ # Calculate slippage
389
+ # TODO: Update for V3, slippage calculation is significantly different in v3
390
+ # try:
391
+ # received_amount, slippage_pct, slippage_pct_float, rate = (
392
+ # _calculate_slippage(subnet_info, amount_to_stake, stake_fee)
393
+ # )
394
+ # except ValueError:
395
+ # return False
396
+ #
397
+ # max_slippage = max(slippage_pct_float, max_slippage)
398
+
399
+ # Temporary workaround - calculations without slippage
400
+ current_price_float = float(subnet_info.price.tao)
401
+ rate = _safe_inverse_rate(current_price_float)
402
+ price_with_tolerance = None
403
+
404
+ # If we are staking safe, add price tolerance
405
+ if safe_staking:
406
+ if subnet_info.is_dynamic:
407
+ price_with_tolerance = current_price_float * (1 + rate_tolerance)
408
+ _rate_with_tolerance = _safe_inverse_rate(
409
+ price_with_tolerance
410
+ ) # Rate only for display
411
+ rate_with_tolerance = f"{_rate_with_tolerance:.4f}"
412
+ price_with_tolerance = Balance.from_tao(
413
+ price_with_tolerance
414
+ ) # Actual price to pass to extrinsic
424
415
  else:
425
- extrinsic_fee = await get_stake_extrinsic_fee(
426
- netuid_=netuid,
427
- amount_=amount_to_stake,
428
- staking_address_=hotkey[1],
429
- safe_staking_=safe_staking,
430
- )
431
- row_extension = []
432
- # TODO this should be asyncio gathered before the for loop
433
- amount_minus_fee = (
434
- (amount_to_stake - extrinsic_fee) if not proxy else amount_to_stake
416
+ rate_with_tolerance = "1"
417
+ price_with_tolerance = Balance.from_rao(1)
418
+ extrinsic_fee = await get_stake_extrinsic_fee(
419
+ netuid_=netuid,
420
+ amount_=amount_to_stake,
421
+ staking_address_=staking_address,
422
+ safe_staking_=safe_staking,
423
+ price_limit=price_with_tolerance,
424
+ )
425
+ row_extension = [
426
+ f"{rate_with_tolerance} {Balance.get_unit(netuid)}/{Balance.get_unit(0)} ",
427
+ f"[{'dark_sea_green3' if allow_partial_stake else 'red'}]"
428
+ # safe staking
429
+ f"{allow_partial_stake}[/{'dark_sea_green3' if allow_partial_stake else 'red'}]",
430
+ ]
431
+ else:
432
+ extrinsic_fee = await get_stake_extrinsic_fee(
433
+ netuid_=netuid,
434
+ amount_=amount_to_stake,
435
+ staking_address_=staking_address,
436
+ safe_staking_=safe_staking,
435
437
  )
436
- sim_swap = await subtensor.sim_swap(
437
- origin_netuid=0,
438
- destination_netuid=netuid,
439
- amount=amount_minus_fee.rao,
438
+ row_extension = []
439
+ # TODO this should be asyncio gathered before the for loop
440
+ amount_minus_fee = (
441
+ (amount_to_stake - extrinsic_fee) if not proxy else amount_to_stake
442
+ )
443
+ sim_swap = await subtensor.sim_swap(
444
+ origin_netuid=0,
445
+ destination_netuid=netuid,
446
+ amount=amount_minus_fee.rao,
447
+ )
448
+ received_amount = sim_swap.alpha_amount
449
+ # Add rows for the table
450
+ base_row = [
451
+ str(netuid), # netuid
452
+ f"{staking_address}", # hotkey
453
+ str(amount_to_stake), # amount
454
+ str(rate) + f" {Balance.get_unit(netuid)}/{Balance.get_unit(0)} ", # rate
455
+ str(received_amount.set_unit(netuid)), # received
456
+ str(sim_swap.tao_fee), # fee
457
+ str(extrinsic_fee),
458
+ # str(slippage_pct), # slippage
459
+ ] + row_extension
460
+ rows.append(tuple(base_row))
461
+ operations.append(
462
+ (
463
+ netuid,
464
+ staking_address,
465
+ amount_to_stake,
466
+ current_stake_balance,
467
+ price_with_tolerance,
440
468
  )
441
- received_amount = sim_swap.alpha_amount
442
- # Add rows for the table
443
- base_row = [
444
- str(netuid), # netuid
445
- f"{hotkey[1]}", # hotkey
446
- str(amount_to_stake), # amount
447
- str(rate)
448
- + f" {Balance.get_unit(netuid)}/{Balance.get_unit(0)} ", # rate
449
- str(received_amount.set_unit(netuid)), # received
450
- str(sim_swap.tao_fee), # fee
451
- str(extrinsic_fee),
452
- # str(slippage_pct), # slippage
453
- ] + row_extension
454
- rows.append(tuple(base_row))
469
+ )
455
470
 
456
471
  # Define and print stake table + slippage warning
457
472
  table = _define_stake_table(wallet, subtensor, safe_staking, rate_tolerance)
@@ -467,23 +482,6 @@ async def stake_add(
467
482
  if not unlock_key(wallet).success:
468
483
  return
469
484
 
470
- # Build the list of (netuid, hotkey, amount, current_stake, price_limit) tuples
471
- # that describe each staking operation we need to perform.
472
- # The zip aligns netuids with amounts/balances (which are populated per
473
- # hotkey-netuid pair, but the zip truncates to len(netuids), matching the
474
- # original execution order). Each netuid's amount/price applies to all hotkeys.
475
- operations = []
476
- if safe_staking:
477
- for ni, am, curr, price in zip(
478
- netuids, amounts_to_stake, current_stake_balances, prices_with_tolerance
479
- ):
480
- for _, staking_address in hotkeys_to_stake_to:
481
- operations.append((ni, staking_address, am, curr, price))
482
- else:
483
- for ni, am, curr in zip(netuids, amounts_to_stake, current_stake_balances):
484
- for _, staking_address in hotkeys_to_stake_to:
485
- operations.append((ni, staking_address, am, curr, None))
486
-
487
485
  total_ops = len(operations)
488
486
  use_batch = total_ops > 1
489
487
 
@@ -614,7 +614,9 @@ async def set_hyperparameter_extrinsic(
614
614
  )
615
615
  elif sudo_ is RootSudoOnly.COMPLICATED:
616
616
  if not prompt:
617
- to_sudo_or_not_to_sudo = True # default to sudo true when no-prompt is set
617
+ # In no-prompt mode, owners should take the owner path; non-owners
618
+ # should default to sudo.
619
+ to_sudo_or_not_to_sudo = subnet_owner != coldkey_ss58
618
620
  else:
619
621
  to_sudo_or_not_to_sudo = confirm_action(
620
622
  "This hyperparam can be executed as sudo or not. Do you want to execute as sudo [y] or not [n]?",
@@ -1874,23 +1874,29 @@ async def swap_hotkey(
1874
1874
  return result
1875
1875
 
1876
1876
 
1877
- def create_key_value_table(title: str = "Details") -> Table:
1877
+ def create_key_value_table(
1878
+ title: str = "Details",
1879
+ key_label: str = "Item",
1880
+ value_label: str = "Value",
1881
+ ) -> Table:
1878
1882
  """Creates a key-value table for displaying information for various cmds.
1879
1883
 
1880
1884
  Args:
1881
1885
  title: The title shown above the table.
1886
+ key_label: The header for the key column.
1887
+ value_label: The header for the value column.
1882
1888
 
1883
1889
  Returns:
1884
1890
  A Rich Table for key-value display.
1885
1891
  """
1886
1892
  return Table(
1887
1893
  Column(
1888
- "Item",
1894
+ key_label,
1889
1895
  justify="right",
1890
1896
  style=COLOR_PALETTE["GENERAL"]["SUBHEADING_MAIN"],
1891
1897
  no_wrap=True,
1892
1898
  ),
1893
- Column("Value", style=COLOR_PALETTE["GENERAL"]["SUBHEADING"]),
1899
+ Column(value_label, style=COLOR_PALETTE["GENERAL"]["SUBHEADING"]),
1894
1900
  title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}",
1895
1901
  show_footer=True,
1896
1902
  show_edge=False,
@@ -2232,11 +2238,34 @@ async def announce_coldkey_swap(
2232
2238
  return False
2233
2239
 
2234
2240
  # Proceed with the announcement
2235
- swap_cost, delay = await asyncio.gather(
2241
+ swap_cost, delay, dest_staking_hotkeys = await asyncio.gather(
2236
2242
  subtensor.get_coldkey_swap_cost(block_hash=block_hash),
2237
2243
  subtensor.get_coldkey_swap_announcement_delay(block_hash=block_hash),
2244
+ subtensor.get_staking_hotkeys(new_coldkey_ss58, block_hash=block_hash),
2238
2245
  )
2239
2246
 
2247
+ if dest_staking_hotkeys:
2248
+ print_error(
2249
+ "Destination coldkey cannot have any staking hotkeys. "
2250
+ "Please use a new coldkey for the swap."
2251
+ )
2252
+ identity_map = await subtensor.fetch_coldkey_hotkey_identities(
2253
+ block_hash=block_hash
2254
+ )
2255
+ hk_table = create_key_value_table(
2256
+ f"Staking Hotkeys Associated with Destination Coldkey \n Count: ({len(dest_staking_hotkeys)})\n",
2257
+ key_label="Hotkey",
2258
+ value_label="Identity",
2259
+ )
2260
+ for hk_ss58 in dest_staking_hotkeys:
2261
+ hk_name = get_hotkey_identity_name(identity_map, hk_ss58) or "~"
2262
+ hk_table.add_row(
2263
+ f"[{COLORS.G.HK}]{hk_ss58}[/{COLORS.G.HK}]",
2264
+ f"[{COLORS.G.CK}]{hk_name}[/{COLORS.G.CK}]",
2265
+ )
2266
+ console.print(hk_table)
2267
+ return False
2268
+
2240
2269
  table = create_key_value_table("Announcing Coldkey Swap\n")
2241
2270
  table.add_row(
2242
2271
  "Current Coldkey",
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "bittensor-cli"
7
- version = "9.20.1"
7
+ version = "9.20.2rc1"
8
8
  description = "Bittensor CLI"
9
9
  readme = "README.md"
10
10
  authors = [