diff --git a/bittensor_cli/src/bittensor/extrinsics/transfer.py b/bittensor_cli/src/bittensor/extrinsics/transfer.py index 6886fb41a..6a7976d11 100644 --- a/bittensor_cli/src/bittensor/extrinsics/transfer.py +++ b/bittensor_cli/src/bittensor/extrinsics/transfer.py @@ -7,7 +7,10 @@ from async_substrate_interface.errors import SubstrateRequestException from bittensor_cli.src.bittensor.balances import Balance -from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface +from bittensor_cli.src.bittensor.subtensor_interface import ( + SubtensorInterface, + GENESIS_ADDRESS, +) from bittensor_cli.src.bittensor.utils import ( console, err_console, @@ -173,7 +176,7 @@ async def do_transfer() -> tuple[bool, str, str, AsyncExtrinsicReceipt]: # Ask before moving on. if prompt: hk_owner = await subtensor.get_hotkey_owner(destination, check_exists=False) - if hk_owner and hk_owner != destination: + if hk_owner and hk_owner not in (destination, GENESIS_ADDRESS): if not Confirm.ask( f"The destination appears to be a hotkey, owned by [bright_magenta]{hk_owner}[/bright_magenta]. " f"Only proceed if you are absolutely sure that [bright_magenta]{destination}[/bright_magenta] is the " diff --git a/bittensor_cli/src/bittensor/subtensor_interface.py b/bittensor_cli/src/bittensor/subtensor_interface.py index 304ad83e6..054d67f7a 100644 --- a/bittensor_cli/src/bittensor/subtensor_interface.py +++ b/bittensor_cli/src/bittensor/subtensor_interface.py @@ -45,6 +45,8 @@ get_hotkey_pub_ss58, ) +GENESIS_ADDRESS = "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" + class ParamWithTypes(TypedDict): name: str # Name of the parameter. @@ -118,6 +120,7 @@ def __init__(self, network, use_disk_cache: bool = False): ss58_format=SS58_FORMAT, type_registry=TYPE_REGISTRY, chain_name="Bittensor", + ws_shutdown_timer=None, ) def __str__(self): @@ -1116,7 +1119,7 @@ async def does_hotkey_exist( block_hash=block_hash, reuse_block_hash=reuse_block, ) - return_val = result != "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" + return_val = result != GENESIS_ADDRESS return return_val async def get_hotkey_owner( @@ -2103,7 +2106,7 @@ async def get_claimable_stakes_for_coldkey( if not stakes_info: return {} - root_stakes = {} + root_stakes: dict[str, Balance] = {} for stake_info in stakes_info: if stake_info.netuid == 0 and stake_info.stake.rao > 0: root_stakes[stake_info.hotkey_ss58] = stake_info.stake @@ -2149,8 +2152,8 @@ async def get_claimable_stakes_for_coldkey( self.substrate.query_multi(batch_claimed_calls, block_hash=block_hash), ) - claimable_rates = {} - claimed_amounts = {} + claimable_rates: dict[str, dict[int, float]] = {} + claimed_amounts: dict[tuple[str, int], Balance] = {} for idx, (_, result) in enumerate(batch_claimable): hotkey = unique_hotkeys[idx] if result: @@ -2166,12 +2169,17 @@ async def get_claimable_stakes_for_coldkey( # Calculate the claimable stake for each pair results = {} + already_claimed: Balance + net_claimable: Balance + rate: float + root_stake: Balance + claimable_stake: Balance for hotkey, netuid in target_pairs: root_stake = root_stakes[hotkey] - rate = claimable_rates[hotkey].get(netuid, 0) + rate = claimable_rates[hotkey].get(netuid, 0.0) claimable_stake = rate * root_stake - already_claimed = claimed_amounts.get((hotkey, netuid), 0) - net_claimable = max(claimable_stake - already_claimed, 0) + already_claimed = claimed_amounts.get((hotkey, netuid), Balance(0)) + net_claimable = max(claimable_stake - already_claimed, Balance(0)) if hotkey not in results: results[hotkey] = {} results[hotkey][netuid] = net_claimable.set_unit(netuid) diff --git a/bittensor_cli/src/commands/stake/list.py b/bittensor_cli/src/commands/stake/list.py index 148da59d7..b2407bab7 100644 --- a/bittensor_cli/src/commands/stake/list.py +++ b/bittensor_cli/src/commands/stake/list.py @@ -153,7 +153,7 @@ def define_table( def create_table( hotkey_: str, - substakes: list[StakeInfo], + substakes_: list[StakeInfo], claimable_amounts_: dict[str, dict[int, Balance]], ): name_ = ( @@ -164,9 +164,9 @@ def create_table( rows = [] total_tao_value_ = Balance(0) total_swapped_tao_value_ = Balance(0) - root_stakes = [s for s in substakes if s.netuid == 0] + root_stakes = [s for s in substakes_ if s.netuid == 0] other_stakes = sorted( - [s for s in substakes if s.netuid != 0], + [s for s in substakes_ if s.netuid != 0], key=lambda x: dynamic_info[x.netuid] .alpha_to_tao(Balance.from_rao(int(x.stake.rao)).set_unit(x.netuid)) .tao, @@ -626,7 +626,7 @@ def format_cell( input() total_tao_value = ( - f"τ {millify_tao(all_hks_tao_value.tao)}" + f"τ {millify_tao(all_hks_tao_value.tao + balance.tao)}" if not verbose else all_hks_tao_value ) @@ -638,10 +638,14 @@ def format_cell( console.print("\n\n") console.print( f"Wallet:\n" - f" Coldkey SS58: [{COLOR_PALETTE['GENERAL']['COLDKEY']}]{coldkey_address}[/{COLOR_PALETTE['GENERAL']['COLDKEY']}]\n" - f" Free Balance: [{COLOR_PALETTE['GENERAL']['BALANCE']}]{balance}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]\n" - f" Total TAO Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]" - # f"\n Total TAO Swapped Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_swapped_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]" + f" Coldkey SS58: " + f"[{COLOR_PALETTE.G.CK}]{coldkey_address}[/{COLOR_PALETTE.G.CK}]\n" + f" Free Balance: " + f"[{COLOR_PALETTE.G.BALANCE}]{balance}[/{COLOR_PALETTE.G.BALANCE}]\n" + f" Total TAO Swapped Value ({Balance.unit}): " + f"[{COLOR_PALETTE.G.BALANCE}]{total_swapped_tao_value}[/{COLOR_PALETTE.G.BALANCE}]\n" + f" Total TAO Value (including free balance) ({Balance.unit}): " + f"[{COLOR_PALETTE.G.BALANCE}]{total_tao_value}[/{COLOR_PALETTE.G.BALANCE}]\n" ) dict_output["free_balance"] = balance.tao dict_output["total_tao_value"] = all_hks_tao_value.tao diff --git a/bittensor_cli/src/commands/wallets.py b/bittensor_cli/src/commands/wallets.py index 6473f2c69..4b42b40dd 100644 --- a/bittensor_cli/src/commands/wallets.py +++ b/bittensor_cli/src/commands/wallets.py @@ -30,7 +30,10 @@ ) from bittensor_cli.src.bittensor.extrinsics.transfer import transfer_extrinsic from bittensor_cli.src.bittensor.networking import int_to_ip -from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface +from bittensor_cli.src.bittensor.subtensor_interface import ( + SubtensorInterface, + GENESIS_ADDRESS, +) from bittensor_cli.src.bittensor.utils import ( RAO_PER_TAO, console, @@ -2261,10 +2264,7 @@ async def check_swap_status( chain_reported_completion_block, destination_address = await subtensor.query( "SubtensorModule", "ColdkeySwapScheduled", [origin_ss58] ) - if ( - chain_reported_completion_block != 0 - and destination_address != "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" - ): + if chain_reported_completion_block != 0 and destination_address != GENESIS_ADDRESS: is_pending = True else: is_pending = False