also get token names
This commit is contained in:
parent
405445e6a8
commit
2a15df144c
@ -34,6 +34,19 @@ import re
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
ENV_FILE = '.env'
|
||||||
|
|
||||||
|
async def save_subscription_id(subscription_id):
|
||||||
|
# storing subscription id in .env file disabled
|
||||||
|
#set_key(ENV_FILE, "SUBSCRIPTION_ID", str(subscription_id))
|
||||||
|
logger.info(f"Saved subscription ID: {subscription_id}")
|
||||||
|
|
||||||
|
async def load_subscription_id():
|
||||||
|
subscription_id = os.getenv("SUBSCRIPTION_ID")
|
||||||
|
return int(subscription_id) if subscription_id else None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Function to find the latest log file
|
# Function to find the latest log file
|
||||||
def get_latest_log_file():
|
def get_latest_log_file():
|
||||||
log_dir = './logs'
|
log_dir = './logs'
|
||||||
@ -103,35 +116,6 @@ async def send_telegram_message(message):
|
|||||||
logging.error(f"Error sending Telegram message: {str(e)}")
|
logging.error(f"Error sending Telegram message: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
# async def get_token_prices(token_addresses: List[str]) -> Dict[str, float]:
|
|
||||||
# url = "https://api.coingecko.com/api/v3/simple/token_price/solana"
|
|
||||||
# params = {
|
|
||||||
# "contract_addresses": ",".join(token_addresses),
|
|
||||||
# "vs_currencies": DISPLAY_CURRENCY.lower()
|
|
||||||
# }
|
|
||||||
# prices = {}
|
|
||||||
|
|
||||||
# async with aiohttp.ClientSession() as session:
|
|
||||||
# async with session.get(url, params=params) as response:
|
|
||||||
# if response.status == 200:
|
|
||||||
# data = await response.json()
|
|
||||||
# for address, price_info in data.items():
|
|
||||||
# if DISPLAY_CURRENCY.lower() in price_info:
|
|
||||||
# prices[address] = price_info[DISPLAY_CURRENCY.lower()]
|
|
||||||
# else:
|
|
||||||
# logging.error(f"Failed to get token prices. Status: {response.status}")
|
|
||||||
|
|
||||||
# # For tokens not found in CoinGecko, try to get price from a DEX or set a default value
|
|
||||||
# missing_tokens = set(token_addresses) - set(prices.keys())
|
|
||||||
# for token in missing_tokens:
|
|
||||||
# # You might want to implement a fallback method here, such as:
|
|
||||||
# # prices[token] = await get_price_from_dex(token)
|
|
||||||
# # For now, we'll set a default value
|
|
||||||
# prices[token] = 0.0
|
|
||||||
# logging.warning(f"Price not found for token {token}. Setting to 0.")
|
|
||||||
|
|
||||||
# return prices
|
|
||||||
|
|
||||||
async def get_token_prices(token_addresses: List[str]) -> Dict[str, float]:
|
async def get_token_prices(token_addresses: List[str]) -> Dict[str, float]:
|
||||||
coingecko_prices = await get_prices_from_coingecko(token_addresses)
|
coingecko_prices = await get_prices_from_coingecko(token_addresses)
|
||||||
|
|
||||||
@ -237,33 +221,6 @@ async def convert_balances_to_currency(balances, token_prices, sol_price):
|
|||||||
return converted_balances
|
return converted_balances
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_token_balance(wallet_address, token_address):
|
|
||||||
try:
|
|
||||||
response = await solana_client.get_token_accounts_by_owner_json_parsed(
|
|
||||||
Pubkey.from_string(wallet_address),
|
|
||||||
opts=TokenAccountOpts(
|
|
||||||
mint=Pubkey.from_string(token_address),
|
|
||||||
# program_id=Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
|
||||||
),
|
|
||||||
commitment=Confirmed
|
|
||||||
)
|
|
||||||
|
|
||||||
if response['result']['value']:
|
|
||||||
balance = await solana_client.get_token_account_balance(
|
|
||||||
response['result']['value'][0]['pubkey']
|
|
||||||
)
|
|
||||||
amount = float(balance['result']['value']['uiAmount'])
|
|
||||||
logging.debug(f"Balance for {token_address} in {wallet_address}: {amount}")
|
|
||||||
return amount
|
|
||||||
else:
|
|
||||||
logging.debug(f"No account found for {token_address} in {wallet_address}")
|
|
||||||
return 0
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Error getting balance for {token_address} in {wallet_address}: {str(e)} \r\n {e}")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
async def get_token_balance_rpc(wallet_address, token_address):
|
async def get_token_balance_rpc(wallet_address, token_address):
|
||||||
url = SOLANA_HTTP_URL
|
url = SOLANA_HTTP_URL
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
@ -313,16 +270,8 @@ async def get_token_balance_rpc(wallet_address, token_address):
|
|||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
logging.error(f"Error getting balance for {token_address} in {wallet_address}: {str(e)} \r\n {e}")
|
logging.error(f"Error getting balance for {token_address} in {wallet_address}: {str(e)} \r\n {e}")
|
||||||
return 0
|
return 0
|
||||||
ENV_FILE = '.env'
|
|
||||||
|
|
||||||
async def save_subscription_id(subscription_id):
|
|
||||||
# storing subscription id in .env file disabled
|
|
||||||
#set_key(ENV_FILE, "SUBSCRIPTION_ID", str(subscription_id))
|
|
||||||
logger.info(f"Saved subscription ID: {subscription_id}")
|
|
||||||
|
|
||||||
async def load_subscription_id():
|
|
||||||
subscription_id = os.getenv("SUBSCRIPTION_ID")
|
|
||||||
return int(subscription_id) if subscription_id else None
|
|
||||||
|
|
||||||
|
|
||||||
async def get_token_name(mint_address):
|
async def get_token_name(mint_address):
|
||||||
@ -356,15 +305,23 @@ async def get_wallet_balances(wallet_address):
|
|||||||
mint = info['mint']
|
mint = info['mint']
|
||||||
amount = float(info['tokenAmount']['uiAmount'])
|
amount = float(info['tokenAmount']['uiAmount'])
|
||||||
if amount > 0:
|
if amount > 0:
|
||||||
token_name = await get_token_name(mint) or mint
|
token_name = await get_token_name(mint) or 'Unknown'
|
||||||
balances[f"{token_name} ({mint})"] = amount
|
balances[mint] = {
|
||||||
|
'name': token_name,
|
||||||
|
'address': mint,
|
||||||
|
'amount': amount
|
||||||
|
}
|
||||||
logging.debug(f"Balance for {token_name} ({mint}): {amount}")
|
logging.debug(f"Balance for {token_name} ({mint}): {amount}")
|
||||||
else:
|
else:
|
||||||
logging.warning(f"Unexpected data format for account: {account}")
|
logging.warning(f"Unexpected data format for account: {account}")
|
||||||
|
|
||||||
sol_balance = await solana_client.get_balance(Pubkey.from_string(wallet_address))
|
sol_balance = await solana_client.get_balance(Pubkey.from_string(wallet_address))
|
||||||
if sol_balance.value is not None:
|
if sol_balance.value is not None:
|
||||||
balances['SOL'] = sol_balance.value / 1e9
|
balances['SOL'] = {
|
||||||
|
'name': 'SOL',
|
||||||
|
'address': 'SOL',
|
||||||
|
'amount': sol_balance.value / 1e9
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
logging.warning(f"SOL balance response missing for wallet: {wallet_address}")
|
logging.warning(f"SOL balance response missing for wallet: {wallet_address}")
|
||||||
|
|
||||||
@ -386,6 +343,49 @@ async def list_initial_wallet_states():
|
|||||||
followed_converted_balances = await convert_balances_to_currency(followed_wallet_balances, token_prices, sol_price)
|
followed_converted_balances = await convert_balances_to_currency(followed_wallet_balances, token_prices, sol_price)
|
||||||
your_converted_balances = await convert_balances_to_currency(your_wallet_balances, token_prices, sol_price)
|
your_converted_balances = await convert_balances_to_currency(your_wallet_balances, token_prices, sol_price)
|
||||||
|
|
||||||
|
TOKEN_ADDRESSES = {token: balance['amount'] for token, balance in {**followed_converted_balances, **your_converted_balances}.items() if balance['amount'] is not None and balance['amount'] > 0}
|
||||||
|
logging.info(f"Monitoring balances for tokens: {[balance['name'] for balance in TOKEN_ADDRESSES.values()]}")
|
||||||
|
|
||||||
|
followed_wallet_state = []
|
||||||
|
FOLLOWED_WALLET_VALUE = 0
|
||||||
|
for token, balance in followed_converted_balances.items():
|
||||||
|
if balance['amount'] is not None and balance['amount'] > 0:
|
||||||
|
followed_wallet_state.append(f"{balance['name']} ({balance['address']}): {balance['amount']:.2f} {DISPLAY_CURRENCY}")
|
||||||
|
FOLLOWED_WALLET_VALUE += balance['amount']
|
||||||
|
|
||||||
|
your_wallet_state = []
|
||||||
|
YOUR_WALLET_VALUE = 0
|
||||||
|
for token, balance in your_converted_balances.items():
|
||||||
|
if balance['amount'] is not None and balance['amount'] > 0:
|
||||||
|
your_wallet_state.append(f"{balance['name']} ({balance['address']}): {balance['amount']:.2f} {DISPLAY_CURRENCY}")
|
||||||
|
YOUR_WALLET_VALUE += balance['amount']
|
||||||
|
|
||||||
|
message = (
|
||||||
|
f"<b>Initial Wallet States (All balances in {DISPLAY_CURRENCY}):</b>\n\n"
|
||||||
|
f"<b>Followed Wallet ({FOLLOWED_WALLET}):</b>\n"
|
||||||
|
f"{chr(10).join(followed_wallet_state)}\n"
|
||||||
|
f"<b>Total Value:</b> {FOLLOWED_WALLET_VALUE:.2f} {DISPLAY_CURRENCY}\n\n"
|
||||||
|
f"<b>Your Wallet ({YOUR_WALLET}):</b>\n"
|
||||||
|
f"{chr(10).join(your_wallet_state)}\n"
|
||||||
|
f"<b>Total Value:</b> {YOUR_WALLET_VALUE:.2f} {DISPLAY_CURRENCY}\n\n"
|
||||||
|
f"<b>Monitored Tokens:</b>\n"
|
||||||
|
f"{', '.join([balance['name'] for balance in TOKEN_ADDRESSES.values()])}"
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.info(message)
|
||||||
|
await send_telegram_message(message)
|
||||||
|
global TOKEN_ADDRESSES, FOLLOWED_WALLET_VALUE, YOUR_WALLET_VALUE
|
||||||
|
|
||||||
|
followed_wallet_balances = await get_wallet_balances(FOLLOWED_WALLET)
|
||||||
|
your_wallet_balances = await get_wallet_balances(YOUR_WALLET)
|
||||||
|
|
||||||
|
all_token_addresses = list(set(followed_wallet_balances.keys()) | set(your_wallet_balances.keys()))
|
||||||
|
token_prices = await get_token_prices(all_token_addresses)
|
||||||
|
sol_price = await get_sol_price()
|
||||||
|
|
||||||
|
followed_converted_balances = await convert_balances_to_currency(followed_wallet_balances, token_prices, sol_price)
|
||||||
|
your_converted_balances = await convert_balances_to_currency(your_wallet_balances, token_prices, sol_price)
|
||||||
|
|
||||||
TOKEN_ADDRESSES = {token: amount for token, amount in {**followed_converted_balances, **your_converted_balances}.items() if amount is not None and amount > 0}
|
TOKEN_ADDRESSES = {token: amount for token, amount in {**followed_converted_balances, **your_converted_balances}.items() if amount is not None and amount > 0}
|
||||||
logging.info(f"Monitoring balances for tokens: {TOKEN_ADDRESSES.keys()}")
|
logging.info(f"Monitoring balances for tokens: {TOKEN_ADDRESSES.keys()}")
|
||||||
|
|
||||||
@ -574,7 +574,16 @@ async def parse_swap_logs(logs):
|
|||||||
|
|
||||||
async def follow_move(move):
|
async def follow_move(move):
|
||||||
your_balances = await get_wallet_balances(YOUR_WALLET)
|
your_balances = await get_wallet_balances(YOUR_WALLET)
|
||||||
your_balance = your_balances.get(move['token_in'], 0)
|
your_balance_info = your_balances.get(move['token_in'])
|
||||||
|
|
||||||
|
if not your_balance_info:
|
||||||
|
message = f"<b>Move Failed:</b>\nNo balance found for token {move['token_in']}"
|
||||||
|
logging.warning(message)
|
||||||
|
await send_telegram_message(message)
|
||||||
|
return
|
||||||
|
|
||||||
|
your_balance = your_balance_info['amount']
|
||||||
|
token_name = your_balance_info['name']
|
||||||
|
|
||||||
# Calculate the amount to swap based on the same percentage as the followed move
|
# Calculate the amount to swap based on the same percentage as the followed move
|
||||||
amount_to_swap = your_balance * (move['percentage_swapped'] / 100)
|
amount_to_swap = your_balance * (move['percentage_swapped'] / 100)
|
||||||
@ -599,11 +608,14 @@ async def follow_move(move):
|
|||||||
result = await async_client.send_raw_transaction(txn=bytes(signed_txn), opts=opts)
|
result = await async_client.send_raw_transaction(txn=bytes(signed_txn), opts=opts)
|
||||||
transaction_id = json.loads(result.to_json())['result']
|
transaction_id = json.loads(result.to_json())['result']
|
||||||
|
|
||||||
|
output_token_info = your_balances.get(move['token_out'], {'name': 'Unknown'})
|
||||||
|
output_token_name = output_token_info['name']
|
||||||
|
|
||||||
message = (
|
message = (
|
||||||
f"<b>Move Followed:</b>\n"
|
f"<b>Move Followed:</b>\n"
|
||||||
f"Swapped {amount_to_swap:.6f} {move['token_in']} "
|
f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) "
|
||||||
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
|
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
|
||||||
f"for {transaction_data['outputAmount'] / 1e6:.6f} {move['token_out']}"
|
f"for {transaction_data['outputAmount'] / 1e6:.6f} {output_token_name} ({move['token_out']})"
|
||||||
)
|
)
|
||||||
logging.info(message)
|
logging.info(message)
|
||||||
await send_telegram_message(message)
|
await send_telegram_message(message)
|
||||||
@ -614,11 +626,10 @@ async def follow_move(move):
|
|||||||
else:
|
else:
|
||||||
message = (
|
message = (
|
||||||
f"<b>Move Failed:</b>\n"
|
f"<b>Move Failed:</b>\n"
|
||||||
f"Insufficient balance to swap {amount_to_swap:.6f} {move['token_in']}"
|
f"Insufficient balance to swap {amount_to_swap:.6f} {token_name} ({move['token_in']})"
|
||||||
)
|
)
|
||||||
logging.warning(message)
|
logging.warning(message)
|
||||||
await send_telegram_message(message)
|
await send_telegram_message(message)
|
||||||
|
|
||||||
# Helper functions (implement these according to your needs)
|
# Helper functions (implement these according to your needs)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user