Spaces:
Runtime error
Runtime error
File size: 7,124 Bytes
e4a3f8e fd97ba6 e4a3f8e fd97ba6 e4a3f8e 07ba1e6 e4a3f8e fd97ba6 07ba1e6 fd97ba6 e4a3f8e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
import requests
import pandas as pd
import gradio as gr
import plotly.express as px
from datetime import datetime, timedelta
from web3 import Web3
from web3.middleware import geth_poa_middleware
# Optimism RPC endpoint (you can use Infura, Alchemy, or any other provider)
OPTIMISM_RPC = "https://mainnet.optimism.io"
# ServiceRegistry contract address and ABI
SERVICE_REGISTRY_ADDRESS = "0x3d77596beb0f130a4415df3D2D8232B3d3D31e44"
SERVICE_REGISTRY_ABI = [
# Include the ABI for the functions you need
# totalSupply() and getService(uint256)
{
"constant": True,
"inputs": [],
"name": "totalSupply",
"outputs": [{"name": "", "type": "uint256"}],
"type": "function",
},
{
"constant": True,
"inputs": [{"name": "serviceId", "type": "uint256"}],
"name": "getService",
"outputs": [
{"name": "owner", "type": "address"},
{"name": "multisig", "type": "address"},
{"name": "agentInstances", "type": "address[]"},
{"name": "threshold", "type": "uint32"},
{"name": "bonds", "type": "uint256[]"},
{"name": "agentIds", "type": "uint256[]"},
{"name": "state", "type": "uint8"},
],
"type": "function",
},
]
# Gnosis Safe ABI (for getting the nonce)
SAFE_ABI = [
{
"constant": True,
"inputs": [],
"name": "nonce",
"outputs": [{"name": "", "type": "uint256"}],
"type": "function",
},
]
def fetch_services():
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
service_registry = w3.eth.contract(
address=Web3.toChecksumAddress(SERVICE_REGISTRY_ADDRESS),
abi=SERVICE_REGISTRY_ABI,
)
total_services = service_registry.functions.totalSupply().call()
print(f"Total services: {total_services}")
services_data = []
for service_id in range(1, total_services + 1):
service = service_registry.functions.getService(service_id).call()
owner = service[0]
multisig = service[1]
agent_ids = service[5] # List of agent IDs
state = service[6]
# Filter for Optimus services (agentId == 25)
if 25 in agent_ids:
# Get the registration block number (we need to get the block number of the transaction that created the service)
# Since we don't have a subgraph, we'll approximate by using the block number of the latest transaction involving the service multisig
# Note: This is a simplification and may not be accurate
# For accurate results, a subgraph or indexed data is recommended
services_data.append({
"service_id": service_id,
"owner": owner,
"multisig": multisig,
"agent_ids": agent_ids,
"state": state,
})
return services_data
def fetch_service_creation_dates(services_data):
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
# Since we don't have direct access to service creation dates, we'll need to fetch historical logs
# Unfortunately, without a subgraph or an indexer, this is impractical for a large number of services
# As an alternative, we can skip this step or set approximate dates
# For demonstration, we'll set all registration dates to today
for service in services_data:
service["registration_date"] = datetime.utcnow().date()
return services_data
def check_service_transactions(services_data):
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
for service in services_data:
multisig_address = service["multisig"]
safe_contract = w3.eth.contract(
address=multisig_address,
abi=SAFE_ABI,
)
try:
nonce = safe_contract.functions.nonce().call()
service["nonce"] = nonce
except Exception as e:
# If the multisig is not a Gnosis Safe or the call fails
service["nonce"] = 0
return services_data
def process_services_data(services_data):
# Convert to DataFrame
df = pd.DataFrame(services_data)
# Convert registration_date to datetime
df["registration_date"] = pd.to_datetime(df["registration_date"])
# Add week number
df["week"] = df["registration_date"].dt.strftime('%Y-%W')
# Determine if service has made at least one transaction
df["has_transaction"] = df["nonce"] > 0
return df
def create_services_visualizations(df):
# 1) Number of services registered WoW
services_registered = df.groupby("week").size().reset_index(name="services_registered")
fig_services_registered = px.bar(services_registered, x="week", y="services_registered",
title="Number of Services Registered WoW")
# 2) Number of services making at least one transaction WoW
services_with_tx = df[df["has_transaction"]].groupby("week").size().reset_index(name="services_with_transaction")
fig_services_with_tx = px.bar(services_with_tx, x="week", y="services_with_transaction",
title="Number of Services with at Least One Transaction WoW")
return fig_services_registered, fig_services_with_tx
# Integrate with the existing dashboard
def dashboard():
with gr.Blocks() as demo:
gr.Markdown("# Valory Transactions Dashboard")
# Existing 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)
# New visualizations for services
with gr.Tab("Services Registered WoW"):
services_data = fetch_services()
services_data = fetch_service_creation_dates(services_data)
services_data = check_service_transactions(services_data)
df_services = process_services_data(services_data)
fig_services_registered, fig_services_with_tx = create_services_visualizations(df_services)
gr.Plot(fig_services_registered)
with gr.Tab("Services with Transactions WoW"):
gr.Plot(fig_services_with_tx)
return demo
if __name__ == "__main__":
dashboard().launch()
|