import requests import pandas as pd import gradio as gr import plotly.express as px from datetime import datetime # Function to fetch and process the transaction data from the API def fetch_transactions(): url = "https://li.quest/v1/analytics/transfers?integrator=valory" headers = {"accept": "application/json"} response = requests.get(url, headers=headers) return response.json() # Function to parse the transaction data and prepare it for visualization def process_transactions(data): transactions = data["transfers"] # Convert the data into a pandas DataFrame for easy manipulation rows = [] for tx in transactions: # Normalize amounts sending_amount = float(tx["sending"]["amount"]) / (10 ** tx["sending"]["token"]["decimals"]) receiving_amount = float(tx["receiving"]["amount"]) / (10 ** tx["receiving"]["token"]["decimals"]) # Convert timestamps to datetime objects sending_timestamp = datetime.utcfromtimestamp(tx["sending"]["timestamp"]) receiving_timestamp = datetime.utcfromtimestamp(tx["receiving"]["timestamp"]) # Prepare row data rows.append({ "transactionId": tx["transactionId"], "from_address": tx["fromAddress"], "to_address": tx["toAddress"], "sending_chain": tx["sending"]["chainId"], "receiving_chain": tx["receiving"]["chainId"], "sending_token_symbol": tx["sending"]["token"]["symbol"], "receiving_token_symbol": tx["receiving"]["token"]["symbol"], "sending_amount": sending_amount, "receiving_amount": receiving_amount, "sending_amount_usd": float(tx["sending"]["amountUSD"]), "receiving_amount_usd": float(tx["receiving"]["amountUSD"]), "sending_gas_used": int(tx["sending"]["gasUsed"]), "receiving_gas_used": int(tx["receiving"]["gasUsed"]), "sending_timestamp": sending_timestamp, "receiving_timestamp": receiving_timestamp, "date": sending_timestamp.date(), # Group by day "week": sending_timestamp.strftime('%Y-%W') # Group by week }) df = pd.DataFrame(rows) return df # Function to create visualizations based on the metrics def create_visualizations(): transactions_data = fetch_transactions() df = process_transactions(transactions_data) # Ensure that chain IDs are strings for consistent grouping df["sending_chain"] = df["sending_chain"].astype(str) df["receiving_chain"] = df["receiving_chain"].astype(str) # 1. Number of Transactions per Chain per Day per Agent tx_per_chain_agent = df.groupby(["date", "from_address", "sending_chain"]).size().reset_index(name="transaction_count") fig_tx_chain_agent = px.bar(tx_per_chain_agent, x="date", y="transaction_count", color="sending_chain", barmode="group", facet_col="from_address", title="Number of Transactions per Chain per Agent per Day") # 2. Number of Opportunities Taken per Agent per Day opportunities_per_agent = df.groupby(["date", "from_address"]).size().reset_index(name="opportunities_taken") fig_opportunities_agent = px.bar(opportunities_per_agent, x="date", y="opportunities_taken", color="from_address", title="Number of Opportunities Taken per Agent per Day") # 3. Amount of Investment in Pools Daily per Agent (Note: Assuming sending_amount_usd as investment) # Since we might not have explicit data about pool investments, we'll use sending_amount_usd investment_per_agent = df.groupby(["date", "from_address"])["sending_amount_usd"].sum().reset_index() fig_investment_agent = px.bar(investment_per_agent, x="date", y="sending_amount_usd", color="from_address", title="Amount of Investment (USD) per Agent per Day") # 4. Number of Swaps per Day # Assuming each transaction is a swap if sending and receiving tokens are different df["is_swap"] = df.apply(lambda x: x["sending_token_symbol"] != x["receiving_token_symbol"], axis=1) swaps_per_day = df[df["is_swap"]].groupby("date").size().reset_index(name="swap_count") fig_swaps_per_day = px.bar(swaps_per_day, x="date", y="swap_count", title="Number of Swaps per Day") # 5. Aggregated Metrics over All Traders amount_usd = df["sending_amount_usd"] stats = { "Total": amount_usd.sum(), "Average": amount_usd.mean(), "Min": amount_usd.min(), "Max": amount_usd.max(), "25th Percentile": amount_usd.quantile(0.25), "50th Percentile (Median)": amount_usd.median(), "75th Percentile": amount_usd.quantile(0.75), } stats_df = pd.DataFrame(list(stats.items()), columns=["Metric", "Value"]) # Visualization for Aggregated Metrics fig_stats = px.bar(stats_df, x="Metric", y="Value", title="Aggregated Transaction Amount Metrics (USD)") return fig_tx_chain_agent, fig_opportunities_agent, fig_investment_agent, fig_swaps_per_day, fig_stats # Gradio interface def dashboard(): with gr.Blocks() as demo: gr.Markdown("# Valory Transactions Dashboard") # Fetch and display visualizations with gr.Tab("Transactions per Chain per Agent"): fig_tx_chain_agent, _, _, _, _ = create_visualizations() gr.Plot(fig_tx_chain_agent) with gr.Tab("Opportunities per Agent"): _, fig_opportunities_agent, _, _, _ = create_visualizations() gr.Plot(fig_opportunities_agent) with gr.Tab("Investment per Agent"): _, _, fig_investment_agent, _, _ = create_visualizations() gr.Plot(fig_investment_agent) with gr.Tab("Swaps per Day"): _, _, _, fig_swaps_per_day, _ = create_visualizations() gr.Plot(fig_swaps_per_day) with gr.Tab("Aggregated Metrics"): _, _, _, _, fig_stats = create_visualizations() gr.Plot(fig_stats) return demo # Launch the dashboard if __name__ == "__main__": dashboard().launch()