diff --git a/Cargo.toml b/Cargo.toml index 553c89f..8688a34 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "solana-streamer-sdk" -version = "3.0.3" +version = "3.0.4" edition = "2021" rust-version = "1.91" authors = ["William ", "sgxiang ", "wei <1415121722@qq.com>"] @@ -22,7 +22,7 @@ sdk-perf-stats = ["sol-parser-sdk/perf-stats"] sdk-ultra-perf = ["sol-parser-sdk/ultra-perf"] [dependencies] -sol-parser-sdk = { path = "../sol-parser-sdk", version = "0.7.3", default-features = false } +sol-parser-sdk = { path = "../sol-parser-sdk", version = "0.7.4", default-features = false } solana-sdk = "=4.0.1" solana-client = "=4.2.2" solana-transaction-status = { version = "=4.2.2", features = ["agave-unstable-api"] } diff --git a/README.md b/README.md index a6eb2ed..db36e30 100755 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ | Area | Coverage | |------|----------| | Input sources | Yellowstone gRPC, Jito ShredStream, fetched RPC transactions, encoded transaction data | -| DEX protocols | PumpFun, PumpSwap, Pump Fees, Raydium LaunchLab, Raydium CPMM, Raydium CLMM, Raydium AMM V4, Meteora DAMM v2, Meteora DLMM, Meteora DBC, Orca Whirlpool | +| DEX protocols | PumpFun, PumpSwap, Pump Fees, LaunchLab, StonkFun, Raydium CPMM, Raydium CLMM, Raydium AMM V4, Meteora DAMM v2, Meteora DLMM, Meteora DBC, Orca Whirlpool | | Use cases | Real-time DEX event streaming, token launch monitoring, copy trading, account-state subscriptions, bot signal pipelines | | Parser backend | `sol-parser-sdk` with default Borsh parsing and optional zero-copy backend for latency-sensitive workloads | @@ -82,7 +82,8 @@ - **PumpFun**: Meme coin trading platform events - **Pump Fees**: Pump fee-sharing configuration events - **PumpSwap**: PumpFun's swap protocol events -- **Raydium LaunchLab**: Token launch platform events; `Protocol::Bonk` and `Protocol::RaydiumLaunchpad` remain compatible aliases +- **LaunchLab**: Shared token-launch program events through `Protocol::LaunchLab`; `Protocol::Bonk` and `Protocol::RaydiumLaunchpad` remain compatible aliases +- **StonkFun**: StonkFun-attributed LaunchLab events through `Protocol::StonkFun`; event metadata reports `ProtocolType::StonkFun` - **Raydium CPMM**: Raydium's Concentrated Pool Market Maker events - **Raydium CLMM**: Raydium's Concentrated Liquidity Market Maker events - **Raydium AMM V4**: Raydium's Automated Market Maker V4 events @@ -129,30 +130,34 @@ Add the dependency to your `Cargo.toml`: ```toml # Add to your Cargo.toml -solana-streamer-sdk = { path = "./solana-streamer", version = "3.0.3" } +solana-streamer-sdk = { path = "./solana-streamer", version = "3.0.4" } ``` ### Use crates.io ```toml # Add to your Cargo.toml -solana-streamer-sdk = "3.0.3" +solana-streamer-sdk = "3.0.4" ``` Parser backend features: ```toml # Default: sol-parser-sdk parse-borsh backend -solana-streamer-sdk = "3.0.3" +solana-streamer-sdk = "3.0.4" # Zero-copy parser backend for latency-sensitive bots -solana-streamer-sdk = { version = "3.0.3", default-features = false, features = ["sdk-parse-zero-copy"] } +solana-streamer-sdk = { version = "3.0.4", default-features = false, features = ["sdk-parse-zero-copy"] } ``` If both `sdk-parse-borsh` and `sdk-parse-zero-copy` are enabled, `sol-parser-sdk 0.6.1+` uses the zero-copy backend. ## 🔄 Migration Guide +### Upgrading to v3.0.4 + +Version 3.0.4 uses `sol-parser-sdk 0.7.4`, adds the user-facing `Protocol::LaunchLab`, `Protocol::StonkFun`, `ProtocolType::LaunchLab`, and `ProtocolType::StonkFun` identifiers, and filters shared LaunchLab traffic by StonkFun's official platform configuration accounts. LaunchLab trade events now forward complete reserves, fee legs, pool status, and the current three appended accounts. `Protocol::RaydiumLaunchpad` remains a source-compatible alias and displays as `LaunchLab`. + ### Upgrading to v3.0.3 Version 3.0.3 uses `sol-parser-sdk 0.7.3` and synchronizes the current PumpFun, PumpSwap, and Pump Fees protocol schemas. PumpFun create/trade events and PumpSwap buy/sell/create-pool events now preserve creator-fee and holder-reward fields through the streamer bridge. PumpFun bonding-curve and PumpSwap pool account events also expose the new creator-fee editability and holder-reward state while retaining defaults for legacy accounts and JSON payloads. The parser rejects truncated current PumpSwap trade and CreatePool tails instead of returning partially populated events. @@ -211,7 +216,7 @@ Version 1.5.8 uses `sol-parser-sdk 0.5.8` from crates.io. It inherits the Pump.f ### Upgrading to v1.5.5 -Version 1.5.5 uses `sol-parser-sdk 0.5.5` from crates.io. The SDK now exposes Raydium LaunchLab as `RaydiumLaunchlab*`; streamer keeps the existing `Bonk*` event structs and `Protocol::Bonk` / `Protocol::RaydiumLaunchpad` aliases for source compatibility, while routing parser calls and upstream gRPC event filters to the new LaunchLab SDK variants. This release also syncs the CLMM/CPMM/Orca account bridges, Meteora DAMM v2 initialize-pool events, Meteora DBC events, and parser warmup on client creation. +Version 1.5.5 uses `sol-parser-sdk 0.5.5` from crates.io. The SDK exposes LaunchLab as `RaydiumLaunchlab*`; streamer keeps the existing `Bonk*` event structs and `Protocol::Bonk` / `Protocol::RaydiumLaunchpad` aliases for source compatibility, while routing parser calls and upstream gRPC event filters to the new LaunchLab SDK variants. This release also syncs the CLMM/CPMM/Orca account bridges, Meteora DAMM v2 initialize-pool events, Meteora DBC events, and parser warmup on client creation. ### Upgrading to v1.5.4 @@ -536,7 +541,8 @@ Note: Multiple subscription attempts on the same client return an error. - **PumpFun**: Primary meme coin trading platform - **Pump Fees**: Pump fee-sharing configuration events - **PumpSwap**: PumpFun's swap protocol -- **Raydium LaunchLab**: Token launch platform; `Bonk` and `RaydiumLaunchpad` are kept as compatibility aliases +- **LaunchLab**: Token launch platform; `Bonk` and `RaydiumLaunchpad` are kept as compatibility aliases +- **StonkFun**: StonkFun-attributed LaunchLab trade and pool-create events - **Raydium CPMM**: Raydium's Concentrated Pool Market Maker protocol - **Raydium CLMM**: Raydium's Concentrated Liquidity Market Maker protocol - **Raydium AMM V4**: Raydium's Automated Market Maker V4 protocol diff --git a/README_CN.md b/README_CN.md index fd8a91d..c29aabe 100644 --- a/README_CN.md +++ b/README_CN.md @@ -64,7 +64,7 @@ | 方向 | 覆盖范围 | |------|----------| | 输入来源 | Yellowstone gRPC、Jito ShredStream、已获取的 RPC 交易、编码交易数据 | -| DEX 协议 | PumpFun、PumpSwap、Pump Fees、Raydium LaunchLab、Raydium CPMM、Raydium CLMM、Raydium AMM V4、Meteora DAMM v2、Meteora DLMM、Meteora DBC、Orca Whirlpool | +| DEX 协议 | PumpFun、PumpSwap、Pump Fees、LaunchLab、StonkFun、Raydium CPMM、Raydium CLMM、Raydium AMM V4、Meteora DAMM v2、Meteora DLMM、Meteora DBC、Orca Whirlpool | | 使用场景 | 实时 DEX 事件流、代币发射监控、跟单交易、账户状态订阅、Bot 信号管道 | | 解析后端 | `sol-parser-sdk`,默认 Borsh 解析,并可为低延迟场景启用 zero-copy 后端 | @@ -81,7 +81,8 @@ - **PumpFun**: 迷因币交易平台事件 - **Pump Fees**: Pump 费用分成配置事件 - **PumpSwap**: PumpFun 的交换协议事件 -- **Raydium LaunchLab**: 代币发射平台事件;`Protocol::Bonk` 和 `Protocol::RaydiumLaunchpad` 仍作为兼容别名保留 +- **LaunchLab**: 通过 `Protocol::LaunchLab` 订阅共享代币发射程序事件;`Protocol::Bonk` 和 `Protocol::RaydiumLaunchpad` 仍作为兼容别名保留 +- **StonkFun**: 通过 `Protocol::StonkFun` 订阅归属于 StonkFun 的 LaunchLab 事件;事件 metadata 使用 `ProtocolType::StonkFun` - **Raydium CPMM**: Raydium 集中池做市商事件 - **Raydium CLMM**: Raydium 集中流动性做市商事件 - **Raydium AMM V4**: Raydium 自动做市商 V4 事件 @@ -128,30 +129,34 @@ git clone https://github.com/0xfnzero/solana-streamer ```toml # 添加到您的 Cargo.toml -solana-streamer-sdk = { path = "./solana-streamer", version = "3.0.3" } +solana-streamer-sdk = { path = "./solana-streamer", version = "3.0.4" } ``` ### 使用 crates.io ```toml # 添加到您的 Cargo.toml -solana-streamer-sdk = "3.0.3" +solana-streamer-sdk = "3.0.4" ``` 解析后端 feature: ```toml # 默认:sol-parser-sdk parse-borsh 后端 -solana-streamer-sdk = "3.0.3" +solana-streamer-sdk = "3.0.4" # 面向低延迟 Bot 的 zero-copy 解析后端 -solana-streamer-sdk = { version = "3.0.3", default-features = false, features = ["sdk-parse-zero-copy"] } +solana-streamer-sdk = { version = "3.0.4", default-features = false, features = ["sdk-parse-zero-copy"] } ``` 如果同时启用 `sdk-parse-borsh` 和 `sdk-parse-zero-copy`,`sol-parser-sdk 0.6.1+` 会优先使用 zero-copy 后端。 ## 🔄 迁移指南 +### 升级到 v3.0.4 + +v3.0.4 使用 `sol-parser-sdk 0.7.4`,新增面向用户的 `Protocol::LaunchLab`、`Protocol::StonkFun`、`ProtocolType::LaunchLab` 与 `ProtocolType::StonkFun` 标识,并根据 StonkFun 官方 platform config 过滤共享 LaunchLab 流量。LaunchLab 交易事件现在会完整转发储备量、手续费、池状态与当前新增的三个尾部账户。`Protocol::RaydiumLaunchpad` 继续作为源码兼容别名保留,其显示名称统一为 `LaunchLab`。 + ### 升级到 v3.0.3 v3.0.3 使用 `sol-parser-sdk 0.7.3`,同步当前 PumpFun、PumpSwap 和 Pump Fees 协议 schema。PumpFun create/trade 事件以及 PumpSwap buy/sell/create-pool 事件现在会通过 streamer bridge 完整保留 creator fee 与 holder reward 字段;PumpFun bonding curve 和 PumpSwap pool 账户事件也会暴露新的 creator fee 可编辑状态与 holder reward 状态,同时继续为旧账户布局和旧 JSON 数据提供默认值。解析器会拒绝截断的当前 PumpSwap trade 和 CreatePool 尾部,不再返回字段不完整的事件。 @@ -210,7 +215,7 @@ v1.5.8 使用 crates.io 上的 `sol-parser-sdk 0.5.8`。该版本继承 parser S ### 升级到 v1.5.5 -v1.5.5 使用 crates.io 上的 `sol-parser-sdk 0.5.5`。底层 SDK 已将 Raydium LaunchLab 事件统一暴露为 `RaydiumLaunchlab*`;streamer 仍保留现有 `Bonk*` 事件结构以及 `Protocol::Bonk` / `Protocol::RaydiumLaunchpad` 兼容别名,同时把解析调用和上游 gRPC 事件过滤映射到新的 LaunchLab SDK variant。该版本也同步了 CLMM/CPMM/Orca account bridge、Meteora DAMM v2 initialize-pool、Meteora DBC 事件,以及客户端创建时的 parser warmup。 +v1.5.5 使用 crates.io 上的 `sol-parser-sdk 0.5.5`。底层 SDK 已将 LaunchLab 事件统一暴露为 `RaydiumLaunchlab*`;streamer 仍保留现有 `Bonk*` 事件结构以及 `Protocol::Bonk` / `Protocol::RaydiumLaunchpad` 兼容别名,同时把解析调用和上游 gRPC 事件过滤映射到新的 LaunchLab SDK variant。该版本也同步了 CLMM/CPMM/Orca account bridge、Meteora DAMM v2 initialize-pool、Meteora DBC 事件,以及客户端创建时的 parser warmup。 ### 升级到 v1.5.4 @@ -515,7 +520,8 @@ grpc.update_subscription( - **PumpFun**: 主要迷因币交易平台 - **Pump Fees**: Pump 费用分成配置事件 - **PumpSwap**: PumpFun 的交换协议 -- **Raydium LaunchLab**: 代币发射平台;`Bonk` 和 `RaydiumLaunchpad` 作为兼容别名保留 +- **LaunchLab**: 代币发射平台;`Bonk` 和 `RaydiumLaunchpad` 作为兼容别名保留 +- **StonkFun**: 归属于 StonkFun 的 LaunchLab 交易和建池事件 - **Raydium CPMM**: Raydium 集中池做市商协议 - **Raydium CLMM**: Raydium 集中流动性做市商协议 - **Raydium AMM V4**: Raydium 自动做市商 V4 协议 diff --git a/src/streaming/event_parser/common/filter.rs b/src/streaming/event_parser/common/filter.rs index 32fcf38..0e06445 100644 --- a/src/streaming/event_parser/common/filter.rs +++ b/src/streaming/event_parser/common/filter.rs @@ -402,7 +402,10 @@ fn push_protocol_sdk_grpc_event_types(protocol: &Protocol, out: &mut Vec out.extend_from_slice(&[ + StProtocol::Bonk + | StProtocol::StonkFun + | StProtocol::LaunchLab + | StProtocol::RaydiumLaunchpad => out.extend_from_slice(&[ Sdk::RaydiumLaunchlabTrade, Sdk::RaydiumLaunchlabPoolCreate, Sdk::RaydiumLaunchlabMigrateAmm, diff --git a/src/streaming/event_parser/common/types.rs b/src/streaming/event_parser/common/types.rs index e5efe27..adb4bc0 100755 --- a/src/streaming/event_parser/common/types.rs +++ b/src/streaming/event_parser/common/types.rs @@ -45,6 +45,8 @@ pub enum ProtocolType { PumpSwap, PumpFun, Bonk, + StonkFun, + LaunchLab, RaydiumCpmm, RaydiumClmm, RaydiumAmmV4, diff --git a/src/streaming/event_parser/core/dispatcher.rs b/src/streaming/event_parser/core/dispatcher.rs index 8e29ac5..a32b0b4 100644 --- a/src/streaming/event_parser/core/dispatcher.rs +++ b/src/streaming/event_parser/core/dispatcher.rs @@ -69,7 +69,10 @@ impl EventDispatcher { pump_amm_inner::parse_pumpswap_inner_instruction(&disc, inner_instruction_data, pm) } Protocol::PumpFees => all_inner::pump_fees::parse(&disc, inner_instruction_data, pm), - Protocol::Bonk | Protocol::RaydiumLaunchpad => { + Protocol::Bonk + | Protocol::StonkFun + | Protocol::LaunchLab + | Protocol::RaydiumLaunchpad => { all_inner::raydium_launchlab::parse(&disc, inner_instruction_data, pm) } Protocol::RaydiumCpmm => { @@ -152,9 +155,10 @@ impl EventDispatcher { Protocol::PumpFun => program_ids::PUMPFUN_PROGRAM_ID, Protocol::PumpFees => program_ids::PUMP_FEES_PROGRAM_ID, Protocol::PumpSwap => program_ids::PUMPSWAP_PROGRAM_ID, - Protocol::Bonk | Protocol::RaydiumLaunchpad => { - program_ids::RAYDIUM_LAUNCHLAB_PROGRAM_ID - } + Protocol::Bonk + | Protocol::StonkFun + | Protocol::LaunchLab + | Protocol::RaydiumLaunchpad => program_ids::RAYDIUM_LAUNCHLAB_PROGRAM_ID, Protocol::RaydiumCpmm => program_ids::RAYDIUM_CPMM_PROGRAM_ID, Protocol::RaydiumClmm => program_ids::RAYDIUM_CLMM_PROGRAM_ID, Protocol::RaydiumAmmV4 => program_ids::RAYDIUM_AMM_V4_PROGRAM_ID, diff --git a/src/streaming/event_parser/protocols/bonk/events.rs b/src/streaming/event_parser/protocols/bonk/events.rs index 9abbba8..667758d 100755 --- a/src/streaming/event_parser/protocols/bonk/events.rs +++ b/src/streaming/event_parser/protocols/bonk/events.rs @@ -71,6 +71,23 @@ pub struct BonkTradeEvent { pub creator_associated_account: Pubkey, } +impl BonkTradeEvent { + #[inline] + pub fn stonkfun_mode(&self) -> Option { + sol_parser_sdk::core::events::stonkfun_mode_from_platform_config(self.platform_config) + } + + #[inline] + pub fn is_stonkfun(&self) -> bool { + self.stonkfun_mode().is_some() + } +} + +/// Preferred generic name for a trade emitted by the shared LaunchLab program. +pub type LaunchLabTradeEvent = BonkTradeEvent; +/// Preferred platform name when [`BonkTradeEvent::is_stonkfun`] is true. +pub type StonkFunTradeEvent = BonkTradeEvent; + pub const BONK_TRADE_EVENT_LOG_SIZE: usize = 32 + 8 * 13 + 1 + 1 + 1; /// Create pool event @@ -107,6 +124,23 @@ pub struct BonkPoolCreateEvent { pub quote_token_program: Pubkey, } +impl BonkPoolCreateEvent { + #[inline] + pub fn stonkfun_mode(&self) -> Option { + sol_parser_sdk::core::events::stonkfun_mode_from_platform_config(self.platform_config) + } + + #[inline] + pub fn is_stonkfun(&self) -> bool { + self.stonkfun_mode().is_some() + } +} + +/// Preferred generic name for a pool created by the shared LaunchLab program. +pub type LaunchLabPoolCreateEvent = BonkPoolCreateEvent; +/// Preferred platform name when [`BonkPoolCreateEvent::is_stonkfun`] is true. +pub type StonkFunPoolCreateEvent = BonkPoolCreateEvent; + pub const BONK_POOL_CREATE_EVENT_LOG_SIZE: usize = 256; /// Create pool event @@ -219,6 +253,18 @@ pub struct BonkMigrateToCpswapEvent { pub remaining_accounts: Vec, } +impl BonkMigrateToCpswapEvent { + #[inline] + pub fn stonkfun_mode(&self) -> Option { + sol_parser_sdk::core::events::stonkfun_mode_from_platform_config(self.platform_config) + } + + #[inline] + pub fn is_stonkfun(&self) -> bool { + self.stonkfun_mode().is_some() + } +} + /// 池状态 #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct BonkPoolStateAccountEvent { @@ -231,6 +277,20 @@ pub struct BonkPoolStateAccountEvent { pub pool_state: PoolState, } +impl BonkPoolStateAccountEvent { + #[inline] + pub fn stonkfun_mode(&self) -> Option { + sol_parser_sdk::core::events::stonkfun_mode_from_platform_config( + self.pool_state.platform_config, + ) + } + + #[inline] + pub fn is_stonkfun(&self) -> bool { + self.stonkfun_mode().is_some() + } +} + /// 全局配置 #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct BonkGlobalConfigAccountEvent { @@ -255,6 +315,18 @@ pub struct BonkPlatformConfigAccountEvent { pub platform_config: PlatformConfig, } +impl BonkPlatformConfigAccountEvent { + #[inline] + pub fn stonkfun_mode(&self) -> Option { + sol_parser_sdk::core::events::stonkfun_mode_from_platform_config(self.pubkey) + } + + #[inline] + pub fn is_stonkfun(&self) -> bool { + self.stonkfun_mode().is_some() + } +} + /// Event discriminator constants pub mod discriminators { // Event discriminators diff --git a/src/streaming/event_parser/protocols/types.rs b/src/streaming/event_parser/protocols/types.rs index b919dc5..319ae22 100755 --- a/src/streaming/event_parser/protocols/types.rs +++ b/src/streaming/event_parser/protocols/types.rs @@ -15,6 +15,11 @@ pub enum Protocol { PumpFees, /// Backward-compatible alias for Raydium Launchpad / LaunchLab. Bonk, + /// StonkFun-attributed pools on LaunchLab. + StonkFun, + /// All LaunchLab traffic, regardless of platform configuration. + LaunchLab, + /// Backward-compatible alias for [`Protocol::LaunchLab`]. RaydiumLaunchpad, RaydiumCpmm, RaydiumClmm, @@ -32,8 +37,10 @@ impl Protocol { Protocol::PumpSwap => vec![PUMPSWAP_PROGRAM_ID], Protocol::PumpFun => vec![PUMPFUN_PROGRAM_ID], Protocol::PumpFees => vec![PUMP_FEES_PROGRAM_ID], - Protocol::Bonk => vec![BONK_PROGRAM_ID], - Protocol::RaydiumLaunchpad => vec![BONK_PROGRAM_ID], + Protocol::Bonk + | Protocol::StonkFun + | Protocol::LaunchLab + | Protocol::RaydiumLaunchpad => vec![BONK_PROGRAM_ID], Protocol::RaydiumCpmm => vec![RAYDIUM_CPMM_PROGRAM_ID], Protocol::RaydiumClmm => vec![RAYDIUM_CLMM_PROGRAM_ID], Protocol::RaydiumAmmV4 => vec![RAYDIUM_AMM_V4_PROGRAM_ID], @@ -53,7 +60,9 @@ impl std::fmt::Display for Protocol { Protocol::PumpFun => write!(f, "PumpFun"), Protocol::PumpFees => write!(f, "PumpFees"), Protocol::Bonk => write!(f, "Bonk"), - Protocol::RaydiumLaunchpad => write!(f, "RaydiumLaunchpad"), + Protocol::StonkFun => write!(f, "StonkFun"), + Protocol::LaunchLab => write!(f, "LaunchLab"), + Protocol::RaydiumLaunchpad => write!(f, "LaunchLab"), Protocol::RaydiumCpmm => write!(f, "RaydiumCpmm"), Protocol::RaydiumClmm => write!(f, "RaydiumClmm"), Protocol::RaydiumAmmV4 => write!(f, "RaydiumAmmV4"), @@ -75,8 +84,11 @@ impl std::str::FromStr for Protocol { "pumpfun" => Ok(Protocol::PumpFun), "pumpfees" | "pump_fees" => Ok(Protocol::PumpFees), "bonk" => Ok(Protocol::Bonk), - "raydiumlaunchpad" | "raydium_launchpad" | "raydium_launchlab" | "launchpad" - | "launchlab" => Ok(Protocol::RaydiumLaunchpad), + "stonkfun" | "stonk_fun" | "stonk" => Ok(Protocol::StonkFun), + "launchlab" | "raydium_launchlab" => Ok(Protocol::LaunchLab), + "raydiumlaunchpad" | "raydium_launchpad" | "launchpad" => { + Ok(Protocol::RaydiumLaunchpad) + } "raydiumcpmm" | "raydium_cpmm" => Ok(Protocol::RaydiumCpmm), "raydiumclmm" | "raydium_clmm" => Ok(Protocol::RaydiumClmm), "raydiumammv4" | "raydium_amm_v4" => Ok(Protocol::RaydiumAmmV4), @@ -99,7 +111,8 @@ mod tests { fn parses_display_style_protocol_names() { for protocol in [ Protocol::PumpFees, - Protocol::RaydiumLaunchpad, + Protocol::StonkFun, + Protocol::LaunchLab, Protocol::RaydiumCpmm, Protocol::RaydiumClmm, Protocol::RaydiumAmmV4, @@ -119,6 +132,7 @@ mod tests { assert_eq!(Protocol::from_str("raydium_cpmm").unwrap(), Protocol::RaydiumCpmm); assert_eq!(Protocol::from_str("pump_fees").unwrap(), Protocol::PumpFees); assert_eq!(Protocol::from_str("raydium_launchpad").unwrap(), Protocol::RaydiumLaunchpad); + assert_eq!(Protocol::from_str("raydium_launchlab").unwrap(), Protocol::LaunchLab); assert_eq!(Protocol::from_str("raydium_clmm").unwrap(), Protocol::RaydiumClmm); assert_eq!(Protocol::from_str("raydium_amm_v4").unwrap(), Protocol::RaydiumAmmV4); assert_eq!(Protocol::from_str("meteora_damm_v2").unwrap(), Protocol::MeteoraDammV2); diff --git a/src/streaming/parser_sdk_bridge/bonk_accounts.rs b/src/streaming/parser_sdk_bridge/bonk_accounts.rs index 4c1c665..2aaaf39 100644 --- a/src/streaming/parser_sdk_bridge/bonk_accounts.rs +++ b/src/streaming/parser_sdk_bridge/bonk_accounts.rs @@ -14,7 +14,8 @@ use crate::streaming::event_parser::protocols::pumpswap::events::{ }; use crate::streaming::event_parser::protocols::pumpswap::types::{GlobalConfig, Pool}; use sol_parser_sdk::core::events::{ - RaydiumLaunchlabTradeEvent as PbBonkTrade, TradeDirection as PbBonkTradeDirection, + RaydiumLaunchlabPoolStatus as PbPoolStatus, RaydiumLaunchlabTradeEvent as PbBonkTrade, + TradeDirection as PbBonkTradeDirection, }; #[inline] pub(crate) fn pb_bonk_trade_direction(d: PbBonkTradeDirection) -> BonkTradeDirection { @@ -38,8 +39,6 @@ pub(crate) fn sdk_bonk_trade_event_type( } } -/// SDK Bonk trade events do not expose reserves or fee rates; keep those fields at streamer -/// defaults. pub(crate) fn bonk_trade_from_parser( b: sol_parser_sdk::core::events::RaydiumLaunchlabTradeEvent, meta: EventMetadata, @@ -47,21 +46,25 @@ pub(crate) fn bonk_trade_from_parser( BonkTradeEvent { metadata: meta, pool_state: b.pool_state, - total_base_sell: 0, - virtual_base: 0, - virtual_quote: 0, - real_base_before: 0, - real_quote_before: 0, - real_base_after: 0, - real_quote_after: 0, + total_base_sell: b.total_base_sell, + virtual_base: b.virtual_base, + virtual_quote: b.virtual_quote, + real_base_before: b.real_base_before, + real_quote_before: b.real_quote_before, + real_base_after: b.real_base_after, + real_quote_after: b.real_quote_after, amount_in: b.amount_in, amount_out: b.amount_out, - protocol_fee: 0, - platform_fee: 0, - creator_fee: 0, - share_fee: 0, + protocol_fee: b.protocol_fee, + platform_fee: b.platform_fee, + creator_fee: b.creator_fee, + share_fee: b.share_fee, trade_direction: pb_bonk_trade_direction(b.trade_direction), - pool_status: PoolStatus::Trade, + pool_status: match b.pool_status { + PbPoolStatus::Fund => PoolStatus::Fund, + PbPoolStatus::Migrate => PoolStatus::Migrate, + PbPoolStatus::Trade => PoolStatus::Trade, + }, exact_in: b.exact_in, payer: b.user, global_config: b.global_config, @@ -74,6 +77,9 @@ pub(crate) fn bonk_trade_from_parser( quote_token_mint: b.quote_mint, base_token_program: b.base_token_program, quote_token_program: b.quote_token_program, + system_program: b.system_program, + platform_associated_account: b.platform_associated_account, + creator_associated_account: b.creator_associated_account, ..Default::default() } } @@ -269,6 +275,7 @@ mod tests { quote_mint: keys[9], base_token_program: keys[10], quote_token_program: Pubkey::new_unique(), + ..Default::default() }; let quote_token_program = event.quote_token_program; diff --git a/src/streaming/parser_sdk_bridge/convert.rs b/src/streaming/parser_sdk_bridge/convert.rs index 69b8d1c..fffaa08 100644 --- a/src/streaming/parser_sdk_bridge/convert.rs +++ b/src/streaming/parser_sdk_bridge/convert.rs @@ -345,22 +345,20 @@ pub(crate) fn convert_parser_event( PbDexEvent::RaydiumLaunchlabTrade(b) => { let et = sdk_bonk_trade_event_type(&b); - let meta = adapt_pm( - b.metadata.clone(), - bt, - recv_wall_us, - ProtocolType::Bonk, - et, - bonk_program(), - ); + let protocol_type = + if b.is_stonkfun() { ProtocolType::StonkFun } else { ProtocolType::LaunchLab }; + let meta = + adapt_pm(b.metadata.clone(), bt, recv_wall_us, protocol_type, et, bonk_program()); Some(DexEvent::BonkTradeEvent(bonk_trade_from_parser(b, meta))) } PbDexEvent::RaydiumLaunchlabPoolCreate(p) => { + let protocol_type = + if p.is_stonkfun() { ProtocolType::StonkFun } else { ProtocolType::LaunchLab }; let meta = adapt_pm( p.metadata.clone(), bt, recv_wall_us, - ProtocolType::Bonk, + protocol_type, EventType::BonkInitialize, bonk_program(), ); @@ -371,7 +369,7 @@ pub(crate) fn convert_parser_event( m.metadata.clone(), bt, recv_wall_us, - ProtocolType::Bonk, + ProtocolType::LaunchLab, EventType::BonkMigrateToAmm, bonk_program(), ); diff --git a/src/streaming/parser_sdk_bridge/filter.rs b/src/streaming/parser_sdk_bridge/filter.rs index 5cb8016..56c36d8 100644 --- a/src/streaming/parser_sdk_bridge/filter.rs +++ b/src/streaming/parser_sdk_bridge/filter.rs @@ -78,7 +78,21 @@ fn protocol_matches_event(p: &Protocol, ev: &DexEvent) -> bool { | (Protocol::RaydiumLaunchpad, DexEvent::BonkMigrateToCpswapEvent(_)) | (Protocol::RaydiumLaunchpad, DexEvent::BonkPoolStateAccountEvent(_)) | (Protocol::RaydiumLaunchpad, DexEvent::BonkGlobalConfigAccountEvent(_)) - | (Protocol::RaydiumLaunchpad, DexEvent::BonkPlatformConfigAccountEvent(_)) => true, + | (Protocol::RaydiumLaunchpad, DexEvent::BonkPlatformConfigAccountEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkTradeEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkPoolCreateEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkMigrateToAmmEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkMigrateToCpswapEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkPoolStateAccountEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkGlobalConfigAccountEvent(_)) + | (Protocol::LaunchLab, DexEvent::BonkPlatformConfigAccountEvent(_)) => true, + (Protocol::StonkFun, DexEvent::BonkTradeEvent(event)) => event.is_stonkfun(), + (Protocol::StonkFun, DexEvent::BonkPoolCreateEvent(event)) => event.is_stonkfun(), + (Protocol::StonkFun, DexEvent::BonkMigrateToCpswapEvent(event)) => event.is_stonkfun(), + (Protocol::StonkFun, DexEvent::BonkPoolStateAccountEvent(event)) => event.is_stonkfun(), + (Protocol::StonkFun, DexEvent::BonkPlatformConfigAccountEvent(event)) => { + event.is_stonkfun() + } (Protocol::RaydiumCpmm, DexEvent::RaydiumCpmmSwapEvent(_)) | (Protocol::RaydiumCpmm, DexEvent::RaydiumCpmmDepositEvent(_)) | (Protocol::RaydiumCpmm, DexEvent::RaydiumCpmmWithdrawEvent(_)) diff --git a/src/streaming/parser_sdk_bridge/mod.rs b/src/streaming/parser_sdk_bridge/mod.rs index da09ff5..a51f516 100644 --- a/src/streaming/parser_sdk_bridge/mod.rs +++ b/src/streaming/parser_sdk_bridge/mod.rs @@ -39,6 +39,10 @@ mod tests { use crate::streaming::event_parser::common::filter::EventTypeFilter; use crate::streaming::event_parser::common::types::{EventType, ProtocolType}; use crate::streaming::event_parser::core::account_event_parser::TokenInfoEvent; + use crate::streaming::event_parser::protocols::bonk::{ + BonkMigrateToCpswapEvent, BonkPlatformConfigAccountEvent, BonkPoolStateAccountEvent, + PoolState, + }; use crate::streaming::event_parser::{DexEvent, Protocol}; use sol_parser_sdk::core::events::{ EventMetadata, MeteoraDammV2AddLiquidityEvent as PbDammAddLiquidity, @@ -49,7 +53,7 @@ mod tests { PumpSwapCreatePoolEvent as PbPumpSwapCreatePool, PumpSwapPool as PbPumpSwapPool, PumpSwapPoolAccountEvent as PbPumpSwapPoolAccount, PumpSwapSellEvent as PbPumpSwapSell, RaydiumLaunchlabTradeEvent as PbBonkTrade, TokenInfoEvent as PbTokenInfo, - TradeDirection as PbBonkDir, + TradeDirection as PbBonkDir, STONKFUN_REWARD_PLATFORM_CONFIG, }; use sol_parser_sdk::DexEvent as PbDexEvent; use solana_sdk::{pubkey::Pubkey, signature::Signature}; @@ -626,6 +630,56 @@ mod tests { assert!(!event_matches_protocol(&[Protocol::PumpFun], &dex)); } + #[test] + fn stonkfun_trade_is_attributed_and_filtered_separately_from_other_launchlab_events() { + let stonkfun = + PbBonkTrade { platform_config: STONKFUN_REWARD_PLATFORM_CONFIG, ..Default::default() }; + let dex = convert_parser_event(PbDexEvent::RaydiumLaunchlabTrade(stonkfun), None, 0) + .expect("convert StonkFun trade"); + + assert_eq!(dex.metadata().protocol, ProtocolType::StonkFun); + assert!(event_matches_protocol(&[Protocol::StonkFun], &dex)); + assert!(event_matches_protocol(&[Protocol::LaunchLab], &dex)); + + let other_launchlab = convert_parser_event( + PbDexEvent::RaydiumLaunchlabTrade(PbBonkTrade::default()), + None, + 0, + ) + .expect("convert generic LaunchLab trade"); + assert_eq!(other_launchlab.metadata().protocol, ProtocolType::LaunchLab); + assert!(!event_matches_protocol(&[Protocol::StonkFun], &other_launchlab)); + assert!(event_matches_protocol(&[Protocol::LaunchLab], &other_launchlab)); + } + + #[test] + fn stonkfun_filter_uses_platform_config_for_migration_and_account_events() { + let migration = DexEvent::BonkMigrateToCpswapEvent(BonkMigrateToCpswapEvent { + platform_config: STONKFUN_REWARD_PLATFORM_CONFIG, + ..Default::default() + }); + let pool = DexEvent::BonkPoolStateAccountEvent(BonkPoolStateAccountEvent { + pool_state: PoolState { + platform_config: STONKFUN_REWARD_PLATFORM_CONFIG, + ..Default::default() + }, + ..Default::default() + }); + let platform = DexEvent::BonkPlatformConfigAccountEvent(BonkPlatformConfigAccountEvent { + pubkey: STONKFUN_REWARD_PLATFORM_CONFIG, + ..Default::default() + }); + + for event in [migration, pool, platform] { + assert!(event_matches_protocol(&[Protocol::StonkFun], &event)); + assert!(event_matches_protocol(&[Protocol::LaunchLab], &event)); + } + + let other = DexEvent::BonkMigrateToCpswapEvent(BonkMigrateToCpswapEvent::default()); + assert!(!event_matches_protocol(&[Protocol::StonkFun], &other)); + assert!(event_matches_protocol(&[Protocol::LaunchLab], &other)); + } + #[test] fn converts_bonk_trade_maps_event_type_buy_exact_in() { let b = PbBonkTrade { @@ -647,6 +701,7 @@ mod tests { quote_mint: Pubkey::default(), base_token_program: Pubkey::default(), quote_token_program: Pubkey::default(), + ..Default::default() }; let dex = convert_parser_event(PbDexEvent::RaydiumLaunchlabTrade(b), None, 0).expect("convert"); @@ -679,6 +734,7 @@ mod tests { quote_mint: Pubkey::default(), base_token_program: Pubkey::default(), quote_token_program: Pubkey::default(), + ..Default::default() }; let dex = convert_parser_event(PbDexEvent::RaydiumLaunchlabTrade(b), None, 0).expect("convert");