storage commeted
This commit is contained in:
@ -48,7 +48,7 @@ import random
|
||||
import websockets
|
||||
from typing import Dict, List, Optional
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from solana.rpc.types import TokenAccountOpts, TxOpts
|
||||
from typing import List, Dict, Any, Tuple
|
||||
import traceback
|
||||
@ -134,6 +134,9 @@ class SolanaWS:
|
||||
elif 'error' in response_data:
|
||||
logger.error(f"Error in WebSocket RPC call: {response_data['error']}")
|
||||
return None
|
||||
# if result is integer
|
||||
elif "id" in response_data and int(response_data['id']) == 1:
|
||||
return int(response_data['result'])
|
||||
else:
|
||||
logger.warning(f"Unexpected response: {response_data}")
|
||||
return None
|
||||
@ -789,30 +792,36 @@ class SolanaAPI:
|
||||
|
||||
async def follow_move(self,move):
|
||||
try:
|
||||
your_balances = await DEX.get_wallet_balances(YOUR_WALLET, doGetTokenName=False)
|
||||
your_balance_info = next((balance for balance in your_balances.values() if balance['address'] == move['token_in']), None)
|
||||
if your_balance_info is not None:
|
||||
# Use the balance
|
||||
print(f"Your balance: {your_balance_info['amount']} {move['symbol_in']}")
|
||||
else:
|
||||
print(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
||||
await telegram_utils.send_telegram_message(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
||||
return
|
||||
|
||||
your_balance = your_balance_info['amount']
|
||||
|
||||
try:
|
||||
your_balances = await DEX.get_wallet_balances(YOUR_WALLET, doGetTokenName=False)
|
||||
your_balance_info = next((balance for balance in your_balances.values() if balance['address'] == move['token_in']), None)
|
||||
if your_balance_info is not None:
|
||||
# Use the balance
|
||||
print(f"Your balance: {your_balance_info['amount']} {move['symbol_in']}")
|
||||
# else:
|
||||
# print(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
||||
# await telegram_utils.send_telegram_message(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
||||
# return
|
||||
|
||||
your_balance = your_balance_info['amount']
|
||||
|
||||
if not your_balance:
|
||||
msg = f"<b>Move not followed:</b>\nNo balance found for token {move['symbol_in']}. Cannot follow move."
|
||||
logging.warning(msg)
|
||||
await telegram_utils.send_telegram_message(msg)
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching your balance: {e}")
|
||||
if FOLLOW_AMOUNT == 'proportional':
|
||||
return
|
||||
|
||||
token_info = DEX.TOKENS_INFO.get(move['token_in'])
|
||||
token_name_in = token_info.get('symbol') or await SAPI.get_token_metadata_symbol(move['token_in'])
|
||||
token_name_out = DEX.TOKENS_INFO[move['token_out']].get('symbol') or await SAPI.get_token_metadata_symbol(move['token_out'])
|
||||
|
||||
if not your_balance:
|
||||
msg = f"<b>Move not followed:</b>\nNo balance found for token {move['symbol_in']}. Cannot follow move."
|
||||
logging.warning(msg)
|
||||
await telegram_utils.send_telegram_message(msg)
|
||||
return
|
||||
|
||||
if FOLLOW_AMOUNT == 'percentage':
|
||||
if FOLLOW_AMOUNT == 'proportional':
|
||||
# Calculate the amount to swap based on the same percentage as the followed move
|
||||
if move.get('percentage_swapped') is None:
|
||||
followed_ballances = await DEX.get_wallet_balances(FOLLOWED_WALLET, doGetTokenName=False)
|
||||
@ -827,11 +836,20 @@ class SolanaAPI:
|
||||
amount_to_swap = 100
|
||||
else:
|
||||
amount_to_swap = your_balance * (move['percentage_swapped'] / 100)
|
||||
elif FOLLOW_AMOUNT == 'exact':
|
||||
amount_to_swap = move['amount_in']
|
||||
# if contains %, then calculate the amount to swap based on the same percentage as the followed move
|
||||
elif '%' in FOLLOW_AMOUNT:
|
||||
try:
|
||||
percentage = float(FOLLOW_AMOUNT.strip('%'))
|
||||
amount_to_swap = move['amount_in'] * (percentage / 100)
|
||||
except ValueError:
|
||||
msg = f"<b>Move not followed:</b>\nInvalid FOLLOW_AMOUNT '{FOLLOW_AMOUNT}'. Must be 'percentage' or a number."
|
||||
logging.warning(msg)
|
||||
await telegram_utils.send_telegram_message(msg)
|
||||
return
|
||||
|
||||
else:
|
||||
try:
|
||||
fixed_amount = float(FOLLOW_AMOUNT) # un USD
|
||||
fixed_amount = float(FOLLOW_AMOUNT) # in USD
|
||||
fixed_amount_in_token = fixed_amount / move["token_in_price"]
|
||||
amount_to_swap = min(fixed_amount_in_token, your_balance)
|
||||
except ValueError:
|
||||
@ -840,7 +858,7 @@ class SolanaAPI:
|
||||
await telegram_utils.send_telegram_message(msg)
|
||||
return
|
||||
|
||||
amount_to_swap = min(amount_to_swap, your_balance) # Ensure we're not trying to swap more than we have
|
||||
# amount_to_swap = min(amount_to_swap, your_balance) # Ensure we're not trying to swap more than we have
|
||||
|
||||
decimals = token_info.get('decimals')
|
||||
# Convert to lamports
|
||||
@ -848,26 +866,26 @@ class SolanaAPI:
|
||||
amount_lamports = int(amount_to_swap * 10**decimals)
|
||||
logging.debug(f"Calculated amount in lamports: {amount_lamports}")
|
||||
|
||||
if your_balance < amount_to_swap: # should not happen
|
||||
msg = (
|
||||
f"<b>Warning:</b>\n"
|
||||
f"Insufficient balance: {your_balance:.6f} {token_name_in}. We want to swap {amount_to_swap:.6f}\n({move['symbol_in']}, decimals {token_info.get('decimals')} amount {amount_lamports}).\n This will probably fail. But we will try anyway."
|
||||
)
|
||||
logging.warning(msg)
|
||||
await telegram_utils.send_telegram_message(msg)
|
||||
# if your_balance < amount_to_swap: # should not happen
|
||||
# msg = (
|
||||
# f"<b>Warning:</b>\n"
|
||||
# f"Insufficient balance: {your_balance:.6f} {token_name_in}. We want to swap {amount_to_swap:.6f}\n({move['symbol_in']}, decimals {token_info.get('decimals')} amount {amount_lamports}).\n This will probably fail. But we will try anyway."
|
||||
# )
|
||||
# logging.warning(msg)
|
||||
# await telegram_utils.send_telegram_message(msg)
|
||||
try:
|
||||
|
||||
try:
|
||||
notification = (
|
||||
f"<b>Initiating move:</b>\n"
|
||||
f"Swapping {amount_to_swap:.2f} {token_name_in} for {token_name_out}"
|
||||
+ (f" ({move['percentage_swapped']:.2f}%)" if 'percentage_swapped' in move else "")
|
||||
)
|
||||
# logging.info(notification)
|
||||
# error_logger.info(notification)
|
||||
# await telegram_utils.send_telegram_message(notification)
|
||||
except Exception as e:
|
||||
logging.error(f"Error sending notification: {e}")
|
||||
# try:
|
||||
# notification = (
|
||||
# f"<b>Initiating move:</b>\n"
|
||||
# f"Swapping {amount_to_swap:.2f} {token_name_in} for {token_name_out}"
|
||||
# + (f" ({move['percentage_swapped']:.2f}%)" if 'percentage_swapped' in move else "")
|
||||
# )
|
||||
# # logging.info(notification)
|
||||
# # error_logger.info(notification)
|
||||
# # await telegram_utils.send_telegram_message(notification)
|
||||
# except Exception as e:
|
||||
# logging.error(f"Error sending notification: {e}")
|
||||
|
||||
if self.pk is None:
|
||||
self.pk = await get_pk()
|
||||
@ -877,6 +895,7 @@ class SolanaAPI:
|
||||
async_client = AsyncClient(SOLANA_WS_URL)
|
||||
jupiter = Jupiter(async_client, private_key)
|
||||
|
||||
|
||||
# https://station.jup.ag/api-v6/post-swap
|
||||
#transaction_data = await jupiter.swap(
|
||||
transaction_data = await self.swap_on_jupiter(
|
||||
@ -889,6 +908,7 @@ class SolanaAPI:
|
||||
logging.info(f"Initiating move. Transaction data:\n {transaction_data}")
|
||||
|
||||
raw_transaction = VersionedTransaction.from_bytes(base64.b64decode(transaction_data))
|
||||
|
||||
# working - no priority fee
|
||||
signature = private_key.sign_message(message.to_bytes_versioned(raw_transaction.message))
|
||||
signed_txn = VersionedTransaction.populate(raw_transaction.message, [signature])
|
||||
@ -896,8 +916,9 @@ class SolanaAPI:
|
||||
opts = TxOpts(
|
||||
skip_preflight=False,
|
||||
preflight_commitment=Processed,
|
||||
max_retries=5 # Add retries for network issues
|
||||
)
|
||||
|
||||
|
||||
# send the transaction
|
||||
result = await async_client.send_raw_transaction(txn=bytes(signed_txn), opts=opts)
|
||||
|
||||
@ -913,7 +934,10 @@ class SolanaAPI:
|
||||
logging.warning(f"Failed to get transaction details for {transaction_id}.\n Probably transaction failed. Retrying again...")
|
||||
await asyncio.sleep(3)
|
||||
except Exception as e:
|
||||
decoded_data = ''# base64.b64decode(transaction_data)
|
||||
# decode transacion data (try base58/64)
|
||||
# decoded_data = base58.b58decode(transaction_data).decode('utf-8')
|
||||
# decoded_data = base64.b64decode(transaction_data).decode('utf-8')
|
||||
decoded_data = None
|
||||
error_message = f"<b>Move Failed:</b>\n{str(e)}</b>\n{decoded_data}</b>\n{move}"
|
||||
logging.error(error_message)
|
||||
# log the errors to /logs/errors.log
|
||||
@ -1045,7 +1069,8 @@ class SolanaDEX:
|
||||
token_info = self.TOKENS_INFO.setdefault(token, {})
|
||||
if 'symbol' not in token_info:
|
||||
token_info['symbol'] = await SAPI.get_token_metadata_symbol(token)
|
||||
token_info['price'] = price
|
||||
token_info['price'] = price
|
||||
token_info['lastUpdated'] = datetime.now().isoformat()
|
||||
|
||||
return prices
|
||||
|
||||
@ -1186,6 +1211,10 @@ class SolanaDEX:
|
||||
asyncio.set_event_loop(loop)
|
||||
logging.info(f"Getting balances for wallet: {wallet_address}")
|
||||
response = None
|
||||
# if ballances got in last 2 minutes, return them
|
||||
if "lastUpdated" in self.TOKENS_INFO and datetime.fromisoformat(self.TOKENS_INFO["lastUpdated"]) > datetime.now() - timedelta(minutes=2):
|
||||
logging.info(f"Using cached balances for wallet: {wallet_address}")
|
||||
return self.TOKENS_INFO
|
||||
try:
|
||||
response = await self.solana_client.get_token_accounts_by_owner_json_parsed(
|
||||
Pubkey.from_string(wallet_address),
|
||||
@ -1204,46 +1233,46 @@ class SolanaDEX:
|
||||
if isinstance(info, dict) and 'mint' in info and 'tokenAmount' in info:
|
||||
mint = info['mint']
|
||||
decimals = int(info['tokenAmount']['decimals'])
|
||||
amount = int(info['tokenAmount']['amount'])
|
||||
amount = int(amount)
|
||||
if amount > 1:
|
||||
amount = float(amount / 10**decimals)
|
||||
if mint in self.TOKENS_INFO:
|
||||
token_name = self.TOKENS_INFO[mint].get('symbol')
|
||||
elif doGetTokenName:
|
||||
token_name = await SAPI.get_token_metadata_symbol(mint) or 'N/A'
|
||||
self.TOKENS_INFO[mint] = {'symbol': token_name}
|
||||
await asyncio.sleep(2)
|
||||
|
||||
self.TOKENS_INFO[mint]['holdedAmount'] = round(amount, decimals)
|
||||
self.TOKENS_INFO[mint]['decimals'] = decimals
|
||||
balances[mint] = {
|
||||
'name': token_name or 'N/A',
|
||||
'address': mint,
|
||||
'amount': amount,
|
||||
'decimals': decimals
|
||||
}
|
||||
try:
|
||||
logging.debug(f"Account balance for {token_name} ({mint}): {amount}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error logging account balance: {str(e)}")
|
||||
amount = float(info['tokenAmount']['uiAmountString'])
|
||||
# amount = float(info['tokenAmount']['amount'])
|
||||
# amount = float(amount / 10**decimals)
|
||||
token_name = None
|
||||
if mint in self.TOKENS_INFO:
|
||||
token_name = self.TOKENS_INFO[mint].get('symbol')
|
||||
elif doGetTokenName:
|
||||
token_name = await SAPI.get_token_metadata_symbol(mint)
|
||||
await asyncio.sleep(2)
|
||||
balances[mint] = {
|
||||
'name': token_name or 'N/A',
|
||||
'address': mint,
|
||||
'amount': amount,
|
||||
'decimals': decimals
|
||||
}
|
||||
self.TOKENS_INFO[mint] = {'symbol': token_name}
|
||||
self.TOKENS_INFO[mint] = self.TOKENS_INFO[mint].update(balances[mint])
|
||||
|
||||
try:
|
||||
logging.debug(f"Account balance for {token_name or "N/A"} ({mint}): {amount}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error logging account balance: {str(e)}")
|
||||
else:
|
||||
logging.warning(f"Unexpected data format for account: {account}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error parsing account data: {str(e)}")
|
||||
|
||||
sol_balance = await self.solana_client.get_balance(Pubkey.from_string(wallet_address))
|
||||
if sol_balance.value is not None:
|
||||
balances['SOL'] = {
|
||||
'name': 'SOL',
|
||||
'address': 'SOL',
|
||||
'amount': sol_balance.value / 1e9
|
||||
}
|
||||
else:
|
||||
logging.warning(f"SOL balance response missing for wallet: {wallet_address}")
|
||||
self.TOKENS_INFO["lastUpdated"] = datetime.now().isoformat()
|
||||
|
||||
# sol_balance = await self.solana_client.get_balance(Pubkey.from_string(wallet_address))
|
||||
# if sol_balance.value is not None:
|
||||
# balances['SOL'] = {
|
||||
# 'name': 'SOL',
|
||||
# 'address': 'SOL',
|
||||
# 'amount': sol_balance.value / 1e9
|
||||
# }
|
||||
# else:
|
||||
# logging.warning(f"SOL balance response missing for wallet: {wallet_address}")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error getting wallet balances: {str(e)}")
|
||||
logging.error(f"Error getting wallet balances: {str(e)} {e.error_msg}")
|
||||
if response and response.value:
|
||||
logging.info(f"Found {len(response.value)} ({len(balances)} non zero) token accounts for wallet: {wallet_address}")
|
||||
else:
|
||||
|
Reference in New Issue
Block a user