22import copy
33import ssl
44from datetime import datetime , timezone
5- from typing import cast , Optional , Any , Union , Iterable , TYPE_CHECKING
5+ from typing import cast , Optional , Any , Union , Iterable , TYPE_CHECKING , Literal
66
77import asyncstdlib as a
88import scalecodec
7373 register_subnet_extrinsic ,
7474 set_subnet_identity_extrinsic ,
7575)
76- from bittensor .core .extrinsics .asyncex .root import root_register_extrinsic
76+ from bittensor .core .extrinsics .asyncex .root import (
77+ claim_root_extrinsic ,
78+ root_register_extrinsic ,
79+ set_root_claim_type_extrinsic ,
80+ )
7781from bittensor .core .extrinsics .asyncex .serving import (
7882 publish_metadata_extrinsic ,
7983)
@@ -2424,6 +2428,17 @@ async def get_liquidity_list(
24242428 logging .debug (f"Subnet { netuid } is not active." )
24252429 return None
24262430
2431+ positions_response = await self .query_map (
2432+ module = "Swap" ,
2433+ name = "Positions" ,
2434+ params = [netuid , wallet .coldkeypub .ss58_address ],
2435+ block = block ,
2436+ block_hash = block_hash ,
2437+ reuse_block = reuse_block ,
2438+ )
2439+ if len (positions_response .records ) == 0 :
2440+ return []
2441+
24272442 block_hash = await self .determine_block_hash (
24282443 block = block , block_hash = block_hash , reuse_block = reuse_block
24292444 )
@@ -2447,25 +2462,20 @@ async def get_liquidity_list(
24472462 params = [netuid ],
24482463 block_hash = block_hash ,
24492464 )
2465+
24502466 (
2451- (fee_global_tao_query , fee_global_alpha_query , sqrt_price_query ),
2452- positions_response ,
2453- ) = await asyncio .gather (
2454- self .substrate .query_multi (
2455- [
2456- fee_global_tao_query_sk ,
2457- fee_global_alpha_query_sk ,
2458- sqrt_price_query_sk ,
2459- ],
2460- block_hash = block_hash ,
2461- ),
2462- self .query_map (
2463- module = "Swap" ,
2464- name = "Positions" ,
2465- block = block ,
2466- params = [netuid , wallet .coldkeypub .ss58_address ],
2467- ),
2467+ fee_global_tao_query ,
2468+ fee_global_alpha_query ,
2469+ sqrt_price_query ,
2470+ ) = await self .substrate .query_multi (
2471+ storage_keys = [
2472+ fee_global_tao_query_sk ,
2473+ fee_global_alpha_query_sk ,
2474+ sqrt_price_query_sk ,
2475+ ],
2476+ block_hash = block_hash ,
24682477 )
2478+
24692479 # convert to floats
24702480 fee_global_tao = fixed_to_float (fee_global_tao_query [1 ])
24712481 fee_global_alpha = fixed_to_float (fee_global_alpha_query [1 ])
@@ -3029,6 +3039,179 @@ async def get_revealed_commitment_by_hotkey(
30293039 return None
30303040 return tuple (decode_revealed_commitment (pair ) for pair in query )
30313041
3042+ async def get_root_claim_type (
3043+ self ,
3044+ coldkey_ss58 : str ,
3045+ block : Optional [int ] = None ,
3046+ block_hash : Optional [str ] = None ,
3047+ reuse_block : bool = False ,
3048+ ) -> str :
3049+ """Retrieves the root claim type for a given coldkey address.
3050+
3051+ Parameters:
3052+ coldkey_ss58: The ss58 address of the coldkey.
3053+ block: The block number to query. Do not specify if using block_hash or reuse_block.
3054+ block_hash: The block hash at which to check the parameter. Do not set if using block or reuse_block.
3055+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
3056+
3057+ Returns:
3058+ RootClaimType value in string representation. Could be `Swap` or `Keep`.
3059+ """
3060+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
3061+ query = await self .substrate .query (
3062+ module = "SubtensorModule" ,
3063+ storage_function = "RootClaimType" ,
3064+ params = [coldkey_ss58 ],
3065+ block_hash = block_hash ,
3066+ reuse_block_hash = reuse_block ,
3067+ )
3068+ return next (iter (query .keys ()))
3069+
3070+ async def get_root_claimable_rate (
3071+ self ,
3072+ hotkey_ss58 : str ,
3073+ netuid : int ,
3074+ block : Optional [int ] = None ,
3075+ block_hash : Optional [str ] = None ,
3076+ reuse_block : bool = False ,
3077+ ) -> float :
3078+ """Retrieves the root claimable rate from a given hotkey address for provided netuid.
3079+
3080+ Parameters:
3081+ hotkey_ss58: The ss58 address of the root validator.
3082+ netuid: The unique identifier of the subnet to get the rate.
3083+ block: The block number to query. Do not specify if using block_hash or reuse_block.
3084+ block_hash: The block hash at which to check the parameter. Do not set if using block or reuse_block.
3085+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
3086+
3087+ Returns:
3088+ The rate of claimable stake from validator's hotkey ss58 address for provided subnet.
3089+ """
3090+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
3091+ all_rates = await self .get_root_claimable_all_rates (
3092+ hotkey_ss58 = hotkey_ss58 ,
3093+ block = block_hash ,
3094+ )
3095+ return all_rates .get (netuid , 0.0 )
3096+
3097+ async def get_root_claimable_all_rates (
3098+ self ,
3099+ hotkey_ss58 : str ,
3100+ block : Optional [int ] = None ,
3101+ block_hash : Optional [str ] = None ,
3102+ reuse_block : bool = False ,
3103+ ) -> dict [int , float ]:
3104+ """Retrieves all root claimable rates from a given hotkey address for all subnets with this validator.
3105+
3106+ Parameters:
3107+ hotkey_ss58: The ss58 address of the root validator.
3108+ block: The block number to query. Do not specify if using block_hash or reuse_block.
3109+ block_hash: The block hash at which to check the parameter. Do not set if using block or reuse_block.
3110+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
3111+
3112+ Returns:
3113+ The rate of claimable stake from validator's hotkey ss58 address for provided subnet.
3114+ """
3115+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
3116+ query = await self .substrate .query (
3117+ module = "SubtensorModule" ,
3118+ storage_function = "RootClaimable" ,
3119+ params = [hotkey_ss58 ],
3120+ block_hash = block_hash ,
3121+ reuse_block_hash = reuse_block ,
3122+ )
3123+ bits_list = next (iter (query .value ))
3124+ return {bits [0 ]: fixed_to_float (bits [1 ], frac_bits = 32 ) for bits in bits_list }
3125+
3126+ async def get_root_claimable_stake (
3127+ self ,
3128+ coldkey_ss58 : str ,
3129+ hotkey_ss58 : str ,
3130+ netuid : int ,
3131+ block : Optional [int ] = None ,
3132+ block_hash : Optional [str ] = None ,
3133+ reuse_block : bool = False ,
3134+ ) -> Balance :
3135+ """
3136+ Retrieves the root claimable stake for a given coldkey address.
3137+
3138+ Parameters:
3139+ coldkey_ss58: Delegate's ColdKey ss58 address.
3140+ hotkey_ss58: The root validator hotkey ss58 address.
3141+ netuid: Delegate's netuid where stake will be claimed.
3142+ block: The block number to query. Do not specify if using block_hash or reuse_block.
3143+ block_hash: The block hash at which to check the parameter. Do not set if using block or reuse_block.
3144+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
3145+
3146+ Returns:
3147+ Available for claiming root stake.
3148+
3149+ Note:
3150+ After manual claim, claimable (available) stake will be added to subtends stake.
3151+ """
3152+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
3153+ root_stake = await self .get_stake (
3154+ coldkey_ss58 = coldkey_ss58 ,
3155+ hotkey_ss58 = hotkey_ss58 ,
3156+ netuid = 0 , # root netuid
3157+ block = block ,
3158+ block_hash = block_hash ,
3159+ reuse_block = reuse_block ,
3160+ )
3161+ root_claimable_rate = await self .get_root_claimable_rate (
3162+ hotkey_ss58 = hotkey_ss58 ,
3163+ netuid = netuid ,
3164+ block = block ,
3165+ block_hash = block_hash ,
3166+ reuse_block = reuse_block ,
3167+ )
3168+ root_claimable_stake = (root_claimable_rate * root_stake ).set_unit (
3169+ netuid = netuid
3170+ )
3171+ root_claimed = await self .get_root_claimed (
3172+ coldkey_ss58 = coldkey_ss58 ,
3173+ hotkey_ss58 = hotkey_ss58 ,
3174+ netuid = netuid ,
3175+ block = block ,
3176+ block_hash = block_hash ,
3177+ reuse_block = reuse_block ,
3178+ )
3179+ return max (
3180+ root_claimable_stake - root_claimed , Balance (0 ).set_unit (netuid = netuid )
3181+ )
3182+
3183+ async def get_root_claimed (
3184+ self ,
3185+ coldkey_ss58 : str ,
3186+ hotkey_ss58 : str ,
3187+ netuid : int ,
3188+ block : Optional [int ] = None ,
3189+ block_hash : Optional [str ] = None ,
3190+ reuse_block : bool = False ,
3191+ ) -> Balance :
3192+ """Retrieves the root claimed Alpha shares for coldkey from hotkey in provided subnet.
3193+
3194+ Parameters:
3195+ coldkey_ss58: The ss58 address of the staker.
3196+ hotkey_ss58: The ss58 address of the root validator.
3197+ netuid: The unique identifier of the subnet.
3198+ block: The block number to query. Do not specify if using block_hash or reuse_block.
3199+ block_hash: The block hash at which to check the parameter. Do not set if using block or reuse_block.
3200+ reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block.
3201+
3202+ Returns:
3203+ The number of Alpha stake claimed from the root validator in Rao.
3204+ """
3205+ block_hash = await self .determine_block_hash (block , block_hash , reuse_block )
3206+ query = await self .substrate .query (
3207+ module = "SubtensorModule" ,
3208+ storage_function = "RootClaimed" ,
3209+ params = [hotkey_ss58 , coldkey_ss58 , netuid ],
3210+ block_hash = block_hash ,
3211+ reuse_block_hash = reuse_block ,
3212+ )
3213+ return Balance .from_rao (query .value ).set_unit (netuid = netuid )
3214+
30323215 async def get_stake (
30333216 self ,
30343217 coldkey_ss58 : str ,
@@ -5095,6 +5278,40 @@ async def burned_register(
50955278 wait_for_finalization = wait_for_finalization ,
50965279 )
50975280
5281+ async def claim_root (
5282+ self ,
5283+ wallet : "Wallet" ,
5284+ netuids : "UIDs" ,
5285+ period : Optional [int ] = DEFAULT_PERIOD ,
5286+ raise_error : bool = False ,
5287+ wait_for_inclusion : bool = True ,
5288+ wait_for_finalization : bool = True ,
5289+ ):
5290+ """Claims the root emissions for a coldkey.
5291+
5292+ Parameters:
5293+ wallet: Bittensor Wallet instance.
5294+ netuids: The netuids to claim root emissions for.
5295+ period: The number of blocks during which the transaction will remain valid after it's submitted. If the
5296+ transaction is not included in a block within that number of blocks, it will expire and be rejected. You
5297+ can think of it as an expiration date for the transaction.
5298+ raise_error: Raises a relevant exception rather than returning `False` if unsuccessful.
5299+ wait_for_inclusion: Whether to wait for the inclusion of the transaction.
5300+ wait_for_finalization: Whether to wait for the finalization of the transaction.
5301+
5302+ Returns:
5303+ ExtrinsicResponse: The result object of the extrinsic execution.
5304+ """
5305+ return await claim_root_extrinsic (
5306+ subtensor = self ,
5307+ wallet = wallet ,
5308+ netuids = netuids ,
5309+ period = period ,
5310+ raise_error = raise_error ,
5311+ wait_for_inclusion = wait_for_inclusion ,
5312+ wait_for_finalization = wait_for_finalization ,
5313+ )
5314+
50985315 async def commit_weights (
50995316 self ,
51005317 wallet : "Wallet" ,
@@ -5967,6 +6184,40 @@ async def set_delegate_take(
59676184 logging .error (f"[red]{ response .message } [/red]" )
59686185 return response
59696186
6187+ async def set_root_claim_type (
6188+ self ,
6189+ wallet : "Wallet" ,
6190+ new_root_claim_type : Literal ["Swap" , "Keep" ],
6191+ period : Optional [int ] = DEFAULT_PERIOD ,
6192+ raise_error : bool = False ,
6193+ wait_for_inclusion : bool = True ,
6194+ wait_for_finalization : bool = True ,
6195+ ):
6196+ """Sets the root claim type for the coldkey in provided wallet.
6197+
6198+ Parameters:
6199+ wallet: Bittensor Wallet instance.
6200+ new_root_claim_type: The new root claim type to set. Could be either "Swap" or "Keep".
6201+ period: The number of blocks during which the transaction will remain valid after it's submitted. If the
6202+ transaction is not included in a block within that number of blocks, it will expire and be rejected. You
6203+ can think of it as an expiration date for the transaction.
6204+ raise_error: Raises a relevant exception rather than returning `False` if unsuccessful.
6205+ wait_for_inclusion: Whether to wait for the inclusion of the transaction.
6206+ wait_for_finalization: Whether to wait for the finalization of the transaction.
6207+
6208+ Returns:
6209+ ExtrinsicResponse: The result object of the extrinsic execution.
6210+ """
6211+ return await set_root_claim_type_extrinsic (
6212+ subtensor = self ,
6213+ wallet = wallet ,
6214+ new_root_claim_type = new_root_claim_type ,
6215+ period = period ,
6216+ raise_error = raise_error ,
6217+ wait_for_inclusion = wait_for_inclusion ,
6218+ wait_for_finalization = wait_for_finalization ,
6219+ )
6220+
59706221 async def set_subnet_identity (
59716222 self ,
59726223 wallet : "Wallet" ,
0 commit comments