bittensor-cli 9.2.0__py3-none-any.whl → 9.3.0__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.
@@ -1,8 +1,9 @@
1
1
  import asyncio
2
+ import json
2
3
  from typing import Optional
3
4
 
4
5
  from bittensor_wallet import Wallet
5
- from rich.prompt import Confirm, Prompt, IntPrompt
6
+ from rich.prompt import Confirm, IntPrompt, FloatPrompt
6
7
  from rich.table import Table
7
8
  from rich.text import Text
8
9
  from async_substrate_interface.errors import SubstrateRequestException
@@ -19,6 +20,7 @@ from bittensor_cli.src.bittensor.utils import (
19
20
  is_valid_ss58_address,
20
21
  format_error_message,
21
22
  unlock_key,
23
+ json_console,
22
24
  )
23
25
 
24
26
 
@@ -28,24 +30,22 @@ async def get_childkey_completion_block(
28
30
  """
29
31
  Calculates the block at which the childkey set request will complete
30
32
  """
33
+ bh = await subtensor.substrate.get_chain_head()
31
34
  blocks_since_last_step_query = subtensor.query(
32
- "SubtensorModule",
33
- "BlocksSinceLastStep",
34
- params=[netuid],
35
+ "SubtensorModule", "BlocksSinceLastStep", params=[netuid], block_hash=bh
35
36
  )
36
37
  tempo_query = subtensor.get_hyperparameter(
37
- param_name="Tempo",
38
- netuid=netuid,
38
+ param_name="Tempo", netuid=netuid, block_hash=bh
39
39
  )
40
40
  block_number, blocks_since_last_step, tempo = await asyncio.gather(
41
- subtensor.substrate.get_block_number(),
41
+ subtensor.substrate.get_block_number(block_hash=bh),
42
42
  blocks_since_last_step_query,
43
43
  tempo_query,
44
44
  )
45
- cooldown = block_number + 1
45
+ cooldown = block_number + 7200
46
46
  blocks_left_in_tempo = tempo - blocks_since_last_step
47
47
  next_tempo = block_number + blocks_left_in_tempo
48
- next_epoch_after_cooldown = (cooldown - next_tempo) % tempo + cooldown
48
+ next_epoch_after_cooldown = (cooldown - next_tempo) % (tempo + 1) + cooldown
49
49
  return block_number, next_epoch_after_cooldown
50
50
 
51
51
 
@@ -84,7 +84,7 @@ async def set_children_extrinsic(
84
84
  if prompt:
85
85
  if all_revoked:
86
86
  if not Confirm.ask(
87
- f"Do you want to revoke all children hotkeys for hotkey {hotkey}?"
87
+ f"Do you want to revoke all children hotkeys for hotkey {hotkey} on netuid {netuid}?"
88
88
  ):
89
89
  return False, "Operation Cancelled"
90
90
  else:
@@ -134,17 +134,9 @@ async def set_children_extrinsic(
134
134
  console.print(":white_heavy_check_mark: [green]Included[/green]")
135
135
  if wait_for_finalization:
136
136
  console.print(":white_heavy_check_mark: [green]Finalized[/green]")
137
- # bittensor.logging.success(
138
- # prefix=operation,
139
- # suffix="<green>Finalized: </green>" + str(success),
140
- # )
141
137
  return True, f"Successfully {operation.lower()} and Finalized."
142
138
  else:
143
139
  err_console.print(f":cross_mark: [red]Failed[/red]: {error_message}")
144
- # bittensor.logging.warning(
145
- # prefix=operation,
146
- # suffix="<red>Failed: </red>" + str(error_message),
147
- # )
148
140
  return False, error_message
149
141
 
150
142
 
@@ -503,6 +495,7 @@ async def set_children(
503
495
  wait_for_inclusion: bool = True,
504
496
  wait_for_finalization: bool = True,
505
497
  prompt: bool = True,
498
+ json_output: bool = False,
506
499
  ):
507
500
  """Set children hotkeys."""
508
501
  # Validate children SS58 addresses
@@ -523,6 +516,7 @@ async def set_children(
523
516
  f"Proposed sum of proportions is {total_proposed}."
524
517
  )
525
518
  children_with_proportions = list(zip(proportions, children))
519
+ successes = {}
526
520
  if netuid is not None:
527
521
  success, message = await set_children_extrinsic(
528
522
  subtensor=subtensor,
@@ -534,12 +528,20 @@ async def set_children(
534
528
  wait_for_inclusion=wait_for_inclusion,
535
529
  wait_for_finalization=wait_for_finalization,
536
530
  )
531
+ successes[netuid] = {
532
+ "success": success,
533
+ "error": message,
534
+ "completion_block": None,
535
+ "set_block": None,
536
+ }
537
537
  # Result
538
538
  if success:
539
539
  if wait_for_inclusion and wait_for_finalization:
540
540
  current_block, completion_block = await get_childkey_completion_block(
541
541
  subtensor, netuid
542
542
  )
543
+ successes[netuid]["completion_block"] = completion_block
544
+ successes[netuid]["set_block"] = current_block
543
545
  console.print(
544
546
  f"Your childkey request has been submitted. It will be completed around block {completion_block}. "
545
547
  f"The current block is {current_block}"
@@ -558,7 +560,7 @@ async def set_children(
558
560
  if netuid_ == 0: # dont include root network
559
561
  continue
560
562
  console.print(f"Setting children on netuid {netuid_}.")
561
- await set_children_extrinsic(
563
+ success, message = await set_children_extrinsic(
562
564
  subtensor=subtensor,
563
565
  wallet=wallet,
564
566
  netuid=netuid_,
@@ -571,6 +573,12 @@ async def set_children(
571
573
  current_block, completion_block = await get_childkey_completion_block(
572
574
  subtensor, netuid_
573
575
  )
576
+ successes[netuid_] = {
577
+ "success": success,
578
+ "error": message,
579
+ "completion_block": completion_block,
580
+ "set_block": current_block,
581
+ }
574
582
  console.print(
575
583
  f"Your childkey request for netuid {netuid_} has been submitted. It will be completed around "
576
584
  f"block {completion_block}. The current block is {current_block}."
@@ -578,6 +586,8 @@ async def set_children(
578
586
  console.print(
579
587
  ":white_heavy_check_mark: [green]Sent set children request for all subnets.[/green]"
580
588
  )
589
+ if json_output:
590
+ json_console.print(json.dumps(successes))
581
591
 
582
592
 
583
593
  async def revoke_children(
@@ -587,11 +597,13 @@ async def revoke_children(
587
597
  wait_for_inclusion: bool = True,
588
598
  wait_for_finalization: bool = True,
589
599
  prompt: bool = True,
600
+ json_output: bool = False,
590
601
  ):
591
602
  """
592
603
  Revokes the children hotkeys associated with a given network identifier (netuid).
593
604
  """
594
- if netuid:
605
+ dict_output = {}
606
+ if netuid is not None:
595
607
  success, message = await set_children_extrinsic(
596
608
  subtensor=subtensor,
597
609
  wallet=wallet,
@@ -602,13 +614,23 @@ async def revoke_children(
602
614
  wait_for_inclusion=wait_for_inclusion,
603
615
  wait_for_finalization=wait_for_finalization,
604
616
  )
617
+ dict_output[netuid] = {
618
+ "success": success,
619
+ "error": message,
620
+ "set_block": None,
621
+ "completion_block": None,
622
+ }
605
623
 
606
624
  # Result
607
625
  if success:
608
- if wait_for_finalization and wait_for_inclusion:
609
- await get_children(wallet, subtensor, netuid)
626
+ current_block, completion_block = await get_childkey_completion_block(
627
+ subtensor, netuid
628
+ )
629
+ dict_output[netuid]["completion_block"] = completion_block
630
+ dict_output[netuid]["set_block"] = current_block
610
631
  console.print(
611
- ":white_heavy_check_mark: [green]Revoked children hotkeys.[/green]"
632
+ f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid} has been submitted. "
633
+ f"It will be completed around block {completion_block}. The current block is {current_block}"
612
634
  )
613
635
  else:
614
636
  console.print(
@@ -617,11 +639,11 @@ async def revoke_children(
617
639
  else:
618
640
  # revoke children from ALL netuids
619
641
  netuids = await subtensor.get_all_subnet_netuids()
620
- for netuid in netuids:
621
- if netuid == 0: # dont include root network
642
+ for netuid_ in netuids:
643
+ if netuid_ == 0: # dont include root network
622
644
  continue
623
- console.print(f"Revoking children from netuid {netuid}.")
624
- await set_children_extrinsic(
645
+ console.print(f"Revoking children from netuid {netuid_}.")
646
+ success, message = await set_children_extrinsic(
625
647
  subtensor=subtensor,
626
648
  wallet=wallet,
627
649
  netuid=netuid,
@@ -631,9 +653,29 @@ async def revoke_children(
631
653
  wait_for_inclusion=True,
632
654
  wait_for_finalization=False,
633
655
  )
634
- console.print(
635
- ":white_heavy_check_mark: [green]Sent revoke children command. Finalization may take a few minutes.[/green]"
636
- )
656
+ dict_output[netuid_] = {
657
+ "success": success,
658
+ "error": message,
659
+ "set_block": None,
660
+ "completion_block": None,
661
+ }
662
+ if success:
663
+ current_block, completion_block = await get_childkey_completion_block(
664
+ subtensor, netuid_
665
+ )
666
+ dict_output[netuid_]["completion_block"] = completion_block
667
+ dict_output[netuid_]["set_block"] = current_block
668
+ console.print(
669
+ f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid_} has been "
670
+ f"submitted. It will be completed around block {completion_block}. The current block "
671
+ f"is {current_block}"
672
+ )
673
+ else:
674
+ err_console.print(
675
+ f"Childkey revocation failed for netuid {netuid_}: {message}."
676
+ )
677
+ if json_output:
678
+ json_console.print(json.dumps(dict_output))
637
679
 
638
680
 
639
681
  async def childkey_take(
@@ -645,8 +687,13 @@ async def childkey_take(
645
687
  wait_for_inclusion: bool = True,
646
688
  wait_for_finalization: bool = True,
647
689
  prompt: bool = True,
648
- ):
649
- """Get or Set childkey take."""
690
+ ) -> list[tuple[Optional[int], bool]]:
691
+ """
692
+ Get or Set childkey take.
693
+
694
+ Returns:
695
+ List of (netuid, success) for specified netuid (or all) and their success in setting take
696
+ """
650
697
 
651
698
  def validate_take_value(take_value: float) -> bool:
652
699
  if not (0 <= take_value <= 0.18):
@@ -656,20 +703,7 @@ async def childkey_take(
656
703
  return False
657
704
  return True
658
705
 
659
- def print_all_takes(takes: list[tuple[int, float]], ss58: str):
660
- """Print table with netuids and Takes"""
661
- table = Table(
662
- title=f"Current Child Takes for [bright_magenta]{ss58}[/bright_magenta]"
663
- )
664
- table.add_column("Netuid", justify="center", style="cyan")
665
- table.add_column("Take (%)", justify="right", style="magenta")
666
-
667
- for take_netuid, take_value in takes:
668
- table.add_row(str(take_netuid), f"{take_value:.2f}%")
669
-
670
- console.print(table)
671
-
672
- async def display_chk_take(ss58, take_netuid):
706
+ async def display_chk_take(ss58, take_netuid) -> float:
673
707
  """Print single key take for hotkey and netuid"""
674
708
  chk_take = await get_childkey_take(
675
709
  subtensor=subtensor, netuid=take_netuid, hotkey=ss58
@@ -680,6 +714,7 @@ async def childkey_take(
680
714
  console.print(
681
715
  f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {take_netuid}."
682
716
  )
717
+ return chk_take
683
718
 
684
719
  async def chk_all_subnets(ss58):
685
720
  """Aggregate data for childkey take from all subnets"""
@@ -694,10 +729,18 @@ async def childkey_take(
694
729
  if curr_take is not None:
695
730
  take_value = u16_to_float(curr_take)
696
731
  takes.append((subnet, take_value * 100))
732
+ table = Table(
733
+ title=f"Current Child Takes for [bright_magenta]{ss58}[/bright_magenta]"
734
+ )
735
+ table.add_column("Netuid", justify="center", style="cyan")
736
+ table.add_column("Take (%)", justify="right", style="magenta")
697
737
 
698
- print_all_takes(takes, ss58)
738
+ for take_netuid, take_value in takes:
739
+ table.add_row(str(take_netuid), f"{take_value:.2f}%")
740
+
741
+ console.print(table)
699
742
 
700
- async def set_chk_take_subnet(subnet, chk_take):
743
+ async def set_chk_take_subnet(subnet: int, chk_take: float) -> bool:
701
744
  """Set the childkey take for a single subnet"""
702
745
  success, message = await set_childkey_take_extrinsic(
703
746
  subtensor=subtensor,
@@ -715,13 +758,17 @@ async def childkey_take(
715
758
  console.print(
716
759
  f"The childkey take for {wallet.hotkey.ss58_address} is now set to {take * 100:.2f}%."
717
760
  )
761
+ return True
718
762
  else:
719
763
  console.print(
720
764
  f":cross_mark:[red] Unable to set childkey take.[/red] {message}"
721
765
  )
766
+ return False
722
767
 
723
768
  # Print childkey take for other user and return (dont offer to change take rate)
724
- if hotkey and hotkey != wallet.hotkey.ss58_address:
769
+ if not hotkey or hotkey == wallet.hotkey.ss58_address:
770
+ hotkey = wallet.hotkey.ss58_address
771
+ if hotkey != wallet.hotkey.ss58_address or not take:
725
772
  # display childkey take for other users
726
773
  if netuid:
727
774
  await display_chk_take(hotkey, netuid)
@@ -729,70 +776,64 @@ async def childkey_take(
729
776
  console.print(
730
777
  f"Hotkey {hotkey} not associated with wallet {wallet.name}."
731
778
  )
732
- return
779
+ return [(netuid, False)]
733
780
  else:
734
- # show childhotkey take on all subnets
781
+ # show child hotkey take on all subnets
735
782
  await chk_all_subnets(hotkey)
736
783
  if take:
737
784
  console.print(
738
785
  f"Hotkey {hotkey} not associated with wallet {wallet.name}."
739
786
  )
740
- return
787
+ return [(netuid, False)]
741
788
 
742
789
  # Validate child SS58 addresses
743
790
  if not take:
744
- # print current Take, ask if change
745
- if netuid:
746
- await display_chk_take(wallet.hotkey.ss58_address, netuid)
747
- else:
748
- # print take from all netuids
749
- await chk_all_subnets(wallet.hotkey.ss58_address)
750
-
751
791
  if not Confirm.ask("Would you like to change the child take?"):
752
- return
753
- new_take_str = Prompt.ask("Enter the new take value (between 0 and 0.18)")
754
- try:
755
- new_take_value = float(new_take_str)
756
- if not validate_take_value(new_take_value):
757
- return
758
- except ValueError:
759
- err_console.print(
760
- ":cross_mark:[red] Invalid input. Please enter a number between 0 and 0.18.[/red]"
792
+ return [(netuid, False)]
793
+ new_take_value = -1.0
794
+ while not validate_take_value(new_take_value):
795
+ new_take_value = FloatPrompt.ask(
796
+ "Enter the new take value (between 0 and 0.18)"
761
797
  )
762
- return
763
798
  take = new_take_value
764
799
  else:
765
800
  if not validate_take_value(take):
766
- return
801
+ return [(netuid, False)]
767
802
 
768
803
  if netuid:
769
- await set_chk_take_subnet(subnet=netuid, chk_take=take)
770
- return
804
+ return [(netuid, await set_chk_take_subnet(subnet=netuid, chk_take=take))]
771
805
  else:
772
806
  new_take_netuids = IntPrompt.ask(
773
807
  "Enter netuid (leave blank for all)", default=None, show_default=True
774
808
  )
775
809
 
776
810
  if new_take_netuids:
777
- await set_chk_take_subnet(subnet=new_take_netuids, chk_take=take)
778
- return
811
+ return [
812
+ (
813
+ new_take_netuids,
814
+ await set_chk_take_subnet(subnet=new_take_netuids, chk_take=take),
815
+ )
816
+ ]
779
817
 
780
818
  else:
781
819
  netuids = await subtensor.get_all_subnet_netuids()
782
- for netuid in netuids:
783
- if netuid == 0:
820
+ output_list = []
821
+ for netuid_ in netuids:
822
+ if netuid_ == 0:
784
823
  continue
785
- console.print(f"Sending to netuid {netuid} take of {take * 100:.2f}%")
786
- await set_childkey_take_extrinsic(
824
+ console.print(f"Sending to netuid {netuid_} take of {take * 100:.2f}%")
825
+ result = await set_childkey_take_extrinsic(
787
826
  subtensor=subtensor,
788
827
  wallet=wallet,
789
- netuid=netuid,
828
+ netuid=netuid_,
790
829
  hotkey=wallet.hotkey.ss58_address,
791
830
  take=take,
792
831
  prompt=prompt,
793
832
  wait_for_inclusion=True,
794
833
  wait_for_finalization=False,
795
834
  )
835
+ output_list.append((netuid_, result))
796
836
  console.print(
797
837
  f":white_heavy_check_mark: [green]Sent childkey take of {take * 100:.2f}% to all subnets.[/green]"
798
838
  )
839
+ return output_list
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
-
2
+ import json
3
+ from collections import defaultdict
3
4
  from typing import TYPE_CHECKING, Optional
4
5
 
5
6
  from bittensor_wallet import Wallet
@@ -18,6 +19,7 @@ from bittensor_cli.src.bittensor.utils import (
18
19
  print_error,
19
20
  millify_tao,
20
21
  get_subnet_name,
22
+ json_console,
21
23
  )
22
24
 
23
25
  if TYPE_CHECKING:
@@ -31,6 +33,7 @@ async def stake_list(
31
33
  live: bool = False,
32
34
  verbose: bool = False,
33
35
  prompt: bool = False,
36
+ json_output: bool = False,
34
37
  ):
35
38
  coldkey_address = coldkey_ss58 if coldkey_ss58 else wallet.coldkeypub.ss58_address
36
39
 
@@ -152,6 +155,7 @@ async def stake_list(
152
155
  reverse=True,
153
156
  )
154
157
  sorted_substakes = root_stakes + other_stakes
158
+ substakes_values = []
155
159
  for substake_ in sorted_substakes:
156
160
  netuid = substake_.netuid
157
161
  pool = dynamic_info[netuid]
@@ -195,7 +199,8 @@ async def stake_list(
195
199
  if not verbose
196
200
  else f"{substake_.stake.tao:,.4f}"
197
201
  )
198
- subnet_name_cell = f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]{symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] {get_subnet_name(dynamic_info[netuid])}"
202
+ subnet_name = get_subnet_name(dynamic_info[netuid])
203
+ subnet_name_cell = f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]{symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] {subnet_name}"
199
204
 
200
205
  rows.append(
201
206
  [
@@ -220,13 +225,28 @@ async def stake_list(
220
225
  str(Balance.from_tao(per_block_tao_emission)),
221
226
  ]
222
227
  )
228
+ substakes_values.append(
229
+ {
230
+ "netuid": netuid,
231
+ "subnet_name": subnet_name,
232
+ "value": tao_value_.tao,
233
+ "stake_value": substake_.stake.tao,
234
+ "rate": pool.price.tao,
235
+ "swap_value": swap_value,
236
+ "registered": True if substake_.is_registered else False,
237
+ "emission": {
238
+ "alpha": per_block_emission,
239
+ "tao": per_block_tao_emission,
240
+ },
241
+ }
242
+ )
223
243
  created_table = define_table(
224
244
  name_, rows, total_tao_value_, total_swapped_tao_value_
225
245
  )
226
246
  for row in rows:
227
247
  created_table.add_row(*row)
228
248
  console.print(created_table)
229
- return total_tao_value_, total_swapped_tao_value_
249
+ return total_tao_value_, total_swapped_tao_value_, substakes_values
230
250
 
231
251
  def create_live_table(
232
252
  substakes: list,
@@ -409,22 +429,23 @@ async def stake_list(
409
429
  # Main execution
410
430
  block_hash = await subtensor.substrate.get_chain_head()
411
431
  (
412
- sub_stakes,
413
- registered_delegate_info,
414
- dynamic_info,
415
- ) = await get_stake_data(block_hash)
416
- balance = await subtensor.get_balance(coldkey_address)
432
+ (
433
+ sub_stakes,
434
+ registered_delegate_info,
435
+ dynamic_info,
436
+ ),
437
+ balance,
438
+ ) = await asyncio.gather(
439
+ get_stake_data(block_hash),
440
+ subtensor.get_balance(coldkey_address, block_hash=block_hash),
441
+ )
417
442
 
418
443
  # Iterate over substakes and aggregate them by hotkey.
419
- hotkeys_to_substakes: dict[str, list[StakeInfo]] = {}
444
+ hotkeys_to_substakes: dict[str, list[StakeInfo]] = defaultdict(list)
420
445
 
421
446
  for substake in sub_stakes:
422
- hotkey = substake.hotkey_ss58
423
- if substake.stake.rao == 0:
424
- continue
425
- if hotkey not in hotkeys_to_substakes:
426
- hotkeys_to_substakes[hotkey] = []
427
- hotkeys_to_substakes[hotkey].append(substake)
447
+ if substake.stake.rao != 0:
448
+ hotkeys_to_substakes[substake.hotkey_ss58].append(substake)
428
449
 
429
450
  if not hotkeys_to_substakes:
430
451
  print_error(f"No stakes found for coldkey ss58: ({coldkey_address})")
@@ -534,15 +555,24 @@ async def stake_list(
534
555
  num_hotkeys = len(hotkeys_to_substakes)
535
556
  all_hks_swapped_tao_value = Balance(0)
536
557
  all_hks_tao_value = Balance(0)
537
- for hotkey in hotkeys_to_substakes.keys():
558
+ dict_output = {
559
+ "stake_info": {},
560
+ "coldkey_address": coldkey_address,
561
+ "network": subtensor.network,
562
+ "free_balance": 0.0,
563
+ "total_tao_value": 0.0,
564
+ "total_swapped_tao_value": 0.0,
565
+ }
566
+ for hotkey, substakes in hotkeys_to_substakes.items():
538
567
  counter += 1
539
- tao_value, swapped_tao_value = create_table(
540
- hotkey, hotkeys_to_substakes[hotkey]
568
+ tao_value, swapped_tao_value, substake_values_ = create_table(
569
+ hotkey, substakes
541
570
  )
571
+ dict_output["stake_info"][hotkey] = substake_values_
542
572
  all_hks_tao_value += tao_value
543
573
  all_hks_swapped_tao_value += swapped_tao_value
544
574
 
545
- if num_hotkeys > 1 and counter < num_hotkeys and prompt:
575
+ if num_hotkeys > 1 and counter < num_hotkeys and prompt and not json_output:
546
576
  console.print("\nPress Enter to continue to the next hotkey...")
547
577
  input()
548
578
 
@@ -556,7 +586,6 @@ async def stake_list(
556
586
  if not verbose
557
587
  else all_hks_swapped_tao_value
558
588
  )
559
-
560
589
  console.print("\n\n")
561
590
  console.print(
562
591
  f"Wallet:\n"
@@ -565,6 +594,11 @@ async def stake_list(
565
594
  f" Total TAO Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]\n"
566
595
  f" Total TAO Swapped Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_swapped_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]"
567
596
  )
597
+ dict_output["free_balance"] = balance.tao
598
+ dict_output["total_tao_value"] = all_hks_tao_value.tao
599
+ dict_output["total_swapped_tao_value"] = all_hks_swapped_tao_value.tao
600
+ if json_output:
601
+ json_console.print(json.dumps(dict_output))
568
602
  if not sub_stakes:
569
603
  console.print(
570
604
  f"\n[blue]No stakes found for coldkey ss58: ({coldkey_address})"
@@ -444,9 +444,10 @@ async def move_stake(
444
444
  destination_hotkey: str,
445
445
  amount: float,
446
446
  stake_all: bool,
447
+ era: int,
447
448
  interactive_selection: bool = False,
448
449
  prompt: bool = True,
449
- ):
450
+ ) -> bool:
450
451
  if interactive_selection:
451
452
  try:
452
453
  selection = await stake_move_transfer_selection(subtensor, wallet)
@@ -512,8 +513,10 @@ async def move_stake(
512
513
  if amount_to_move_as_balance > origin_stake_balance:
513
514
  err_console.print(
514
515
  f"[red]Not enough stake[/red]:\n"
515
- f" Stake balance: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{origin_stake_balance}[/{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
516
- f" < Moving amount: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{amount_to_move_as_balance}[/{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
516
+ f" Stake balance: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
517
+ f"{origin_stake_balance}[/{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
518
+ f" < Moving amount: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
519
+ f"{amount_to_move_as_balance}[/{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]"
517
520
  )
518
521
  return False
519
522
 
@@ -563,7 +566,7 @@ async def move_stake(
563
566
  },
564
567
  )
565
568
  extrinsic = await subtensor.substrate.create_signed_extrinsic(
566
- call=call, keypair=wallet.coldkey
569
+ call=call, keypair=wallet.coldkey, era={"period": era}
567
570
  )
568
571
  response = await subtensor.substrate.submit_extrinsic(
569
572
  extrinsic, wait_for_inclusion=True, wait_for_finalization=False
@@ -573,13 +576,12 @@ async def move_stake(
573
576
  console.print(":white_heavy_check_mark: [green]Sent[/green]")
574
577
  return True
575
578
  else:
576
- await response.process_events()
577
579
  if not await response.is_success:
578
580
  err_console.print(
579
581
  f"\n:cross_mark: [red]Failed[/red] with error:"
580
582
  f" {format_error_message(await response.error_message)}"
581
583
  )
582
- return
584
+ return False
583
585
  else:
584
586
  console.print(
585
587
  ":white_heavy_check_mark: [dark_sea_green3]Stake moved.[/dark_sea_green3]"
@@ -611,7 +613,7 @@ async def move_stake(
611
613
  f"Destination Stake:\n [blue]{destination_stake_balance}[/blue] :arrow_right: "
612
614
  f"[{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_destination_stake_balance}"
613
615
  )
614
- return
616
+ return True
615
617
 
616
618
 
617
619
  async def transfer_stake(
@@ -622,6 +624,7 @@ async def transfer_stake(
622
624
  origin_netuid: int,
623
625
  dest_netuid: int,
624
626
  dest_coldkey_ss58: str,
627
+ era: int,
625
628
  interactive_selection: bool = False,
626
629
  stake_all: bool = False,
627
630
  prompt: bool = True,
@@ -747,7 +750,7 @@ async def transfer_stake(
747
750
  )
748
751
 
749
752
  extrinsic = await subtensor.substrate.create_signed_extrinsic(
750
- call=call, keypair=wallet.coldkey
753
+ call=call, keypair=wallet.coldkey, era={"period": era}
751
754
  )
752
755
 
753
756
  response = await subtensor.substrate.submit_extrinsic(
@@ -758,7 +761,6 @@ async def transfer_stake(
758
761
  console.print(":white_heavy_check_mark: [green]Sent[/green]")
759
762
  return True
760
763
 
761
- await response.process_events()
762
764
  if not await response.is_success:
763
765
  err_console.print(
764
766
  f":cross_mark: [red]Failed[/red] with error: "
@@ -798,6 +800,7 @@ async def swap_stake(
798
800
  destination_netuid: int,
799
801
  amount: float,
800
802
  swap_all: bool = False,
803
+ era: int = 3,
801
804
  interactive_selection: bool = False,
802
805
  prompt: bool = True,
803
806
  wait_for_inclusion: bool = True,
@@ -903,7 +906,8 @@ async def swap_stake(
903
906
  return False
904
907
 
905
908
  with console.status(
906
- f"\n:satellite: Swapping stake from netuid [blue]{origin_netuid}[/blue] to netuid [blue]{destination_netuid}[/blue]..."
909
+ f"\n:satellite: Swapping stake from netuid [blue]{origin_netuid}[/blue] "
910
+ f"to netuid [blue]{destination_netuid}[/blue]..."
907
911
  ):
908
912
  call = await subtensor.substrate.compose_call(
909
913
  call_module="SubtensorModule",
@@ -917,7 +921,7 @@ async def swap_stake(
917
921
  )
918
922
 
919
923
  extrinsic = await subtensor.substrate.create_signed_extrinsic(
920
- call=call, keypair=wallet.coldkey
924
+ call=call, keypair=wallet.coldkey, era={"period": era}
921
925
  )
922
926
 
923
927
  response = await subtensor.substrate.submit_extrinsic(
@@ -930,7 +934,6 @@ async def swap_stake(
930
934
  console.print(":white_heavy_check_mark: [green]Sent[/green]")
931
935
  return True
932
936
 
933
- await response.process_events()
934
937
  if not await response.is_success:
935
938
  err_console.print(
936
939
  f":cross_mark: [red]Failed[/red] with error: "