parsing logs only - no details

This commit is contained in:
Dobromir Popov 2024-10-05 21:49:32 +03:00
parent 019e9f66d4
commit 52c4877ed4

View File

@ -644,57 +644,71 @@ async def process_log(log_result):
tx_signature_str = log_result['value']['signature'] tx_signature_str = log_result['value']['signature']
logs = log_result['value']['logs'] logs = log_result['value']['logs']
try: try:
# Detect swap operations in logs # Detect swap operations in logs
swap_operations = ['Program log: Instruction: Swap', 'Program log: Instruction: Swap2'] swap_operations = ['Program log: Instruction: Swap', 'Program log: Instruction: Swap2']
for log_entry in logs: for log_entry in logs:
if any(op in log_entry for op in swap_operations): if any(op in log_entry for op in swap_operations):
try: 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})
# Check post token balances for final token states
for balance in transaction.get('postTokenBalances', []): watched_tokens = await get_non_zero_token_balances(FOLLOWED_WALLET)
amount = balance['uiTokenAmount']['amount'] details = parse_swap_logs(logs)
mint = balance['mint'] # transaction = await get_transaction_details_rpc(tx_signature_str, True)
tokens.append({'amount': amount, 'mint': mint})
# 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 # Get amount_in, amount_out, tokens, and USD value
swap_details = { swap_details = {
'amount_in': details['total_amount_in'], 'amount_in': details['total_amount_in'],
'amount_out': details['total_amount_out'], 'amount_out': details['total_amount_out'],
'tokens': tokens 'tokens': tokens,
'source_token': source_token,
'target_token': target_token
} }
message_text = ( message_text = (
f"Swap detected:\n" f"Swap detected:\n"
f"Amount In: {swap_details['amount_in']}\n" f"Amount In: {swap_details['amount_in']}\n"
f"Amount Out: {swap_details['amount_out']}\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}" f"Tokens: {tokens}"
) )
@ -704,43 +718,63 @@ async def process_log(log_result):
except Exception as e: except Exception as e:
logging.error(f"Error fetching transaction details: {e}") logging.error(f"Error fetching transaction details: {e}")
return return
except Exception as e: except Exception as e:
logging.error(f"Error processing log: {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: for log in logs:
if "SwapEvent" in log: # Check for source and target tokens
parts = log.split("{ ")[1].strip(" }").split(", ") if "Program log:" in log:
event_details = {} if "Swap2" in log:
for part in parts: # This log indicates the start of a swap, resetting details
key, value = part.split(": ") token_in = None
event_details[key.strip()] = value.strip() token_out = None
elif "order_id" in log:
# Aggregate amounts order_id = log.split("order_id: ")[-1]
total_amount_in += int(event_details.get("amount_in", 0)) else:
total_amount_out += int(event_details.get("amount_out", 0)) # Check for source and target tokens
if not token_in:
if "source_token_change:" in log: token_in = log.split("Program log: ")[-1].strip()
# Extract final source and destination token changes 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(", ") changes = log.split(", ")
for change in changes: for change in changes:
key_value = change.split(": ", 1) if "source_token_change" in change:
if len(key_value) != 2: amount_in = int(change.split(": ")[-1])
continue elif "destination_token_change" in change:
key, value = key_value amount_out_expected = int(change.split(": ")[-1])
if key == "source_token_change":
total_amount_in = int(value) # Assuming amount_out_actual is derived in a similar way to amount_out_expected
elif key == "destination_token_change": amount_out_actual = amount_out_expected # Modify if there is a separate way to determine actual amount
total_amount_out = int(value)
return { # Return parsed details as a dictionary
"total_amount_in": total_amount_in, return {
"total_amount_out": total_amount_out, "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): async def on_logs(log):