@@ -339,119 +339,134 @@ async def stake_extrinsic(
339339 )
340340
341341 # Determine the amount we are staking.
342- rows = []
343- amounts_to_stake = []
344- current_stake_balances = []
345- prices_with_tolerance = []
346- remaining_wallet_balance = current_wallet_balance
347- max_slippage = 0.0
348-
342+ operation_targets = []
349343 for hotkey in hotkeys_to_stake_to :
350344 for netuid in netuids :
351345 # Check that the subnet exists.
352346 subnet_info = all_subnets .get (netuid )
353347 if not subnet_info :
354348 print_error (f"Subnet with netuid: { netuid } does not exist." )
355349 continue
356- current_stake_balances .append (hotkey_stake_map [hotkey [1 ]][netuid ])
357-
358- # Get the amount.
359- amount_to_stake = Balance (0 )
360- if amount :
361- amount_to_stake = Balance .from_tao (amount )
362- elif stake_all :
363- amount_to_stake = current_wallet_balance / len (netuids )
364- elif not amount :
365- amount_to_stake , _ = _prompt_stake_amount (
366- current_balance = remaining_wallet_balance ,
367- netuid = netuid ,
368- action_name = "stake" ,
369- )
370- amounts_to_stake .append (amount_to_stake )
350+ operation_targets .append (
351+ (hotkey , netuid , subnet_info , hotkey_stake_map [hotkey [1 ]][netuid ])
352+ )
371353
372- # Check enough to stake.
373- if amount_to_stake > remaining_wallet_balance :
374- print_error (
375- f"Not enough stake:[bold white]\n wallet balance:{ remaining_wallet_balance } < "
376- f"staking amount: { amount_to_stake } [/bold white]"
377- )
378- return
379- remaining_wallet_balance -= amount_to_stake
380-
381- # Calculate slippage
382- # TODO: Update for V3, slippage calculation is significantly different in v3
383- # try:
384- # received_amount, slippage_pct, slippage_pct_float, rate = (
385- # _calculate_slippage(subnet_info, amount_to_stake, stake_fee)
386- # )
387- # except ValueError:
388- # return False
389- #
390- # max_slippage = max(slippage_pct_float, max_slippage)
391-
392- # Temporary workaround - calculations without slippage
393- current_price_float = float (subnet_info .price .tao )
394- rate = _safe_inverse_rate (current_price_float )
395-
396- # If we are staking safe, add price tolerance
397- if safe_staking :
398- if subnet_info .is_dynamic :
399- price_with_tolerance = current_price_float * (1 + rate_tolerance )
400- _rate_with_tolerance = _safe_inverse_rate (
401- price_with_tolerance
402- ) # Rate only for display
403- rate_with_tolerance = f"{ _rate_with_tolerance :.4f} "
404- price_with_tolerance = Balance .from_tao (
405- price_with_tolerance
406- ) # Actual price to pass to extrinsic
407- else :
408- rate_with_tolerance = "1"
409- price_with_tolerance = Balance .from_rao (1 )
410- extrinsic_fee = await get_stake_extrinsic_fee (
411- netuid_ = netuid ,
412- amount_ = amount_to_stake ,
413- staking_address_ = hotkey [1 ],
414- safe_staking_ = safe_staking ,
415- price_limit = price_with_tolerance ,
416- )
417- prices_with_tolerance .append (price_with_tolerance )
418- row_extension = [
419- f"{ rate_with_tolerance } { Balance .get_unit (netuid )} /{ Balance .get_unit (0 )} " ,
420- f"[{ 'dark_sea_green3' if allow_partial_stake else 'red' } ]"
421- # safe staking
422- f"{ allow_partial_stake } [/{ 'dark_sea_green3' if allow_partial_stake else 'red' } ]" ,
423- ]
354+ if stake_all and not operation_targets :
355+ print_error ("No valid staking operations to perform." )
356+ return
357+
358+ rows = []
359+ operations = []
360+ remaining_wallet_balance = current_wallet_balance
361+ max_slippage = 0.0
362+
363+ for hotkey , netuid , subnet_info , current_stake_balance in operation_targets :
364+ staking_address = hotkey [1 ]
365+
366+ # Get the amount.
367+ amount_to_stake = Balance (0 )
368+ if amount :
369+ amount_to_stake = Balance .from_tao (amount )
370+ elif stake_all :
371+ amount_to_stake = current_wallet_balance / len (operation_targets )
372+ elif not amount :
373+ amount_to_stake , _ = _prompt_stake_amount (
374+ current_balance = remaining_wallet_balance ,
375+ netuid = netuid ,
376+ action_name = "stake" ,
377+ )
378+
379+ # Check enough to stake.
380+ if amount_to_stake > remaining_wallet_balance :
381+ print_error (
382+ f"Not enough stake:[bold white]\n wallet balance:{ remaining_wallet_balance } < "
383+ f"staking amount: { amount_to_stake } [/bold white]"
384+ )
385+ return
386+ remaining_wallet_balance -= amount_to_stake
387+
388+ # Calculate slippage
389+ # TODO: Update for V3, slippage calculation is significantly different in v3
390+ # try:
391+ # received_amount, slippage_pct, slippage_pct_float, rate = (
392+ # _calculate_slippage(subnet_info, amount_to_stake, stake_fee)
393+ # )
394+ # except ValueError:
395+ # return False
396+ #
397+ # max_slippage = max(slippage_pct_float, max_slippage)
398+
399+ # Temporary workaround - calculations without slippage
400+ current_price_float = float (subnet_info .price .tao )
401+ rate = _safe_inverse_rate (current_price_float )
402+ price_with_tolerance = None
403+
404+ # If we are staking safe, add price tolerance
405+ if safe_staking :
406+ if subnet_info .is_dynamic :
407+ price_with_tolerance = current_price_float * (1 + rate_tolerance )
408+ _rate_with_tolerance = _safe_inverse_rate (
409+ price_with_tolerance
410+ ) # Rate only for display
411+ rate_with_tolerance = f"{ _rate_with_tolerance :.4f} "
412+ price_with_tolerance = Balance .from_tao (
413+ price_with_tolerance
414+ ) # Actual price to pass to extrinsic
424415 else :
425- extrinsic_fee = await get_stake_extrinsic_fee (
426- netuid_ = netuid ,
427- amount_ = amount_to_stake ,
428- staking_address_ = hotkey [1 ],
429- safe_staking_ = safe_staking ,
430- )
431- row_extension = []
432- # TODO this should be asyncio gathered before the for loop
433- amount_minus_fee = (
434- (amount_to_stake - extrinsic_fee ) if not proxy else amount_to_stake
416+ rate_with_tolerance = "1"
417+ price_with_tolerance = Balance .from_rao (1 )
418+ extrinsic_fee = await get_stake_extrinsic_fee (
419+ netuid_ = netuid ,
420+ amount_ = amount_to_stake ,
421+ staking_address_ = staking_address ,
422+ safe_staking_ = safe_staking ,
423+ price_limit = price_with_tolerance ,
424+ )
425+ row_extension = [
426+ f"{ rate_with_tolerance } { Balance .get_unit (netuid )} /{ Balance .get_unit (0 )} " ,
427+ f"[{ 'dark_sea_green3' if allow_partial_stake else 'red' } ]"
428+ # safe staking
429+ f"{ allow_partial_stake } [/{ 'dark_sea_green3' if allow_partial_stake else 'red' } ]" ,
430+ ]
431+ else :
432+ extrinsic_fee = await get_stake_extrinsic_fee (
433+ netuid_ = netuid ,
434+ amount_ = amount_to_stake ,
435+ staking_address_ = staking_address ,
436+ safe_staking_ = safe_staking ,
435437 )
436- sim_swap = await subtensor .sim_swap (
437- origin_netuid = 0 ,
438- destination_netuid = netuid ,
439- amount = amount_minus_fee .rao ,
438+ row_extension = []
439+ # TODO this should be asyncio gathered before the for loop
440+ amount_minus_fee = (
441+ (amount_to_stake - extrinsic_fee ) if not proxy else amount_to_stake
442+ )
443+ sim_swap = await subtensor .sim_swap (
444+ origin_netuid = 0 ,
445+ destination_netuid = netuid ,
446+ amount = amount_minus_fee .rao ,
447+ )
448+ received_amount = sim_swap .alpha_amount
449+ # Add rows for the table
450+ base_row = [
451+ str (netuid ), # netuid
452+ f"{ staking_address } " , # hotkey
453+ str (amount_to_stake ), # amount
454+ str (rate ) + f" { Balance .get_unit (netuid )} /{ Balance .get_unit (0 )} " , # rate
455+ str (received_amount .set_unit (netuid )), # received
456+ str (sim_swap .tao_fee ), # fee
457+ str (extrinsic_fee ),
458+ # str(slippage_pct), # slippage
459+ ] + row_extension
460+ rows .append (tuple (base_row ))
461+ operations .append (
462+ (
463+ netuid ,
464+ staking_address ,
465+ amount_to_stake ,
466+ current_stake_balance ,
467+ price_with_tolerance ,
440468 )
441- received_amount = sim_swap .alpha_amount
442- # Add rows for the table
443- base_row = [
444- str (netuid ), # netuid
445- f"{ hotkey [1 ]} " , # hotkey
446- str (amount_to_stake ), # amount
447- str (rate )
448- + f" { Balance .get_unit (netuid )} /{ Balance .get_unit (0 )} " , # rate
449- str (received_amount .set_unit (netuid )), # received
450- str (sim_swap .tao_fee ), # fee
451- str (extrinsic_fee ),
452- # str(slippage_pct), # slippage
453- ] + row_extension
454- rows .append (tuple (base_row ))
469+ )
455470
456471 # Define and print stake table + slippage warning
457472 table = _define_stake_table (wallet , subtensor , safe_staking , rate_tolerance )
@@ -467,23 +482,6 @@ async def stake_extrinsic(
467482 if not unlock_key (wallet ).success :
468483 return
469484
470- # Build the list of (netuid, hotkey, amount, current_stake, price_limit) tuples
471- # that describe each staking operation we need to perform.
472- # The zip aligns netuids with amounts/balances (which are populated per
473- # hotkey-netuid pair, but the zip truncates to len(netuids), matching the
474- # original execution order). Each netuid's amount/price applies to all hotkeys.
475- operations = []
476- if safe_staking :
477- for ni , am , curr , price in zip (
478- netuids , amounts_to_stake , current_stake_balances , prices_with_tolerance
479- ):
480- for _ , staking_address in hotkeys_to_stake_to :
481- operations .append ((ni , staking_address , am , curr , price ))
482- else :
483- for ni , am , curr in zip (netuids , amounts_to_stake , current_stake_balances ):
484- for _ , staking_address in hotkeys_to_stake_to :
485- operations .append ((ni , staking_address , am , curr , None ))
486-
487485 total_ops = len (operations )
488486 use_batch = total_ops > 1
489487
0 commit comments