MCPcopy Index your code
hub / github.com/ValidatorsDAO/solana-stream

github.com/ValidatorsDAO/solana-stream @v1.4.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.4.0 ↗ · + Follow
459 symbols 989 edges 97 files 46 documented · 10% updated 4d agov1.4.0 · 2026-06-26★ 42
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

SolanaStreamSDK Follow @ValidatorsDAO Crate NPM Version

Solana Stream SDK

A collection of Rust and TypeScript packages for Solana stream data, operated by ValidatorsDAO. This repository is published as open-source software (OSS) and is freely available for anyone to use.

Powered By Solana

Overview

This project provides libraries and tools for streaming real-time data from the Solana blockchain. It supports both Geyser and Shreds approaches, making it easier for developers to access Solana data streams.

Choose Your Path

  • Geyser gRPC (TypeScript/Rust): production-ready streaming with resilient reconnects
  • Shreds gRPC (TypeScript/Rust): raw shreds over gRPC for high-throughput ingestion
  • UDP Shreds (Rust): lowest-latency signal for detection and trading workflows

What's New (TypeScript v1.1.0)

  • Refreshed starter layout and docs to highlight trading hooks
  • Yellowstone Geyser gRPC connection upgraded to an NAPI-RS-powered client for better backpressure
  • NAPI-powered Shreds client/decoder so TypeScript can tap Rust-grade throughput
  • Improved backpressure handling and up to 4x streaming efficiency (400% improvement)
  • Faster real-time Geyser streams for TypeScript clients with lower overhead

Production-Ready Geyser Clients (TypeScript + Rust)

  • Rust Geyser exports track yellowstone-grpc-client 13.x and expose deshred, token-account expansion, and cuckoo filter helpers
  • Ping/Pong handling to keep Yellowstone gRPC streams alive
  • Exponential reconnect backoff plus gap recovery (fromSlot / from_slot)
  • Bounded queues/channels with drop logging for backpressure safety
  • Code-based subscription filters in TypeScript
  • Optional runtime metrics logging (TypeScript)
  • Default filters drop vote/failed transactions to reduce traffic
  • Rust Geyser client ships the same safeguards and powers UDP Shreds for fastest signal

Tip: start with slots, then add filters as needed. When resuming from fromSlot, duplicates are expected.

Rust Highlight: UDP Shreds (Fastest Signal)

If you have ERPC Dedicated Shreds, you can forward raw Shreds over UDP to your own listener. This is Solana’s fastest observation layer—before Geyser gRPC and far ahead of RPC/WebSocket. The SDK includes a simple Rust sample; pump.fun is used only because it’s the most common question we get.

Why this is the fastest path

  • Shreds arrive first: validator-to-validator Shreds land before Geyser gRPC or RPC/WebSocket, so latency-critical flows see events earliest.
  • UDP keeps overhead tiny: no connection setup, retransmit, or ordering; matches the on-wire format between validators.
  • Optional latency monitoring uses a DashMap-backed slot tracker to reduce lock contention.
  • Trade-off: pre-finalization data can be missing/out-of-order/failed—handle that as part of the speed bargain.

Note: the shared Shreds gRPC endpoint runs over TCP, so it’s slower than UDP Shreds.

Try it with Solana Stream SDK

  • Sample code (shreds-udp-rs, Rust): pump.fun is just a common example—swap in your own target.
    https://github.com/ValidatorsDAO/solana-stream/tree/main/temp-release/shreds-udp-rs
  • Quick start requires settings.jsonc plus env (e.g., SOLANA_RPC_ENDPOINT); see the sample README.
  • Dedicated Shreds users: point your Shreds sender to the sample’s ip:port to see detections.
  • Not on UDP yet? Run it locally or on your own server to explore logs and customize hooks.

Pump.fun example log

pump.fun hits over UDP Shreds

This example comes from the SDK sample; clone and run it to see hits, or swap in your own target.

Resources

  • All code and README docs are in the Solana Stream SDK repo:
    https://github.com/ValidatorsDAO/solana-stream

Package Structure

Rust Clients

  • client/geyser-rs/: Rust client using Geyser gRPC
  • client/shreds-rs/: Rust client for Shredstream over gRPC
  • client/shreds-udp-rs/: Minimal UDP shred listener; includes pump.fun token-mint detection example

TypeScript Clients

  • client/geyser-ts/: TypeScript client using Geyser gRPC
  • client/shreds-ts/: TypeScript client for Shredstream over gRPC

SDK Packages

  • crate/solana-stream-sdk/: Rust SDK for Solana stream functionality
  • package/solana-stream-sdk/: TypeScript SDK for Solana stream functionality

Getting Started

Prerequisites

  • Node.js 22 or 24 (LTS) for TypeScript packages
  • Rust (for Rust packages)
  • pnpm (for package management)

Installation

For the entire workspace:

git clone https://github.com/ValidatorsDAO/solana-stream.git
cd solana-stream
pnpm install

Geyser Client Example – TypeScript

Create a .env file at client/geyser-ts/.env with your environment variables:

# Optional: required only if your endpoint enforces auth
X_TOKEN=YOUR_X_TOKEN
GEYSER_ENDPOINT=https://grpc-ams.erpc.global
SOLANA_RPC_ENDPOINT="https://edge.erpc.global?api-key=YOUR_API_KEY"

⚠️ Please note: This endpoint is a sample and cannot be used as is. Please obtain and configure the appropriate endpoint for your environment.

Next, build and run the client:

pnpm -F @validators-dao/solana-stream-sdk build
pnpm -F geyser-ts dev
  • A 1-day free trial for the Geyser gRPC endpoints is available by joining the Validators DAO Discord community. Please try it out:

https://discord.gg/C7ZQSrCkYR

Quick Start Guide for Sample Shreds Client - Rust

Create a .env file (placed in the project root)

SHREDS_ENDPOINT=https://shreds-ams.erpc.global
SOLANA_RPC_ENDPOINT="https://edge.erpc.global?api-key=YOUR_API_KEY"

⚠️ Please note: This endpoint is a sample and cannot be used as is. Please obtain and configure the appropriate endpoint for your environment.

Run the sample client

cargo run -p shreds-rs

The sample code can be found at:

https://github.com/ValidatorsDAO/solana-stream/blob/main/client/shreds-rs/src/main.rs

A 1-day free trial for the Shreds endpoints is available by joining the Validators DAO Discord community. Please try it out: https://discord.gg/C7ZQSrCkYR

Usage with solana-stream-sdk

You can also use the published crate in your own projects:

[dependencies]
solana-stream-sdk = "1.4.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
dotenvy = "0.15"
solana-entry = "3.0.12"
bincode = "1.3.3"
use solana_stream_sdk::{CommitmentLevel, ShredstreamClient};
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load environment variables
    dotenvy::dotenv().ok();

    // Connect to shreds endpoint
    let endpoint = env::var("SHREDS_ENDPOINT")
        .unwrap_or_else(|_| "https://shreds-ams.erpc.global".to_string());
    let mut client = ShredstreamClient::connect(&endpoint).await?;

    // Create subscription for specific account
    let request = ShredstreamClient::create_entries_request_for_account(
        "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P",
        Some(CommitmentLevel::Processed),
    );

    // Subscribe to entries stream
    let mut stream = client.subscribe_entries(request).await?;

    // Process incoming entries
    while let Some(entry) = stream.message().await? {
        let entries = bincode::deserialize::<Vec<solana_entry::entry::Entry>>(&entry.entries)?;
        println!("Slot: {}, Entries: {}", entry.slot, entries.len());

        for entry in entries {
            println!("  Entry has {} transactions", entry.transactions.len());
        }
    }

    Ok(())
}

For specific packages, navigate to the package directory and install dependencies.

Shreds UDP Pump.fun Watcher (Rust)

client/shreds-udp-rs listens for Shredstream over UDP and highlights watched programs (defaults to pump.fun). Settings live in client/shreds-udp-rs/settings.jsonc and are embedded at build time; secrets like RPC can be overridden via environment variables.

Quick start:

export SOLANA_RPC_ENDPOINT=https://api.mainnet-beta.solana.com   # pass secrets via env only
cargo run -p shreds-udp-rs                                       # settings already in settings.jsonc

Log legend:

  • Prefix: 🎯 program hit, 🐣 authority hit (🎯🐣 means both)
  • Action: 🐣 create, 🟢 buy, 🔻 sell, 🪙 other, unknown/missing amounts
  • Votes skipped by default (skip_vote_txs=true)
  • pump_min_lamports can suppress small pump.fun buy/sell logs
  • Pump.fun SOL values are instruction limits (max for buy/create, min for sell); actual fills require event/meta data (e.g., Geyser/RPC).
  • UDP shreds are processed directly; not dependent on RPC commitment. Failed transactions may still appear; missing fields show as .

Components from crate/solana-stream-sdk (5 layers):

  • Config loader (ShredsUdpConfig): reads JSONC/env and builds ProgramWatchConfig (pump.fun defaults; composite mint finder = pump.fun accounts + SPL Token MintTo/Initialize). Use watch_config_no_defaults() to opt out of pump.fun fallbacks.
  • Receiver (UdpShredReceiver): minimal UDP socket reader with timestamps.
  • Pipeline (5 layers): ① receive/prefilter (decode_udp_datagram) → ② FEC buffer (insert_shred + ShredsUdpState) → ③ deshred (deshred_shreds_to_entries) → ④ watcher/detail (collect_watch_events + detailers) → ⑤ sink (logs/custom hooks).
  • One-call convenience: handle_pumpfun_watcher wraps the same 5 layers (pump.fun defaults).
  • Customize sink/detailer: via ProgramWatchConfig::with_detailers(...) or replace the sink with your own hook.
  • Vote filtering: by default skip_vote_txs=true, so vote-only shreds/txs are dropped early.
  • Samples: cargo run -p shreds-udp-rs (pump.fun defaults, one-call wrapper) or cargo run -p shreds-udp-rs --bin generic_logger (pump.fun-free logger; set GENERIC_WATCH_PROGRAM_IDS / GENERIC_WATCH_AUTHORITIES to watch your own programs).

Troubleshooting:

  • Use solana-stream-sdk >= 1.4.0 for Direct Shreds UDP. Agave 3.x serializes deshredded entries with wincode; SDK 1.2.0 tried bincode first in the UDP helper, and SDK 1.2.1 could still decode from the middle of a multi-FEC entry segment.
  • Errors such as entry decode failed: invalid value: integer ..., expected a valid transaction message version, continue signal on byte-three, unexpected end of file, or alias encoding usually indicate a codec mismatch rather than firewall loss.
  • UDP packet sizes around 1203/1228 bytes are normal Merkle shred sizes and do not by themselves indicate truncation.

Design notes

  • Layered pipeline (5 layers): ① UDP receive → ② FEC buffer/pre-deshred → ③ deshred → ④ watcher (mint extraction) → ⑤ detailer/sink (labeling + log output). Each stage can be swapped or reused.
  • Pure UDP/FEC path: single-purpose deshredder tuned for Agave merkle sizing; leaves ledger/rpc out of the hot path.
  • Config is JSONC/env: secrets (RPC) in env, behavior (watch ids, logging) in JSONC; defaults prefill pump.fun watch ids.
  • Pump filters: optional pump_min_lamports to log only pump.fun buy/sell with SOL limit above a threshold; logs show sol: when the limit is parsed.
  • Composable stages: receiver → deshred → watcher → detailer → sink; each stage can be swapped or reused.
  • Signal-first logging: emoji at a glance, vote-filtered by default, and mint-level detail with adapters (pump.fun).
  • Small, dependency-light SDK crate backing a CLI client; intended to embed into larger consumers as well.

Quick choices:

  • Want a one-call, pump.fun-ready loop? Use handle_pumpfun_watcher in your own binary and set watch IDs/env as needed. This matches the out-of-the-box behavior shown in the screenshots.
  • Need to act on detections (e.g., push to a queue, custom filtering, alternate watchers/detailers)? Use the modular pipeline (decode_udp_datagraminsert_shreddeshred_shreds_to_entriescollect_watch_events) and hook your own sink right after detection (see client/shreds-udp-rs custom hook example).

Minimal usage example (Rust):

```rust use solana_stream_sdk::shreds_udp::{ShredsUdpConfig, ShredsUdpState, DeshredPolicy, handle_pumpfun_watcher}; use solana_stream_sdk::UdpShredReceiver; use std::sync::Arc;

[tokio::main]

async fn main() -> Result<(), Box> { let cfg = ShredsUdpConfig::from_env(); // reads SHREDS_UDP_CONFIG jsonc too let mut receiver = UdpShredReceiver::bind(&cfg.bind_addr, None).await?; let policy = DeshredPolicy { require_code_match: cfg.require_code_match }; let watch_

Extension points exported contracts — how you extend this code

MintFinder (Interface)
(no doc) [3 implementers]
crate/solana-stream-sdk/src/txn.rs
SubscribeRequest (Interface)
(no doc)
client/geyser-ts/src/utils/geyser.ts
SubscribeRequest (Interface)
(no doc)
temp-release/geyser-ts/src/utils/geyser.ts
MintDetailer (Interface)
(no doc) [1 implementers]
crate/solana-stream-sdk/src/txn.rs
GeyserRunnerOptions (Interface)
(no doc)
client/geyser-ts/src/lib/geyserRunner.ts
GeyserRunnerOptions (Interface)
(no doc)
temp-release/geyser-ts/src/lib/geyserRunner.ts
RuntimeConfig (Interface)
(no doc)
client/geyser-ts/src/lib/runtimeConfig.ts
RuntimeConfig (Interface)
(no doc)
temp-release/geyser-ts/src/lib/runtimeConfig.ts

Core symbols most depended-on inside this repo

notify_discord
called by 28
temp-release/trade-app/src/webhook.rs
lang
called by 17
temp-release/trade-app/src/i18n.rs
parse_pubkeys
called by 16
crate/solana-stream-sdk/src/txn.rs
parse
called by 14
temp-release/trade-app/src/i18n.rs
sleep
called by 13
temp-release/geyser-ts/src/lib/geyserRunner.ts
env_bool_opt
called by 12
crate/solana-stream-sdk/src/shreds_udp.rs
remove_batch
called by 10
crate/solana-stream-sdk/src/shreds_udp.rs
warn_once
called by 9
crate/solana-stream-sdk/src/shreds_udp.rs

Shape

Function 265
Class 90
Method 84
Enum 10
Interface 10

Languages

Rust80%
TypeScript20%

Modules by API surface

crate/solana-stream-sdk/src/shreds_udp.rs105 symbols
temp-release/trade-app/src/api.rs31 symbols
crate/solana-stream-sdk/src/txn.rs29 symbols
temp-release/trade-app/src/i18n.rs21 symbols
temp-release/trade-app/src/engine.rs21 symbols
temp-release/trade-app/src/state.rs14 symbols
temp-release/trade-app/src/utils/config.rs12 symbols
temp-release/geyser-rs/src/utils/config.rs12 symbols
client/geyser-rs/src/utils/config.rs12 symbols
package/solana-shreds-client/src/lib.rs11 symbols
temp-release/geyser-ts/src/lib/geyserRunner.ts9 symbols
client/geyser-ts/src/lib/geyserRunner.ts9 symbols

For agents

$ claude mcp add solana-stream \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact