Add mayhem mode support and Token2022 integration (#149)

* feat: mayhem update in idl

* feat(examples): update bonding curve scripts

* feat(example): update listen_blocksubscribe

* feat(examples): update geyser listener

* feat(examples): update all new token listeners

* feat(examples): add comments, fix printing, formatting

* feat(examples): pumpswap buy and sell update with mayhem mode

* fix(examples): sell pump amm fee recipient

* feat(examples): update decode scripts

* feat(examples): update fetch price

* feat(examples): buy and sell bonding curve scripts

* feat(examples): add mint with mayhem mode enabled

* feat(examples): improve listening to wallet txs

* feat(examples): migration listener improvements

* feat(examples): global vol accumulator is not writable

* feat(examples): support token/token2022 programs in buy instructions

* feat(examples): token/token2022 for pumpswap buy

* feat(examples): token/token2022 supprot for sell instructions

* feat(bot): support create_v2 with token2022, mayhem mode, other fixes

* fix(bot): support only token2022 in logs and pumportal listeners

* feat(bot): token2022 support in cleanup flow

* fix(bot): update token program handling and improve price validation in trading logic

* feat(bot): enhance token program handling for LetsBonk integration
This commit is contained in:
Anton Sauchyk
2025-11-18 13:09:37 +01:00
committed by GitHub
parent 7ae8b560bd
commit 03a4e7bcbc
42 changed files with 4593 additions and 885 deletions
+27 -5
View File
@@ -66,10 +66,20 @@ class PlatformAwareBuyer(Trader):
pool_address = self._get_pool_address(token_info, address_provider)
# Regular behavior with RPC call
token_price_sol = await curve_manager.calculate_price(pool_address)
token_amount = (
self.amount / token_price_sol if token_price_sol > 0 else 0
)
# Fetch pool state to get price and mayhem mode status
pool_state = await curve_manager.get_pool_state(pool_address)
token_price_sol = pool_state.get("price_per_token")
# Validate price_per_token is present and positive
if token_price_sol is None or token_price_sol <= 0:
raise ValueError(
f"Invalid price_per_token: {token_price_sol} for pool {pool_address} "
f"(mint: {token_info.mint}) - cannot execute buy with zero/invalid price"
)
# Set is_mayhem_mode from bonding curve state
token_info.is_mayhem_mode = pool_state.get("is_mayhem_mode", False)
token_amount = self.amount / token_price_sol
# Calculate minimum token amount with slippage
minimum_token_amount = token_amount * (1 - self.slippage)
@@ -225,7 +235,19 @@ class PlatformAwareSeller(Trader):
# Get pool address and current price using platform-agnostic method
pool_address = self._get_pool_address(token_info, address_provider)
token_price_sol = await curve_manager.calculate_price(pool_address)
# Fetch pool state to get price and mayhem mode status
pool_state = await curve_manager.get_pool_state(pool_address)
token_price_sol = pool_state.get("price_per_token")
# Validate price_per_token is present and positive
if token_price_sol is None or token_price_sol <= 0:
raise ValueError(
f"Invalid price_per_token: {token_price_sol} for pool {pool_address} "
f"(mint: {token_info.mint}) - cannot execute sell with zero/invalid price"
)
# Set is_mayhem_mode from bonding curve state
token_info.is_mayhem_mode = pool_state.get("is_mayhem_mode", False)
logger.info(f"Price per Token: {token_price_sol:.8f} SOL")
+16 -1
View File
@@ -193,6 +193,7 @@ class UniversalTrader:
# State tracking
self.traded_mints: set[Pubkey] = set()
self.traded_token_programs: dict[str, Pubkey] = {} # Maps mint (as string) to token_program_id
self.token_queue: asyncio.Queue = asyncio.Queue()
self.processing: bool = False
self.processed_tokens: set[str] = set()
@@ -325,10 +326,17 @@ class UniversalTrader:
if self.traded_mints:
try:
logger.info(f"Cleaning up {len(self.traded_mints)} traded token(s)...")
# Build parallel lists of mints and token_program_ids
mints_list = list(self.traded_mints)
token_program_ids = [
self.traded_token_programs.get(str(mint))
for mint in mints_list
]
await handle_cleanup_post_session(
self.solana_client,
self.wallet,
list(self.traded_mints),
mints_list,
token_program_ids,
self.priority_fee_manager,
self.cleanup_mode,
self.cleanup_with_priority_fee,
@@ -447,6 +455,10 @@ class UniversalTrader:
buy_result.tx_signature,
)
self.traded_mints.add(token_info.mint)
# Track token program for cleanup
mint_str = str(token_info.mint)
if token_info.token_program_id:
self.traded_token_programs[mint_str] = token_info.token_program_id
# Choose exit strategy
if not self.marry_mode:
@@ -469,6 +481,7 @@ class UniversalTrader:
self.solana_client,
self.wallet,
token_info.mint,
token_info.token_program_id,
self.priority_fee_manager,
self.cleanup_mode,
self.cleanup_with_priority_fee,
@@ -521,6 +534,7 @@ class UniversalTrader:
self.solana_client,
self.wallet,
token_info.mint,
token_info.token_program_id,
self.priority_fee_manager,
self.cleanup_mode,
self.cleanup_with_priority_fee,
@@ -590,6 +604,7 @@ class UniversalTrader:
self.solana_client,
self.wallet,
token_info.mint,
token_info.token_program_id,
self.priority_fee_manager,
self.cleanup_mode,
self.cleanup_with_priority_fee,