From 52c4877ed4882aa70d17aa9444b6945e68a2897e Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Sat, 5 Oct 2024 21:49:32 +0300 Subject: [PATCH] parsing logs only - no details --- crypto/sol/app.py | 158 ++++++++++++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 62 deletions(-) diff --git a/crypto/sol/app.py b/crypto/sol/app.py index d1e0894..91fac0e 100644 --- a/crypto/sol/app.py +++ b/crypto/sol/app.py @@ -644,57 +644,71 @@ async def process_log(log_result): tx_signature_str = log_result['value']['signature'] logs = log_result['value']['logs'] - try: # Detect swap operations in logs swap_operations = ['Program log: Instruction: Swap', 'Program log: Instruction: Swap2'] for log_entry in logs: if any(op in log_entry for op in swap_operations): - try: - watched_tokens = await get_non_zero_token_balances(FOLLOWED_WALLET) - details = parse_swap_logs(logs, watched_tokens) - transaction = await get_transaction_details_rpc(tx_signature_str, True) - - tokens = [] - # Check inner instructions for transfers and mints - for instruction_set in transaction.get('meta', {}).get('innerInstructions', []): - for instruction in instruction_set.get('instructions', []): - if 'parsed' in instruction and 'info' in instruction['parsed']: - info = instruction['parsed']['info'] - amount = None - mint = 'Unknown' - - # Check for amount in transfer and transferChecked instructions - if 'amount' in info: - amount = info['amount'] - elif 'tokenAmount' in info and 'amount' in info['tokenAmount']: - amount = info['tokenAmount']['amount'] - - # Get mint if available - if 'mint' in info: - mint = info['mint'] - - if amount is not None: - tokens.append({'amount': amount, 'mint': mint}) + try: - # Check post token balances for final token states - for balance in transaction.get('postTokenBalances', []): - amount = balance['uiTokenAmount']['amount'] - mint = balance['mint'] - tokens.append({'amount': amount, 'mint': mint}) + + watched_tokens = await get_non_zero_token_balances(FOLLOWED_WALLET) + details = parse_swap_logs(logs) + # transaction = await get_transaction_details_rpc(tx_signature_str, True) + + # tokens = [] + # source_token = None + # target_token = None + + # # Check inner instructions for transfers and mints + # for instruction_set in transaction.get('meta', {}).get('innerInstructions', []): + # for instruction in instruction_set.get('instructions', []): + # if 'parsed' in instruction and 'info' in instruction['parsed']: + # info = instruction['parsed']['info'] + # amount = None + # mint = 'Unknown' + + # # Check for amount in transfer and transferChecked instructions + # if 'amount' in info: + # amount = info['amount'] + # elif 'tokenAmount' in info and 'amount' in info['tokenAmount']: + # amount = info['tokenAmount']['amount'] + + # # Get mint if available + # if 'mint' in info: + # mint = info['mint'] + + # if amount is not None: + # tokens.append({'amount': amount, 'mint': mint}) + + # # Identify source and target tokens + # if 'source' in info: + # source_token = info['source'] + # if 'destination' in info: + # target_token = info['destination'] + + # # Check post token balances for final token states + # for balance in transaction.get('postTokenBalances', []): + # amount = balance['uiTokenAmount']['amount'] + # mint = balance['mint'] + # tokens.append({'amount': amount, 'mint': mint}) # Get amount_in, amount_out, tokens, and USD value swap_details = { 'amount_in': details['total_amount_in'], 'amount_out': details['total_amount_out'], - 'tokens': tokens + 'tokens': tokens, + 'source_token': source_token, + 'target_token': target_token } message_text = ( f"Swap detected:\n" f"Amount In: {swap_details['amount_in']}\n" f"Amount Out: {swap_details['amount_out']}\n" + f"Source Token: {swap_details['source_token']}\n" + f"Target Token: {swap_details['target_token']}\n" f"Tokens: {tokens}" ) @@ -704,43 +718,63 @@ async def process_log(log_result): except Exception as e: logging.error(f"Error fetching transaction details: {e}") return - + except Exception as e: logging.error(f"Error processing log: {e}") -def parse_swap_logs(logs, watched_tokens): - total_amount_in = 0 - total_amount_out = 0 - token_addresses = [] + + # "Program log: Instruction: Swap2", + # "Program log: order_id: 13985890735038016", + # "Program log: AbrMJWfDVRZ2EWCQ1xSCpoVeVgZNpq1U2AoYG98oRXfn", source + # "Program log: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", target + +def parse_swap_logs(logs): + # Initialize variables to store the details + token_in = None + token_out = None + amount_in = 0 + amount_out_expected = 0 + amount_out_actual = 0 + + # Parse through each log entry for log in logs: - if "SwapEvent" in log: - parts = log.split("{ ")[1].strip(" }").split(", ") - event_details = {} - for part in parts: - key, value = part.split(": ") - event_details[key.strip()] = value.strip() - - # Aggregate amounts - total_amount_in += int(event_details.get("amount_in", 0)) - total_amount_out += int(event_details.get("amount_out", 0)) - - if "source_token_change:" in log: - # Extract final source and destination token changes + # Check for source and target tokens + if "Program log:" in log: + if "Swap2" in log: + # This log indicates the start of a swap, resetting details + token_in = None + token_out = None + elif "order_id" in log: + order_id = log.split("order_id: ")[-1] + else: + # Check for source and target tokens + if not token_in: + token_in = log.split("Program log: ")[-1].strip() + elif not token_out: + token_out = log.split("Program log: ")[-1].strip() + + # Example assuming token changes can be parsed as "source_token_change:" and "destination_token_change:" + elif "source_token_change:" in log: changes = log.split(", ") for change in changes: - key_value = change.split(": ", 1) - if len(key_value) != 2: - continue - key, value = key_value - if key == "source_token_change": - total_amount_in = int(value) - elif key == "destination_token_change": - total_amount_out = int(value) + if "source_token_change" in change: + amount_in = int(change.split(": ")[-1]) + elif "destination_token_change" in change: + amount_out_expected = int(change.split(": ")[-1]) + + # Assuming amount_out_actual is derived in a similar way to amount_out_expected + amount_out_actual = amount_out_expected # Modify if there is a separate way to determine actual amount - return { - "total_amount_in": total_amount_in, - "total_amount_out": total_amount_out, + # Return parsed details as a dictionary + return { + "token_in": token_in, + "token_out": token_out, + "amount_in": amount_in, + "amount_out_expected": amount_out_expected, + "amount_out_actual": amount_out_actual, + "amount_in_USD": amount_out_actual, # Assuming conversion logic elsewhere + "amount_out_USD": amount_out_actual, # Assuming conversion logic elsewhere } async def on_logs(log):