Skip to content

Commit 6c9dd90

Browse files
authored
Merge pull request #49 from drift-labs:goldhaxx/DPE-3459/fix-risk-dashboard-loading-issues
Refactor deposits, and liquidation curve APIs & pages, update routing
2 parents 480f137 + 0629bcd commit 6c9dd90

File tree

11 files changed

+343
-259
lines changed

11 files changed

+343
-259
lines changed

backend/api/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
from . import (
22
asset_liability,
33
backend_health,
4-
deposits,
4+
deposits_api,
55
health,
6-
liquidation,
6+
high_leverage_api,
7+
liquidation_curves_api,
8+
market_recommender_api,
79
metadata,
10+
open_interest_api,
811
pnl,
912
positions,
1013
price_shock,
1114
snapshot,
1215
ucache,
16+
user_retention_explorer_api,
17+
user_retention_summary_api,
1318
vaults,
1419
)

backend/api/deposits.py renamed to backend/api/deposits_api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ async def get_deposits(request: BackendRequest, market_index: Optional[int] = No
2323
dict: A dictionary containing deposits with total value and balance info
2424
"""
2525
vat: Vat = request.state.backend_state.vat
26+
last_oracle_slot = getattr(request.state.backend_state, "last_oracle_slot", 0)
2627
deposits = []
2728
vaults_program = await get_vaults_program(request.state.backend_state.connection)
2829
vaults = await vaults_program.account["Vault"].all()
@@ -53,6 +54,7 @@ async def get_deposits(request: BackendRequest, market_index: Optional[int] = No
5354

5455
deposits.sort(key=lambda x: x["value"], reverse=True)
5556
return {
57+
"slot": last_oracle_slot,
5658
"deposits": deposits,
5759
"vaults": vault_pubkeys,
5860
"total_value": sum(d["value"] for d in deposits),

backend/api/liquidation.py renamed to backend/api/liquidation_curves_api.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@
77
router = APIRouter()
88

99

10-
@router.get("/liquidation-curve")
10+
@router.get("/liquidation-curves")
1111
def get_liquidation_curve(request: BackendRequest, market_index: int):
1212
vat: Vat = request.state.backend_state.vat
13+
last_oracle_slot = getattr(request.state.backend_state, "last_oracle_slot", 0)
14+
# Debug logging to understand the slot issue
15+
print(f"[DEBUG] Liquidation API - last_oracle_slot: {last_oracle_slot}, pickle_path: {request.state.backend_state.current_pickle_path}")
1316
liquidations_long: list[tuple[float, float, str]] = []
1417
liquidations_short: list[tuple[float, float, str]] = []
1518
market_price = vat.perp_oracles.get(market_index)
1619
if market_price is None:
1720
print("Market price is None")
18-
return {"liquidations_long": [], "liquidations_short": [], "market_price_ui": 0}
21+
return {
22+
"liquidations_long": [],
23+
"liquidations_short": [],
24+
"market_price_ui": 0,
25+
"slot": last_oracle_slot
26+
}
1927
market_price_ui = market_price.price / PRICE_PRECISION
2028
for pubkey, user in vat.users.user_map.items():
2129
perp_position = user.get_perp_position(market_index)
@@ -48,4 +56,5 @@ def get_liquidation_curve(request: BackendRequest, market_index: int):
4856
"liquidations_long": liquidations_long,
4957
"liquidations_short": liquidations_short,
5058
"market_price_ui": market_price_ui,
59+
"slot": last_oracle_slot,
5160
}

backend/app.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from backend.api import (
1212
asset_liability,
1313
backend_health,
14-
deposits,
14+
deposits_api,
1515
health,
16-
liquidation,
16+
liquidation_curves_api,
1717
market_recommender_api,
1818
metadata,
1919
open_interest_api,
@@ -80,14 +80,14 @@ async def lifespan(app: FastAPI):
8080
app.include_router(health.router, prefix="/api/health", tags=["health"])
8181
app.include_router(backend_health.router, prefix="/api/backend-health", tags=["backend-health"])
8282
app.include_router(metadata.router, prefix="/api/metadata", tags=["metadata"])
83-
app.include_router(liquidation.router, prefix="/api/liquidation", tags=["liquidation"])
83+
app.include_router(liquidation_curves_api.router, prefix="/api/liquidation-curves", tags=["liquidation-curves"])
8484
app.include_router(price_shock.router, prefix="/api/price-shock", tags=["price-shock"])
8585
app.include_router(
8686
asset_liability.router, prefix="/api/asset-liability", tags=["asset-liability"]
8787
)
8888
app.include_router(snapshot.router, prefix="/api/snapshot", tags=["snapshot"])
8989
app.include_router(ucache.router, prefix="/api/ucache", tags=["ucache"])
90-
app.include_router(deposits.router, prefix="/api/deposits", tags=["deposits"])
90+
app.include_router(deposits_api.router, prefix="/api/deposits", tags=["deposits"])
9191
app.include_router(pnl.router, prefix="/api/pnl", tags=["pnl"])
9292
app.include_router(vaults.router, prefix="/api/vaults", tags=["vaults"])
9393
app.include_router(positions.router, prefix="/api/positions", tags=["positions"])

images/pacman.gif

18.5 KB
Loading

src/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
from lib.page import header, needs_backend, sidebar
1111
from page.asset_liability import asset_liab_matrix_cached_page
1212
from page.backend import backend_page
13-
from page.deposits import deposits_page
13+
from page.deposits_page import deposits_page
1414
from page.health import health_page
15-
from page.liquidation_curves import liquidation_curves_page
15+
from page.liquidation_curves_page import liquidation_curves_page
1616
from page.market_inspector import market_inspector_page
1717
from page.orderbook import orderbook_page
1818
from page.pnl import pnl_page

src/page/deposits.py renamed to src/page/deposits_page.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import pandas as pd
22
import streamlit as st
33
import logging
4+
import time
45
from typing import Optional
56
from driftpy.constants.spot_markets import mainnet_spot_market_configs
67

78
from lib.api import fetch_api_data
9+
from src.utils import get_current_slot
810

911
# Configure logging
1012
logging.basicConfig(level=logging.INFO)
1113
logger = logging.getLogger(__name__)
1214

15+
def is_processing(result):
16+
"""Checks if the API result indicates backend processing."""
17+
return isinstance(result, dict) and result.get("result") == "processing"
18+
19+
def has_error(result):
20+
"""Checks if the API result indicates an error."""
21+
return isinstance(result, dict) and "error" in result
22+
1323
def format_authority(authority: str) -> str:
1424
"""Format authority to show first and last 4 chars"""
1525
return f"{authority[:4]}...{authority[-4:]}"
@@ -42,6 +52,9 @@ def get_market_symbol(market_index: int) -> str:
4252

4353
def deposits_page():
4454
try:
55+
# Explicitly type hint as DataFrame
56+
df: pd.DataFrame = pd.DataFrame()
57+
4558
params = st.query_params
4659
market_index = int(params.get("market_index", 0))
4760

@@ -87,11 +100,27 @@ def deposits_page():
87100
retry=True,
88101
)
89102

103+
if is_processing(result):
104+
st.info("Backend is initializing data. Please wait.")
105+
with st.spinner("Auto-refreshing in 10 seconds..."):
106+
time.sleep(10)
107+
st.rerun()
108+
return
109+
110+
if has_error(result):
111+
st.error(f"An error occurred: {result.get('error', 'Unknown error')}")
112+
return
113+
90114
if result is None:
91115
logger.error("API returned no deposits data")
92116
st.error("No deposits found")
93117
return
94118

119+
slot = result.get("slot", 0)
120+
current_slot = get_current_slot()
121+
slot_age = current_slot - slot
122+
st.info(f"Data from slot {slot}, which is {slot_age} slots old.")
123+
95124
df = pd.DataFrame(result["deposits"])
96125
if df.empty:
97126
logger.warning("Empty deposits dataframe created")
@@ -104,7 +133,7 @@ def deposits_page():
104133

105134
if exclude_vaults:
106135
original_len = len(df)
107-
df = df[~df["authority"].isin(result["vaults"])]
136+
df = df.loc[~df["authority"].isin(result["vaults"])]
108137
logger.info(f"Excluded {original_len - len(df)} vault entries")
109138

110139
with col1:
@@ -119,7 +148,7 @@ def deposits_page():
119148
tabs = st.tabs(["By Position", "By Authority"])
120149

121150
with tabs[0]:
122-
filtered_df = df[df["balance"] >= min_balance]
151+
filtered_df: pd.DataFrame = df.loc[df["balance"] >= min_balance].copy()
123152
st.write(f"Total deposits value: **${filtered_df['value'].sum():,.2f}**")
124153
st.write(f"Number of depositor user accounts: **{len(filtered_df):,}**")
125154

@@ -133,7 +162,8 @@ def deposits_page():
133162
)
134163

135164
# Safely map market indices to symbols
136-
filtered_df["market_index"] = filtered_df["market_index"].map(get_market_symbol)
165+
if not filtered_df.empty:
166+
filtered_df["market_index"] = filtered_df["market_index"].map(get_market_symbol)
137167

138168
st.dataframe(
139169
filtered_df.sort_values("value", ascending=False),
@@ -164,7 +194,7 @@ def deposits_page():
164194
.agg({"value": "sum", "balance": "sum", "user_account": "count"})
165195
.reset_index()
166196
)
167-
grouped_df = grouped_df[grouped_df["value"] >= min_balance]
197+
grouped_df: pd.DataFrame = grouped_df.loc[grouped_df["value"] >= min_balance].copy()
168198
st.write(f"Total deposits value: **${grouped_df['value'].sum():,.2f}**")
169199
st.write(f"Total number of authorities with deposits: **{len(grouped_df):,}**")
170200
grouped_df = grouped_df.rename(columns={"user_account": "num_accounts"})

src/page/health.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,7 @@ def health_page():
381381
)
382382

383383
# Check if there are any error messages in the data
384-
has_errors = 'Error' in levered_spot_df.columns and levered_spot_df['Error'].any()
385-
if has_errors:
384+
if 'Error' in levered_spot_df.columns:
386385
error_records = levered_spot_df[levered_spot_df['Error'].notna() & (levered_spot_df['Error'] != '')]
387386
if not error_records.empty:
388387
st.warning(f"Found {len(error_records)} positions with errors. Please check with the team.")

0 commit comments

Comments
 (0)