@@ -2810,6 +2810,9 @@ async def add_stake(
28102810 amount : Optional [Balance ] = None ,
28112811 wait_for_inclusion : bool = True ,
28122812 wait_for_finalization : bool = False ,
2813+ safe_staking : bool = False ,
2814+ allow_partial_stake : bool = False ,
2815+ rate_threshold : float = 0.005 ,
28132816 ) -> bool :
28142817 """
28152818 Adds the specified amount of stake to a neuron identified by the hotkey ``SS58`` address.
@@ -2823,12 +2826,20 @@ async def add_stake(
28232826 amount (Balance): The amount of TAO to stake.
28242827 wait_for_inclusion (bool): Waits for the transaction to be included in a block.
28252828 wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
2829+ safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The stake
2830+ will only execute if the price change doesn't exceed the rate threshold. Default is False.
2831+ allow_partial_stake (bool): If true and safe_staking is enabled, allows partial staking when
2832+ the full amount would exceed the price threshold. If false, the entire stake fails if it would
2833+ exceed the threshold. Default is False.
2834+ rate_threshold (float): The maximum allowed price change ratio when staking. For example,
2835+ 0.005 = 0.5% maximum price increase. Only used when safe_staking is True. Default is 0.005.
28262836
28272837 Returns:
28282838 bool: ``True`` if the staking is successful, False otherwise.
28292839
2830- This function enables neurons to increase their stake in the network, enhancing their influence and potential
2831- rewards in line with Bittensor's consensus and reward mechanisms.
2840+ This function enables neurons to increase their stake in the network, enhancing their influence and potential.
2841+ When safe_staking is enabled, it provides protection against price fluctuations during the time stake is
2842+ executed and the time it is actually processed by the chain.
28322843 """
28332844 amount = check_and_convert_to_balance (amount )
28342845 return await add_stake_extrinsic (
@@ -2839,6 +2850,9 @@ async def add_stake(
28392850 amount = amount ,
28402851 wait_for_inclusion = wait_for_inclusion ,
28412852 wait_for_finalization = wait_for_finalization ,
2853+ safe_staking = safe_staking ,
2854+ allow_partial_stake = allow_partial_stake ,
2855+ rate_threshold = rate_threshold ,
28422856 )
28432857
28442858 async def add_stake_multiple (
@@ -3460,6 +3474,9 @@ async def swap_stake(
34603474 amount : Balance ,
34613475 wait_for_inclusion : bool = True ,
34623476 wait_for_finalization : bool = False ,
3477+ safe_staking : bool = False ,
3478+ allow_partial_stake : bool = False ,
3479+ rate_threshold : float = 0.005 ,
34633480 ) -> bool :
34643481 """
34653482 Moves stake between subnets while keeping the same coldkey-hotkey pair ownership.
@@ -3473,9 +3490,25 @@ async def swap_stake(
34733490 amount (Union[Balance, float]): The amount to swap.
34743491 wait_for_inclusion (bool): Waits for the transaction to be included in a block.
34753492 wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3493+ safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The swap
3494+ will only execute if the price ratio between subnets doesn't exceed the rate threshold.
3495+ Default is False.
3496+ allow_partial_stake (bool): If true and safe_staking is enabled, allows partial stake swaps when
3497+ the full amount would exceed the price threshold. If false, the entire swap fails if it would
3498+ exceed the threshold. Default is False.
3499+ rate_threshold (float): The maximum allowed increase in the price ratio between subnets
3500+ (origin_price/destination_price). For example, 0.005 = 0.5% maximum increase. Only used
3501+ when safe_staking is True. Default is 0.005.
34763502
34773503 Returns:
34783504 success (bool): True if the extrinsic was successful.
3505+
3506+ The price ratio for swap_stake in safe mode is calculated as: origin_subnet_price / destination_subnet_price
3507+ When safe_staking is enabled, the swap will only execute if:
3508+ - With allow_partial_stake=False: The entire swap amount can be executed without the price ratio
3509+ increasing more than rate_threshold
3510+ - With allow_partial_stake=True: A partial amount will be swapped up to the point where the
3511+ price ratio would increase by rate_threshold
34793512 """
34803513 amount = check_and_convert_to_balance (amount )
34813514 return await swap_stake_extrinsic (
@@ -3487,6 +3520,9 @@ async def swap_stake(
34873520 amount = amount ,
34883521 wait_for_inclusion = wait_for_inclusion ,
34893522 wait_for_finalization = wait_for_finalization ,
3523+ safe_staking = safe_staking ,
3524+ allow_partial_stake = allow_partial_stake ,
3525+ rate_threshold = rate_threshold ,
34903526 )
34913527
34923528 async def transfer_stake (
@@ -3575,6 +3611,9 @@ async def unstake(
35753611 amount : Optional [Balance ] = None ,
35763612 wait_for_inclusion : bool = True ,
35773613 wait_for_finalization : bool = False ,
3614+ safe_staking : bool = False ,
3615+ allow_partial_stake : bool = False ,
3616+ rate_threshold : float = 0.005 ,
35783617 ) -> bool :
35793618 """
35803619 Removes a specified amount of stake from a single hotkey account. This function is critical for adjusting
@@ -3584,10 +3623,17 @@ async def unstake(
35843623 wallet (bittensor_wallet.wallet): The wallet associated with the neuron from which the stake is being
35853624 removed.
35863625 hotkey_ss58 (Optional[str]): The ``SS58`` address of the hotkey account to unstake from.
3587- netuid (Optional[int]): Subnet unique ID .
3626+ netuid (Optional[int]): The unique identifier of the subnet .
35883627 amount (Balance): The amount of TAO to unstake. If not specified, unstakes all.
35893628 wait_for_inclusion (bool): Waits for the transaction to be included in a block.
35903629 wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3630+ safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The unstake
3631+ will only execute if the price change doesn't exceed the rate threshold. Default is False.
3632+ allow_partial_stake (bool): If true and safe_staking is enabled, allows partial unstaking when
3633+ the full amount would exceed the price threshold. If false, the entire unstake fails if it would
3634+ exceed the threshold. Default is False.
3635+ rate_threshold (float): The maximum allowed price change ratio when unstaking. For example,
3636+ 0.005 = 0.5% maximum price decrease. Only used when safe_staking is True. Default is 0.005.
35913637
35923638 Returns:
35933639 bool: ``True`` if the unstaking process is successful, False otherwise.
@@ -3604,6 +3650,9 @@ async def unstake(
36043650 amount = amount ,
36053651 wait_for_inclusion = wait_for_inclusion ,
36063652 wait_for_finalization = wait_for_finalization ,
3653+ safe_staking = safe_staking ,
3654+ allow_partial_stake = allow_partial_stake ,
3655+ rate_threshold = rate_threshold ,
36073656 )
36083657
36093658 async def unstake_multiple (
0 commit comments