bittensor-cli 9.0.0rc4__py3-none-any.whl → 9.0.2__py3-none-any.whl

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.
@@ -49,26 +49,36 @@ async def unstake(
49
49
  f"Retrieving subnet data & identities from {subtensor.network}...",
50
50
  spinner="earth",
51
51
  ):
52
- all_sn_dynamic_info_, ck_hk_identities, old_identities = await asyncio.gather(
53
- subtensor.all_subnets(),
54
- subtensor.fetch_coldkey_hotkey_identities(),
55
- subtensor.get_delegate_identities(),
52
+ chain_head = await subtensor.substrate.get_chain_head()
53
+ (
54
+ all_sn_dynamic_info_,
55
+ ck_hk_identities,
56
+ old_identities,
57
+ stake_infos,
58
+ ) = await asyncio.gather(
59
+ subtensor.all_subnets(block_hash=chain_head),
60
+ subtensor.fetch_coldkey_hotkey_identities(block_hash=chain_head),
61
+ subtensor.get_delegate_identities(block_hash=chain_head),
62
+ subtensor.get_stake_for_coldkey(
63
+ wallet.coldkeypub.ss58_address, block_hash=chain_head
64
+ ),
56
65
  )
57
66
  all_sn_dynamic_info = {info.netuid: info for info in all_sn_dynamic_info_}
58
67
 
59
68
  if interactive:
60
69
  hotkeys_to_unstake_from, unstake_all_from_hk = await _unstake_selection(
61
- subtensor,
62
- wallet,
63
70
  all_sn_dynamic_info,
64
71
  ck_hk_identities,
65
72
  old_identities,
73
+ stake_infos,
66
74
  netuid=netuid,
67
75
  )
68
76
  if unstake_all_from_hk:
69
77
  hotkey_to_unstake_all = hotkeys_to_unstake_from[0]
70
78
  unstake_all_alpha = Confirm.ask(
71
- "\nUnstake [blue]all alpha stakes[/blue] and stake back to [blue]root[/blue]? (No will unstake everything)",
79
+ "\nDo you want to:\n"
80
+ "[blue]Yes[/blue]: Unstake from all subnets and automatically restake to subnet 0 (root)\n"
81
+ "[blue]No[/blue]: Unstake everything (including subnet 0)",
72
82
  default=True,
73
83
  )
74
84
  return await unstake_all(
@@ -96,20 +106,17 @@ async def unstake(
96
106
  all_hotkeys=all_hotkeys,
97
107
  include_hotkeys=include_hotkeys,
98
108
  exclude_hotkeys=exclude_hotkeys,
109
+ stake_infos=stake_infos,
110
+ identities=ck_hk_identities,
111
+ old_identities=old_identities,
99
112
  )
100
113
 
101
114
  with console.status(
102
115
  f"Retrieving stake data from {subtensor.network}...",
103
116
  spinner="earth",
104
117
  ):
105
- # Fetch stake balances
106
- chain_head = await subtensor.substrate.get_chain_head()
107
- stake_info_list = await subtensor.get_stake_for_coldkey(
108
- coldkey_ss58=wallet.coldkeypub.ss58_address,
109
- block_hash=chain_head,
110
- )
111
118
  stake_in_netuids = {}
112
- for stake_info in stake_info_list:
119
+ for stake_info in stake_infos:
113
120
  if stake_info.hotkey_ss58 not in stake_in_netuids:
114
121
  stake_in_netuids[stake_info.hotkey_ss58] = {}
115
122
  stake_in_netuids[stake_info.hotkey_ss58][stake_info.netuid] = (
@@ -313,6 +320,9 @@ async def unstake_all(
313
320
  subtensor: "SubtensorInterface",
314
321
  hotkey_ss58_address: str,
315
322
  unstake_all_alpha: bool = False,
323
+ all_hotkeys: bool = False,
324
+ include_hotkeys: list[str] = [],
325
+ exclude_hotkeys: list[str] = [],
316
326
  prompt: bool = True,
317
327
  ) -> bool:
318
328
  """Unstakes all stakes from all hotkeys in all subnets."""
@@ -334,10 +344,27 @@ async def unstake_all(
334
344
  subtensor.all_subnets(),
335
345
  subtensor.get_balance(wallet.coldkeypub.ss58_address),
336
346
  )
337
- if not hotkey_ss58_address:
338
- hotkey_ss58_address = wallet.hotkey.ss58_address
347
+
348
+ if all_hotkeys:
349
+ hotkeys = _get_hotkeys_to_unstake(
350
+ wallet,
351
+ hotkey_ss58_address=hotkey_ss58_address,
352
+ all_hotkeys=all_hotkeys,
353
+ include_hotkeys=include_hotkeys,
354
+ exclude_hotkeys=exclude_hotkeys,
355
+ stake_infos=stake_info,
356
+ identities=ck_hk_identities,
357
+ old_identities=old_identities,
358
+ )
359
+ elif not hotkey_ss58_address:
360
+ hotkeys = [(wallet.hotkey_str, wallet.hotkey.ss58_address)]
361
+ else:
362
+ hotkeys = [(None, hotkey_ss58_address)]
363
+
364
+ hotkey_names = {ss58: name for name, ss58 in hotkeys if name is not None}
365
+ hotkey_ss58s = [ss58 for _, ss58 in hotkeys]
339
366
  stake_info = [
340
- stake for stake in stake_info if stake.hotkey_ss58 == hotkey_ss58_address
367
+ stake for stake in stake_info if stake.hotkey_ss58 in hotkey_ss58s
341
368
  ]
342
369
 
343
370
  if unstake_all_alpha:
@@ -403,18 +430,7 @@ async def unstake_all(
403
430
  if stake.stake.rao == 0:
404
431
  continue
405
432
 
406
- # Get hotkey identity
407
- if hk_identity := ck_hk_identities["hotkeys"].get(stake.hotkey_ss58):
408
- hotkey_name = hk_identity.get("identity", {}).get(
409
- "name", ""
410
- ) or hk_identity.get("display", "~")
411
- hotkey_display = f"{hotkey_name}"
412
- elif old_identity := old_identities.get(stake.hotkey_ss58):
413
- hotkey_name = old_identity.display
414
- hotkey_display = f"{hotkey_name}"
415
- else:
416
- hotkey_display = stake.hotkey_ss58
417
-
433
+ hotkey_display = hotkey_names.get(stake.hotkey_ss58, stake.hotkey_ss58)
418
434
  subnet_info = all_sn_dynamic_info.get(stake.netuid)
419
435
  stake_amount = stake.stake
420
436
  received_amount, slippage_pct, slippage_pct_float = _calculate_slippage(
@@ -455,56 +471,16 @@ async def unstake_all(
455
471
  err_console.print("Error decrypting coldkey (possibly incorrect password)")
456
472
  return False
457
473
 
458
- console_status = (
459
- ":satellite: Unstaking all Alpha stakes..."
460
- if unstake_all_alpha
461
- else ":satellite: Unstaking all stakes..."
462
- )
463
- previous_root_stake = await subtensor.get_stake(
464
- hotkey_ss58=hotkey_ss58_address,
465
- coldkey_ss58=wallet.coldkeypub.ss58_address,
466
- netuid=0,
467
- )
468
- with console.status(console_status):
469
- call_function = "unstake_all_alpha" if unstake_all_alpha else "unstake_all"
470
- call = await subtensor.substrate.compose_call(
471
- call_module="SubtensorModule",
472
- call_function=call_function,
473
- call_params={"hotkey": hotkey_ss58_address},
474
- )
475
- success, error_message = await subtensor.sign_and_send_extrinsic(
476
- call=call,
477
- wallet=wallet,
478
- wait_for_inclusion=True,
479
- wait_for_finalization=False,
480
- )
481
-
482
- if success:
483
- success_message = (
484
- ":white_heavy_check_mark: [green]Successfully unstaked all stakes[/green]"
485
- if not unstake_all_alpha
486
- else ":white_heavy_check_mark: [green]Successfully unstaked all Alpha stakes[/green]"
487
- )
488
- console.print(success_message)
489
- new_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
490
- console.print(
491
- f"Balance:\n [blue]{current_wallet_balance}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_balance}"
492
- )
493
- if unstake_all_alpha:
494
- root_stake = await subtensor.get_stake(
495
- hotkey_ss58=hotkey_ss58_address,
496
- coldkey_ss58=wallet.coldkeypub.ss58_address,
497
- netuid=0,
498
- )
499
- console.print(
500
- f"Root Stake:\n [blue]{previous_root_stake}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{root_stake}"
501
- )
502
- return True
503
- else:
504
- err_console.print(
505
- f":cross_mark: [red]Failed to unstake[/red]: {error_message}"
474
+ with console.status("Unstaking all stakes...") as status:
475
+ for hotkey_ss58 in hotkey_ss58s:
476
+ await _unstake_all_extrinsic(
477
+ wallet=wallet,
478
+ subtensor=subtensor,
479
+ hotkey_ss58=hotkey_ss58,
480
+ hotkey_name=hotkey_names.get(hotkey_ss58, hotkey_ss58),
481
+ unstake_all_alpha=unstake_all_alpha,
482
+ status=status,
506
483
  )
507
- return False
508
484
 
509
485
 
510
486
  # Extrinsics
@@ -561,7 +537,7 @@ async def _unstake_extrinsic(
561
537
  if not await response.is_success:
562
538
  err_out(
563
539
  f"{failure_prelude} with error: "
564
- f"{format_error_message(await response.error_message, subtensor.substrate)}"
540
+ f"{format_error_message(await response.error_message)}"
565
541
  )
566
542
  return
567
543
 
@@ -666,15 +642,13 @@ async def _safe_unstake_extrinsic(
666
642
  )
667
643
  return
668
644
  else:
669
- err_out(
670
- f"\n{failure_prelude} with error: {format_error_message(e, subtensor.substrate)}"
671
- )
645
+ err_out(f"\n{failure_prelude} with error: {format_error_message(e)}")
672
646
  return
673
647
 
674
648
  await response.process_events()
675
649
  if not await response.is_success:
676
650
  err_out(
677
- f"\n{failure_prelude} with error: {format_error_message(await response.error_message, subtensor.substrate)}"
651
+ f"\n{failure_prelude} with error: {format_error_message(await response.error_message)}"
678
652
  )
679
653
  return
680
654
 
@@ -709,6 +683,115 @@ async def _safe_unstake_extrinsic(
709
683
  )
710
684
 
711
685
 
686
+ async def _unstake_all_extrinsic(
687
+ wallet: Wallet,
688
+ subtensor: "SubtensorInterface",
689
+ hotkey_ss58: str,
690
+ hotkey_name: str,
691
+ unstake_all_alpha: bool,
692
+ status=None,
693
+ ) -> None:
694
+ """Execute an unstake all extrinsic.
695
+
696
+ Args:
697
+ wallet: Wallet instance
698
+ subtensor: Subtensor interface
699
+ hotkey_ss58: Hotkey SS58 address
700
+ hotkey_name: Display name of the hotkey
701
+ unstake_all_alpha: Whether to unstake only alpha stakes
702
+ status: Optional status for console updates
703
+ """
704
+ err_out = partial(print_error, status=status)
705
+ failure_prelude = (
706
+ f":cross_mark: [red]Failed[/red] to unstake all from {hotkey_name}"
707
+ )
708
+
709
+ if status:
710
+ status.update(
711
+ f"\n:satellite: {'Unstaking all Alpha stakes' if unstake_all_alpha else 'Unstaking all stakes'} from {hotkey_name} ..."
712
+ )
713
+
714
+ block_hash = await subtensor.substrate.get_chain_head()
715
+ if unstake_all_alpha:
716
+ previous_root_stake, current_balance = await asyncio.gather(
717
+ subtensor.get_stake(
718
+ hotkey_ss58=hotkey_ss58,
719
+ coldkey_ss58=wallet.coldkeypub.ss58_address,
720
+ netuid=0,
721
+ block_hash=block_hash,
722
+ ),
723
+ subtensor.get_balance(
724
+ wallet.coldkeypub.ss58_address, block_hash=block_hash
725
+ ),
726
+ )
727
+ else:
728
+ current_balance = await subtensor.get_balance(
729
+ wallet.coldkeypub.ss58_address, block_hash=block_hash
730
+ )
731
+
732
+ call_function = "unstake_all_alpha" if unstake_all_alpha else "unstake_all"
733
+ call = await subtensor.substrate.compose_call(
734
+ call_module="SubtensorModule",
735
+ call_function=call_function,
736
+ call_params={"hotkey": hotkey_ss58},
737
+ )
738
+
739
+ try:
740
+ response = await subtensor.substrate.submit_extrinsic(
741
+ extrinsic=await subtensor.substrate.create_signed_extrinsic(
742
+ call=call,
743
+ keypair=wallet.coldkey,
744
+ ),
745
+ wait_for_inclusion=True,
746
+ wait_for_finalization=False,
747
+ )
748
+ await response.process_events()
749
+
750
+ if not await response.is_success:
751
+ err_out(
752
+ f"{failure_prelude} with error: "
753
+ f"{format_error_message(await response.error_message)}"
754
+ )
755
+ return
756
+
757
+ # Fetch latest balance and stake
758
+ block_hash = await subtensor.substrate.get_chain_head()
759
+ if unstake_all_alpha:
760
+ new_root_stake, new_balance = await asyncio.gather(
761
+ subtensor.get_stake(
762
+ hotkey_ss58=hotkey_ss58,
763
+ coldkey_ss58=wallet.coldkeypub.ss58_address,
764
+ netuid=0,
765
+ block_hash=block_hash,
766
+ ),
767
+ subtensor.get_balance(
768
+ wallet.coldkeypub.ss58_address, block_hash=block_hash
769
+ ),
770
+ )
771
+ else:
772
+ new_balance = await subtensor.get_balance(
773
+ wallet.coldkeypub.ss58_address, block_hash=block_hash
774
+ )
775
+
776
+ success_message = (
777
+ ":white_heavy_check_mark: [green]Finalized: Successfully unstaked all stakes[/green]"
778
+ if not unstake_all_alpha
779
+ else ":white_heavy_check_mark: [green]Finalized: Successfully unstaked all Alpha stakes[/green]"
780
+ )
781
+ console.print(f"{success_message} from {hotkey_name}")
782
+ console.print(
783
+ f"Balance:\n [blue]{current_balance}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_balance}"
784
+ )
785
+
786
+ if unstake_all_alpha:
787
+ console.print(
788
+ f"Root Stake for {hotkey_name}:\n [blue]{previous_root_stake}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_root_stake}"
789
+ )
790
+
791
+ except Exception as e:
792
+ err_out(f"{failure_prelude} with error: {str(e)}")
793
+
794
+
712
795
  # Helpers
713
796
  def _calculate_slippage(subnet_info, amount: Balance) -> tuple[Balance, str, float]:
714
797
  """Calculate slippage and received amount for unstaking operation.
@@ -737,17 +820,12 @@ def _calculate_slippage(subnet_info, amount: Balance) -> tuple[Balance, str, flo
737
820
 
738
821
 
739
822
  async def _unstake_selection(
740
- subtensor: "SubtensorInterface",
741
- wallet: Wallet,
742
823
  dynamic_info,
743
824
  identities,
744
825
  old_identities,
826
+ stake_infos,
745
827
  netuid: Optional[int] = None,
746
828
  ):
747
- stake_infos = await subtensor.get_stake_for_coldkey(
748
- coldkey_ss58=wallet.coldkeypub.ss58_address
749
- )
750
-
751
829
  if not stake_infos:
752
830
  print_error("You have no stakes to unstake.")
753
831
  raise typer.Exit()
@@ -771,16 +849,11 @@ async def _unstake_selection(
771
849
 
772
850
  hotkeys_info = []
773
851
  for idx, (hotkey_ss58, netuid_stakes) in enumerate(hotkey_stakes.items()):
774
- if hk_identity := identities["hotkeys"].get(hotkey_ss58):
775
- hotkey_name = hk_identity.get("identity", {}).get(
776
- "name", ""
777
- ) or hk_identity.get("display", "~")
778
- elif old_identity := old_identities.get(hotkey_ss58):
779
- hotkey_name = old_identity.display
780
- else:
781
- hotkey_name = "~"
782
- # TODO: Add wallet ids here.
783
-
852
+ hotkey_name = get_hotkey_identity(
853
+ hotkey_ss58=hotkey_ss58,
854
+ identities=identities,
855
+ old_identities=old_identities,
856
+ )
784
857
  hotkeys_info.append(
785
858
  {
786
859
  "index": idx,
@@ -983,6 +1056,9 @@ def _get_hotkeys_to_unstake(
983
1056
  all_hotkeys: bool,
984
1057
  include_hotkeys: list[str],
985
1058
  exclude_hotkeys: list[str],
1059
+ stake_infos: list,
1060
+ identities: dict,
1061
+ old_identities: dict,
986
1062
  ) -> list[tuple[Optional[str], str]]:
987
1063
  """Get list of hotkeys to unstake from based on input parameters.
988
1064
 
@@ -1002,13 +1078,27 @@ def _get_hotkeys_to_unstake(
1002
1078
 
1003
1079
  if all_hotkeys:
1004
1080
  print_verbose("Unstaking from all hotkeys")
1005
- all_hotkeys_: list[Wallet] = get_hotkey_wallets_for_wallet(wallet=wallet)
1006
- return [
1081
+ all_hotkeys_ = get_hotkey_wallets_for_wallet(wallet=wallet)
1082
+ wallet_hotkeys = [
1007
1083
  (wallet.hotkey_str, wallet.hotkey.ss58_address)
1008
1084
  for wallet in all_hotkeys_
1009
1085
  if wallet.hotkey_str not in exclude_hotkeys
1010
1086
  ]
1011
1087
 
1088
+ wallet_hotkey_addresses = {addr for _, addr in wallet_hotkeys}
1089
+ chain_hotkeys = [
1090
+ (
1091
+ get_hotkey_identity(stake_info.hotkey_ss58, identities, old_identities),
1092
+ stake_info.hotkey_ss58,
1093
+ )
1094
+ for stake_info in stake_infos
1095
+ if (
1096
+ stake_info.hotkey_ss58 not in wallet_hotkey_addresses
1097
+ and stake_info.hotkey_ss58 not in exclude_hotkeys
1098
+ )
1099
+ ]
1100
+ return wallet_hotkeys + chain_hotkeys
1101
+
1012
1102
  if include_hotkeys:
1013
1103
  print_verbose("Unstaking from included hotkeys")
1014
1104
  result = []
@@ -1144,3 +1234,28 @@ The columns are as follows:
1144
1234
  - [bold white]Partial unstaking[/bold white]: If True, allows unstaking up to the rate tolerance limit. If False, the entire transaction will fail if rate tolerance is exceeded.\n"""
1145
1235
 
1146
1236
  console.print(base_description + (safe_staking_description if safe_staking else ""))
1237
+
1238
+
1239
+ def get_hotkey_identity(
1240
+ hotkey_ss58: str,
1241
+ identities: dict,
1242
+ old_identities: dict,
1243
+ ) -> str:
1244
+ """Get identity name for a hotkey from identities or old_identities.
1245
+
1246
+ Args:
1247
+ hotkey_ss58 (str): The hotkey SS58 address
1248
+ identities (dict): Current identities from fetch_coldkey_hotkey_identities
1249
+ old_identities (dict): Old identities from get_delegate_identities
1250
+
1251
+ Returns:
1252
+ str: Identity name or truncated address
1253
+ """
1254
+ if hk_identity := identities["hotkeys"].get(hotkey_ss58):
1255
+ return hk_identity.get("identity", {}).get("name", "") or hk_identity.get(
1256
+ "display", "~"
1257
+ )
1258
+ elif old_identity := old_identities.get(hotkey_ss58):
1259
+ return old_identity.display
1260
+ else:
1261
+ return f"{hotkey_ss58[:4]}...{hotkey_ss58[-4:]}"
@@ -35,12 +35,13 @@ from bittensor_cli.src.bittensor.utils import (
35
35
  update_metadata_table,
36
36
  prompt_for_identity,
37
37
  get_subnet_name,
38
+ unlock_key,
38
39
  )
39
40
 
40
41
  if TYPE_CHECKING:
41
42
  from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface
42
43
 
43
- TAO_WEIGHT = 0.018
44
+ TAO_WEIGHT = 0.18
44
45
 
45
46
  # helpers and extrinsics
46
47
 
@@ -183,7 +184,7 @@ async def register_subnetwork_extrinsic(
183
184
  await response.process_events()
184
185
  if not await response.is_success:
185
186
  err_console.print(
186
- f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message, substrate)}"
187
+ f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message)}"
187
188
  )
188
189
  await asyncio.sleep(0.5)
189
190
  return False
@@ -888,8 +889,8 @@ async def show(
888
889
  total_emission_per_block = 0
889
890
  for netuid_ in range(len(all_subnets)):
890
891
  subnet = all_subnets[netuid_]
891
- emission_on_subnet = (
892
- root_state.emission_history[netuid_][idx] / subnet.tempo
892
+ emission_on_subnet = root_state.emission_history[netuid_][idx] / (
893
+ subnet.tempo or 1
893
894
  )
894
895
  total_emission_per_block += subnet.alpha_to_tao(
895
896
  Balance.from_rao(emission_on_subnet)
@@ -1322,7 +1323,7 @@ async def show(
1322
1323
  return hotkey
1323
1324
  else:
1324
1325
  console.print(
1325
- f"[red]Invalid UID. Please enter a valid UID from the table above[/red]"
1326
+ "[red]Invalid UID. Please enter a valid UID from the table above[/red]"
1326
1327
  )
1327
1328
  except ValueError:
1328
1329
  console.print("[red]Please enter a valid number[/red]")
@@ -2026,3 +2027,144 @@ async def metagraph_cmd(
2026
2027
  table.add_row(*row)
2027
2028
 
2028
2029
  console.print(table)
2030
+
2031
+
2032
+ def create_identity_table(title: str = None):
2033
+ if not title:
2034
+ title = "Subnet Identity"
2035
+
2036
+ table = Table(
2037
+ Column(
2038
+ "Item",
2039
+ justify="right",
2040
+ style=COLOR_PALETTE["GENERAL"]["SUBHEADING_MAIN"],
2041
+ no_wrap=True,
2042
+ ),
2043
+ Column("Value", style=COLOR_PALETTE["GENERAL"]["SUBHEADING"]),
2044
+ title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}\n",
2045
+ show_footer=True,
2046
+ show_edge=False,
2047
+ header_style="bold white",
2048
+ border_style="bright_black",
2049
+ style="bold",
2050
+ title_justify="center",
2051
+ show_lines=False,
2052
+ pad_edge=True,
2053
+ )
2054
+ return table
2055
+
2056
+
2057
+ async def set_identity(
2058
+ wallet: "Wallet",
2059
+ subtensor: "SubtensorInterface",
2060
+ netuid: int,
2061
+ subnet_identity: dict,
2062
+ prompt: bool = False,
2063
+ ) -> bool:
2064
+ """Set identity information for a subnet"""
2065
+
2066
+ if not await subtensor.subnet_exists(netuid):
2067
+ err_console.print(f"Subnet {netuid} does not exist")
2068
+ return False
2069
+
2070
+ identity_data = {
2071
+ "netuid": netuid,
2072
+ "subnet_name": subnet_identity.get("subnet_name", ""),
2073
+ "github_repo": subnet_identity.get("github_repo", ""),
2074
+ "subnet_contact": subnet_identity.get("subnet_contact", ""),
2075
+ "subnet_url": subnet_identity.get("subnet_url", ""),
2076
+ "discord": subnet_identity.get("discord", ""),
2077
+ "description": subnet_identity.get("description", ""),
2078
+ "additional": subnet_identity.get("additional", ""),
2079
+ }
2080
+
2081
+ if not unlock_key(wallet).success:
2082
+ return False
2083
+
2084
+ if prompt:
2085
+ if not Confirm.ask(
2086
+ "Are you sure you want to set subnet's identity? This is subject to a fee."
2087
+ ):
2088
+ return False
2089
+
2090
+ call = await subtensor.substrate.compose_call(
2091
+ call_module="SubtensorModule",
2092
+ call_function="set_subnet_identity",
2093
+ call_params=identity_data,
2094
+ )
2095
+
2096
+ with console.status(
2097
+ " :satellite: [dark_sea_green3]Setting subnet identity on-chain...",
2098
+ spinner="earth",
2099
+ ):
2100
+ success, err_msg = await subtensor.sign_and_send_extrinsic(call, wallet)
2101
+
2102
+ if not success:
2103
+ err_console.print(f"[red]:cross_mark: Failed![/red] {err_msg}")
2104
+ return False
2105
+
2106
+ console.print(
2107
+ ":white_heavy_check_mark: [dark_sea_green3]Successfully set subnet identity\n"
2108
+ )
2109
+
2110
+ subnet = await subtensor.subnet(netuid)
2111
+ identity = subnet.subnet_identity if subnet else None
2112
+
2113
+ if identity:
2114
+ table = create_identity_table(title=f"New Subnet {netuid} Identity")
2115
+ table.add_row("Netuid", str(netuid))
2116
+ for key in [
2117
+ "subnet_name",
2118
+ "github_repo",
2119
+ "subnet_contact",
2120
+ "subnet_url",
2121
+ "discord",
2122
+ "description",
2123
+ "additional",
2124
+ ]:
2125
+ value = getattr(identity, key, None)
2126
+ table.add_row(key, str(value) if value else "~")
2127
+ console.print(table)
2128
+
2129
+ return True
2130
+
2131
+
2132
+ async def get_identity(subtensor: "SubtensorInterface", netuid: int, title: str = None):
2133
+ """Fetch and display existing subnet identity information."""
2134
+ if not title:
2135
+ title = "Subnet Identity"
2136
+
2137
+ if not await subtensor.subnet_exists(netuid):
2138
+ print_error(f"Subnet {netuid} does not exist.")
2139
+ raise typer.Exit()
2140
+
2141
+ with console.status(
2142
+ ":satellite: [bold green]Querying subnet identity...", spinner="earth"
2143
+ ):
2144
+ subnet = await subtensor.subnet(netuid)
2145
+ identity = subnet.subnet_identity if subnet else None
2146
+
2147
+ if not identity:
2148
+ err_console.print(
2149
+ f"Existing subnet identity not found"
2150
+ f" for subnet [blue]{netuid}[/blue]"
2151
+ f" on {subtensor}"
2152
+ )
2153
+ return {}
2154
+
2155
+ if identity:
2156
+ table = create_identity_table(title=f"Current Subnet {netuid} Identity")
2157
+ table.add_row("Netuid", str(netuid))
2158
+ for key in [
2159
+ "subnet_name",
2160
+ "github_repo",
2161
+ "subnet_contact",
2162
+ "subnet_url",
2163
+ "discord",
2164
+ "description",
2165
+ "additional",
2166
+ ]:
2167
+ value = getattr(identity, key, None)
2168
+ table.add_row(key, str(value) if value else "~")
2169
+ console.print(table)
2170
+ return identity