<div align="center">
<h1>β‘ Sol Parser SDK</h1>
<h3><em>Ultra-low latency Solana DEX event parser with SIMD optimization</em></h3>
</div>
<p align="center">
<strong>High-performance Rust library for parsing Solana DEX events with microsecond-level latency</strong>
</p>
<p align="center">
<a href="https://crates.io/crates/sol-parser-sdk">
<img src="https://img.shields.io/crates/v/sol-parser-sdk.svg" alt="Crates.io">
</a>
<a href="https://docs.rs/sol-parser-sdk">
<img src="https://docs.rs/sol-parser-sdk/badge.svg" alt="Documentation">
</a>
<a href="https://github.com/0xfnzero/solana-streamer/blob/main/LICENSE">
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
</a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white" alt="Rust">
<img src="https://img.shields.io/badge/Solana-9945FF?style=for-the-badge&logo=solana&logoColor=white" alt="Solana">
<img src="https://img.shields.io/badge/SIMD-FF6B6B?style=for-the-badge&logo=intel&logoColor=white" alt="SIMD">
<img src="https://img.shields.io/badge/gRPC-4285F4?style=for-the-badge&logo=grpc&logoColor=white" alt="gRPC">
</p>
<p align="center">
<a href="https://github.com/0xfnzero/sol-parser-sdk/blob/main/README_CN.md">δΈζ</a> |
<a href="https://github.com/0xfnzero/sol-parser-sdk/blob/main/README.md">English</a> |
<a href="https://fnzero.dev/">Website</a> |
<a href="https://t.me/fnzero_group">Telegram</a> |
<a href="https://discord.gg/vuazbGkqQE">Discord</a>
</p>
---
## π Performance Highlights
### β‘ Ultra-Low Latency
- **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
### ποΈ Flexible Order Modes
| **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 | Full slot ordering, wait for complete slot |
### π Optimization Highlights
- β
**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
---
## π₯ Quick Start
### Installation
Clone the repository:
```bash
cd your_project_dir
git clone https://github.com/0xfnzero/sol-parser-sdk
```
Add to your `Cargo.toml`:
```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"] }
```
### Performance Testing
Test parsing latency with the optimized examples:
```bash
# PumpFun with detailed metrics
cargo run --example pumpfun_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ζ₯ζΆζΆι΄: 1234567890 ΞΌs
# δΊδ»Άζ₯ζΆζΆι΄: 1234567900 ΞΌs
# ε»ΆθΏζΆι΄: 10 ΞΌs <-- Ultra-low latency!
```
### Examples
| **PumpFun Examples** |
| `pumpfun_with_metrics` | PumpFun event parsing with detailed performance metrics | `cargo run --example pumpfun_with_metrics --release` |
| `pumpfun_trade_filter` | PumpFun trade type filtering (Buy/Sell/BuyExactSolIn) - Unordered | `cargo run --example pumpfun_trade_filter --release` |
| `pumpfun_trade_filter_ordered` | PumpFun trade filtering with StreamingOrdered mode | `cargo run --example pumpfun_trade_filter_ordered --release` |
| `pumpfun_quick_test` | Quick PumpFun connection test (receives first 10 events) | `cargo run --example pumpfun_quick_test --release` |
| `parse_pump_tx` | Parse specific PumpFun transaction from RPC | `TX_SIGNATURE=<sig> cargo run --example parse_pump_tx --release` |
| `debug_pump_tx` | Debug PumpFun transaction parsing | `cargo run --example debug_pump_tx --release` |
| **PumpSwap Examples** |
| `pumpswap_low_latency` | PumpSwap ultra-low latency testing (Unordered, full event data) | `cargo run --example pumpswap_low_latency --release` |
| `pumpswap_ordered` | PumpSwap Buy/Sell/CreatePool with MicroBatch ordering | `cargo run --example pumpswap_ordered --release` |
| `parse_pumpswap_tx` | Parse specific PumpSwap transaction from RPC | `TX_SIGNATURE=<sig> cargo run --example parse_pumpswap_tx --release` |
| `debug_pumpswap_tx` | Debug PumpSwap transaction parsing | `cargo run --example debug_pumpswap_tx --release` |
| **Meteora DAMM Examples** |
| `meteora_damm_grpc` | Meteora DAMM gRPC streaming (Swap/Swap2/AddLiquidity/RemoveLiquidity) | `cargo run --example meteora_damm_grpc --release` |
| `parse_meteora_damm_tx` | Parse specific Meteora DAMM transaction from RPC | `TX_SIGNATURE=<sig> cargo run --example parse_meteora_damm_tx --release` |
| **Utility Examples** |
| `dynamic_subscription` | Dynamic filter updates without reconnecting | `cargo run --example dynamic_subscription --release` |
### Basic Usage
```rust
use sol_parser_sdk::grpc::{YellowstoneGrpc, ClientConfig, OrderMode, EventTypeFilter, EventType};
#[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,
)?;
// Filter for PumpFun Trade events only (ultra-fast path)
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunTrade
]);
// 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(())
}
```
---
## ποΈ Supported Protocols
### DEX Protocols
- β
**PumpFun** - Meme coin trading (ultra-fast zero-copy path)
- β
**PumpSwap** - PumpFun swap protocol
- β
**Raydium AMM V4** - Automated Market Maker
- β
**Raydium CLMM** - Concentrated Liquidity
- β
**Raydium CPMM** - Concentrated Pool
- β
**Orca Whirlpool** - Concentrated liquidity AMM
- β
**Meteora AMM** - Dynamic AMM
- β
**Meteora DAMM** - Dynamic AMM V2
- β
**Meteora DLMM** - Dynamic Liquidity Market Maker
- β
**Bonk Launchpad** - Token launch platform
### Event Types
Each protocol supports:
- π **Trade/Swap Events** - Buy/sell transactions
- π§ **Liquidity Events** - Deposits/withdrawals
- π **Pool Events** - Pool creation/initialization
- π― **Position Events** - Open/close positions (CLMM)
---
## β‘ Performance Features
### Zero-Copy Parsing
```rust
// 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()?;
```
### SIMD Pattern Matching
```rust
// 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;
}
```
### Event Type Filtering
```rust
// 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
);
}
}
```
### Lock-Free Queue
```rust
// 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
}
```
---
## π― Event Filtering
Reduce processing overhead by filtering specific events:
### Example: Trading Bot
```rust
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunTrade,
EventType::RaydiumAmmV4Swap,
EventType::RaydiumClmmSwap,
EventType::OrcaWhirlpoolSwap,
]);
```
### Example: Pool Monitor
```rust
let event_filter = EventTypeFilter::include_only(vec![
EventType::PumpFunCreate,
EventType::RaydiumClmmCreatePool,
EventType::OrcaWhirlpoolInitialize,
]);
```
**Performance Impact:**
- 60-80% reduction in processing
- Lower memory usage
- Reduced network bandwidth
---
## π§ Advanced Features
### Create+Buy Detection
Automatically detects when a token is created and immediately bought in the same transaction:
```rust
// 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;
}
```
### Dynamic Subscription
Update filters without reconnecting:
```rust
grpc.update_subscription(
vec![new_transaction_filter],
vec![new_account_filter],
).await?;
```
### Order Modes
Choose the right balance between latency and ordering:
```rust
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()
};
// Full slot ordering (1-50ms, wait for complete slot)
let config = ClientConfig {
order_mode: OrderMode::Ordered,
order_timeout_ms: 100,
..ClientConfig::default()
};
```
### Performance Metrics
```rust
let config = ClientConfig {
enable_metrics: true,
..ClientConfig::default()
};
let grpc = YellowstoneGrpc::new_with_config(endpoint, token, config)?;
```
---
## π Project Structure
```
src/
βββ core/
β βββ events.rs # Event definitions
βββ grpc/
β βββ client.rs # Yellowstone gRPC client
β βββ buffers.rs # SlotBuffer & MicroBatchBuffer
β βββ types.rs # OrderMode, ClientConfig, filters
βββ 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
```
---
## π Optimization Techniques
### 1. **SIMD String Matching**
- Replaced all `.contains()` with `memmem::Finder`
- 3-10x performance improvement
- Pre-compiled static finders
### 2. **Zero-Copy Parsing**
- Stack-allocated buffers (512 bytes)
- No heap allocation in hot path
- Inline helper functions
### 3. **Event Type Filtering**
- Early filtering at protocol level
- Conditional Create detection
- Single-type ultra-fast path
### 4. **Lock-Free Queue**
- ArrayQueue (100K capacity)
- Spin-wait hybrid strategy
- No mutex overhead
### 5. **Aggressive Inlining**
```rust
#[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
}
}
```
---
## π Benchmarks
### Parsing Latency (Release Mode)
| 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 |
### SIMD Pattern Matching
| Protocol detection | 50-100ns | 10-20ns | 3-10x |
| Create event detection | 150ns | 30ns | 5x |
---
## π License
MIT License
## π Contact
- **Repository**: https://github.com/0xfnzero/solana-streamer
- **Telegram**: https://t.me/fnzero_group
- **Discord**: https://discord.gg/vuazbGkqQE
---
## β οΈ Performance Tips
1. **Use Event Filtering** - Filter at the source for 60-80% performance gain
2. **Run in Release Mode** - `cargo build --release` for full optimization
3. **Test with sudo** - `sudo cargo run --example basic --release` for accurate timing
4. **Monitor Latency** - Check `grpc_recv_us` and queue latency in production
5. **Tune Queue Size** - Adjust ArrayQueue capacity based on your throughput
6. **Spin-Wait Strategy** - Tune spin count (default: 1000) for your use case
## π¬ Development
```bash
# Run tests
cargo test
# Build release binary
cargo build --release
# Generate docs
cargo doc --open
```