bittensor-cli 8.4.4__py3-none-any.whl → 9.0.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.
- bittensor_cli/__init__.py +1 -1
- bittensor_cli/cli.py +1827 -1394
- bittensor_cli/src/__init__.py +623 -168
- bittensor_cli/src/bittensor/balances.py +41 -8
- bittensor_cli/src/bittensor/chain_data.py +557 -428
- bittensor_cli/src/bittensor/extrinsics/registration.py +129 -23
- bittensor_cli/src/bittensor/extrinsics/root.py +3 -3
- bittensor_cli/src/bittensor/extrinsics/transfer.py +6 -11
- bittensor_cli/src/bittensor/minigraph.py +46 -8
- bittensor_cli/src/bittensor/subtensor_interface.py +567 -250
- bittensor_cli/src/bittensor/utils.py +370 -25
- bittensor_cli/src/commands/stake/__init__.py +154 -0
- bittensor_cli/src/commands/stake/add.py +625 -0
- bittensor_cli/src/commands/stake/children_hotkeys.py +103 -75
- bittensor_cli/src/commands/stake/list.py +687 -0
- bittensor_cli/src/commands/stake/move.py +1000 -0
- bittensor_cli/src/commands/stake/remove.py +1146 -0
- bittensor_cli/src/commands/subnets/__init__.py +0 -0
- bittensor_cli/src/commands/subnets/price.py +867 -0
- bittensor_cli/src/commands/subnets/subnets.py +2028 -0
- bittensor_cli/src/commands/sudo.py +554 -12
- bittensor_cli/src/commands/wallets.py +225 -531
- bittensor_cli/src/commands/weights.py +2 -2
- {bittensor_cli-8.4.4.dist-info → bittensor_cli-9.0.0.dist-info}/METADATA +7 -4
- bittensor_cli-9.0.0.dist-info/RECORD +34 -0
- bittensor_cli/src/bittensor/async_substrate_interface.py +0 -2748
- bittensor_cli/src/commands/root.py +0 -1787
- bittensor_cli/src/commands/stake/stake.py +0 -1448
- bittensor_cli/src/commands/subnets.py +0 -897
- bittensor_cli-8.4.4.dist-info/RECORD +0 -31
- {bittensor_cli-8.4.4.dist-info → bittensor_cli-9.0.0.dist-info}/WHEEL +0 -0
- {bittensor_cli-8.4.4.dist-info → bittensor_cli-9.0.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-8.4.4.dist-info → bittensor_cli-9.0.0.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ from bittensor_wallet import Wallet
|
|
5
5
|
from rich.prompt import Confirm, Prompt, IntPrompt
|
6
6
|
from rich.table import Table
|
7
7
|
from rich.text import Text
|
8
|
-
from
|
8
|
+
from async_substrate_interface.errors import SubstrateRequestException
|
9
9
|
|
10
10
|
from bittensor_cli.src.bittensor.balances import Balance
|
11
11
|
from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface
|
@@ -22,6 +22,33 @@ from bittensor_cli.src.bittensor.utils import (
|
|
22
22
|
)
|
23
23
|
|
24
24
|
|
25
|
+
async def get_childkey_completion_block(
|
26
|
+
subtensor: SubtensorInterface, netuid: int
|
27
|
+
) -> tuple[int, int]:
|
28
|
+
"""
|
29
|
+
Calculates the block at which the childkey set request will complete
|
30
|
+
"""
|
31
|
+
blocks_since_last_step_query = subtensor.query(
|
32
|
+
"SubtensorModule",
|
33
|
+
"BlocksSinceLastStep",
|
34
|
+
params=[netuid],
|
35
|
+
)
|
36
|
+
tempo_query = subtensor.get_hyperparameter(
|
37
|
+
param_name="Tempo",
|
38
|
+
netuid=netuid,
|
39
|
+
)
|
40
|
+
block_number, blocks_since_last_step, tempo = await asyncio.gather(
|
41
|
+
subtensor.substrate.get_block_number(),
|
42
|
+
blocks_since_last_step_query,
|
43
|
+
tempo_query,
|
44
|
+
)
|
45
|
+
cooldown = block_number + 1
|
46
|
+
blocks_left_in_tempo = tempo - blocks_since_last_step
|
47
|
+
next_tempo = block_number + blocks_left_in_tempo
|
48
|
+
next_epoch_after_cooldown = (cooldown - next_tempo) % tempo + cooldown
|
49
|
+
return block_number, next_epoch_after_cooldown
|
50
|
+
|
51
|
+
|
25
52
|
async def set_children_extrinsic(
|
26
53
|
subtensor: "SubtensorInterface",
|
27
54
|
wallet: Wallet,
|
@@ -223,13 +250,13 @@ async def get_childkey_take(subtensor, hotkey: str, netuid: int) -> Optional[int
|
|
223
250
|
- Optional[float]: The value of the "ChildkeyTake" if found, or None if any error occurs.
|
224
251
|
"""
|
225
252
|
try:
|
226
|
-
childkey_take_ = await subtensor.
|
253
|
+
childkey_take_ = await subtensor.query(
|
227
254
|
module="SubtensorModule",
|
228
255
|
storage_function="ChildkeyTake",
|
229
256
|
params=[hotkey, netuid],
|
230
257
|
)
|
231
258
|
if childkey_take_:
|
232
|
-
return int(childkey_take_)
|
259
|
+
return int(childkey_take_.value)
|
233
260
|
|
234
261
|
except SubstrateRequestException as e:
|
235
262
|
err_console.print(f"Error querying ChildKeys: {format_error_message(e)}")
|
@@ -264,6 +291,7 @@ def prepare_child_proportions(children_with_proportions):
|
|
264
291
|
async def get_children(
|
265
292
|
wallet: Wallet, subtensor: "SubtensorInterface", netuid: Optional[int] = None
|
266
293
|
):
|
294
|
+
# TODO rao asks separately for the hotkey from the user, should we do this, or the way we do it now?
|
267
295
|
"""
|
268
296
|
Retrieves the child hotkeys for the specified wallet.
|
269
297
|
|
@@ -281,35 +309,7 @@ async def get_children(
|
|
281
309
|
- If netuid is not specified, generates and prints a summary table of all child hotkeys across all subnets.
|
282
310
|
"""
|
283
311
|
|
284
|
-
async def
|
285
|
-
"""
|
286
|
-
Fetches and displays the total stake for a specified hotkey from the Subtensor blockchain network.
|
287
|
-
If `parent` is True, it prints the hotkey and its corresponding stake.
|
288
|
-
|
289
|
-
Parameters:
|
290
|
-
- hotkey (str): The hotkey for which the stake needs to be fetched.
|
291
|
-
- parent (bool, optional): A flag to indicate whether the hotkey is the parent key. Defaults to False.
|
292
|
-
|
293
|
-
Returns:
|
294
|
-
- Balance: The total stake associated with the specified hotkey.
|
295
|
-
"""
|
296
|
-
_result = await subtensor.substrate.query(
|
297
|
-
module="SubtensorModule",
|
298
|
-
storage_function="TotalHotkeyStake",
|
299
|
-
params=[hotkey],
|
300
|
-
reuse_block_hash=True,
|
301
|
-
)
|
302
|
-
stake = Balance.from_rao(_result) if _result is not None else Balance(0)
|
303
|
-
if parent:
|
304
|
-
console.print(
|
305
|
-
f"\nYour Hotkey: [bright_magenta]{hotkey}[/bright_magenta] | Total Stake: [dark_orange]{stake}t[/dark_orange]\n",
|
306
|
-
end="",
|
307
|
-
no_wrap=True,
|
308
|
-
)
|
309
|
-
|
310
|
-
return stake
|
311
|
-
|
312
|
-
async def get_take(child: tuple) -> float:
|
312
|
+
async def get_take(child: tuple, netuid__: int) -> float:
|
313
313
|
"""
|
314
314
|
Get the take value for a given subtensor, hotkey, and netuid.
|
315
315
|
|
@@ -320,7 +320,7 @@ async def get_children(
|
|
320
320
|
"""
|
321
321
|
child_hotkey = child[1]
|
322
322
|
take_u16 = await get_childkey_take(
|
323
|
-
subtensor=subtensor, hotkey=child_hotkey, netuid=
|
323
|
+
subtensor=subtensor, hotkey=child_hotkey, netuid=netuid__
|
324
324
|
)
|
325
325
|
if take_u16:
|
326
326
|
return u16_to_float(take_u16)
|
@@ -329,7 +329,7 @@ async def get_children(
|
|
329
329
|
|
330
330
|
async def _render_table(
|
331
331
|
parent_hotkey: str,
|
332
|
-
|
332
|
+
netuid_children_: list[tuple[int, list[tuple[int, str]]]],
|
333
333
|
):
|
334
334
|
"""
|
335
335
|
Retrieves and renders children hotkeys and their details for a given parent hotkey.
|
@@ -352,10 +352,11 @@ async def get_children(
|
|
352
352
|
"Current Stake Weight", style="bold red", no_wrap=True, justify="right"
|
353
353
|
)
|
354
354
|
|
355
|
-
if not
|
355
|
+
if not netuid_children_:
|
356
356
|
console.print(table)
|
357
357
|
console.print(
|
358
|
-
f"[bold red]There are currently no child hotkeys with parent hotkey:
|
358
|
+
f"[bold red]There are currently no child hotkeys with parent hotkey: "
|
359
|
+
f"{wallet.name} | {wallet.hotkey_str} ({parent_hotkey}).[/bold red]"
|
359
360
|
)
|
360
361
|
return
|
361
362
|
|
@@ -363,48 +364,64 @@ async def get_children(
|
|
363
364
|
total_proportion = 0
|
364
365
|
total_stake_weight = 0
|
365
366
|
|
366
|
-
|
367
|
-
|
368
|
-
|
367
|
+
netuid_children_.sort(key=lambda x: x[0]) # Sort by netuid in ascending order
|
368
|
+
unique_keys = set(
|
369
|
+
[parent_hotkey]
|
370
|
+
+ [s for _, child_list in netuid_children_ for _, s in child_list]
|
371
|
+
)
|
372
|
+
hotkey_stake_dict = await subtensor.get_total_stake_for_hotkey(
|
373
|
+
*unique_keys,
|
374
|
+
netuids=[n[0] for n in netuid_children_],
|
375
|
+
)
|
376
|
+
parent_total = sum(hotkey_stake_dict[parent_hotkey].values())
|
377
|
+
insert_text = (
|
378
|
+
" "
|
379
|
+
if netuid is None
|
380
|
+
else f" on netuids: {', '.join(str(n[0]) for n in netuid_children_)} "
|
381
|
+
)
|
382
|
+
console.print(
|
383
|
+
f"The total stake of parent hotkey '{parent_hotkey}'{insert_text}is {parent_total}."
|
384
|
+
)
|
369
385
|
|
370
|
-
for index, (
|
386
|
+
for index, (netuid_, children_) in enumerate(netuid_children_):
|
371
387
|
# calculate totals
|
372
388
|
total_proportion_per_netuid = 0
|
373
389
|
total_stake_weight_per_netuid = 0
|
374
|
-
avg_take_per_netuid = 0
|
390
|
+
avg_take_per_netuid = 0.0
|
375
391
|
|
376
|
-
|
377
|
-
parent_hotkey
|
378
|
-
)
|
379
|
-
hotkey_stake = hotkey_stake_dict.get(parent_hotkey, Balance(0))
|
392
|
+
hotkey_stake: dict[int, Balance] = hotkey_stake_dict[parent_hotkey]
|
380
393
|
|
381
394
|
children_info = []
|
382
|
-
|
383
|
-
*[
|
395
|
+
child_takes = await asyncio.gather(
|
396
|
+
*[get_take(c, netuid_) for c in children_]
|
384
397
|
)
|
385
|
-
|
386
|
-
for child, child_stake, child_take in zip(
|
387
|
-
children_, child_stakes, child_takes
|
388
|
-
):
|
398
|
+
for child, child_take in zip(children_, child_takes):
|
389
399
|
proportion = child[0]
|
390
400
|
child_hotkey = child[1]
|
391
401
|
|
392
402
|
# add to totals
|
393
403
|
avg_take_per_netuid += child_take
|
394
404
|
|
395
|
-
|
405
|
+
converted_proportion = u64_to_float(proportion)
|
396
406
|
|
397
407
|
children_info.append(
|
398
|
-
(
|
408
|
+
(
|
409
|
+
converted_proportion,
|
410
|
+
child_hotkey,
|
411
|
+
hotkey_stake_dict[child_hotkey][netuid_],
|
412
|
+
child_take,
|
413
|
+
)
|
399
414
|
)
|
400
415
|
|
401
416
|
children_info.sort(
|
402
417
|
key=lambda x: x[0], reverse=True
|
403
418
|
) # sorting by proportion (highest first)
|
404
419
|
|
405
|
-
for
|
406
|
-
proportion_percent =
|
407
|
-
proportion_tao =
|
420
|
+
for proportion_, hotkey, stake, child_take in children_info:
|
421
|
+
proportion_percent = proportion_ * 100 # Proportion in percent
|
422
|
+
proportion_tao = (
|
423
|
+
hotkey_stake[netuid_].tao * proportion_
|
424
|
+
) # Proportion in TAO
|
408
425
|
|
409
426
|
total_proportion_per_netuid += proportion_percent
|
410
427
|
|
@@ -414,9 +431,9 @@ async def get_children(
|
|
414
431
|
total_stake_weight_per_netuid += stake_weight
|
415
432
|
take_str = f"{child_take * 100:.3f}%"
|
416
433
|
|
417
|
-
hotkey = Text(hotkey, style="italic red" if
|
434
|
+
hotkey = Text(hotkey, style="italic red" if proportion_ == 0 else "")
|
418
435
|
table.add_row(
|
419
|
-
str(
|
436
|
+
str(netuid_),
|
420
437
|
hotkey,
|
421
438
|
proportion_str,
|
422
439
|
take_str,
|
@@ -440,7 +457,7 @@ async def get_children(
|
|
440
457
|
total_stake_weight += total_stake_weight_per_netuid
|
441
458
|
|
442
459
|
# Add a dividing line if there are more than one netuid
|
443
|
-
if len(
|
460
|
+
if len(netuid_children_) > 1:
|
444
461
|
table.add_section()
|
445
462
|
|
446
463
|
console.print(table)
|
@@ -449,17 +466,16 @@ async def get_children(
|
|
449
466
|
if netuid is None:
|
450
467
|
# get all netuids
|
451
468
|
netuids = await subtensor.get_all_subnet_netuids()
|
452
|
-
await get_total_stake_for_hk(wallet.hotkey.ss58_address, True)
|
453
469
|
netuid_children_tuples = []
|
454
|
-
for
|
470
|
+
for netuid_ in netuids:
|
455
471
|
success, children, err_mg = await subtensor.get_children(
|
456
|
-
wallet.hotkey.ss58_address,
|
472
|
+
wallet.hotkey.ss58_address, netuid_
|
457
473
|
)
|
458
474
|
if children:
|
459
|
-
netuid_children_tuples.append((
|
475
|
+
netuid_children_tuples.append((netuid_, children))
|
460
476
|
if not success:
|
461
477
|
err_console.print(
|
462
|
-
f"Failed to get children from subtensor {
|
478
|
+
f"Failed to get children from subtensor {netuid_}: {err_mg}"
|
463
479
|
)
|
464
480
|
await _render_table(wallet.hotkey.ss58_address, netuid_children_tuples)
|
465
481
|
else:
|
@@ -468,7 +484,6 @@ async def get_children(
|
|
468
484
|
)
|
469
485
|
if not success:
|
470
486
|
err_console.print(f"Failed to get children from subtensor: {err_mg}")
|
471
|
-
await get_total_stake_for_hk(wallet.hotkey.ss58_address, True)
|
472
487
|
if children:
|
473
488
|
netuid_children_tuples = [(netuid, children)]
|
474
489
|
await _render_table(wallet.hotkey.ss58_address, netuid_children_tuples)
|
@@ -488,6 +503,8 @@ async def set_children(
|
|
488
503
|
):
|
489
504
|
"""Set children hotkeys."""
|
490
505
|
# Validate children SS58 addresses
|
506
|
+
# TODO check to see if this should be allowed to be specified by user instead of pulling from wallet
|
507
|
+
hotkey = wallet.hotkey.ss58_address
|
491
508
|
for child in children:
|
492
509
|
if not is_valid_ss58_address(child):
|
493
510
|
err_console.print(f":cross_mark:[red] Invalid SS58 address: {child}[/red]")
|
@@ -502,14 +519,13 @@ async def set_children(
|
|
502
519
|
f"Invalid proportion: The sum of all proportions cannot be greater than 1. "
|
503
520
|
f"Proposed sum of proportions is {total_proposed}."
|
504
521
|
)
|
505
|
-
|
506
522
|
children_with_proportions = list(zip(proportions, children))
|
507
|
-
if netuid:
|
523
|
+
if netuid is not None:
|
508
524
|
success, message = await set_children_extrinsic(
|
509
525
|
subtensor=subtensor,
|
510
526
|
wallet=wallet,
|
511
527
|
netuid=netuid,
|
512
|
-
hotkey=
|
528
|
+
hotkey=hotkey,
|
513
529
|
children_with_proportions=children_with_proportions,
|
514
530
|
prompt=prompt,
|
515
531
|
wait_for_inclusion=wait_for_inclusion,
|
@@ -518,8 +534,13 @@ async def set_children(
|
|
518
534
|
# Result
|
519
535
|
if success:
|
520
536
|
if wait_for_inclusion and wait_for_finalization:
|
521
|
-
|
522
|
-
|
537
|
+
current_block, completion_block = await get_childkey_completion_block(
|
538
|
+
subtensor, netuid
|
539
|
+
)
|
540
|
+
console.print(
|
541
|
+
f"Your childkey request has been submitted. It will be completed around block {completion_block}. "
|
542
|
+
f"The current block is {current_block}"
|
543
|
+
)
|
523
544
|
console.print(
|
524
545
|
":white_heavy_check_mark: [green]Set children hotkeys.[/green]"
|
525
546
|
)
|
@@ -530,20 +551,27 @@ async def set_children(
|
|
530
551
|
else:
|
531
552
|
# set children on all subnets that parent is registered on
|
532
553
|
netuids = await subtensor.get_all_subnet_netuids()
|
533
|
-
for
|
534
|
-
if
|
554
|
+
for netuid_ in netuids:
|
555
|
+
if netuid_ == 0: # dont include root network
|
535
556
|
continue
|
536
|
-
console.print(f"Setting children on netuid {
|
557
|
+
console.print(f"Setting children on netuid {netuid_}.")
|
537
558
|
await set_children_extrinsic(
|
538
559
|
subtensor=subtensor,
|
539
560
|
wallet=wallet,
|
540
|
-
netuid=
|
541
|
-
hotkey=
|
561
|
+
netuid=netuid_,
|
562
|
+
hotkey=hotkey,
|
542
563
|
children_with_proportions=children_with_proportions,
|
543
564
|
prompt=prompt,
|
544
565
|
wait_for_inclusion=True,
|
545
566
|
wait_for_finalization=False,
|
546
567
|
)
|
568
|
+
current_block, completion_block = await get_childkey_completion_block(
|
569
|
+
subtensor, netuid_
|
570
|
+
)
|
571
|
+
console.print(
|
572
|
+
f"Your childkey request for netuid {netuid_} has been submitted. It will be completed around "
|
573
|
+
f"block {completion_block}. The current block is {current_block}."
|
574
|
+
)
|
547
575
|
console.print(
|
548
576
|
":white_heavy_check_mark: [green]Sent set children request for all subnets.[/green]"
|
549
577
|
)
|