Archie
Auto-load top issuers, remove unnecessary button
214809e
"""
BlockchainToken Explorer β€” HuggingFace Space
Search 303,330 Dogeparty & Counterparty blockchain assets.
Data served from blockchaintoken.com API.
"""
import gradio as gr
import requests
import pandas as pd
API_BASE = "https://blockchaintoken.com/api.php"
def get_stats(network):
r = requests.get(API_BASE, params={"action": "stats", "network": network}, timeout=10)
return r.json()
def search_assets(query, network, asset_type, page):
params = {"action": "search", "network": network, "q": query, "page": int(page)}
if asset_type and asset_type != "all":
params["type"] = asset_type
r = requests.get(API_BASE, params=params, timeout=10)
data = r.json()
if not data.get("results"):
return pd.DataFrame(), f"No results found for '{query}'"
rows = []
for a in data["results"]:
rows.append({
"Asset": a.get("asset_longname") or a.get("asset", ""),
"Type": a.get("type", ""),
"Supply": f"{a.get('supply', 0):,.0f}",
"Divisible": "Yes" if a.get("divisible") else "No",
"Locked": "πŸ”’" if a.get("locked") else "",
"Description": (a.get("description") or "")[:100],
"Issuer": (a.get("issuer") or "")[:20] + "..." if len(a.get("issuer","")) > 20 else a.get("issuer",""),
})
df = pd.DataFrame(rows)
info = f"Page {data.get('page',1)} of {data.get('pages',1)} β€” {data.get('total',0):,} total results"
return df, info
def get_asset_detail(asset_name, network):
if not asset_name.strip():
return "Enter an asset name"
r = requests.get(API_BASE, params={"action": "asset", "network": network, "asset": asset_name.strip()}, timeout=10)
data = r.json()
if "error" in data:
return f"❌ {data['error']}"
lines = [
f"# {data.get('asset_longname') or data.get('asset', 'Unknown')}",
"",
f"**Network:** {network.title()}",
f"**Type:** {data.get('type', 'unknown')}",
f"**Supply:** {data.get('supply', 0):,.8f}" if data.get('divisible') else f"**Supply:** {data.get('supply', 0):,.0f}",
f"**Divisible:** {'Yes' if data.get('divisible') else 'No'}",
f"**Locked:** {'Yes πŸ”’' if data.get('locked') else 'No'}",
f"**Issuer:** `{data.get('issuer', 'unknown')}`",
f"**Owner:** `{data.get('owner', 'unknown')}`",
]
if data.get("description"):
lines.append(f"**Description:** {data['description']}")
return "\n".join(lines)
def get_top_issuers(network):
r = requests.get(API_BASE, params={"action": "issuers", "network": network}, timeout=10)
data = r.json()
if not data.get("issuers"):
return pd.DataFrame()
rows = []
for iss in data["issuers"][:20]:
rows.append({
"Address": iss.get("issuer","")[:16] + "..." if len(iss.get("issuer","")) > 16 else iss.get("issuer",""),
"Full Address": iss.get("issuer",""),
"Assets Created": iss.get("count", 0),
})
return pd.DataFrame(rows)
def load_stats(network):
try:
s = get_stats(network)
return (
f"### {network.title()} Network\n\n"
f"| Metric | Count |\n|--------|-------|\n"
f"| **Total Assets** | **{s['total']:,}** |\n"
f"| Named | {s['named']:,} |\n"
f"| Numeric | {s['numeric']:,} |\n"
f"| Subassets | {s['sub']:,} |\n"
f"| Locked | {s['locked']:,} |"
)
except Exception as e:
return f"Error loading stats: {e}"
# Build the UI
theme = gr.themes.Base(
primary_hue="amber",
neutral_hue="gray",
font=gr.themes.GoogleFont("Space Grotesk"),
font_mono=gr.themes.GoogleFont("JetBrains Mono"),
).set(
body_background_fill="#ffffff",
body_background_fill_dark="#1a1a2e",
block_background_fill="#f8f8f8",
block_background_fill_dark="#22223a",
body_text_color="#1a1a1a",
body_text_color_dark="#e8e6e3",
block_label_text_color="#1a1a1a",
block_label_text_color_dark="#b0b0bc",
block_title_text_color="#1a1a1a",
block_title_text_color_dark="#b0b0bc",
button_primary_background_fill="#b8941e",
button_primary_background_fill_dark="#c4a035",
button_primary_text_color="#ffffff",
button_primary_text_color_dark="#0a0a0f",
border_color_primary="#b8941e",
border_color_primary_dark="#c4a035",
input_background_fill="#ffffff",
input_background_fill_dark="#2a2a42",
input_border_color="#cccccc",
input_border_color_dark="#444466",
)
css = """
.gradio-container { max-width: 1200px !important; }
.main-header { text-align: center; margin-bottom: 1rem; }
.main-header h1 { font-family: 'JetBrains Mono', monospace; color: #b8941e !important; }
.main-header p { color: #555 !important; }
footer { display: none !important; }
/* Ensure all text is readable */
.gradio-dataframe td, .gradio-dataframe th { color: #1a1a1a !important; }
.dark .gradio-dataframe td, .dark .gradio-dataframe th { color: #e8e6e3 !important; }
/* Radio buttons, checkboxes, labels */
.gradio-radio label span, .gradio-radio .group_label,
input[type="radio"] + label, .radio-group label,
label.svelte-1qxcj04, span.svelte-1qxcj04,
.block label span, .wrap label span { color: #1a1a1a !important; }
.dark .block label span, .dark .wrap label span { color: #e8e6e3 !important; }
/* All form labels and text - force black */
.label-wrap span, .block .label-wrap, .gradio-group label,
label, .label-wrap, .block label, span[data-testid],
.gradio-container label, .gradio-container .label-wrap span,
.block .wrap .label-wrap span, h3, h4 { color: #1a1a1a !important; }
.dark .label-wrap span, .dark .block .label-wrap { color: #e8e6e3 !important; }
/* Input text */
input, textarea, select, .input-text { color: #1a1a1a !important; }
.dark input, .dark textarea, .dark select { color: #e8e6e3 !important; }
/* Dropdown and textbox */
.secondary-text, .token-text { color: #555 !important; }
"""
with gr.Blocks(theme=theme, css=css, title="BlockchainToken Explorer") as demo:
gr.HTML("""
<div class="main-header">
<h1>Ð BLOCKCHAIN<span style="color:#888;font-weight:400">TOKEN</span></h1>
<p style="color:#555;font-size:0.9rem;">
The most comprehensive Dogeparty & Counterparty asset database β€” 303,330 assets indexed.
<br>Powered by <a href="https://blockchaintoken.com" style="color:#c4a035">blockchaintoken.com</a>
</p>
</div>
""")
with gr.Row():
network = gr.Radio(
choices=["dogeparty", "counterparty"],
value="dogeparty",
label="Network",
scale=1,
)
stats_display = gr.Markdown(label="Stats")
# Load stats on network change
network.change(fn=load_stats, inputs=network, outputs=stats_display)
demo.load(fn=load_stats, inputs=network, outputs=stats_display)
with gr.Tabs():
with gr.Tab("πŸ” Search Assets"):
with gr.Row():
search_query = gr.Textbox(label="Search", placeholder="Enter asset name...", scale=3)
search_type = gr.Dropdown(
choices=["all", "named", "numeric", "subasset"],
value="all", label="Type", scale=1
)
search_page = gr.Number(value=1, label="Page", minimum=1, scale=1)
search_btn = gr.Button("Search", variant="primary", scale=1)
search_info = gr.Textbox(label="Results", interactive=False)
search_results = gr.Dataframe(
label="Assets",
headers=["Asset", "Type", "Supply", "Divisible", "Locked", "Description", "Issuer"],
interactive=False,
)
search_btn.click(
fn=search_assets,
inputs=[search_query, network, search_type, search_page],
outputs=[search_results, search_info]
)
search_query.submit(
fn=search_assets,
inputs=[search_query, network, search_type, search_page],
outputs=[search_results, search_info]
)
with gr.Tab("πŸ“‹ Asset Detail"):
with gr.Row():
asset_input = gr.Textbox(label="Asset Name", placeholder="e.g. PEPECASH, XDP, FDCARD", scale=3)
detail_btn = gr.Button("Look Up", variant="primary", scale=1)
asset_detail = gr.Markdown(label="Asset Information")
detail_btn.click(fn=get_asset_detail, inputs=[asset_input, network], outputs=asset_detail)
asset_input.submit(fn=get_asset_detail, inputs=[asset_input, network], outputs=asset_detail)
with gr.Tab("πŸ† Top Issuers"):
issuer_table = gr.Dataframe(
label="Top 20 Asset Creators",
headers=["Address", "Full Address", "Assets Created"],
interactive=False,
)
# Auto-load on network change and page load
network.change(fn=get_top_issuers, inputs=network, outputs=issuer_table)
demo.load(fn=get_top_issuers, inputs=network, outputs=issuer_table)
gr.HTML("""
<div style="text-align:center;margin-top:2rem;padding:1rem;border-top:1px solid #ddd;">
<p style="font-family:'JetBrains Mono',monospace;font-size:0.7rem;color:#666;">
DATA: <a href="https://blockchaintoken.com" style="color:#b8941e">blockchaintoken.com</a> Β·
API: <a href="https://blockchaintoken.com/api.php?action=stats" style="color:#b8941e">Free JSON API</a> Β·
<a href="https://dogeparty.net" style="color:#b8941e">Dogeparty</a> Β·
<a href="https://counterparty.io" style="color:#b8941e">Counterparty</a>
</p>
</div>
""")
if __name__ == "__main__":
demo.launch()