swap stable again
This commit is contained in:
parent
1b0c72dc08
commit
69241b1498
@ -24,7 +24,7 @@ TELEGRAM_BOT_TOKEN="6749075936:AAHUHiPTDEIu6JH7S2fQdibwsu6JVG3FNG0"
|
||||
DISPLAY_CURRENCY=USD
|
||||
#FOLLOW_AMOUNT=3
|
||||
# proportional, xx%,
|
||||
FOLLOW_AMOUNT=5%
|
||||
FOLLOW_AMOUNT=2%
|
||||
|
||||
LIQUIDITY_TOKENS=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v,So11111111111111111111111111111111111111112
|
||||
|
||||
|
@ -14,17 +14,18 @@ from jupiter_python_sdk.jupiter import Jupiter, Jupiter_DCA
|
||||
from dexscreener import DexscreenerClient
|
||||
from solana.rpc.types import TokenAccountOpts, TxOpts
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.transaction import Signature
|
||||
from solana.rpc.websocket_api import connect
|
||||
from solana.rpc.commitment import Confirmed, Processed
|
||||
from solana.transaction import Transaction
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.rpc.types import TxOpts
|
||||
from solana.rpc.commitment import Confirmed, Finalized, Processed
|
||||
from solana.rpc.core import RPCException
|
||||
|
||||
from solana.transaction import Signature, Transaction
|
||||
from spl.token.client import Token
|
||||
from base64 import b64decode
|
||||
import base58
|
||||
from threading import Thread
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.rpc.types import TxOpts
|
||||
from solana.rpc.commitment import Confirmed, Finalized, Processed
|
||||
|
||||
|
||||
from solders.rpc.requests import GetTransaction
|
||||
@ -304,7 +305,9 @@ class SolanaAPI:
|
||||
finally:
|
||||
receive_task.cancel()
|
||||
process_task.cancel()
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logging.info("Websocket connection cancelled, attempting to reconnect...")
|
||||
await asyncio.sleep(5) # Wait before reconnecting
|
||||
except Exception as e:
|
||||
logger.error(f"An unexpected error occurred: {e}")
|
||||
logger.error("".join(traceback.format_exception(None, e, e.__traceback__)))
|
||||
@ -361,7 +364,7 @@ class SolanaAPI:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def get_token_metadata_symbol(self, mint_address):
|
||||
if mint_address in DEX.TOKENS_INFO and 'symbol' in DEX.TOKENS_INFO[mint_address]:
|
||||
if mint_address in DEX.TOKENS_INFO and DEX.TOKENS_INFO[mint_address] is not None:
|
||||
return DEX.TOKENS_INFO[mint_address].get('symbol')
|
||||
|
||||
try:
|
||||
@ -370,6 +373,8 @@ class SolanaAPI:
|
||||
account_data_data = account_data_result['value']['data']
|
||||
if 'parsed' in account_data_data and 'info' in account_data_data['parsed']:
|
||||
account_data_info = account_data_data['parsed']['info']
|
||||
if DEX.TOKENS_INFO[mint_address] is None:
|
||||
DEX.TOKENS_INFO[mint_address] = {}
|
||||
if 'decimals' in account_data_info:
|
||||
if mint_address in DEX.TOKENS_INFO:
|
||||
DEX.TOKENS_INFO[mint_address]['decimals'] = account_data_info['decimals']
|
||||
@ -780,10 +785,10 @@ class SolanaAPI:
|
||||
# )
|
||||
# response_data = response.json()
|
||||
|
||||
result = response_data['swapTransaction']
|
||||
|
||||
try:
|
||||
response_data['swapTransaction']
|
||||
return response_data['swapTransaction']
|
||||
result = response_data['swapTransaction']
|
||||
return (response_data['swapTransaction'], response_data['lastValidBlockHeight'])
|
||||
except:
|
||||
raise Exception(response_data['error'])
|
||||
# Return the serialized transaction
|
||||
@ -793,15 +798,16 @@ class SolanaAPI:
|
||||
async def follow_move(self,move):
|
||||
try:
|
||||
try:
|
||||
your_balance = 0
|
||||
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:
|
||||
if your_balance_info is not None and 'amount' in your_balance_info and float(your_balance_info['amount']) > 0:
|
||||
# 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
|
||||
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']
|
||||
|
||||
@ -812,7 +818,7 @@ class SolanaAPI:
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching your balance: {e}")
|
||||
logging.error(f"Error fetching your balance: {str(e)}", exc_info=True)
|
||||
if FOLLOW_AMOUNT == 'proportional':
|
||||
return
|
||||
|
||||
@ -898,7 +904,7 @@ class SolanaAPI:
|
||||
|
||||
# https://station.jup.ag/api-v6/post-swap
|
||||
#transaction_data = await jupiter.swap(
|
||||
transaction_data = await self.swap_on_jupiter(
|
||||
(transaction_data, block) = await self.swap_on_jupiter(
|
||||
input_mint=move['token_in'],
|
||||
output_mint=move['token_out'],
|
||||
amount=amount_lamports,
|
||||
@ -933,6 +939,32 @@ class SolanaAPI:
|
||||
else:
|
||||
logging.warning(f"Failed to get transaction details for {transaction_id}.\n Probably transaction failed. Retrying again...")
|
||||
await asyncio.sleep(3)
|
||||
except RPCException as rpce:
|
||||
# Convert to string and parse for key information
|
||||
error_str = str(rpce)
|
||||
|
||||
# Get the main error message
|
||||
if "Error processing Instruction" in error_str:
|
||||
# Check for common errors
|
||||
if "insufficient funds" in error_str:
|
||||
logging.error("Transaction failed: Insufficient funds")
|
||||
elif "custom program error: 0x28" in error_str:
|
||||
logging.error("Transaction failed: Custom program error 40 (0x28) - Likely insufficient funds")
|
||||
|
||||
# Parse logs if available
|
||||
try:
|
||||
logs = rpce.data.result.logs
|
||||
if logs:
|
||||
# Get the last error message from logs
|
||||
error_logs = [log for log in logs if "Error:" in log]
|
||||
if error_logs:
|
||||
logging.error(f"Program error: {error_logs[-1]}")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# Full debug logging
|
||||
logging.debug(f"Full RPC error: {error_str}")
|
||||
|
||||
except Exception as e:
|
||||
# decode transacion data (try base58/64)
|
||||
# decoded_data = base58.b58decode(transaction_data).decode('utf-8')
|
||||
@ -1071,6 +1103,7 @@ class SolanaDEX:
|
||||
token_info['symbol'] = await SAPI.get_token_metadata_symbol(token)
|
||||
token_info['price'] = price
|
||||
token_info['lastUpdated'] = datetime.now().isoformat()
|
||||
token_info['address'] = token
|
||||
|
||||
return prices
|
||||
|
||||
@ -1225,6 +1258,9 @@ class SolanaDEX:
|
||||
)
|
||||
|
||||
if response.value:
|
||||
|
||||
if self.TOKENS_INFO is None:
|
||||
self.TOKENS_INFO = {}
|
||||
for account in response.value:
|
||||
try:
|
||||
parsed_data = account.account.data.parsed
|
||||
@ -1237,7 +1273,7 @@ class SolanaDEX:
|
||||
# amount = float(info['tokenAmount']['amount'])
|
||||
# amount = float(amount / 10**decimals)
|
||||
token_name = None
|
||||
if mint in self.TOKENS_INFO:
|
||||
if mint in self.TOKENS_INFO and isinstance(self.TOKENS_INFO[mint], dict):
|
||||
token_name = self.TOKENS_INFO[mint].get('symbol')
|
||||
elif doGetTokenName:
|
||||
token_name = await SAPI.get_token_metadata_symbol(mint)
|
||||
@ -1252,27 +1288,31 @@ class SolanaDEX:
|
||||
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}")
|
||||
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)}")
|
||||
logging.error(f"Error logging account balance: {str(e)}", exc_info=True)
|
||||
else:
|
||||
logging.warning(f"Unexpected data format for account: {account}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error parsing account data: {str(e)}")
|
||||
logging.error(f"Error parsing account data: {str(e)}", exc_info=True)
|
||||
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}")
|
||||
sol_balance = await self.solana_client.get_balance(Pubkey.from_string(wallet_address))
|
||||
if sol_balance.value is not None:
|
||||
mint = 'So11111111111111111111111111111111111111112'
|
||||
balances[mint] = {
|
||||
'name': 'SOL',
|
||||
'address': mint,
|
||||
'amount': sol_balance.value / 1e9,
|
||||
'decimals': 9
|
||||
}
|
||||
self.TOKENS_INFO[mint] = {'symbol': token_name}
|
||||
self.TOKENS_INFO[mint] = self.TOKENS_INFO[mint].update(balances[mint])
|
||||
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)} {e.error_msg}")
|
||||
logging.error(f"Error getting wallet balances: {str(e)}", exc_info=True)
|
||||
if response and response.value:
|
||||
logging.info(f"Found {len(response.value)} ({len(balances)} non zero) token accounts for wallet: {wallet_address}")
|
||||
else:
|
||||
|
@ -335,13 +335,15 @@ def init_app(tr_handler=None):
|
||||
tr["token_out"]
|
||||
)
|
||||
# ToDo - optimize
|
||||
# prices = await SolanaAPI.DEX.get_token_prices(
|
||||
# [tr["token_in"], tr["token_out"]]
|
||||
# )
|
||||
# tr["token_in_price"] = prices.get(tr["token_in"], 0)
|
||||
# tr["token_out_price"] = prices.get(tr["token_out"], 0)
|
||||
# tr["value_in_USD"] = prices.get(tr["token_in"], 0) * tr["amount_in"]
|
||||
# tr["value_out_USD"] = prices.get(tr["token_out"], 0) * tr["amount_out"]
|
||||
prices = await SolanaAPI.DEX.get_token_prices(
|
||||
[tr["token_in"], tr["token_out"]]
|
||||
)
|
||||
await SolanaAPI.DEX.save_token_info()
|
||||
|
||||
tr["token_in_price"] = prices.get(tr["token_in"], 0)
|
||||
tr["token_out_price"] = prices.get(tr["token_out"], 0)
|
||||
tr["value_in_USD"] = prices.get(tr["token_in"], 0) * tr["amount_in"]
|
||||
tr["value_out_USD"] = prices.get(tr["token_out"], 0) * tr["amount_out"]
|
||||
|
||||
# notification = f"<b>Got WH notification:</b>: {tr['amount_in']} {tr['symbol_in'] or tr["token_in"]} swapped for {tr['amount_out']} {tr['symbol_out']} ${tr['value_out_USD']}\n"
|
||||
# logging.info(notification)
|
||||
|
Loading…
x
Reference in New Issue
Block a user