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.
bittensor_cli/cli.py CHANGED
@@ -26,7 +26,9 @@ from bittensor_cli.src import (
26
26
  WalletValidationTypes as WV,
27
27
  Constants,
28
28
  COLOR_PALETTE,
29
+ HYPERPARAMS,
29
30
  )
31
+ from bittensor_cli.version import __version__, __version_as_int__
30
32
  from bittensor_cli.src.bittensor import utils
31
33
  from bittensor_cli.src.bittensor.balances import Balance
32
34
  from async_substrate_interface.errors import SubstrateRequestException
@@ -72,21 +74,8 @@ except ImportError:
72
74
  pass
73
75
 
74
76
 
75
- __version__ = "9.0.0rc4"
76
77
 
77
78
 
78
- _core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
79
- _version_split = _core_version.split(".")
80
- __version_info__ = tuple(int(part) for part in _version_split)
81
- _version_int_base = 1000
82
- assert max(__version_info__) < _version_int_base
83
-
84
- __version_as_int__: int = sum(
85
- e * (_version_int_base**i) for i, e in enumerate(reversed(__version_info__))
86
- )
87
- assert __version_as_int__ < 2**31 # fits in int32
88
- __new_signature_version__ = 360
89
-
90
79
  _epilog = "Made with [bold red]:heart:[/bold red] by The Openτensor Foundaτion"
91
80
 
92
81
  np.set_printoptions(precision=8, suppress=True, floatmode="fixed")
@@ -124,7 +113,7 @@ class Options:
124
113
  )
125
114
  mnemonic = typer.Option(
126
115
  None,
127
- help="Mnemonic used to regenerate your key. For example: horse cart dog ...",
116
+ help='Mnemonic used to regenerate your key. For example: "horse cart dog ..."',
128
117
  )
129
118
  seed = typer.Option(
130
119
  None, help="Seed hex string used to regenerate your key. For example: 0x1234..."
@@ -141,22 +130,15 @@ class Options:
141
130
  use_password = typer.Option(
142
131
  True,
143
132
  help="Set this to `True` to protect the generated Bittensor key with a password.",
144
- is_flag=True,
145
- flag_value=False,
146
133
  )
147
134
  public_hex_key = typer.Option(None, help="The public key in hex format.")
148
135
  ss58_address = typer.Option(
149
136
  None, "--ss58", "--ss58-address", help="The SS58 address of the coldkey."
150
137
  )
151
- overwrite_coldkey = typer.Option(
152
- False,
153
- help="Overwrite the old coldkey with the newly generated coldkey.",
154
- prompt=True,
155
- )
156
- overwrite_hotkey = typer.Option(
138
+ overwrite = typer.Option(
157
139
  False,
158
- help="Overwrite the old hotkey with the newly generated hotkey.",
159
- prompt=True,
140
+ "--overwrite/--no-overwrite",
141
+ help="Overwrite the existing wallet file with the new one.",
160
142
  )
161
143
  network = typer.Option(
162
144
  None,
@@ -663,7 +645,7 @@ class CLIManager:
663
645
  self.config_app.command("set")(self.set_config)
664
646
  self.config_app.command("get")(self.get_config)
665
647
  self.config_app.command("clear")(self.del_config)
666
- self.config_app.command("metagraph", hidden=True)(self.metagraph_config)
648
+ # self.config_app.command("metagraph", hidden=True)(self.metagraph_config)
667
649
 
668
650
  # wallet commands
669
651
  self.wallet_app.command(
@@ -811,6 +793,12 @@ class CLIManager:
811
793
  self.subnets_app.command(
812
794
  "price", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"]
813
795
  )(self.subnets_price)
796
+ self.subnets_app.command(
797
+ "set-identity", rich_help_panel=HELP_PANELS["SUBNETS"]["IDENTITY"]
798
+ )(self.subnets_set_identity)
799
+ self.subnets_app.command(
800
+ "get-identity", rich_help_panel=HELP_PANELS["SUBNETS"]["IDENTITY"]
801
+ )(self.subnets_get_identity)
814
802
 
815
803
  # weights commands
816
804
  self.weights_app.command(
@@ -970,13 +958,13 @@ class CLIManager:
970
958
  finally:
971
959
  if initiated is False:
972
960
  asyncio.create_task(cmd).cancel()
973
- if exit_early is True:
961
+ if (
962
+ exit_early is True
963
+ ): # temporarily to handle multiple run commands in one session
974
964
  try:
975
965
  raise typer.Exit()
976
966
  except Exception as e: # ensures we always exit cleanly
977
- if not isinstance(
978
- e, (typer.Exit, RuntimeError)
979
- ): # temporarily to handle multiple run commands in one session
967
+ if not isinstance(e, (typer.Exit, RuntimeError)):
980
968
  err_console.print(f"An unknown error has occurred: {e}")
981
969
 
982
970
  return self.asyncio_runner(_run())
@@ -1563,7 +1551,7 @@ class CLIManager:
1563
1551
  """
1564
1552
  Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config.
1565
1553
 
1566
- The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that is not encrypted and exists on the device.
1554
+ The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address (or an `<ENCRYPTED>` marker, for encrypted hotkeys) is displayed for each coldkey and hotkey that exists on the device.
1567
1555
 
1568
1556
  Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the
1569
1557
  public keys are available (`?` denotes unavailable or encrypted keys).
@@ -1648,7 +1636,7 @@ class CLIManager:
1648
1636
  "Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
1649
1637
  )
1650
1638
 
1651
- ask_for = [WO.NAME, WO.PATH] if not all_wallets else [WO.PATH]
1639
+ ask_for = [WO.NAME] if not all_wallets else []
1652
1640
  validate = WV.WALLET if not all_wallets else WV.NONE
1653
1641
  wallet = self.wallet_ask(
1654
1642
  wallet_name, wallet_path, wallet_hotkey, ask_for=ask_for, validate=validate
@@ -1696,9 +1684,11 @@ class CLIManager:
1696
1684
  None,
1697
1685
  "--amount",
1698
1686
  "-a",
1699
- prompt=True,
1700
1687
  help="Amount (in TAO) to transfer.",
1701
1688
  ),
1689
+ transfer_all: bool = typer.Option(
1690
+ False, "--all", prompt=False, help="Transfer all available balance."
1691
+ ),
1702
1692
  wallet_name: str = Options.wallet_name,
1703
1693
  wallet_path: str = Options.wallet_path,
1704
1694
  wallet_hotkey: str = Options.wallet_hotkey,
@@ -1734,20 +1724,25 @@ class CLIManager:
1734
1724
  wallet_name,
1735
1725
  wallet_path,
1736
1726
  wallet_hotkey,
1737
- ask_for=[WO.NAME, WO.PATH],
1727
+ ask_for=[WO.NAME],
1738
1728
  validate=WV.WALLET,
1739
1729
  )
1740
-
1741
- # For Rao games - temporarily commented out
1742
- # effective_network = get_effective_network(self.config, network)
1743
- # if is_rao_network(effective_network):
1744
- # print_error("This command is disabled on the 'rao' network.")
1745
- # raise typer.Exit()
1746
-
1747
1730
  subtensor = self.initialize_chain(network)
1731
+ if transfer_all and amount:
1732
+ print_error("Cannot specify an amount and '--all' flag.")
1733
+ raise typer.Exit()
1734
+ elif transfer_all:
1735
+ amount = 0
1736
+ elif not amount:
1737
+ amount = FloatPrompt.ask("Enter amount (in TAO) to transfer.")
1748
1738
  return self._run_command(
1749
1739
  wallets.transfer(
1750
- wallet, subtensor, destination_ss58_address, amount, prompt
1740
+ wallet,
1741
+ subtensor,
1742
+ destination_ss58_address,
1743
+ amount,
1744
+ transfer_all,
1745
+ prompt,
1751
1746
  )
1752
1747
  )
1753
1748
 
@@ -1933,6 +1928,7 @@ class CLIManager:
1933
1928
  "--max-successes",
1934
1929
  help="Set the maximum number of times to successfully run the faucet for this command.",
1935
1930
  ),
1931
+ prompt: bool = Options.prompt,
1936
1932
  ):
1937
1933
  """
1938
1934
  Obtain test TAO tokens by performing Proof of Work (PoW).
@@ -1971,6 +1967,7 @@ class CLIManager:
1971
1967
  output_in_place,
1972
1968
  verbose,
1973
1969
  max_successes,
1970
+ prompt,
1974
1971
  )
1975
1972
  )
1976
1973
 
@@ -1984,6 +1981,7 @@ class CLIManager:
1984
1981
  json: Optional[str] = Options.json,
1985
1982
  json_password: Optional[str] = Options.json_password,
1986
1983
  use_password: Optional[bool] = Options.use_password,
1984
+ overwrite: bool = Options.overwrite,
1987
1985
  quiet: bool = Options.quiet,
1988
1986
  verbose: bool = Options.verbose,
1989
1987
  ):
@@ -2030,6 +2028,7 @@ class CLIManager:
2030
2028
  json,
2031
2029
  json_password,
2032
2030
  use_password,
2031
+ overwrite,
2033
2032
  )
2034
2033
  )
2035
2034
 
@@ -2040,6 +2039,7 @@ class CLIManager:
2040
2039
  wallet_hotkey: Optional[str] = Options.wallet_hotkey,
2041
2040
  public_key_hex: Optional[str] = Options.public_hex_key,
2042
2041
  ss58_address: Optional[str] = Options.ss58_address,
2042
+ overwrite: bool = Options.overwrite,
2043
2043
  quiet: bool = Options.quiet,
2044
2044
  verbose: bool = Options.verbose,
2045
2045
  ):
@@ -2087,7 +2087,7 @@ class CLIManager:
2087
2087
  rich.print("[red]Error: Invalid SS58 address or public key![/red]")
2088
2088
  raise typer.Exit()
2089
2089
  return self._run_command(
2090
- wallets.regen_coldkey_pub(wallet, ss58_address, public_key_hex)
2090
+ wallets.regen_coldkey_pub(wallet, ss58_address, public_key_hex, overwrite)
2091
2091
  )
2092
2092
 
2093
2093
  def wallet_regen_hotkey(
@@ -2102,9 +2102,8 @@ class CLIManager:
2102
2102
  use_password: bool = typer.Option(
2103
2103
  False, # Overriden to False
2104
2104
  help="Set to 'True' to protect the generated Bittensor key with a password.",
2105
- is_flag=True,
2106
- flag_value=True,
2107
2105
  ),
2106
+ overwrite: bool = Options.overwrite,
2108
2107
  quiet: bool = Options.quiet,
2109
2108
  verbose: bool = Options.verbose,
2110
2109
  ):
@@ -2120,6 +2119,7 @@ class CLIManager:
2120
2119
  # Example usage:
2121
2120
 
2122
2121
  [green]$[/green] btcli wallet regen_hotkey --seed 0x1234...
2122
+ [green]$[/green] btcli wallet regen-hotkey --mnemonic "word1 word2 ... word12"
2123
2123
 
2124
2124
  [bold]Note[/bold]: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery.
2125
2125
  It should be used with caution to avoid accidental overwriting of existing keys.
@@ -2143,6 +2143,7 @@ class CLIManager:
2143
2143
  json,
2144
2144
  json_password,
2145
2145
  use_password,
2146
+ overwrite,
2146
2147
  )
2147
2148
  )
2148
2149
 
@@ -2160,10 +2161,9 @@ class CLIManager:
2160
2161
  use_password: bool = typer.Option(
2161
2162
  False, # Overriden to False
2162
2163
  help="Set to 'True' to protect the generated Bittensor key with a password.",
2163
- is_flag=True,
2164
- flag_value=True,
2165
2164
  ),
2166
2165
  uri: Optional[str] = Options.uri,
2166
+ overwrite: bool = Options.overwrite,
2167
2167
  quiet: bool = Options.quiet,
2168
2168
  verbose: bool = Options.verbose,
2169
2169
  ):
@@ -2204,7 +2204,9 @@ class CLIManager:
2204
2204
  )
2205
2205
  if not uri:
2206
2206
  n_words = get_n_words(n_words)
2207
- return self._run_command(wallets.new_hotkey(wallet, n_words, use_password, uri))
2207
+ return self._run_command(
2208
+ wallets.new_hotkey(wallet, n_words, use_password, uri, overwrite)
2209
+ )
2208
2210
 
2209
2211
  def wallet_new_coldkey(
2210
2212
  self,
@@ -2219,6 +2221,7 @@ class CLIManager:
2219
2221
  ),
2220
2222
  use_password: Optional[bool] = Options.use_password,
2221
2223
  uri: Optional[str] = Options.uri,
2224
+ overwrite: bool = Options.overwrite,
2222
2225
  quiet: bool = Options.quiet,
2223
2226
  verbose: bool = Options.verbose,
2224
2227
  ):
@@ -2258,7 +2261,7 @@ class CLIManager:
2258
2261
  if not uri:
2259
2262
  n_words = get_n_words(n_words)
2260
2263
  return self._run_command(
2261
- wallets.new_coldkey(wallet, n_words, use_password, uri)
2264
+ wallets.new_coldkey(wallet, n_words, use_password, uri, overwrite)
2262
2265
  )
2263
2266
 
2264
2267
  def wallet_check_ck_swap(
@@ -2294,6 +2297,7 @@ class CLIManager:
2294
2297
  n_words: Optional[int] = None,
2295
2298
  use_password: bool = Options.use_password,
2296
2299
  uri: Optional[str] = Options.uri,
2300
+ overwrite: bool = Options.overwrite,
2297
2301
  quiet: bool = Options.quiet,
2298
2302
  verbose: bool = Options.verbose,
2299
2303
  ):
@@ -2337,12 +2341,7 @@ class CLIManager:
2337
2341
  if not uri:
2338
2342
  n_words = get_n_words(n_words)
2339
2343
  return self._run_command(
2340
- wallets.wallet_create(
2341
- wallet,
2342
- n_words,
2343
- use_password,
2344
- uri,
2345
- )
2344
+ wallets.wallet_create(wallet, n_words, use_password, uri, overwrite)
2346
2345
  )
2347
2346
 
2348
2347
  def wallet_balance(
@@ -2873,7 +2872,7 @@ class CLIManager:
2873
2872
  netuid = get_optional_netuid(netuid, all_netuids)
2874
2873
 
2875
2874
  if stake_all and amount:
2876
- err_console.print(
2875
+ print_error(
2877
2876
  "Cannot specify an amount and 'stake-all'. Choose one or the other."
2878
2877
  )
2879
2878
  raise typer.Exit()
@@ -2883,14 +2882,14 @@ class CLIManager:
2883
2882
  raise typer.Exit()
2884
2883
 
2885
2884
  if all_hotkeys and include_hotkeys:
2886
- err_console.print(
2885
+ print_error(
2887
2886
  "You have specified hotkeys to include and also the `--all-hotkeys` flag. The flag"
2888
2887
  "should only be used standalone (to use all hotkeys) or with `--exclude-hotkeys`."
2889
2888
  )
2890
2889
  raise typer.Exit()
2891
2890
 
2892
2891
  if include_hotkeys and exclude_hotkeys:
2893
- err_console.print(
2892
+ print_error(
2894
2893
  "You have specified options for both including and excluding hotkeys. Select one or the other."
2895
2894
  )
2896
2895
  raise typer.Exit()
@@ -2960,24 +2959,24 @@ class CLIManager:
2960
2959
  )
2961
2960
 
2962
2961
  if include_hotkeys:
2963
- included_hotkeys = parse_to_list(
2962
+ include_hotkeys = parse_to_list(
2964
2963
  include_hotkeys,
2965
2964
  str,
2966
2965
  "Hotkeys must be a comma-separated list of ss58s, e.g., `--include-hotkeys 5Grw....,5Grw....`.",
2967
2966
  is_ss58=True,
2968
2967
  )
2969
2968
  else:
2970
- included_hotkeys = []
2969
+ include_hotkeys = []
2971
2970
 
2972
2971
  if exclude_hotkeys:
2973
- excluded_hotkeys = parse_to_list(
2972
+ exclude_hotkeys = parse_to_list(
2974
2973
  exclude_hotkeys,
2975
2974
  str,
2976
2975
  "Hotkeys must be a comma-separated list of ss58s, e.g., `--exclude-hotkeys 5Grw....,5Grw....`.",
2977
2976
  is_ss58=True,
2978
2977
  )
2979
2978
  else:
2980
- excluded_hotkeys = []
2979
+ exclude_hotkeys = []
2981
2980
 
2982
2981
  # TODO: Ask amount for each subnet explicitly if more than one
2983
2982
  if not stake_all and not amount:
@@ -3017,8 +3016,8 @@ class CLIManager:
3017
3016
  amount,
3018
3017
  prompt,
3019
3018
  all_hotkeys,
3020
- included_hotkeys,
3021
- excluded_hotkeys,
3019
+ include_hotkeys,
3020
+ exclude_hotkeys,
3022
3021
  safe_staking,
3023
3022
  rate_tolerance,
3024
3023
  allow_partial_stake,
@@ -3126,32 +3125,32 @@ class CLIManager:
3126
3125
  if interactive and any(
3127
3126
  [hotkey_ss58_address, include_hotkeys, exclude_hotkeys, all_hotkeys]
3128
3127
  ):
3129
- err_console.print(
3128
+ print_error(
3130
3129
  "Interactive mode cannot be used with hotkey selection options like --include-hotkeys, --exclude-hotkeys, --all-hotkeys, or --hotkey."
3131
3130
  )
3132
3131
  raise typer.Exit()
3133
3132
 
3134
3133
  if unstake_all and unstake_all_alpha:
3135
- err_console.print("Cannot specify both unstake-all and unstake-all-alpha.")
3134
+ print_error("Cannot specify both unstake-all and unstake-all-alpha.")
3136
3135
  raise typer.Exit()
3137
3136
 
3138
3137
  if not interactive and not unstake_all and not unstake_all_alpha:
3139
3138
  netuid = get_optional_netuid(netuid, all_netuids)
3140
3139
  if all_hotkeys and include_hotkeys:
3141
- err_console.print(
3140
+ print_error(
3142
3141
  "You have specified hotkeys to include and also the `--all-hotkeys` flag. The flag"
3143
3142
  " should only be used standalone (to use all hotkeys) or with `--exclude-hotkeys`."
3144
3143
  )
3145
3144
  raise typer.Exit()
3146
3145
 
3147
3146
  if include_hotkeys and exclude_hotkeys:
3148
- err_console.print(
3147
+ print_error(
3149
3148
  "You have specified both including and excluding hotkeys options. Select one or the other."
3150
3149
  )
3151
3150
  raise typer.Exit()
3152
3151
 
3153
3152
  if unstake_all and amount:
3154
- err_console.print(
3153
+ print_error(
3155
3154
  "Cannot specify both a specific amount and 'unstake-all'. Choose one or the other."
3156
3155
  )
3157
3156
  raise typer.Exit()
@@ -3212,11 +3211,23 @@ class CLIManager:
3212
3211
  else:
3213
3212
  print_error("Invalid hotkey ss58 address.")
3214
3213
  raise typer.Exit()
3215
- else:
3216
- hotkey_or_ss58 = Prompt.ask(
3217
- "Enter the [blue]hotkey[/blue] name or [blue]ss58 address[/blue] to unstake all from",
3218
- default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
3214
+ elif all_hotkeys:
3215
+ wallet = self.wallet_ask(
3216
+ wallet_name,
3217
+ wallet_path,
3218
+ wallet_hotkey,
3219
+ ask_for=[WO.NAME, WO.PATH],
3219
3220
  )
3221
+ else:
3222
+ if not hotkey_ss58_address and not wallet_hotkey:
3223
+ hotkey_or_ss58 = Prompt.ask(
3224
+ "Enter the [blue]hotkey[/blue] name or [blue]ss58 address[/blue] to unstake all from [dim](or enter 'all' to unstake from all hotkeys)[/dim]",
3225
+ default=self.config.get("wallet_hotkey")
3226
+ or defaults.wallet.hotkey,
3227
+ )
3228
+ else:
3229
+ hotkey_or_ss58 = hotkey_ss58_address or wallet_hotkey
3230
+
3220
3231
  if is_valid_ss58_address(hotkey_or_ss58):
3221
3232
  hotkey_ss58_address = hotkey_or_ss58
3222
3233
  wallet = self.wallet_ask(
@@ -3225,6 +3236,14 @@ class CLIManager:
3225
3236
  wallet_hotkey,
3226
3237
  ask_for=[WO.NAME, WO.PATH],
3227
3238
  )
3239
+ elif hotkey_or_ss58 == "all":
3240
+ all_hotkeys = True
3241
+ wallet = self.wallet_ask(
3242
+ wallet_name,
3243
+ wallet_path,
3244
+ wallet_hotkey,
3245
+ ask_for=[WO.NAME, WO.PATH],
3246
+ )
3228
3247
  else:
3229
3248
  wallet_hotkey = hotkey_or_ss58
3230
3249
  wallet = self.wallet_ask(
@@ -3240,6 +3259,9 @@ class CLIManager:
3240
3259
  subtensor=self.initialize_chain(network),
3241
3260
  hotkey_ss58_address=hotkey_ss58_address,
3242
3261
  unstake_all_alpha=unstake_all_alpha,
3262
+ all_hotkeys=all_hotkeys,
3263
+ include_hotkeys=include_hotkeys,
3264
+ exclude_hotkeys=exclude_hotkeys,
3243
3265
  prompt=prompt,
3244
3266
  )
3245
3267
  )
@@ -3265,24 +3287,20 @@ class CLIManager:
3265
3287
  )
3266
3288
 
3267
3289
  if include_hotkeys:
3268
- included_hotkeys = parse_to_list(
3290
+ include_hotkeys = parse_to_list(
3269
3291
  include_hotkeys,
3270
3292
  str,
3271
3293
  "Hotkeys must be a comma-separated list of ss58s or names, e.g., `--include-hotkeys hk1,hk2`.",
3272
3294
  is_ss58=False,
3273
3295
  )
3274
- else:
3275
- included_hotkeys = []
3276
3296
 
3277
3297
  if exclude_hotkeys:
3278
- excluded_hotkeys = parse_to_list(
3298
+ exclude_hotkeys = parse_to_list(
3279
3299
  exclude_hotkeys,
3280
3300
  str,
3281
3301
  "Hotkeys must be a comma-separated list of ss58s or names, e.g., `--exclude-hotkeys hk3,hk4`.",
3282
3302
  is_ss58=False,
3283
3303
  )
3284
- else:
3285
- excluded_hotkeys = []
3286
3304
 
3287
3305
  return self._run_command(
3288
3306
  remove_stake.unstake(
@@ -3290,8 +3308,8 @@ class CLIManager:
3290
3308
  subtensor=self.initialize_chain(network),
3291
3309
  hotkey_ss58_address=hotkey_ss58_address,
3292
3310
  all_hotkeys=all_hotkeys,
3293
- include_hotkeys=included_hotkeys,
3294
- exclude_hotkeys=excluded_hotkeys,
3311
+ include_hotkeys=include_hotkeys,
3312
+ exclude_hotkeys=exclude_hotkeys,
3295
3313
  amount=amount,
3296
3314
  prompt=prompt,
3297
3315
  interactive=interactive,
@@ -3745,7 +3763,6 @@ class CLIManager:
3745
3763
  [],
3746
3764
  "--proportions",
3747
3765
  "--prop",
3748
- "-p",
3749
3766
  help="Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1)",
3750
3767
  prompt=False,
3751
3768
  ),
@@ -3753,9 +3770,10 @@ class CLIManager:
3753
3770
  wait_for_finalization: bool = Options.wait_for_finalization,
3754
3771
  quiet: bool = Options.quiet,
3755
3772
  verbose: bool = Options.verbose,
3773
+ prompt: bool = Options.prompt,
3756
3774
  ):
3757
3775
  """
3758
- Set child hotkeys on specified subnets.
3776
+ Set child hotkeys on a specified subnet (or all). Overrides currently set children.
3759
3777
 
3760
3778
  Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1.
3761
3779
 
@@ -3792,7 +3810,7 @@ class CLIManager:
3792
3810
  wallet_name,
3793
3811
  wallet_path,
3794
3812
  wallet_hotkey,
3795
- ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
3813
+ ask_for=[WO.NAME, WO.HOTKEY],
3796
3814
  validate=WV.WALLET_AND_HOTKEY,
3797
3815
  )
3798
3816
  return self._run_command(
@@ -3804,6 +3822,7 @@ class CLIManager:
3804
3822
  proportions=proportions,
3805
3823
  wait_for_finalization=wait_for_finalization,
3806
3824
  wait_for_inclusion=wait_for_inclusion,
3825
+ prompt=prompt,
3807
3826
  )
3808
3827
  )
3809
3828
 
@@ -3829,9 +3848,10 @@ class CLIManager:
3829
3848
  wait_for_finalization: bool = Options.wait_for_finalization,
3830
3849
  quiet: bool = Options.quiet,
3831
3850
  verbose: bool = Options.verbose,
3851
+ prompt: bool = Options.prompt,
3832
3852
  ):
3833
3853
  """
3834
- Remove all children hotkeys on a specified subnet.
3854
+ Remove all children hotkeys on a specified subnet (or all).
3835
3855
 
3836
3856
  This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet.
3837
3857
 
@@ -3844,7 +3864,7 @@ class CLIManager:
3844
3864
  wallet_name,
3845
3865
  wallet_path,
3846
3866
  wallet_hotkey,
3847
- ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
3867
+ ask_for=[WO.NAME, WO.HOTKEY],
3848
3868
  validate=WV.WALLET_AND_HOTKEY,
3849
3869
  )
3850
3870
  if all_netuids and netuid:
@@ -3863,6 +3883,7 @@ class CLIManager:
3863
3883
  netuid,
3864
3884
  wait_for_inclusion,
3865
3885
  wait_for_finalization,
3886
+ prompt=prompt,
3866
3887
  )
3867
3888
  )
3868
3889
 
@@ -3918,7 +3939,7 @@ class CLIManager:
3918
3939
  wallet_name,
3919
3940
  wallet_path,
3920
3941
  wallet_hotkey,
3921
- ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
3942
+ ask_for=[WO.NAME, WO.HOTKEY],
3922
3943
  validate=WV.WALLET_AND_HOTKEY,
3923
3944
  )
3924
3945
  if all_netuids and netuid:
@@ -3953,7 +3974,7 @@ class CLIManager:
3953
3974
  param_name: str = typer.Option(
3954
3975
  "", "--param", "--parameter", help="The subnet hyperparameter to set"
3955
3976
  ),
3956
- param_value: str = typer.Option(
3977
+ param_value: Optional[str] = typer.Option(
3957
3978
  "", "--value", help="Value to set the hyperparameter to."
3958
3979
  ),
3959
3980
  quiet: bool = Options.quiet,
@@ -3970,13 +3991,13 @@ class CLIManager:
3970
3991
  """
3971
3992
  self.verbosity_handler(quiet, verbose)
3972
3993
 
3973
- hyperparams = self._run_command(
3974
- sudo.get_hyperparameters(self.initialize_chain(network), netuid),
3975
- exit_early=False,
3976
- )
3977
-
3978
- if not hyperparams:
3979
- raise typer.Exit()
3994
+ if not param_name or not param_value:
3995
+ hyperparams = self._run_command(
3996
+ sudo.get_hyperparameters(self.initialize_chain(network), netuid),
3997
+ exit_early=False,
3998
+ )
3999
+ if not hyperparams:
4000
+ raise typer.Exit()
3980
4001
 
3981
4002
  if not param_name:
3982
4003
  hyperparam_list = [field.name for field in fields(SubnetHyperparameters)]
@@ -3991,10 +4012,23 @@ class CLIManager:
3991
4012
  )
3992
4013
  param_name = hyperparam_list[choice - 1]
3993
4014
 
3994
- if not param_value:
3995
- param_value = Prompt.ask(
3996
- f"Enter the new value for [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{param_name}[/{COLOR_PALETTE['GENERAL']['SUBHEADING']}] in the VALUE column format"
4015
+ if param_name in ["alpha_high", "alpha_low"]:
4016
+ param_name = "alpha_values"
4017
+ low_val = FloatPrompt.ask(
4018
+ "Enter the new value for [dark_orange]alpha_low[/dark_orange]"
4019
+ )
4020
+ high_val = FloatPrompt.ask(
4021
+ "Enter the new value for [dark_orange]alpha_high[/dark_orange]"
3997
4022
  )
4023
+ param_value = f"{low_val},{high_val}"
4024
+
4025
+ if not param_value:
4026
+ if HYPERPARAMS.get(param_name):
4027
+ param_value = Prompt.ask(
4028
+ f"Enter the new value for [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{param_name}[/{COLOR_PALETTE['GENERAL']['SUBHEADING']}] in the VALUE column format"
4029
+ )
4030
+ else:
4031
+ param_value = None
3998
4032
 
3999
4033
  wallet = self.wallet_ask(
4000
4034
  wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
@@ -4060,7 +4094,9 @@ class CLIManager:
4060
4094
  [green]$[/green] btcli sudo proposals
4061
4095
  """
4062
4096
  self.verbosity_handler(quiet, verbose)
4063
- return self._run_command(sudo.proposals(self.initialize_chain(network)))
4097
+ return self._run_command(
4098
+ sudo.proposals(self.initialize_chain(network), verbose)
4099
+ )
4064
4100
 
4065
4101
  def sudo_senate_vote(
4066
4102
  self,
@@ -4438,6 +4474,7 @@ class CLIManager:
4438
4474
  validate=WV.WALLET_AND_HOTKEY,
4439
4475
  )
4440
4476
  identity = prompt_for_subnet_identity(
4477
+ current_identity={},
4441
4478
  subnet_name=subnet_name,
4442
4479
  github_repo=github_repo,
4443
4480
  subnet_contact=subnet_contact,
@@ -4468,6 +4505,118 @@ class CLIManager:
4468
4505
  verbose=verbose,
4469
4506
  )
4470
4507
 
4508
+ def subnets_get_identity(
4509
+ self,
4510
+ network: Optional[list[str]] = Options.network,
4511
+ netuid: int = Options.netuid,
4512
+ quiet: bool = Options.quiet,
4513
+ verbose: bool = Options.verbose,
4514
+ ):
4515
+ """
4516
+ Get the identity information for a subnet.
4517
+
4518
+ This command displays the identity information of a subnet including name, GitHub repo, contact details, etc.
4519
+
4520
+ [green]$[/green] btcli subnets get-identity --netuid 1
4521
+ """
4522
+ self.verbosity_handler(quiet, verbose)
4523
+ return self._run_command(
4524
+ subnets.get_identity(
4525
+ self.initialize_chain(network),
4526
+ netuid,
4527
+ )
4528
+ )
4529
+
4530
+ def subnets_set_identity(
4531
+ self,
4532
+ wallet_name: str = Options.wallet_name,
4533
+ wallet_path: str = Options.wallet_path,
4534
+ wallet_hotkey: str = Options.wallet_hotkey,
4535
+ network: Optional[list[str]] = Options.network,
4536
+ netuid: int = Options.netuid,
4537
+ subnet_name: Optional[str] = typer.Option(
4538
+ None, "--subnet-name", "--name", help="Name of the subnet"
4539
+ ),
4540
+ github_repo: Optional[str] = typer.Option(
4541
+ None, "--github-repo", "--repo", help="GitHub repository URL"
4542
+ ),
4543
+ subnet_contact: Optional[str] = typer.Option(
4544
+ None,
4545
+ "--subnet-contact",
4546
+ "--contact",
4547
+ "--email",
4548
+ help="Contact email for subnet",
4549
+ ),
4550
+ subnet_url: Optional[str] = typer.Option(
4551
+ None, "--subnet-url", "--url", help="Subnet URL"
4552
+ ),
4553
+ discord: Optional[str] = typer.Option(
4554
+ None, "--discord-handle", "--discord", help="Discord handle"
4555
+ ),
4556
+ description: Optional[str] = typer.Option(
4557
+ None, "--description", help="Description"
4558
+ ),
4559
+ additional_info: Optional[str] = typer.Option(
4560
+ None, "--additional-info", help="Additional information"
4561
+ ),
4562
+ prompt: bool = Options.prompt,
4563
+ quiet: bool = Options.quiet,
4564
+ verbose: bool = Options.verbose,
4565
+ ):
4566
+ """
4567
+ Set or update the identity information for a subnet.
4568
+
4569
+ This command allows subnet owners to set or update identity information like name, GitHub repo, contact details, etc.
4570
+
4571
+ [bold]Common Examples:[/bold]
4572
+
4573
+ 1. Interactive subnet identity setting:
4574
+ [green]$[/green] btcli subnets set-identity --netuid 1
4575
+
4576
+ 2. Set subnet identity with specific values:
4577
+ [green]$[/green] btcli subnets set-identity --netuid 1 --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net
4578
+ """
4579
+ self.verbosity_handler(quiet, verbose)
4580
+ wallet = self.wallet_ask(
4581
+ wallet_name,
4582
+ wallet_path,
4583
+ wallet_hotkey,
4584
+ ask_for=[WO.NAME],
4585
+ validate=WV.WALLET,
4586
+ )
4587
+
4588
+ current_identity = self._run_command(
4589
+ subnets.get_identity(
4590
+ self.initialize_chain(network),
4591
+ netuid,
4592
+ f"Current Subnet {netuid}'s Identity",
4593
+ ),
4594
+ exit_early=False,
4595
+ )
4596
+ if current_identity is None:
4597
+ raise typer.Exit()
4598
+
4599
+ identity = prompt_for_subnet_identity(
4600
+ current_identity=current_identity,
4601
+ subnet_name=subnet_name,
4602
+ github_repo=github_repo,
4603
+ subnet_contact=subnet_contact,
4604
+ subnet_url=subnet_url,
4605
+ discord=discord,
4606
+ description=description,
4607
+ additional=additional_info,
4608
+ )
4609
+
4610
+ return self._run_command(
4611
+ subnets.set_identity(
4612
+ wallet,
4613
+ self.initialize_chain(network),
4614
+ netuid,
4615
+ identity,
4616
+ prompt,
4617
+ )
4618
+ )
4619
+
4471
4620
  def subnets_pow_register(
4472
4621
  self,
4473
4622
  wallet_name: Optional[str] = Options.wallet_name,
@@ -4515,6 +4664,7 @@ class CLIManager:
4515
4664
  "-tbp",
4516
4665
  help="Set the number of threads per block for CUDA.",
4517
4666
  ),
4667
+ prompt: bool = Options.prompt,
4518
4668
  ):
4519
4669
  """
4520
4670
  Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW).
@@ -4552,6 +4702,7 @@ class CLIManager:
4552
4702
  use_cuda,
4553
4703
  dev_id,
4554
4704
  threads_per_block,
4705
+ prompt=prompt,
4555
4706
  )
4556
4707
  )
4557
4708
 
@@ -4582,7 +4733,7 @@ class CLIManager:
4582
4733
  wallet_name,
4583
4734
  wallet_path,
4584
4735
  wallet_hotkey,
4585
- ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
4736
+ ask_for=[WO.NAME, WO.HOTKEY],
4586
4737
  validate=WV.WALLET_AND_HOTKEY,
4587
4738
  )
4588
4739
  return self._run_command(
@@ -4717,6 +4868,7 @@ class CLIManager:
4717
4868
  ),
4718
4869
  quiet: bool = Options.quiet,
4719
4870
  verbose: bool = Options.verbose,
4871
+ prompt: bool = Options.prompt,
4720
4872
  ):
4721
4873
  """
4722
4874
  Reveal weights for a specific subnet.
@@ -4788,6 +4940,7 @@ class CLIManager:
4788
4940
  weights,
4789
4941
  salt,
4790
4942
  __version_as_int__,
4943
+ prompt=prompt,
4791
4944
  )
4792
4945
  )
4793
4946
 
@@ -4813,6 +4966,7 @@ class CLIManager:
4813
4966
  ),
4814
4967
  quiet: bool = Options.quiet,
4815
4968
  verbose: bool = Options.verbose,
4969
+ prompt: bool = Options.prompt,
4816
4970
  ):
4817
4971
  """
4818
4972
 
@@ -4883,6 +5037,7 @@ class CLIManager:
4883
5037
  weights,
4884
5038
  salt,
4885
5039
  __version_as_int__,
5040
+ prompt=prompt,
4886
5041
  )
4887
5042
  )
4888
5043