blup-dashboard / app.py
Trireme's picture
Upload folder using huggingface_hub
5337889 verified
Raw
History Blame Contribute Delete
6.94 kB
import requests
import asyncio
import aiohttp
import pandas as pd
import urllib
import gradio as gr
import os
from pymongo import MongoClient
addresses = [
"0x46dae11e3ab74C417d370FB0d467364397178f5d",
"0x2B3cb7D697Dd5224f3AcfC1b7EbDe77F468Dd539",
"0x7B04395AF49caf8C4Fd5FF716698D97f394d0d41",
"0x4dAFdbdB45947AB8666411AFc07F95b39Ab3841B",
"0xa2ebb53A922E8fe9E6949316b0018F95f0956Ce7",
"0x0FCc5f7845F3B2188918495f60F6294a15dc772b",
"0xefa59c4aE5BaBA2c1017Ce2Fc9c1E0E080e5F448",
"0x1C2A2D1b1A95a252AD4f9E8c9055885a1721c252",
"0xfCb81D6a2678D9f0798124BD3E46bA0E1Ff0C32c",
"0xdF04384C3AE43bD08E04692139C6B6C6Eb308B76",
"0xA734C747E53171261568DbBB1BCd699EDF01925c",
"0xC6347a0924aAbBA5E655397fbD18cb702066304b",
"0xc6300201821CB7026E0e73cC10dC9Ca5C623Ff15",
"0x2777698A53410C344e98267dB672a432c77C6Ed9",
"0xCCc07e973c04c607381b96eCBe3e426cc7c17B88",
"0xE813553077d0bfdd9615465D8A974F63bbf33aD4",
"0x0a045118cDb3fB0FDb50D2f91f04c56B28F5fD07",
"0x0bC67eE9A36f5bc8e05282E538FDe119C372a222",
"0x1ca7bCe8A7c4F62a3575279688D9E9ad337f6b3d",
"0x940665c733acBcA198306F8881c1d268E2F92DFA",
"0x6393613ca5a87Cc2BEe2eC3610EcAcD279FcBcD6",
"0xAB851cA6F8e5329Dcf9B164d312f7d5C9D41eE01",
"0xe2Db92758567D1D67A861F0645F850ddb6e216E8",
"0x4a7F42021C71Be21D3c21717743449620Abb3D25",
"0x2Bd99Ac1dCa390A543BD06F7712ece7B787752a5",
"0x8c27aa11FF3562c807C5A40e0512bDC043B39Bb0",
"0xB4e6dEa305a1A84FA0B2185F36de31bcE2c22005",
"0xA89f812f26ef2f6D89c81371A89787240c63D524",
"0xF7a54082215D4508CD674b270ECc37Bd281FD92d",
"0xc419410F5B29cdd4343013210ac194B872cF5a4B"
]
# Chunk into groups of 3
def chunk_addresses(addresses, size):
return [addresses[i:i + size] for i in range(0, len(addresses), size)]
API_URL = "https://api.g.alchemy.com/data/v1/yhe6L3PXmiENzS1sP9Fu4_T5E3l0QyeB/assets/tokens/by-address"
async def fetch_batch(session, batch):
json_payload = {
"addresses": [{"address": addr, "networks": ["arb-mainnet"]} for addr in batch],
"withMetadata": True,
"withPrices": True,
"includeNativeTokens": True
}
async with session.post(API_URL, json=json_payload) as response:
response = await response.json()
return response['data']['tokens']
async def get_wallet_balances(addresses):
async with aiohttp.ClientSession() as session:
batches = chunk_addresses(addresses, 3)
tasks = [fetch_batch(session, batch) for batch in batches]
responses = await asyncio.gather(*tasks)
first_parts = []
rest_parts = []
for res in responses:
first_parts.extend(res[:3])
rest_parts.extend(res[3:])
responses = first_parts + rest_parts
df = pd.DataFrame(responses)
for i in range(len(addresses)):
df.at[i,'tokenMetadata'] = {}
df['tokenBalance'] = df['tokenBalance'].apply(lambda x : int(x,16))
df['decimals'] = df['tokenMetadata'].apply(lambda x : x.get('decimals',0))
df['tokenBalance'] = df['tokenBalance']/(10**df['decimals'])
for i in range(len(addresses)):
df.at[i, 'tokenBalance'] = df.at[i, 'tokenBalance'] / (10**18)
df['symbol'] = df['tokenMetadata'].apply(lambda x : x.get('symbol',''))
for i in range(len(addresses)):
df.at[i,'symbol'] = 'ETH'
df['currentPrice'] = df['tokenPrices'].apply(lambda x : x[0].get('value',None) if len(x) > 0 else None)
df.drop(columns=['tokenPrices','tokenMetadata','network','tokenAddress'], inplace=True)
df = df.dropna()
df['tokenBalance'] = pd.to_numeric(df['tokenBalance'], errors='coerce')
df = df[df['tokenBalance'] != 0]
df['tokenBalance'] = pd.to_numeric(df['tokenBalance'], errors='coerce')
df['currentPrice'] = pd.to_numeric(df['currentPrice'], errors='coerce')
df['value'] = df['tokenBalance'] * df['currentPrice']
df.drop(columns=['decimals'],inplace=True)
df = df[df['symbol'].isin(['BLUP', 'ETH', 'USDT', 'USDC'])]
df= df[['address','symbol','tokenBalance','value']]
df = df.rename(columns={'tokenBalance':'amount','value':'usd_value'})
df = df.sort_values(['address', 'symbol'])
df['address'] = df['address'].mask(df['address'].duplicated()).fillna('')
#df = df.groupby("symbol", as_index=False).sum()
return df, df['usd_value'].sum()
async def get_lp_balances():
client = MongoClient(os.getenv('MONGO_DB_URI'))
db = client["debank_tokens"]
token_collection = db["debank"]
token_list = token_collection.find_one(sort=[("timestamp", -1)])
del token_list["_id"]
del token_list["timestamp"]
url = "https://api.debank.com/user?id=0x275c7f2781db0b78228029f85735059c9bdd4f35"
SCRAPE_DO_TOKEN = os.getenv('SCRAPE_DO_KEY')
headers = token_list
encoded_url = urllib.parse.quote(url)
proxy_url = f"http://api.scrape.do/?token={SCRAPE_DO_TOKEN}&url={encoded_url}&forwardHeaders=True&super=True"
response = requests.get(proxy_url, headers=headers)
response = response.json()['data']['user']['stats']
top_coins = response['top_coins']
top_tokens = response['top_tokens']
coins = pd.DataFrame(top_coins)
tokens = pd.DataFrame(top_tokens)
balances = pd.concat([coins, tokens], axis=0)
balances.drop(columns=['id','logo_url','percent','price','chain_id'],inplace=True)
balances = balances[['symbol','amount','usd_value']]
return balances, balances['usd_value'].sum()
async def get_all_dfs():
wallet_df, wallet_total = await get_wallet_balances(addresses)
lp_df, lp_total = await get_lp_balances()
final_df = pd.concat([wallet_df,lp_df],axis=0)
final_df.drop(columns=['address'],inplace=True)
final_df = final_df.groupby("symbol", as_index=False).sum()
starting_df = pd.DataFrame([{"symbol":"ETH","amount":24,"usd_value":1613*24}])
pnl = final_df['usd_value'].sum() - starting_df['usd_value'].sum()
return wallet_df, wallet_total, lp_df, lp_total, final_df, final_df['usd_value'].sum(),starting_df,starting_df['usd_value'].sum(),pnl
with gr.Blocks() as demo:
gr.Markdown("## BLUP Balances and PnL")
df3_out = gr.Dataframe(label="Starting Balances")
txt3_out = gr.Textbox(label="Total Value")
df0_out = gr.Dataframe(label="Wallet Balances")
txt0_out = gr.Textbox(label="Total Value")
df1_out = gr.Dataframe(label="LP Balances")
txt1_out = gr.Textbox(label="Total Value")
df2_out = gr.Dataframe(label="Total Balances")
txt2_out = gr.Textbox(label="Total Value")
pnl_out = gr.Textbox(label="PNL (AUM Model)")
# Load from MongoDB on app load (sync function)
demo.load(
fn= get_all_dfs,
inputs = [],
outputs=[df0_out, txt0_out, df1_out, txt1_out, df2_out, txt2_out,df3_out,txt3_out,pnl_out]
)
demo.launch(debug=True, share=True)