use solana_streamer_sdk::{ match_event, streaming::{ event_parser::{ protocols::{ bonk::{ parser::BONK_PROGRAM_ID, BonkMigrateToAmmEvent, BonkMigrateToCpswapEvent, BonkPoolCreateEvent, BonkTradeEvent, }, pumpfun::{parser::PUMPFUN_PROGRAM_ID, PumpFunCreateTokenEvent, PumpFunTradeEvent}, pumpswap::{ parser::PUMPSWAP_PROGRAM_ID, PumpSwapBuyEvent, PumpSwapCreatePoolEvent, PumpSwapDepositEvent, PumpSwapSellEvent, PumpSwapWithdrawEvent, }, raydium_clmm::{ parser::RAYDIUM_CLMM_PROGRAM_ID, RaydiumClmmSwapEvent, RaydiumClmmSwapV2Event, }, raydium_cpmm::{parser::RAYDIUM_CPMM_PROGRAM_ID, RaydiumCpmmSwapEvent}, }, Protocol, UnifiedEvent, }, ShredStreamGrpc, YellowstoneGrpc, yellowstone_grpc::ClientConfig, shred_stream::ShredClientConfig, }, }; #[tokio::main] async fn main() -> Result<(), Box> { println!("Starting Solana Streamer..."); test_grpc().await?; test_shreds().await?; Ok(()) } async fn test_grpc() -> Result<(), Box> { println!("Subscribing to Yellowstone gRPC events..."); // Create low-latency configuration let mut config = ClientConfig::low_latency(); // Enable performance monitoring, has performance overhead, disabled by default config.enable_metrics = true; let grpc = YellowstoneGrpc::new_with_config( "https://solana-yellowstone-grpc.publicnode.com:443".to_string(), None, config, )?; println!("GRPC client created successfully"); let callback = create_event_callback(); // Will try to parse corresponding protocol events from transactions let protocols = vec![ Protocol::PumpFun, Protocol::PumpSwap, Protocol::Bonk, Protocol::RaydiumCpmm, Protocol::RaydiumClmm, ]; println!("Protocols to monitor: {:?}", protocols); // Filter accounts let account_include = vec![ PUMPFUN_PROGRAM_ID.to_string(), // Listen to pumpfun program ID PUMPSWAP_PROGRAM_ID.to_string(), // Listen to pumpswap program ID BONK_PROGRAM_ID.to_string(), // Listen to bonk program ID RAYDIUM_CPMM_PROGRAM_ID.to_string(), // Listen to raydium_cpmm program ID RAYDIUM_CLMM_PROGRAM_ID.to_string(), // Listen to raydium_clmm program ID ]; let account_exclude = vec![]; let account_required = vec![]; println!("Starting to listen for events, press Ctrl+C to stop..."); println!("Monitoring programs: {:?}", account_include); println!("Starting subscription..."); grpc.subscribe_events_v2( protocols, None, account_include, account_exclude, account_required, None, callback, ) .await?; Ok(()) } async fn test_shreds() -> Result<(), Box> { println!("Subscribing to ShredStream events..."); // Create low-latency configuration let mut config = ShredClientConfig::low_latency(); // Enable performance monitoring, has performance overhead, disabled by default config.enable_metrics = true; let shred_stream = ShredStreamGrpc::new_with_config("http://127.0.0.1:10800".to_string(), config).await?; let callback = create_event_callback(); let protocols = vec![ Protocol::PumpFun, Protocol::PumpSwap, Protocol::Bonk, Protocol::RaydiumCpmm, Protocol::RaydiumClmm, ]; println!("Listening for events, press Ctrl+C to stop..."); shred_stream.shredstream_subscribe(protocols, None, callback).await?; Ok(()) } fn create_event_callback() -> impl Fn(Box) { |event: Box| { println!("🎉 Event received! Type: {:?}, ID: {}", event.event_type(), event.id()); match_event!(event, { BonkPoolCreateEvent => |e: BonkPoolCreateEvent| { // When using grpc, you can get block_time from each event println!("block_time: {:?}, block_time_ms: {:?}", e.metadata.block_time, e.metadata.block_time_ms); println!("BonkPoolCreateEvent: {:?}", e.base_mint_param.symbol); }, BonkTradeEvent => |e: BonkTradeEvent| { println!("BonkTradeEvent: {e:?}"); }, BonkMigrateToAmmEvent => |e: BonkMigrateToAmmEvent| { println!("BonkMigrateToAmmEvent: {e:?}"); }, BonkMigrateToCpswapEvent => |e: BonkMigrateToCpswapEvent| { println!("BonkMigrateToCpswapEvent: {e:?}"); }, PumpFunTradeEvent => |e: PumpFunTradeEvent| { println!("PumpFunTradeEvent: {e:?}"); }, PumpFunCreateTokenEvent => |e: PumpFunCreateTokenEvent| { println!("PumpFunCreateTokenEvent: {e:?}"); }, PumpSwapBuyEvent => |e: PumpSwapBuyEvent| { println!("Buy event: {e:?}"); }, PumpSwapSellEvent => |e: PumpSwapSellEvent| { println!("Sell event: {e:?}"); }, PumpSwapCreatePoolEvent => |e: PumpSwapCreatePoolEvent| { println!("CreatePool event: {e:?}"); }, PumpSwapDepositEvent => |e: PumpSwapDepositEvent| { println!("Deposit event: {e:?}"); }, PumpSwapWithdrawEvent => |e: PumpSwapWithdrawEvent| { println!("Withdraw event: {e:?}"); }, RaydiumCpmmSwapEvent => |e: RaydiumCpmmSwapEvent| { println!("RaydiumCpmmSwapEvent: {e:?}"); }, RaydiumClmmSwapEvent => |e: RaydiumClmmSwapEvent| { println!("RaydiumClmmSwapEvent: {e:?}"); }, RaydiumClmmSwapV2Event => |e: RaydiumClmmSwapV2Event| { println!("RaydiumClmmSwapV2Event: {e:?}"); } }); } }