High-performance Rust library for parsing Solana DEX events with microsecond-level latency
δΈζ | English | Website | Telegram | Discord
Parser SDK language versions and related Rust SDKs:
| Language | Repository | Description | Version |
|---|---|---|---|
| Rust | sol-parser-sdk | Ultra-low latency with SIMD optimization | v0.7.13 |
| Node.js | sol-parser-sdk-nodejs | TypeScript/JavaScript for Node.js | v0.5.19 |
| Python | sol-parser-sdk-python | Async/await native support | v0.5.12 |
| Go | sol-parser-sdk-golang | Concurrent-safe with goroutine support | v0.5.12 |
| Rust | sol-shred-sdk | Raw Solana shred decoding and ShredStream DEX event parsing | v4.0.4 |
| Rust | sol-trade-sdk | Solana DEX trade construction and transaction execution | v6.0.1 |
Adds signed Pump depth-2 create-event replay coverage, including ALT-loaded accounts and executed logs. Existing event layouts and public parsing interfaces remain unchanged.
Validation includes official Pump SDK 4.1.0 instruction comparisons, signed local LiteSVM simulations and SDK regressions. Local simulation state/config is synthetic; no funded transactions were broadcast and production latency was not measured.
Fixes PumpFun migration event decoding from event CPI instructions, including captured migrate_v2 and already-migrated transaction regressions. Retains the signed transaction, loaded-address, ordered stream and parser lifecycle hardening from 0.7.11.
Published together with solana-streamer-sdk 3.0.10, which pins this parser release. Validation uses offline transaction fixtures and local tests; no funded mainnet transactions are broadcast.
Hardens signed transaction sanitization, loaded-address boundaries, ordered stream filtering and parser lifecycle. Aligns CLMM and DEX instruction/event layouts, nested CPI route attribution and liquidity/reward accounting. Adds independently signed wire fixtures, ALT failure cases and offline bank regressions.
Validation includes local CPU benchmarks and offline signed-bank scenarios. Measured hot paths use cached inputs without RPC. Benchmarks do not establish production network or transaction-landing latency. No funded mainnet transactions were broadcast.
sol-parser-sdk is the low-level Rust parser core for Solana DEX events. It is designed for trading bots, copy-trading pipelines, sniper bots, indexers, and stream processors that need fast, typed parsing from Yellowstone gRPC transactions, Jito ShredStream entries, RPC transaction payloads, or account subscriptions.
| Area | Coverage |
|---|---|
| Parser inputs | Yellowstone gRPC, ShredStream, RPC transactions, encoded transactions, protocol account data |
| DEX protocols | PumpFun, PumpSwap, Pump Fees, LaunchLab (including StonkFun), Raydium CPMM, Raydium CLMM, Raydium AMM V4, Meteora DAMM v2, Meteora DLMM, Meteora DBC, Orca Whirlpool |
| Parser backends | Default Borsh parser for maintainability, optional zero-copy parser for latency-sensitive hot paths |
| Related SDK | Use solana-streamer (3.0.11) when you want a higher-level streaming facade over this parser core |
- 10-20ΞΌs parsing latency in release mode
- Zero-copy parsing with stack-allocated buffers
- SIMD-accelerated pattern matching (memchr)
- Lock-free ArrayQueue for event delivery
| Mode | Latency | Description |
|---|---|---|
| Unordered | 10-20ΞΌs | Immediate output, ultra-low latency |
| MicroBatch | 50-200ΞΌs | Micro-batch ordering with time window |
| StreamingOrdered | 0.1-5ms | Stream ordering with continuous sequence release |
| Ordered | 1-50ms | Buffered slot ordering, flush on newer slot or timeout |
Ordered output retains its last emitted (slot, tx_index) watermark. A newer-slot flush closes older slots; timeout flushing still accepts later transactions in the same slot with a higher index. Late data from closed slots or at/before the watermark is dropped with an Ordered continuity break warning. Events within one transaction preserve parser order. This mode cannot guarantee upstream completeness.
- β Zero heap allocation for hot paths
- β SIMD pattern matching for all protocol detection
- β Static pre-compiled finders for string search
- β Inline functions with aggressive optimization
- β Event type filtering for targeted parsing
- β Conditional Create detection (only when needed)
- β Multiple order modes for latency vs ordering trade-off
Clone the repository:
cd your_project_dir
git clone https://github.com/0xfnzero/sol-parser-sdkAdd to your Cargo.toml:
[dependencies]
# Default: Borsh parser
sol-parser-sdk = { path = "../sol-parser-sdk" }
# Or: Zero-copy parser (maximum performance)
sol-parser-sdk = { path = "../sol-parser-sdk", default-features = false, features = ["parse-zero-copy"] }# Add to your Cargo.toml
sol-parser-sdk = "0.7.13"Or with the zero-copy parser (maximum performance):
sol-parser-sdk = { version = "0.7.13", default-features = false, features = ["parse-zero-copy"] }- Matches PumpFun create/create_v2 accounts by the actual instruction discriminator and event mint, including CPI calls; ambiguous matches are left unspecified.
- Stops inferring quote mint/vault/token-program fields from arbitrary remaining create_v2 accounts and preserves authoritative decoded fields.
- Restores historical CreateEvent decoding and verifies successful and failed transactions using saved mainnet fixtures.
- Fixes PumpSwap
boost_buy_and_burnvault and token-program backfills using its own account layout and boost vault authority. - Preserves strict pool, direction, user and uniqueness matching, plus count-aware ALT enrichment for regular trades.
- Aligns log-derived instruction positions past Ed25519, secp256k1 and secp256r1 precompiles.
- Adds offline mainnet replay fixtures for boost buys and precompile-containing sells across RPC and both Yellowstone parsing paths.
- Updates CPMM creator-fee collection accounts, share PDA and AmmConfig share-rate decoding.
- Fixes failed-transaction event suppression and instruction/account preservation.
- Adds RPC capture/replay examples and 13 mainnet transactions with 17 independently checked operations.
- Run
cargo run --example rpc_corpus_validate -- --listto view real signatures; run without arguments for offline validation.
- Adds opt-in instruction-level route analysis with CPI positions, observed transfers, native SOL/WSOL lifecycle evidence, and unknown-program coverage.
- Tracks verified StonkFun inner/graduated pool identities and migration clues without assuming every CPMM pool is StonkFun.
- Adds raw gRPC account snapshots with slot/write-version ordering and a cache capture example for RPC-free trading hot paths.
- Anchors Raydium CLMM/CPMM, Orca Whirlpool, Meteora DLMM, and Raydium AMM account fills on the event's own pool so multi-hop routes no longer cross-fill vaults or configs from a sibling swap.
- Exposes instruction account fields on CPMM/CLMM/Whirlpool/DLMM/AMM swap events (config, vaults, mints, observation, tick arrays / bitmap extension where applicable).
- Tightens invoke matching helpers used by account fillers and merger paths.
- Backfills Meteora DAMM v2 swap/swap2 mint, vault, payer, token-program, and remaining instruction accounts from the matching pool's real swap instruction, including optional referral handling.
- Avoids assigning accounts from a different pool or from ambiguous repeated swaps in the same pool.
- Verifies both transactions reported in solana-streamer issue #82 with live mainnet RPC regressions for the default and zero-copy parsers.
- Adds
Protocol::StonkFunandProtocol::LaunchLabas the preferred subscription names; the oldProtocol::RaydiumLaunchlabremains compatible. - Identifies StonkFun standard and reward pools from their official LaunchLab platform configuration accounts.
- Opt-in RPC/Yellowstone route inspection preserves CPI positions, mint flows, limits, observed amounts and opaque programs; migration events expose pool provenance. See the StonkFun route analysis and account subscriptions.
- Parses the complete current LaunchLab trade event, including reserves, all fee legs, pool status, and the three appended trade accounts.
- Supports the current 18-account LaunchLab trade instruction layout and preserves the appended accounts when merging log and instruction events.
- Adds a real mainnet StonkFun reward-pool transaction regression using signature
4Pb4vgRq6rAFi5NmMZMsfBvuwVVsvBqhySfPS3naMksujvEiGtPjxRLape7V82ZVQvxt7P8YKPCL6RSWTreMUFrY. - Adds a real mainnet graduated StonkFun CPMM swap regression using signature
3jiXX1AXnQfve1FCHwqUUXoM2BpS2jZEDNB7S6UXLdHGQa3VmBoWNVw9A2gTLbvEZeSU697s9XKgKDqxaR92Qqcz.
Run the gated mainnet parser regression with:
RUN_MAINNET_TESTS=1 cargo test --test current_mainnet_transactions current_stonkfun_reward_trade_preserves_platform_quote_accounts_and_fees -- --nocapture
RUN_MAINNET_TESTS=1 cargo test --test current_mainnet_transactions current_stonkfun_graduated_cpmm_swap_parses_from_mainnet -- --nocapture- Syncs the vendored PumpFun, PumpSwap, and Pump Fees IDLs with the current official
pump-public-docsdefinitions. - Adds current creator-fee, holder-reward, quote, cashback, buyback, and pool configuration fields across instruction, log, account, RPC, gRPC, and ShredStream parsing paths.
- Preserves PumpFun holder-reward values when merging outer instructions with event-CPI data and keeps the multi-language event schema aligned.
- Rejects truncated known PumpSwap trade and CreatePool tails while retaining complete historical layouts and forward-compatible appended fields.
- Syncs vendored Meteora DAMM v2 IDL to 0.2.4 and DBC IDL to 0.2.1.
- Adds parsers for DAMM v2 Position Delegate and config events:
EvtUpdateDelegatePermission,EvtWithdrawDeadLiquidityReward,EvtCreateConfig, andEvtCreateDynamicConfig(including the 0.2.4permissionfield). - Wires the new events through log, optimized matcher, and inner-instruction paths, plus
EventType/DexEventfilters. - Identifies Yellowstone V1 messages through
Message.configand exposes all four transaction-config requests: priority fee, compute-unit limit, loaded-accounts data-size limit, and heap size. V1 ComputeBudget instructions remain ignored as required by Solana. - Yellowstone V1 ingestion requires
yellowstone-grpc-proto >= 12.6.0and a server running Yellowstone geyser plugin>= 15.1.1; older server plugins silently downgrade V1 to V0 and discardMessage.configbefore transmission. - Accelerates RPC inner-instruction Base58 decoding through the portable safe
base58-turbopath. The saved mainnet corpus reduces end-to-end RPC parse latency by 17.7% to more than 80%, depending on instruction payload size. - Borrows RPC log and balance metadata through the parse path to avoid redundant cloning. The final cross-protocol corpus parses PumpFun, PumpSwap, Raydium CPMM, and Meteora/Orca transactions in 7.40-11.80 us.
- Adds offline PumpFun, PumpSwap, Raydium CPMM, and Meteora DLMM/Orca RPC fixtures with exact event regression tests and a shared cross-protocol benchmark.
- Fixes current Meteora DAMM v2
EvtSwap2parsing for the 180-byte layout, all three swap modes, transfer fees, reserves, and the mainnet fee-layout upgrade boundary. - Adds the current unified
EvtLiquidityChangediscriminator and routes itschange_typeto exact AddLiquidity or RemoveLiquidity events across log, optimized, and inner-instruction paths. - Adds reproducible mainnet RPC regression tests for DAMM v2 Swap and AddLiquidity transactions.
- Upgrades the public Solana types to Solana 4, including Legacy, V0, and V1 transaction messages.
- Uses
wincode 0.5.5in production ShredStream and RPC transaction decode paths. On the reproducible 21,000-byte Entry benchmark, decode latency dropped from the previous bincode baseline of 39.005 us/op to 8.956 us/op (77.0%, 4.36x faster). - Removes unused direct dependencies and aligns the Agave dependency family. The normal dependency graph dropped from 658 to 533 package/version entries, while duplicated crate names dropped from 111 to 28.
- Requires Rust 1.91 or newer for the Solana 4 client dependency stack.
- Adds Meteora DLMM user token account context and preserves backward-compatible Serde defaults.
- Adds the post-transaction
token_balanceto PumpFun trade events in raw mint units. - Adds the post-transaction
sol_balancein lamports, filled directly from transaction metadata without extra RPC calls. - Reduces end-to-end PumpFun Yellowstone parsing latency by 34.23% on the captured benchmark fixture, from 6.7349 us to 4.4293 us.
- Adds reproducible Criterion benchmarks, a captured Yellowstone transaction fixture, and live balance-delta validation.
- Adds
token_x_mintandtoken_y_mintcontext to current Meteora DLMM swap events. - Anchors mint enrichment to each event pool so multi-leg DLMM routes cannot reuse another pool's accounts.
- Adds reusable mainnet RPC examples captured on 2026-08-14 for direct
swapand CPIswap2parsing. - Keeps JSON produced before the new mint fields compatible with Serde deserialization.
- Exposes current LaunchLab quote mint and global configuration context, including USD1 pools.
- Adds opt-in transaction fee, priority fee, compute budget, and SWQoS tip parsing for all providers supported by sol-trade-sdk.
- Identifies each recognized tip provider and recipient while keeping the disabled transaction-cost path allocation-free and effectively zero-cost.
- Adds reusable mainnet transaction fixtures captured on 2026-08-13 for LaunchLab USD1 and transaction-cost parsing.
- Parses the current Meteora DLMM Anchor event-CPI prefix layout while retaining legacy suffix compatibility.
- Aligns Meteora DLMM, Raydium CPMM/AMM V4, and Orca Whirlpool event and account layouts with current official sources.
- Preserves repeated swaps and liquidity events with occurrence-aware log/instruction deduplication and stack-aware CPI merging.
- Adds reusable mainnet transaction fixtures captured on 2026-08-13 for Meteora DLMM, PumpFun, PumpSwap, Raydium, and Orca.
- Decodes the complete current PumpSwap Buy/Sell event tail across log and CPI/inner-instruction paths: cashback, buyback fees, signed virtual quote reserves, boost eligibility, and base supply.
- Uses one validated PumpSwap trade decoder for the default and zero-copy feature configurations while preserving historical event layouts.
- Rejects truncated tails, malformed UTF-8, invalid Borsh booleans, and overflowing string bounds instead of emitting partially decoded events.
- Keeps older serialized PumpSwap events compatible by defaulting fields introduced by the buyback and boost upgrades.
- Fixes Pump.fun
create_v2quote mint parsing for both 16-account and 19-account layouts. - Uses the appended quote mint only when the 19-account quote-pool tail is present; 16-account
create_v2keeps the SOL sentinel. - Selects the matching create/create_v2 instruction when filling accounts so later buy/sell instructions cannot overwrite create quote fields.
- Preserves real Pump.fun WSOL quote mints (
So11111111111111111111111111111111111111112) in gRPC and ShredStream create/trade outputs. - Keeps the Solscan SOL sentinel (
So11111111111111111111111111111111111111111) only for legacy or missing Pump.fun quote mint fields. - Adds merge coverage so a placeholder SOL quote mint can be replaced by a later real WSOL quote mint from logs or instruction/account context.
- Parses PumpSwap
create_poolinstruction args, includingindex, deposit amounts,coin_creator,is_mayhem_mode, andis_cashback_coin. - Fixes PumpSwap
create_poolinstruction account mapping to match the IDL (pool,creator,base_mint,quote_mint, LP/user token accounts). - Preserves
is_cashback_coinwhen instruction-derived CreatePool data is merged with log-derived CreatePool data. - Clarifies source semantics: the PumpSwap log
CreatePoolEventIDL does not carryis_cashback_coin; ShredStream/outer-instruction parsing can read it from instruction data, and account subscriptions can read the authoritativePoolaccount field.
- Aligns PumpSwap
CreatePoolEventwith the on-chain IDL: the event exposesis_mayhem_modebut notis_cashback_coin. - Keeps PumpSwap
is_cashback_coinon theAccountPumpSwapPoolaccount event, where the on-chainPoolaccount stores it. - Fixes the PumpSwap CreatePool log payload length check to include the final
is_mayhem_modebyte. - Documents that ShredStream CreatePool events cannot recover
is_cashback_coinbecause Shred entries do not include account bodies.
- Implements real Yellowstone gRPC
stop()behavior by signaling, aborting, and awaiting the active subscription task. - Serializes gRPC subscription lifecycle transitions so concurrent stop/re-subscribe calls cannot orphan retry loops.
- Uses a per-subscription stop signal so a new subscription cannot accidentally reset the stop state for an older task.
- Labels stream failures as
Grpc Stream errorto distinguish them from ShredStream logs. - Makes the warmup test independent from global test execution order.
- Adds configurable ShredStream event filter examples, including Pump.fun trade, create-trade, buy, sell, and buy-exact-sol-in presets.
- Clarifies Pump.fun IDL instruction names in
ix_name:buy,buy_v2,buy_exact_sol_in,buy_exact_quote_in_v2,sell, andsell_v2. - Keeps Pump.fun filter families aligned with IDL semantics:
PumpFunBuycovers all buy instructions,PumpFunSellcovers all sell instructions, andPumpFunTradecovers all buy and sell instructions. - Ensures subscribing only to
PumpFunTradeemits unifiedDexEvent::PumpFunTradeevents on the ShredStream hot path.
- Aligns ShredStream static-account parsing across Rust, Node.js, Python, and Go.
- Keeps V0 ALT-loaded instruction accounts on the hot path with default pubkey placeholders instead of dropping the whole instruction.
- Adds discriminator fallback when a ShredStream outer program id is ALT-loaded and not present in the static account table.
- Improves Pump.fun ShredStream parity for create/create_v2, v2 short-account trades, and event-type filtering.
- Refreshes multi-protocol routing and account-fill documentation for Pump.fun, PumpSwap, Pump Fees, Raydium, Orca, and Meteora paths.
- Emits Pump.fun
createandcreate_v2as one canonicalPumpFunCreateevent. - Treats
PumpFunCreateandPumpFunCreateV2filters as the same create-family subscription. - Keeps create_v2 account fields on the canonical create event so bots do not need to handle two event variants.
- Prevents duplicate new-mint callbacks from gRPC log + instruction parsing.
- Preserves real Pump.fun v2
ix_namevalues, includingbuy_v2,sell_v2, andbuy_exact_quote_in_v2. - Improves ShredStream Pump.fun v2 parsing with best-effort short-account handling for buy, sell, and exact-quote instructions.
- Treats Pump.fun buy-family filters symmetrically, so
PumpFunBuyandPumpFunBuyExactSolInsubscriptions both match the compatible buy variants. - Keeps ShredStream ALT/default-account best-effort parsing for outer instructions while preserving the CPI/inner-only limitation.
Transaction-cost parsing is opt-in and does not run on the default DEX event path:
use sol_parser_sdk::{parse_yellowstone_transaction_cost, SwqosProvider};
let cost = parse_yellowstone_transaction_cost(&transaction, &meta).unwrap();
let jito_tip = cost.tip_lamports_for(SwqosProvider::Jito);Yellowstone and RPC results use status metadata for the authoritative transaction fee and
confirmed tip status. transaction_fee_lamports already includes the priority fee; relay tips
are separate transfers and are added only in total_fee_and_tip_lamports. Tip recipients for every
SWQoS provider supported by sol-trade-sdk are recognized automatically, and each TipPayment
identifies its provider. ShredStream can expose requested compute-budget values and outer tip
transfers, but cannot confirm fees, execution, inner instructions, or ALT-loaded tip recipients.
Test parsing latency with the optimized examples:
# PumpFun with detailed metrics (per-event + 10s stats)
cargo run --example pumpfun_with_metrics --release
# PumpSwap with detailed metrics (per-event + 10s stats)
cargo run --example pumpswap_with_metrics --release
# PumpSwap ultra-low latency test
cargo run --example pumpswap_low_latency --release
# PumpSwap with MicroBatch ordering
cargo run --example pumpswap_ordered --release
# Expected output:
# gRPC receive time: 1234567890 ΞΌs
# Event receive time: 1234567900 ΞΌs
# Latency: 10 ΞΌs <-- Ultra-low latency!| Description | Run Command | Source Code |
|---|---|---|
| PumpFun | ||
| PumpFun event parsing with metrics | cargo run --example pumpfun_with_metrics --release |
examples/pumpfun_with_metrics.rs |
| PumpFun trade type filtering | cargo run --example pumpfun_trade_filter --release |
examples/pumpfun_trade_filter.rs |
| PumpFun trade with ordered mode | cargo run --example pumpfun_trade_filter_ordered --release |
examples/pumpfun_trade_filter_ordered.rs |
| Quick PumpFun connection test | cargo run --example pumpfun_quick_test --release |
examples/pumpfun_quick_test.rs |
| Parse PumpFun tx by signature | TX_SIGNATURE=<sig> cargo run --example parse_pump_tx --release |
examples/parse_pump_tx.rs |
| Parse PumpFun quote-mint cases | TX_SIGNATURES=<sig1,sig2> cargo run --example parse_pumpfun_quote_cases --release |
examples/parse_pumpfun_quote_cases.rs |
| Debug PumpFun transaction | cargo run --example debug_pump_tx --release |
examples/debug_pump_tx.rs |
| PumpSwap | ||
| PumpSwap events with metrics | cargo run --example pumpswap_with_metrics --release |
examples/pumpswap_with_metrics.rs |
| PumpSwap ultra-low latency | cargo run --example pumpswap_low_latency --release |
examples/pumpswap_low_latency.rs |
| PumpSwap with MicroBatch ordering | cargo run --example pumpswap_ordered --release |
examples/pumpswap_ordered.rs |
| Parse PumpSwap tx by signature | TX_SIGNATURE=<sig> cargo run --example parse_pumpswap_tx --release |
examples/parse_pumpswap_tx.rs |
| Debug PumpSwap transaction | cargo run --example debug_pumpswap_tx --release |
examples/debug_pumpswap_tx.rs |
| Meteora DAMM | ||
| Meteora DAMM V2 events | cargo run --example meteora_damm_grpc --release |
examples/meteora_damm_grpc.rs |
| Parse Meteora DAMM tx by signature | TX_SIGNATURE=<sig> cargo run --example parse_meteora_damm_tx --release |
examples/parse_meteora_damm_tx.rs |
| Non-Pump DEX dry-run scenarios | ||
| LaunchLab migration filter | cargo run --example raydium_launchlab_migration |
examples/raydium_launchlab_migration.rs |
| Raydium CPMM new pool filter | cargo run --example raydium_cpmm_new_pool |
examples/raydium_cpmm_new_pool.rs |
| Raydium CLMM token price math | cargo run --example raydium_clmm_token_price |
examples/raydium_clmm_token_price.rs |
| Orca Whirlpool token price math | cargo run --example orca_whirlpool_token_price |
examples/orca_whirlpool_token_price.rs |
| Meteora DAMM new pool baseline | cargo run --example meteora_damm_new_pool |
examples/meteora_damm_new_pool.rs |
| Meteora DBC token price math | cargo run --example meteora_dbc_token_price |
examples/meteora_dbc_token_price.rs |
| Wallet trade filter | cargo run --example wallet_trade_filter |
examples/wallet_trade_filter.rs |
| gRPC latency slot compare config | cargo run --example grpc_latency_slot_compare |
examples/grpc_latency_slot_compare.rs |
| Account subscription | ||
| Token account balance updates | TOKEN_ACCOUNT=<pubkey> cargo run --example token_balance_listen --release |
examples/token_balance_listen.rs |
| Nonce account state changes | NONCE_ACCOUNT=<pubkey> cargo run --example nonce_listen --release |
examples/nonce_listen.rs |
| Mint account info | MINT_ACCOUNT=<pubkey> cargo run --example token_decimals_listen --release |
examples/token_decimals_listen.rs |
| PumpSwap pool accounts via memcmp | cargo run --example pumpswap_pool_account_listen --release |
examples/pumpswap_pool_account_listen.rs |
| All ATAs for mints | cargo run --example mint_all_ata_account_listen --release |
examples/mint_all_ata_account_listen.rs |
| ShredStream | ||
| Jito ShredStream subscription | cargo run --example shredstream_example --release |
examples/shredstream_example.rs |
| Utility | ||
| Dynamic subscription filters | cargo run --example dynamic_subscription --release |
examples/dynamic_subscription.rs |
| Debug PumpSwap account filling | cargo run --example test_account_filling --release |
examples/test_account_filling.rs |
use sol_parser_sdk::grpc::{
AccountFilter, ClientConfig, EventType, EventTypeFilter, OrderMode, Protocol,
TransactionFilter, YellowstoneGrpc,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create gRPC client with default config (Unordered mode)
let grpc = YellowstoneGrpc::new(
"https://solana-yellowstone-grpc.publicnode.com:443".to_string(),
None,
)?;
// Or with custom config for ordered events
let config = ClientConfig {
order_mode: OrderMode::MicroBatch, // Low latency + ordering
micro_batch_us: 100, // 100ΞΌs batch window
..ClientConfig::default()
};
let grpc = YellowstoneGrpc::new_with_config(
"https://solana-yellowstone-grpc.publicnode.com:443".to_string(),
None,
config,
)?;
let protocols = vec![Protocol::PumpFun, Protocol::PumpSwap, Protocol::RaydiumCpmm];
let transaction_filter = TransactionFilter::for_protocols(&protocols);
let account_filter = AccountFilter::for_protocols(&protocols);
// Filter before parsing for the lowest-latency path.
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunBuy,
EventType::PumpFunSell,
EventType::PumpSwapBuy,
EventType::PumpSwapSell,
EventType::RaydiumCpmmSwap,
]);
// Subscribe and get lock-free queue
let queue = grpc.subscribe_dex_events(
vec![transaction_filter],
vec![account_filter],
Some(event_filter),
).await?;
// Consume events with minimal latency
tokio::spawn(async move {
let mut spin_count = 0;
loop {
if let Some(event) = queue.pop() {
spin_count = 0;
// Process event (10-20ΞΌs latency!)
println!("{:?}", event);
} else {
// Hybrid spin-wait strategy
spin_count += 1;
if spin_count < 1000 {
std::hint::spin_loop();
} else {
tokio::task::yield_now().await;
spin_count = 0;
}
}
}
});
Ok(())
}ShredStream provides ultra-low latency (~50-100ms faster than gRPC) by directly subscribing to Jito's ShredStream service:
use sol_parser_sdk::grpc::{EventType, EventTypeFilter};
use sol_parser_sdk::shredstream::{ShredStreamClient, ShredStreamConfig};
use sol_parser_sdk::DexEvent;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create ShredStream client
let client = ShredStreamClient::new("http://127.0.0.1:10800").await?;
// Or with custom config
let config = ShredStreamConfig {
connection_timeout_ms: 5000,
request_timeout_ms: 30000,
max_decoding_message_size: 1024 * 1024 * 1024,
reconnect_delay_ms: 1000,
max_reconnect_attempts: 0, // 0 = infinite reconnect
};
let client = ShredStreamClient::new_with_config("http://127.0.0.1:10800", config).await?;
// Subscribe with SDK-side filtering before event conversion.
// Use `client.subscribe().await?` to receive every supported event.
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunBuy,
EventType::PumpSwapBuy,
EventType::RaydiumCpmmSwap,
]);
let queue = client.subscribe_with_filter(Some(event_filter)).await?;
// Consume events
loop {
if let Some(event) = queue.pop() {
match &event {
DexEvent::PumpFunTrade(e) => {
println!("PumpFun Trade: mint={}, is_buy={}", e.mint, e.is_buy);
}
DexEvent::PumpSwapBuy(e) => {
println!("PumpSwap Buy: pool={}", e.pool);
}
_ => {}
}
} else {
std::hint::spin_loop();
}
}
}ShredStream Limitations:
- Only
static_account_keys()- ALT-loaded instruction accounts use default placeholders, while outer instructions are parsed best-effort from data/discriminators - No Inner Instructions - CPI/inner-only events cannot be recovered from ShredStream entries
- No block_time - always 0
- tx_index is entry-level, not slot-level
- β PumpFun - Meme coin trading (ultra-fast zero-copy path, incl. v2 instructions)
- β Pump Fees - Pump fee-sharing configuration events
- β PumpSwap - PumpFun swap protocol
- β LaunchLab - Token launch platform, including StonkFun attribution
- β Raydium AMM V4 - Automated Market Maker
- β Raydium CLMM - Concentrated Liquidity
- β Raydium CPMM - Concentrated Pool
- β Orca Whirlpool - Concentrated liquidity AMM
- β Meteora Pools - Dynamic AMM
- β Meteora DAMM v2 - Dynamic AMM V2
- β Meteora DLMM - Dynamic Liquidity Market Maker
- π§ Meteora DBC - Program id and filters added; transaction/account parser pass pending
Each protocol supports:
- π Trade/Swap Events - Buy/sell transactions
- π§ Liquidity Events - Deposits/withdrawals
- π Pool Events - Pool creation/initialization
- π― Position Events - Open/close positions (CLMM)
| Protocol | Events | Accounts | Examples | Language constants |
|---|---|---|---|---|
| LaunchLab | Trade, pool create, migrate | Pool/config snapshots | Migration, buy/sell oracle planned | Rust, Node, Python, Go |
| Raydium CPMM | Swap, deposit, withdraw, initialize | AmmConfig, PoolState | New pool, token price | Rust, Node, Python, Go |
| Raydium CLMM | Swap, pool, position, liquidity | AmmConfig, PoolState, TickArray | Token price | Rust, Node, Python, Go |
| Raydium AMM V4 | Swap, deposit, withdraw, initialize2 | Pending | Token price oracle planned | Rust, Node, Python, Go |
| Orca Whirlpool | Swap, liquidity, pool init | Whirlpool, Position, TickArray, FeeTier, Config | Token price | Rust, Node, Python, Go |
| Meteora Pools | Swap, liquidity, pool create, fees | Pending | Token price oracle planned | Rust, Node, Python, Go |
| Meteora DAMM V2 | Swap, liquidity, position | Pending | New pool, token price oracle planned | Rust, Node, Python, Go |
| Meteora DLMM | Swap, liquidity, bin/position | Pool/bin array/bitmap snapshots | Token price oracle planned | Rust, Node, Python, Go |
| Meteora DBC | Swap, initialize pool, curve complete (Rust log parser) | Pending | Token price, migration oracle planned | Rust, Node, Python, Go |
The canonical cross-language baseline is tracked in
protocols/canonical.json. Raw account updates are opt-in via AccountRawSnapshot; specialized snapshots cover LaunchLab pools/configs, DLMM pools/bin arrays/bitmap extensions, Whirlpool dynamic arrays/adaptive Oracles and CLMM bitmap extensions.
// Stack-allocated 512-byte buffer for PumpFun Trade
const MAX_DECODE_SIZE: usize = 512;
let mut decode_buf: [u8; MAX_DECODE_SIZE] = [0u8; MAX_DECODE_SIZE];
// Decode directly to stack, no heap allocation
general_purpose::STANDARD
.decode_slice(data_part.as_bytes(), &mut decode_buf)
.ok()?;// Pre-compiled SIMD finders (initialized once)
static PUMPFUN_FINDER: Lazy<memmem::Finder> =
Lazy::new(|| memmem::Finder::new(b"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"));
// 3-10x faster than .contains()
if PUMPFUN_FINDER.find(log_bytes).is_some() {
return LogType::PumpFun;
}// Ultra-fast path for single event type
if include_only.len() == 1 && include_only[0] == EventType::PumpFunTrade {
if log_type == LogType::PumpFun {
return parse_pumpfun_trade( // Zero-copy path
log, signature, slot, block_time, grpc_recv_us, is_created_buy
);
}
}// ArrayQueue with 100,000 capacity
let queue = Arc::new(ArrayQueue::<DexEvent>::new(100_000));
// Non-blocking push/pop (no mutex overhead)
let _ = queue.push(event);
if let Some(event) = queue.pop() {
// Process event
}Reduce processing overhead by filtering specific events:
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunBuy,
EventType::PumpFunSell,
EventType::PumpFunBuyExactSolIn,
EventType::PumpSwapBuy,
EventType::PumpSwapSell,
EventType::RaydiumLaunchlabTrade,
EventType::RaydiumCpmmSwap,
EventType::RaydiumAmmV4Swap,
EventType::RaydiumClmmSwap,
EventType::OrcaWhirlpoolSwap,
EventType::MeteoraPoolsSwap,
EventType::MeteoraDammV2Swap,
EventType::MeteoraDlmmSwap,
]);let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunCreate,
EventType::PumpFeesUpdateFeeShares,
EventType::PumpSwapCreatePool,
EventType::AccountPumpSwapPool,
EventType::RaydiumCpmmInitialize,
EventType::RaydiumClmmCreatePool,
EventType::OrcaWhirlpoolPoolInitialized,
EventType::MeteoraPoolsPoolCreated,
EventType::MeteoraDammV2CreatePosition,
EventType::MeteoraDlmmInitializePool,
]);PumpSwapCreatePool includes is_mayhem_mode. For is_cashback_coin,
ShredStream/outer-instruction parsing reads the flag from the create_pool
instruction args, while log-only CreatePoolEvent payloads keep the default
false because the log event IDL does not carry this field. The authoritative
account value is also available from
PumpSwapPoolAccountEvent.pool.is_cashback_coin.
Performance Impact:
- 60-80% reduction in processing
- Lower memory usage
- Reduced network bandwidth
Automatically detects when a token is created and immediately bought in the same transaction:
// Detects "Program data: GB7IKAUcB3c..." pattern
let has_create = detect_pumpfun_create(logs);
// Sets is_created_buy flag on Trade events
if has_create {
trade_event.is_created_buy = true;
}The SDK recognizes Pump.fun's new v2 trading instructions introduced in the Bonding Curve upgrade. Event logs from buy_v2, sell_v2, and buy_exact_quote_in_v2 are parsed with the same zero-copy path and mapped to the existing event types:
| ix_name in TradeEvent | DexEvent Variant |
|---|---|
"buy" / "buy_v2" / "buy_exact_quote_in" / "buy_exact_quote_in_v2" |
DexEvent::PumpFunBuy |
"sell" / "sell_v2" |
DexEvent::PumpFunSell |
"buy_exact_sol_in" |
DexEvent::PumpFunBuyExactSolIn |
No changes are required in your event handling code β v2 events arrive through the same PumpFunTradeEvent struct with the correct ix_name field populated. Instruction discriminators for buy_v2 ([184, 23, 238, 97, 103, 197, 211, 61]), sell_v2 ([93, 246, 130, 60, 231, 233, 64, 178]), and buy_exact_quote_in_v2 ([194, 171, 28, 70, 104, 77, 91, 47]) are recognized at the instruction parser level.
CreateEvent also exposes quote_mint and virtual_quote_reserves, so USDC quote pools can be distinguished from native SOL pools and initialized with the correct quote-side reserve.
Update filters without reconnecting:
grpc.update_subscription(
vec![new_transaction_filter],
vec![new_account_filter],
).await?;Choose the right balance between latency and ordering:
use sol_parser_sdk::grpc::{ClientConfig, OrderMode};
// Ultra-low latency (no ordering guarantee)
let config = ClientConfig {
order_mode: OrderMode::Unordered,
..ClientConfig::default()
};
// Low latency with micro-batch ordering (50-200ΞΌs)
let config = ClientConfig {
order_mode: OrderMode::MicroBatch,
micro_batch_us: 100, // 100ΞΌs batch window
..ClientConfig::default()
};
// Stream ordering with continuous sequence release (0.1-5ms)
let config = ClientConfig {
order_mode: OrderMode::StreamingOrdered,
order_timeout_ms: 50, // Timeout for incomplete sequences
..ClientConfig::default()
};
// Buffered slot ordering (flush on newer slot or timeout)
let config = ClientConfig {
order_mode: OrderMode::Ordered,
order_timeout_ms: 100,
..ClientConfig::default()
};let config = ClientConfig {
enable_metrics: true,
..ClientConfig::default()
};
let grpc = YellowstoneGrpc::new_with_config(endpoint, token, config)?;src/
βββ core/
β βββ events.rs # Event definitions
βββ grpc/
β βββ client.rs # Yellowstone gRPC client
β βββ buffers.rs # SlotBuffer & MicroBatchBuffer
β βββ types.rs # OrderMode, ClientConfig, filters
βββ shredstream/
β βββ client.rs # Jito ShredStream client
β βββ config.rs # ShredStreamConfig
β βββ proto/ # Protobuf definitions
βββ logs/
β βββ optimized_matcher.rs # SIMD log detection
β βββ zero_copy_parser.rs # Zero-copy parsing
β βββ pumpfun.rs # PumpFun parser
β βββ raydium_*.rs # Raydium parsers
β βββ orca_*.rs # Orca parsers
β βββ meteora_*.rs # Meteora parsers
βββ instr/
β βββ *.rs # Instruction parsers
βββ warmup/
β βββ mod.rs # Parser warmup (auto-called)
βββ lib.rs
- Replaced all
.contains()withmemmem::Finder - 3-10x performance improvement
- Pre-compiled static finders
- Stack-allocated buffers (512 bytes)
- No heap allocation in hot path
- Inline helper functions
- Early filtering at protocol level
- Conditional Create detection
- Single-type ultra-fast path
- ArrayQueue (100K capacity)
- Spin-wait hybrid strategy
- No mutex overhead
#[inline(always)]
fn read_u64_le_inline(data: &[u8], offset: usize) -> Option<u64> {
if offset + 8 <= data.len() {
let mut bytes = [0u8; 8];
bytes.copy_from_slice(&data[offset..offset + 8]);
Some(u64::from_le_bytes(bytes))
} else {
None
}
}| Protocol | Avg Latency | Min | Max |
|---|---|---|---|
| PumpFun Trade (zero-copy) | 10-15ΞΌs | 8ΞΌs | 20ΞΌs |
| Raydium AMM V4 Swap | 15-20ΞΌs | 12ΞΌs | 25ΞΌs |
| Orca Whirlpool Swap | 15-20ΞΌs | 12ΞΌs | 25ΞΌs |
| Operation | Before (contains) | After (SIMD) | Speedup |
|---|---|---|---|
| Protocol detection | 50-100ns | 10-20ns | 3-10x |
| Create event detection | 150ns | 30ns | 5x |
MIT License
- Repository: https://github.com/0xfnzero/sol-parser-sdk
- Telegram: https://t.me/fnzero_group
- Discord: https://discord.gg/vuazbGkqQE
- Use Event Filtering - Filter at the source for 60-80% performance gain
- Run in Release Mode -
cargo build --releasefor full optimization - Test with sudo -
sudo cargo run --example basic --releasefor accurate timing - Monitor Latency - Check
grpc_recv_usand queue latency in production - Tune Queue Size - Adjust ArrayQueue capacity based on your throughput
- Spin-Wait Strategy - Tune spin count (default: 1000) for your use case
# Run tests
cargo test
# Build release binary
cargo build --release
# Generate docs
cargo doc --openShared PumpFun create/create_v2 mainnet fixtures, replay instructions and verification limits are documented in the validation guide.