|
import requests |
|
import pandas as pd |
|
import gradio as gr |
|
import plotly.graph_objects as go |
|
import plotly.express as px |
|
from datetime import datetime, timedelta |
|
import json |
|
|
|
|
|
import os |
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
import matplotlib.dates as mdates |
|
import random |
|
|
|
|
|
|
|
from apr_visualization import generate_apr_visualizations |
|
|
|
|
|
def create_transcation_visualizations(): |
|
"""Dummy implementation that returns a placeholder graph""" |
|
fig = go.Figure() |
|
fig.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
return fig |
|
|
|
def create_active_agents_visualizations(): |
|
"""Dummy implementation that returns a placeholder graph""" |
|
fig = go.Figure() |
|
fig.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
return fig |
|
|
|
|
|
""" |
|
# Load environment variables from .env file |
|
# RPC URLs |
|
OPTIMISM_RPC_URL = os.getenv('OPTIMISM_RPC_URL') |
|
MODE_RPC_URL = os.getenv('MODE_RPC_URL') |
|
|
|
# Initialize Web3 instances |
|
web3_instances = { |
|
'optimism': Web3(Web3.HTTPProvider(OPTIMISM_RPC_URL)), |
|
'mode': Web3(Web3.HTTPProvider(MODE_RPC_URL)) |
|
} |
|
|
|
# Contract addresses for service registries |
|
contract_addresses = { |
|
'optimism': '0x3d77596beb0f130a4415df3D2D8232B3d3D31e44', |
|
'mode': '0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE' |
|
} |
|
|
|
# Load the ABI from the provided JSON file |
|
with open('./contracts/service_registry_abi.json', 'r') as abi_file: |
|
contract_abi = json.load(abi_file) |
|
|
|
# Create the contract instances |
|
service_registries = { |
|
chain_name: web3.eth.contract(address=contract_addresses[chain_name], abi=contract_abi) |
|
for chain_name, web3 in web3_instances.items() |
|
} |
|
|
|
# Check if connections are successful |
|
for chain_name, web3_instance in web3_instances.items(): |
|
if not web3_instance.is_connected(): |
|
raise Exception(f"Failed to connect to the {chain_name.capitalize()} network.") |
|
else: |
|
print(f"Successfully connected to the {chain_name.capitalize()} network.") |
|
""" |
|
|
|
|
|
def get_transfers(integrator: str, wallet: str) -> str: |
|
"""Dummy function that returns an empty result""" |
|
return {"transfers": []} |
|
|
|
def fetch_and_aggregate_transactions(): |
|
"""Dummy function that returns empty data""" |
|
return [], {} |
|
|
|
|
|
def process_transactions_and_agents(data): |
|
"""Dummy function that returns empty dataframes""" |
|
df_transactions = pd.DataFrame() |
|
df_agents = pd.DataFrame(columns=['date', 'agent_count']) |
|
df_agents_weekly = pd.DataFrame() |
|
return df_transactions, df_agents, df_agents_weekly |
|
|
|
|
|
def create_visualizations(): |
|
""" |
|
# Commenting out the original visualization code temporarily for debugging |
|
transactions_data = fetch_and_aggregate_transactions() |
|
df_transactions, df_agents, df_agents_weekly = process_transactions_and_agents(transactions_data) |
|
|
|
# Fetch daily value locked data |
|
df_tvl = pd.read_csv('daily_value_locked.csv') |
|
|
|
# Calculate total value locked per chain per day |
|
df_tvl["total_value_locked_usd"] = df_tvl["amount0_usd"] + df_tvl["amount1_usd"] |
|
df_tvl_daily = df_tvl.groupby(["date", "chain_name"])["total_value_locked_usd"].sum().reset_index() |
|
df_tvl_daily['date'] = pd.to_datetime(df_tvl_daily['date']) |
|
|
|
# Filter out dates with zero total value locked |
|
df_tvl_daily = df_tvl_daily[df_tvl_daily["total_value_locked_usd"] > 0] |
|
|
|
chain_name_map = { |
|
"mode": "Mode", |
|
"base": "Base", |
|
"ethereum": "Ethereum", |
|
"optimism": "Optimism" |
|
} |
|
df_tvl_daily["chain_name"] = df_tvl_daily["chain_name"].map(chain_name_map) |
|
|
|
# Plot total value locked |
|
fig_tvl = px.bar( |
|
df_tvl_daily, |
|
x="date", |
|
y="total_value_locked_usd", |
|
color="chain_name", |
|
opacity=0.7, |
|
title="Total Volume Invested in Pools in Different Chains Daily", |
|
labels={"date": "Date","chain_name": "Transaction Chain", "total_value_locked_usd": "Total Volume Invested (USD)"}, |
|
barmode='stack', |
|
color_discrete_map={ |
|
"Mode": "orange", |
|
"Base": "purple", |
|
"Ethereum": "darkgreen", |
|
"Optimism": "blue" |
|
} |
|
) |
|
fig_tvl.update_layout( |
|
xaxis_title="Date", |
|
|
|
yaxis=dict(tickmode='linear', tick0=0, dtick=4), |
|
xaxis=dict( |
|
tickmode='array', |
|
tickvals=df_tvl_daily['date'], |
|
ticktext=df_tvl_daily['date'].dt.strftime('%b %d'), |
|
tickangle=-45, |
|
), |
|
bargap=0.6, # Increase gap between bar groups (0-1) |
|
bargroupgap=0.1, # Decrease gap between bars in a group (0-1) |
|
height=600, |
|
width=1200, # Specify width to prevent bars from being too wide |
|
showlegend=True, |
|
template='plotly_white' |
|
) |
|
fig_tvl.update_xaxes(tickformat="%b %d") |
|
|
|
chain_name_map = { |
|
10: "Optimism", |
|
8453: "Base", |
|
1: "Ethereum", |
|
34443: "Mode" |
|
} |
|
|
|
df_transactions["sending_chain"] = df_transactions["sending_chain"].map(chain_name_map) |
|
df_transactions["receiving_chain"] = df_transactions["receiving_chain"].map(chain_name_map) |
|
|
|
df_transactions["sending_chain"] = df_transactions["sending_chain"].astype(str) |
|
df_transactions["receiving_chain"] = df_transactions["receiving_chain"].astype(str) |
|
df_transactions['date'] = pd.to_datetime(df_transactions['date']) |
|
df_transactions["is_swap"] = df_transactions.apply(lambda x: x["sending_chain"] == x["receiving_chain"], axis=1) |
|
|
|
swaps_per_chain = df_transactions[df_transactions["is_swap"]].groupby(["date", "sending_chain"]).size().reset_index(name="swap_count") |
|
fig_swaps_chain = px.bar( |
|
swaps_per_chain, |
|
x="date", |
|
y="swap_count", |
|
color="sending_chain", |
|
title="Chain Daily Activity: Swaps", |
|
labels={"sending_chain": "Transaction Chain", "swap_count": "Daily Swap Nr"}, |
|
barmode="stack", |
|
opacity=0.7, |
|
color_discrete_map={ |
|
"Optimism": "blue", |
|
"Ethereum": "darkgreen", |
|
"Base": "purple", |
|
"Mode": "orange" |
|
} |
|
) |
|
fig_swaps_chain.update_layout( |
|
xaxis_title="Date", |
|
yaxis_title="Daily Swap Count", |
|
yaxis=dict(tickmode='linear', tick0=0, dtick=1), |
|
xaxis=dict( |
|
tickmode='array', |
|
tickvals=[d for d in swaps_per_chain['date']], |
|
ticktext=[d.strftime('%m-%d') for d in swaps_per_chain['date']], |
|
tickangle=-45, |
|
), |
|
bargap=0.6, |
|
bargroupgap=0.1, |
|
height=600, |
|
width=1200, |
|
margin=dict(l=50, r=50, t=50, b=50), |
|
showlegend=True, |
|
legend=dict( |
|
yanchor="top", |
|
y=0.99, |
|
xanchor="right", |
|
x=0.99 |
|
), |
|
template='plotly_white' |
|
) |
|
fig_swaps_chain.update_xaxes(tickformat="%m-%d") |
|
|
|
df_transactions["is_bridge"] = df_transactions.apply(lambda x: x["sending_chain"] != x["receiving_chain"], axis=1) |
|
|
|
bridges_per_chain = df_transactions[df_transactions["is_bridge"]].groupby(["date", "sending_chain"]).size().reset_index(name="bridge_count") |
|
fig_bridges_chain = px.bar( |
|
bridges_per_chain, |
|
x="date", |
|
y="bridge_count", |
|
color="sending_chain", |
|
title="Chain Daily Activity: Bridges", |
|
labels={"sending_chain": "Transaction Chain", "bridge_count": "Daily Bridge Nr"}, |
|
barmode="stack", |
|
opacity=0.7, |
|
color_discrete_map={ |
|
"Optimism": "blue", |
|
"Ethereum": "darkgreen", |
|
"Base": "purple", |
|
"Mode": "orange" |
|
} |
|
) |
|
fig_bridges_chain.update_layout( |
|
xaxis_title="Date", |
|
yaxis_title="Daily Bridge Count", |
|
yaxis=dict(tickmode='linear', tick0=0, dtick=1), |
|
xaxis=dict( |
|
tickmode='array', |
|
tickvals=[d for d in bridges_per_chain['date']], |
|
ticktext=[d.strftime('%m-%d') for d in bridges_per_chain['date']], |
|
tickangle=-45, |
|
), |
|
bargap=0.6, |
|
bargroupgap=0.1, |
|
height=600, |
|
width=1200, |
|
margin=dict(l=50, r=50, t=50, b=50), |
|
showlegend=True, |
|
legend=dict( |
|
yanchor="top", |
|
y=0.99, |
|
xanchor="right", |
|
x=0.99 |
|
), |
|
template='plotly_white' |
|
) |
|
fig_bridges_chain.update_xaxes(tickformat="%m-%d") |
|
df_agents['date'] = pd.to_datetime(df_agents['date']) |
|
|
|
daily_agents_df = df_agents.groupby('date').agg({'agent_count': 'sum'}).reset_index() |
|
daily_agents_df.rename(columns={'agent_count': 'daily_agent_count'}, inplace=True) |
|
# Sort by date to ensure proper running total calculation |
|
daily_agents_df = daily_agents_df.sort_values('date') |
|
|
|
# Create week column |
|
daily_agents_df['week'] = daily_agents_df['date'].dt.to_period('W').apply(lambda r: r.start_time) |
|
|
|
# Calculate running total within each week |
|
daily_agents_df['running_weekly_total'] = daily_agents_df.groupby('week')['daily_agent_count'].cumsum() |
|
|
|
# Create final merged dataframe |
|
weekly_merged_df = daily_agents_df.copy() |
|
adjustment_date = pd.to_datetime('2024-11-15') |
|
weekly_merged_df.loc[weekly_merged_df['date'] == adjustment_date, 'daily_agent_count'] -= 1 |
|
weekly_merged_df.loc[weekly_merged_df['date'] == adjustment_date, 'running_weekly_total'] -= 1 |
|
fig_agents_registered = go.Figure(data=[ |
|
go.Bar( |
|
name='Daily nr of Registered Agents', |
|
x=weekly_merged_df['date'].dt.strftime("%b %d"), |
|
y=weekly_merged_df['daily_agent_count'], |
|
opacity=0.7, |
|
marker_color='blue' |
|
), |
|
go.Bar( |
|
name='Weekly Nr of Registered Agents', |
|
x=weekly_merged_df['date'].dt.strftime("%b %d"), |
|
y=weekly_merged_df['running_weekly_total'], |
|
opacity=0.7, |
|
marker_color='purple' |
|
) |
|
]) |
|
|
|
fig_agents_registered.update_layout( |
|
xaxis_title='Date', |
|
yaxis_title='Number of Agents', |
|
title="Nr of Agents Registered", |
|
barmode='group', |
|
yaxis=dict(tickmode='linear', tick0=0, dtick=1), |
|
xaxis=dict( |
|
categoryorder='array', |
|
categoryarray=weekly_merged_df['date'].dt.strftime("%b %d"), |
|
tickangle=-45 |
|
), |
|
bargap=0.3, |
|
height=600, |
|
width=1200, |
|
showlegend=True, |
|
legend=dict( |
|
yanchor="top", |
|
xanchor="right", |
|
), |
|
template='plotly_white', |
|
) |
|
|
|
return fig_swaps_chain, fig_bridges_chain, fig_agents_registered,fig_tvl |
|
""" |
|
|
|
fig_swaps_chain = go.Figure() |
|
fig_swaps_chain.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
|
|
fig_bridges_chain = go.Figure() |
|
fig_bridges_chain.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
|
|
fig_agents_registered = go.Figure() |
|
fig_agents_registered.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
|
|
fig_tvl = go.Figure() |
|
fig_tvl.add_annotation( |
|
text="Blockchain data loading disabled - placeholder visualization", |
|
x=0.5, y=0.5, xref="paper", yref="paper", |
|
showarrow=False, font=dict(size=20) |
|
) |
|
|
|
return fig_swaps_chain, fig_bridges_chain, fig_agents_registered, fig_tvl |
|
|
|
|
|
def dashboard(): |
|
with gr.Blocks() as demo: |
|
gr.Markdown("# Valory APR Metrics") |
|
|
|
|
|
with gr.Tab("APR Metrics"): |
|
with gr.Column(): |
|
refresh_btn = gr.Button("Refresh APR Data") |
|
|
|
|
|
per_agent_graph = gr.Plot(label="APR Per Agent") |
|
combined_graph = gr.Plot(label="Combined APR (All Agents)") |
|
|
|
|
|
def update_apr_graphs(): |
|
|
|
per_agent_fig, combined_fig, _ = generate_apr_visualizations() |
|
return per_agent_fig, combined_fig |
|
|
|
|
|
refresh_btn.click( |
|
fn=update_apr_graphs, |
|
inputs=[], |
|
outputs=[per_agent_graph, combined_graph] |
|
) |
|
|
|
|
|
|
|
import plotly.graph_objects as go |
|
placeholder_fig = go.Figure() |
|
placeholder_fig.add_annotation( |
|
text="Click 'Refresh APR Data' to load APR graphs", |
|
x=0.5, y=0.5, |
|
showarrow=False, |
|
font=dict(size=15) |
|
) |
|
per_agent_graph.value = placeholder_fig |
|
combined_graph.value = placeholder_fig |
|
|
|
return demo |
|
|
|
|
|
if __name__ == "__main__": |
|
dashboard().launch() |