From b7974fbc93f31aadb63b6553bd058d55b5fa6cad Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 7 Oct 2024 14:25:57 +0300 Subject: [PATCH] more robust transaction details (with retries) and following --- crypto/sol/app.py | 67 +++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/crypto/sol/app.py b/crypto/sol/app.py index d5d03a1..a3d1d57 100644 --- a/crypto/sol/app.py +++ b/crypto/sol/app.py @@ -430,7 +430,17 @@ async def get_swap_transaction_details(tx_signature_str): return None - +async def get_transaction_details_with_retry(transaction_id, retry_delay = 9, max_retries = 7): + # wait for the transaction to be confirmed + # await async_client.wait_for_confirmation(Signature.from_string(transaction_id)) + # qwery every 5 seconds for the transaction details untill not None or 30 seconds + for _ in range(max_retries): + tx_details = await get_transaction_details_rpc(transaction_id) + if tx_details is not None: + break + logging.info(f"({_} of {max_retries}) Waiting for transaction details for {transaction_id}") + await asyncio.sleep(retry_delay) + return tx_details async def get_transaction_details_rpc(tx_signature, readfromDump=False): @@ -445,6 +455,10 @@ async def get_transaction_details_rpc(tx_signature, readfromDump=False): with open('./logs/transation_details.json', 'w') as f: json.dump(transaction_details, f, indent=2) + if transaction_details is None: + logging.error(f"Error fetching transaction details for {tx_signature}") + return None + # Initialize default result structure parsed_result = { "order_id": None, @@ -536,8 +550,11 @@ async def get_transaction_details_rpc(tx_signature, readfromDump=False): # Calculate percentage swapped - if parsed_result["amount_in"] > 0 and parsed_result["before_source_balance"] > 0: - parsed_result["percentage_swapped"] = (parsed_result["amount_in"] / parsed_result["before_source_balance"]) * 100 + try: + if parsed_result["amount_in"] > 0 and 'before_source_balance' in parsed_result and parsed_result["before_source_balance"] > 0: + parsed_result["percentage_swapped"] = (parsed_result["amount_in"] / parsed_result["before_source_balance"]) * 100 + except Exception as e: + logging.error(f"Error calculating percentage swapped: {e}") return parsed_result @@ -674,8 +691,7 @@ async def process_log(log_result): message_text = ( - f"Swap detected:\n" - f"Order ID: {tr_details['order_id']}\n" + f"Swap detected:\n" f"Token In: {tr_details['token_in']}\n" f"Token Out: {tr_details['token_out']}\n" f"Amount In USD: {tr_details['amount_in_USD']}\n" @@ -705,7 +721,7 @@ async def get_transaction_details_info(tx_signature_str: str, logs: List[str]) - except Exception as e: logging.error(f"Error fetching swap transaction details: {e}") - tr_info = await get_transaction_details_rpc(tx_signature_str) + tr_info = await get_transaction_details_with_retry(tx_signature_str) # Fetch token prices token_prices = await get_token_prices([tr_info['token_in'], tr_info['token_out']]) @@ -765,26 +781,31 @@ async def follow_move(move): result = await async_client.send_raw_transaction(txn=bytes(signed_txn), opts=opts) transaction_id = json.loads(result.to_json())['result'] - print(f"Transaction sent: https://explorer.solana.com/tx/{transaction_id}") + print(f"Follow Transaction Sent: https://solscan.io/tx/{transaction_id}") - # wait for the transaction to be confirmed - # await async_client.wait_for_confirmation(Signature.from_string(transaction_id)) - # wait 10 seconds - await asyncio.sleep(10) - # Fetch the transaction details to get the output amount - tx_details = await get_transaction_details_rpc(transaction_id) - output_amount = tx_details.value.meta.post_balances[1] - tx_details.value.meta.pre_balances[1] + tx_details = await get_transaction_details_with_retry(transaction_id) - output_token_info = your_balances.get(move['token_out'], {'name': 'Unknown'}) - output_token_name = output_token_info['name'] + if tx_details is None: + logging.info(f"Failed to get transaction details for {transaction_id}") + notification = ( + f"Move Followed:\n" + f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) " + f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n" + f"\n\nTransaction: {transaction_id}" + ) + + else: + output_token_info = your_balances.get(move['token_out'], {'name': 'Unknown'}) + output_token_name = output_token_info['name'] - notification = ( - f"Move Followed:\n" - f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) " - f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n" - f"for {transaction_data['outputAmount'] / 1e6:.6f} {output_token_name} ({move['token_out']})" - f"\n\nTransaction: {transaction_id}" - ) + notification = ( + f"Move Followed:\n" + f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) " + f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n" + f"for {tx_details['amount_out']:.6f} {output_token_name} ({move['token_out']})" + # f"Amount In USD: {tr_details['amount_in_USD']}\n" + f"\n\nTransaction: {transaction_id}" + ) logging.info(notification) await send_telegram_message(notification)