bittensor-cli 9.1.3__py3-none-any.whl → 9.2.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.
@@ -46,9 +46,7 @@ async def stake_add(
46
46
  netuid: the netuid to stake to (None indicates all subnets)
47
47
  stake_all: whether to stake all available balance
48
48
  amount: specified amount of balance to stake
49
- delegate: whether to delegate stake, currently unused
50
49
  prompt: whether to prompt the user
51
- max_stake: maximum amount to stake (used in combination with stake_all), currently unused
52
50
  all_hotkeys: whether to stake all hotkeys
53
51
  include_hotkeys: list of hotkeys to include in staking process (if not specifying `--all`)
54
52
  exclude_hotkeys: list of hotkeys to exclude in staking (if specifying `--all`)
@@ -61,18 +59,16 @@ async def stake_add(
61
59
  """
62
60
 
63
61
  async def safe_stake_extrinsic(
64
- netuid: int,
65
- amount: Balance,
62
+ netuid_: int,
63
+ amount_: Balance,
66
64
  current_stake: Balance,
67
- hotkey_ss58: str,
65
+ hotkey_ss58_: str,
68
66
  price_limit: Balance,
69
- wallet: Wallet,
70
- subtensor: "SubtensorInterface",
71
67
  status=None,
72
68
  ) -> None:
73
69
  err_out = partial(print_error, status=status)
74
70
  failure_prelude = (
75
- f":cross_mark: [red]Failed[/red] to stake {amount} on Netuid {netuid}"
71
+ f":cross_mark: [red]Failed[/red] to stake {amount_} on Netuid {netuid_}"
76
72
  )
77
73
  current_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
78
74
  next_nonce = await subtensor.substrate.get_account_next_index(
@@ -82,9 +78,9 @@ async def stake_add(
82
78
  call_module="SubtensorModule",
83
79
  call_function="add_stake_limit",
84
80
  call_params={
85
- "hotkey": hotkey_ss58,
86
- "netuid": netuid,
87
- "amount_staked": amount.rao,
81
+ "hotkey": hotkey_ss58_,
82
+ "netuid": netuid_,
83
+ "amount_staked": amount_.rao,
88
84
  "limit_price": price_limit,
89
85
  "allow_partial": allow_partial_stake,
90
86
  },
@@ -119,30 +115,30 @@ async def stake_add(
119
115
  new_balance, new_stake = await asyncio.gather(
120
116
  subtensor.get_balance(wallet.coldkeypub.ss58_address, block_hash),
121
117
  subtensor.get_stake(
122
- hotkey_ss58=hotkey_ss58,
118
+ hotkey_ss58=hotkey_ss58_,
123
119
  coldkey_ss58=wallet.coldkeypub.ss58_address,
124
- netuid=netuid,
120
+ netuid=netuid_,
125
121
  block_hash=block_hash,
126
122
  ),
127
123
  )
128
124
  console.print(
129
- f":white_heavy_check_mark: [dark_sea_green3]Finalized. Stake added to netuid: {netuid}[/dark_sea_green3]"
125
+ f":white_heavy_check_mark: [dark_sea_green3]Finalized. Stake added to netuid: {netuid_}[/dark_sea_green3]"
130
126
  )
131
127
  console.print(
132
128
  f"Balance:\n [blue]{current_balance}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_balance}"
133
129
  )
134
130
 
135
131
  amount_staked = current_balance - new_balance
136
- if allow_partial_stake and (amount_staked != amount):
132
+ if allow_partial_stake and (amount_staked != amount_):
137
133
  console.print(
138
134
  "Partial stake transaction. Staked:\n"
139
135
  f" [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{amount_staked}[/{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}] "
140
136
  f"instead of "
141
- f"[blue]{amount}[/blue]"
137
+ f"[blue]{amount_}[/blue]"
142
138
  )
143
139
 
144
140
  console.print(
145
- f"Subnet: [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{netuid}[/{COLOR_PALETTE['GENERAL']['SUBHEADING']}] "
141
+ f"Subnet: [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{netuid_}[/{COLOR_PALETTE['GENERAL']['SUBHEADING']}] "
146
142
  f"Stake:\n"
147
143
  f" [blue]{current_stake}[/blue] "
148
144
  f":arrow_right: "
@@ -286,10 +282,24 @@ async def stake_add(
286
282
  return False
287
283
  remaining_wallet_balance -= amount_to_stake
288
284
 
289
- # Calculate slippage
290
- received_amount, slippage_pct, slippage_pct_float, rate = (
291
- _calculate_slippage(subnet_info, amount_to_stake)
285
+ stake_fee = await subtensor.get_stake_fee(
286
+ origin_hotkey_ss58=None,
287
+ origin_netuid=None,
288
+ origin_coldkey_ss58=wallet.coldkeypub.ss58_address,
289
+ destination_hotkey_ss58=hotkey[1],
290
+ destination_netuid=netuid,
291
+ destination_coldkey_ss58=wallet.coldkeypub.ss58_address,
292
+ amount=amount_to_stake.rao,
292
293
  )
294
+
295
+ # Calculate slippage
296
+ try:
297
+ received_amount, slippage_pct, slippage_pct_float, rate = (
298
+ _calculate_slippage(subnet_info, amount_to_stake, stake_fee)
299
+ )
300
+ except ValueError:
301
+ return False
302
+
293
303
  max_slippage = max(slippage_pct_float, max_slippage)
294
304
 
295
305
  # Add rows for the table
@@ -300,6 +310,7 @@ async def stake_add(
300
310
  str(rate)
301
311
  + f" {Balance.get_unit(netuid)}/{Balance.get_unit(0)} ", # rate
302
312
  str(received_amount.set_unit(netuid)), # received
313
+ str(stake_fee), # fee
303
314
  str(slippage_pct), # slippage
304
315
  ]
305
316
 
@@ -361,13 +372,11 @@ async def stake_add(
361
372
  else:
362
373
  stake_coroutines.append(
363
374
  safe_stake_extrinsic(
364
- netuid=ni,
365
- amount=am,
375
+ netuid_=ni,
376
+ amount_=am,
366
377
  current_stake=curr,
367
- hotkey_ss58=staking_address,
378
+ hotkey_ss58_=staking_address,
368
379
  price_limit=price_with_tolerance,
369
- wallet=wallet,
370
- subtensor=subtensor,
371
380
  )
372
381
  )
373
382
  else:
@@ -537,6 +546,11 @@ def _define_stake_table(
537
546
  justify="center",
538
547
  style=COLOR_PALETTE["POOLS"]["TAO_EQUIV"],
539
548
  )
549
+ table.add_column(
550
+ "Fee (τ)",
551
+ justify="center",
552
+ style=COLOR_PALETTE["STAKE"]["STAKE_AMOUNT"],
553
+ )
540
554
  table.add_column(
541
555
  "Slippage", justify="center", style=COLOR_PALETTE["STAKE"]["SLIPPAGE_PERCENT"]
542
556
  )
@@ -590,28 +604,42 @@ The columns are as follows:
590
604
  console.print(base_description + (safe_staking_description if safe_staking else ""))
591
605
 
592
606
 
593
- def _calculate_slippage(subnet_info, amount: Balance) -> tuple[Balance, str, float]:
607
+ def _calculate_slippage(
608
+ subnet_info, amount: Balance, stake_fee: Balance
609
+ ) -> tuple[Balance, str, float, str]:
594
610
  """Calculate slippage when adding stake.
595
611
 
596
612
  Args:
597
613
  subnet_info: Subnet dynamic info
598
614
  amount: Amount being staked
615
+ stake_fee: Transaction fee for the stake operation
599
616
 
600
617
  Returns:
601
618
  tuple containing:
602
- - received_amount: Amount received after slippage
619
+ - received_amount: Amount received after slippage and fees
603
620
  - slippage_str: Formatted slippage percentage string
604
621
  - slippage_float: Raw slippage percentage value
622
+ - rate: Exchange rate string
605
623
  """
606
- received_amount, _, slippage_pct_float = subnet_info.tao_to_alpha_with_slippage(
607
- amount
608
- )
624
+ amount_after_fee = amount - stake_fee
625
+
626
+ if amount_after_fee < 0:
627
+ print_error("You don't have enough balance to cover the stake fee.")
628
+ raise ValueError()
629
+
630
+ received_amount, _, _ = subnet_info.tao_to_alpha_with_slippage(amount_after_fee)
631
+
609
632
  if subnet_info.is_dynamic:
633
+ ideal_amount = subnet_info.tao_to_alpha(amount)
634
+ total_slippage = ideal_amount - received_amount
635
+ slippage_pct_float = 100 * (total_slippage.tao / ideal_amount.tao)
610
636
  slippage_str = f"{slippage_pct_float:.4f} %"
611
637
  rate = f"{(1 / subnet_info.price.tao or 1):.4f}"
612
638
  else:
613
- slippage_pct_float = 0
614
- slippage_str = f"[{COLOR_PALETTE['STAKE']['SLIPPAGE_TEXT']}]N/A[/{COLOR_PALETTE['STAKE']['SLIPPAGE_TEXT']}]"
639
+ slippage_pct_float = (
640
+ 100 * float(stake_fee.tao) / float(amount.tao) if amount.tao != 0 else 0
641
+ )
642
+ slippage_str = f"{slippage_pct_float:.4f} %"
615
643
  rate = "1"
616
644
 
617
645
  return received_amount, slippage_str, slippage_pct_float, rate
@@ -313,9 +313,12 @@ async def get_children(
313
313
  """
314
314
  Get the take value for a given subtensor, hotkey, and netuid.
315
315
 
316
- @param child: The hotkey to retrieve the take value for.
316
+ Arguments:
317
+ child: The hotkey to retrieve the take value for.
318
+ netuid__: the netuid to retrieve the take value for.
317
319
 
318
- @return: The take value as a float. If the take value is not available, it returns 0.
320
+ Returns:
321
+ The take value as a float. If the take value is not available, it returns 0.
319
322
 
320
323
  """
321
324
  child_hotkey = child[1]
@@ -383,7 +386,7 @@ async def get_children(
383
386
  f"The total stake of parent hotkey '{parent_hotkey}'{insert_text}is {parent_total}."
384
387
  )
385
388
 
386
- for index, (netuid_, children_) in enumerate(netuid_children_):
389
+ for index, (child_netuid, children_) in enumerate(netuid_children_):
387
390
  # calculate totals
388
391
  total_proportion_per_netuid = 0
389
392
  total_stake_weight_per_netuid = 0
@@ -393,7 +396,7 @@ async def get_children(
393
396
 
394
397
  children_info = []
395
398
  child_takes = await asyncio.gather(
396
- *[get_take(c, netuid_) for c in children_]
399
+ *[get_take(c, child_netuid) for c in children_]
397
400
  )
398
401
  for child, child_take in zip(children_, child_takes):
399
402
  proportion = child[0]
@@ -408,7 +411,7 @@ async def get_children(
408
411
  (
409
412
  converted_proportion,
410
413
  child_hotkey,
411
- hotkey_stake_dict[child_hotkey][netuid_],
414
+ hotkey_stake_dict[child_hotkey][child_netuid],
412
415
  child_take,
413
416
  )
414
417
  )
@@ -420,7 +423,7 @@ async def get_children(
420
423
  for proportion_, hotkey, stake, child_take in children_info:
421
424
  proportion_percent = proportion_ * 100 # Proportion in percent
422
425
  proportion_tao = (
423
- hotkey_stake[netuid_].tao * proportion_
426
+ hotkey_stake[child_netuid].tao * proportion_
424
427
  ) # Proportion in TAO
425
428
 
426
429
  total_proportion_per_netuid += proportion_percent
@@ -433,7 +436,7 @@ async def get_children(
433
436
 
434
437
  hotkey = Text(hotkey, style="italic red" if proportion_ == 0 else "")
435
438
  table.add_row(
436
- str(netuid_),
439
+ str(child_netuid),
437
440
  hotkey,
438
441
  proportion_str,
439
442
  take_str,
@@ -661,28 +664,28 @@ async def childkey_take(
661
664
  table.add_column("Netuid", justify="center", style="cyan")
662
665
  table.add_column("Take (%)", justify="right", style="magenta")
663
666
 
664
- for netuid, take_value in takes:
665
- table.add_row(str(netuid), f"{take_value:.2f}%")
667
+ for take_netuid, take_value in takes:
668
+ table.add_row(str(take_netuid), f"{take_value:.2f}%")
666
669
 
667
670
  console.print(table)
668
671
 
669
- async def display_chk_take(ss58, netuid):
672
+ async def display_chk_take(ss58, take_netuid):
670
673
  """Print single key take for hotkey and netuid"""
671
674
  chk_take = await get_childkey_take(
672
- subtensor=subtensor, netuid=netuid, hotkey=ss58
675
+ subtensor=subtensor, netuid=take_netuid, hotkey=ss58
673
676
  )
674
677
  if chk_take is None:
675
678
  chk_take = 0
676
679
  chk_take = u16_to_float(chk_take)
677
680
  console.print(
678
- f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {netuid}."
681
+ f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {take_netuid}."
679
682
  )
680
683
 
681
684
  async def chk_all_subnets(ss58):
682
685
  """Aggregate data for childkey take from all subnets"""
683
- netuids = await subtensor.get_all_subnet_netuids()
686
+ all_netuids = await subtensor.get_all_subnet_netuids()
684
687
  takes = []
685
- for subnet in netuids:
688
+ for subnet in all_netuids:
686
689
  if subnet == 0:
687
690
  continue
688
691
  curr_take = await get_childkey_take(