Yellowstone SDK
Two SDKs wrap the gRPC transport with the same source helpers and typed data. The Rust SDK adds a stream-based subscription model and a raw geyser passthrough; the TypeScript SDK uses callbacks. Pick your language.
Install
Add the crate and an async runtime. Subscription streams are consumed with futures::StreamExt.
[dependencies]
raptor-yellowstone = "0.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
futures = "0.3"Connect
connect(url, token) opens the client. An https:// endpoint uses native-root TLS; http://localhost:... is plaintext. The token is sent as the x-token metadata header on every call (pass an empty string to omit it); see Authentication.
use raptor_yellowstone::connect;
let client = connect("https://yellowstone.raptor.trade", std::env::var("RAPTOR_TOKEN")?).await?;Query
Each source helper builds a <source>::<topic> method and its params. duration(...) maps to the wire window param; unset selectors are dropped. get() returns the typed data.
use raptor_yellowstone::{connect, market, priority_fee};
let client = connect("https://yellowstone.raptor.trade", "<RAPTOR_TOKEN>").await?;
let candles = market(&client)
.ohlcv()
.base("So11111111111111111111111111111111111111112")
.duration("1m")
.limit(100)
.get()
.await?; // Vec<Ohlcv>
let fees = priority_fee(&client).cluster().duration("5m").get().await?; // Vec<RowMeta>Subscribe
subscribe() returns a Subscription<T> that implements Stream, yielding Event<T> with the change kind and the decoded row. Hydration arrives first, then live changes.
use futures::StreamExt;
let mut stream = market(&client)
.ohlcv()
.duration("1m")
.hydrate(50)
.throttle("1s")
.subscribe()
.await?;
while let Some(event) = stream.next().await {
let event = event?; // Event<Ohlcv> { kind: ChangeKind, row: Ohlcv }
println!("{:?} {:#?}", event.kind, event.row);
}Sources and topics
- DEX source -
market. Exposestrades,block,ohlcv,twap,vwap,volume,token. - priority_fee -
block,fee,stats,cluster,recommendation,top_txs,top_accounts,account_block,account_stats,account_recommendation.
Builder setters are base, quote, mint, account, duration, limit (selectors) and hydrate, throttle, linger (subscribe options). DEX helpers decode into typed structs (Ohlcv, Trade, Twap, Vwap, Volume, BlockBar, Token); priority-fee helpers decode into RowMeta. Values render like the other transports - numbers as strings, DateTime/Duration as ISO strings, blobs as 0x hex, a missing value (none) as JSON null, booleans native.
Low level
To write the method+params or RQL yourself, call the client directly. Decode into any T: serde::de::DeserializeOwned (or RowMeta for an untyped map).
use raptor_yellowstone::{RowMeta, SubscribeOptions};
use serde_json::json;
let rows: Vec<RowMeta> = client
.query_method("solana::market::ohlcv", json!({ "base": "So111...", "window": "1m" }))
.await?;
let rows: Vec<RowMeta> = client
.query_rql("from solana::market::ohlcv::1m | take { 10 }")
.await?;
let sub = client
.subscribe_method::<RowMeta>(
"solana::market::ohlcv",
json!({ "window": "1m" }),
SubscribeOptions { hydrate: Some(50), throttle: Some("1s".into()), ..Default::default() },
)
.await?;Geyser passthrough
client.geyser() wraps the official yellowstone-grpc-client on the same endpoint and token, with curated helpers (subscribe_accounts, subscribe_transactions, subscribe_slots, subscribe_blocks_meta), subscribe(req) for a full SubscribeRequest, and raw() for the underlying client. The upstream crates are re-exported as raptor_yellowstone::yellowstone_grpc_client and ::yellowstone_grpc_proto.
use futures::StreamExt;
let mut geyser = client.geyser().await?;
let mut accounts = geyser
.subscribe_accounts(vec!["<pubkey>".into()], vec![])
.await?;
while let Some(update) = accounts.next().await {
let update = update?; // yellowstone_grpc_proto::geyser::SubscribeUpdate
}Passthrough, not routing
