Spaces:
Runtime error
Runtime error
| 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) |