Skip to content

Conversation

@smypmsa
Copy link
Member

@smypmsa smypmsa commented Aug 4, 2025

Major changes:

  • add support for letsbonk fun (buy, sell, geyser, blocks, pumpportal listeners)
  • add instruction/event parsing based on IDL
  • add platform extensibility

From user perspective, it's a new field in the config called platform.

Summary by CodeRabbit

  • New Features

    • Added multi-platform trading support for Pump.Fun and LetsBonk platforms.
    • Introduced universal, platform-aware token listeners and trading logic.
    • Added platform configuration option for flexible platform selection in bot configs.
    • Implemented centralized IDL management for multi-platform Solana program decoding.
    • Added platform factory and registry for managing platform-specific implementations.
    • Introduced platform-aware address providers, instruction builders, curve managers, and event parsers.
  • Improvements

    • Refactored bot runner and config loader for platform validation and compatibility checks.
    • Unified token event detection across logs, blocks, Geyser, and PumpPortal listeners with platform filtering.
    • Enhanced trading modules with platform-aware buyers, sellers, and universal trader classes.
    • Improved logging, error handling, and startup validation for multi-platform support.
    • Updated README and usage instructions to reflect multi-platform support and tooling changes.
  • Bug Fixes

    • Fixed platform-listener compatibility validation and error reporting.
    • Improved robustness in token parsing and event processing across platforms.
  • Documentation

    • Removed legacy and outdated markdown docs and test scripts related to single-platform implementations.
  • Chores

    • Removed legacy pump.fun-specific buyers, sellers, and event processors.
    • Cleaned up platform-specific code to support extensibility and maintainability.

@smypmsa smypmsa self-assigned this Aug 4, 2025
@smypmsa smypmsa added the enhancement New feature or request label Aug 4, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 4, 2025

Walkthrough

This 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 platform key. Extensive documentation, legacy code, and test scripts are removed or replaced to align with the new architecture.

Changes

Cohort / File(s) Change Summary
Documentation & Rules Removal
.cursor/rules/*, CLAUDE.md
Deleted all documentation and rule markdown files, including configuration guides, architecture overviews, listener and trading docs, and developer guides.
Bot Configuration Updates
bots/bot-sniper-1-geyser.yaml, bots/bot-sniper-2-logs.yaml, bots/bot-sniper-3-blocks.yaml, bots/bot-sniper-4-pp.yaml
Added platform key (default "pump_fun" or "lets_bonk"); in bot-sniper-2-logs.yaml, changed exit_strategy and updated profit/loss percentages.
Core Refactor & Platform Abstraction
src/bot_runner.py, src/config_loader.py, src/core/pubkeys.py, src/interfaces/core.py, src/platforms/__init__.py, src/monitoring/base_listener.py, src/monitoring/listener_factory.py, src/trading/base.py, src/trading/platform_aware.py, src/trading/universal_trader.py, src/utils/idl_manager.py, src/utils/idl_parser.py
Introduced platform-agnostic interfaces and factories, refactored runner and config loader for platform validation and multi-platform support, updated system addresses, added universal listener factory, enhanced base listener, implemented IDL management and parsing, and replaced trading base with platform support.
Platform Implementations: PumpFun
src/platforms/pumpfun/__init__.py, src/platforms/pumpfun/address_provider.py, src/platforms/pumpfun/curve_manager.py, src/platforms/pumpfun/event_parser.py, src/platforms/pumpfun/instruction_builder.py, src/platforms/pumpfun/pumpportal_processor.py
Added PumpFun-specific address provider, curve manager, event parser, instruction builder, and PumpPortal processor, all conforming to new interfaces and IDL-driven logic.
Platform Implementations: LetsBonk
src/platforms/letsbonk/__init__.py, src/platforms/letsbonk/address_provider.py, src/platforms/letsbonk/curve_manager.py, src/platforms/letsbonk/event_parser.py, src/platforms/letsbonk/instruction_builder.py, src/platforms/letsbonk/pumpportal_processor.py
Added LetsBonk-specific address provider, curve manager, event parser, instruction builder, and PumpPortal processor, all implementing the new platform interface system.
Universal Listeners
src/monitoring/universal_block_listener.py, src/monitoring/universal_geyser_listener.py, src/monitoring/universal_logs_listener.py, src/monitoring/universal_pumpportal_listener.py
Replaced pump.fun-specific listeners with universal listeners supporting multiple platforms, using dynamic event parser registration and platform filtering.
Removed Legacy Listeners & Processors
src/monitoring/block_event_processor.py, src/monitoring/geyser_event_processor.py, src/monitoring/logs_event_processor.py, src/monitoring/logs_listener.py
Deleted pump.fun-specific event processors and listeners, replaced by universal, platform-aware versions.
Removed Legacy Trading Logic
src/core/curve.py, src/trading/buyer.py, src/trading/seller.py
Deleted pump.fun-specific bonding curve and trading logic, replaced by platform-agnostic and interface-driven modules.
Test Scripts Removal
tests/compare_listeners.py, tests/test_block_listener.py, tests/test_geyser_listener.py, tests/test_logs_listener.py
Deleted legacy test scripts for listeners, as the listener architecture is now universal and platform-driven.

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
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90+ minutes

Possibly related PRs

Suggested reviewers

  • akegaviar

Poem

Oh, what a leap for this codebase bold,
Platforms united, new stories unfold!
PumpFun and LetsBonk, side by side,
Universal listeners, no need to hide.
Rabbits rejoice in this platformy spree—
Multi-chain magic, as far as we see!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/platform-abstraction

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@smypmsa
Copy link
Member Author

smypmsa commented Aug 4, 2025

I forgot to include rules for Claude and Cursor. I'll get them back in future commits.

@smypmsa smypmsa requested a review from akegaviar August 4, 2025 05:44
@smypmsa smypmsa linked an issue Aug 4, 2025 that may be closed by this pull request
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 mismatch

The lets_bonk platform 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 is geyser:.
  • 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 least refresh_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 - the platform variable is not used in the loop body. Rename to _platform for 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 & Docs

Same note as other configs: verify "pump_fun" / "lets_bonk" match the Platform enum 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 readability

Optional 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 TokenInfo object 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_logger

Then 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 None

Or 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 platform variable 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 variable

The platform variable 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_info
src/platforms/letsbonk/event_parser.py (2)

48-64: Remove unused method or implement functionality

The 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 function

The 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 parameters

The 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 = config

Also, 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 Pubkey objects 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 addresses

Remove the @dataclass decorator since these are all class constants, not instance fields.


105-122: Document why quote_mint parameter is ignored.

The quote_mint parameter 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 addresses

Remove the @dataclass decorator 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 = path

Then 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 ClassVar to 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 Exception can 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

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 risk

The platform key addition itself is fine, however the accompanying PumpPortal listener block is incomplete:

  • Coding-guidelines mandate endpoint and api_key when pumpportal is used – only url is 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_type remains "pumpportal" after fixing.

bots/bot-sniper-3-blocks.yaml (1)

14-22: Inconsistent listener configuration – file will be rejected by validator

  • filters.listener_type is set to "blocks" but the only listener section present is Geyser – coding guidelines require exactly one matching section.
  • If a blocks listener is intended, a blocks: section with refresh_interval is mandatory.
  • If Geyser is desired, change listener_type to "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   # seconds

or

-  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 configured

This 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 filename bot-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 parameters

Also 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 immutable tuple for __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 consistency

Mirror 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 strategy

When using exit_strategy: "time_based", the take_profit_percentage and stop_loss_percentage fields 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 seconds
src/monitoring/base_listener.py (1)

14-20: Add return type annotation for init method

The 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 method

Apply this diff to add the return type annotation:

-    def __init__(self):
+    def __init__(self) -> None:

61-66: Verify LetsBonk field mappings with actual PumpPortal data

The 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 logging

Use more specific exception handling and logger.exception for 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 None
src/monitoring/universal_pumpportal_listener.py (1)

21-32: Add return type annotation for init method

Apply 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 performance

Dynamic 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 UniversalPumpPortalListener

Then 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 constant

The 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_PLATFORMS
src/bot_runner.py (1)

42-44: Use more specific exception handling

Catching generic ValueError could 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."""
    pass

Then 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}")
         return
src/trading/universal_trader.py (1)

549-550: Use pathlib instead of os.path for file operations

The 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_trade method.

Also applies to: 578-578, 588-588

src/monitoring/universal_logs_listener.py (1)

197-201: Rename unused loop variable

The platform variable 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_info
src/monitoring/universal_geyser_listener.py (2)

80-99: Add return type annotation

The 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 annotations

The 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 Any

The transaction_info parameter uses Any type 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 Exception catch 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 Pubkey objects are immutable and marked as Final, 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 @dataclass decorator 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_pda
src/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.exception to 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 Exception could 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_Legacy violates 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)

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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.exception to 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 errors
src/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 Exception catch and use of logger.error instead of logger.exception makes 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
-        pass
src/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

📥 Commits

Reviewing files that changed from the base of the PR and between ea1d6b4 and 53763b7.

📒 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)

**/*: Use uv for all package operations; never use pip, pipenv, poetry, or conda
Use uv run for script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency

Files:

  • src/monitoring/listener_factory.py
  • src/trading/universal_trader.py
  • src/trading/platform_aware.py
  • src/config_loader.py
  • src/interfaces/core.py
  • src/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.py
  • src/trading/universal_trader.py
  • src/trading/platform_aware.py
  • src/utils/idl_manager.py
src/config_loader.py

📄 CodeRabbit Inference Engine (CLAUDE.md)

Use src/config_loader.py to 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.py
  • src/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.py
  • src/trading/universal_trader.py
  • src/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.py
  • src/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.py
  • src/trading/universal_trader.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/trading/platform_aware.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.py
  • src/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.Path and 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 line

Alternatively, you could use a well-known example token address as the default.

README.md (2)

15-15: Prefer concise wording & tighten the sentence

Replace 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 link

Nested 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

📥 Commits

Reviewing files that changed from the base of the PR and between 53763b7 and 83a7f9e.

📒 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)

**/*: Use uv for all package operations; never use pip, pipenv, poetry, or conda
Use uv run for 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.py
  • README.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.py
  • README.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.py
  • README.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.py
  • README.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 argparse enables 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 implementations

We’ve confirmed that PumpFunCurveManager and LetsBonkCurveManager exist under:

  • src/platforms/pumpfun/curve_manager.py
  • src/platforms/letsbonk/curve_manager.py

Both 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 SolanaClient and IDLParser
• Create PumpFunCurveManager(client, idl_parser)
• Replace the manual discriminator check and Construct parsing in get_bonding_curve_state with calls to curve_manager.get_pool_state(curve_address)
• Delegate all calculations (price, buy/sell amounts, completion) to the manager methods

That 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 to uv run

This change aligns the README with the project-wide guideline of using uv for script execution. Looks correct to me.


114-118: ✅ Confirmed script path in README

  • learning-examples/bonding-curve-progress/get_bonding_curve_status.py exists as referenced.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 Exception can 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 Pubkey
src/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() without await, but get_pool_state is 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_instruction method.

Also applies to: 235-240

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 874d148 and 3292666.

📒 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)

**/*: Use uv for all package operations; never use pip, pipenv, poetry, or conda
Use uv run for script execution to ensure proper virtual environment activation
All documentation and examples should reference uv commands for consistency

Files:

  • src/core/pubkeys.py
  • src/platforms/letsbonk/curve_manager.py
  • src/monitoring/universal_geyser_listener.py
  • src/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.py
  • src/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.py
  • src/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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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_mint parameter 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3292666 and cb5c9ed.

📒 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)

**/*: Use uv for all package operations; never use pip, pipenv, poetry, or conda
Use uv run for 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.

@akegaviar akegaviar merged commit f2efd56 into main Aug 6, 2025
5 checks passed
@smypmsa smypmsa deleted the feat/platform-abstraction branch August 6, 2025 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Price/buy/sell for bonk.fun

3 participants