Spaces:
Runtime error
Runtime error
File size: 6,944 Bytes
a4a226b 91cdfbe 1fd1024 a4a226b 5337889 a4a226b 5337889 a4a226b 5337889 a4a226b 1fd1024 a59dc6c 4a72f7f a4a226b a59dc6c a4a226b 5337889 5d6129a faffd71 5d6129a a4a226b 5d6129a a4a226b 1fd1024 5d6129a a4a226b 2775398 a4a226b | 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 | 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) |