more robust transaction details (with retries) and following

This commit is contained in:
Dobromir Popov 2024-10-07 14:25:57 +03:00
parent e32901d228
commit b7974fbc93

View File

@ -430,7 +430,17 @@ async def get_swap_transaction_details(tx_signature_str):
return None 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): 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: with open('./logs/transation_details.json', 'w') as f:
json.dump(transaction_details, f, indent=2) 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 # Initialize default result structure
parsed_result = { parsed_result = {
"order_id": None, "order_id": None,
@ -536,8 +550,11 @@ async def get_transaction_details_rpc(tx_signature, readfromDump=False):
# Calculate percentage swapped # Calculate percentage swapped
if parsed_result["amount_in"] > 0 and parsed_result["before_source_balance"] > 0: try:
parsed_result["percentage_swapped"] = (parsed_result["amount_in"] / parsed_result["before_source_balance"]) * 100 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 return parsed_result
@ -674,8 +691,7 @@ async def process_log(log_result):
message_text = ( message_text = (
f"Swap detected:\n" f"<b>Swap detected:</b>\n"
f"Order ID: {tr_details['order_id']}\n"
f"Token In: {tr_details['token_in']}\n" f"Token In: {tr_details['token_in']}\n"
f"Token Out: {tr_details['token_out']}\n" f"Token Out: {tr_details['token_out']}\n"
f"Amount In USD: {tr_details['amount_in_USD']}\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: except Exception as e:
logging.error(f"Error fetching swap transaction details: {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 # Fetch token prices
token_prices = await get_token_prices([tr_info['token_in'], tr_info['token_out']]) 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) 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']
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 tx_details = await get_transaction_details_with_retry(transaction_id)
# 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]
output_token_info = your_balances.get(move['token_out'], {'name': 'Unknown'}) if tx_details is None:
output_token_name = output_token_info['name'] logging.info(f"Failed to get transaction details for {transaction_id}")
notification = (
f"<b>Move Followed:</b>\n"
f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) "
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
f"\n\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
)
notification = ( else:
f"<b>Move Followed:</b>\n" output_token_info = your_balances.get(move['token_out'], {'name': 'Unknown'})
f"Swapped {amount_to_swap:.6f} {token_name} ({move['token_in']}) " output_token_name = output_token_info['name']
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
f"for {transaction_data['outputAmount'] / 1e6:.6f} {output_token_name} ({move['token_out']})" notification = (
f"\n\n<b>Transaction:</b> <a href='https://explorer.solana.com/tx/{transaction_id}'>{transaction_id}</a>" f"<b>Move Followed:</b>\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\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
)
logging.info(notification) logging.info(notification)
await send_telegram_message(notification) await send_telegram_message(notification)