feat: expose StonkFun and LaunchLab streaming

This commit is contained in:
0xfnzero
2026-09-14 17:43:40 +08:00
parent 52dabc6631
commit e491ba14c4
12 changed files with 238 additions and 56 deletions
+2 -2
View File
@@ -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 <byteblock6@gmail.com>", "sgxiang <sgxiang@gmail.com>", "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"] }
+14 -8
View File
@@ -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
+14 -8
View File
@@ -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 协议
+4 -1
View File
@@ -402,7 +402,10 @@ fn push_protocol_sdk_grpc_event_types(protocol: &Protocol, out: &mut Vec<SdkGrpc
Sdk::PumpSwapLiquidityAdded,
Sdk::PumpSwapLiquidityRemoved,
]),
StProtocol::Bonk | StProtocol::RaydiumLaunchpad => out.extend_from_slice(&[
StProtocol::Bonk
| StProtocol::StonkFun
| StProtocol::LaunchLab
| StProtocol::RaydiumLaunchpad => out.extend_from_slice(&[
Sdk::RaydiumLaunchlabTrade,
Sdk::RaydiumLaunchlabPoolCreate,
Sdk::RaydiumLaunchlabMigrateAmm,
@@ -45,6 +45,8 @@ pub enum ProtocolType {
PumpSwap,
PumpFun,
Bonk,
StonkFun,
LaunchLab,
RaydiumCpmm,
RaydiumClmm,
RaydiumAmmV4,
@@ -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,
@@ -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::StonkFunMode> {
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::StonkFunMode> {
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<Pubkey>,
}
impl BonkMigrateToCpswapEvent {
#[inline]
pub fn stonkfun_mode(&self) -> Option<sol_parser_sdk::core::events::StonkFunMode> {
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::StonkFunMode> {
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::StonkFunMode> {
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
+20 -6
View File
@@ -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);
@@ -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;
+8 -10
View File
@@ -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(),
);
+15 -1
View File
@@ -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(_))
+57 -1
View File
@@ -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");