-
Notifications
You must be signed in to change notification settings - Fork 312
Refactor platform support, add letsbonk #127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis update introduces a comprehensive multi-platform architecture for the trading bot, enabling support for both pump.fun and LetsBonk platforms. The refactor replaces pump.fun-specific logic with platform-agnostic interfaces, factories, and event parsers. New modules implement platform-specific address providers, curve managers, instruction builders, and event processors. Platform-aware listeners and traders are introduced, and configuration files now support a Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant BotRunner
participant ConfigLoader
participant PlatformFactory
participant UniversalTrader
participant ListenerFactory
participant UniversalListener
participant PlatformImpl (AddressProvider/CurveManager/...)
participant SolanaClient
User->>BotRunner: Start bot(s)
BotRunner->>ConfigLoader: Load and validate config
ConfigLoader->>PlatformFactory: Validate platform, get supported listeners
BotRunner->>ListenerFactory: Create universal listener (platform-aware)
ListenerFactory->>UniversalListener: Instantiate with platform(s)
UniversalListener->>PlatformFactory: Register event parsers for each platform
BotRunner->>PlatformFactory: Create platform implementations (AddressProvider, CurveManager, etc.)
BotRunner->>UniversalTrader: Instantiate with platform, listener, etc.
UniversalTrader->>UniversalListener: Listen for tokens
UniversalListener->>UniversalTrader: On token detected (platform-matched)
UniversalTrader->>PlatformImpl: Use AddressProvider/CurveManager for trading logic
UniversalTrader->>SolanaClient: Send transaction(s)
UniversalTrader->>User: Report trade result
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
I forgot to include rules for Claude and Cursor. I'll get them back in future commits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 34
🔭 Outside diff range comments (2)
bots/bot-sniper-3-blocks.yaml (1)
14-20: Fix listener configuration mismatchThe
lets_bonkplatform value is valid (Platform.LETS_BONK == "lets_bonk"in src/interfaces/core.py), but your filters/listener sections don’t align:
- In bots/bot-sniper-3-blocks.yaml under
filters, you have
listener_type: "blocks"
yet the only listener block present isgeyser:.- Per our bots-file rules, exactly one listener section must match
filters.listener_type.Please update one of the following in bots/bot-sniper-3-blocks.yaml:
• Change the listener_type to
"geyser":filters: - listener_type: "blocks" + listener_type: "geyser"• Or add a top-level
blocks:section (with at leastrefresh_interval) to match"blocks":geyser: endpoint: "${GEYSER_ENDPOINT}" api_token: "${GEYSER_API_TOKEN}" +blocks: + refresh_interval: 10 # seconds (adjust as needed)src/bot_runner.py (1)
1-18: Move module imports before asyncio setup.Module imports should be at the top of the file before any code execution.
import asyncio import logging import multiprocessing from datetime import datetime from pathlib import Path import uvloop -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - from config_loader import ( get_platform_from_config, load_bot_config, print_config_summary, validate_platform_listener_combination, ) from trading.universal_trader import UniversalTrader from utils.logger import setup_file_logging +asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
♻️ Duplicate comments (3)
src/monitoring/universal_logs_listener.py (1)
197-197: Rename unused loop variable.Same issue as in
universal_block_listener.py- theplatformvariable is not used in the loop body. Rename to_platformfor consistency.src/platforms/letsbonk/instruction_builder.py (2)
187-188: Hardcoded account creation cost (duplicate issue).Same issue as in
build_buy_instruction- the account creation cost is hardcoded.
230-236: Use lowercase for local variable names (duplicate issue).Same naming convention issue as in
build_buy_instruction.
🧹 Nitpick comments (35)
bots/bot-sniper-4-pp.yaml (1)
14-16: Platform field added – check enumeration & DocsSame note as other configs: verify
"pump_fun"/"lets_bonk"match thePlatformenum strings and update README / sample-docs so users know this field is now mandatory (or optional with default).src/platforms/pumpfun/__init__.py (1)
14-21: Minor: keep__all__alphabetical for readabilityOptional nitpick – listing exports alphabetically avoids merge noise as the file grows.
-__all__ = [ - 'PumpFunAddressProvider', - 'PumpFunCurveManager', - 'PumpFunEventParser', - 'PumpFunInstructionBuilder', - 'PumpFunPumpPortalProcessor' -] +__all__ = [ + 'PumpFunAddressProvider', + 'PumpFunCurveManager', + 'PumpFunEventParser', + 'PumpFunInstructionBuilder', + 'PumpFunPumpPortalProcessor', +]src/platforms/letsbonk/__init__.py (1)
14-21: Alphabetise__all__list (optional)Same cosmetic suggestion as for the pump.fun module.
src/monitoring/base_listener.py (1)
14-20: Add missing return type annotation.The constructor logic is correct and enables platform filtering functionality.
Apply this diff to address the static analysis hint:
- def __init__(self, platform: Platform | None = None): + def __init__(self, platform: Platform | None = None) -> None:src/platforms/letsbonk/pumpportal_processor.py (2)
18-30: Add missing return type annotation.The processor initialization and properties are well-structured and follow the established pattern.
Apply this diff to address the static analysis hint:
- def __init__(self): + def __init__(self) -> None:
53-102: Consider optimizing the additional accounts derivation.The token data processing logic is sound, but creating a temporary
TokenInfoobject to derive additional accounts seems inefficient.Consider adding a direct method to the address provider:
# Instead of creating a temporary TokenInfo base_vault, quote_vault = self.address_provider.derive_vault_addresses(mint, pool_state)This would be more efficient and clearer than the current approach of creating a minimal TokenInfo instance.
src/monitoring/universal_pumpportal_listener.py (2)
21-61: Address import placement and add return type annotation.The multi-platform processor setup is well-designed with efficient pool-to-processor mapping. The dynamic imports are appropriately used to avoid circular dependencies.
Apply these diffs to address static analysis hints:
1. Add return type annotation:
def __init__( self, pumpportal_url: str = "wss://pumpportal.fun/api/data", platforms: list[Platform] | None = None, - ): + ) -> None:2. Move imports to top level (if no circular dependency issues):
+from platforms.letsbonk.pumpportal_processor import LetsBonkPumpPortalProcessor +from platforms.pumpfun.pumpportal_processor import PumpFunPumpPortalProcessor from interfaces.core import Platform, TokenInfo from monitoring.base_listener import BaseTokenListener from utils.logger import get_loggerThen remove the imports from the constructor. However, if this causes circular imports, the current approach is acceptable.
216-216: Consider improving control flow clarity.The function logic is correct, but the return statement placement could be clearer.
Apply this diff to make the control flow more explicit:
except Exception as e: logger.error(f"Error processing PumpPortal WebSocket message: {e}") + return None - return None + # This should not be reached, but included for completeness + return NoneOr restructure to use an else block as suggested by static analysis.
src/monitoring/listener_factory.py (1)
131-147: Consider moving platform-listener compatibility to platform implementations.The hardcoded compatibility lists could become inconsistent with actual platform capabilities. Consider having each platform implementation declare its supported listeners.
This would follow the Open/Closed Principle - new platforms could be added without modifying this factory. Each platform implementation could have a
get_supported_listeners()method.src/platforms/letsbonk/curve_manager.py (1)
25-37: Add return type annotation for__init__method.-def __init__(self, client: SolanaClient, idl_parser: IDLParser): +def __init__(self, client: SolanaClient, idl_parser: IDLParser) -> None:src/monitoring/universal_block_listener.py (1)
216-229: Rename unused loop variable.The
platformvariable is not used in the loop body.-for platform, parser in self.platform_parsers.items(): +for _platform, parser in self.platform_parsers.items(): # Check if the parser has a block parsing method if hasattr(parser, 'parse_token_creation_from_block'):src/bot_runner.py (2)
39-54: Remove redundant exception objects from logging.exception calls.
logging.exception()already includes the exception details and traceback.-logging.exception(f"Platform configuration error: {e}") +logging.exception("Platform configuration error")-logging.exception(f"Could not validate platform support: {e}") +logging.exception("Could not validate platform support")
152-229: Consider extracting bot validation logic to reduce complexity.The function's complexity (11) exceeds the recommended threshold due to nested validation. Consider extracting the validation logic into a separate function.
Example refactor:
def validate_bot_config(cfg: dict, bot_name: str) -> tuple[bool, Platform | None, str]: """Validate bot configuration. Returns: Tuple of (is_valid, platform, error_message) """ try: platform = get_platform_from_config(cfg) # ... rest of validation logic return True, platform, "" except Exception as e: return False, None, str(e)This would simplify the main loop and make testing easier.
src/monitoring/universal_geyser_listener.py (1)
200-208: Use underscore prefix for unused loop variableThe
platformvariable is not used within the loop body.- for platform, parser in self.platform_parsers.items(): + for _platform, parser in self.platform_parsers.items(): if program_id == parser.get_program_id(): # Use the platform's event parser token_info = parser.parse_token_creation_from_instruction( ix.data, ix.accounts, msg.account_keys ) if token_info: return token_infosrc/platforms/letsbonk/event_parser.py (2)
48-64: Remove unused method or implement functionalityThe method has unused parameters and always returns
None. If LetsBonk doesn't support log-based token detection, consider documenting this more clearly.def parse_token_creation_from_logs( self, - logs: list[str], - signature: str + logs: list[str], # noqa: ARG002 + signature: str # noqa: ARG002 ) -> TokenInfo | None: """Parse token creation from LetsBonk transaction logs. + Note: LetsBonk doesn't emit specific logs for token creation. + Token creation must be identified through instruction parsing. + Args: logs: List of log strings from transaction signature: Transaction signature Returns: - TokenInfo if token creation found, None otherwise + None - LetsBonk requires instruction-based parsing """ - # LetsBonk doesn't emit specific logs for token creation like pump.fun - # Token creation is identified through instruction parsing return None
87-94: Add type annotations to inner functionThe helper function should have proper type annotations.
- def get_account_key(index): + def get_account_key(index: int) -> Pubkey | None: if index >= len(accounts): return None account_index = accounts[index] if account_index >= len(account_keys): return None return Pubkey.from_bytes(account_keys[account_index])src/trading/platform_aware.py (1)
23-43: Refactor constructor to reduce parametersThe constructor has too many parameters (8). Consider using a configuration object.
@dataclass class BuyerConfig: """Configuration for platform-aware buyer.""" amount: float slippage: float = 0.01 max_retries: int = 5 extreme_fast_token_amount: int = 0 extreme_fast_mode: bool = False class PlatformAwareBuyer(Trader): def __init__( self, client: SolanaClient, wallet: Wallet, priority_fee_manager: PriorityFeeManager, config: BuyerConfig, ): """Initialize platform-aware token buyer.""" self.client = client self.wallet = wallet self.priority_fee_manager = priority_fee_manager self.config = configAlso, consider making boolean parameters keyword-only:
max_retries: int = 5, + *, extreme_fast_token_amount: int = 0, extreme_fast_mode: bool = False,src/config_loader.py (3)
42-43: Ensure platform validation values match the Platform enum.The platform values here are hardcoded strings. Consider importing and using the Platform enum values directly to maintain consistency:
- "platform": ["pump_fun", "lets_bonk"], + "platform": [p.value for p in Platform],This ensures the validation automatically stays in sync with any future Platform enum changes.
161-167: Consider moving platform factory import to module level.The dynamic import inside the function could impact performance if this validation is called frequently. Consider importing at module level with proper error handling:
# At module level try: from platforms import platform_factory HAS_PLATFORM_FACTORY = True except ImportError: HAS_PLATFORM_FACTORY = False # In function if HAS_PLATFORM_FACTORY: if not platform_factory.registry.is_platform_supported(platform): # ... error handling
265-266: Fix percentage display calculation.The percentage calculation has a potential issue:
- print(f" - Buy slippage: {trade.get('buy_slippage', 'not configured') * 100}%") + buy_slippage = trade.get('buy_slippage', 'not configured') + print(f" - Buy slippage: {buy_slippage * 100 if isinstance(buy_slippage, (int, float)) else buy_slippage}%")This prevents attempting to multiply a string by 100 when the value is 'not configured'.
src/platforms/pumpfun/curve_manager.py (2)
24-35: Add return type annotation for consistency.- def __init__(self, client: SolanaClient, idl_parser: IDLParser): + def __init__(self, client: SolanaClient, idl_parser: IDLParser) -> None:
181-182: Provide more specific error information.Consider including the account type in the error message for better debugging:
if not decoded_curve_state: - raise ValueError("Failed to decode bonding curve state with IDL parser") + raise ValueError("Failed to decode BondingCurve account data with IDL parser")src/platforms/pumpfun/address_provider.py (2)
22-36: Consider using class-level constants instead of dataclass fields.The static analyzer warns about function calls in dataclass defaults. While
Pubkeyobjects are likely immutable, you could refactor to avoid the warning:class PumpFunAddresses: """Pump.fun program addresses.""" PROGRAM: Final[Pubkey] = Pubkey.from_string( "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" ) # ... rest of the addressesRemove the
@dataclassdecorator since these are all class constants, not instance fields.
105-122: Document why quote_mint parameter is ignored.The
quote_mintparameter is unused, which could confuse users of this interface:def derive_pool_address(self, base_mint: Pubkey, quote_mint: Pubkey | None = None) -> Pubkey: """Derive the bonding curve address for a token. For pump.fun, this is the bonding curve PDA derived from the mint. + The quote_mint parameter is ignored as pump.fun always uses SOL as the quote token. Args: base_mint: Token mint address - quote_mint: Not used for pump.fun (SOL is always the quote) + quote_mint: Ignored - pump.fun always uses SOL as quote token Returns: Bonding curve address """src/platforms/letsbonk/address_provider.py (2)
22-26: Apply same refactoring as pump.fun for consistency.Like the pump.fun provider, consider using class-level constants:
class LetsBonkAddresses: """LetsBonk (Raydium LaunchLab) program addresses.""" # Raydium LaunchLab program addresses PROGRAM: Final[Pubkey] = Pubkey.from_string("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj") # ... rest of the addressesRemove the
@dataclassdecorator for consistency with the pump.fun implementation.
184-184: Use lowercase for local constants per Python conventions.- AUTH_SEED = b"vault_auth_seed" + auth_seed = b"vault_auth_seed" authority_pda, _ = Pubkey.find_program_address( - [AUTH_SEED], + [auth_seed], LetsBonkAddresses.PROGRAM ) # Similarly for EVENT_AUTHORITY_SEED: - EVENT_AUTHORITY_SEED = b"__event_authority" + event_authority_seed = b"__event_authority"Also applies to: 199-199
src/utils/idl_manager.py (1)
58-65: Define custom exceptions for better error handling.The long error messages in exceptions should be moved to custom exception classes for better maintainability and consistent error handling.
Define custom exceptions at the module level:
class PlatformNotSupportedError(ValueError): """Raised when a platform doesn't have IDL support configured.""" def __init__(self, platform: Platform): super().__init__(f"Platform {platform.value} does not have IDL support configured") self.platform = platform class IDLFileNotFoundError(FileNotFoundError): """Raised when IDL file is not found for a platform.""" def __init__(self, platform: Platform, path: str): super().__init__(f"IDL file not found for {platform.value} at {path}") self.platform = platform self.path = pathThen use them:
-if platform not in self._idl_paths: - raise ValueError(f"Platform {platform.value} does not have IDL support configured") +if platform not in self._idl_paths: + raise PlatformNotSupportedError(platform) -if not os.path.exists(idl_path): - raise FileNotFoundError(f"IDL file not found for {platform.value} at {idl_path}") +if not idl_path.exists(): + raise IDLFileNotFoundError(platform, str(idl_path))src/trading/base.py (2)
86-86: Follow Python naming conventions for classes.Class names should use CapWords convention without underscores.
-class TokenInfo_Legacy: +class TokenInfoLegacy: """Legacy token information structure for backward compatibility."""Update all references to this class throughout the file accordingly.
203-251: Refactor function with too many parameters.This function has 9 parameters, making it difficult to use and maintain. Consider using a builder pattern or configuration object.
@dataclass class PumpFunTokenConfig: """Configuration for creating pump.fun tokens.""" name: str symbol: str uri: str mint: Pubkey bonding_curve: Pubkey associated_bonding_curve: Pubkey user: Pubkey creator: Pubkey | None = None creator_vault: Pubkey | None = None extra_fields: dict[str, Any] = field(default_factory=dict) def create_pump_fun_token_info(config: PumpFunTokenConfig) -> TokenInfo: """Create pump.fun TokenInfo from configuration.""" return TokenInfo( name=config.name, symbol=config.symbol, uri=config.uri, mint=config.mint, platform=Platform.PUMP_FUN, bonding_curve=config.bonding_curve, associated_bonding_curve=config.associated_bonding_curve, user=config.user, creator=config.creator or config.user, creator_vault=config.creator_vault, **config.extra_fields )src/platforms/letsbonk/instruction_builder.py (2)
28-42: Add return type annotation to__init__method.According to type annotation best practices, special methods should have explicit return type annotations.
- def __init__(self, idl_parser: IDLParser): + def __init__(self, idl_parser: IDLParser) -> None:
132-137: Use lowercase for local variable names.Local variable should follow lowercase naming convention.
- # Build instruction data: discriminator + amount_in + minimum_amount_out + share_fee_rate - SHARE_FEE_RATE = 0 # No sharing fee + # Build instruction data: discriminator + amount_in + minimum_amount_out + share_fee_rate + share_fee_rate = 0 # No sharing fee instruction_data = ( self._buy_exact_in_discriminator + struct.pack("<Q", amount_in) + # amount_in (u64) - SOL to spend struct.pack("<Q", minimum_amount_out) + # minimum_amount_out (u64) - min tokens - struct.pack("<Q", SHARE_FEE_RATE) # share_fee_rate (u64): 0 + struct.pack("<Q", share_fee_rate) # share_fee_rate (u64): 0 )src/utils/idl_parser.py (4)
25-38: Add ClassVar annotation for mutable class attribute.Mutable class attributes should be annotated with
ClassVarto indicate they're shared across instances.+from typing import ClassVar + class IDLParser: """Parser for automatically decoding instructions and events using IDL definitions.""" # A single source of truth for primitive type information, mapping the type name # to its struct format character and size in bytes. - _PRIMITIVE_TYPE_INFO = { + _PRIMITIVE_TYPE_INFO: ClassVar[dict[str, tuple[str | None, int]]] = {
40-48: Add return type annotation and improve parameter design.The
__init__method should have a return type annotation, and boolean parameters should be keyword-only.- def __init__(self, idl_path: str, verbose: bool = False): + def __init__(self, idl_path: str, *, verbose: bool = False) -> None:
91-116: Use more specific exception types instead of bare Exception.Catching bare
Exceptioncan hide unexpected errors. Consider catching specific exceptions.for arg in instruction.get('args', []): try: value, decode_offset = self._decode_type(data_args, decode_offset, arg['type']) args[arg['name']] = value - except Exception as e: + except (ValueError, struct.error, IndexError) as e: if self.verbose: print(f"❌ Decode error in argument '{arg['name']}': {e}") return None
224-228: Use more specific exception types in event field decoding.Similar to instruction decoding, use specific exceptions.
try: value, decode_offset = self._decode_type(data_part, decode_offset, field['type']) event_fields[field['name']] = value if self.verbose: if field['type'] == 'string': print(f" -> '{value}'") elif field['type'] == 'pubkey': print(f" -> {value}") else: print(f" -> {value}") - except Exception as e: + except (ValueError, struct.error, IndexError) as e: if self.verbose: print(f"Error decoding field {field['name']}: {e}") # Don't return None here, continue with other fields continue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 27
🔭 Outside diff range comments (3)
bots/bot-sniper-4-pp.yaml (1)
14-20: Missing mandatory PumpPortal fields and listener mismatch riskThe
platformkey addition itself is fine, however the accompanying PumpPortal listener block is incomplete:
- Coding-guidelines mandate
endpointandapi_keywhenpumpportalis used – onlyurlis provided.- Without these keys the config loader will likely reject the file or the bot will fail at runtime.
pumpportal: - url: "wss://pumpportal.fun/api/data" # Default PumpPortal WebSocket URL + # Mandatory fields + endpoint: "wss://pumpportal.fun/api/data" + api_key: "${PUMPPORTAL_API_KEY}" + # Optional alias + url: "wss://pumpportal.fun/api/data"Also double-check that
filters.listener_typeremains"pumpportal"after fixing.bots/bot-sniper-3-blocks.yaml (1)
14-22: Inconsistent listener configuration – file will be rejected by validator
filters.listener_typeis set to"blocks"but the only listener section present is Geyser – coding guidelines require exactly one matching section.- If a
blockslistener is intended, ablocks:section withrefresh_intervalis mandatory.- If Geyser is desired, change
listener_typeto"geyser"and drop the comment header.-# Geyser configuration (fastest method for getting updates) -geyser: - endpoint: "${GEYSER_ENDPOINT}" - api_token: "${GEYSER_API_TOKEN}" - auth_type: "basic" # or "x-token" +# Blocks listener configuration +blocks: + refresh_interval: 0.4 # secondsor
- listener_type: "blocks" + listener_type: "geyser"Pick one to satisfy the “exactly one listener” rule.
Also applies to: 54-58
bots/bot-sniper-2-logs.yaml (1)
17-22: Configuration inconsistency: Both Geyser and logs listeners configuredThis configuration file contains both a Geyser section (lines 17-22) and sets
listener_type: "logs"(line 57). According to the coding guidelines, each configuration must specify exactly one listener section. Based on the filenamebot-sniper-2-logs.yaml, the Geyser section should be removed.Apply this diff to remove the inconsistent Geyser configuration:
-# Geyser configuration (fastest method for getting updates) -geyser: - endpoint: "${GEYSER_ENDPOINT}" - api_token: "${GEYSER_API_TOKEN}" - auth_type: "basic" # or "x-token" - # Trading parametersAlso applies to: 57-57
♻️ Duplicate comments (2)
src/platforms/letsbonk/instruction_builder.py (2)
187-187: Use the same constant for account creation cost.This is a duplicate of the hardcoded value in the buy method.
230-230: Use lowercase for local variable names.Same naming convention issue as in the buy method.
🧹 Nitpick comments (38)
src/platforms/letsbonk/__init__.py (1)
14-21: Minor style nit – prefer immutabletuplefor__all__Not critical, but using a tuple avoids accidental mutation.
-__all__ = [ +__all__ = ( 'LetsBonkAddressProvider', 'LetsBonkCurveManager', 'LetsBonkEventParser', 'LetsBonkInstructionBuilder', - 'LetsBonkPumpPortalProcessor' -] + 'LetsBonkPumpPortalProcessor', +)src/platforms/pumpfun/__init__.py (1)
14-21: Apply same__all__tuple style for consistencyMirror the immutable-tuple pattern suggested for LetsBonk to keep both platform packages consistent.
-__all__ = [ +__all__ = ( 'PumpFunAddressProvider', 'PumpFunCurveManager', 'PumpFunEventParser', 'PumpFunInstructionBuilder', - 'PumpFunPumpPortalProcessor' -] + 'PumpFunPumpPortalProcessor', +)bots/bot-sniper-2-logs.yaml (1)
31-33: Remove unnecessary TP/SL parameters for time-based strategyWhen using
exit_strategy: "time_based", thetake_profit_percentageandstop_loss_percentagefields are not utilized. These should be removed to avoid confusion.Apply this diff to remove the unnecessary fields:
# Exit strategy configuration exit_strategy: "time_based" # Options: "time_based", "tp_sl", "manual" - take_profit_percentage: 0.4 # Take profit at 40% gain (0.4 = 40%) - stop_loss_percentage: 0.4 # Stop loss at 40% loss (0.4 = 40%) max_hold_time: 60 # Maximum hold time in secondssrc/monitoring/base_listener.py (1)
14-20: Add return type annotation for init methodThe platform-agnostic refactoring looks good. Consider adding the return type annotation for completeness.
Apply this diff to add the return type annotation:
- def __init__(self, platform: Platform | None = None): + def __init__(self, platform: Platform | None = None) -> None:src/platforms/letsbonk/pumpportal_processor.py (3)
18-20: Add return type annotation for init methodApply this diff to add the return type annotation:
- def __init__(self): + def __init__(self) -> None:
61-66: Verify LetsBonk field mappings with actual PumpPortal dataThe TODO comment indicates uncertainty about the actual field mappings for LetsBonk tokens from PumpPortal. This needs to be verified with real data to ensure the processor works correctly.
Would you like me to help implement a test script to capture and analyze actual PumpPortal data for LetsBonk tokens to confirm the correct field mappings?
116-118: Improve exception handling and loggingUse more specific exception handling and
logger.exceptionfor better debugging.Apply this diff to improve error handling:
- except Exception as e: - logger.error(f"Failed to process PumpPortal LetsBonk token data: {e}") + except (KeyError, ValueError, TypeError) as e: + logger.exception("Failed to process PumpPortal LetsBonk token data") return Nonesrc/monitoring/universal_pumpportal_listener.py (1)
21-32: Add return type annotation for init methodApply this diff to add the return type annotation:
def __init__( self, pumpportal_url: str = "wss://pumpportal.fun/api/data", platforms: list[Platform] | None = None, - ): + ) -> None:src/monitoring/listener_factory.py (2)
52-93: Move dynamic imports to module level for better performanceDynamic imports inside the method add overhead on every listener creation. Consider moving them to the module level or implementing import caching.
Move imports to the top of the file:
from monitoring.universal_geyser_listener import UniversalGeyserListener from monitoring.universal_logs_listener import UniversalLogsListener from monitoring.universal_block_listener import UniversalBlockListener from monitoring.universal_pumpportal_listener import UniversalPumpPortalListenerThen simplify the method:
if listener_type == "geyser": if not geyser_endpoint or not geyser_api_token: raise ValueError( "Geyser endpoint and API token are required for geyser listener" ) - from monitoring.universal_geyser_listener import UniversalGeyserListener - listener = UniversalGeyserListener(
95-97: Extract supported platforms to class constantThe supported platforms for PumpPortal are hardcoded. Consider extracting them to a class constant for better maintainability.
class ListenerFactory: """Factory for creating appropriate token listeners based on configuration.""" + + PUMPPORTAL_SUPPORTED_PLATFORMS = [Platform.PUMP_FUN, Platform.LETS_BONK] @staticmethod def create_listener(Then use it:
- supported_pumpportal_platforms = [Platform.PUMP_FUN, Platform.LETS_BONK] + supported_pumpportal_platforms = ListenerFactory.PUMPPORTAL_SUPPORTED_PLATFORMSsrc/bot_runner.py (1)
42-44: Use more specific exception handlingCatching generic
ValueErrorcould mask other issues. The error handling should be more specific to platform configuration errors.Consider creating a custom exception:
class PlatformConfigurationError(ValueError): """Raised when platform configuration is invalid.""" passThen update the error handling:
try: platform = get_platform_from_config(cfg) logging.info(f"Detected platform: {platform.value}") - except ValueError as e: + except (ValueError, KeyError) as e: logging.exception(f"Platform configuration error: {e}") returnsrc/trading/universal_trader.py (1)
549-550: Use pathlib instead of os.path for file operationsThe code uses old-style os.path operations instead of the more modern pathlib.
+from pathlib import Path + async def _save_token_info(self, token_info: TokenInfo) -> None: """Save token information to a file.""" try: - os.makedirs("trades", exist_ok=True) - file_name = os.path.join("trades", f"{token_info.mint}.txt") + trades_dir = Path("trades") + trades_dir.mkdir(exist_ok=True) + file_path = trades_dir / f"{token_info.mint}.txt" # ... token_dict creation ... - with open(file_name, "w") as file: - file.write(json.dumps(token_dict, indent=2)) + file_path.write_text(json.dumps(token_dict, indent=2)) - logger.info(f"Token information saved to {file_name}") + logger.info(f"Token information saved to {file_path}")Apply similar changes to
_log_trademethod.Also applies to: 578-578, 588-588
src/monitoring/universal_logs_listener.py (1)
197-201: Rename unused loop variableThe
platformvariable is not used within the loop body.- for platform, parser in self.platform_parsers.items(): + for _, parser in self.platform_parsers.items(): token_info = parser.parse_token_creation_from_logs(logs, signature) if token_info: return token_infosrc/monitoring/universal_geyser_listener.py (2)
80-99: Add return type annotationThe method should specify its return type for better type safety.
- async def _create_geyser_connection(self): + async def _create_geyser_connection(self) -> tuple[geyser_pb2_grpc.GeyserStub, grpc.aio.Channel]: """Establish a secure connection to the Geyser endpoint."""
100-113: Add return type annotation- def _create_subscription_request(self): + def _create_subscription_request(self) -> geyser_pb2.SubscribeRequest: """Create a subscription request for all monitored platforms."""src/monitoring/universal_block_listener.py (1)
137-166: Add type annotation for websocket parameter- async def _subscribe_to_programs(self, websocket) -> None: + async def _subscribe_to_programs(self, websocket: websockets.WebSocketClientProtocol) -> None: """Subscribe to blocks mentioning any of the monitored program IDs.src/platforms/pumpfun/pumpportal_processor.py (1)
15-21: Add return type annotation for init- def __init__(self): + def __init__(self) -> None: """Initialize the processor with address provider.""" self.address_provider = PumpFunAddressProvider()src/trading/platform_aware.py (2)
23-43: Reduce constructor parameters and add type annotationsThe constructor has 8 parameters which exceeds recommended limits. Consider using a configuration object.
+from dataclasses import dataclass + +@dataclass +class BuyerConfig: + """Configuration for platform-aware buyer.""" + amount: float + slippage: float = 0.01 + max_retries: int = 5 + extreme_fast_token_amount: int = 0 + extreme_fast_mode: bool = False + class PlatformAwareBuyer(Trader): """Platform-aware token buyer that works with any supported platform.""" def __init__( self, client: SolanaClient, wallet: Wallet, priority_fee_manager: PriorityFeeManager, - amount: float, - slippage: float = 0.01, - max_retries: int = 5, - extreme_fast_token_amount: int = 0, - extreme_fast_mode: bool = False, - ): + config: BuyerConfig, + ) -> None: """Initialize platform-aware token buyer.""" self.client = client self.wallet = wallet self.priority_fee_manager = priority_fee_manager - self.amount = amount - self.slippage = slippage - self.max_retries = max_retries - self.extreme_fast_mode = extreme_fast_mode - self.extreme_fast_token_amount = extreme_fast_token_amount + self.config = config
150-164: Add return type annotation- def __init__( + def __init__( self, client: SolanaClient, wallet: Wallet, priority_fee_manager: PriorityFeeManager, slippage: float = 0.25, max_retries: int = 5, - ): + ) -> None: """Initialize platform-aware token seller."""src/interfaces/core.py (1)
333-346: Consider using a more specific type than AnyThe
transaction_infoparameter usesAnytype which reduces type safety.Consider defining a protocol or TypedDict for the expected structure:
from typing import Protocol class GeyserTransactionInfo(Protocol): """Protocol for Geyser transaction data.""" # Define expected attributes here pass # Then use it in the method signature def parse_token_creation_from_geyser( self, transaction_info: GeyserTransactionInfo ) -> TokenInfo | None:This would provide better type hints for users of the interface.
src/config_loader.py (1)
318-322: Consider more specific exception handling for better diagnostics.The broad
Exceptioncatch makes it harder to diagnose specific configuration issues.Consider catching specific exceptions:
- except Exception as e: + except (ValueError, KeyError, FileNotFoundError) as e: results["invalid_configs"].append({ "file": config_file, "error": str(e) }) + except Exception as e: + results["invalid_configs"].append({ + "file": config_file, + "error": f"Unexpected error: {type(e).__name__}: {str(e)}" + })src/utils/idl_parser.py (1)
25-38: Consider making _PRIMITIVE_TYPE_INFO immutable or use ClassVar.The static analysis correctly identifies that mutable class attributes can lead to unexpected behavior if modified.
Make this a class-level constant:
+from typing import ClassVar + class IDLParser: """Parser for automatically decoding instructions and events using IDL definitions.""" # A single source of truth for primitive type information, mapping the type name # to its struct format character and size in bytes. - _PRIMITIVE_TYPE_INFO = { + _PRIMITIVE_TYPE_INFO: ClassVar[dict[str, tuple[str | None, int]]] = { # type_name: (format_char, size_in_bytes) 'u8': ('<B', 1),src/platforms/letsbonk/event_parser.py (1)
257-262: Consider extracting magic numbers as named constants.The magic numbers make the code less maintainable.
Define constants at class level:
class LetsBonkEventParser(EventParser): """LetsBonk implementation of EventParser interface with IDL-based parsing.""" + + DISCRIMINATOR_SIZE = 8 + MIN_INITIALIZE_ACCOUNTS = 10 def __init__(self, idl_parser: IDLParser):Then use them:
- if len(ix_data) >= 8: - discriminator = struct.unpack("<Q", ix_data[:8])[0] + if len(ix_data) >= self.DISCRIMINATOR_SIZE: + discriminator = struct.unpack("<Q", ix_data[:self.DISCRIMINATOR_SIZE])[0] if discriminator == self._initialize_discriminator: - if len(ix_data) <= 8 or len(ix.accounts) < 10: + if len(ix_data) <= self.DISCRIMINATOR_SIZE or len(ix.accounts) < self.MIN_INITIALIZE_ACCOUNTS:src/platforms/pumpfun/address_provider.py (1)
18-36: Consider using class attributes instead of dataclass fields for constants.The static analysis correctly flags that function calls in dataclass defaults can be problematic. While the current implementation works because
Pubkeyobjects are immutable and marked asFinal, it would be cleaner to define these as class attributes:-@dataclass class PumpFunAddresses: """Pump.fun program addresses.""" - PROGRAM: Final[Pubkey] = Pubkey.from_string( + PROGRAM: Final[Pubkey] = Pubkey.from_string( "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" ) - GLOBAL: Final[Pubkey] = Pubkey.from_string( + GLOBAL: Final[Pubkey] = Pubkey.from_string( "4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf" ) - EVENT_AUTHORITY: Final[Pubkey] = Pubkey.from_string( + EVENT_AUTHORITY: Final[Pubkey] = Pubkey.from_string( "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" ) - FEE: Final[Pubkey] = Pubkey.from_string( + FEE: Final[Pubkey] = Pubkey.from_string( "CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM" ) - LIQUIDITY_MIGRATOR: Final[Pubkey] = Pubkey.from_string( + LIQUIDITY_MIGRATOR: Final[Pubkey] = Pubkey.from_string( "39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg" )This removes the need for the
@dataclassdecorator since there are no instance fields, only class constants and static methods.src/platforms/letsbonk/address_provider.py (2)
18-26: Consider using class attributes instead of dataclass fields for constants.Similar to the PumpFun implementation, these constants would be better defined as class attributes:
-@dataclass class LetsBonkAddresses: """LetsBonk (Raydium LaunchLab) program addresses.""" # Raydium LaunchLab program addresses - PROGRAM: Final[Pubkey] = Pubkey.from_string("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj") - GLOBAL_CONFIG: Final[Pubkey] = Pubkey.from_string("6s1xP3hpbAfFoNtUNF8mfHsjr2Bd97JxFJRWLbL6aHuX") - PLATFORM_CONFIG: Final[Pubkey] = Pubkey.from_string("FfYek5vEz23cMkWsdJwG2oa6EphsvXSHrGpdALN4g6W1") + PROGRAM: Final[Pubkey] = Pubkey.from_string("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj") + GLOBAL_CONFIG: Final[Pubkey] = Pubkey.from_string("6s1xP3hpbAfFoNtUNF8mfHsjr2Bd97JxFJRWLbL6aHuX") + PLATFORM_CONFIG: Final[Pubkey] = Pubkey.from_string("FfYek5vEz23cMkWsdJwG2oa6EphsvXSHrGpdALN4g6W1")
176-204: Move PDA seed constants to class level.The seed constants should be defined at the class level rather than inside methods to improve maintainability and follow Python conventions:
class LetsBonkAddressProvider(AddressProvider): """LetsBonk (Raydium LaunchLab) implementation of AddressProvider interface.""" + # PDA seeds + _AUTH_SEED = b"vault_auth_seed" + _EVENT_AUTHORITY_SEED = b"__event_authority" + @property def platform(self) -> Platform: """Get the platform this provider serves.""" return Platform.LETS_BONK # ... other methods ... def derive_authority_pda(self) -> Pubkey: """Derive the authority PDA for Raydium LaunchLab. This PDA acts as the authority for pool vault operations. Returns: Authority PDA address """ - AUTH_SEED = b"vault_auth_seed" authority_pda, _ = Pubkey.find_program_address( - [AUTH_SEED], + [self._AUTH_SEED], LetsBonkAddresses.PROGRAM ) return authority_pda def derive_event_authority_pda(self) -> Pubkey: """Derive the event authority PDA for Raydium LaunchLab. This PDA is used for emitting program events during swaps. Returns: Event authority PDA address """ - EVENT_AUTHORITY_SEED = b"__event_authority" event_authority_pda, _ = Pubkey.find_program_address( - [EVENT_AUTHORITY_SEED], + [self._EVENT_AUTHORITY_SEED], LetsBonkAddresses.PROGRAM ) return event_authority_pdasrc/utils/idl_manager.py (2)
27-38: Consider using pathlib for more robust path handling.The current implementation works but could be modernized using pathlib:
+from pathlib import Path import os from typing import Any from interfaces.core import Platform from utils.idl_parser import IDLParser from utils.logger import get_logger def _setup_platform_idl_paths(self) -> None: """Setup IDL file paths for each platform.""" # Get the project root directory (3 levels up from this file) - current_dir = os.path.dirname(os.path.abspath(__file__)) - project_root = os.path.join(current_dir, "..", "..") - project_root = os.path.normpath(project_root) + current_file = Path(__file__) + project_root = current_file.parent.parent.parent # Define IDL paths for each platform self._idl_paths = { - Platform.LETS_BONK: os.path.join(project_root, "idl", "raydium_launchlab_idl.json"), - Platform.PUMP_FUN: os.path.join(project_root, "idl", "pump_fun_idl.json"), + Platform.LETS_BONK: project_root / "idl" / "raydium_launchlab_idl.json", + Platform.PUMP_FUN: project_root / "idl" / "pump_fun_idl.json", }Then update the file existence check:
# Verify IDL file exists - if not os.path.exists(idl_path): + if not idl_path.exists(): raise FileNotFoundError(f"IDL file not found for {platform.value} at {idl_path}")
245-255: Use logger.exception for better error tracking.When catching exceptions, use
logger.exceptionto include the full traceback:except Exception as e: - logger.error(f"Failed to get capabilities for {platform.value}: {e}") + logger.exception(f"Failed to get capabilities for {platform.value}") return { "platform": platform.value, "has_idl_support": False, "error": str(e), "instructions": [], "events": [], "instruction_count": 0, "event_count": 0, }src/platforms/__init__.py (1)
187-227: Use logger instead of print for consistency.Replace print statements with logger warnings:
except ImportError as e: - print(f"Warning: Could not register pump.fun platform: {e}") + logger.warning(f"Could not register pump.fun platform: {e}") # Import and register LetsBonk platform try: from platforms.letsbonk import ( LetsBonkAddressProvider, LetsBonkCurveManager, LetsBonkEventParser, LetsBonkInstructionBuilder, ) self.registry.register_platform( Platform.LETS_BONK, LetsBonkAddressProvider, LetsBonkInstructionBuilder, LetsBonkCurveManager, LetsBonkEventParser ) except ImportError as e: - print(f"Warning: Could not register LetsBonk platform: {e}") + logger.warning(f"Could not register LetsBonk platform: {e}")src/platforms/pumpfun/event_parser.py (3)
28-34: Add return type annotation for__init__method.For consistency with type hints throughout the codebase, add the return type annotation.
- def __init__(self, idl_parser: IDLParser): + def __init__(self, idl_parser: IDLParser) -> None:
219-226: Add type annotations to helper function.The nested helper function should have proper type annotations for clarity.
- def get_account_key(index): + def get_account_key(index: int) -> Pubkey | None:
265-307: Consider more specific exception handling.While the implementation is correct, catching generic
Exceptioncould hide bugs. Consider catching specific exceptions or adding more granular error handling.src/platforms/letsbonk/instruction_builder.py (3)
28-34: Add return type annotation for consistency.- def __init__(self, idl_parser: IDLParser): + def __init__(self, idl_parser: IDLParser) -> None:
132-132: Use lowercase for local variable names.Follow Python naming conventions.
- SHARE_FEE_RATE = 0 # No sharing fee + share_fee_rate = 0 # No sharing fee instruction_data = ( self._buy_exact_in_discriminator + struct.pack("<Q", amount_in) + # amount_in (u64) - SOL to spend struct.pack("<Q", minimum_amount_out) + # minimum_amount_out (u64) - min tokens - struct.pack("<Q", SHARE_FEE_RATE) # share_fee_rate (u64): 0 + struct.pack("<Q", share_fee_rate) # share_fee_rate (u64): 0 )
347-348: Consider using constants for Token Program instruction discriminators.While these values are standard, using named constants improves code clarity.
+# At module level +TOKEN_PROGRAM_INITIALIZE_ACCOUNT = 1 +TOKEN_PROGRAM_CLOSE_ACCOUNT = 9 + # In _create_initialize_account_instruction - data = bytes([1]) + data = bytes([TOKEN_PROGRAM_INITIALIZE_ACCOUNT]) # In _create_close_account_instruction - data = bytes([9]) + data = bytes([TOKEN_PROGRAM_CLOSE_ACCOUNT])Also applies to: 378-379
src/platforms/pumpfun/instruction_builder.py (1)
25-25: Add return type annotation for__init__method.- def __init__(self, idl_parser: IDLParser): + def __init__(self, idl_parser: IDLParser) -> None:src/trading/base.py (2)
86-86: Consider the naming convention for legacy class.The class name
TokenInfo_Legacyviolates CapWords convention, but this appears intentional to clearly mark it as a legacy class. If this is a deliberate choice for clarity, you may want to suppress the linting warning with a comment.+# ruff: noqa: N801 - Intentional naming to indicate legacy status @dataclass class TokenInfo_Legacy:
180-189: Extract error messages to constants for better maintainability.+# Error message constants +_PLATFORM_CONVERSION_ERROR = "Can only convert pump.fun tokens to legacy format" +_MISSING_FIELDS_ERROR = "Enhanced TokenInfo missing required pump.fun fields" + def create_legacy_token_info(enhanced_token_info: TokenInfo) -> TokenInfo_Legacy: """Convert enhanced TokenInfo back to legacy TokenInfo if needed. This function allows the enhanced TokenInfo to be used with existing code that expects the legacy format. Args: enhanced_token_info: Enhanced TokenInfo instance Returns: Legacy TokenInfo instance Raises: ValueError: If enhanced TokenInfo doesn't have required pump.fun fields """ if enhanced_token_info.platform != Platform.PUMP_FUN: - raise ValueError("Can only convert pump.fun tokens to legacy format") + raise ValueError(_PLATFORM_CONVERSION_ERROR) if not all([ enhanced_token_info.bonding_curve, enhanced_token_info.associated_bonding_curve, enhanced_token_info.creator_vault ]): - raise ValueError("Enhanced TokenInfo missing required pump.fun fields") + raise ValueError(_MISSING_FIELDS_ERROR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (5)
src/trading/universal_trader.py (4)
546-584: Modernize file operations with pathlib.The method already imports pathlib but doesn't fully utilize it. Complete the modernization.
async def _save_token_info(self, token_info: TokenInfo) -> None: """Save token information to a file.""" try: trades_dir = Path("trades") trades_dir.mkdir(exist_ok=True) file_path = trades_dir / f"{token_info.mint}.txt" # ... token_dict construction ... - file_path.write_text(json.dumps(token_dict, indent=2)) + file_path.write_text(json.dumps(token_dict, indent=2)) logger.info(f"Token information saved to {file_path}") - except OSError: - logger.exception("Failed to save token information") + except (OSError, IOError): + logger.exception("Failed to save token information")
110-116: Move import to module level and improve error handling.The dynamic import inside the method violates PEP8 and the error handling could be more specific.
Move the import to the top of the file and simplify the validation:
+from platforms import platform_factory class UniversalTrader:Then update the validation:
- # Validate platform support - try: - from platforms import platform_factory - if not platform_factory.registry.is_platform_supported(self.platform): - raise ValueError(f"Platform {self.platform.value} is not supported") - except Exception as e: - logger.error(f"Platform validation failed: {e}") - raise + # Validate platform support + if not platform_factory.registry.is_platform_supported(self.platform): + raise ValueError(f"Platform {self.platform.value} is not supported")
388-390: Use logger.exception for better error tracking.When catching exceptions, use
logger.exceptionto include the full traceback.- except Exception as e: - logger.error(f"Error handling token {token_info.symbol}: {e!s}") + except Exception: + logger.exception(f"Error handling token {token_info.symbol}")
529-531: Use logger.exception in position monitoring error handler.For better debugging of monitoring errors, use
logger.exception.- except Exception as e: - logger.error(f"Error monitoring position: {e}") + except Exception: + logger.exception("Error monitoring position") await asyncio.sleep(self.price_check_interval) # Continue monitoring despite errorssrc/utils/idl_manager.py (1)
244-254: Improve exception handling as previously suggested.The exception handling still needs improvement as noted in the previous review. The broad
Exceptioncatch and use oflogger.errorinstead oflogger.exceptionmakes debugging difficult.Apply the previously suggested fix:
- except Exception as e: - logger.error(f"Failed to get capabilities for {platform.value}: {e}") + except (FileNotFoundError, ValueError) as e: + logger.exception(f"Failed to get capabilities for {platform.value}")
🧹 Nitpick comments (4)
src/trading/universal_trader.py (1)
533-545: Consider using getattr with default instead of hasattr checks.The current implementation could be simplified and made more robust.
def _get_pool_address(self, token_info: TokenInfo) -> Pubkey: """Get the pool/curve address for price monitoring using platform-agnostic method.""" address_provider = self.platform_implementations.address_provider # Use platform-specific logic to get the appropriate address - if hasattr(token_info, 'bonding_curve') and token_info.bonding_curve: - return token_info.bonding_curve - elif hasattr(token_info, 'pool_state') and token_info.pool_state: - return token_info.pool_state - else: - # Fallback to deriving the address using platform provider - return address_provider.derive_pool_address(token_info.mint) + if token_info.platform == Platform.PUMP_FUN: + if bonding_curve := getattr(token_info, 'bonding_curve', None): + return bonding_curve + elif token_info.platform == Platform.LETS_BONK: + if pool_state := getattr(token_info, 'pool_state', None): + return pool_state + + # Fallback to deriving the address using platform provider + return address_provider.derive_pool_address(token_info.mint)src/monitoring/listener_factory.py (1)
129-145: Consider extracting platform compatibility to a constant.The platform compatibility logic is duplicated from the module-level constant.
+# At module level, define the compatibility map +PLATFORM_LISTENER_COMPATIBILITY = { + Platform.PUMP_FUN: ["logs", "blocks", "geyser", "pumpportal"], + Platform.LETS_BONK: ["blocks", "geyser", "pumpportal"], +} + @staticmethod def get_platform_compatible_listeners(platform: Platform) -> list[str]: """Get list of listener types compatible with a specific platform.""" - if platform == Platform.PUMP_FUN: - return ["logs", "blocks", "geyser", "pumpportal"] - elif platform == Platform.LETS_BONK: - return ["blocks", "geyser", "pumpportal"] # Added pumpportal support - else: - return ["blocks", "geyser"] # Default universal listeners + return PLATFORM_LISTENER_COMPATIBILITY.get(platform, ["blocks", "geyser"])src/config_loader.py (1)
166-173: Consider handling platform factory as optional dependency at module level.The dynamic import could be moved to module level with proper optional handling.
+# At module level +try: + from platforms import platform_factory + HAS_PLATFORM_FACTORY = True +except ImportError: + platform_factory = None + HAS_PLATFORM_FACTORY = False def validate_platform_config(config: dict, platform: Platform) -> None: """Validate platform-specific configuration requirements.""" # Check if platform is supported - try: - from platforms import platform_factory + if HAS_PLATFORM_FACTORY: if not platform_factory.registry.is_platform_supported(platform): raise ValueError(f"Platform {platform.value} is not supported. Available platforms: {[p.value for p in platform_factory.get_supported_platforms()]}") - except ImportError: - # If platform factory not available, just validate enum - passsrc/trading/platform_aware.py (1)
199-200: Remove unnecessary type conversions.The float conversions are redundant as the values are already numeric.
- expected_sol_output = float(token_balance_decimal) * float(token_price_sol) + expected_sol_output = token_balance_decimal * token_price_sol
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/config_loader.py(5 hunks)src/core/pubkeys.py(1 hunks)src/interfaces/core.py(1 hunks)src/monitoring/listener_factory.py(1 hunks)src/trading/platform_aware.py(1 hunks)src/trading/universal_trader.py(22 hunks)src/utils/idl_manager.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/core/pubkeys.py
🧰 Additional context used
📓 Path-based instructions (5)
src/monitoring/*.py
📄 CodeRabbit Inference Engine (.cursor/rules/monitoring.mdc)
src/monitoring/*.py: Implement event monitoring and data collection systems for tracking blockchain activity when working on token detection, event processing, or subscription logic.
Each listener must have a corresponding event processor that validates incoming events, extracts relevant token information, applies filtering rules, and dispatches events to trading components.
Files:
src/monitoring/listener_factory.py
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/package-management.mdc)
**/*: Useuvfor all package operations; never use pip, pipenv, poetry, or conda
Useuv runfor script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency
Files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.pysrc/trading/platform_aware.pysrc/config_loader.pysrc/interfaces/core.pysrc/utils/idl_manager.py
src/{core,trading,monitoring,cleanup,utils}/**/*.py
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
Place all source code files in the @src/ directory, with core components under @src/core/, trading system under @src/trading/, monitoring system under @src/monitoring/, resource management under @src/cleanup/, and shared utilities under @src/utils/.
Files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.pysrc/trading/platform_aware.pysrc/utils/idl_manager.py
src/config_loader.py
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use
src/config_loader.pyto handle YAML configuration loading, validation, and environment variable resolution.
Files:
src/config_loader.py
src/utils/*.py
📄 CodeRabbit Inference Engine (.cursor/rules/utils.mdc)
src/utils/*.py: Reuse existing utilities rather than implementing similar functionality
Keep utilities focused on a single responsibility
Document usage examples for each utility
Maintain backward compatibility when enhancing utilities
Use get_logger(name) from src/utils/logger.py for logging to ensure consistent log formatting, log level management, and context-aware logging
Files:
src/utils/idl_manager.py
🧠 Learnings (47)
📓 Common learnings
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Organize the pump-bot system into modular components with clear separation of concerns to facilitate maintainability, testing, and extension of functionality.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
📚 Learning: applies to src/monitoring/*_listener.py : implement multiple listener types for token detection in t...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/monitoring/*_listener.py : Implement multiple listener types for token detection in the `src/monitoring/` directory: logs, blocks, Geyser, PumpPortal, and an abstract base class.
Applied to files:
src/monitoring/listener_factory.pysrc/interfaces/core.py
📚 Learning: applies to src/monitoring/base_listener.py : define a common interface for all token listeners by im...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/base_listener.py : Define a common interface for all token listeners by implementing an abstract base class (e.g., BaseTokenListener) that declares required methods for event subscription and standardizes token event processing.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.pysrc/interfaces/core.py
📚 Learning: applies to src/monitoring/pumpportal_listener.py : integrate with external services (such as pumppor...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/pumpportal_listener.py : Integrate with external services (such as PumpPortal API) to receive preprocessed token events and simplify third-party data provider integration.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.py
📚 Learning: applies to tests/test_*_listener.py : each listener test should output new token information in a st...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_*_listener.py : Each listener test should output new token information in a standardized format, including token name, symbol, mint, URI, and creator.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.pysrc/interfaces/core.py
📚 Learning: applies to src/monitoring/geyser_listener.py : implement geyser-based listener logic for direct conn...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/geyser_listener.py : Implement Geyser-based listener logic for direct connection to the Geyser WebSocket endpoint, providing lowest latency token detection and advanced filtering capabilities.
Applied to files:
src/monitoring/listener_factory.py
📚 Learning: applies to src/monitoring/*.py : each listener must have a corresponding event processor that valida...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/*.py : Each listener must have a corresponding event processor that validates incoming events, extracts relevant token information, applies filtering rules, and dispatches events to trading components.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.py
📚 Learning: specify the listener type and related filters in bot configuration files using the 'listener_type' a...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Specify the listener type and related filters in bot configuration files using the 'listener_type' and 'max_token_age' fields.
Applied to files:
src/monitoring/listener_factory.py
📚 Learning: applies to src/monitoring/logs_listener.py : implement log-based monitoring by subscribing to progra...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/logs_listener.py : Implement log-based monitoring by subscribing to program logs and performing pattern matching for token creation events.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.py
📚 Learning: applies to tests/test_logs_listener.py : use tests/test_logs_listener.py to validate log-based monit...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_logs_listener.py : Use tests/test_logs_listener.py to validate log-based monitoring by subscribing to program logs, matching patterns for token creation events, and verifying detection accuracy.
Applied to files:
src/monitoring/listener_factory.py
📚 Learning: applies to bots/*.yaml : if the `geyser` listener is used, it must include `endpoint`, `api_token`, ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : If the `geyser` listener is used, it must include `endpoint`, `api_token`, and `auth_type` fields.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.py
📚 Learning: applies to tests/test_geyser_listener.py : use tests/test_geyser_listener.py to test the fastest det...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_geyser_listener.py : Use tests/test_geyser_listener.py to test the fastest detection method via direct gRPC connection to the Geyser endpoint, monitoring real-time token creation and measuring performance.
Applied to files:
src/monitoring/listener_factory.py
📚 Learning: applies to bots/*.yaml : if the `pumpportal` listener is used, it must include `endpoint` and `api_k...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : If the `pumpportal` listener is used, it must include `endpoint` and `api_key` fields.
Applied to files:
src/monitoring/listener_factory.pysrc/trading/universal_trader.py
📚 Learning: applies to src/trading/trader.py : implement trading logic in `src/trading/trader.py` using the `pum...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/trader.py : orchestrate the trading lifecycle, including token detection to e...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/base.py : common trading data structures such as `tokeninfo` and `traderesult...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/base.py : Common trading data structures such as `TokenInfo` and `TradeResult` should be defined in `src/trading/base.py`.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/base.py : define and maintain core abstractions, shared data structures, type...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/base.py : Define and maintain core abstractions, shared data structures, type definitions, and interface contracts for trading components in src/trading/base.py.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: the bot trades on pump.fun bonding curves and handles migrations to pumpswap....
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Applied to files:
src/trading/universal_trader.py
📚 Learning: applies to src/trading/seller.py : token sale logic should be implemented in `src/trading/seller.py`...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/seller.py : Token sale logic should be implemented in `src/trading/seller.py` using the `TokenSeller` class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/buyer.py : token purchase logic with slippage and retry support should be imp...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/buyer.py : Token purchase logic with slippage and retry support should be implemented in `src/trading/buyer.py` using the `TokenBuyer` class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/position.py : position tracking with take-profit/stop-loss functionality shou...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/position.py : Position tracking with take-profit/stop-loss functionality should be implemented in `src/trading/position.py` using the `Position` class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.py
📚 Learning: applies to src/bot_runner.py : the main entry point that loads configurations and starts trading bot...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/bot_runner.py : The main entry point that loads configurations and starts trading bots should be implemented in `src/bot_runner.py`.
Applied to files:
src/trading/universal_trader.pysrc/config_loader.py
📚 Learning: applies to src/trading/buyer.py : implement buy operations, including slippage calculation, buy tran...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/buyer.py : Implement buy operations, including slippage calculation, buy transaction creation, and transaction validation, in src/trading/buyer.py using the TokenBuyer class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.py
📚 Learning: applies to src/monitoring/block_listener.py : implement block-based scanning to process entire block...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/block_listener.py : Implement block-based scanning to process entire blocks, extract transaction data, and identify token creation events.
Applied to files:
src/trading/universal_trader.pysrc/interfaces/core.py
📚 Learning: applies to src/trading/seller.py : implement sell operations, including exit strategies, profit calc...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/seller.py : Implement sell operations, including exit strategies, profit calculation, and transaction construction, in src/trading/seller.py using the TokenSeller class.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.py
📚 Learning: follow the documented trading flows for token purchase, token sale, and error handling to ensure con...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Follow the documented trading flows for token purchase, token sale, and error handling to ensure consistency in transaction processing and position management.
Applied to files:
src/trading/universal_trader.pysrc/trading/platform_aware.py
📚 Learning: implement trading strategies such as time-based exits, take profit/stop loss (tp/sl), and manual exi...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Implement trading strategies such as time-based exits, take profit/stop loss (TP/SL), and manual exits as configurable options in the trading system.
Applied to files:
src/trading/universal_trader.py
📚 Learning: applies to src/trading/position.py : implement position management, including entry/exit price recor...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/position.py : Implement position management, including entry/exit price recording, profit/loss calculation, and risk management boundaries, in src/trading/position.py.
Applied to files:
src/trading/universal_trader.py
📚 Learning: applies to src/cleanup/manager.py : implement safe cleanup of associated token accounts (atas), mana...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/cleanup.mdc:0-0
Timestamp: 2025-08-01T05:34:09.740Z
Learning: Applies to src/cleanup/manager.py : Implement safe cleanup of Associated Token Accounts (ATAs), manage token burning operations when needed, and ensure proper account closure to recover rent in the AccountCleanupManager class.
Applied to files:
src/trading/universal_trader.py
📚 Learning: applies to src/core/pubkeys.py : define system address constants, program id references, address der...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/pubkeys.py : Define system address constants, program ID references, address derivation utilities, and token account resolution functions in src/core/pubkeys.py.
Applied to files:
src/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to src/core/curve.py : bonding curve calculations for pump.fun tokens should be implemented ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Applied to files:
src/trading/platform_aware.pysrc/interfaces/core.py
📚 Learning: applies to bots/*.yaml : the `trade` section must be present and include `buy_amount`, `buy_slippage...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : The `trade` section must be present and include `buy_amount`, `buy_slippage`, `sell_slippage`, `exit_strategy`, and, if `exit_strategy` is `tp_sl`, also `take_profit_percentage` and `stop_loss_percentage`.
Applied to files:
src/trading/platform_aware.py
📚 Learning: applies to src/config_loader.py : use `src/config_loader.py` to handle yaml configuration loading, v...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/config_loader.py : Use `src/config_loader.py` to handle YAML configuration loading, validation, and environment variable resolution.
Applied to files:
src/config_loader.py
📚 Learning: applies to src/core/priority_fee/{manager,dynamic_fee,fixed_fee}.py : priority fee calculation shoul...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/priority_fee/{manager,dynamic_fee,fixed_fee}.py : Priority fee calculation should be managed in `src/core/priority_fee/manager.py`, with dynamic and fixed fee implementations in `src/core/priority_fee/dynamic_fee.py` and `src/core/priority_fee/fixed_fee.py` respectively.
Applied to files:
src/config_loader.py
📚 Learning: applies to src/core/priority_fee/manager.py : implement dynamic priority fee calculation, fee cap en...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/priority_fee/manager.py : Implement dynamic priority fee calculation, fee cap enforcement, network congestion detection, and transaction prioritization strategies in src/core/priority_fee/manager.py.
Applied to files:
src/config_loader.py
📚 Learning: applies to bots/*.yaml : each configuration file must include required sections: bot identification ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : Each configuration file must include required sections: Bot Identification and Connection Settings, Trading Parameters, Listener Configuration, Filters, and may include Priority Fees, Error Handling and Retries, and Cleanup Settings.
Applied to files:
src/config_loader.py
📚 Learning: applies to bots/*.yaml : bot configurations are stored in `bots/*.yaml` files. each bot can run inde...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to bots/*.yaml : Bot configurations are stored in `bots/*.yaml` files. Each bot can run independently with its own settings.
Applied to files:
src/config_loader.py
📚 Learning: applies to bots/*.yaml : each configuration must specify exactly one listener section: `geyser`, `lo...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : Each configuration must specify exactly one listener section: `geyser`, `logs`, `blocks`, or `pumpportal`.
Applied to files:
src/config_loader.py
📚 Learning: applies to bots/*.yaml : place bot configuration files in the @bots/ directory, using yaml format fo...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Applies to bots/*.yaml : Place bot configuration files in the @bots/ directory, using YAML format for each bot configuration.
Applied to files:
src/config_loader.py
📚 Learning: applies to src/{core,trading,monitoring,cleanup,utils}/**/*.py : place all source code files in the ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Applies to src/{core,trading,monitoring,cleanup,utils}/**/*.py : Place all source code files in the @src/ directory, with core components under @src/core/, trading system under @src/trading/, monitoring system under @src/monitoring/, resource management under @src/cleanup/, and shared utilities under @src/utils/.
Applied to files:
src/interfaces/core.py
📚 Learning: applies to tests/test_block_listener.py : use tests/test_block_listener.py to test block-based scann...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_block_listener.py : Use tests/test_block_listener.py to test block-based scanning for token discovery, including full block processing and transaction analysis.
Applied to files:
src/interfaces/core.py
📚 Learning: applies to src/monitoring/*.py : implement event monitoring and data collection systems for tracking...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/*.py : Implement event monitoring and data collection systems for tracking blockchain activity when working on token detection, event processing, or subscription logic.
Applied to files:
src/interfaces/core.py
📚 Learning: applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, includin...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Applied to files:
src/interfaces/core.pysrc/utils/idl_manager.py
📚 Learning: applies to idl/*.json : idl files must define the structure and interface of on-chain solana program...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/*.json : IDL files must define the structure and interface of on-chain Solana programs, including instruction schemas, account structures, event definitions, and discriminators.
Applied to files:
src/utils/idl_manager.py
📚 Learning: applies to idl/*.json : program interface definitions for on-chain contract interactions must be def...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/*.json : Program interface definitions for on-chain contract interactions must be defined in IDL (Interface Definition Language) JSON files located in the idl/ directory.
Applied to files:
src/utils/idl_manager.py
📚 Learning: applies to idl/*.json : store interface definitions for on-chain programs in the @idl/ directory as ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Applies to idl/*.json : Store interface definitions for on-chain programs in the @idl/ directory as JSON files.
Applied to files:
src/utils/idl_manager.py
📚 Learning: applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol in...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Applied to files:
src/utils/idl_manager.py
🪛 Ruff (0.12.2)
src/monitoring/listener_factory.py
16-16: create_listener is too complex (11 > 10)
(C901)
16-16: Too many arguments in function definition (7 > 5)
(PLR0913)
46-48: Avoid specifying long messages outside the exception class
(TRY003)
50-50: import should be at the top-level of a file
(PLC0415)
63-63: Avoid specifying long messages outside the exception class
(TRY003)
65-65: import should be at the top-level of a file
(PLC0415)
76-76: Avoid specifying long messages outside the exception class
(TRY003)
78-78: import should be at the top-level of a file
(PLC0415)
89-91: import should be at the top-level of a file
(PLC0415)
104-104: Avoid specifying long messages outside the exception class
(TRY003)
115-118: Avoid specifying long messages outside the exception class
(TRY003)
src/trading/universal_trader.py
110-110: import should be at the top-level of a file
(PLC0415)
112-112: Abstract raise to an inner function
(TRY301)
112-112: Avoid specifying long messages outside the exception class
(TRY003)
114-114: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
284-284: Consider moving this statement to an else block
(TRY300)
388-388: Do not catch blind exception: Exception
(BLE001)
389-389: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
529-529: Do not catch blind exception: Exception
(BLE001)
530-530: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
src/trading/platform_aware.py
23-23: Too many arguments in function definition (8 > 5)
(PLR0913)
23-23: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
32-32: Boolean-typed positional argument in function definition
(FBT001)
32-32: Boolean default positional argument in function definition
(FBT002)
150-150: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
src/config_loader.py
147-147: Abstract raise to an inner function
(TRY301)
147-147: Avoid specifying long messages outside the exception class
(TRY003)
159-159: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
159-159: Avoid specifying long messages outside the exception class
(TRY003)
167-167: import should be at the top-level of a file
(PLC0415)
169-169: Avoid specifying long messages outside the exception class
(TRY003)
180-183: Abstract raise to an inner function
(TRY301)
180-183: Avoid specifying long messages outside the exception class
(TRY003)
205-205: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
205-205: Avoid specifying long messages outside the exception class
(TRY003)
321-321: Do not catch blind exception: Exception
(BLE001)
343-343: Do not catch blind exception: Exception
(BLE001)
src/interfaces/core.py
335-335: Dynamically typed expressions (typing.Any) are disallowed in transaction_info
(ANN401)
src/utils/idl_manager.py
21-21: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
39-39: Boolean-typed positional argument in function definition
(FBT001)
39-39: Boolean default positional argument in function definition
(FBT002)
58-58: Avoid specifying long messages outside the exception class
(TRY003)
64-64: Avoid specifying long messages outside the exception class
(TRY003)
109-109: Boolean-typed positional argument in function definition
(FBT001)
109-109: Boolean default positional argument in function definition
(FBT002)
244-244: Do not catch blind exception: Exception
(BLE001)
245-245: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
267-267: Using the global statement to update _idl_manager is discouraged
(PLW0603)
273-273: Boolean-typed positional argument in function definition
(FBT001)
273-273: Boolean default positional argument in function definition
(FBT002)
298-298: Boolean-typed positional argument in function definition
(FBT001)
298-298: Boolean default positional argument in function definition
(FBT002)
🔇 Additional comments (11)
src/monitoring/listener_factory.py (1)
87-112: Well-implemented platform validation for PumpPortal.The platform validation and filtering logic for PumpPortal is thorough and provides clear warnings for unsupported platforms.
src/config_loader.py (2)
70-73: Good backward compatibility with default platform.The automatic assignment of default platform ensures existing configurations continue to work without modification.
284-328: Well-structured batch validation with comprehensive statistics.The function provides excellent visibility into configuration health across all bot files, with proper error collection and distribution statistics.
src/interfaces/core.py (2)
23-48: Well-designed TokenInfo with platform flexibility.The dataclass design elegantly handles platform-specific fields as optional attributes while maintaining a common interface. This allows each platform to use only the fields it needs.
50-285: Excellent interface design with clear contracts.The abstract interfaces (AddressProvider, InstructionBuilder, CurveManager) are well-structured with:
- Clear method signatures and return types
- Comprehensive documentation
- Proper use of async where appropriate
- Platform-agnostic design allowing flexible implementations
src/utils/idl_manager.py (6)
1-26: LGTM! Clean imports and initialization.The module imports are well-organized and the class initialization properly sets up the required data structures with appropriate type hints.
27-37: Good implementation using pathlib as previously suggested.The path construction correctly uses
pathlib.Pathand the/operator, addressing the previous review feedback about cross-platform compatibility.
39-75: Solid parser management with good caching and error handling.The method implements proper caching logic and provides informative error messages. While static analysis flags the boolean parameter and long exception messages, these are acceptable here as the verbose flag is a common pattern for optional detailed logging, and the detailed error messages aid in debugging IDL loading issues.
77-123: Well-implemented utility methods with clear logic.The utility methods provide clean abstractions for IDL parser management with appropriate logging and clear documentation.
124-207: Excellent convenience API with clear organization.The convenience methods provide a clean interface to parser functionality with good section organization and consistent delegation patterns.
256-347: Appropriate global singleton pattern for shared IDL management.The global singleton pattern is well-suited for IDL management as it ensures efficient resource sharing across the application. The module-level convenience functions provide a clean API while maintaining the benefits of centralized parser caching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
learning-examples/bonding-curve-progress/get_bonding_curve_status.py (1)
25-25: False positive from static analysis - consider clearer default value.The static analysis tool flagged this as a potential hardcoded password, but it's just a placeholder. Consider using a more descriptive default value to avoid confusion.
-TOKEN_MINT = "..." +TOKEN_MINT = None # Default placeholder - specify via command lineAlternatively, you could use a well-known example token address as the default.
README.md (2)
15-15: Prefer concise wording & tighten the sentenceReplace the verbose “a lot of useful scripts” with a more concise construction and fix the singular “deep dive”.
-The project allows you to create bots for trading on pump.fun and letsbonk.fun. Its core feature is to snipe new tokens. Besides that, learning examples contain a lot of useful scripts for different types of listeners (new tokens, migrations) and deep dive into calculations required for trading. +The project lets you build bots for trading on pump.fun and letsbonk.fun, with a primary focus on sniping new tokens. The learning examples also include many useful scripts covering various listener types (new tokens, migrations) and in-depth calculations required for trading.
120-128: Fix malformed Markdown linkNested brackets break the rendered link for
blockSubscribe. Use regular Markdown syntax instead.-Note that it's using the [blockSubscribe]([url](https://docs.chainstack.com/reference/blocksubscribe-solana)) method +Note that it’s using the [`blockSubscribe`](https://docs.chainstack.com/reference/blocksubscribe-solana) method
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.md(4 hunks)learning-examples/bonding-curve-progress/get_bonding_curve_status.py(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/package-management.mdc)
**/*: Useuvfor all package operations; never use pip, pipenv, poetry, or conda
Useuv runfor script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency
Files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.pyREADME.md
{README.md,MAINTAINERS.md,CLAUDE.md}
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
Maintain related documentation in @README.md, @MAINTAINERS.md, and @CLAUDE.md at the project root.
Files:
README.md
🧠 Learnings (26)
📓 Common learnings
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Organize the pump-bot system into modular components with clear separation of concerns to facilitate maintainability, testing, and extension of functionality.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
📚 Learning: applies to src/core/curve.py : bonding curve calculations for pump.fun tokens should be implemented ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.pyREADME.md
📚 Learning: applies to src/monitoring/pumpportal_listener.py : integrate with external services (such as pumppor...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/pumpportal_listener.py : Integrate with external services (such as PumpPortal API) to receive preprocessed token events and simplify third-party data provider integration.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.py
📚 Learning: tests require the following environment variables to be set: solana_node_rpc_endpoint, solana_node_w...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Tests require the following environment variables to be set: SOLANA_NODE_RPC_ENDPOINT, SOLANA_NODE_WSS_ENDPOINT, GEYSER_ENDPOINT, and GEYSER_API_TOKEN.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.py
📚 Learning: applies to src/core/pubkeys.py : define system address constants, program id references, address der...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/pubkeys.py : Define system address constants, program ID references, address derivation utilities, and token account resolution functions in src/core/pubkeys.py.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.py
📚 Learning: applies to src/trading/trader.py : implement trading logic in `src/trading/trader.py` using the `pum...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.pyREADME.md
📚 Learning: applies to src/trading/trader.py : orchestrate the trading lifecycle, including token detection to e...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.py
📚 Learning: applies to src/bot_runner.py : the main entry point that loads configurations and starts trading bot...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/bot_runner.py : The main entry point that loads configurations and starts trading bots should be implemented in `src/bot_runner.py`.
Applied to files:
learning-examples/bonding-curve-progress/get_bonding_curve_status.pyREADME.md
📚 Learning: the bot trades on pump.fun bonding curves and handles migrations to pumpswap....
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Applied to files:
README.md
📚 Learning: applies to pyproject.toml : define project dependencies and the `pump_bot` command in `pyproject.tom...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/package-management.mdc:0-0
Timestamp: 2025-08-01T05:34:47.588Z
Learning: Applies to pyproject.toml : Define project dependencies and the `pump_bot` command in `pyproject.toml`
Applied to files:
README.md
📚 Learning: launch the bot using the installed `pump_bot` command or by running `uv run src/bot_runner.py`....
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Launch the bot using the installed `pump_bot` command or by running `uv run src/bot_runner.py`.
Applied to files:
README.md
📚 Learning: applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol in...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Applied to files:
README.md
📚 Learning: applies to **/* : use `uv run` for script execution to ensure proper virtual environment activation...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/package-management.mdc:0-0
Timestamp: 2025-08-01T05:34:47.588Z
Learning: Applies to **/* : Use `uv run` for script execution to ensure proper virtual environment activation
Applied to files:
README.md
📚 Learning: applies to bots/*.yaml : bot configurations are stored in `bots/*.yaml` files. each bot can run inde...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to bots/*.yaml : Bot configurations are stored in `bots/*.yaml` files. Each bot can run independently with its own settings.
Applied to files:
README.md
📚 Learning: applies to bots/*.yaml : configure bot parameters in @bots/*.yaml before launching bots....
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Applies to bots/*.yaml : Configure bot parameters in @bots/*.yaml before launching bots.
Applied to files:
README.md
📚 Learning: applies to **/* : use `uv` for all package operations; never use pip, pipenv, poetry, or conda...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/package-management.mdc:0-0
Timestamp: 2025-08-01T05:34:47.588Z
Learning: Applies to **/* : Use `uv` for all package operations; never use pip, pipenv, poetry, or conda
Applied to files:
README.md
📚 Learning: applies to src/core/curve.py : implement mathematical models for bonding curve calculations, price i...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/curve.py : Implement mathematical models for bonding curve calculations, price impact estimation, liquidity modeling, and swap pricing utilities in src/core/curve.py.
Applied to files:
README.md
📚 Learning: applies to idl/raydium_amm_idl.json : @idl/raydium_amm_idl.json must provide integration with raydiu...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/raydium_amm_idl.json : @idl/raydium_amm_idl.json must provide integration with Raydium, including AMM pool interface definitions, liquidity provider instructions, market making operations, and price discovery mechanisms.
Applied to files:
README.md
📚 Learning: applies to src/monitoring/*.py : implement event monitoring and data collection systems for tracking...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/*.py : Implement event monitoring and data collection systems for tracking blockchain activity when working on token detection, event processing, or subscription logic.
Applied to files:
README.md
📚 Learning: applies to tests/*.py : performance testing and listener comparison scripts for token detection syst...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/*.py : Performance testing and listener comparison scripts for token detection systems must be used when benchmarking listener performance or validating detection accuracy.
Applied to files:
README.md
📚 Learning: applies to tests/test_logs_listener.py : use tests/test_logs_listener.py to validate log-based monit...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_logs_listener.py : Use tests/test_logs_listener.py to validate log-based monitoring by subscribing to program logs, matching patterns for token creation events, and verifying detection accuracy.
Applied to files:
README.md
📚 Learning: applies to src/monitoring/*_listener.py : implement multiple listener types for token detection in t...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/monitoring/*_listener.py : Implement multiple listener types for token detection in the `src/monitoring/` directory: logs, blocks, Geyser, PumpPortal, and an abstract base class.
Applied to files:
README.md
📚 Learning: applies to tests/test_block_listener.py : use tests/test_block_listener.py to test block-based scann...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_block_listener.py : Use tests/test_block_listener.py to test block-based scanning for token discovery, including full block processing and transaction analysis.
Applied to files:
README.md
📚 Learning: applies to src/monitoring/block_listener.py : implement block-based scanning to process entire block...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/block_listener.py : Implement block-based scanning to process entire blocks, extract transaction data, and identify token creation events.
Applied to files:
README.md
📚 Learning: applies to tests/test_*_listener.py : each listener test should output new token information in a st...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_*_listener.py : Each listener test should output new token information in a standardized format, including token name, symbol, mint, URI, and creator.
Applied to files:
README.md
📚 Learning: applies to tests/test_geyser_listener.py : use tests/test_geyser_listener.py to test the fastest det...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_geyser_listener.py : Use tests/test_geyser_listener.py to test the fastest detection method via direct gRPC connection to the Geyser endpoint, monitoring real-time token creation and measuring performance.
Applied to files:
README.md
🪛 Ruff (0.12.2)
learning-examples/bonding-curve-progress/get_bonding_curve_status.py
25-25: Possible hardcoded password assigned to: "TOKEN_MINT"
(S105)
🪛 LanguageTool
README.md
[style] ~15-~15: Consider using a synonym to be more concise.
Context: ...Besides that, learning examples contain a lot of useful scripts for different types of l...
(A_LOT_OF)
🔇 Additional comments (5)
learning-examples/bonding-curve-progress/get_bonding_curve_status.py (3)
9-9: Good addition for script flexibility.Adding
argparseenables runtime specification of token mint addresses, which aligns well with the multi-platform architecture introduced in this PR.
176-180: Excellent implementation of CLI argument parsing.The argument parsing implementation is clean and provides good flexibility. The use of
nargs='?'with a default fallback maintains backward compatibility while enabling command-line usage.
1-185: Consider using platform-specific CurveManager implementationsWe’ve confirmed that PumpFunCurveManager and LetsBonkCurveManager exist under:
src/platforms/pumpfun/curve_manager.pysrc/platforms/letsbonk/curve_manager.pyBoth implement the core CurveManager interface with methods like
get_pool_state,calculate_price,calculate_buy_amount_out, etc. To integrate this example script with them, you could:• Instantiate a
SolanaClientandIDLParser
• CreatePumpFunCurveManager(client, idl_parser)
• Replace the manual discriminator check and Construct parsing inget_bonding_curve_statewith calls tocurve_manager.get_pool_state(curve_address)
• Delegate all calculations (price, buy/sell amounts, completion) to the manager methodsThat refactor would align the script with the shared platform-aware architecture and reduce low-level parsing code. However, since this is a learning-focused example illustrating raw bonding-curve interactions, the current explicit approach is acceptable. If you evolve this into a production utility or shared library, consider adopting the CurveManager implementations above.
README.md (2)
85-86: Good call switching touv runThis change aligns the README with the project-wide guideline of using
uvfor script execution. Looks correct to me.
114-118: ✅ Confirmed script path in README
learning-examples/bonding-curve-progress/get_bonding_curve_status.pyexists as referenced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (6)
src/monitoring/universal_geyser_listener.py (3)
54-66: Move import to module level and extract DummyClient class.Creating a class inside a method is poor practice, and the import should be at the top of the file.
Move the import to module level and create a proper mock client:
+from core.client import SolanaClient from geyser.generated import geyser_pb2, geyser_pb2_grpc from interfaces.core import Platform, TokenInfo +class MockSolanaClient: + """Mock client for scenarios where network operations aren't needed.""" + def __init__(self): + self.rpc_endpoint = "http://dummy" + self._client = None + self._cached_blockhash = None + self._blockhash_lock = None + self._blockhash_updater_task = None class UniversalGeyserListener(BaseTokenListener): ... for platform in self.platforms: try: - # Create a simple dummy client that doesn't start blockhash updater - from core.client import SolanaClient - - # Create a mock client class to avoid network operations - class DummyClient(SolanaClient): - def __init__(self): - # Skip SolanaClient.__init__ to avoid starting blockhash updater - self.rpc_endpoint = "http://dummy" - self._client = None - self._cached_blockhash = None - self._blockhash_lock = None - self._blockhash_updater_task = None - - dummy_client = DummyClient() + dummy_client = MockSolanaClient()
75-76: Improve exception handling specificity.Catching broad
Exceptioncan hide important errors.- except Exception as e: - logger.warning(f"Could not register platform {platform.value}: {e}") + except (ImportError, AttributeError) as e: + logger.warning(f"Platform {platform.value} not available: {e}") + except Exception as e: + logger.error(f"Unexpected error registering platform {platform.value}: {e}", exc_info=True) + raise
186-186: Move Pubkey import to module level.+from solders.pubkey import Pubkey from geyser.generated import geyser_pb2, geyser_pb2_grpc from interfaces.core import Platform, TokenInfo # In _process_update method, remove line 186: - from solders.pubkey import Pubkeysrc/platforms/letsbonk/curve_manager.py (2)
62-64: Preserve exception context when re-raising.except Exception as e: - logger.exception("Failed to get pool state") - raise ValueError(f"Invalid pool state: {e!s}") + logger.exception("Failed to get pool state") + raise ValueError(f"Invalid pool state: {e!s}") from e
212-244: Critical: async method called without await.The method calls
self.get_pool_state()withoutawait, butget_pool_stateis an async method. This will fail at runtime.Make this method async and await the call:
- def validate_pool_state_structure(self, pool_address: Pubkey) -> bool: + async def validate_pool_state_structure(self, pool_address: Pubkey) -> bool: """Validate that the pool state structure matches IDL expectations. Args: pool_address: Address of the pool state Returns: True if structure is valid, False otherwise """ try: # This would be used during development/testing to ensure # the IDL parsing is working correctly - pool_state = await self.get_pool_state(pool_address) + pool_state = await self.get_pool_state(pool_address)src/platforms/letsbonk/instruction_builder.py (1)
316-327: Improve WSOL seed generation to avoid potential collisions.Using only timestamp in seconds could cause collisions if multiple transactions occur within the same second.
def _generate_wsol_seed(self, user: Pubkey) -> str: """Generate a unique seed for WSOL account creation. Args: user: User's wallet address Returns: Unique seed string for WSOL account """ - # Generate a unique seed based on timestamp and user pubkey - seed_data = f"{int(time.time())}{user!s}" + # Generate a unique seed with higher precision timestamp + import secrets + timestamp_ns = int(time.time() * 1_000_000_000) # nanosecond precision + random_bytes = secrets.token_bytes(4).hex() + seed_data = f"{timestamp_ns}{user!s}{random_bytes}" return hashlib.sha256(seed_data.encode()).hexdigest()[:32]
🧹 Nitpick comments (2)
src/monitoring/universal_geyser_listener.py (1)
197-204: Rename unused loop variable.- for platform, parser in self.platform_parsers.items(): + for _platform, parser in self.platform_parsers.items():src/platforms/letsbonk/instruction_builder.py (1)
137-142: Use lowercase for local constants per Python conventions.- # Build instruction data: discriminator + amount_in + minimum_amount_out + share_fee_rate - SHARE_FEE_RATE = 0 # No sharing fee + # Build instruction data: discriminator + amount_in + minimum_amount_out + share_fee_rate + share_fee_rate = 0 # No sharing fee instruction_data = ( self._buy_exact_in_discriminator + struct.pack("<Q", amount_in) + # amount_in (u64) - SOL to spend struct.pack("<Q", minimum_amount_out) + # minimum_amount_out (u64) - min tokens - struct.pack("<Q", SHARE_FEE_RATE) # share_fee_rate (u64): 0 + struct.pack("<Q", share_fee_rate) # share_fee_rate (u64): 0 )Apply the same change in the
build_sell_instructionmethod.Also applies to: 235-240
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/core/pubkeys.py(1 hunks)src/monitoring/universal_geyser_listener.py(6 hunks)src/platforms/letsbonk/curve_manager.py(1 hunks)src/platforms/letsbonk/instruction_builder.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
src/core/pubkeys.py
📄 CodeRabbit Inference Engine (.cursor/rules/core.mdc)
Define system address constants, program ID references, address derivation utilities, and token account resolution functions in src/core/pubkeys.py.
Files:
src/core/pubkeys.py
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/package-management.mdc)
**/*: Useuvfor all package operations; never use pip, pipenv, poetry, or conda
Useuv runfor script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency
Files:
src/core/pubkeys.pysrc/platforms/letsbonk/curve_manager.pysrc/monitoring/universal_geyser_listener.pysrc/platforms/letsbonk/instruction_builder.py
src/{core,trading,monitoring,cleanup,utils}/**/*.py
📄 CodeRabbit Inference Engine (.cursor/rules/project-structure.mdc)
Place all source code files in the @src/ directory, with core components under @src/core/, trading system under @src/trading/, monitoring system under @src/monitoring/, resource management under @src/cleanup/, and shared utilities under @src/utils/.
Files:
src/core/pubkeys.pysrc/monitoring/universal_geyser_listener.py
src/monitoring/*_listener.py
📄 CodeRabbit Inference Engine (CLAUDE.md)
Implement multiple listener types for token detection in the
src/monitoring/directory: logs, blocks, Geyser, PumpPortal, and an abstract base class.
Files:
src/monitoring/universal_geyser_listener.py
src/monitoring/*.py
📄 CodeRabbit Inference Engine (.cursor/rules/monitoring.mdc)
src/monitoring/*.py: Implement event monitoring and data collection systems for tracking blockchain activity when working on token detection, event processing, or subscription logic.
Each listener must have a corresponding event processor that validates incoming events, extracts relevant token information, applies filtering rules, and dispatches events to trading components.
Files:
src/monitoring/universal_geyser_listener.py
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Organize the pump-bot system into modular components with clear separation of concerns to facilitate maintainability, testing, and extension of functionality.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
📚 Learning: applies to src/core/pubkeys.py : define system address constants, program id references, address der...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/pubkeys.py : Define system address constants, program ID references, address derivation utilities, and token account resolution functions in src/core/pubkeys.py.
Applied to files:
src/core/pubkeys.pysrc/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/core/curve.py : implement mathematical models for bonding curve calculations, price i...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/curve.py : Implement mathematical models for bonding curve calculations, price impact estimation, liquidity modeling, and swap pricing utilities in src/core/curve.py.
Applied to files:
src/platforms/letsbonk/curve_manager.py
📚 Learning: applies to src/core/curve.py : bonding curve calculations for pump.fun tokens should be implemented ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Applied to files:
src/platforms/letsbonk/curve_manager.py
📚 Learning: applies to idl/raydium_amm_idl.json : @idl/raydium_amm_idl.json must provide integration with raydiu...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/raydium_amm_idl.json : @idl/raydium_amm_idl.json must provide integration with Raydium, including AMM pool interface definitions, liquidity provider instructions, market making operations, and price discovery mechanisms.
Applied to files:
src/platforms/letsbonk/curve_manager.py
📚 Learning: applies to src/monitoring/*_listener.py : implement multiple listener types for token detection in t...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/monitoring/*_listener.py : Implement multiple listener types for token detection in the `src/monitoring/` directory: logs, blocks, Geyser, PumpPortal, and an abstract base class.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/geyser_listener.py : implement geyser-based listener logic for direct conn...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/geyser_listener.py : Implement Geyser-based listener logic for direct connection to the Geyser WebSocket endpoint, providing lowest latency token detection and advanced filtering capabilities.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/base_listener.py : define a common interface for all token listeners by im...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/base_listener.py : Define a common interface for all token listeners by implementing an abstract base class (e.g., BaseTokenListener) that declares required methods for event subscription and standardizes token event processing.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/pumpportal_listener.py : integrate with external services (such as pumppor...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/pumpportal_listener.py : Integrate with external services (such as PumpPortal API) to receive preprocessed token events and simplify third-party data provider integration.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to tests/test_geyser_listener.py : use tests/test_geyser_listener.py to test the fastest det...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_geyser_listener.py : Use tests/test_geyser_listener.py to test the fastest detection method via direct gRPC connection to the Geyser endpoint, monitoring real-time token creation and measuring performance.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/logs_listener.py : implement log-based monitoring by subscribing to progra...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/logs_listener.py : Implement log-based monitoring by subscribing to program logs and performing pattern matching for token creation events.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/*.py : each listener must have a corresponding event processor that valida...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/*.py : Each listener must have a corresponding event processor that validates incoming events, extracts relevant token information, applies filtering rules, and dispatches events to trading components.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to tests/test_*_listener.py : each listener test should output new token information in a st...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_*_listener.py : Each listener test should output new token information in a standardized format, including token name, symbol, mint, URI, and creator.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/block_listener.py : implement block-based scanning to process entire block...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/block_listener.py : Implement block-based scanning to process entire blocks, extract transaction data, and identify token creation events.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/monitoring/*.py : implement event monitoring and data collection systems for tracking...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/monitoring.mdc:0-0
Timestamp: 2025-08-01T05:34:40.453Z
Learning: Applies to src/monitoring/*.py : Implement event monitoring and data collection systems for tracking blockchain activity when working on token detection, event processing, or subscription logic.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to src/core/client.py : use `src/core/client.py` for solana rpc operations with background b...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/client.py : Use `src/core/client.py` for Solana RPC operations with background blockhash caching via the `SolanaClient` abstraction.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to bots/*.yaml : if the `geyser` listener is used, it must include `endpoint`, `api_token`, ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/bots.mdc:0-0
Timestamp: 2025-08-01T05:34:00.113Z
Learning: Applies to bots/*.yaml : If the `geyser` listener is used, it must include `endpoint`, `api_token`, and `auth_type` fields.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: geyser listener provides fastest token detection....
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Geyser listener provides fastest token detection.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to tests/test_logs_listener.py : use tests/test_logs_listener.py to validate log-based monit...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-08-01T05:35:12.677Z
Learning: Applies to tests/test_logs_listener.py : Use tests/test_logs_listener.py to validate log-based monitoring by subscribing to program logs, matching patterns for token creation events, and verifying detection accuracy.
Applied to files:
src/monitoring/universal_geyser_listener.py
📚 Learning: applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, includin...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
📚 Learning: applies to idl/*.json : idl files must define the structure and interface of on-chain solana program...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/*.json : IDL files must define the structure and interface of on-chain Solana programs, including instruction schemas, account structures, event definitions, and discriminators.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
📚 Learning: applies to src/trading/seller.py : token sale logic should be implemented in `src/trading/seller.py`...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/seller.py : Token sale logic should be implemented in `src/trading/seller.py` using the `TokenSeller` class.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
📚 Learning: applies to src/trading/seller.py : implement sell operations, including exit strategies, profit calc...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/seller.py : Implement sell operations, including exit strategies, profit calculation, and transaction construction, in src/trading/seller.py using the TokenSeller class.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
📚 Learning: applies to src/trading/buyer.py : implement buy operations, including slippage calculation, buy tran...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/buyer.py : Implement buy operations, including slippage calculation, buy transaction creation, and transaction validation, in src/trading/buyer.py using the TokenBuyer class.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
📚 Learning: applies to src/trading/buyer.py : token purchase logic with slippage and retry support should be imp...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/buyer.py : Token purchase logic with slippage and retry support should be implemented in `src/trading/buyer.py` using the `TokenBuyer` class.
Applied to files:
src/platforms/letsbonk/instruction_builder.py
🪛 Ruff (0.12.2)
src/platforms/letsbonk/curve_manager.py
25-25: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
55-55: Abstract raise to an inner function
(TRY301)
55-55: Avoid specifying long messages outside the exception class
(TRY003)
60-60: Consider moving this statement to an else block
(TRY300)
64-64: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
64-64: Avoid specifying long messages outside the exception class
(TRY003)
82-82: Avoid specifying long messages outside the exception class
(TRY003)
184-184: Avoid specifying long messages outside the exception class
(TRY003)
240-240: Consider moving this statement to an else block
(TRY300)
src/monitoring/universal_geyser_listener.py
22-22: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
37-40: Avoid specifying long messages outside the exception class
(TRY003)
54-54: import should be at the top-level of a file
(PLC0415)
58-58: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
75-75: Do not catch blind exception: Exception
(BLE001)
78-78: Missing return type annotation for private function _create_geyser_connection
(ANN202)
98-98: Missing return type annotation for private function _create_subscription_request
(ANN202)
175-175: Missing type annotation for function argument update
(ANN001)
186-186: import should be at the top-level of a file
(PLC0415)
197-197: Loop control variable platform not used within loop body
Rename unused platform to _platform
(B007)
206-206: Consider moving this statement to an else block
(TRY300)
src/platforms/letsbonk/instruction_builder.py
33-33: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
137-137: Variable SHARE_FEE_RATE in function should be lowercase
(N806)
235-235: Variable SHARE_FEE_RATE in function should be lowercase
(N806)
🔇 Additional comments (1)
src/core/pubkeys.py (1)
1-62: Well-structured refactoring to support multi-platform architecture.The removal of platform-specific address logic and consolidation to only system-level Solana addresses aligns perfectly with the multi-platform architecture. The previous dataclass issues with function calls have been properly addressed by defining module-level constants and referencing them in the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/platforms/pumpfun/address_provider.py (1)
105-121: Remove unused parameter and improve method documentation.The
quote_mintparameter is not used in pump.fun's bonding curve derivation since SOL is always the quote currency.Apply this diff to remove the unused parameter:
-def derive_pool_address(self, base_mint: Pubkey, quote_mint: Pubkey | None = None) -> Pubkey: +def derive_pool_address(self, base_mint: Pubkey, quote_mint: Pubkey | None = None) -> Pubkey: """Derive the bonding curve address for a token. For pump.fun, this is the bonding curve PDA derived from the mint. + The quote_mint parameter is ignored as SOL is always the quote currency. Args: base_mint: Token mint address - quote_mint: Not used for pump.fun (SOL is always the quote) + quote_mint: Ignored for pump.fun (SOL is always the quote) Returns: Bonding curve address """ + # Explicitly ignore quote_mint for pump.fun + _ = quote_mint bonding_curve, _ = Pubkey.find_program_address( [b"bonding-curve", bytes(base_mint)], PumpFunAddresses.PROGRAM ) return bonding_curve
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
bots/bot-sniper-4-pp.yaml(2 hunks)src/platforms/pumpfun/address_provider.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- bots/bot-sniper-4-pp.yaml
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/package-management.mdc)
**/*: Useuvfor all package operations; never use pip, pipenv, poetry, or conda
Useuv runfor script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency
Files:
src/platforms/pumpfun/address_provider.py
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: The bot trades on pump.fun bonding curves and handles migrations to PumpSwap.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-01T05:35:03.187Z
Learning: Organize the pump-bot system into modular components with clear separation of concerns to facilitate maintainability, testing, and extension of functionality.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
📚 Learning: applies to src/core/pubkeys.py : define system address constants, program id references, address der...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/core.mdc:0-0
Timestamp: 2025-08-01T05:34:17.966Z
Learning: Applies to src/core/pubkeys.py : Define system address constants, program ID references, address derivation utilities, and token account resolution functions in src/core/pubkeys.py.
Applied to files:
src/platforms/pumpfun/address_provider.py
📚 Learning: applies to src/trading/trader.py : implement trading logic in `src/trading/trader.py` using the `pum...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/trading/trader.py : Implement trading logic in `src/trading/trader.py` using the `PumpTrader` class to orchestrate token detection, buying, and selling.
Applied to files:
src/platforms/pumpfun/address_provider.py
📚 Learning: applies to idl/pump_fun_idl.json : @idl/pump_fun_idl.json must contain the main pump.fun protocol in...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_fun_idl.json : idl/pump_fun_idl.json must contain the main pump.fun protocol instruction schemas, account structures, token management instructions, and event definitions.
Applied to files:
src/platforms/pumpfun/address_provider.py
📚 Learning: applies to src/core/curve.py : bonding curve calculations for pump.fun tokens should be implemented ...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-01T05:33:45.793Z
Learning: Applies to src/core/curve.py : Bonding curve calculations for pump.fun tokens should be implemented in `src/core/curve.py`.
Applied to files:
src/platforms/pumpfun/address_provider.py
📚 Learning: applies to src/trading/trader.py : orchestrate the trading lifecycle, including token detection to e...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/trading.mdc:0-0
Timestamp: 2025-08-01T05:35:22.716Z
Learning: Applies to src/trading/trader.py : Orchestrate the trading lifecycle, including token detection to execution flow, risk management controls, buy/sell coordination, and position tracking/reporting, in src/trading/trader.py using the PumpTrader class.
Applied to files:
src/platforms/pumpfun/address_provider.py
📚 Learning: applies to idl/pump_swap_idl.json : @idl/pump_swap_idl.json must define the swap interface, includin...
Learnt from: CR
PR: chainstacklabs/pump-fun-bot#0
File: .cursor/rules/idl.mdc:0-0
Timestamp: 2025-08-01T05:34:30.188Z
Learning: Applies to idl/pump_swap_idl.json : idl/pump_swap_idl.json must define the swap interface, including token swap instruction formats, liquidity management operations, price calculation functions, and fee structure definitions.
Applied to files:
src/platforms/pumpfun/address_provider.py
🧬 Code Graph Analysis (1)
src/platforms/pumpfun/address_provider.py (7)
src/core/wallet.py (2)
pubkey(24-26)get_associated_token_address(33-42)src/core/pubkeys.py (5)
SystemAddresses(39-62)get_all_system_addresses(50-62)PumpAddresses(34-82)SystemAddresses(15-30)find_user_volume_accumulator(68-82)src/interfaces/core.py (12)
AddressProvider(50-110)Platform(17-20)TokenInfo(24-47)platform(55-57)platform(118-120)platform(212-214)platform(292-294)program_id(61-63)get_system_addresses(66-72)derive_pool_address(75-85)derive_user_token_account(88-98)get_additional_accounts(101-110)src/platforms/pumpfun/curve_manager.py (1)
platform(37-39)src/platforms/pumpfun/event_parser.py (1)
platform(49-51)src/platforms/letsbonk/address_provider.py (8)
platform(32-34)program_id(37-39)get_system_addresses(41-59)derive_pool_address(61-80)derive_user_token_account(128-138)get_additional_accounts(140-174)get_buy_instruction_accounts(218-245)get_sell_instruction_accounts(247-274)src/platforms/pumpfun/instruction_builder.py (1)
platform(41-43)
🪛 Ruff (0.12.2)
src/platforms/pumpfun/address_provider.py
22-24: Do not perform function call Pubkey.from_string in dataclass defaults
(RUF009)
25-27: Do not perform function call Pubkey.from_string in dataclass defaults
(RUF009)
28-30: Do not perform function call Pubkey.from_string in dataclass defaults
(RUF009)
31-33: Do not perform function call Pubkey.from_string in dataclass defaults
(RUF009)
34-36: Do not perform function call Pubkey.from_string in dataclass defaults
(RUF009)
105-105: Unused method argument: quote_mint
(ARG002)
🔇 Additional comments (2)
src/platforms/pumpfun/address_provider.py (2)
135-168: LGTM! Clean account derivation logic.The additional accounts method properly handles optional fields from TokenInfo and provides fallback derivation when needed. The conditional logic for deriving missing associated bonding curves and creator vaults is well-structured.
170-203: LGTM! Correct PDA derivations for pump.fun.The PDA derivations for associated bonding curve and creator vault use the correct seeds and program IDs. The associated bonding curve derivation properly uses the associated token program, while the creator vault uses the pump.fun program.
Major changes:
From user perspective, it's a new field in the config called
platform.Summary by CodeRabbit
New Features
platformconfiguration option for flexible platform selection in bot configs.Improvements
Bug Fixes
Documentation
Chores