Spaces:
Running
Running
gauravlochab
commited on
Commit
•
2a40784
1
Parent(s):
1854b8e
revertring changes
Browse files
app.py
CHANGED
@@ -2,156 +2,109 @@ import requests
|
|
2 |
import pandas as pd
|
3 |
import gradio as gr
|
4 |
import plotly.express as px
|
5 |
-
from datetime import datetime
|
6 |
-
|
7 |
-
from
|
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 |
-
def fetch_services():
|
53 |
-
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
|
54 |
-
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
|
55 |
-
|
56 |
-
service_registry = w3.eth.contract(
|
57 |
-
address=Web3.toChecksumAddress(SERVICE_REGISTRY_ADDRESS),
|
58 |
-
abi=SERVICE_REGISTRY_ABI,
|
59 |
-
)
|
60 |
-
|
61 |
-
total_services = service_registry.functions.totalSupply().call()
|
62 |
-
print(f"Total services: {total_services}")
|
63 |
-
|
64 |
-
services_data = []
|
65 |
-
for service_id in range(1, total_services + 1):
|
66 |
-
service = service_registry.functions.getService(service_id).call()
|
67 |
-
owner = service[0]
|
68 |
-
multisig = service[1]
|
69 |
-
agent_ids = service[5] # List of agent IDs
|
70 |
-
state = service[6]
|
71 |
-
|
72 |
-
# Filter for Optimus services (agentId == 25)
|
73 |
-
if 25 in agent_ids:
|
74 |
-
# Get the registration block number (we need to get the block number of the transaction that created the service)
|
75 |
-
# Since we don't have a subgraph, we'll approximate by using the block number of the latest transaction involving the service multisig
|
76 |
-
# Note: This is a simplification and may not be accurate
|
77 |
-
# For accurate results, a subgraph or indexed data is recommended
|
78 |
-
services_data.append({
|
79 |
-
"service_id": service_id,
|
80 |
-
"owner": owner,
|
81 |
-
"multisig": multisig,
|
82 |
-
"agent_ids": agent_ids,
|
83 |
-
"state": state,
|
84 |
-
})
|
85 |
-
|
86 |
-
return services_data
|
87 |
-
|
88 |
-
def fetch_service_creation_dates(services_data):
|
89 |
-
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
|
90 |
-
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
|
91 |
-
|
92 |
-
# Since we don't have direct access to service creation dates, we'll need to fetch historical logs
|
93 |
-
# Unfortunately, without a subgraph or an indexer, this is impractical for a large number of services
|
94 |
-
# As an alternative, we can skip this step or set approximate dates
|
95 |
-
|
96 |
-
# For demonstration, we'll set all registration dates to today
|
97 |
-
for service in services_data:
|
98 |
-
service["registration_date"] = datetime.utcnow().date()
|
99 |
-
|
100 |
-
return services_data
|
101 |
-
|
102 |
-
def check_service_transactions(services_data):
|
103 |
-
w3 = Web3(Web3.HTTPProvider(OPTIMISM_RPC))
|
104 |
-
w3.middleware_onion.inject(geth_poa_middleware, layer=0) # For Optimism
|
105 |
-
|
106 |
-
for service in services_data:
|
107 |
-
multisig_address = service["multisig"]
|
108 |
-
safe_contract = w3.eth.contract(
|
109 |
-
address=multisig_address,
|
110 |
-
abi=SAFE_ABI,
|
111 |
-
)
|
112 |
-
try:
|
113 |
-
nonce = safe_contract.functions.nonce().call()
|
114 |
-
service["nonce"] = nonce
|
115 |
-
except Exception as e:
|
116 |
-
# If the multisig is not a Gnosis Safe or the call fails
|
117 |
-
service["nonce"] = 0
|
118 |
-
|
119 |
-
return services_data
|
120 |
-
|
121 |
-
def process_services_data(services_data):
|
122 |
-
# Convert to DataFrame
|
123 |
-
df = pd.DataFrame(services_data)
|
124 |
-
|
125 |
-
# Convert registration_date to datetime
|
126 |
-
df["registration_date"] = pd.to_datetime(df["registration_date"])
|
127 |
-
|
128 |
-
# Add week number
|
129 |
-
df["week"] = df["registration_date"].dt.strftime('%Y-%W')
|
130 |
-
|
131 |
-
# Determine if service has made at least one transaction
|
132 |
-
df["has_transaction"] = df["nonce"] > 0
|
133 |
-
|
134 |
return df
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
def dashboard():
|
151 |
with gr.Blocks() as demo:
|
152 |
gr.Markdown("# Valory Transactions Dashboard")
|
153 |
|
154 |
-
#
|
155 |
with gr.Tab("Transactions per Chain per Agent"):
|
156 |
fig_tx_chain_agent, _, _, _, _ = create_visualizations()
|
157 |
gr.Plot(fig_tx_chain_agent)
|
@@ -171,20 +124,10 @@ def dashboard():
|
|
171 |
with gr.Tab("Aggregated Metrics"):
|
172 |
_, _, _, _, fig_stats = create_visualizations()
|
173 |
gr.Plot(fig_stats)
|
174 |
-
|
175 |
-
# New visualizations for services
|
176 |
-
with gr.Tab("Services Registered WoW"):
|
177 |
-
services_data = fetch_services()
|
178 |
-
services_data = fetch_service_creation_dates(services_data)
|
179 |
-
services_data = check_service_transactions(services_data)
|
180 |
-
df_services = process_services_data(services_data)
|
181 |
-
fig_services_registered, fig_services_with_tx = create_services_visualizations(df_services)
|
182 |
-
gr.Plot(fig_services_registered)
|
183 |
-
|
184 |
-
with gr.Tab("Services with Transactions WoW"):
|
185 |
-
gr.Plot(fig_services_with_tx)
|
186 |
|
187 |
return demo
|
188 |
|
|
|
189 |
if __name__ == "__main__":
|
190 |
dashboard().launch()
|
|
|
|
2 |
import pandas as pd
|
3 |
import gradio as gr
|
4 |
import plotly.express as px
|
5 |
+
from datetime import datetime
|
6 |
+
|
7 |
+
# Function to fetch and process the transaction data from the API
|
8 |
+
def fetch_transactions():
|
9 |
+
url = "https://li.quest/v1/analytics/transfers?integrator=valory"
|
10 |
+
headers = {"accept": "application/json"}
|
11 |
+
response = requests.get(url, headers=headers)
|
12 |
+
return response.json()
|
13 |
+
|
14 |
+
# Function to parse the transaction data and prepare it for visualization
|
15 |
+
def process_transactions(data):
|
16 |
+
transactions = data["transfers"]
|
17 |
+
|
18 |
+
# Convert the data into a pandas DataFrame for easy manipulation
|
19 |
+
rows = []
|
20 |
+
for tx in transactions:
|
21 |
+
# Normalize amounts
|
22 |
+
sending_amount = float(tx["sending"]["amount"]) / (10 ** tx["sending"]["token"]["decimals"])
|
23 |
+
receiving_amount = float(tx["receiving"]["amount"]) / (10 ** tx["receiving"]["token"]["decimals"])
|
24 |
+
|
25 |
+
# Convert timestamps to datetime objects
|
26 |
+
sending_timestamp = datetime.utcfromtimestamp(tx["sending"]["timestamp"])
|
27 |
+
receiving_timestamp = datetime.utcfromtimestamp(tx["receiving"]["timestamp"])
|
28 |
+
|
29 |
+
# Prepare row data
|
30 |
+
rows.append({
|
31 |
+
"transactionId": tx["transactionId"],
|
32 |
+
"from_address": tx["fromAddress"],
|
33 |
+
"to_address": tx["toAddress"],
|
34 |
+
"sending_chain": tx["sending"]["chainId"],
|
35 |
+
"receiving_chain": tx["receiving"]["chainId"],
|
36 |
+
"sending_token_symbol": tx["sending"]["token"]["symbol"],
|
37 |
+
"receiving_token_symbol": tx["receiving"]["token"]["symbol"],
|
38 |
+
"sending_amount": sending_amount,
|
39 |
+
"receiving_amount": receiving_amount,
|
40 |
+
"sending_amount_usd": float(tx["sending"]["amountUSD"]),
|
41 |
+
"receiving_amount_usd": float(tx["receiving"]["amountUSD"]),
|
42 |
+
"sending_gas_used": int(tx["sending"]["gasUsed"]),
|
43 |
+
"receiving_gas_used": int(tx["receiving"]["gasUsed"]),
|
44 |
+
"sending_timestamp": sending_timestamp,
|
45 |
+
"receiving_timestamp": receiving_timestamp,
|
46 |
+
"date": sending_timestamp.date(), # Group by day
|
47 |
+
"week": sending_timestamp.strftime('%Y-%W') # Group by week
|
48 |
+
})
|
49 |
+
|
50 |
+
df = pd.DataFrame(rows)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
return df
|
52 |
|
53 |
+
# Function to create visualizations based on the metrics
|
54 |
+
def create_visualizations():
|
55 |
+
transactions_data = fetch_transactions()
|
56 |
+
df = process_transactions(transactions_data)
|
57 |
+
|
58 |
+
# Ensure that chain IDs are strings for consistent grouping
|
59 |
+
df["sending_chain"] = df["sending_chain"].astype(str)
|
60 |
+
df["receiving_chain"] = df["receiving_chain"].astype(str)
|
61 |
+
|
62 |
+
# 1. Number of Transactions per Chain per Day per Agent
|
63 |
+
tx_per_chain_agent = df.groupby(["date", "from_address", "sending_chain"]).size().reset_index(name="transaction_count")
|
64 |
+
fig_tx_chain_agent = px.bar(tx_per_chain_agent, x="date", y="transaction_count", color="sending_chain", barmode="group",
|
65 |
+
facet_col="from_address", title="Number of Transactions per Chain per Agent per Day")
|
66 |
+
|
67 |
+
# 2. Number of Opportunities Taken per Agent per Day
|
68 |
+
opportunities_per_agent = df.groupby(["date", "from_address"]).size().reset_index(name="opportunities_taken")
|
69 |
+
fig_opportunities_agent = px.bar(opportunities_per_agent, x="date", y="opportunities_taken", color="from_address",
|
70 |
+
title="Number of Opportunities Taken per Agent per Day")
|
71 |
+
|
72 |
+
# 3. Amount of Investment in Pools Daily per Agent (Note: Assuming sending_amount_usd as investment)
|
73 |
+
# Since we might not have explicit data about pool investments, we'll use sending_amount_usd
|
74 |
+
investment_per_agent = df.groupby(["date", "from_address"])["sending_amount_usd"].sum().reset_index()
|
75 |
+
fig_investment_agent = px.bar(investment_per_agent, x="date", y="sending_amount_usd", color="from_address",
|
76 |
+
title="Amount of Investment (USD) per Agent per Day")
|
77 |
+
|
78 |
+
# 4. Number of Swaps per Day
|
79 |
+
# Assuming each transaction is a swap if sending and receiving tokens are different
|
80 |
+
df["is_swap"] = df.apply(lambda x: x["sending_token_symbol"] != x["receiving_token_symbol"], axis=1)
|
81 |
+
swaps_per_day = df[df["is_swap"]].groupby("date").size().reset_index(name="swap_count")
|
82 |
+
fig_swaps_per_day = px.bar(swaps_per_day, x="date", y="swap_count", title="Number of Swaps per Day")
|
83 |
+
|
84 |
+
# 5. Aggregated Metrics over All Traders
|
85 |
+
amount_usd = df["sending_amount_usd"]
|
86 |
+
stats = {
|
87 |
+
"Total": amount_usd.sum(),
|
88 |
+
"Average": amount_usd.mean(),
|
89 |
+
"Min": amount_usd.min(),
|
90 |
+
"Max": amount_usd.max(),
|
91 |
+
"25th Percentile": amount_usd.quantile(0.25),
|
92 |
+
"50th Percentile (Median)": amount_usd.median(),
|
93 |
+
"75th Percentile": amount_usd.quantile(0.75),
|
94 |
+
}
|
95 |
+
stats_df = pd.DataFrame(list(stats.items()), columns=["Metric", "Value"])
|
96 |
+
|
97 |
+
# Visualization for Aggregated Metrics
|
98 |
+
fig_stats = px.bar(stats_df, x="Metric", y="Value", title="Aggregated Transaction Amount Metrics (USD)")
|
99 |
+
|
100 |
+
return fig_tx_chain_agent, fig_opportunities_agent, fig_investment_agent, fig_swaps_per_day, fig_stats
|
101 |
+
|
102 |
+
# Gradio interface
|
103 |
def dashboard():
|
104 |
with gr.Blocks() as demo:
|
105 |
gr.Markdown("# Valory Transactions Dashboard")
|
106 |
|
107 |
+
# Fetch and display visualizations
|
108 |
with gr.Tab("Transactions per Chain per Agent"):
|
109 |
fig_tx_chain_agent, _, _, _, _ = create_visualizations()
|
110 |
gr.Plot(fig_tx_chain_agent)
|
|
|
124 |
with gr.Tab("Aggregated Metrics"):
|
125 |
_, _, _, _, fig_stats = create_visualizations()
|
126 |
gr.Plot(fig_stats)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
128 |
return demo
|
129 |
|
130 |
+
# Launch the dashboard
|
131 |
if __name__ == "__main__":
|
132 |
dashboard().launch()
|
133 |
+
|