Release v1.5.5 parser SDK sync

This commit is contained in:
0xfnzero
2026-06-01 20:20:01 +08:00
parent 5a282bd84d
commit 83c5476ff3
45 changed files with 979 additions and 211 deletions
+2 -3
View File
@@ -69,8 +69,7 @@ pub fn parse_grpc_transaction_events(
let recv_us = transaction_pretty.recv_us;
let grpc_tx = transaction_pretty.grpc_tx;
let block_time_us = block_time.map(|t| t.seconds * 1_000_000 + t.nanos as i64 / 1_000);
let update =
SubscribeUpdateTransaction { slot, transaction: Some(grpc_tx), ..Default::default() };
let update = SubscribeUpdateTransaction { slot, transaction: Some(grpc_tx) };
let sdk_parse_filter = build_sdk_parse_event_filter(event_type_filter);
let sdk_events = parse_subscribe_update_transaction_low_latency(
&update,
@@ -116,7 +115,7 @@ pub async fn process_grpc_transaction(
AccountParseResult::Event(mut event) => {
event.metadata_mut().handle_us = elapsed_micros_since(account_pretty.recv_us);
let processing_time_us = event.metadata().handle_us as f64;
callback(event);
callback(*event);
update_metrics(MetricsEventType::Account, 1, processing_time_us);
return Ok(());
}
+8 -2
View File
@@ -194,6 +194,12 @@ impl PerformanceMetrics {
}
}
impl Default for PerformanceMetrics {
fn default() -> Self {
Self::new()
}
}
/// High-performance metrics system
#[derive(Debug)]
pub struct HighPerformanceMetrics {
@@ -525,7 +531,7 @@ impl MetricsManager {
let new_count = GLOBAL_METRICS.dropped_events_count.fetch_add(1, Ordering::Relaxed) + 1;
// 每丢弃1000个事件记录一次警告日志
if new_count % 1000 == 0 {
if new_count.is_multiple_of(1000) {
log::debug!("Dropped events count reached: {}", new_count);
}
}
@@ -547,7 +553,7 @@ impl MetricsManager {
}
// 每丢弃1000个事件记录一次警告日志
if new_count % 1000 == 0 || (new_count / 1000) != ((new_count - count) / 1000) {
if new_count.is_multiple_of(1000) || (new_count / 1000) != ((new_count - count) / 1000) {
log::debug!("Dropped events count reached: {}", new_count);
}
}
+70 -36
View File
@@ -136,17 +136,18 @@ pub(crate) fn build_sdk_shred_parse_event_filter(
protocols: &[Protocol],
filter: Option<&EventTypeFilter>,
) -> Option<SdkGrpcEventTypeFilter> {
if protocols.is_empty() {
return build_sdk_parse_event_filter(filter);
}
if let Some(f) = filter.filter(|f| !f.include.is_empty()) {
if let Some(exact) = build_sdk_parse_event_filter(Some(f)) {
return Some(exact);
}
if !f.include_transaction_event() {
return Some(SdkGrpcEventTypeFilter::include_only(Vec::new()));
}
if protocols.is_empty() {
return build_sdk_parse_event_filter(Some(f));
}
if let Some(exact) = build_sdk_parse_event_filter(Some(f)) {
return Some(exact);
}
} else if protocols.is_empty() {
return build_sdk_parse_event_filter(filter);
}
let mut raw = Vec::with_capacity(protocols.len() * 8);
@@ -229,12 +230,12 @@ fn push_streamer_event_sdk_grpc_types(
St::PumpSwapDeposit => out.push(Sdk::PumpSwapLiquidityAdded),
St::PumpSwapWithdraw => out.push(Sdk::PumpSwapLiquidityRemoved),
St::BonkBuyExactIn | St::BonkBuyExactOut | St::BonkSellExactIn | St::BonkSellExactOut => {
out.push(Sdk::BonkTrade)
out.push(Sdk::RaydiumLaunchlabTrade)
}
St::BonkInitialize | St::BonkInitializeV2 | St::BonkInitializeWithToken2022 => {
out.push(Sdk::BonkPoolCreate)
out.push(Sdk::RaydiumLaunchlabPoolCreate)
}
St::BonkMigrateToAmm => out.push(Sdk::BonkMigrateAmm),
St::BonkMigrateToAmm => out.push(Sdk::RaydiumLaunchlabMigrateAmm),
St::RaydiumCpmmSwapBaseInput | St::RaydiumCpmmSwapBaseOutput => {
out.push(Sdk::RaydiumCpmmSwap)
}
@@ -278,8 +279,12 @@ fn push_streamer_event_sdk_grpc_types(
St::MeteoraDammV2Swap | St::MeteoraDammV2Swap2 => out.push(Sdk::MeteoraDammV2Swap),
St::MeteoraDammV2AddLiquidity => out.push(Sdk::MeteoraDammV2AddLiquidity),
St::MeteoraDammV2RemoveLiquidity => out.push(Sdk::MeteoraDammV2RemoveLiquidity),
St::MeteoraDammV2InitializePool => out.push(Sdk::MeteoraDammV2InitializePool),
St::MeteoraDammV2CreatePosition => out.push(Sdk::MeteoraDammV2CreatePosition),
St::MeteoraDammV2ClosePosition => out.push(Sdk::MeteoraDammV2ClosePosition),
St::MeteoraDbcSwap => out.push(Sdk::MeteoraDbcSwap),
St::MeteoraDbcInitializePool => out.push(Sdk::MeteoraDbcInitializePool),
St::MeteoraDbcCurveComplete => out.push(Sdk::MeteoraDbcCurveComplete),
St::MeteoraDlmmSwap => out.push(Sdk::MeteoraDlmmSwap),
St::MeteoraDlmmAddLiquidity => out.push(Sdk::MeteoraDlmmAddLiquidity),
St::MeteoraDlmmRemoveLiquidity => out.push(Sdk::MeteoraDlmmRemoveLiquidity),
@@ -302,6 +307,16 @@ fn push_streamer_event_sdk_grpc_types(
}
St::AccountPumpSwapGlobalConfig => out.push(Sdk::AccountPumpSwapGlobalConfig),
St::AccountPumpSwapPool => out.push(Sdk::AccountPumpSwapPool),
St::AccountRaydiumClmmAmmConfig => out.push(Sdk::AccountRaydiumClmmAmmConfig),
St::AccountRaydiumClmmPoolState => out.push(Sdk::AccountRaydiumClmmPoolState),
St::AccountRaydiumClmmTickArrayState => out.push(Sdk::AccountRaydiumClmmTickArrayState),
St::AccountRaydiumCpmmAmmConfig => out.push(Sdk::AccountRaydiumCpmmAmmConfig),
St::AccountRaydiumCpmmPoolState => out.push(Sdk::AccountRaydiumCpmmPoolState),
St::AccountOrcaWhirlpool => out.push(Sdk::AccountOrcaWhirlpool),
St::AccountOrcaPosition => out.push(Sdk::AccountOrcaPosition),
St::AccountOrcaTickArray => out.push(Sdk::AccountOrcaTickArray),
St::AccountOrcaFeeTier => out.push(Sdk::AccountOrcaFeeTier),
St::AccountOrcaWhirlpoolsConfig => out.push(Sdk::AccountOrcaWhirlpoolsConfig),
_ => return false,
}
true
@@ -351,9 +366,11 @@ 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(&[Sdk::BonkTrade, Sdk::BonkPoolCreate, Sdk::BonkMigrateAmm])
}
StProtocol::Bonk | StProtocol::RaydiumLaunchpad => out.extend_from_slice(&[
Sdk::RaydiumLaunchlabTrade,
Sdk::RaydiumLaunchlabPoolCreate,
Sdk::RaydiumLaunchlabMigrateAmm,
]),
StProtocol::RaydiumCpmm => out.extend_from_slice(&[
Sdk::RaydiumCpmmSwap,
Sdk::RaydiumCpmmDeposit,
@@ -390,9 +407,15 @@ fn push_protocol_sdk_grpc_event_types(protocol: &Protocol, out: &mut Vec<SdkGrpc
Sdk::MeteoraDammV2Swap,
Sdk::MeteoraDammV2AddLiquidity,
Sdk::MeteoraDammV2RemoveLiquidity,
Sdk::MeteoraDammV2InitializePool,
Sdk::MeteoraDammV2CreatePosition,
Sdk::MeteoraDammV2ClosePosition,
]),
StProtocol::MeteoraDbc => out.extend_from_slice(&[
Sdk::MeteoraDbcSwap,
Sdk::MeteoraDbcInitializePool,
Sdk::MeteoraDbcCurveComplete,
]),
StProtocol::OrcaWhirlpool => out.extend_from_slice(&[
Sdk::OrcaWhirlpoolSwap,
Sdk::OrcaWhirlpoolLiquidityIncreased,
@@ -499,11 +522,7 @@ mod tests {
#[test]
fn exclude_blocks_even_when_include_empty() {
let f = EventTypeFilter {
include: vec![],
exclude: vec![EventType::PumpFunSell],
..Default::default()
};
let f = EventTypeFilter { include: vec![], exclude: vec![EventType::PumpFunSell] };
let ev = DexEvent::ParserSdkErrorEvent(ParserSdkErrorEvent {
metadata: mk_meta(EventType::PumpFunSell),
message: "x".into(),
@@ -528,7 +547,6 @@ mod tests {
let f = EventTypeFilter {
include: vec![EventType::PumpFunBuy, EventType::PumpFunSell],
exclude: vec![EventType::PumpFunSell],
..Default::default()
};
let buy = DexEvent::ParserSdkErrorEvent(ParserSdkErrorEvent {
metadata: mk_meta(EventType::PumpFunBuy),
@@ -544,11 +562,7 @@ mod tests {
#[test]
fn build_sdk_filter_exclude_only_pumpfun_sell() {
let f = EventTypeFilter {
include: vec![],
exclude: vec![EventType::PumpFunSell],
..Default::default()
};
let f = EventTypeFilter { include: vec![], exclude: vec![EventType::PumpFunSell] };
let sdk_f = build_sdk_parse_event_filter(Some(&f)).expect("mapped");
assert!(sdk_f.should_include(SdkGrpcEventType::PumpFunBuy));
assert!(!sdk_f.should_include(SdkGrpcEventType::PumpFunSell));
@@ -725,8 +739,12 @@ mod tests {
EventType::MeteoraDammV2Swap2,
EventType::MeteoraDammV2AddLiquidity,
EventType::MeteoraDammV2RemoveLiquidity,
EventType::MeteoraDammV2InitializePool,
EventType::MeteoraDammV2CreatePosition,
EventType::MeteoraDammV2ClosePosition,
EventType::MeteoraDbcSwap,
EventType::MeteoraDbcInitializePool,
EventType::MeteoraDbcCurveComplete,
EventType::MeteoraDlmmSwap,
EventType::MeteoraDlmmAddLiquidity,
EventType::MeteoraDlmmRemoveLiquidity,
@@ -746,6 +764,16 @@ mod tests {
EventType::AccountPumpFunUserVolumeAccumulator,
EventType::AccountPumpSwapGlobalConfig,
EventType::AccountPumpSwapPool,
EventType::AccountRaydiumClmmAmmConfig,
EventType::AccountRaydiumClmmPoolState,
EventType::AccountRaydiumClmmTickArrayState,
EventType::AccountRaydiumCpmmAmmConfig,
EventType::AccountRaydiumCpmmPoolState,
EventType::AccountOrcaWhirlpool,
EventType::AccountOrcaPosition,
EventType::AccountOrcaTickArray,
EventType::AccountOrcaFeeTier,
EventType::AccountOrcaWhirlpoolsConfig,
];
for event_type in sdk_filter_backed {
@@ -760,7 +788,10 @@ mod tests {
#[test]
fn build_sdk_filter_none_when_public_sdk_filter_enum_cannot_express_requested_type() {
let f = EventTypeFilter {
include: vec![EventType::PumpFunBuy, EventType::MeteoraDammV2InitializePool],
include: vec![
EventType::PumpFunBuy,
EventType::MeteoraDammV2InitializeCustomizablePool,
],
..Default::default()
};
assert!(build_sdk_parse_event_filter(Some(&f)).is_none());
@@ -769,7 +800,7 @@ mod tests {
#[test]
fn build_sdk_shred_filter_falls_back_to_protocol_group_for_sdk_enum_gap() {
let f = EventTypeFilter {
include: vec![EventType::MeteoraDammV2InitializePool],
include: vec![EventType::MeteoraDammV2InitializeCustomizablePool],
..Default::default()
};
let sdk_f =
@@ -792,12 +823,20 @@ mod tests {
}
#[test]
fn build_sdk_filter_exclude_only_orca_maps_upstream() {
fn build_sdk_shred_filter_skips_transaction_parse_for_account_only_without_protocols() {
let f = EventTypeFilter {
include: vec![],
exclude: vec![EventType::OrcaWhirlpoolSwap],
include: vec![EventType::AccountRaydiumClmmPoolState],
..Default::default()
};
let sdk_f = build_sdk_shred_parse_event_filter(&[], Some(&f)).unwrap();
assert!(!sdk_f.should_include(SdkGrpcEventType::RaydiumClmmSwap));
assert!(!sdk_f.should_include(SdkGrpcEventType::PumpFunBuy));
}
#[test]
fn build_sdk_filter_exclude_only_orca_maps_upstream() {
let f = EventTypeFilter { include: vec![], exclude: vec![EventType::OrcaWhirlpoolSwap] };
let sdk_f = build_sdk_parse_event_filter(Some(&f)).expect("mapped");
assert!(!sdk_f.should_include(SdkGrpcEventType::OrcaWhirlpoolSwap));
assert!(sdk_f.should_include(SdkGrpcEventType::PumpFunBuy));
@@ -807,19 +846,14 @@ mod tests {
fn build_sdk_filter_exclude_only_none_when_only_sdk_filter_enum_gap() {
let f = EventTypeFilter {
include: vec![],
exclude: vec![EventType::MeteoraDammV2InitializePool],
..Default::default()
exclude: vec![EventType::MeteoraDammV2InitializeCustomizablePool],
};
assert!(build_sdk_parse_event_filter(Some(&f)).is_none());
}
#[test]
fn build_sdk_filter_exclude_only_none_when_only_unmapped_types() {
let f = EventTypeFilter {
include: vec![],
exclude: vec![EventType::SetComputeUnitLimit],
..Default::default()
};
let f = EventTypeFilter { include: vec![], exclude: vec![EventType::SetComputeUnitLimit] };
assert!(build_sdk_parse_event_filter(Some(&f)).is_none());
}
}
@@ -49,6 +49,7 @@ pub enum ProtocolType {
RaydiumClmm,
RaydiumAmmV4,
MeteoraDammV2,
MeteoraDbc,
OrcaWhirlpool,
MeteoraPools,
MeteoraDlmm,
@@ -153,6 +154,11 @@ pub enum EventType {
MeteoraDammV2AddLiquidity,
MeteoraDammV2RemoveLiquidity,
// Meteora DBC
MeteoraDbcSwap,
MeteoraDbcInitializePool,
MeteoraDbcCurveComplete,
// Orca Whirlpool
OrcaWhirlpoolSwap,
OrcaWhirlpoolLiquidityIncreased,
@@ -196,6 +202,11 @@ pub enum EventType {
AccountRaydiumClmmTickArrayState,
AccountRaydiumCpmmAmmConfig,
AccountRaydiumCpmmPoolState,
AccountOrcaWhirlpool,
AccountOrcaPosition,
AccountOrcaTickArray,
AccountOrcaFeeTier,
AccountOrcaWhirlpoolsConfig,
NonceAccount,
TokenAccount,
@@ -228,6 +239,11 @@ pub const ACCOUNT_EVENT_TYPES: &[EventType] = &[
EventType::AccountRaydiumClmmTickArrayState,
EventType::AccountRaydiumCpmmAmmConfig,
EventType::AccountRaydiumCpmmPoolState,
EventType::AccountOrcaWhirlpool,
EventType::AccountOrcaPosition,
EventType::AccountOrcaTickArray,
EventType::AccountOrcaFeeTier,
EventType::AccountOrcaWhirlpoolsConfig,
EventType::TokenAccount,
EventType::TokenInfo,
EventType::NonceAccount,
+10 -3
View File
@@ -70,7 +70,7 @@ impl EventDispatcher {
}
Protocol::PumpFees => all_inner::pump_fees::parse(&disc, inner_instruction_data, pm),
Protocol::Bonk | Protocol::RaydiumLaunchpad => {
all_inner::bonk::parse(&disc, inner_instruction_data, pm)
all_inner::raydium_launchlab::parse(&disc, inner_instruction_data, pm)
}
Protocol::RaydiumCpmm => {
all_inner::raydium_cpmm::parse(&disc, inner_instruction_data, pm)
@@ -86,6 +86,8 @@ impl EventDispatcher {
Protocol::MeteoraDammV2 => {
all_inner::meteora_damm::parse(&disc, inner_instruction_data, pm)
}
// Meteora DBC is currently log-side in sol-parser-sdk; direct inner dispatch is absent.
Protocol::MeteoraDbc => None,
Protocol::OrcaWhirlpool => all_inner::orca::parse(&disc, inner_instruction_data, pm),
Protocol::MeteoraPools => {
all_inner::meteora_amm::parse(&disc, inner_instruction_data, pm)
@@ -108,7 +110,7 @@ impl EventDispatcher {
Some(Protocol::PumpFees)
} else if program_id == &program_ids::PUMPSWAP_PROGRAM_ID {
Some(Protocol::PumpSwap)
} else if program_id == &program_ids::BONK_PROGRAM_ID {
} else if program_id == &program_ids::RAYDIUM_LAUNCHLAB_PROGRAM_ID {
Some(Protocol::Bonk)
} else if program_id == &program_ids::RAYDIUM_CPMM_PROGRAM_ID {
Some(Protocol::RaydiumCpmm)
@@ -118,6 +120,8 @@ impl EventDispatcher {
Some(Protocol::RaydiumAmmV4)
} else if program_id == &program_ids::METEORA_DAMM_V2_PROGRAM_ID {
Some(Protocol::MeteoraDammV2)
} else if program_id == &program_ids::METEORA_DBC_PROGRAM_ID {
Some(Protocol::MeteoraDbc)
} else if program_id == &program_ids::ORCA_WHIRLPOOL_PROGRAM_ID {
Some(Protocol::OrcaWhirlpool)
} else if program_id == &program_ids::METEORA_POOLS_PROGRAM_ID {
@@ -148,11 +152,14 @@ 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::BONK_PROGRAM_ID,
Protocol::Bonk | 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,
Protocol::MeteoraDammV2 => program_ids::METEORA_DAMM_V2_PROGRAM_ID,
Protocol::MeteoraDbc => program_ids::METEORA_DBC_PROGRAM_ID,
Protocol::OrcaWhirlpool => program_ids::ORCA_WHIRLPOOL_PROGRAM_ID,
Protocol::MeteoraPools => program_ids::METEORA_POOLS_PROGRAM_ID,
Protocol::MeteoraDlmm => program_ids::METEORA_DLMM_PROGRAM_ID,
@@ -9,6 +9,7 @@ pub(crate) mod helpers;
pub struct EventParser;
impl EventParser {
#[allow(clippy::too_many_arguments)]
pub async fn parse_grpc_transaction(
protocols: &[crate::streaming::event_parser::Protocol],
event_type_filter: Option<&crate::streaming::event_parser::common::filter::EventTypeFilter>,
@@ -32,7 +33,6 @@ impl EventParser {
let update = yellowstone_grpc_proto::geyser::SubscribeUpdateTransaction {
slot: slot.unwrap_or(0),
transaction: Some(grpc_tx),
..Default::default()
};
let sdk_parse_filter =
crate::streaming::event_parser::common::filter::build_sdk_parse_event_filter(
@@ -1,3 +1,5 @@
#![allow(clippy::single_match)]
use crate::streaming::event_parser::DexEvent;
use solana_sdk::{pubkey, pubkey::Pubkey};
+26 -7
View File
@@ -14,14 +14,16 @@ use crate::streaming::event_parser::protocols::raydium_amm_v4::events::*;
use crate::streaming::event_parser::protocols::raydium_clmm::events::*;
use crate::streaming::event_parser::protocols::raydium_cpmm::events::*;
use crate::streaming::event_parser::protocols::sol_parser_forward::events::{
MeteoraDbcCurveCompleteEvent, MeteoraDbcInitializePoolEvent, MeteoraDbcSwapEvent,
MeteoraDlmmAddLiquidityEvent, MeteoraDlmmClaimFeeEvent, MeteoraDlmmClosePositionEvent,
MeteoraDlmmCreatePositionEvent, MeteoraDlmmInitializeBinArrayEvent,
MeteoraDlmmInitializePoolEvent, MeteoraDlmmRemoveLiquidityEvent, MeteoraDlmmSwapEvent,
MeteoraPoolsAddLiquidityEvent, MeteoraPoolsBootstrapLiquidityEvent,
MeteoraPoolsPoolCreatedEvent, MeteoraPoolsRemoveLiquidityEvent, MeteoraPoolsSetPoolFeesEvent,
MeteoraPoolsSwapEvent, OrcaWhirlpoolLiquidityDecreasedEvent,
MeteoraPoolsSwapEvent, OrcaFeeTierAccountEvent, OrcaPositionAccountEvent,
OrcaTickArrayAccountEvent, OrcaWhirlpoolAccountEvent, OrcaWhirlpoolLiquidityDecreasedEvent,
OrcaWhirlpoolLiquidityIncreasedEvent, OrcaWhirlpoolPoolInitializedEvent,
OrcaWhirlpoolSwapEvent, ParserSdkErrorEvent,
OrcaWhirlpoolSwapEvent, OrcaWhirlpoolsConfigAccountEvent, ParserSdkErrorEvent,
};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
@@ -96,17 +98,17 @@ pub enum DexEvent {
RaydiumClmmCreatePoolEvent(RaydiumClmmCreatePoolEvent),
RaydiumClmmOpenPositionWithToken22NftEvent(RaydiumClmmOpenPositionWithToken22NftEvent),
RaydiumClmmOpenPositionV2Event(RaydiumClmmOpenPositionV2Event),
RaydiumClmmAmmConfigAccountEvent(RaydiumClmmAmmConfigAccountEvent),
RaydiumClmmPoolStateAccountEvent(RaydiumClmmPoolStateAccountEvent),
RaydiumClmmTickArrayStateAccountEvent(RaydiumClmmTickArrayStateAccountEvent),
RaydiumClmmAmmConfigAccountEvent(Box<RaydiumClmmAmmConfigAccountEvent>),
RaydiumClmmPoolStateAccountEvent(Box<RaydiumClmmPoolStateAccountEvent>),
RaydiumClmmTickArrayStateAccountEvent(Box<RaydiumClmmTickArrayStateAccountEvent>),
// Raydium CPMM events
RaydiumCpmmSwapEvent(RaydiumCpmmSwapEvent),
RaydiumCpmmDepositEvent(RaydiumCpmmDepositEvent),
RaydiumCpmmWithdrawEvent(RaydiumCpmmWithdrawEvent),
RaydiumCpmmInitializeEvent(RaydiumCpmmInitializeEvent),
RaydiumCpmmAmmConfigAccountEvent(RaydiumCpmmAmmConfigAccountEvent),
RaydiumCpmmPoolStateAccountEvent(RaydiumCpmmPoolStateAccountEvent),
RaydiumCpmmAmmConfigAccountEvent(Box<RaydiumCpmmAmmConfigAccountEvent>),
RaydiumCpmmPoolStateAccountEvent(Box<RaydiumCpmmPoolStateAccountEvent>),
// Meteora DAMM v2 events
MeteoraDammV2SwapEvent(MeteoraDammV2SwapEvent),
@@ -122,10 +124,19 @@ pub enum DexEvent {
MeteoraDammV2CreatePositionEvent(MeteoraDammV2CreatePositionEvent),
MeteoraDammV2ClosePositionEvent(MeteoraDammV2ClosePositionEvent),
MeteoraDbcSwapEvent(MeteoraDbcSwapEvent),
MeteoraDbcInitializePoolEvent(MeteoraDbcInitializePoolEvent),
MeteoraDbcCurveCompleteEvent(MeteoraDbcCurveCompleteEvent),
OrcaWhirlpoolSwapEvent(OrcaWhirlpoolSwapEvent),
OrcaWhirlpoolLiquidityIncreasedEvent(OrcaWhirlpoolLiquidityIncreasedEvent),
OrcaWhirlpoolLiquidityDecreasedEvent(OrcaWhirlpoolLiquidityDecreasedEvent),
OrcaWhirlpoolPoolInitializedEvent(OrcaWhirlpoolPoolInitializedEvent),
OrcaWhirlpoolAccountEvent(Box<OrcaWhirlpoolAccountEvent>),
OrcaPositionAccountEvent(Box<OrcaPositionAccountEvent>),
OrcaTickArrayAccountEvent(Box<OrcaTickArrayAccountEvent>),
OrcaFeeTierAccountEvent(Box<OrcaFeeTierAccountEvent>),
OrcaWhirlpoolsConfigAccountEvent(Box<OrcaWhirlpoolsConfigAccountEvent>),
MeteoraPoolsSwapEvent(MeteoraPoolsSwapEvent),
MeteoraPoolsAddLiquidityEvent(MeteoraPoolsAddLiquidityEvent),
@@ -256,10 +267,18 @@ impl_dex_event_metadata!(
MeteoraDammV2RemoveLiquidityEvent,
MeteoraDammV2CreatePositionEvent,
MeteoraDammV2ClosePositionEvent,
MeteoraDbcSwapEvent,
MeteoraDbcInitializePoolEvent,
MeteoraDbcCurveCompleteEvent,
OrcaWhirlpoolSwapEvent,
OrcaWhirlpoolLiquidityIncreasedEvent,
OrcaWhirlpoolLiquidityDecreasedEvent,
OrcaWhirlpoolPoolInitializedEvent,
OrcaWhirlpoolAccountEvent,
OrcaPositionAccountEvent,
OrcaTickArrayAccountEvent,
OrcaFeeTierAccountEvent,
OrcaWhirlpoolsConfigAccountEvent,
MeteoraPoolsSwapEvent,
MeteoraPoolsAddLiquidityEvent,
MeteoraPoolsRemoveLiquidityEvent,
@@ -3,7 +3,7 @@ use crate::streaming::event_parser::{
};
use solana_sdk::pubkey::Pubkey;
pub use sol_parser_sdk::instr::program_ids::BONK_PROGRAM_ID;
pub use sol_parser_sdk::instr::program_ids::RAYDIUM_LAUNCHLAB_PROGRAM_ID as BONK_PROGRAM_ID;
pub fn parse_bonk_instruction_data(
discriminator: &[u8],
@@ -32,32 +32,22 @@ pub struct VestingParams {
pub unlock_period: u64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub enum AmmFeeOn {
#[default]
QuoteToken,
BothToken,
}
impl Default for AmmFeeOn {
fn default() -> Self {
Self::QuoteToken
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
#[borsh(use_discriminant = true)]
#[repr(u8)]
pub enum AmmCreatorFeeOn {
#[default]
QuoteToken = 0,
BothToken = 1,
}
impl Default for AmmCreatorFeeOn {
fn default() -> Self {
Self::QuoteToken
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct ConstantCurve {
pub supply: u64,
@@ -170,7 +160,7 @@ impl Default for PoolState {
}
}
pub const POOL_STATE_SIZE: usize = 8 + 1 * 5 + 8 * 10 + 32 * 7 + 8 * 8 + 8 * 5 + 1 + 1 + 8 + 54;
pub const POOL_STATE_SIZE: usize = 8 + 5 + 8 * 10 + 32 * 7 + 8 * 8 + 8 * 5 + 1 + 1 + 8 + 54;
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct GlobalConfig {
pub epoch: u64,
@@ -168,10 +168,10 @@ pub mod discriminators {
// 指令鉴别器
pub const SWAP_BASE_IN: &[u8] = &[9];
pub const SWAP_BASE_OUT: &[u8] = &[11];
pub const DEPOSIT: &[u8] = &[03];
pub const INITIALIZE2: &[u8] = &[01];
pub const WITHDRAW: &[u8] = &[04];
pub const WITHDRAW_PNL: &[u8] = &[07];
pub const DEPOSIT: &[u8] = &[3];
pub const INITIALIZE2: &[u8] = &[1];
pub const WITHDRAW: &[u8] = &[4];
pub const WITHDRAW_PNL: &[u8] = &[7];
/// 池信息鉴别器
pub const AMM_INFO: &[u8] = &[6];
@@ -105,7 +105,7 @@ pub struct PoolState {
pub const POOL_STATE_SIZE: usize = 1536;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct TickState {
pub tick: i32,
pub liquidity_net: i128,
@@ -120,24 +120,6 @@ pub struct TickState {
pub padding: [u32; 3],
}
impl Default for TickState {
fn default() -> Self {
Self {
tick: 0,
liquidity_net: 0,
liquidity_gross: 0,
fee_growth_outside0_x64: 0,
fee_growth_outside1_x64: 0,
reward_growths_outside_x64: [0; 3],
order_phase: 0,
orders_amount: 0,
part_filled_orders_remaining: 0,
unfilled_ratio_x64: 0,
padding: [0; 3],
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct TickArrayState {
pub pool_id: Pubkey,
@@ -69,6 +69,185 @@ pub struct OrcaWhirlpoolPoolInitializedEvent {
pub initial_sqrt_price: u128,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaWhirlpoolAccountEvent {
pub metadata: EventMetadata,
pub pubkey: Pubkey,
pub executable: bool,
pub lamports: u64,
pub owner: Pubkey,
pub rent_epoch: u64,
pub whirlpool: OrcaWhirlpoolAccount,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaWhirlpoolAccount {
pub whirlpools_config: Pubkey,
pub whirlpool_bump: u8,
pub tick_spacing: u16,
pub tick_spacing_seed: [u8; 2],
pub fee_rate: u16,
pub protocol_fee_rate: u16,
pub liquidity: u128,
pub sqrt_price: u128,
pub tick_current_index: i32,
pub protocol_fee_owed_a: u64,
pub protocol_fee_owed_b: u64,
pub token_mint_a: Pubkey,
pub token_vault_a: Pubkey,
pub fee_growth_global_a: u128,
pub token_mint_b: Pubkey,
pub token_vault_b: Pubkey,
pub fee_growth_global_b: u128,
pub reward_last_updated_timestamp: u64,
pub reward_infos: [OrcaWhirlpoolRewardInfo; 3],
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaWhirlpoolRewardInfo {
pub mint: Pubkey,
pub vault: Pubkey,
pub authority: Pubkey,
pub emissions_per_second_x64: u128,
pub growth_global_x64: u128,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaPositionAccountEvent {
pub metadata: EventMetadata,
pub pubkey: Pubkey,
pub executable: bool,
pub lamports: u64,
pub owner: Pubkey,
pub rent_epoch: u64,
pub position: OrcaPositionAccount,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaPositionAccount {
pub whirlpool: Pubkey,
pub position_mint: Pubkey,
pub liquidity: u128,
pub tick_lower_index: i32,
pub tick_upper_index: i32,
pub fee_growth_checkpoint_a: u128,
pub fee_owed_a: u64,
pub fee_growth_checkpoint_b: u128,
pub fee_owed_b: u64,
pub reward_infos: [OrcaPositionRewardInfo; 3],
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaPositionRewardInfo {
pub growth_inside_checkpoint: u128,
pub amount_owed: u64,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaTickArrayAccountEvent {
pub metadata: EventMetadata,
pub pubkey: Pubkey,
pub executable: bool,
pub lamports: u64,
pub owner: Pubkey,
pub rent_epoch: u64,
pub tick_array: OrcaTickArrayAccount,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaTickArrayAccount {
pub start_tick_index: i32,
pub ticks: Vec<OrcaTick>,
pub whirlpool: Pubkey,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaTick {
pub initialized: bool,
pub liquidity_net: i128,
pub liquidity_gross: u128,
pub fee_growth_outside_a: u128,
pub fee_growth_outside_b: u128,
pub reward_growths_outside: [u128; 3],
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaFeeTierAccountEvent {
pub metadata: EventMetadata,
pub pubkey: Pubkey,
pub executable: bool,
pub lamports: u64,
pub owner: Pubkey,
pub rent_epoch: u64,
pub fee_tier: OrcaFeeTierAccount,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaFeeTierAccount {
pub whirlpools_config: Pubkey,
pub tick_spacing: u16,
pub default_fee_rate: u16,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaWhirlpoolsConfigAccountEvent {
pub metadata: EventMetadata,
pub pubkey: Pubkey,
pub executable: bool,
pub lamports: u64,
pub owner: Pubkey,
pub rent_epoch: u64,
pub config: OrcaWhirlpoolsConfigAccount,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrcaWhirlpoolsConfigAccount {
pub fee_authority: Pubkey,
pub collect_protocol_fees_authority: Pubkey,
pub reward_emissions_super_authority: Pubkey,
pub default_protocol_fee_rate: u16,
}
// --- Meteora DBC ---
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct MeteoraDbcSwapEvent {
pub metadata: EventMetadata,
pub pool: Pubkey,
pub config: Pubkey,
pub trade_direction: u8,
pub has_referral: bool,
pub amount_in: u64,
pub minimum_amount_out: u64,
pub actual_input_amount: u64,
pub output_amount: u64,
pub next_sqrt_price: u128,
pub trading_fee: u64,
pub protocol_fee: u64,
pub referral_fee: u64,
pub current_timestamp: u64,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct MeteoraDbcInitializePoolEvent {
pub metadata: EventMetadata,
pub pool: Pubkey,
pub config: Pubkey,
pub creator: Pubkey,
pub base_mint: Pubkey,
pub pool_type: u8,
pub activation_point: u64,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct MeteoraDbcCurveCompleteEvent {
pub metadata: EventMetadata,
pub pool: Pubkey,
pub config: Pubkey,
pub base_reserve: u64,
pub quote_reserve: u64,
}
// --- Meteora Pools ---
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
+10 -3
View File
@@ -1,8 +1,9 @@
use anyhow::{anyhow, Result};
use sol_parser_sdk::instr::program_ids::{
BONK_PROGRAM_ID, METEORA_DAMM_V2_PROGRAM_ID, METEORA_DLMM_PROGRAM_ID, METEORA_POOLS_PROGRAM_ID,
ORCA_WHIRLPOOL_PROGRAM_ID, PUMPFUN_PROGRAM_ID, PUMPSWAP_PROGRAM_ID, PUMP_FEES_PROGRAM_ID,
RAYDIUM_AMM_V4_PROGRAM_ID, RAYDIUM_CLMM_PROGRAM_ID, RAYDIUM_CPMM_PROGRAM_ID,
METEORA_DAMM_V2_PROGRAM_ID, METEORA_DBC_PROGRAM_ID, METEORA_DLMM_PROGRAM_ID,
METEORA_POOLS_PROGRAM_ID, ORCA_WHIRLPOOL_PROGRAM_ID, PUMPFUN_PROGRAM_ID, PUMPSWAP_PROGRAM_ID,
PUMP_FEES_PROGRAM_ID, RAYDIUM_AMM_V4_PROGRAM_ID, RAYDIUM_CLMM_PROGRAM_ID,
RAYDIUM_CPMM_PROGRAM_ID, RAYDIUM_LAUNCHLAB_PROGRAM_ID as BONK_PROGRAM_ID,
};
use solana_sdk::pubkey::Pubkey;
@@ -19,6 +20,7 @@ pub enum Protocol {
RaydiumClmm,
RaydiumAmmV4,
MeteoraDammV2,
MeteoraDbc,
OrcaWhirlpool,
MeteoraPools,
MeteoraDlmm,
@@ -36,6 +38,7 @@ impl Protocol {
Protocol::RaydiumClmm => vec![RAYDIUM_CLMM_PROGRAM_ID],
Protocol::RaydiumAmmV4 => vec![RAYDIUM_AMM_V4_PROGRAM_ID],
Protocol::MeteoraDammV2 => vec![METEORA_DAMM_V2_PROGRAM_ID],
Protocol::MeteoraDbc => vec![METEORA_DBC_PROGRAM_ID],
Protocol::OrcaWhirlpool => vec![ORCA_WHIRLPOOL_PROGRAM_ID],
Protocol::MeteoraPools => vec![METEORA_POOLS_PROGRAM_ID],
Protocol::MeteoraDlmm => vec![METEORA_DLMM_PROGRAM_ID],
@@ -55,6 +58,7 @@ impl std::fmt::Display for Protocol {
Protocol::RaydiumClmm => write!(f, "RaydiumClmm"),
Protocol::RaydiumAmmV4 => write!(f, "RaydiumAmmV4"),
Protocol::MeteoraDammV2 => write!(f, "MeteoraDammV2"),
Protocol::MeteoraDbc => write!(f, "MeteoraDbc"),
Protocol::OrcaWhirlpool => write!(f, "OrcaWhirlpool"),
Protocol::MeteoraPools => write!(f, "MeteoraPools"),
Protocol::MeteoraDlmm => write!(f, "MeteoraDlmm"),
@@ -77,6 +81,7 @@ impl std::str::FromStr for Protocol {
"raydiumclmm" | "raydium_clmm" => Ok(Protocol::RaydiumClmm),
"raydiumammv4" | "raydium_amm_v4" => Ok(Protocol::RaydiumAmmV4),
"meteoradammv2" | "meteoradamm_v2" | "meteora_damm_v2" => Ok(Protocol::MeteoraDammV2),
"meteoradbc" | "meteora_dbc" => Ok(Protocol::MeteoraDbc),
"orcawhirlpool" | "orca_whirlpool" | "orca" => Ok(Protocol::OrcaWhirlpool),
"meteorapools" | "meteora_pools" => Ok(Protocol::MeteoraPools),
"meteoradlmm" | "meteora_dlmm" => Ok(Protocol::MeteoraDlmm),
@@ -99,6 +104,7 @@ mod tests {
Protocol::RaydiumClmm,
Protocol::RaydiumAmmV4,
Protocol::MeteoraDammV2,
Protocol::MeteoraDbc,
Protocol::OrcaWhirlpool,
Protocol::MeteoraPools,
Protocol::MeteoraDlmm,
@@ -116,6 +122,7 @@ mod tests {
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);
assert_eq!(Protocol::from_str("meteora_dbc").unwrap(), Protocol::MeteoraDbc);
assert_eq!(Protocol::from_str("orca_whirlpool").unwrap(), Protocol::OrcaWhirlpool);
assert_eq!(Protocol::from_str("meteora_pools").unwrap(), Protocol::MeteoraPools);
assert_eq!(Protocol::from_str("meteora_dlmm").unwrap(), Protocol::MeteoraDlmm);
+1 -1
View File
@@ -54,7 +54,7 @@ impl SubscriptionManager {
)> {
// When no filter is set, subscribe to block meta like before; if a filter exists,
// only keep block meta when the filter includes block-related event types.
let blocks_meta = if event_type_filter.map_or(true, |f| f.include_block_event()) {
let blocks_meta = if event_type_filter.is_none_or(|f| f.include_block_event()) {
HashMap::from([("".to_owned(), SubscribeRequestFilterBlocksMeta {})])
} else {
HashMap::new()
+2 -16
View File
@@ -11,6 +11,7 @@ use yellowstone_grpc_proto::{
pub type TransactionsFilterMap = HashMap<String, SubscribeRequestFilterTransactions>;
pub type AccountsFilterMap = HashMap<String, SubscribeRequestFilterAccounts>;
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug)]
pub enum EventPretty {
BlockMeta(BlockMetaPretty),
@@ -65,7 +66,7 @@ impl fmt::Debug for BlockMetaPretty {
}
}
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct TransactionPretty {
pub slot: u64,
pub tx_index: Option<u64>, // 新增:交易在slot中的索引
@@ -88,18 +89,3 @@ impl fmt::Debug for TransactionPretty {
.finish()
}
}
impl Default for TransactionPretty {
fn default() -> Self {
Self {
slot: 0,
tx_index: None,
block_hash: String::new(),
block_time: None,
signature: Signature::default(),
is_vote: false,
grpc_tx: SubscribeUpdateTransactionInfo::default(),
recv_us: 0,
}
}
}
+58 -3
View File
@@ -11,7 +11,7 @@ use super::convert_parser_event;
use super::filter::event_matches_protocol;
pub(crate) enum AccountParseResult {
Event(DexEvent),
Event(Box<DexEvent>),
Filtered,
Unsupported,
}
@@ -22,7 +22,7 @@ pub(crate) fn parse_account_event(
event_type_filter: Option<&EventTypeFilter>,
) -> Option<DexEvent> {
match parse_account_event_for_streamer(account, protocols, event_type_filter) {
AccountParseResult::Event(event) => Some(event),
AccountParseResult::Event(event) => Some(*event),
AccountParseResult::Filtered | AccountParseResult::Unsupported => None,
}
}
@@ -68,7 +68,7 @@ pub(crate) fn parse_account_event_for_streamer(
return AccountParseResult::Filtered;
}
normalize_account_event(&mut event, account);
AccountParseResult::Event(event)
AccountParseResult::Event(Box::new(event))
}
fn build_sdk_account_event_filter(filter: Option<&EventTypeFilter>) -> SdkGrpcEventTypeFilter {
@@ -124,6 +124,19 @@ fn streamer_account_event_to_sdk_types(t: &EventType) -> Vec<SdkGrpcEventType> {
EventType::AccountRaydiumClmmTickArrayState => {
vec![SdkGrpcEventType::AccountRaydiumClmmTickArrayState]
}
EventType::AccountRaydiumCpmmAmmConfig => {
vec![SdkGrpcEventType::AccountRaydiumCpmmAmmConfig]
}
EventType::AccountRaydiumCpmmPoolState => {
vec![SdkGrpcEventType::AccountRaydiumCpmmPoolState]
}
EventType::AccountOrcaWhirlpool => vec![SdkGrpcEventType::AccountOrcaWhirlpool],
EventType::AccountOrcaPosition => vec![SdkGrpcEventType::AccountOrcaPosition],
EventType::AccountOrcaTickArray => vec![SdkGrpcEventType::AccountOrcaTickArray],
EventType::AccountOrcaFeeTier => vec![SdkGrpcEventType::AccountOrcaFeeTier],
EventType::AccountOrcaWhirlpoolsConfig => {
vec![SdkGrpcEventType::AccountOrcaWhirlpoolsConfig]
}
_ => Vec::new(),
}
}
@@ -195,6 +208,48 @@ fn normalize_account_event(event: &mut DexEvent, account: &AccountPretty) {
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::RaydiumCpmmAmmConfigAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::RaydiumCpmmPoolStateAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::OrcaWhirlpoolAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::OrcaPositionAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::OrcaTickArrayAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::OrcaFeeTierAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
DexEvent::OrcaWhirlpoolsConfigAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
_ => {}
}
}
@@ -14,7 +14,7 @@ use crate::streaming::event_parser::protocols::pumpswap::events::{
};
use crate::streaming::event_parser::protocols::pumpswap::types::{GlobalConfig, Pool};
use sol_parser_sdk::core::events::{
BonkTradeEvent as PbBonkTrade, TradeDirection as PbBonkTradeDirection,
RaydiumLaunchlabTradeEvent as PbBonkTrade, TradeDirection as PbBonkTradeDirection,
};
use solana_sdk::pubkey::Pubkey;
@@ -43,7 +43,7 @@ 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::BonkTradeEvent,
b: sol_parser_sdk::core::events::RaydiumLaunchlabTradeEvent,
meta: EventMetadata,
) -> BonkTradeEvent {
BonkTradeEvent {
@@ -71,7 +71,7 @@ pub(crate) fn bonk_trade_from_parser(
}
pub(crate) fn bonk_pool_create_from_parser(
p: sol_parser_sdk::core::events::BonkPoolCreateEvent,
p: sol_parser_sdk::core::events::RaydiumLaunchlabPoolCreateEvent,
meta: EventMetadata,
) -> BonkPoolCreateEvent {
BonkPoolCreateEvent {
@@ -93,7 +93,7 @@ pub(crate) fn bonk_pool_create_from_parser(
}
pub(crate) fn bonk_migrate_to_amm_from_parser(
m: sol_parser_sdk::core::events::BonkMigrateAmmEvent,
m: sol_parser_sdk::core::events::RaydiumLaunchlabMigrateAmmEvent,
meta: EventMetadata,
) -> BonkMigrateToAmmEvent {
BonkMigrateToAmmEvent {
+154 -12
View File
@@ -338,7 +338,7 @@ pub(crate) fn convert_parser_event(
Some(DexEvent::PumpSwapWithdrawEvent(pumpswap_liquidity_removed_to_withdraw(r, meta)))
}
PbDexEvent::BonkTrade(b) => {
PbDexEvent::RaydiumLaunchlabTrade(b) => {
let et = sdk_bonk_trade_event_type(&b);
let meta = adapt_pm(
b.metadata.clone(),
@@ -350,7 +350,7 @@ pub(crate) fn convert_parser_event(
);
Some(DexEvent::BonkTradeEvent(bonk_trade_from_parser(b, meta)))
}
PbDexEvent::BonkPoolCreate(p) => {
PbDexEvent::RaydiumLaunchlabPoolCreate(p) => {
let meta = adapt_pm(
p.metadata.clone(),
bt,
@@ -361,7 +361,7 @@ pub(crate) fn convert_parser_event(
);
Some(DexEvent::BonkPoolCreateEvent(bonk_pool_create_from_parser(p, meta)))
}
PbDexEvent::BonkMigrateAmm(m) => {
PbDexEvent::RaydiumLaunchlabMigrateAmm(m) => {
let meta = adapt_pm(
m.metadata.clone(),
bt,
@@ -422,6 +422,32 @@ pub(crate) fn convert_parser_event(
);
Some(DexEvent::RaydiumCpmmInitializeEvent(raydium_cpmm_initialize_from_parser(e, meta)))
}
PbDexEvent::RaydiumCpmmAmmConfigAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::RaydiumCpmm,
EventType::AccountRaydiumCpmmAmmConfig,
raydium_cpmm_program(),
);
Some(DexEvent::RaydiumCpmmAmmConfigAccountEvent(Box::new(
raydium_cpmm_amm_config_account_from_parser(*e, meta),
)))
}
PbDexEvent::RaydiumCpmmPoolStateAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::RaydiumCpmm,
EventType::AccountRaydiumCpmmPoolState,
raydium_cpmm_program(),
);
Some(DexEvent::RaydiumCpmmPoolStateAccountEvent(Box::new(
raydium_cpmm_pool_state_account_from_parser(*e, meta),
)))
}
PbDexEvent::RaydiumClmmSwap(e) => {
let meta = adapt_pm(
@@ -651,9 +677,9 @@ pub(crate) fn convert_parser_event(
EventType::AccountRaydiumClmmAmmConfig,
raydium_clmm_program(),
);
Some(DexEvent::RaydiumClmmAmmConfigAccountEvent(
raydium_clmm_amm_config_account_from_parser(e, meta),
))
Some(DexEvent::RaydiumClmmAmmConfigAccountEvent(Box::new(
raydium_clmm_amm_config_account_from_parser(*e, meta),
)))
}
PbDexEvent::RaydiumClmmPoolStateAccount(e) => {
let meta = adapt_pm(
@@ -664,9 +690,9 @@ pub(crate) fn convert_parser_event(
EventType::AccountRaydiumClmmPoolState,
raydium_clmm_program(),
);
Some(DexEvent::RaydiumClmmPoolStateAccountEvent(
raydium_clmm_pool_state_account_from_parser(e, meta),
))
Some(DexEvent::RaydiumClmmPoolStateAccountEvent(Box::new(
raydium_clmm_pool_state_account_from_parser(*e, meta),
)))
}
PbDexEvent::RaydiumClmmTickArrayStateAccount(e) => {
let meta = adapt_pm(
@@ -677,9 +703,9 @@ pub(crate) fn convert_parser_event(
EventType::AccountRaydiumClmmTickArrayState,
raydium_clmm_program(),
);
Some(DexEvent::RaydiumClmmTickArrayStateAccountEvent(
raydium_clmm_tick_array_state_account_from_parser(e, meta),
))
Some(DexEvent::RaydiumClmmTickArrayStateAccountEvent(Box::new(
raydium_clmm_tick_array_state_account_from_parser(*e, meta),
)))
}
PbDexEvent::RaydiumAmmV4Swap(e) => {
@@ -758,6 +784,19 @@ pub(crate) fn convert_parser_event(
);
Some(DexEvent::MeteoraDammV2SwapEvent(meteora_damm_v2_swap_from_parser(e, meta)))
}
PbDexEvent::MeteoraDammV2InitializePool(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::MeteoraDammV2,
EventType::MeteoraDammV2InitializePool,
meteora_damm_program(),
);
Some(DexEvent::MeteoraDammV2InitializePoolEvent(
meteora_damm_v2_initialize_pool_from_parser(e, meta),
))
}
PbDexEvent::MeteoraDammV2AddLiquidity(e) => {
let meta = adapt_pm(
e.metadata.clone(),
@@ -811,6 +850,44 @@ pub(crate) fn convert_parser_event(
)))
}
PbDexEvent::MeteoraDbcSwap(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::MeteoraDbc,
EventType::MeteoraDbcSwap,
meteora_dbc_program(),
);
Some(DexEvent::MeteoraDbcSwapEvent(meteora_dbc_swap_from_pb(e, meta)))
}
PbDexEvent::MeteoraDbcInitializePool(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::MeteoraDbc,
EventType::MeteoraDbcInitializePool,
meteora_dbc_program(),
);
Some(DexEvent::MeteoraDbcInitializePoolEvent(meteora_dbc_initialize_pool_from_pb(
e, meta,
)))
}
PbDexEvent::MeteoraDbcCurveComplete(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::MeteoraDbc,
EventType::MeteoraDbcCurveComplete,
meteora_dbc_program(),
);
Some(DexEvent::MeteoraDbcCurveCompleteEvent(meteora_dbc_curve_complete_from_pb(
e, meta,
)))
}
PbDexEvent::TokenAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
@@ -943,6 +1020,71 @@ pub(crate) fn convert_parser_event(
e, meta,
)))
}
PbDexEvent::OrcaWhirlpoolAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::OrcaWhirlpool,
EventType::AccountOrcaWhirlpool,
orca_whirlpool_program(),
);
Some(DexEvent::OrcaWhirlpoolAccountEvent(Box::new(orca_whirlpool_account_from_pb(
*e, meta,
))))
}
PbDexEvent::OrcaPositionAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::OrcaWhirlpool,
EventType::AccountOrcaPosition,
orca_whirlpool_program(),
);
Some(DexEvent::OrcaPositionAccountEvent(Box::new(orca_position_account_from_pb(
*e, meta,
))))
}
PbDexEvent::OrcaTickArrayAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::OrcaWhirlpool,
EventType::AccountOrcaTickArray,
orca_whirlpool_program(),
);
Some(DexEvent::OrcaTickArrayAccountEvent(Box::new(orca_tick_array_account_from_pb(
*e, meta,
))))
}
PbDexEvent::OrcaFeeTierAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::OrcaWhirlpool,
EventType::AccountOrcaFeeTier,
orca_whirlpool_program(),
);
Some(DexEvent::OrcaFeeTierAccountEvent(Box::new(orca_fee_tier_account_from_pb(
*e, meta,
))))
}
PbDexEvent::OrcaWhirlpoolsConfigAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::OrcaWhirlpool,
EventType::AccountOrcaWhirlpoolsConfig,
orca_whirlpool_program(),
);
Some(DexEvent::OrcaWhirlpoolsConfigAccountEvent(Box::new(
orca_whirlpools_config_account_from_pb(*e, meta),
)))
}
PbDexEvent::MeteoraPoolsSwap(e) => {
let meta = adapt_pm(
e.metadata.clone(),
+10 -1
View File
@@ -25,6 +25,7 @@ fn is_protocol_independent_event(ev: &DexEvent) -> bool {
)
}
#[allow(clippy::match_like_matches_macro)]
fn protocol_matches_event(p: &Protocol, ev: &DexEvent) -> bool {
match (p, ev) {
(Protocol::PumpFun, DexEvent::PumpFunCreateTokenEvent(_))
@@ -122,10 +123,18 @@ fn protocol_matches_event(p: &Protocol, ev: &DexEvent) -> bool {
| (Protocol::MeteoraDammV2, DexEvent::MeteoraDammV2RemoveLiquidityEvent(_))
| (Protocol::MeteoraDammV2, DexEvent::MeteoraDammV2CreatePositionEvent(_))
| (Protocol::MeteoraDammV2, DexEvent::MeteoraDammV2ClosePositionEvent(_)) => true,
(Protocol::MeteoraDbc, DexEvent::MeteoraDbcSwapEvent(_))
| (Protocol::MeteoraDbc, DexEvent::MeteoraDbcInitializePoolEvent(_))
| (Protocol::MeteoraDbc, DexEvent::MeteoraDbcCurveCompleteEvent(_)) => true,
(Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolSwapEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolLiquidityIncreasedEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolLiquidityDecreasedEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolPoolInitializedEvent(_)) => true,
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolPoolInitializedEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolAccountEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaPositionAccountEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaTickArrayAccountEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaFeeTierAccountEvent(_))
| (Protocol::OrcaWhirlpool, DexEvent::OrcaWhirlpoolsConfigAccountEvent(_)) => true,
(Protocol::MeteoraPools, DexEvent::MeteoraPoolsSwapEvent(_))
| (Protocol::MeteoraPools, DexEvent::MeteoraPoolsAddLiquidityEvent(_))
| (Protocol::MeteoraPools, DexEvent::MeteoraPoolsRemoveLiquidityEvent(_))
+193 -3
View File
@@ -1,14 +1,18 @@
//! Orca Whirlpool and Meteora Pools / DLMM events with SDK-shaped payloads.
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::sol_parser_forward::events::{
MeteoraDbcCurveCompleteEvent, MeteoraDbcInitializePoolEvent, MeteoraDbcSwapEvent,
MeteoraDlmmAddLiquidityEvent, MeteoraDlmmClaimFeeEvent, MeteoraDlmmClosePositionEvent,
MeteoraDlmmCreatePositionEvent, MeteoraDlmmInitializeBinArrayEvent,
MeteoraDlmmInitializePoolEvent, MeteoraDlmmRemoveLiquidityEvent, MeteoraDlmmSwapEvent,
MeteoraPoolsAddLiquidityEvent, MeteoraPoolsBootstrapLiquidityEvent,
MeteoraPoolsPoolCreatedEvent, MeteoraPoolsRemoveLiquidityEvent, MeteoraPoolsSetPoolFeesEvent,
MeteoraPoolsSwapEvent, OrcaWhirlpoolLiquidityDecreasedEvent,
OrcaWhirlpoolLiquidityIncreasedEvent, OrcaWhirlpoolPoolInitializedEvent,
OrcaWhirlpoolSwapEvent,
MeteoraPoolsSwapEvent, OrcaFeeTierAccount, OrcaFeeTierAccountEvent, OrcaPositionAccount,
OrcaPositionAccountEvent, OrcaPositionRewardInfo, OrcaTick, OrcaTickArrayAccount,
OrcaTickArrayAccountEvent, OrcaWhirlpoolAccount, OrcaWhirlpoolAccountEvent,
OrcaWhirlpoolLiquidityDecreasedEvent, OrcaWhirlpoolLiquidityIncreasedEvent,
OrcaWhirlpoolPoolInitializedEvent, OrcaWhirlpoolRewardInfo, OrcaWhirlpoolSwapEvent,
OrcaWhirlpoolsConfigAccount, OrcaWhirlpoolsConfigAccountEvent,
};
pub(crate) fn orca_swap_from_pb(
@@ -85,6 +89,192 @@ pub(crate) fn orca_pool_initialized_from_pb(
}
}
fn orca_whirlpool_reward_from_pb(
r: sol_parser_sdk::core::events::OrcaWhirlpoolRewardInfo,
) -> OrcaWhirlpoolRewardInfo {
OrcaWhirlpoolRewardInfo {
mint: r.mint,
vault: r.vault,
authority: r.authority,
emissions_per_second_x64: r.emissions_per_second_x64,
growth_global_x64: r.growth_global_x64,
}
}
fn orca_position_reward_from_pb(
r: sol_parser_sdk::core::events::OrcaPositionRewardInfo,
) -> OrcaPositionRewardInfo {
OrcaPositionRewardInfo {
growth_inside_checkpoint: r.growth_inside_checkpoint,
amount_owed: r.amount_owed,
}
}
fn orca_tick_from_pb(t: sol_parser_sdk::core::events::OrcaTick) -> OrcaTick {
OrcaTick {
initialized: t.initialized,
liquidity_net: t.liquidity_net,
liquidity_gross: t.liquidity_gross,
fee_growth_outside_a: t.fee_growth_outside_a,
fee_growth_outside_b: t.fee_growth_outside_b,
reward_growths_outside: t.reward_growths_outside,
}
}
pub(crate) fn orca_whirlpool_account_from_pb(
e: sol_parser_sdk::core::events::OrcaWhirlpoolAccountEvent,
meta: EventMetadata,
) -> OrcaWhirlpoolAccountEvent {
OrcaWhirlpoolAccountEvent {
metadata: meta,
pubkey: e.pubkey,
whirlpool: OrcaWhirlpoolAccount {
whirlpools_config: e.whirlpool.whirlpools_config,
whirlpool_bump: e.whirlpool.whirlpool_bump,
tick_spacing: e.whirlpool.tick_spacing,
tick_spacing_seed: e.whirlpool.tick_spacing_seed,
fee_rate: e.whirlpool.fee_rate,
protocol_fee_rate: e.whirlpool.protocol_fee_rate,
liquidity: e.whirlpool.liquidity,
sqrt_price: e.whirlpool.sqrt_price,
tick_current_index: e.whirlpool.tick_current_index,
protocol_fee_owed_a: e.whirlpool.protocol_fee_owed_a,
protocol_fee_owed_b: e.whirlpool.protocol_fee_owed_b,
token_mint_a: e.whirlpool.token_mint_a,
token_vault_a: e.whirlpool.token_vault_a,
fee_growth_global_a: e.whirlpool.fee_growth_global_a,
token_mint_b: e.whirlpool.token_mint_b,
token_vault_b: e.whirlpool.token_vault_b,
fee_growth_global_b: e.whirlpool.fee_growth_global_b,
reward_last_updated_timestamp: e.whirlpool.reward_last_updated_timestamp,
reward_infos: e.whirlpool.reward_infos.map(orca_whirlpool_reward_from_pb),
},
..Default::default()
}
}
pub(crate) fn orca_position_account_from_pb(
e: sol_parser_sdk::core::events::OrcaPositionAccountEvent,
meta: EventMetadata,
) -> OrcaPositionAccountEvent {
OrcaPositionAccountEvent {
metadata: meta,
pubkey: e.pubkey,
position: OrcaPositionAccount {
whirlpool: e.position.whirlpool,
position_mint: e.position.position_mint,
liquidity: e.position.liquidity,
tick_lower_index: e.position.tick_lower_index,
tick_upper_index: e.position.tick_upper_index,
fee_growth_checkpoint_a: e.position.fee_growth_checkpoint_a,
fee_owed_a: e.position.fee_owed_a,
fee_growth_checkpoint_b: e.position.fee_growth_checkpoint_b,
fee_owed_b: e.position.fee_owed_b,
reward_infos: e.position.reward_infos.map(orca_position_reward_from_pb),
},
..Default::default()
}
}
pub(crate) fn orca_tick_array_account_from_pb(
e: sol_parser_sdk::core::events::OrcaTickArrayAccountEvent,
meta: EventMetadata,
) -> OrcaTickArrayAccountEvent {
OrcaTickArrayAccountEvent {
metadata: meta,
pubkey: e.pubkey,
tick_array: OrcaTickArrayAccount {
start_tick_index: e.tick_array.start_tick_index,
ticks: e.tick_array.ticks.into_iter().map(orca_tick_from_pb).collect(),
whirlpool: e.tick_array.whirlpool,
},
..Default::default()
}
}
pub(crate) fn orca_fee_tier_account_from_pb(
e: sol_parser_sdk::core::events::OrcaFeeTierAccountEvent,
meta: EventMetadata,
) -> OrcaFeeTierAccountEvent {
OrcaFeeTierAccountEvent {
metadata: meta,
pubkey: e.pubkey,
fee_tier: OrcaFeeTierAccount {
whirlpools_config: e.fee_tier.whirlpools_config,
tick_spacing: e.fee_tier.tick_spacing,
default_fee_rate: e.fee_tier.default_fee_rate,
},
..Default::default()
}
}
pub(crate) fn orca_whirlpools_config_account_from_pb(
e: sol_parser_sdk::core::events::OrcaWhirlpoolsConfigAccountEvent,
meta: EventMetadata,
) -> OrcaWhirlpoolsConfigAccountEvent {
OrcaWhirlpoolsConfigAccountEvent {
metadata: meta,
pubkey: e.pubkey,
config: OrcaWhirlpoolsConfigAccount {
fee_authority: e.config.fee_authority,
collect_protocol_fees_authority: e.config.collect_protocol_fees_authority,
reward_emissions_super_authority: e.config.reward_emissions_super_authority,
default_protocol_fee_rate: e.config.default_protocol_fee_rate,
},
..Default::default()
}
}
pub(crate) fn meteora_dbc_swap_from_pb(
e: sol_parser_sdk::core::events::MeteoraDbcSwapEvent,
meta: EventMetadata,
) -> MeteoraDbcSwapEvent {
MeteoraDbcSwapEvent {
metadata: meta,
pool: e.pool,
config: e.config,
trade_direction: e.trade_direction,
has_referral: e.has_referral,
amount_in: e.amount_in,
minimum_amount_out: e.minimum_amount_out,
actual_input_amount: e.actual_input_amount,
output_amount: e.output_amount,
next_sqrt_price: e.next_sqrt_price,
trading_fee: e.trading_fee,
protocol_fee: e.protocol_fee,
referral_fee: e.referral_fee,
current_timestamp: e.current_timestamp,
}
}
pub(crate) fn meteora_dbc_initialize_pool_from_pb(
e: sol_parser_sdk::core::events::MeteoraDbcInitializePoolEvent,
meta: EventMetadata,
) -> MeteoraDbcInitializePoolEvent {
MeteoraDbcInitializePoolEvent {
metadata: meta,
pool: e.pool,
config: e.config,
creator: e.creator,
base_mint: e.base_mint,
pool_type: e.pool_type,
activation_point: e.activation_point,
}
}
pub(crate) fn meteora_dbc_curve_complete_from_pb(
e: sol_parser_sdk::core::events::MeteoraDbcCurveCompleteEvent,
meta: EventMetadata,
) -> MeteoraDbcCurveCompleteEvent {
MeteoraDbcCurveCompleteEvent {
metadata: meta,
pool: e.pool,
config: e.config,
base_reserve: e.base_reserve,
quote_reserve: e.quote_reserve,
}
}
pub(crate) fn meteora_pools_swap_from_pb(
e: sol_parser_sdk::core::events::MeteoraPoolsSwapEvent,
meta: EventMetadata,
+8 -5
View File
@@ -32,6 +32,7 @@ pub(crate) use adapt::{block_timestamp_from_stream_meta, fuse_streamer_ix_ctx};
pub(crate) use convert::{adapt_parser_event, adapt_parser_events_list, convert_parser_event};
#[cfg(test)]
#[allow(clippy::field_reassign_with_default)]
mod tests {
use super::filter::event_matches_protocol;
use super::{adapt_parser_event, convert_parser_event};
@@ -40,9 +41,9 @@ mod tests {
use crate::streaming::event_parser::core::account_event_parser::TokenInfoEvent;
use crate::streaming::event_parser::{DexEvent, Protocol};
use sol_parser_sdk::core::events::{
BonkTradeEvent as PbBonkTrade, EventMetadata, MeteoraDlmmSwapEvent as PbDlmmSwap,
OrcaWhirlpoolSwapEvent as PbOrcaSwap, PumpFunCreateV2TokenEvent as PbPumpCreateV2,
PumpFunTradeEvent as PbPumpTrade, TokenInfoEvent as PbTokenInfo,
EventMetadata, MeteoraDlmmSwapEvent as PbDlmmSwap, OrcaWhirlpoolSwapEvent as PbOrcaSwap,
PumpFunCreateV2TokenEvent as PbPumpCreateV2, PumpFunTradeEvent as PbPumpTrade,
RaydiumLaunchlabTradeEvent as PbBonkTrade, TokenInfoEvent as PbTokenInfo,
TradeDirection as PbBonkDir,
};
use sol_parser_sdk::DexEvent as PbDexEvent;
@@ -370,7 +371,8 @@ mod tests {
trade_direction: PbBonkDir::Buy,
exact_in: true,
};
let dex = convert_parser_event(PbDexEvent::BonkTrade(b), None, 0).expect("convert");
let dex =
convert_parser_event(PbDexEvent::RaydiumLaunchlabTrade(b), None, 0).expect("convert");
match dex {
DexEvent::BonkTradeEvent(e) => {
assert_eq!(e.metadata.event_type, EventType::BonkBuyExactIn)
@@ -391,7 +393,8 @@ mod tests {
trade_direction: PbBonkDir::Sell,
exact_in: false,
};
let dex = convert_parser_event(PbDexEvent::BonkTrade(b), None, 0).expect("convert");
let dex =
convert_parser_event(PbDexEvent::RaydiumLaunchlabTrade(b), None, 0).expect("convert");
match dex {
DexEvent::BonkTradeEvent(e) => {
assert_eq!(e.metadata.event_type, EventType::BonkSellExactOut)
@@ -12,7 +12,7 @@ pub(crate) fn pump_fees_program() -> Pubkey {
program_ids::PUMP_FEES_PROGRAM_ID
}
pub(crate) fn bonk_program() -> Pubkey {
program_ids::BONK_PROGRAM_ID
program_ids::RAYDIUM_LAUNCHLAB_PROGRAM_ID
}
pub(crate) fn raydium_cpmm_program() -> Pubkey {
program_ids::RAYDIUM_CPMM_PROGRAM_ID
@@ -27,6 +27,10 @@ pub(crate) fn meteora_damm_program() -> Pubkey {
program_ids::METEORA_DAMM_V2_PROGRAM_ID
}
pub(crate) fn meteora_dbc_program() -> Pubkey {
program_ids::METEORA_DBC_PROGRAM_ID
}
pub(crate) fn orca_whirlpool_program() -> Pubkey {
program_ids::ORCA_WHIRLPOOL_PROGRAM_ID
}
@@ -2,7 +2,8 @@
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::meteora_damm_v2::events::{
MeteoraDammV2AddLiquidityEvent, MeteoraDammV2ClosePositionEvent,
MeteoraDammV2CreatePositionEvent, MeteoraDammV2RemoveLiquidityEvent, MeteoraDammV2SwapEvent,
MeteoraDammV2CreatePositionEvent, MeteoraDammV2InitializePoolEvent,
MeteoraDammV2RemoveLiquidityEvent, MeteoraDammV2SwapEvent,
};
use crate::streaming::event_parser::protocols::raydium_amm_v4::events::{
RaydiumAmmV4DepositEvent, RaydiumAmmV4Initialize2Event, RaydiumAmmV4SwapEvent,
@@ -24,8 +25,11 @@ use crate::streaming::event_parser::protocols::raydium_clmm::types::{
RewardInfo as ClmmRewardInfo, TickArrayState as ClmmTickArrayState, TickState as ClmmTickState,
};
use crate::streaming::event_parser::protocols::raydium_cpmm::events::{
RaydiumCpmmDepositEvent, RaydiumCpmmInitializeEvent, RaydiumCpmmSwapEvent,
RaydiumCpmmWithdrawEvent,
RaydiumCpmmAmmConfigAccountEvent, RaydiumCpmmDepositEvent, RaydiumCpmmInitializeEvent,
RaydiumCpmmPoolStateAccountEvent, RaydiumCpmmSwapEvent, RaydiumCpmmWithdrawEvent,
};
use crate::streaming::event_parser::protocols::raydium_cpmm::types::{
AmmConfig as CpmmAmmConfig, PoolState as CpmmPoolState,
};
use solana_sdk::pubkey::Pubkey;
pub(crate) fn meteora_damm_v2_swap_from_parser(
@@ -72,6 +76,38 @@ pub(crate) fn meteora_damm_v2_swap_from_parser(
}
}
pub(crate) fn meteora_damm_v2_initialize_pool_from_parser(
e: sol_parser_sdk::core::events::MeteoraDammV2InitializePoolEvent,
meta: EventMetadata,
) -> MeteoraDammV2InitializePoolEvent {
MeteoraDammV2InitializePoolEvent {
metadata: meta,
pool: e.pool,
token_a_mint: e.token_a_mint,
token_b_mint: e.token_b_mint,
creator: e.creator,
payer: e.payer,
alpha_vault: e.alpha_vault,
sqrt_min_price: e.sqrt_min_price,
sqrt_max_price: e.sqrt_max_price,
activation_type: e.activation_type,
collect_fee_mode: e.collect_fee_mode,
liquidity: e.liquidity,
sqrt_price: e.sqrt_price,
activation_point: e.activation_point.unwrap_or(0),
token_a_flag: e.token_a_flag,
token_b_flag: e.token_b_flag,
token_a_amount: e.token_a_amount,
token_b_amount: e.token_b_amount,
total_amount_a: e.total_amount_a,
total_amount_b: e.total_amount_b,
pool_type: e.pool_type,
position: e.position,
position_nft_mint: e.position_nft_mint,
..Default::default()
}
}
pub(crate) fn raydium_cpmm_swap_from_parser(
e: sol_parser_sdk::core::events::RaydiumCpmmSwapEvent,
meta: EventMetadata,
@@ -164,6 +200,85 @@ pub(crate) fn raydium_cpmm_initialize_from_parser(
}
}
fn raydium_cpmm_amm_config_from_parser(
c: sol_parser_sdk::core::events::RaydiumCpmmAmmConfig,
) -> CpmmAmmConfig {
CpmmAmmConfig {
bump: c.bump,
disable_create_pool: c.disable_create_pool,
index: c.index,
trade_fee_rate: c.trade_fee_rate,
protocol_fee_rate: c.protocol_fee_rate,
fund_fee_rate: c.fund_fee_rate,
create_pool_fee: c.create_pool_fee,
protocol_owner: c.protocol_owner,
fund_owner: c.fund_owner,
creator_fee_rate: c.creator_fee_rate,
padding: c.padding,
}
}
fn raydium_cpmm_pool_state_from_parser(
p: sol_parser_sdk::core::events::RaydiumCpmmPoolState,
) -> CpmmPoolState {
CpmmPoolState {
amm_config: p.amm_config,
pool_creator: p.pool_creator,
token_0_vault: p.token_0_vault,
token_1_vault: p.token_1_vault,
lp_mint: p.lp_mint,
token_0_mint: p.token_0_mint,
token_1_mint: p.token_1_mint,
token_0_program: p.token_0_program,
token_1_program: p.token_1_program,
observation_key: p.observation_key,
auth_bump: p.auth_bump,
status: p.status,
lp_mint_decimals: p.lp_mint_decimals,
mint_0_decimals: p.mint_0_decimals,
mint_1_decimals: p.mint_1_decimals,
lp_supply: p.lp_supply,
protocol_fees_token_0: p.protocol_fees_token_0,
protocol_fees_token_1: p.protocol_fees_token_1,
fund_fees_token_0: p.fund_fees_token_0,
fund_fees_token_1: p.fund_fees_token_1,
open_time: p.open_time,
recent_epoch: p.recent_epoch,
creator_fee_on: p.creator_fee_on,
enable_creator_fee: p.enable_creator_fee,
padding1: p.padding1,
creator_fees_token_0: p.creator_fees_token_0,
creator_fees_token_1: p.creator_fees_token_1,
padding: p.padding,
}
}
pub(crate) fn raydium_cpmm_amm_config_account_from_parser(
e: sol_parser_sdk::core::events::RaydiumCpmmAmmConfigAccountEvent,
meta: EventMetadata,
) -> RaydiumCpmmAmmConfigAccountEvent {
RaydiumCpmmAmmConfigAccountEvent {
metadata: meta,
pubkey: e.pubkey,
owner: super::program_ids::raydium_cpmm_program(),
amm_config: raydium_cpmm_amm_config_from_parser(e.amm_config),
..Default::default()
}
}
pub(crate) fn raydium_cpmm_pool_state_account_from_parser(
e: sol_parser_sdk::core::events::RaydiumCpmmPoolStateAccountEvent,
meta: EventMetadata,
) -> RaydiumCpmmPoolStateAccountEvent {
RaydiumCpmmPoolStateAccountEvent {
metadata: meta,
pubkey: e.pubkey,
owner: super::program_ids::raydium_cpmm_program(),
pool_state: raydium_cpmm_pool_state_from_parser(e.pool_state),
..Default::default()
}
}
pub(crate) fn raydium_amm_v4_swap_from_parser(
e: sol_parser_sdk::core::events::RaydiumAmmV4SwapEvent,
meta: EventMetadata,
+1
View File
@@ -25,6 +25,7 @@ impl ShredStreamGrpc {
/// 创建客户端,使用自定义配置
pub async fn new_with_config(endpoint: String, config: StreamClientConfig) -> AnyResult<Self> {
sol_parser_sdk::warmup_parser();
let shredstream_client = ShredstreamProxyClient::connect(endpoint.clone())
.await?
.max_decoding_message_size(config.connection.max_decoding_message_size);
+1 -1
View File
@@ -63,7 +63,7 @@ impl PooledTransactionWithSlot {
/// 使用优化的工厂方法创建 TransactionWithSlot(移动数据而不是克隆)
pub fn into_transaction_with_slot(mut self) -> TransactionWithSlot {
// 移动数据而不是克隆,避免多余的内存分配
std::mem::replace(self.deref_mut(), TransactionWithSlot::default())
std::mem::take(self.deref_mut())
}
}
+2
View File
@@ -66,6 +66,7 @@ impl YellowstoneGrpc {
x_token: Option<String>,
config: StreamClientConfig,
) -> AnyResult<Self> {
sol_parser_sdk::warmup_parser();
let _ = rustls::crypto::ring::default_provider().install_default().ok();
let subscription_manager =
SubscriptionManager::new(endpoint.clone(), x_token.clone(), config.clone());
@@ -133,6 +134,7 @@ impl YellowstoneGrpc {
///
/// # Returns
/// Returns `AnyResult<()>`, `Ok(())` on success, error information on failure
#[allow(clippy::too_many_arguments)]
pub async fn subscribe_events_immediate<F>(
&self,
protocols: Vec<Protocol>,
+7 -9
View File
@@ -16,6 +16,7 @@ use yellowstone_grpc_proto::geyser::{
const SYSTEM_PROGRAM_ID: Pubkey = pubkey!("11111111111111111111111111111111");
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum SystemEvent {
NewTransfer(TransferInfo),
@@ -101,15 +102,12 @@ impl YellowstoneGrpc {
where
F: Fn(SystemEvent) + Send + Sync,
{
match event_pretty {
EventPretty::Transaction(transaction_pretty) => {
callback(SystemEvent::NewTransfer(TransferInfo {
slot: transaction_pretty.slot,
signature: transaction_pretty.signature.to_string(),
tx: Some(transaction_pretty.grpc_tx),
}));
}
_ => {}
if let EventPretty::Transaction(transaction_pretty) = event_pretty {
callback(SystemEvent::NewTransfer(TransferInfo {
slot: transaction_pretty.slot,
signature: transaction_pretty.signature.to_string(),
tx: Some(transaction_pretty.grpc_tx),
}));
}
Ok(())
}