Spaces:
Running
Running
import bittensor as bt | |
from substrateinterface import Keypair | |
import gradio as gr | |
import pandas as pd | |
import time | |
# primitive caching | |
g_cached_data: pd.DataFrame | None = None | |
g_last_fetch_time = 0.0 | |
def fetch_incentive_data() -> pd.DataFrame: | |
data = [] | |
subtensor = bt.subtensor(network="finney") | |
print("connected to subtensor") | |
subnets = subtensor.all_subnets() | |
print("fetched all subnets") | |
metagraphs = subtensor.get_all_metagraphs_info() | |
print("fetched all metagraphs") | |
assert subnets, "WTF" | |
assert metagraphs, "WTF" | |
for sn in range(1, 129): | |
subnet = subnets[sn] | |
metagraph = metagraphs[sn] | |
hotkeys_to_uid = {hk: i for i, hk in enumerate(metagraph.hotkeys)} | |
# The incentives that are assigned to the owner hotkey are being burned/not given out | |
# by Maciej Kula [Bo𝞃, Bo𝞃] 23.07.2025 | |
addresses = [("hotkey", subnet.owner_hotkey)] # So don't include ("coldkey", subnet.owner_coldkey). | |
for key_type, address in addresses: | |
uid = hotkeys_to_uid.get(address, None) | |
if uid is None: | |
continue | |
incentive = metagraph.incentives[uid] | |
if incentive <= 0: | |
continue | |
is_active = metagraph.pending_root_emission.tao > 0 and metagraph.alpha_out_emission > 0 and metagraph.moving_price > 0 | |
data.append([ | |
f"[netuid: {sn} / {subnet.subnet_name}](https://taostats.io/subnets/{sn})", | |
is_active, | |
round(subnet.alpha_to_tao(1).tao, 6), | |
round(incentive*100, 2), | |
f"[{address}](https://taostats.io/{key_type}/{address}) [{uid}]" | |
]) | |
break | |
df = pd.DataFrame(data, columns=["Subnet", "Active", "α to τ", "Burn (%)", "Address [UID]"]) # type: ignore | |
print(f"{len(data)} subnets burn") | |
return df | |
def get_cached_data() -> tuple[str, pd.DataFrame]: | |
global g_cached_data, g_last_fetch_time | |
if g_cached_data is None or (time.time() - g_last_fetch_time) > 1200: # 20 min | |
g_last_fetch_time = time.time() | |
g_cached_data = fetch_incentive_data() | |
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(g_last_fetch_time + 1200)) | |
return time_str, g_cached_data | |
with gr.Blocks(title="Bittensor Subnet Incentives") as demo: | |
gr.HTML( | |
""" | |
<div style="text-align: center"> | |
<h1>Burntensor</h1> | |
<img src='https://huggingface.co/spaces/pawkanarek/burntensor/resolve/main/assets/burn.gif' widht=200 style="display: block; margin: 0 auto;" /> | |
<h3>This dashboard displays the burn percentage set by subnet owners for miners. Fetching data takes ~1min</h3> | |
</div> | |
""" | |
) | |
next_process_text = gr.Textbox(label="Next refresh time", interactive=False) | |
output_df = gr.DataFrame( | |
datatype=["markdown", "bool", "number", "number", "markdown"], | |
label="Subnet Burn Data", | |
show_row_numbers=True, | |
interactive=False, | |
max_height=1000000 | |
) | |
demo.load(get_cached_data, None, [next_process_text, output_df]) | |
demo.launch() | |