solana API in module

This commit is contained in:
Dobromir Popov 2024-10-14 17:34:18 +03:00
parent 6b6018cd85
commit 8d714a9801

View File

@ -26,12 +26,14 @@ from config import (
FOLLOWED_WALLET, SOLANA_HTTP_URL FOLLOWED_WALLET, SOLANA_HTTP_URL
) )
from modules.utils import telegram_utils
class SolanaAPI: class SolanaWS:
def __init__(self): def __init__(self, on_message: Optional[callable] = None):
self.websocket = None self.websocket = None
self.subscription_id = None self.subscription_id = None
self.message_queue = asyncio.Queue() self.message_queue = asyncio.Queue()
self.on_message = on_message
async def connect(self): async def connect(self):
while True: while True:
@ -104,8 +106,7 @@ class SolanaAPI:
async def process_messages(self): async def process_messages(self):
while True: while True:
message = await self.message_queue.get() message = await self.message_queue.get()
# Process the message here await self.on_message(message)
# You can add your message processing logic
logger.info(f"Received message: {message}") logger.info(f"Received message: {message}")
async def close(self): async def close(self):
@ -171,98 +172,97 @@ async def solana_jsonrpc(method, params = None, jsonParsed = True):
logging.error(f"Error fetching data from Solana RPC: {e}") logging.error(f"Error fetching data from Solana RPC: {e}")
return None return None
class SolanaAPI:
async def process_log(log): def __init__(self, process_log_callback, send_telegram_message_callback, list_initial_wallet_states_callback):
# Implement your log processing logic here self.process_log = process_log_callback
pass self.list_initial_wallet_states = list_initial_wallet_states_callback
async def send_telegram_message(message): async def process_messages(self, solana_ws):
# Implement your Telegram message sending logic here while True:
pass message = await solana_ws.message_queue.get()
await self.process_log(message)
async def list_initial_wallet_states(): async def wallet_watch_loop():
# Implement your initial wallet state listing logic here solana_ws = SolanaWS(on_message=process_log)
pass first_subscription = True
async def wallet_watch_loop():
solana_ws = SolanaAPI()
first_subscription = True
while True:
try:
await solana_ws.connect()
await solana_ws.subscribe()
if first_subscription:
asyncio.create_task(list_initial_wallet_states())
first_subscription = False
await send_telegram_message(f"Solana mainnet connected ({solana_ws.subscription_id})...")
receive_task = asyncio.create_task(solana_ws.receive_messages())
process_task = asyncio.create_task(solana_ws.process_messages())
while True:
try: try:
await asyncio.gather(receive_task, process_task) await solana_ws.connect()
except asyncio.CancelledError: await solana_ws.subscribe()
pass
if first_subscription:
asyncio.create_task(self.list_initial_wallet_states())
first_subscription = False
await telegram_utils.send_telegram_message(f"Solana mainnet connected ({solana_ws.subscription_id})...")
receive_task = asyncio.create_task(solana_ws.receive_messages())
process_task = asyncio.create_task(solana_ws.process_messages())
try:
await asyncio.gather(receive_task, process_task)
except asyncio.CancelledError:
pass
finally:
receive_task.cancel()
process_task.cancel()
except Exception as e:
logger.error(f"An unexpected error occurred: {e}")
finally: finally:
receive_task.cancel() await solana_ws.unsubscribe()
process_task.cancel() if solana_ws.websocket:
await solana_ws.websocket.close()
await telegram_utils.send_telegram_message("Reconnecting...")
await asyncio.sleep(5)
except Exception as e: async def process_transaction(signature):
logger.error(f"An unexpected error occurred: {e}") # Implement your logic to process each transaction
finally: print(f"Processing transaction: {signature['signature']}")
await solana_ws.unsubscribe() # You can add more processing logic here, such as storing in a database,
if solana_ws.websocket: # triggering notifications, etc.
await solana_ws.websocket.close() # Example usage
await send_telegram_message("Reconnecting...") # async def main():
await asyncio.sleep(5) # account_address = "Vote111111111111111111111111111111111111111"
# Example usage async def get_last_transactions(account_address, check_interval=300, limit=1000):
# async def main(): last_check_time = None
# account_address = "Vote111111111111111111111111111111111111111" last_signature = None
async def get_last_transactions(account_address, check_interval=300, limit=1000): while True:
last_check_time = None current_time = datetime.now()
last_signature = None
while True: if last_check_time is None or (current_time - last_check_time).total_seconds() >= check_interval:
current_time = datetime.now() params = [
account_address,
{
"limit": limit
}
]
if last_check_time is None or (current_time - last_check_time).total_seconds() >= check_interval: if last_signature:
params = [ params[1]["before"] = last_signature
account_address,
{
"limit": limit
}
]
if last_signature: result = await solana_jsonrpc("getSignaturesForAddress", params)
params[1]["before"] = last_signature
result = await solana_jsonrpc("getSignaturesForAddress", params)
if result:
for signature in result:
if last_signature and signature['signature'] == last_signature:
break
# Process the transaction
await process_transaction(signature)
if result: if result:
last_signature = result[0]['signature'] for signature in result:
if last_signature and signature['signature'] == last_signature:
break
last_check_time = current_time # Process the transaction
await process_transaction(signature)
if result:
last_signature = result[0]['signature']
last_check_time = current_time
await asyncio.sleep(1) # Sleep for 1 second before checking again
await asyncio.sleep(1) # Sleep for 1 second before checking again
async def process_transaction(signature):
# Implement your logic to process each transaction
print(f"Processing transaction: {signature['signature']}")
# You can add more processing logic here, such as storing in a database,
# triggering notifications, etc.
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(wallet_watch_loop()) asyncio.run(wallet_watch_loop())