Release parser SDK bridge updates

This commit is contained in:
0xfnzero
2026-05-25 01:48:41 +08:00
parent 45ab6eb061
commit aaa10a69f7
8 changed files with 86 additions and 25 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "solana-streamer-sdk" name = "solana-streamer-sdk"
version = "1.4.9" version = "1.4.10"
edition = "2021" edition = "2021"
authors = ["William <byteblock6@gmail.com>", "sgxiang <sgxiang@gmail.com>", "wei <1415121722@qq.com>"] authors = ["William <byteblock6@gmail.com>", "sgxiang <sgxiang@gmail.com>", "wei <1415121722@qq.com>"]
repository = "https://github.com/0xfnzero/solana-streamer" repository = "https://github.com/0xfnzero/solana-streamer"
@@ -15,13 +15,13 @@ crate-type = ["cdylib", "rlib"]
[features] [features]
default = ["sdk-parse-borsh"] default = ["sdk-parse-borsh"]
sdk-parse-borsh = ["sol-parser-sdk/parse-borsh"] sdk-parse-borsh = ["sol-parser-sdk/parse-borsh"]
# If both parser backend features are enabled, sol-parser-sdk 0.4.14+ uses zero-copy. # If both parser backend features are enabled, sol-parser-sdk 0.4.15+ uses zero-copy.
sdk-parse-zero-copy = ["sol-parser-sdk/parse-zero-copy"] sdk-parse-zero-copy = ["sol-parser-sdk/parse-zero-copy"]
sdk-perf-stats = ["sol-parser-sdk/perf-stats"] sdk-perf-stats = ["sol-parser-sdk/perf-stats"]
sdk-ultra-perf = ["sol-parser-sdk/ultra-perf"] sdk-ultra-perf = ["sol-parser-sdk/ultra-perf"]
[dependencies] [dependencies]
sol-parser-sdk = { version = "0.4.14", default-features = false } sol-parser-sdk = { version = "0.4.15", default-features = false }
solana-sdk = "3.0.0" solana-sdk = "3.0.0"
solana-client = "3.1.12" solana-client = "3.1.12"
solana-transaction-status = "3.1.12" solana-transaction-status = "3.1.12"
+6 -6
View File
@@ -123,33 +123,33 @@ Add the dependency to your `Cargo.toml`:
```toml ```toml
# Add to your Cargo.toml # Add to your Cargo.toml
solana-streamer-sdk = { path = "./solana-streamer", version = "1.4.7" } solana-streamer-sdk = { path = "./solana-streamer", version = "1.4.10" }
``` ```
### Use crates.io ### Use crates.io
```toml ```toml
# Add to your Cargo.toml # Add to your Cargo.toml
solana-streamer-sdk = "1.4.7" solana-streamer-sdk = "1.4.10"
``` ```
Parser backend features: Parser backend features:
```toml ```toml
# Default: sol-parser-sdk parse-borsh backend # Default: sol-parser-sdk parse-borsh backend
solana-streamer-sdk = "1.4.7" solana-streamer-sdk = "1.4.10"
# Zero-copy parser backend for latency-sensitive bots # Zero-copy parser backend for latency-sensitive bots
solana-streamer-sdk = { version = "1.4.7", default-features = false, features = ["sdk-parse-zero-copy"] } solana-streamer-sdk = { version = "1.4.10", default-features = false, features = ["sdk-parse-zero-copy"] }
``` ```
If both `sdk-parse-borsh` and `sdk-parse-zero-copy` are enabled, `sol-parser-sdk 0.4.11+` uses the zero-copy backend. If both `sdk-parse-borsh` and `sdk-parse-zero-copy` are enabled, `sol-parser-sdk 0.4.11+` uses the zero-copy backend.
## 🔄 Migration Guide ## 🔄 Migration Guide
### Upgrading to v1.4.7 ### Upgrading to v1.4.10
Version 1.4.7 uses `sol-parser-sdk 0.4.11` from crates.io and adds the SDK-compatible Yellowstone gRPC ordering modes to the streamer facade while preserving the existing subscription and callback API. Existing bots can keep the default ultra-low-latency `Unordered` mode or opt into `Ordered`, `StreamingOrdered`, or `MicroBatch` through `ClientConfig`. Version 1.4.10 uses `sol-parser-sdk 0.4.15` from crates.io and preserves the SDK-compatible Yellowstone gRPC ordering modes in the streamer facade while adding the latest PumpFun USDC/v2 parser fields.
New optional capabilities: New optional capabilities:
+6 -6
View File
@@ -122,33 +122,33 @@ git clone https://github.com/0xfnzero/solana-streamer
```toml ```toml
# 添加到您的 Cargo.toml # 添加到您的 Cargo.toml
solana-streamer-sdk = { path = "./solana-streamer", version = "1.4.7" } solana-streamer-sdk = { path = "./solana-streamer", version = "1.4.10" }
``` ```
### 使用 crates.io ### 使用 crates.io
```toml ```toml
# 添加到您的 Cargo.toml # 添加到您的 Cargo.toml
solana-streamer-sdk = "1.4.7" solana-streamer-sdk = "1.4.10"
``` ```
解析后端 feature 解析后端 feature
```toml ```toml
# 默认:sol-parser-sdk parse-borsh 后端 # 默认:sol-parser-sdk parse-borsh 后端
solana-streamer-sdk = "1.4.7" solana-streamer-sdk = "1.4.10"
# 面向低延迟 Bot 的 zero-copy 解析后端 # 面向低延迟 Bot 的 zero-copy 解析后端
solana-streamer-sdk = { version = "1.4.7", default-features = false, features = ["sdk-parse-zero-copy"] } solana-streamer-sdk = { version = "1.4.10", default-features = false, features = ["sdk-parse-zero-copy"] }
``` ```
如果同时启用 `sdk-parse-borsh``sdk-parse-zero-copy``sol-parser-sdk 0.4.11+` 会优先使用 zero-copy 后端。 如果同时启用 `sdk-parse-borsh``sdk-parse-zero-copy``sol-parser-sdk 0.4.11+` 会优先使用 zero-copy 后端。
## 🔄 迁移指南 ## 🔄 迁移指南
### 升级到 v1.4.7 ### 升级到 v1.4.10
v1.4.7 使用 crates.io 上的 `sol-parser-sdk 0.4.11`并在 streamer facade 中补齐与 SDK 兼容的 Yellowstone gRPC 输出顺序模式,同时保留已有订阅和回调 API。现有 Bot 可以继续使用默认的超低延迟 `Unordered` 模式,也可以通过 `ClientConfig` 选择 `Ordered``StreamingOrdered``MicroBatch` v1.4.10 使用 crates.io 上的 `sol-parser-sdk 0.4.15`保留 streamer facade 中与 SDK 兼容的 Yellowstone gRPC 输出顺序模式,并补齐最新 PumpFun USDC/v2 解析字段
新增可选能力: 新增可选能力:
@@ -253,6 +253,7 @@ fn push_streamer_event_sdk_grpc_types(t: &EventType, out: &mut Vec<SdkGrpcEventT
St::TokenAccount | St::TokenInfo => out.push(Sdk::TokenAccount), St::TokenAccount | St::TokenInfo => out.push(Sdk::TokenAccount),
St::NonceAccount => out.push(Sdk::NonceAccount), St::NonceAccount => out.push(Sdk::NonceAccount),
St::AccountPumpFunGlobal => out.push(Sdk::AccountPumpFunGlobal), St::AccountPumpFunGlobal => out.push(Sdk::AccountPumpFunGlobal),
St::AccountPumpFunBondingCurve => out.push(Sdk::AccountPumpFunBondingCurve),
St::AccountPumpSwapGlobalConfig => out.push(Sdk::AccountPumpSwapGlobalConfig), St::AccountPumpSwapGlobalConfig => out.push(Sdk::AccountPumpSwapGlobalConfig),
St::AccountPumpSwapPool => out.push(Sdk::AccountPumpSwapPool), St::AccountPumpSwapPool => out.push(Sdk::AccountPumpSwapPool),
_ => return false, _ => return false,
+19 -7
View File
@@ -101,6 +101,9 @@ fn streamer_account_event_to_sdk_types(t: &EventType) -> Vec<SdkGrpcEventType> {
EventType::TokenAccount | EventType::TokenInfo => vec![SdkGrpcEventType::TokenAccount], EventType::TokenAccount | EventType::TokenInfo => vec![SdkGrpcEventType::TokenAccount],
EventType::NonceAccount => vec![SdkGrpcEventType::NonceAccount], EventType::NonceAccount => vec![SdkGrpcEventType::NonceAccount],
EventType::AccountPumpFunGlobal => vec![SdkGrpcEventType::AccountPumpFunGlobal], EventType::AccountPumpFunGlobal => vec![SdkGrpcEventType::AccountPumpFunGlobal],
EventType::AccountPumpFunBondingCurve => {
vec![SdkGrpcEventType::AccountPumpFunBondingCurve]
}
EventType::AccountPumpSwapGlobalConfig => { EventType::AccountPumpSwapGlobalConfig => {
vec![SdkGrpcEventType::AccountPumpSwapGlobalConfig] vec![SdkGrpcEventType::AccountPumpSwapGlobalConfig]
} }
@@ -121,13 +124,22 @@ fn dedup_sdk_grpc_event_types(v: &mut Vec<SdkGrpcEventType>) {
} }
fn normalize_account_event(event: &mut DexEvent, account: &AccountPretty) { fn normalize_account_event(event: &mut DexEvent, account: &AccountPretty) {
if let DexEvent::PumpFunGlobalAccountEvent(e) = event { match event {
e.executable = account.executable; DexEvent::PumpFunGlobalAccountEvent(e) => {
e.lamports = account.lamports; e.executable = account.executable;
e.owner = account.owner; e.lamports = account.lamports;
e.rent_epoch = account.rent_epoch; e.owner = account.owner;
if let Some(flag) = account.data.get(PUMPFUN_GLOBAL_CASHBACK_OFFSET) { e.rent_epoch = account.rent_epoch;
e.global.is_cashback_enabled = *flag != 0; if let Some(flag) = account.data.get(PUMPFUN_GLOBAL_CASHBACK_OFFSET) {
e.global.is_cashback_enabled = *flag != 0;
}
} }
DexEvent::PumpFunBondingCurveAccountEvent(e) => {
e.executable = account.executable;
e.lamports = account.lamports;
e.owner = account.owner;
e.rent_epoch = account.rent_epoch;
}
_ => {}
} }
} }
@@ -215,6 +215,23 @@ pub(crate) fn convert_parser_event(
); );
Some(DexEvent::PumpFunGlobalAccountEvent(pumpfun_global_account_from_parser(e, meta))) Some(DexEvent::PumpFunGlobalAccountEvent(pumpfun_global_account_from_parser(e, meta)))
} }
PbDexEvent::PumpFunBondingCurveAccount(e) => {
let meta = adapt_pm(
e.metadata.clone(),
bt,
recv_wall_us,
ProtocolType::PumpFun,
EventType::AccountPumpFunBondingCurve,
pump_program(),
);
Some(DexEvent::PumpFunBondingCurveAccountEvent(
pumpfun_bonding_curve_account_from_parser(e, meta),
))
}
PbDexEvent::PumpFunFeeConfigAccount(_)
| PbDexEvent::PumpFunSharingConfigAccount(_)
| PbDexEvent::PumpFunGlobalVolumeAccumulatorAccount(_)
| PbDexEvent::PumpFunUserVolumeAccumulatorAccount(_) => None,
PbDexEvent::PumpSwapTrade(t) => pumpswap_trade_from_parser(t, bt, recv_wall_us), PbDexEvent::PumpSwapTrade(t) => pumpswap_trade_from_parser(t, bt, recv_wall_us),
PbDexEvent::PumpSwapBuy(b) => { PbDexEvent::PumpSwapBuy(b) => {
+4
View File
@@ -77,6 +77,8 @@ mod tests {
t.program = Pubkey::new_unique(); t.program = Pubkey::new_unique();
t.global_volume_accumulator = Pubkey::new_unique(); t.global_volume_accumulator = Pubkey::new_unique();
t.user_volume_accumulator = Pubkey::new_unique(); t.user_volume_accumulator = Pubkey::new_unique();
t.associated_creator_vault = Pubkey::new_unique();
t.sharing_config = Pubkey::new_unique();
t.fee_config = Pubkey::new_unique(); t.fee_config = Pubkey::new_unique();
t.fee_program = Pubkey::new_unique(); t.fee_program = Pubkey::new_unique();
t.quote_mint = Pubkey::new_unique(); t.quote_mint = Pubkey::new_unique();
@@ -108,6 +110,8 @@ mod tests {
assert_ne!(st.program, Pubkey::default()); assert_ne!(st.program, Pubkey::default());
assert_ne!(st.global_volume_accumulator, Pubkey::default()); assert_ne!(st.global_volume_accumulator, Pubkey::default());
assert_ne!(st.user_volume_accumulator, Pubkey::default()); assert_ne!(st.user_volume_accumulator, Pubkey::default());
assert_ne!(st.associated_creator_vault, Pubkey::default());
assert_ne!(st.sharing_config, Pubkey::default());
assert_ne!(st.fee_config, Pubkey::default()); assert_ne!(st.fee_config, Pubkey::default());
assert_ne!(st.fee_program, Pubkey::default()); assert_ne!(st.fee_program, Pubkey::default());
assert_ne!(st.quote_mint, Pubkey::default()); assert_ne!(st.quote_mint, Pubkey::default());
@@ -7,10 +7,11 @@ use crate::streaming::event_parser::protocols::pumpfun::events::{
PumpFeesRevokeFeeSharingAuthorityEvent, PumpFeesShareholder, PumpFeesRevokeFeeSharingAuthorityEvent, PumpFeesShareholder,
PumpFeesTransferFeeSharingAuthorityEvent, PumpFeesUpdateAdminEvent, PumpFeesTransferFeeSharingAuthorityEvent, PumpFeesUpdateAdminEvent,
PumpFeesUpdateFeeConfigEvent, PumpFeesUpdateFeeSharesEvent, PumpFeesUpsertFeeTiersEvent, PumpFeesUpdateFeeConfigEvent, PumpFeesUpdateFeeSharesEvent, PumpFeesUpsertFeeTiersEvent,
PumpFunCreateTokenEvent, PumpFunCreateV2TokenEvent, PumpFunGlobalAccountEvent, PumpFunBondingCurveAccountEvent, PumpFunCreateTokenEvent, PumpFunCreateV2TokenEvent,
PumpFunMigrateBondingCurveCreatorEvent, PumpFunMigrateEvent, PumpFunTradeEvent, PumpFunGlobalAccountEvent, PumpFunMigrateBondingCurveCreatorEvent, PumpFunMigrateEvent,
PumpFunTradeEvent,
}; };
use crate::streaming::event_parser::protocols::pumpfun::types::Global; use crate::streaming::event_parser::protocols::pumpfun::types::{BondingCurve, Global};
use crate::streaming::event_parser::protocols::pumpswap::events::{ use crate::streaming::event_parser::protocols::pumpswap::events::{
PumpSwapBuyEvent, PumpSwapCreatePoolEvent, PumpSwapDepositEvent, PumpSwapSellEvent, PumpSwapBuyEvent, PumpSwapCreatePoolEvent, PumpSwapDepositEvent, PumpSwapSellEvent,
PumpSwapWithdrawEvent, PumpSwapWithdrawEvent,
@@ -332,6 +333,32 @@ pub(crate) fn pumpfun_global_account_from_parser(
} }
} }
pub(crate) fn pumpfun_bonding_curve_account_from_parser(
e: sol_parser_sdk::core::events::PumpFunBondingCurveAccountEvent,
meta: EventMetadata,
) -> PumpFunBondingCurveAccountEvent {
PumpFunBondingCurveAccountEvent {
metadata: meta,
pubkey: e.pubkey,
executable: false,
lamports: 0,
owner: pump_program(),
rent_epoch: 0,
bonding_curve: BondingCurve {
virtual_token_reserves: e.bonding_curve.virtual_token_reserves,
// Streamer keeps the historical SOL field names; SDK v0.4.15 uses quote reserves.
virtual_sol_reserves: e.bonding_curve.virtual_quote_reserves,
real_token_reserves: e.bonding_curve.real_token_reserves,
real_sol_reserves: e.bonding_curve.real_quote_reserves,
token_total_supply: e.bonding_curve.token_total_supply,
complete: e.bonding_curve.complete,
creator: e.bonding_curve.creator,
is_mayhem_mode: e.bonding_curve.is_mayhem_mode,
is_cashback_coin: e.bonding_curve.is_cashback_coin,
},
}
}
pub(crate) fn pumpswap_buy_full_from_parser( pub(crate) fn pumpswap_buy_full_from_parser(
b: sol_parser_sdk::core::events::PumpSwapBuyEvent, b: sol_parser_sdk::core::events::PumpSwapBuyEvent,
meta: EventMetadata, meta: EventMetadata,