6565)
6666from bittensor .core .metagraph import AsyncMetagraph
6767from bittensor .core .settings import version_as_int , TYPE_REGISTRY , DELEGATES_DETAILS_URL
68- from bittensor .core .types import ParamWithTypes
69- from bittensor .core .types import SubtensorMixin
68+ from bittensor .core .types import ParamWithTypes , SubtensorMixin
7069from bittensor .utils import (
7170 decode_hex_identity_dict ,
7271 format_error_message ,
@@ -563,12 +562,16 @@ async def all_subnets(
563562 block_number : Optional [int ] = None ,
564563 block_hash : Optional [str ] = None ,
565564 reuse_block : bool = False ,
566- ) -> Optional [list [" DynamicInfo" ]]:
565+ ) -> Optional [list [DynamicInfo ]]:
567566 """
568567 Retrieves the subnet information for all subnets in the network.
569568
570569 Args:
571- block_number (Optional[int]): The block number to query the subnet information from.
570+ block_number (Optional[int]): The block number to query the subnet information from. Do not specify if using
571+ block_hash or reuse_block
572+ block_hash: The hash of the blockchain block number for the query. Do not specify if using reuse_block or
573+ block.
574+ reuse_block: Whether to reuse the last-used blockchain block hash. Do not set if using block_hash or block.
572575
573576 Returns:
574577 Optional[DynamicInfo]: A list of DynamicInfo objects, each containing detailed information about a subnet.
@@ -577,6 +580,8 @@ async def all_subnets(
577580 block_hash = await self .determine_block_hash (
578581 block_number , block_hash , reuse_block
579582 )
583+ if not block_hash and reuse_block :
584+ block_hash = self .substrate .last_block_hash
580585 query = await self .substrate .runtime_call (
581586 "SubnetInfoRuntimeApi" ,
582587 "get_all_dynamic_info" ,
@@ -799,7 +804,7 @@ async def get_balance(
799804 block : Optional [int ] = None ,
800805 block_hash : Optional [str ] = None ,
801806 reuse_block : bool = False ,
802- ) -> " Balance" :
807+ ) -> Balance :
803808 """
804809 Retrieves the balance for given coldkey.
805810
@@ -1321,9 +1326,29 @@ async def get_minimum_required_stake(self):
13211326 return Balance .from_rao (getattr (result , "value" , 0 ))
13221327
13231328 async def get_metagraph_info (
1324- self , netuid : int , block : Optional [int ] = None
1325- ) -> Optional [MetagraphInfo ]:
1326- block_hash = await self .get_block_hash (block )
1329+ self ,
1330+ netuid : int ,
1331+ block : Optional [int ] = None ,
1332+ block_hash : Optional [str ] = None ,
1333+ reuse_block : bool = False ,
1334+ ) -> MetagraphInfo :
1335+ """
1336+ Retrieves the MetagraphInfo dataclass from the node for a single subnet (netuid)
1337+
1338+ Arguments:
1339+ netuid: The NetUID of the subnet.
1340+ block: the block number at which to retrieve the hyperparameter. Do not specify if using block_hash or
1341+ reuse_block
1342+ block_hash: The hash of blockchain block number for the query. Do not specify if using
1343+ block or reuse_block
1344+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
1345+
1346+ Returns:
1347+ MetagraphInfo dataclass
1348+ """
1349+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
1350+ if not block_hash and reuse_block :
1351+ block_hash = self .substrate .last_block_hash
13271352
13281353 query = await self .substrate .runtime_call (
13291354 "SubnetInfoRuntimeApi" ,
@@ -1335,10 +1360,27 @@ async def get_metagraph_info(
13351360 return MetagraphInfo .from_vec_u8 (metagraph_bytes )
13361361
13371362 async def get_all_metagraphs_info (
1338- self , block : Optional [int ] = None
1363+ self ,
1364+ block : Optional [int ] = None ,
1365+ block_hash : Optional [str ] = None ,
1366+ reuse_block : bool = False ,
13391367 ) -> list [MetagraphInfo ]:
1340- block_hash = await self .get_block_hash (block )
1368+ """
1369+ Retrieves a list of MetagraphInfo objects for all subnets
1370+
1371+ Arguments:
1372+ block: the block number at which to retrieve the hyperparameter. Do not specify if using block_hash or
1373+ reuse_block
1374+ block_hash (Optional[str]): The hash of blockchain block number for the query. Do not specify if using
1375+ block or reuse_block
1376+ reuse_block (bool): Whether to reuse the last-used block hash. Do not set if using block_hash or block.
13411377
1378+ Returns:
1379+ MetagraphInfo dataclass
1380+ """
1381+ block_hash = await self .determine_block_hash (block , block_hash .reuse_block )
1382+ if not block_hash and reuse_block :
1383+ block_hash = self .substrate .last_block_hash
13421384 query = await self .substrate .runtime_call (
13431385 "SubnetInfoRuntimeApi" ,
13441386 "get_all_metagraphs" ,
@@ -1492,9 +1534,11 @@ async def get_stake(
14921534 Args:
14931535 hotkey_ss58 (str): The SS58 address of the hotkey.
14941536 coldkey_ss58 (str): The SS58 address of the coldkey.
1495- netuid (Optional[int]): The subnet ID to filter by. If provided, only returns stake for this specific subnet.
1537+ netuid (Optional[int]): The subnet ID to filter by. If provided, only returns stake for this specific
1538+ subnet.
14961539 block (Optional[int]): The block number at which to query the stake information.
1497- block_hash (Optional[str]): The hash of the block to retrieve the stake from. Do not specify if using block or reuse_block
1540+ block_hash (Optional[str]): The hash of the block to retrieve the stake from. Do not specify if using block
1541+ or reuse_block
14981542 reuse_block (bool): Whether to use the last-used block. Do not set if using block_hash or block.
14991543
15001544 Returns:
@@ -1569,18 +1613,15 @@ async def get_stake_for_coldkey(
15691613 hex_bytes_result = await self .query_runtime_api (
15701614 runtime_api = "StakeInfoRuntimeApi" ,
15711615 method = "get_stake_info_for_coldkey" ,
1572- params = [encoded_coldkey ], # type: ignore
1616+ params = [encoded_coldkey ],
15731617 block_hash = block_hash ,
1618+ reuse_block = reuse_block ,
15741619 )
15751620
15761621 if hex_bytes_result is None :
15771622 return []
1578- try :
1579- bytes_result = bytes .fromhex (hex_bytes_result [2 :])
1580- except ValueError :
1581- bytes_result = bytes .fromhex (hex_bytes_result )
15821623
1583- stakes = StakeInfo .list_from_vec_u8 (bytes_result ) # type: ignore
1624+ stakes = StakeInfo .list_from_vec_u8 (hex_to_bytes ( hex_bytes_result ) ) # type: ignore
15841625 return [stake for stake in stakes if stake .stake > 0 ]
15851626
15861627 async def get_stake_info_for_coldkey (
@@ -1898,8 +1939,8 @@ async def get_total_subnets(
18981939 return getattr (result , "value" , None )
18991940
19001941 async def get_transfer_fee (
1901- self , wallet : "Wallet" , dest : str , value : Union [" Balance" , float , int ]
1902- ) -> " Balance" :
1942+ self , wallet : "Wallet" , dest : str , value : Union [Balance , float , int ]
1943+ ) -> Balance :
19031944 """
19041945 Calculates the transaction fee for transferring tokens from a wallet to a specified destination address. This
19051946 function simulates the transfer to estimate the associated cost, taking into account the current network
@@ -2501,7 +2542,7 @@ async def recycle(
25012542 block : Optional [int ] = None ,
25022543 block_hash : Optional [str ] = None ,
25032544 reuse_block : bool = False ,
2504- ) -> Optional [" Balance" ]:
2545+ ) -> Optional [Balance ]:
25052546 """
25062547 Retrieves the 'Burn' hyperparameter for a specified subnet. The 'Burn' parameter represents the amount of Tao
25072548 that is effectively recycled within the Bittensor network.
@@ -2530,7 +2571,7 @@ async def recycle(
25302571 async def subnet (
25312572 self ,
25322573 netuid : int ,
2533- block_number : int = None ,
2574+ block : int = None ,
25342575 block_hash : Optional [str ] = None ,
25352576 reuse_block : bool = False ,
25362577 ) -> Optional [DynamicInfo ]:
@@ -2539,21 +2580,16 @@ async def subnet(
25392580
25402581 Args:
25412582 netuid (int): The unique identifier of the subnet.
2542- block_number (Optional[int]): The block number to get the subnets at.
2583+ block (Optional[int]): The block number to get the subnets at.
2584+ block_hash (str): The hash of the blockchain block number for the query.
2585+ reuse_block (bool): Whether to reuse the last-used blockchain block hash.
25432586
25442587 Returns:
25452588 Optional[DynamicInfo]: A DynamicInfo object, containing detailed information about a subnet.
2546-
2547- This function can be called in two ways:
2548- 1. As a context manager:
2549- async with sub:
2550- subnet = await sub.subnet(1)
2551- 2. Directly:
2552- subnet = await sub.subnet(1)
25532589 """
2554- block_hash = await self .determine_block_hash (
2555- block_number , block_hash , reuse_block
2556- )
2590+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
2591+ if not block_hash and reuse_block :
2592+ block_hash = self . substrate . last_block_hash
25572593 query = await self .substrate .runtime_call (
25582594 "SubnetInfoRuntimeApi" ,
25592595 "get_dynamic_info" ,
@@ -2681,6 +2717,41 @@ async def tx_rate_limit(
26812717 )
26822718 return getattr (result , "value" , None )
26832719
2720+ async def wait_for_block (self , block : Optional [int ] = None ):
2721+ """
2722+ Waits until a specific block is reached on the chain. If no block is specified,
2723+ waits for the next block.
2724+
2725+ Args:
2726+ block (Optional[int]): The block number to wait for. If None, waits for next block.
2727+
2728+ Returns:
2729+ bool: True if the target block was reached, False if timeout occurred.
2730+
2731+ Example:
2732+ >>> await subtensor.wait_for_block() # Waits for next block
2733+ >>> await subtensor.wait_for_block(block=1234) # Waits for specific block
2734+ """
2735+
2736+ async def handler (block_data : dict ):
2737+ logging .debug (
2738+ f'reached block { block_data ["header" ]["number" ]} . Waiting for block { target_block } '
2739+ )
2740+ if block_data ["header" ]["number" ] >= target_block :
2741+ return True
2742+
2743+ current_block = await self .substrate .get_block ()
2744+ current_block_hash = current_block .get ("header" , {}).get ("hash" )
2745+ if block is not None :
2746+ target_block = block
2747+ else :
2748+ target_block = current_block ["header" ]["number" ] + 1
2749+
2750+ await self .substrate ._get_block_handler (
2751+ current_block_hash , header_only = True , subscription_handler = handler
2752+ )
2753+ return True
2754+
26842755 async def weights (
26852756 self ,
26862757 netuid : int ,
@@ -2817,6 +2888,7 @@ async def add_stake(
28172888 Args:
28182889 wallet (bittensor_wallet.Wallet): The wallet to be used for staking.
28192890 hotkey_ss58 (Optional[str]): The ``SS58`` address of the hotkey associated with the neuron.
2891+ netuid: subnet UID
28202892 amount (Balance): The amount of TAO to stake.
28212893 wait_for_inclusion (bool): Waits for the transaction to be included in a block.
28222894 wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
@@ -2853,6 +2925,7 @@ async def add_stake_multiple(
28532925 Args:
28542926 wallet (bittensor_wallet.Wallet): The wallet used for staking.
28552927 hotkey_ss58s (list[str]): List of ``SS58`` addresses of hotkeys to stake to.
2928+ netuids: list of subnet UIDs
28562929 amounts (list[Balance]): Corresponding amounts of TAO to stake for each hotkey.
28572930 wait_for_inclusion (bool): Waits for the transaction to be included in a block.
28582931 wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
@@ -3387,7 +3460,7 @@ async def swap_stake(
33873460 hotkey_ss58 : str ,
33883461 origin_netuid : int ,
33893462 destination_netuid : int ,
3390- amount : Union [ " Balance" , float ] ,
3463+ amount : Balance ,
33913464 wait_for_inclusion : bool = True ,
33923465 wait_for_finalization : bool = False ,
33933466 ) -> bool :
@@ -3465,7 +3538,7 @@ async def transfer(
34653538 self ,
34663539 wallet : "Wallet" ,
34673540 dest : str ,
3468- amount : " Balance" ,
3541+ amount : Balance ,
34693542 transfer_all : bool = False ,
34703543 wait_for_inclusion : bool = True ,
34713544 wait_for_finalization : bool = False ,
0 commit comments