Solana Streamer SDK

repository·main·Indexed 41 days ago

https://github.com/0xfnzero/solana-streamer

A high-performance Rust SDK for real-time event streaming from Solana DEX trading programs. It provides a unified API over Yellowstone gRPC, ShredStream, and RPC parsing helpers, utilizing sol-parser-sdk for low-latency event processing. Version 3.0.5 supports protocols including PumpFun, Raydium, Meteora DAMM v2, and Orca Whirlpool, with options for both Borsh-based and zero-copy parsing backends.

Tokens
20.1K
Snippets
48
Records
80
Agent score
51%

What's inside Solana Streamer

  1. Overview of Solana Streamer SDK

    main

    The solana-streamer-sdk is a lightweight Rust library built on top of sol-parser-sdk. It provides a stable API for real-time event streaming from Solana DEX programs, designed specifically for Solana bots, indexers, copy-trading systems, sniper bots, and DEX monitoring tools.

    Supported Input Sources

    • Yellowstone gRPC: High-performance event subscriptions.
    • Jito ShredStream: Alternative event stream transmission.
    • RPC Transactions: Parsing fetched RPC transactions or converting transactions by signature into streamer events.
    • Encoded Transaction Data: Direct parsing of raw data.

    Supported DEX Protocols

    • PumpFun Ecosystem: PumpFun, PumpSwap, Pump Fees.
    • Launchpads: LaunchLab (and aliases Bonk, RaydiumLaunchpad), StonkFun.
    • Raydium: Raydium CPMM, Raydium CLMM, Raydium AMM V4.
    • Meteora: Meteora DAMM v2, Meteora DLMM, Meteora DBC, Meteora Pools.
    • Orca: Orca Whirlpool.
  2. Understand Shredstream parsing limitations and missing events

    main

    Shredstream has significant parsing limitations because it only iterates over outer instructions (transaction.message.instructions()) and does not process inner_instructions.

    Critical Limitations:

    • Missing CPI-only Events: If a protocol (e.g., PumpFun, PumpSwap) is called only via CPI (for example, through a Jupiter or Raydium aggregator), Shredstream will completely miss the event. It will not emit any event for that protocol.
    • Address Lookup Tables (ALT): Shredstream only provides static accounts. If an instruction uses accounts loaded via ALT, they will appear as Pubkey::default() (11111...). This may cause errors in instructions that rely on account indexing.
    • No CPI Merging: Because inner instructions are missing, all data that normally comes from CPI execution (like actual swap amounts, reserves, fees, and timestamps) will be 0 or default values.

    When to use which:

    • Use gRPC: For accurate accounting, statistics, and processing transactions routed through aggregators/routers.
    • Use Shredstream: For latency-sensitive scenarios where you only care about direct user-to-protocol interactions and can handle missing/default fields.
  3. Understand ShredStream parsing limitations and data source differences

    main

    ShredStream is optimized for low latency but operates with 'best-effort' semantics, which leads to specific data gaps compared to gRPC (Yellowstone) providers.

    Key Limitations

    • Address Lookup Tables (ALT) Issues: Current ShredStream Entry messages only contain the slot and serialized entry data. Because V0 transactions only record indices for lookup tables rather than the actual Pubkeys, the parser cannot losslessly recover loaded addresses without additional context.
    • Missing Inner Instructions: Transactions without inner instructions will lack CPI (Cross-Program Invocation) merging.
    • Missed Events: Events triggered solely via CPI may be missed.
    • Program Identity Ambiguity: When a program ID cannot be recovered due to ALT limitations, the parser may attempt 'discriminator-only' parsing. This can lead to collisions where different programs share the same Anchor discriminator, potentially resulting in incorrect event attribution.

    Decision Matrix: When to use ShredStream vs. Yellowstone gRPC

    FeatureShredStreamYellowstone gRPC
    Primary GoalUltra-low latencyData integrity & strict correctness
    Account AccuracyBest-effort (may use Pubkey placeholders)Fully resolved accounts
    Program IdentityMay rely on discriminator fallbackGuaranteed via resolved program IDs
    Use CaseHigh-frequency, latency-sensitive tasksBusiness logic requiring strict account/program validation
  4. Filter events using EventTypeFilter

    main

    Use EventTypeFilter to reduce processing overhead (up to 60-80% reduction) and focus on specific data.

    Important: Transaction fee, priority-fee, and SWQoS tip parsing is strictly opt-in. Using None, EventTypeFilter::default(), or EventTypeFilter::all() will not enable transaction-cost scanning. You must explicitly include EventType::TransactionCost to see tip payments.

    use solana_streamer_sdk::streaming::event_parser::common::{filter::EventTypeFilter, EventType};
    
    // No filtering - receive all events
    let event_type_filter = None;
    
    // Filter specific event types - only receive PumpSwap buy/sell events
    let event_type_filter = Some(EventTypeFilter::include_only(vec![
        EventType::PumpSwapBuy,
        EventType::PumpSwapSell,
    ]));
    
    // Exclude noisy events while keeping everything else
    let event_type_filter = Some(EventTypeFilter::exclude_only(vec![EventType::BlockMeta]));
    
    // Opt-in to transaction cost scanning
    let event_type_filter = Some(EventTypeFilter::include_only(vec![
        EventType::PumpFunBuy,
        EventType::TransactionCost,
    ]));
    
    let callback = |event: DexEvent| {
        if let DexEvent::TransactionCostEvent(cost) = event {
            println!("tips: {:?}", cost.tip_payments);
        }
    };
  5. Filter DEX events for performance

    main

    Using EventTypeFilter can reduce unnecessary event processing by 60-80%, lowering memory usage and network bandwidth. You can use include_only to whitelist specific events or exclude_only to blacklist noise (like EventType::BlockMeta).

    use solana_streamer_sdk::streaming::event_parser::common::{filter::EventTypeFilter, EventType};
    
    // No filter - receive all events
    let event_type_filter = None;
    
    // Filter specific event types - only receive PumpSwap buy/sell events
    let event_type_filter = Some(EventTypeFilter::include_only(vec![
        EventType::PumpSwapBuy,
        EventType::PumpSwapSell,
    ]));
    
    // Exclude high-frequency noise, keep everything else
    let event_type_filter = Some(EventTypeFilter::exclude_only(vec![EventType::BlockMeta]));
  6. Streaming Infrastructure Components

    main

    The SDK provides multiple ways to ingest data depending on your requirements:

    • Yellowstone gRPC Client: An optimized client specifically for Solana event streaming.
    • ShredStream Client: An alternative streaming implementation.
    • Async Processing: All event handling is non-blocking to ensure high performance.
  7. Understand the solana-streamer-sdk project structure

    main

    The SDK is organized into several functional modules:

    • common/: General utilities and types.
    • protos/: Protocol buffer definitions.
    • streaming/: The core event streaming system, which includes:
      • event_parser/: A streamer-compatible event facade based on sol-parser-sdk. It contains public event metadata, filtering types, and the SDK distribution entry point.
      • parser_sdk_bridge/: An adaptation layer for sol-parser-sdk events.
      • rpc_parse.rs: Helpers for parsing RPC transactions.
      • sdk_bridge.rs: High-level SDK interoperability modules.
      • shred_stream.rs: ShredStream client.
      • yellowstone_grpc.rs: Yellowstone gRPC client.
      • yellowstone_sub_system.rs: Yellowstone subsystem.
    • lib.rs: The main library entry point.
  8. Configure ShredStream parsing modes

    main

    The project is moving towards supporting three distinct parsing modes to handle the trade-off between latency and data completeness. While implementation details are evolving, the conceptual modes are:

    • Strict: Skips instructions if the program ID or necessary accounts cannot be parsed. It does not produce 'guessed' events.
    • Cached: Performs full parsing only when the Address Lookup Table (ALT) is present in the local cache. If a cache miss occurs, it skips the instruction and loads the table asynchronously (non-blocking).
    • BestEffort (Current Default): Uses Pubkey placeholders and discriminator fallbacks to provide the most data possible, even if identity is uncertain. This is intended for compatibility and high-speed streams where some inaccuracy is acceptable.
  9. Compare gRPC (Yellowstone) vs Shredstream data sources

    main

    When choosing between gRPC and Shredstream, understand the fundamental differences in the data provided. Use gRPC if you require full transaction context, and Shredstream if you prioritize low latency and can tolerate partial data.

    FeaturegRPC (Yellowstone)Shredstream
    Account ListFull resolved list (static + loaded_addresses)Only static_account_keys()
    Inner Instructions (CPI)Available (from block execution results)None (Entry only contains raw transaction)
    block_timeAvailableNone (Always 0)
    tx_indexTransaction index within slotTransaction index within entry (best-effort)
  10. Important usage considerations and limitations

    main

    When deploying the SDK in production, keep the following in mind:

    • Network Stability: A stable network connection is required for continuous event stream transmission.
    • Rate Limiting: Be aware of rate limits imposed by public gRPC endpoints.
    • Error Recovery: You must implement your own error handling and reconnection logic to handle stream interruptions.
    • Compliance: Ensure your usage complies with all relevant laws and regulations.
  11. How the Event Parsing System works

    main

    The parsing system delegates heavy lifting to sol-parser-sdk while providing a streamlined interface for the streamer.

    • Protocol Parsing: Yellowstone gRPC, ShredStream, RPC transaction parsing, and account parsing are all delegated to sol-parser-sdk via a facade.
    • Local Processing: The streamer's local handling is reserved for infrastructure tasks and non-DEX compatibility cases (e.g., ComputeBudget metadata).
    • Extensibility: The streaming::sdk_bridge module allows advanced users to access raw SDK functionality without needing to rewrite existing bot callback logic.
  12. Understand the Unified Event Interface

    main

    The SDK uses a unified event model to provide type-safe access to various protocol events. This allows you to handle events from different sources using a consistent interface.

    Key components include:

    • DexEvent Enum: A type-safe enum that contains all possible protocol events.
    • Protocol Enum: Used to easily identify the source of an event.
    • SDK Bridge: A mechanism that adapts sol-parser-sdk::DexEvent into the streamer's own DexEvent type, ensuring compatibility between the underlying parser and the streamer's interface.