tick
This commit is contained in:
parent
b5bc6505a2
commit
019e9f66d4
@ -8,6 +8,11 @@ from solana.rpc.websocket_api import connect
|
||||
from solana.rpc.types import TokenAccountOpts, TxOpts
|
||||
from solana.rpc.commitment import Confirmed
|
||||
from solders.pubkey import Pubkey
|
||||
from solders.keypair import Keypair
|
||||
from solders.transaction import Transaction
|
||||
from solders.message import Message
|
||||
from solders.instruction import Instruction
|
||||
from solders.hash import Hash
|
||||
from dexscreener import DexscreenerClient
|
||||
from telegram import Bot
|
||||
from telegram.constants import ParseMode
|
||||
@ -83,7 +88,7 @@ bot = Bot(token=TELEGRAM_BOT_TOKEN)
|
||||
TOKEN_ADDRESSES = {
|
||||
"SOL": "So11111111111111111111111111111111111111112",
|
||||
"USDC": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
"TARD": "4nfn86ssbv7wiqcsw7bpvn46k24jhe334fudtyxhp1og"
|
||||
"TARD": "4nfn86ssbv7wiqcsw7bpvn46k24jhe334fudtyxhp1og",
|
||||
}
|
||||
|
||||
async def send_telegram_message(message):
|
||||
@ -231,10 +236,20 @@ async def convert_balances_to_currency(balances, token_prices, sol_price):
|
||||
|
||||
async def get_token_balance(wallet_address, token_address):
|
||||
try:
|
||||
response = await solana_client.get_token_accounts_by_owner(
|
||||
response = await solana_client.get_token_accounts_by_owner_json_parsed(
|
||||
Pubkey.from_string(wallet_address),
|
||||
{"mint": Pubkey.from_string(token_address)}
|
||||
opts=TokenAccountOpts(
|
||||
mint=Pubkey.from_string(token_address),
|
||||
# program_id=Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
||||
),
|
||||
commitment=Confirmed
|
||||
)
|
||||
|
||||
|
||||
# response = await solana_client.get_token_accounts_by_owner(
|
||||
# Pubkey.from_string(wallet_address),
|
||||
# {"mint": Pubkey.from_string(token_address)}
|
||||
# )
|
||||
if response['result']['value']:
|
||||
balance = await solana_client.get_token_account_balance(
|
||||
response['result']['value'][0]['pubkey']
|
||||
@ -250,6 +265,55 @@ async def get_token_balance(wallet_address, token_address):
|
||||
return 0
|
||||
|
||||
|
||||
async def get_token_balance_rpc(wallet_address, token_address):
|
||||
url = SOLANA_HTTP_URL
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "getTokenAccountsByOwner",
|
||||
"params": [
|
||||
wallet_address,
|
||||
{
|
||||
"mint": token_address
|
||||
},
|
||||
{
|
||||
"encoding": "jsonParsed"
|
||||
}
|
||||
]
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, headers=headers, data=json.dumps(data))
|
||||
response.raise_for_status() # Raises an error for bad responses
|
||||
accounts = response.json()
|
||||
|
||||
if 'result' in accounts and accounts['result']['value']:
|
||||
first_account = accounts['result']['value'][0]['pubkey']
|
||||
balance_data = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "getTokenAccountBalance",
|
||||
"params": [
|
||||
first_account
|
||||
]
|
||||
}
|
||||
balance_response = requests.post(url, headers=headers, data=json.dumps(balance_data))
|
||||
balance_response.raise_for_status()
|
||||
balance = balance_response.json()
|
||||
|
||||
if 'result' in balance and 'value' in balance['result']:
|
||||
amount = float(balance['result']['value']['uiAmount'])
|
||||
logging.debug(f"Balance for {token_address} in {wallet_address}: {amount}")
|
||||
return amount
|
||||
else:
|
||||
logging.debug(f"No balance found for {token_address} in {wallet_address}")
|
||||
return 0
|
||||
else:
|
||||
logging.debug(f"No account found for {token_address} in {wallet_address}")
|
||||
return 0
|
||||
except requests.exceptions.RequestException as e:
|
||||
logging.error(f"Error getting balance for {token_address} in {wallet_address}: {str(e)} \r\n {e}")
|
||||
return 0
|
||||
ENV_FILE = '.env'
|
||||
|
||||
async def save_subscription_id(subscription_id):
|
||||
@ -335,16 +399,24 @@ async def send_initial_wallet_states(followed_wallet, your_wallet):
|
||||
|
||||
|
||||
async def get_non_zero_token_balances(wallet_address):
|
||||
non_zero_balances = {}
|
||||
|
||||
followed_wallet_balances, followed_token_addresses = await get_wallet_balances(FOLLOWED_WALLET)
|
||||
# return non zero balances for followed wallet
|
||||
non_zero_balances = {token: address for token, address in {**followed_wallet_balances}.items() if address is not None and address > 0}
|
||||
logging.info(f"Getting non-zero balances for wallet: {wallet_address}")
|
||||
for token, address in TOKEN_ADDRESSES.items():
|
||||
balance = await get_token_balance(wallet_address, address)
|
||||
if balance > 0:
|
||||
non_zero_balances[token] = address
|
||||
logging.debug(f"Non-zero balance for {token}: {balance}")
|
||||
return non_zero_balances
|
||||
|
||||
|
||||
# non_zero_balances = {}
|
||||
# logging.info(f"Getting non-zero balances for wallet: {wallet_address}")
|
||||
# for token, address in TOKEN_ADDRESSES.items():
|
||||
# balance = await get_token_balance_rpc(wallet_address, address)
|
||||
# if balance > 0:
|
||||
# non_zero_balances[token] = address
|
||||
# logging.debug(f"Non-zero balance for {token}: {balance}")
|
||||
# return non_zero_balances
|
||||
|
||||
|
||||
async def list_initial_wallet_states():
|
||||
global TOKEN_ADDRESSES, FOLLOWED_WALLET_VALUE, YOUR_WALLET_VALUE
|
||||
|
||||
@ -579,67 +651,40 @@ async def process_log(log_result):
|
||||
|
||||
for log_entry in logs:
|
||||
if any(op in log_entry for op in swap_operations):
|
||||
try:
|
||||
# ++ OLD using solana-py
|
||||
# # Convert the base58 signature string to bytes
|
||||
# tx_signature = Signature(b58decode(tx_signature_str))
|
||||
# # Fetch transaction details
|
||||
# tx_result = await solana_client.get_transaction(tx_signature, max_supported_transaction_version=0)
|
||||
# #tx_result = await get_transaction_details(tx_signature_str)
|
||||
# if tx_result.value is None:
|
||||
# logging.error(f"Transaction not found: {tx_signature_str}")
|
||||
# return
|
||||
# transaction2 = tx_result.value.transaction
|
||||
# -- OLD using solana-py
|
||||
|
||||
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)
|
||||
|
||||
# instructions = transaction['transaction']['message']['instructions']
|
||||
|
||||
# for instruction in instructions:
|
||||
# from_pubkey, to_pubkey, amount_in, amount_out = extract_swap_details(instruction, logs, watched_tokens)
|
||||
|
||||
# if from_pubkey in watched_tokens.values() or to_pubkey in watched_tokens.values():
|
||||
# from_token = determine_token(from_pubkey, watched_tokens)
|
||||
# to_token = determine_token(to_pubkey, watched_tokens)
|
||||
|
||||
# move = {
|
||||
# 'token': from_token,
|
||||
# 'amount': amount_in,
|
||||
# 'to_token': to_token
|
||||
# }
|
||||
# message_text = (
|
||||
# f"Swap detected:\n"
|
||||
# f"From: {from_pubkey} ({from_token})\n"
|
||||
# f"To: {to_pubkey} ({to_token})\n"
|
||||
# f"Amount In: {amount_in}\n"
|
||||
# f"Amount Out: {amount_out}"
|
||||
# )
|
||||
# await send_telegram_message(message_text)
|
||||
# await follow_move(move)
|
||||
|
||||
tokens = []
|
||||
|
||||
|
||||
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']
|
||||
# Assume mint is available for mintTo
|
||||
mint = info.get('mint', 'Unknown')
|
||||
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', []):
|
||||
amount = balance['uiTokenAmount']['amount']
|
||||
mint = balance['mint']
|
||||
tokens.append({'amount': amount, 'mint': mint})
|
||||
tokens.append({'amount': amount, 'mint': mint})
|
||||
|
||||
# get amount_in, amount_out and token in and token out and USD value
|
||||
# Get amount_in, amount_out, tokens, and USD value
|
||||
swap_details = {
|
||||
'amount_in': details['total_amount_in'],
|
||||
'amount_out': details['total_amount_out'],
|
||||
@ -649,11 +694,12 @@ async def process_log(log_result):
|
||||
message_text = (
|
||||
f"Swap detected:\n"
|
||||
f"Amount In: {swap_details['amount_in']}\n"
|
||||
f"Amount Out: {swap_details['amount_out']}"
|
||||
f"Amount Out: {swap_details['amount_out']}\n"
|
||||
f"Tokens: {tokens}"
|
||||
)
|
||||
|
||||
await send_telegram_message(message_text)
|
||||
# await follow_move(move)
|
||||
await follow_move(swap_details)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching transaction details: {e}")
|
||||
@ -784,7 +830,7 @@ async def main():
|
||||
# Initialize logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
await send_telegram_message("Solana Agent Started. Connecting to mainnet...")
|
||||
# await subscribe_to_wallet()
|
||||
await subscribe_to_wallet()
|
||||
|
||||
def run_flask():
|
||||
# Run Flask app without the reloader, so we can run the async main function
|
||||
|
Loading…
x
Reference in New Issue
Block a user