Skip to content

Commit 07c788d

Browse files
authored
Merge pull request #449 from opentensor/release/9.4.1
Release/9.4.1
2 parents 6b3a711 + 4634592 commit 07c788d

File tree

11 files changed

+154
-82
lines changed

11 files changed

+154
-82
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 9.4.1 /2025-04-17
4+
5+
## What's Changed
6+
* Fixes `test_staking_sudo` setting `max_burn` by @thewhaleking in https://github.com/opentensor/btcli/pull/440
7+
* Fixes Error Formatter by @thewhaleking in https://github.com/opentensor/btcli/pull/439
8+
* Pulls shares in a gather rather than one-at-a-time by @thewhaleking in https://github.com/opentensor/btcli/pull/438
9+
* Pull emission start schedule dynamically by @thewhaleking in https://github.com/opentensor/btcli/pull/442
10+
* Lengthen default era period + rename "era" to "period" by @thewhaleking in https://github.com/opentensor/btcli/pull/443
11+
* docs: fixed redundant "from" by @mdqst in https://github.com/opentensor/btcli/pull/429
12+
* click version 8.2.0 broken by @thewhaleking in https://github.com/opentensor/btcli/pull/447
13+
* JSON Name shadowing bug by @thewhaleking in https://github.com/opentensor/btcli/pull/445
14+
* Stop Parsing, Start Asking by @thewhaleking in https://github.com/opentensor/btcli/pull/446
15+
16+
**Full Changelog**: https://github.com/opentensor/btcli/compare/v9.4.0...v9.4.1
17+
318
## 9.4.0 /2025-04-17
419

520
## What's Changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Installation steps are described below. For a full documentation on how to use `
3939

4040
## Install on macOS and Linux
4141

42-
You can install `btcli` on your local machine directly from source, or from from PyPI. **Make sure you verify your installation after you install**:
42+
You can install `btcli` on your local machine directly from source, or from PyPI. **Make sure you verify your installation after you install**:
4343

4444

4545
### Install from PyPI

bittensor_cli/cli.py

Lines changed: 75 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,11 @@ class Options:
293293
"--json-out",
294294
help="Outputs the result of the command as JSON.",
295295
)
296-
era: int = typer.Option(
297-
3, help="Length (in blocks) for which the transaction should be valid."
296+
period: int = typer.Option(
297+
16,
298+
"--period",
299+
"--era",
300+
help="Length (in blocks) for which the transaction should be valid.",
298301
)
299302

300303

@@ -436,36 +439,49 @@ def parse_mnemonic(mnemonic: str) -> str:
436439
def get_creation_data(
437440
mnemonic: Optional[str],
438441
seed: Optional[str],
439-
json: Optional[str],
442+
json_path: Optional[str],
440443
json_password: Optional[str],
441444
) -> tuple[str, str, str, str]:
442445
"""
443446
Determines which of the key creation elements have been supplied, if any. If None have been supplied,
444447
prompts to user, and determines what they've supplied. Returns all elements in a tuple.
445448
"""
446-
if not mnemonic and not seed and not json:
447-
prompt_answer = Prompt.ask(
448-
"Enter the mnemonic, or the seed hex string, or the location of the JSON file."
449+
if not mnemonic and not seed and not json_path:
450+
choices = {
451+
1: "mnemonic",
452+
2: "seed hex string",
453+
3: "path to JSON File",
454+
}
455+
type_answer = IntPrompt.ask(
456+
"Select one of the following to enter\n"
457+
f"[{COLORS.G.HINT}][1][/{COLORS.G.HINT}] Mnemonic\n"
458+
f"[{COLORS.G.HINT}][2][/{COLORS.G.HINT}] Seed hex string\n"
459+
f"[{COLORS.G.HINT}][3][/{COLORS.G.HINT}] Path to JSON File\n",
460+
choices=["1", "2", "3"],
461+
show_choices=False,
449462
)
450-
if prompt_answer.startswith("0x"):
463+
prompt_answer = Prompt.ask(f"Please enter your {choices[type_answer]}")
464+
if type_answer == 1:
465+
mnemonic = prompt_answer
466+
elif type_answer == 2:
451467
seed = prompt_answer
452-
elif len(prompt_answer.split(" ")) > 1:
453-
mnemonic = parse_mnemonic(prompt_answer)
454-
else:
455-
json = prompt_answer
468+
if seed.startswith("0x"):
469+
seed = seed[2:]
470+
elif type_answer == 3:
471+
json_path = prompt_answer
456472
elif mnemonic:
457473
mnemonic = parse_mnemonic(mnemonic)
458474

459-
if json:
460-
if not os.path.exists(json):
461-
print_error(f"The JSON file '{json}' does not exist.")
475+
if json_path:
476+
if not os.path.exists(json_path):
477+
print_error(f"The JSON file '{json_path}' does not exist.")
462478
raise typer.Exit()
463479

464-
if json and not json_password:
480+
if json_path and not json_password:
465481
json_password = Prompt.ask(
466482
"Enter the backup password for JSON file.", password=True
467483
)
468-
return mnemonic, seed, json, json_password
484+
return mnemonic, seed, json_path, json_password
469485

470486

471487
def config_selector(conf: dict, title: str):
@@ -1792,7 +1808,7 @@ def wallet_transfer(
17921808
transfer_all: bool = typer.Option(
17931809
False, "--all", prompt=False, help="Transfer all available balance."
17941810
),
1795-
era: int = Options.era,
1811+
period: int = Options.period,
17961812
wallet_name: str = Options.wallet_name,
17971813
wallet_path: str = Options.wallet_path,
17981814
wallet_hotkey: str = Options.wallet_hotkey,
@@ -1847,7 +1863,7 @@ def wallet_transfer(
18471863
destination=destination_ss58_address,
18481864
amount=amount,
18491865
transfer_all=transfer_all,
1850-
era=era,
1866+
era=period,
18511867
prompt=prompt,
18521868
json_output=json_output,
18531869
)
@@ -2090,7 +2106,7 @@ def wallet_regen_coldkey(
20902106
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
20912107
mnemonic: Optional[str] = Options.mnemonic,
20922108
seed: Optional[str] = Options.seed,
2093-
json: Optional[str] = Options.json,
2109+
json_path: Optional[str] = Options.json,
20942110
json_password: Optional[str] = Options.json_password,
20952111
use_password: Optional[bool] = Options.use_password,
20962112
overwrite: bool = Options.overwrite,
@@ -2130,15 +2146,15 @@ def wallet_regen_coldkey(
21302146

21312147
wallet = Wallet(wallet_name, wallet_hotkey, wallet_path)
21322148

2133-
mnemonic, seed, json, json_password = get_creation_data(
2134-
mnemonic, seed, json, json_password
2149+
mnemonic, seed, json_path, json_password = get_creation_data(
2150+
mnemonic, seed, json_path, json_password
21352151
)
21362152
return self._run_command(
21372153
wallets.regen_coldkey(
21382154
wallet,
21392155
mnemonic,
21402156
seed,
2141-
json,
2157+
json_path,
21422158
json_password,
21432159
use_password,
21442160
overwrite,
@@ -2214,7 +2230,7 @@ def wallet_regen_hotkey(
22142230
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
22152231
mnemonic: Optional[str] = Options.mnemonic,
22162232
seed: Optional[str] = Options.seed,
2217-
json: Optional[str] = Options.json,
2233+
json_path: Optional[str] = Options.json,
22182234
json_password: Optional[str] = Options.json_password,
22192235
use_password: bool = typer.Option(
22202236
False, # Overriden to False
@@ -2250,15 +2266,15 @@ def wallet_regen_hotkey(
22502266
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
22512267
validate=WV.WALLET,
22522268
)
2253-
mnemonic, seed, json, json_password = get_creation_data(
2254-
mnemonic, seed, json, json_password
2269+
mnemonic, seed, json_path, json_password = get_creation_data(
2270+
mnemonic, seed, json_path, json_password
22552271
)
22562272
return self._run_command(
22572273
wallets.regen_hotkey(
22582274
wallet,
22592275
mnemonic,
22602276
seed,
2261-
json,
2277+
json_path,
22622278
json_password,
22632279
use_password,
22642280
overwrite,
@@ -3190,7 +3206,7 @@ def stake_add(
31903206
rate_tolerance: Optional[float] = Options.rate_tolerance,
31913207
safe_staking: Optional[bool] = Options.safe_staking,
31923208
allow_partial_stake: Optional[bool] = Options.allow_partial_stake,
3193-
era: int = Options.era,
3209+
period: int = Options.period,
31943210
prompt: bool = Options.prompt,
31953211
quiet: bool = Options.quiet,
31963212
verbose: bool = Options.verbose,
@@ -3386,7 +3402,7 @@ def stake_add(
33863402
rate_tolerance,
33873403
allow_partial_stake,
33883404
json_output,
3389-
era,
3405+
period,
33903406
)
33913407
)
33923408

@@ -3438,7 +3454,7 @@ def stake_remove(
34383454
rate_tolerance: Optional[float] = Options.rate_tolerance,
34393455
safe_staking: Optional[bool] = Options.safe_staking,
34403456
allow_partial_stake: Optional[bool] = Options.allow_partial_stake,
3441-
era: int = Options.era,
3457+
period: int = Options.period,
34423458
prompt: bool = Options.prompt,
34433459
interactive: bool = typer.Option(
34443460
False,
@@ -3631,7 +3647,7 @@ def stake_remove(
36313647
exclude_hotkeys=exclude_hotkeys,
36323648
prompt=prompt,
36333649
json_output=json_output,
3634-
era=era,
3650+
era=period,
36353651
)
36363652
)
36373653
elif (
@@ -3687,7 +3703,7 @@ def stake_remove(
36873703
rate_tolerance=rate_tolerance,
36883704
allow_partial_stake=allow_partial_stake,
36893705
json_output=json_output,
3690-
era=era,
3706+
era=period,
36913707
)
36923708
)
36933709

@@ -3715,7 +3731,7 @@ def stake_move(
37153731
stake_all: bool = typer.Option(
37163732
False, "--stake-all", "--all", help="Stake all", prompt=False
37173733
),
3718-
era: int = Options.era,
3734+
period: int = Options.period,
37193735
prompt: bool = Options.prompt,
37203736
quiet: bool = Options.quiet,
37213737
verbose: bool = Options.verbose,
@@ -3845,7 +3861,7 @@ def stake_move(
38453861
destination_hotkey=destination_hotkey,
38463862
amount=amount,
38473863
stake_all=stake_all,
3848-
era=era,
3864+
era=period,
38493865
interactive_selection=interactive_selection,
38503866
prompt=prompt,
38513867
)
@@ -3886,7 +3902,7 @@ def stake_transfer(
38863902
stake_all: bool = typer.Option(
38873903
False, "--stake-all", "--all", help="Stake all", prompt=False
38883904
),
3889-
era: int = Options.era,
3905+
period: int = Options.period,
38903906
prompt: bool = Options.prompt,
38913907
quiet: bool = Options.quiet,
38923908
verbose: bool = Options.verbose,
@@ -4008,7 +4024,7 @@ def stake_transfer(
40084024
dest_netuid=dest_netuid,
40094025
dest_coldkey_ss58=dest_ss58,
40104026
amount=amount,
4011-
era=era,
4027+
era=period,
40124028
interactive_selection=interactive_selection,
40134029
stake_all=stake_all,
40144030
prompt=prompt,
@@ -4050,7 +4066,7 @@ def stake_swap(
40504066
"--all",
40514067
help="Swap all available stake",
40524068
),
4053-
era: int = Options.era,
4069+
period: int = Options.period,
40544070
prompt: bool = Options.prompt,
40554071
wait_for_inclusion: bool = Options.wait_for_inclusion,
40564072
wait_for_finalization: bool = Options.wait_for_finalization,
@@ -4115,7 +4131,7 @@ def stake_swap(
41154131
destination_netuid=dest_netuid,
41164132
amount=amount,
41174133
swap_all=swap_all,
4118-
era=era,
4134+
era=period,
41194135
interactive_selection=interactive_selection,
41204136
prompt=prompt,
41214137
wait_for_inclusion=wait_for_inclusion,
@@ -4430,6 +4446,7 @@ def sudo_set(
44304446
param_value: Optional[str] = typer.Option(
44314447
"", "--value", help="Value to set the hyperparameter to."
44324448
),
4449+
prompt: bool = Options.prompt,
44334450
quiet: bool = Options.quiet,
44344451
verbose: bool = Options.verbose,
44354452
json_output: bool = Options.json_output,
@@ -4454,6 +4471,11 @@ def sudo_set(
44544471
raise typer.Exit()
44554472

44564473
if not param_name:
4474+
if not prompt:
4475+
err_console.print(
4476+
"Param name not supplied with `--no-prompt` flag. Cannot continue"
4477+
)
4478+
return False
44574479
hyperparam_list = [field.name for field in fields(SubnetHyperparameters)]
44584480
console.print("Available hyperparameters:\n")
44594481
for idx, param in enumerate(hyperparam_list, start=1):
@@ -4467,6 +4489,11 @@ def sudo_set(
44674489
param_name = hyperparam_list[choice - 1]
44684490

44694491
if param_name in ["alpha_high", "alpha_low"]:
4492+
if not prompt:
4493+
err_console.print(
4494+
"`alpha_high` and `alpha_low` values cannot be set with `--no-prompt`"
4495+
)
4496+
return False
44704497
param_name = "alpha_values"
44714498
low_val = FloatPrompt.ask(
44724499
"Enter the new value for [dark_orange]alpha_low[/dark_orange]"
@@ -4477,6 +4504,11 @@ def sudo_set(
44774504
param_value = f"{low_val},{high_val}"
44784505

44794506
if not param_value:
4507+
if not prompt:
4508+
err_console.print(
4509+
"Param value not supplied with `--no-prompt` flag. Cannot continue."
4510+
)
4511+
return False
44804512
if HYPERPARAMS.get(param_name):
44814513
param_value = Prompt.ask(
44824514
f"Enter the new value for [{COLORS.G.SUBHEAD}]{param_name}[/{COLORS.G.SUBHEAD}] "
@@ -4495,6 +4527,7 @@ def sudo_set(
44954527
netuid,
44964528
param_name,
44974529
param_value,
4530+
prompt,
44984531
json_output,
44994532
)
45004533
)
@@ -5258,10 +5291,12 @@ def subnets_register(
52585291
wallet_hotkey: str = Options.wallet_hotkey,
52595292
network: Optional[list[str]] = Options.network,
52605293
netuid: int = Options.netuid,
5261-
era: Optional[
5294+
period: Optional[
52625295
int
5263-
] = typer.Option( # Should not be Options.era bc this needs to be an Optional[int]
5296+
] = typer.Option( # Should not be Options.period bc this needs to be an Optional[int]
52645297
None,
5298+
"--period",
5299+
"--era",
52655300
help="Length (in blocks) for which the transaction should be valid. Note that it is possible that if you "
52665301
"use an era for this transaction that you may pay a different fee to register than the one stated.",
52675302
),
@@ -5294,7 +5329,7 @@ def subnets_register(
52945329
wallet,
52955330
self.initialize_chain(network),
52965331
netuid,
5297-
era,
5332+
period,
52985333
json_output,
52995334
prompt,
53005335
)

bittensor_cli/src/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class Constants:
3838
"test": "0x8f9cf856bf558a14440e75569c9e58594757048d7b3a84b5d25f6bd978263105",
3939
}
4040
delegates_detail_url = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json"
41-
emission_start_schedule = 7 * 24 * 60 * 60 / 12 # 7 days
4241

4342

4443
@dataclass
@@ -640,7 +639,7 @@ class WalletValidationTypes(Enum):
640639
"activity_cutoff": ("sudo_set_activity_cutoff", False),
641640
"target_regs_per_interval": ("sudo_set_target_registrations_per_interval", True),
642641
"min_burn": ("sudo_set_min_burn", True),
643-
"max_burn": ("sudo_set_max_burn", False),
642+
"max_burn": ("sudo_set_max_burn", True),
644643
"bonds_moving_avg": ("sudo_set_bonds_moving_average", False),
645644
"max_regs_per_block": ("sudo_set_max_registrations_per_block", True),
646645
"serving_rate_limit": ("sudo_set_serving_rate_limit", False),

0 commit comments

Comments
 (0)