import json import os from pycoingecko import CoinGeckoAPI from rediscluster import RedisCluster import redis import ast import requests import traceback #const DEFAULT_PRICE = 0.00000000000000001 #redis keys TOKENPRICE = 'TOKENPRICE_TO_FETCH' R = None # REDIS_ONLINE = 'denet-chain-prod.y2slbl.clustercfg.memorydb.us-east-1.amazonaws.com' # R = RedisCluster(host=REDIS_ONLINE, port=6379, decode_responses=True, skip_full_coverage_check=True) env = os.environ['ENV'] redis_host = os.environ['redis_host'] if env == 'dev': redis_password = os.environ['redis_password'] R = redis.Redis( host=redis_host, port=6379, password='denet#2022', decode_responses=True) else: R = RedisCluster(host=redis_host, port=6379, decode_responses=True, skip_full_coverage_check=True) def get_swap_price(tokens): print('get_swap_price') ret_d = {} for t in tokens: segs = t.split('_') chain = segs[0] contract = segs[1] if chain.strip().upper() == 'BSC': price = get_pancakeswap_price(contract) if price is not None: ret_d[t] = price return ret_d def get_pancakeswap_price(contract): url = f'https://api.pancakeswap.info/api/v2/tokens/{contract}' try: ret = requests.get(url) price = float(ret.json()['data']['price']) print(price) return price except: traceback.print_exc() return None def get_coingecko_price(tokens): print('get_coingecko_price') exceptions = set() ret_d = {} try: cg = CoinGeckoAPI() coin_prices = cg.get_price(ids=list(tokens), vs_currencies='usd') print(coin_prices) for k, v in coin_prices.items(): if v.get('usd') is None: exceptions.add(k) continue price = v['usd'] ret_d[k] = price except: traceback.print_exc() print('get_coingecko_price exception tokens', exceptions) return ret_d def get_tokens(): tokens = R.smembers(TOKENPRICE) tokens = [ast.literal_eval(t) for t in tokens] print(tokens) realtime_price_token = set() fixed_or_swap_price_token = set() for t in tokens: if t.get('fixed_price') is None: realtime_price_token.add(t.get('coingecko_id')) else: fixed_or_swap_price_token.add(f"{t.get('chain')}_{t.get('contract')}") realtime_price = get_coingecko_price(realtime_price_token) #{'coingecko_id':price} swap_price_token = get_swap_price(fixed_or_swap_price_token) #{'chain_contract': price} return tokens, realtime_price, swap_price_token def merge_price(tokens, realtime_price, swap_price_token): ret_d = {} exceptions = set() for t in tokens: chain = t.get('chain') contract = t.get('contract') coingecko_id = t.get('coingecko_id') fixed_price = t.get('fixed_price') now_price = realtime_price.get(coingecko_id) if now_price is None: now_price = swap_price_token.get(f'{chain}_{contract}') if now_price is None: now_price = fixed_price if now_price is None: exceptions.add(str(t)) else: l = ret_d.get(chain, []) l.append({'contract': contract, 'usdPrice': now_price}) ret_d[chain] = l print('merge_price exceptions', exceptions) return ret_d def save_price(prices): for chain, token_dict in prices.items(): R.set(f'{TOKENPRICE}{chain.upper()}', json.dumps({'tokenPrice':token_dict})) print('add', f'{TOKENPRICE}{chain.upper()}', json.dumps({'tokenPrice':token_dict})) if __name__ == '__main__': tokens, realtime_price, swap_price_token = get_tokens() prices = merge_price(tokens, realtime_price, swap_price_token) save_price(prices)