Edit on GitHub

communex.cli.misc

  1import typer
  2from typer import Context
  3
  4from communex._common import BalanceUnit, format_balance
  5from communex.balance import from_nano
  6from communex.cli._common import make_custom_context, print_module_info
  7from communex.client import CommuneClient
  8from communex.compat.key import local_key_addresses
  9from communex.misc import get_map_modules
 10from communex.types import ModuleInfoWithOptionalBalance
 11
 12misc_app = typer.Typer(no_args_is_help=True)
 13
 14
 15def circulating_tokens(c_client: CommuneClient) -> int:
 16    """
 17    Gets total circulating supply
 18    """
 19
 20    with c_client.get_conn(init=True) as substrate:
 21        block_hash = substrate.get_block_hash()
 22
 23    total_balance = c_client.get_total_free_issuance(block_hash=block_hash)
 24    total_stake = c_client.get_total_stake(block_hash=block_hash)
 25    return total_stake + total_balance
 26
 27
 28@misc_app.command()
 29def circulating_supply(ctx: Context, unit: BalanceUnit = BalanceUnit.joule):
 30    """
 31    Gets the value of all keys on the network, stake + balances
 32    """
 33    context = make_custom_context(ctx)
 34    client = context.com_client()
 35
 36    with context.progress_status(
 37        "Getting circulating supply, across all subnets..."
 38    ):
 39        supply = circulating_tokens(client)
 40
 41    context.output(format_balance(supply, unit))
 42
 43
 44@misc_app.command()
 45def apr(ctx: Context, fee: int = 0):
 46    """
 47    Gets the current staking APR on validators.
 48    The miner reinvest rate & fee are specified in percentages.
 49    """
 50    context = make_custom_context(ctx)
 51    client = context.com_client()
 52
 53    # adjusting the fee to the correct format
 54    # the default validator fee on the commune network is 20%
 55    fee_to_float = fee / 100
 56
 57    # network parameters
 58    block_time = 8  # seconds
 59    seconds_in_a_day = 86400
 60    blocks_in_a_day = seconds_in_a_day / block_time
 61
 62    with context.progress_status("Getting staking APR..."):
 63        unit_emission = client.get_unit_emission()
 64        total_staked_tokens = client.query("TotalStake")
 65    # 50% of the total emission goes to stakers
 66    daily_token_rewards = blocks_in_a_day * from_nano(unit_emission) / 2
 67    _apr = (
 68        (daily_token_rewards * (1 - fee_to_float) * 365)
 69        / total_staked_tokens
 70        * 100
 71    )
 72
 73    context.output(f"Fee {fee} | APR {_apr:.2f}%")
 74
 75
 76@misc_app.command(name="stats")
 77def stats(ctx: Context, balances: bool = False, netuid: int = 0):
 78    context = make_custom_context(ctx)
 79    client = context.com_client()
 80
 81    with context.progress_status(
 82        f"Getting Modules on a subnet with netuid {netuid}..."
 83    ):
 84        modules = get_map_modules(
 85            client, netuid=netuid, include_balances=balances
 86        )
 87    modules_to_list = [value for _, value in modules.items()]
 88    local_keys = local_key_addresses(password_provider=context.password_manager)
 89    local_modules = [
 90        *filter(
 91            lambda module: module["key"] in local_keys.values(), modules_to_list
 92        )
 93    ]
 94    local_miners: list[ModuleInfoWithOptionalBalance] = []
 95    local_validators: list[ModuleInfoWithOptionalBalance] = []
 96    local_inactive: list[ModuleInfoWithOptionalBalance] = []
 97    for module in local_modules:
 98        if module["incentive"] == module["dividends"] == 0:
 99            local_inactive.append(module)
100        elif module["incentive"] > module["dividends"]:
101            local_miners.append(module)
102        else:
103            local_validators.append(module)
104
105    print_module_info(
106        client, local_inactive, context.console, netuid, "inactive"
107    )
108    print_module_info(client, local_miners, context.console, netuid, "miners")
109    print_module_info(
110        client, local_validators, context.console, netuid, "validators"
111    )
112
113
114@misc_app.command(name="treasury-address")
115def get_treasury_address(ctx: Context):
116    context = make_custom_context(ctx)
117    client = context.com_client()
118
119    with context.progress_status("Getting DAO treasury address..."):
120        dao_address = client.get_dao_treasury_address()
121    context.output(dao_address)
122
123
124@misc_app.command()
125def delegate_rootnet_control(ctx: Context, key: str, target: str):
126    """
127    Delegates control of the rootnet to a key
128    """
129    context = make_custom_context(ctx)
130    client = context.com_client()
131    resolved_key = context.load_key(key, None)
132    ss58_target = context.resolve_key_ss58(target, None)
133
134    with context.progress_status("Delegating control of the rootnet..."):
135        client.delegate_rootnet_control(resolved_key, ss58_target)
136    context.info("Control delegated.")
misc_app = <typer.main.Typer object>
def circulating_tokens(c_client: communex.client.CommuneClient) -> int:
16def circulating_tokens(c_client: CommuneClient) -> int:
17    """
18    Gets total circulating supply
19    """
20
21    with c_client.get_conn(init=True) as substrate:
22        block_hash = substrate.get_block_hash()
23
24    total_balance = c_client.get_total_free_issuance(block_hash=block_hash)
25    total_stake = c_client.get_total_stake(block_hash=block_hash)
26    return total_stake + total_balance

Gets total circulating supply

@misc_app.command()
def circulating_supply( ctx: typer.models.Context, unit: communex._common.BalanceUnit = <BalanceUnit.joule: 'joule'>):
29@misc_app.command()
30def circulating_supply(ctx: Context, unit: BalanceUnit = BalanceUnit.joule):
31    """
32    Gets the value of all keys on the network, stake + balances
33    """
34    context = make_custom_context(ctx)
35    client = context.com_client()
36
37    with context.progress_status(
38        "Getting circulating supply, across all subnets..."
39    ):
40        supply = circulating_tokens(client)
41
42    context.output(format_balance(supply, unit))

Gets the value of all keys on the network, stake + balances

@misc_app.command()
def apr(ctx: typer.models.Context, fee: int = 0):
45@misc_app.command()
46def apr(ctx: Context, fee: int = 0):
47    """
48    Gets the current staking APR on validators.
49    The miner reinvest rate & fee are specified in percentages.
50    """
51    context = make_custom_context(ctx)
52    client = context.com_client()
53
54    # adjusting the fee to the correct format
55    # the default validator fee on the commune network is 20%
56    fee_to_float = fee / 100
57
58    # network parameters
59    block_time = 8  # seconds
60    seconds_in_a_day = 86400
61    blocks_in_a_day = seconds_in_a_day / block_time
62
63    with context.progress_status("Getting staking APR..."):
64        unit_emission = client.get_unit_emission()
65        total_staked_tokens = client.query("TotalStake")
66    # 50% of the total emission goes to stakers
67    daily_token_rewards = blocks_in_a_day * from_nano(unit_emission) / 2
68    _apr = (
69        (daily_token_rewards * (1 - fee_to_float) * 365)
70        / total_staked_tokens
71        * 100
72    )
73
74    context.output(f"Fee {fee} | APR {_apr:.2f}%")

Gets the current staking APR on validators. The miner reinvest rate & fee are specified in percentages.

@misc_app.command(name='stats')
def stats(ctx: typer.models.Context, balances: bool = False, netuid: int = 0):
 77@misc_app.command(name="stats")
 78def stats(ctx: Context, balances: bool = False, netuid: int = 0):
 79    context = make_custom_context(ctx)
 80    client = context.com_client()
 81
 82    with context.progress_status(
 83        f"Getting Modules on a subnet with netuid {netuid}..."
 84    ):
 85        modules = get_map_modules(
 86            client, netuid=netuid, include_balances=balances
 87        )
 88    modules_to_list = [value for _, value in modules.items()]
 89    local_keys = local_key_addresses(password_provider=context.password_manager)
 90    local_modules = [
 91        *filter(
 92            lambda module: module["key"] in local_keys.values(), modules_to_list
 93        )
 94    ]
 95    local_miners: list[ModuleInfoWithOptionalBalance] = []
 96    local_validators: list[ModuleInfoWithOptionalBalance] = []
 97    local_inactive: list[ModuleInfoWithOptionalBalance] = []
 98    for module in local_modules:
 99        if module["incentive"] == module["dividends"] == 0:
100            local_inactive.append(module)
101        elif module["incentive"] > module["dividends"]:
102            local_miners.append(module)
103        else:
104            local_validators.append(module)
105
106    print_module_info(
107        client, local_inactive, context.console, netuid, "inactive"
108    )
109    print_module_info(client, local_miners, context.console, netuid, "miners")
110    print_module_info(
111        client, local_validators, context.console, netuid, "validators"
112    )
@misc_app.command(name='treasury-address')
def get_treasury_address(ctx: typer.models.Context):
115@misc_app.command(name="treasury-address")
116def get_treasury_address(ctx: Context):
117    context = make_custom_context(ctx)
118    client = context.com_client()
119
120    with context.progress_status("Getting DAO treasury address..."):
121        dao_address = client.get_dao_treasury_address()
122    context.output(dao_address)
@misc_app.command()
def delegate_rootnet_control(ctx: typer.models.Context, key: str, target: str):
125@misc_app.command()
126def delegate_rootnet_control(ctx: Context, key: str, target: str):
127    """
128    Delegates control of the rootnet to a key
129    """
130    context = make_custom_context(ctx)
131    client = context.com_client()
132    resolved_key = context.load_key(key, None)
133    ss58_target = context.resolve_key_ss58(target, None)
134
135    with context.progress_status("Delegating control of the rootnet..."):
136        client.delegate_rootnet_control(resolved_key, ss58_target)
137    context.info("Control delegated.")

Delegates control of the rootnet to a key