sol-parser-sdk 0.8.0

A lightweight Rust library for real-time event streaming from Solana DEX trading programs. Supports PumpFun, PumpSwap, LaunchLab, and Raydium protocols with Yellowstone gRPC and ShredStream.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
Current version: **0.8.0**. SDK, native-language tests, examples and documentation are synchronized in this release. See [RELEASE_NOTES.md](RELEASE_NOTES.md) for migration details.

<div align="center">
    <h1>โšก Sol Parser SDK</h1>
    <h3><em>Ultra-low latency Solana DEX event parser with SIMD optimization</em></h3>
</div>

[Examples](examples/README.md) ยท [Documentation](docs/README.md) ยท [Release history](CHANGELOG.md)

## v0.8.0 โ€” Trade provenance and opt-in stock prices

Uniform router provenance across supported gRPC trade families, plus an opt-in
stock/ETF execution-price subscription with an extensible, screened multi-source
catalog. No RPC in the parsing hot path. Missing live conversion or liquidity
data stays unknown. See [stock price subscriptions](docs/stock-prices.md) and
[trade provenance](docs/wrapped-pumpfun.md).

[Cross-DEX stock routes](docs/cross-dex-stock-routes.md): per-leg protocol/pool
identification, Pump.fun v2 route support, and six signed mainnet replay cases.
Run `cargo run --example stock_route_replay` offline.

Stock catalog admission uses at least $500 of verified liquid-side pool reserve,
without a volume filter. Lower known fees take priority within each mint;
historical fee snapshots distinguish pool fees from token transfer taxes.
Parser and trade SDKs package the same 34-mint / 63-pool catalog and fee
preference. Offline discovery includes Stonk, Pump.fun/PumpSwap and Raydium
AMM v4/CPMM/CLMM; candidates require account, identity and depth validation.

<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/sol-parser-sdk/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>

---

## ๐Ÿ“ฆ SDK Versions and Related SDKs

Parser SDK language versions and related Rust SDKs:

| Language | Repository | Description | Version |
|----------|------------|-------------|---------|
| **Rust** | [sol-parser-sdk]https://github.com/0xfnzero/sol-parser-sdk | Ultra-low latency with SIMD optimization | `v0.8.0` |
| **Node.js** | [sol-parser-sdk-nodejs]https://github.com/0xfnzero/sol-parser-sdk-nodejs | TypeScript/JavaScript for Node.js | `v0.6.0` |
| **Python** | [sol-parser-sdk-python]https://github.com/0xfnzero/sol-parser-sdk-python | Async/await native support | `v0.6.0` |
| **Go** | [sol-parser-sdk-golang]https://github.com/0xfnzero/sol-parser-sdk-golang | Concurrent-safe with goroutine support | `v0.6.0` |
| **Rust** | [sol-shred-sdk]https://github.com/0xfnzero/sol-shred-sdk | Raw Solana shred decoding and ShredStream DEX event parsing | `v5.0.0` |
| **Rust** | [sol-trade-sdk]https://github.com/0xfnzero/sol-trade-sdk | Solana DEX trade construction and transaction execution | `v8.0.0` |

## What This SDK Is For

`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]https://github.com/0xfnzero/solana-streamer (`3.0.16`) when you want a higher-level streaming facade over this parser core |

---

## ๐Ÿ“Š 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
| 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.

### ๐Ÿš€ 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"] }
```

### Use crates.io

```toml
# Add to your Cargo.toml
sol-parser-sdk = "0.8.0"
```

Or with the zero-copy parser (maximum performance):

```toml
sol-parser-sdk = { version = "0.8.0", default-features = false, features = ["parse-zero-copy"] }
```

### Performance Testing

Transaction-cost parsing is opt-in and does not run on the default DEX event path:

```rust
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:

```bash
# 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!
```

### Examples

| Description | Run Command | Source Code |
|-------------|-------------|-------------|
| **PumpFun** | | |
| PumpFun event parsing with metrics | `cargo run --example pumpfun_with_metrics --release` | [examples/pumpfun_with_metrics.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpfun_with_metrics.rs | `v0.8.0` |
| PumpFun trade type filtering | `cargo run --example pumpfun_trade_filter --release` | [examples/pumpfun_trade_filter.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpfun_trade_filter.rs | `v0.8.0` |
| PumpFun trade with ordered mode | `cargo run --example pumpfun_trade_filter_ordered --release` | [examples/pumpfun_trade_filter_ordered.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpfun_trade_filter_ordered.rs | `v0.8.0` |
| Quick PumpFun connection test | `cargo run --example pumpfun_quick_test --release` | [examples/pumpfun_quick_test.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpfun_quick_test.rs | `v0.8.0` |
| Parse PumpFun tx by signature | `TX_SIGNATURE=<sig> cargo run --example parse_pump_tx --release` | [examples/parse_pump_tx.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/parse_pump_tx.rs | `v0.8.0` |
| Parse PumpFun quote-mint cases | `TX_SIGNATURES=<sig1,sig2> cargo run --example parse_pumpfun_quote_cases --release` | [examples/parse_pumpfun_quote_cases.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/parse_pumpfun_quote_cases.rs | `v0.8.0` |
| Debug PumpFun transaction | `cargo run --example debug_pump_tx --release` | [examples/debug_pump_tx.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/debug_pump_tx.rs | `v0.8.0` |
| **PumpSwap** | | |
| PumpSwap events with metrics | `cargo run --example pumpswap_with_metrics --release` | [examples/pumpswap_with_metrics.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpswap_with_metrics.rs | `v0.8.0` |
| PumpSwap ultra-low latency | `cargo run --example pumpswap_low_latency --release` | [examples/pumpswap_low_latency.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpswap_low_latency.rs | `v0.8.0` |
| PumpSwap with MicroBatch ordering | `cargo run --example pumpswap_ordered --release` | [examples/pumpswap_ordered.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpswap_ordered.rs | `v0.8.0` |
| Parse PumpSwap tx by signature | `TX_SIGNATURE=<sig> cargo run --example parse_pumpswap_tx --release` | [examples/parse_pumpswap_tx.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/parse_pumpswap_tx.rs | `v0.8.0` |
| Debug PumpSwap transaction | `cargo run --example debug_pumpswap_tx --release` | [examples/debug_pumpswap_tx.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/debug_pumpswap_tx.rs | `v0.8.0` |
| **Meteora DAMM** | | |
| Meteora DAMM V2 events | `cargo run --example meteora_damm_grpc --release` | [examples/meteora_damm_grpc.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/meteora_damm_grpc.rs | `v0.8.0` |
| Parse Meteora DAMM tx by signature | `TX_SIGNATURE=<sig> cargo run --example parse_meteora_damm_tx --release` | [examples/parse_meteora_damm_tx.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/parse_meteora_damm_tx.rs | `v0.8.0` |
| **Non-Pump DEX dry-run scenarios** | | |
| LaunchLab migration filter | `cargo run --example raydium_launchlab_migration` | [examples/raydium_launchlab_migration.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/raydium_launchlab_migration.rs | `v0.8.0` |
| Raydium CPMM new pool filter | `cargo run --example raydium_cpmm_new_pool` | [examples/raydium_cpmm_new_pool.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/raydium_cpmm_new_pool.rs | `v0.8.0` |
| Raydium CLMM token price math | `cargo run --example raydium_clmm_token_price` | [examples/raydium_clmm_token_price.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/raydium_clmm_token_price.rs | `v0.8.0` |
| Orca Whirlpool token price math | `cargo run --example orca_whirlpool_token_price` | [examples/orca_whirlpool_token_price.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/orca_whirlpool_token_price.rs | `v0.8.0` |
| Meteora DAMM new pool baseline | `cargo run --example meteora_damm_new_pool` | [examples/meteora_damm_new_pool.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/meteora_damm_new_pool.rs | `v0.8.0` |
| Meteora DBC token price math | `cargo run --example meteora_dbc_token_price` | [examples/meteora_dbc_token_price.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/meteora_dbc_token_price.rs | `v0.8.0` |
| Wallet trade filter | `cargo run --example wallet_trade_filter` | [examples/wallet_trade_filter.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/wallet_trade_filter.rs | `v0.8.0` |
| gRPC latency slot compare config | `cargo run --example grpc_latency_slot_compare` | [examples/grpc_latency_slot_compare.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/grpc_latency_slot_compare.rs | `v0.8.0` |
| **Account subscription** | | |
| Token account balance updates | `TOKEN_ACCOUNT=<pubkey> cargo run --example token_balance_listen --release` | [examples/token_balance_listen.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/token_balance_listen.rs | `v0.8.0` |
| Nonce account state changes | `NONCE_ACCOUNT=<pubkey> cargo run --example nonce_listen --release` | [examples/nonce_listen.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/nonce_listen.rs | `v0.8.0` |
| Mint account info | `MINT_ACCOUNT=<pubkey> cargo run --example token_decimals_listen --release` | [examples/token_decimals_listen.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/token_decimals_listen.rs | `v0.8.0` |
| PumpSwap pool accounts via memcmp | `cargo run --example pumpswap_pool_account_listen --release` | [examples/pumpswap_pool_account_listen.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/pumpswap_pool_account_listen.rs | `v0.8.0` |
| All ATAs for mints | `cargo run --example mint_all_ata_account_listen --release` | [examples/mint_all_ata_account_listen.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/mint_all_ata_account_listen.rs | `v0.8.0` |
| **ShredStream** | | |
| Jito ShredStream subscription | `cargo run --example shredstream_example --release` | [examples/shredstream_example.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/shredstream_example.rs | `v0.8.0` |
| **Utility** | | |
| Dynamic subscription filters | `cargo run --example dynamic_subscription --release` | [examples/dynamic_subscription.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/dynamic_subscription.rs | `v0.8.0` |
| Debug PumpSwap account filling | `cargo run --example test_account_filling --release` | [examples/test_account_filling.rs]https://github.com/0xfnzero/sol-parser-sdk/blob/main/examples/test_account_filling.rs | `v0.8.0` |

### Basic Usage

```rust
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 Usage (Jito)

ShredStream provides ultra-low latency (~50-100ms faster than gRPC) by directly subscribing to Jito's ShredStream service:

```rust
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:**
- The default parser requires resolved instruction keys. Supply cached ALT addresses with `parse_transaction_dex_events_with_loaded_addresses` or `with_address_lookup_resolver`; unresolved instructions are skipped. An explicit `best_effort` API retains provisional legacy behavior.
- No execution metadata: supported official routes and known wrappers emit explicit route intents, while arbitrary CPI results and confirmed fills require the execution-metadata path.
- No block_time - always 0
- tx_index is entry-level, not slot-level

---

## ๐Ÿ—๏ธ Supported Protocols

### DEX Protocols
- โœ… **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

### 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)

### Non-Pump DEX Support Matrix

| 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`](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.

---

## โšก 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::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,
]);
```

### Example: Pool Monitor
```rust
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:**
- Avoids decoding excluded event families; measure the benefit with your event mix
- 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;
}
```

### Pump.fun Bonding Curve v2 (buy_v2 / sell_v2 / buy_exact_quote_in_v2)

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.

### 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()
};

// Buffered slot ordering (flush on newer slot or timeout)
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
โ”œโ”€โ”€ 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
```

---

## ๐Ÿš€ 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)
| 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 |

### SIMD Pattern Matching
| Operation | Before (contains) | After (SIMD) | Speedup |
|-----------|------------------|--------------|---------|
| Protocol detection | 50-100ns | 10-20ns | 3-10x |
| Create event detection | 150ns | 30ns | 5x |

---

## ๐Ÿ“„ License

MIT License

## ๐Ÿ“ž Contact

- **Repository**: https://github.com/0xfnzero/sol-parser-sdk
- **Telegram**: https://t.me/fnzero_group
- **Discord**: https://discord.gg/vuazbGkqQE

---

## โš ๏ธ Performance Tips

1. **Use Event Filtering** - Skip unneeded event families; measure with representative traffic
2. **Run in Release Mode** - `cargo build --release` for full optimization
3. **Use repeatable measurements** - Keep build profile, input corpus and machine load consistent; elevated privileges do not make timing accurate
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
```

Shared PumpFun create/create_v2 mainnet fixtures, replay instructions and verification limits are documented in the [validation guide](https://github.com/0xfnzero/sol-parser-sdk-golang/tree/main/validation/pumpfun_create_20261007).

## Usage documentation

- [Account subscriptions]docs/ACCOUNT_SUBSCRIPTIONS.md
- [Route analysis]docs/ROUTE_ANALYSIS.md
- [CPMM creator-fee]docs/cpmm-creator-fee-share.md
- [Pump/PumpSwap account layouts]docs/PUMP_PUMP_AMM_PARSER_ACCOUNTS.md
- [gRPC versus RPC]docs/grpc-vs-rpc.md
- [Latency troubleshooting]docs/troubleshooting-latency.md


### Pump routes in ShredStream (offline, before execution)

The DEX shred parser recognizes official `multi_hop_swap` and
`multi_hop_curve_swap`, plus the captured RapidBuy (`rapidV5DAโ€ฆ`, 41-byte layout)
and BuyPumpDelta (`J7pourVwโ€ฆ`, 28-byte layout) wrapper versions. It emits
`DexEvent::PumpRouteIntent`, with the original instruction index, user, input and
output accounts, route hops and original instruction data. A two-hop route is
**one route event with two hops**; three separate wrapper calls produce three
route events. Unknown programs or changed layouts are not guessed by scanning
for embedded Pump bytes.

**These events are intents, not confirmed fills.** They contain no execution
status, actual fill amounts, reserves or post balances. `amount_in` and
`min_amount_out` are explicit instruction constraints where decoded; BuyPumpDelta
chooses its input at runtime, so these fields are `None`. Failed or conditional
execution cannot be determined from raw shreds. Use execution metadata for fills.

Subscribe with `EventType::PumpRouteIntent`. Broad `PumpFunTrade` subscriptions
also receive route intents; official `MultiHopSwap` routes can contain both Pump
families and also match `PumpSwapTrade`. Direction-specific buy/sell and create
filters do not match route intents. `exclude_types([PumpRouteIntent])` suppresses
all intents. Consumers must handle the new `DexEvent::PumpRouteIntent` variant
rather than assuming every callback is a trade variant.

`filter: None` already includes route intents; changing the filter does not
convert them into `PumpFunTrade`. For RapidBuy and BuyPumpDelta, `is_buy` is
`Some(true)`, relative to `hops[0].base_mint`; the payment mint is
`hops[0].quote_mint`. RapidBuy also exposes
`ix_name = Some("buy_exact_quote_in_v2")` from its validated embedded
instruction. BuyPumpDelta's expected method is unknown (`None`). Both hints
are `None` for multi-hop routes. These are pre-execution hints, not proof of
a successful CPI. Older serialized events deserialize with unknown hints.

```rust,ignore
if let DexEvent::PumpRouteIntent(intent) = event {
    println!("buy intent: {:?}, expected method: {:?}",
        intent.is_buy, intent.ix_name);
    for hop in &intent.hops {
        println!("base: {}, quote: {}", hop.base_mint, hop.quote_mint);
    }
}
```

The new optional fields preserve JSON read compatibility, but downstream Rust
code constructing `PumpRouteIntentEvent` literals must supply the two fields.

ALT addresses must come from a prewarmed, slot-aware local cache. Both SDKs expose
`shredstream::parse_transaction_dex_events_with_loaded_addresses`: pass all loaded
writable addresses, then all loaded readonly addresses, in the message lookup
order. Count/index errors return before appending events. The caller must ensure
address identity and lookup-table activation at the transaction slot. The default
parser skips unresolved instruction accounts instead of emitting placeholder
pubkeys. `parse_transaction_dex_events_best_effort` retains the older provisional
behavior for direct instructions; route adapters always require resolved keys.

High-level clients accept `with_address_lookup_resolver(|transaction, slot| ...)`,
returning `LoadedAddresses` from your cache. Cache errors skip the transaction;
without a resolver, fully static instructions can still parse. Do not perform RPC
or blocking I/O in this synchronous callback. The SDK parsing path performs no
RPC, simulation, or transaction submission.

Regression coverage includes the six original signed mainnet transaction wires,
ALT/filter/error cases, signed static official routes, and malformed/truncated
instructions. Run `cargo test --test pump_shred_routes`. The tests are offline;
synthetic signing validates extraction and does not simulate program execution.

### Repeatable offline Pump simulations

Run the native Rust example and tests:

```sh
cargo run --offline --example pump_offline_bank
cargo test --offline --test pump_offline_bank --test pump_shred_routes
```

The example signs and executes 20 route scenarios against frozen deployed programs
in LiteSVM twice, checks rollback/signature/ALT behavior and validates SDK parsing.
The integration test reuses the example code. No Python, RPC calls or broadcasts are
required. See [configuration, snapshot provenance and scope](examples/offline_bank/README.md).


## Reproducible local hot-path latency

Run the native Rust example with a configuration file (no RPC):

```sh
cargo run --release --example hotpath_latency -- examples/hotpath_latency.json
```

The JSON configuration controls `warmup`, `samples`, and `batch`. Output includes
p50/p95/p99 nanoseconds per operation and the build profile. Use `--release` for
performance comparisons and run on an otherwise idle machine. Re-run with the
same configuration and fixtures before comparing changes.

Six captured signed transactions are decoded and signature-verified before the
measurement. Strict parsing uses cached loaded addresses and validates expected
event counts. Two unsigned synthetic cases measure irrelevant-program and
unknown-discriminator rejection. Output-vector storage is reused. Measurements
exclude signature verification, fixture loading, network reception, and bank
execution; they do not establish production ShredStream latency.