wip
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@ crypto/sol/logs/error.log
|
|||||||
crypto/sol/logs/token_info.json
|
crypto/sol/logs/token_info.json
|
||||||
crypto/sol/logs/transation_details.json
|
crypto/sol/logs/transation_details.json
|
||||||
.env
|
.env
|
||||||
|
app_data.db
|
||||||
|
BIN
app_data.db
BIN
app_data.db
Binary file not shown.
@ -207,161 +207,161 @@ async def process_log(log_result):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def follow_move_legacy(move):
|
# async def follow_move_legacy(move):
|
||||||
global pk
|
# global pk
|
||||||
if pk is None:
|
# if pk is None:
|
||||||
pk = await get_pk()
|
# pk = await get_pk()
|
||||||
your_balances = await SAPI.dex.get_wallet_balances(YOUR_WALLET, doGetTokenName=False)
|
# your_balances = await SAPI.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)
|
# 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:
|
||||||
# Use the balance
|
# # Use the balance
|
||||||
print(f"Your balance: {your_balance_info['amount']} {move['symbol_in']}")
|
# print(f"Your balance: {your_balance_info['amount']} {move['symbol_in']}")
|
||||||
else:
|
# else:
|
||||||
print(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
# 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.")
|
# await telegram_utils.send_telegram_message(f"No ballance found for {move['symbol_in']}. Skipping move.")
|
||||||
return
|
# return
|
||||||
|
|
||||||
your_balance = your_balance_info['amount']
|
# your_balance = your_balance_info['amount']
|
||||||
|
|
||||||
|
|
||||||
token_info = SAPI.dex.TOKENS_INFO.get(move['token_in'])
|
# token_info = SAPI.dex.TOKENS_INFO.get(move['token_in'])
|
||||||
token_name_in = token_info.get('symbol') or await SAPI.get_token_metadata(move['token_in'])
|
# token_name_in = token_info.get('symbol') or await SAPI.get_token_metadata(move['token_in'])
|
||||||
token_name_out = SAPI.dex.TOKENS_INFO[move['token_out']].get('symbol') or await SAPI.get_token_metadata_symbol(move['token_out'])
|
# token_name_out = SAPI.dex.TOKENS_INFO[move['token_out']].get('symbol') or await SAPI.get_token_metadata_symbol(move['token_out'])
|
||||||
|
|
||||||
if not your_balance:
|
# if not your_balance:
|
||||||
msg = f"<b>Move not followed:</b>\nNo balance found for token {move['symbol_in']}. Cannot follow move."
|
# msg = f"<b>Move not followed:</b>\nNo balance found for token {move['symbol_in']}. Cannot follow move."
|
||||||
logging.warning(msg)
|
# logging.warning(msg)
|
||||||
await telegram_utils.send_telegram_message(msg)
|
# await telegram_utils.send_telegram_message(msg)
|
||||||
return
|
# return
|
||||||
|
|
||||||
if FOLLOW_AMOUNT == 'percentage':
|
# if FOLLOW_AMOUNT == 'percentage':
|
||||||
# Calculate the amount to swap based on the same percentage as the followed move
|
# # Calculate the amount to swap based on the same percentage as the followed move
|
||||||
amount_to_swap = your_balance * (move['percentage_swapped'] / 100)
|
# amount_to_swap = your_balance * (move['percentage_swapped'] / 100)
|
||||||
elif FOLLOW_AMOUNT == 'exact':
|
# elif FOLLOW_AMOUNT == 'exact':
|
||||||
amount_to_swap = move['amount_in']
|
# amount_to_swap = move['amount_in']
|
||||||
else:
|
# else:
|
||||||
try:
|
# try:
|
||||||
fixed_amount = float(FOLLOW_AMOUNT) # un USD
|
# fixed_amount = float(FOLLOW_AMOUNT) # un USD
|
||||||
fixed_amount_in_token = fixed_amount / move["token_in_price"]
|
# fixed_amount_in_token = fixed_amount / move["token_in_price"]
|
||||||
amount_to_swap = min(fixed_amount_in_token, your_balance)
|
# amount_to_swap = min(fixed_amount_in_token, your_balance)
|
||||||
except ValueError:
|
# except ValueError:
|
||||||
msg = f"<b>Move not followed:</b>\nInvalid FOLLOW_AMOUNT '{FOLLOW_AMOUNT}'. Must be 'percentage' or a number."
|
# msg = f"<b>Move not followed:</b>\nInvalid FOLLOW_AMOUNT '{FOLLOW_AMOUNT}'. Must be 'percentage' or a number."
|
||||||
logging.warning(msg)
|
# logging.warning(msg)
|
||||||
await telegram_utils.send_telegram_message(msg)
|
# await telegram_utils.send_telegram_message(msg)
|
||||||
return
|
# 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')
|
# decimals = token_info.get('decimals')
|
||||||
# Convert to lamports
|
# # Convert to lamports
|
||||||
# if decimals is 6, then amount = amount * 1e6; if 9, then amount = amount * 1e9
|
# # if decimals is 6, then amount = amount * 1e6; if 9, then amount = amount * 1e9
|
||||||
amount = int(amount_to_swap * 10**decimals)
|
# amount = int(amount_to_swap * 10**decimals)
|
||||||
amount = int(amount)
|
# amount = int(amount)
|
||||||
logging.debug(f"Calculated amount in lamports: {amount}")
|
# logging.debug(f"Calculated amount in lamports: {amount}")
|
||||||
|
|
||||||
if your_balance < amount_to_swap: # should not happen
|
# if your_balance < amount_to_swap: # should not happen
|
||||||
msg = (
|
# msg = (
|
||||||
f"<b>Warning:</b>\n"
|
# 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}).\n This will probably fail. But we will try anyway."
|
# 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}).\n This will probably fail. But we will try anyway."
|
||||||
)
|
# )
|
||||||
logging.warning(msg)
|
# logging.warning(msg)
|
||||||
await telegram_utils.send_telegram_message(msg)
|
# await telegram_utils.send_telegram_message(msg)
|
||||||
try:
|
# try:
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
notification = (
|
# notification = (
|
||||||
f"<b>Initiating move:</b>\n"
|
# f"<b>Initiating move:</b>\n"
|
||||||
f"Swapping {amount_to_swap:.2f} {token_name_in} for {token_name_out}"
|
# f"Swapping {amount_to_swap:.2f} {token_name_in} for {token_name_out}"
|
||||||
+ (f" ({move['percentage_swapped']:.2f}%)" if 'percentage_swapped' in move else "")
|
# + (f" ({move['percentage_swapped']:.2f}%)" if 'percentage_swapped' in move else "")
|
||||||
)
|
# )
|
||||||
# logging.info(notification)
|
# # logging.info(notification)
|
||||||
# error_logger.info(notification)
|
# # error_logger.info(notification)
|
||||||
await telegram_utils.send_telegram_message(notification)
|
# await telegram_utils.send_telegram_message(notification)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logging.error(f"Error sending notification: {e}")
|
# logging.error(f"Error sending notification: {e}")
|
||||||
|
|
||||||
for retry in range(3):
|
# for retry in range(3):
|
||||||
try:
|
# try:
|
||||||
private_key = Keypair.from_bytes(base58.b58decode(pk))
|
# private_key = Keypair.from_bytes(base58.b58decode(pk))
|
||||||
async_client = AsyncClient(SOLANA_WS_URL)
|
# async_client = AsyncClient(SOLANA_WS_URL)
|
||||||
jupiter = Jupiter(async_client, private_key)
|
# jupiter = Jupiter(async_client, private_key)
|
||||||
transaction_data = await jupiter.swap(
|
# transaction_data = await jupiter.swap(
|
||||||
input_mint=move['token_in'],
|
# input_mint=move['token_in'],
|
||||||
output_mint=move['token_out'],
|
# output_mint=move['token_out'],
|
||||||
amount=amount,
|
# amount=amount,
|
||||||
slippage_bps=300, # Increased to 3%
|
# slippage_bps=300, # Increased to 3%
|
||||||
)
|
# )
|
||||||
logging.info(f"Initiating move. Transaction data:\n {transaction_data}")
|
# logging.info(f"Initiating move. Transaction data:\n {transaction_data}")
|
||||||
error_logger.info(f"Initiating move. Transaction data:\n {transaction_data}")
|
# error_logger.info(f"Initiating move. Transaction data:\n {transaction_data}")
|
||||||
raw_transaction = VersionedTransaction.from_bytes(base64.b64decode(transaction_data))
|
# raw_transaction = VersionedTransaction.from_bytes(base64.b64decode(transaction_data))
|
||||||
message = raw_transaction.message
|
# message = raw_transaction.message
|
||||||
signature = private_key.sign_message(message.to_bytes_versioned())
|
# signature = private_key.sign_message(message.to_bytes_versioned())
|
||||||
signed_txn = VersionedTransaction.populate(raw_transaction.message, [signature])
|
# signed_txn = VersionedTransaction.populate(raw_transaction.message, [signature])
|
||||||
opts = TxOpts(skip_preflight=False, preflight_commitment=Processed)
|
# opts = TxOpts(skip_preflight=False, preflight_commitment=Processed)
|
||||||
|
|
||||||
# send the transaction
|
# # send the transaction
|
||||||
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"Follow Transaction Sent: https://solscan.io/tx/{transaction_id}")
|
# print(f"Follow Transaction Sent: https://solscan.io/tx/{transaction_id}")
|
||||||
# append to notification
|
# # append to notification
|
||||||
notification += f"\n\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
|
# notification += f"\n\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
|
||||||
|
|
||||||
await telegram_utils.send_telegram_message(f"Follow Transaction Sent: {transaction_id}")
|
# await telegram_utils.send_telegram_message(f"Follow Transaction Sent: {transaction_id}")
|
||||||
tx_details = await SAPI.get_transaction_details_with_retry(transaction_id)
|
# tx_details = await SAPI.get_transaction_details_with_retry(transaction_id)
|
||||||
|
|
||||||
if tx_details is not None:
|
# if tx_details is not None:
|
||||||
break
|
# break
|
||||||
else:
|
# else:
|
||||||
logging.warning(f"Failed to get transaction details for {transaction_id}. Probably transaction failed. Retrying again...")
|
# logging.warning(f"Failed to get transaction details for {transaction_id}. Probably transaction failed. Retrying again...")
|
||||||
await asyncio.sleep(3)
|
# await asyncio.sleep(3)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
error_message = f"<b>Move Failed:</b>\n{str(e)}</b>\n{transaction_data}</b>\n{move}"
|
# error_message = f"<b>Move Failed:</b>\n{str(e)}</b>\n{transaction_data}</b>\n{move}"
|
||||||
logging.error(error_message)
|
# logging.error(error_message)
|
||||||
# log the errors to /logs/errors.log
|
# # log the errors to /logs/errors.log
|
||||||
error_logger.error(error_message)
|
# error_logger.error(error_message)
|
||||||
error_logger.exception(e)
|
# error_logger.exception(e)
|
||||||
await telegram_utils.send_telegram_message(error_message)
|
# await telegram_utils.send_telegram_message(error_message)
|
||||||
amount = amount * 0.75
|
# amount = amount * 0.75
|
||||||
|
|
||||||
await SAPI.dex.get_wallet_balances(YOUR_WALLET, doGetTokenName=False)
|
# await SAPI.dex.get_wallet_balances(YOUR_WALLET, doGetTokenName=False)
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
if tx_details is None:
|
# if tx_details is None:
|
||||||
logging.info(f"Failed to get transaction details for {transaction_id}")
|
# logging.info(f"Failed to get transaction details for {transaction_id}")
|
||||||
notification = (
|
# notification = (
|
||||||
f"<b>Move Followed, failed to get transaction details.</b>\n"
|
# f"<b>Move Followed, failed to get transaction details.</b>\n"
|
||||||
f"Swapped {amount_to_swap:.6f} {token_name_in} ({move['token_in']}) "
|
# f"Swapped {amount_to_swap:.6f} {token_name_in} ({move['token_in']}) "
|
||||||
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
|
# 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>"
|
# f"\n\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
|
||||||
# log_successful_swap ()
|
# # log_successful_swap ()
|
||||||
)
|
# )
|
||||||
|
|
||||||
else:
|
# else:
|
||||||
notification = (
|
# notification = (
|
||||||
f"<b>Move Followed:</b>\n"
|
# f"<b>Move Followed:</b>\n"
|
||||||
f"Swapped {amount_to_swap:.6f} {token_name_in} ({move['symbol_in']}) "
|
# f"Swapped {amount_to_swap:.6f} {token_name_in} ({move['symbol_in']}) "
|
||||||
f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
|
# f"(same {move['percentage_swapped']:.2f}% as followed wallet)\n"
|
||||||
f"for {tx_details['amount_out']:.2f} {token_name_out}"
|
# f"for {tx_details['amount_out']:.2f} {token_name_out}"
|
||||||
# f"Amount In USD: {tr_details['amount_in_USD']}\n"
|
# # 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>"
|
# f"\n\n<b>Transaction:</b> <a href='https://solscan.io/tx/{transaction_id}'>{transaction_id}</a>"
|
||||||
)
|
# )
|
||||||
logging.info(notification)
|
# logging.info(notification)
|
||||||
await telegram_utils.send_telegram_message(notification)
|
# await telegram_utils.send_telegram_message(notification)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logging.error(f"Error sending notification: {e}")
|
# logging.error(f"Error sending notification: {e}")
|
||||||
|
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
error_message = f"<b>Swap Follow Error:</b>\n{str(e)}"
|
# error_message = f"<b>Swap Follow Error:</b>\n{str(e)}"
|
||||||
logging.error(error_message)
|
# logging.error(error_message)
|
||||||
# log the errors to /logs/errors.log
|
# # log the errors to /logs/errors.log
|
||||||
error_logger.error(error_message)
|
# error_logger.error(error_message)
|
||||||
error_logger.exception(e) \
|
# error_logger.exception(e) \
|
||||||
# if error_message contains 'Program log: Error: insufficient funds'
|
# # if error_message contains 'Program log: Error: insufficient funds'
|
||||||
if 'insufficient funds' in error_message:
|
# if 'insufficient funds' in error_message:
|
||||||
await telegram_utils.send_telegram_message("Insufficient funds. Cannot follow move. Please check your balance.")
|
# await telegram_utils.send_telegram_message("Insufficient funds. Cannot follow move. Please check your balance.")
|
||||||
else:
|
# else:
|
||||||
await telegram_utils.send_telegram_message(error_message)
|
# await telegram_utils.send_telegram_message(error_message)
|
||||||
|
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
@ -401,7 +401,8 @@ async def process_messages(websocket):
|
|||||||
|
|
||||||
|
|
||||||
pk = None
|
pk = None
|
||||||
app = init_app(follow_move_legacy)
|
app = init_app()
|
||||||
|
# app = init_app(follow_move_legacy)
|
||||||
# Convert Flask app to ASGI
|
# Convert Flask app to ASGI
|
||||||
asgi_app = WsgiToAsgi(app)
|
asgi_app = WsgiToAsgi(app)
|
||||||
|
|
||||||
|
@ -276,15 +276,15 @@ class SolanaAPI:
|
|||||||
if solana_ws.websocket:
|
if solana_ws.websocket:
|
||||||
await solana_ws.close()
|
await solana_ws.close()
|
||||||
await async_safe_call(self.on_bot_message,"Reconnecting...")
|
await async_safe_call(self.on_bot_message,"Reconnecting...")
|
||||||
if self.receive_task and not self.receive_task.cancelled():
|
if receive_task and not receive_task.cancelled():
|
||||||
receive_task.cancel()
|
receive_task.cancel()
|
||||||
if self.process_task and not self.process_task.cancelled():
|
if process_task and not process_task.cancelled():
|
||||||
process_task.cancel()
|
process_task.cancel()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"An error occurred while unsubscribing: {e}")
|
logger.error(f"An error occurred while unsubscribing: {e}")
|
||||||
finally:
|
finally:
|
||||||
self.receive_task = None
|
receive_task = None
|
||||||
self.process_task = None
|
process_task = None
|
||||||
|
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(5)
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ def get_latest_log_file(wh:bool):
|
|||||||
# files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f))]
|
# files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f))]
|
||||||
# filter files mask log_20241005_004103_143116.json
|
# filter files mask log_20241005_004103_143116.json
|
||||||
if wh:
|
if wh:
|
||||||
files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f)) and f.startswith('wh-')]
|
files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f)) and f.startswith('wh_')]
|
||||||
else:
|
else:
|
||||||
files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f)) and f.startswith('log_')]
|
files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f)) and f.startswith('log_')]
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user