gRPC Streaming

Real-time account and transaction streaming via high-performance gRPC. Powered by custom Geyser plugins.

Features

  • Sub-millisecond Latency: Faster than WebSocket
  • Account Streaming: Real-time account updates
  • Transaction Streaming: Pre-confirmation transaction data
  • Block Streaming: Full block data as it's produced
  • Filtered Streams: Subscribe to specific accounts/programs

Endpoint

You connect to our gRPC endpoints utilizing IP Whitelisting instead of API keys. Once your server IP is whitelisted, you can access the endpoint directly.

http://[IP_ADDRESS]:[PORT]

Proto Definition

You will need the standard Solana Geyser proto file. Save this as geyser.proto.

Download Standard Geyser Proto

Installation

Node.js

1npm install @grpc/grpc-js @grpc/proto-loader

Rust

Add to Cargo.toml:

1[dependencies]
2tonic = "0.10"
3prost = "0.12"
4tokio = { version = "1.0", features = ["full"] }
5yellowstone-grpc-proto = "1.4.0"

Usage

Node.js Example

1const grpc = require('@grpc/grpc-js');
2const protoLoader = require('@grpc/proto-loader');
3
4// Load the protobuf definition
5const packageDefinition = protoLoader.loadSync('geyser.proto', {
6  keepCase: true,
7  longs: String,
8  enums: String,
9  defaults: true,
10  oneofs: true
11});
12const proto = grpc.loadPackageDefinition(packageDefinition).geyser;
13
14// Create client (Note: insecure credentials since traffic is direct to IP)
15const client = new proto.Geyser('[IP_ADDRESS]:[PORT]', grpc.credentials.createInsecure());
16
17// Metadata (Not needed if IP is whitelisted)
18const metadata = new grpc.Metadata();
19
20// Create stream
21const stream = client.subscribe(metadata);
22
23stream.on('data', (data) => {
24  console.log('Update received:', data);
25});
26
27stream.on('error', (error) => {
28  console.error('Stream error:', error);
29});
30
31// Send subscription request
32const request = {
33  accounts: {
34    'client': {
35      account: [],
36      owner: [],
37      filters: []
38    }
39  },
40  slots: {},
41  transactions: {},
42  blocks: {},
43  blocksMeta: {},
44  commitment: 'processed',
45  entry: {}
46};
47
48stream.write(request);

Rust Example

1use yellowstone_grpc_proto::geyser::geyser_client::GeyserClient;
2use yellowstone_grpc_proto::geyser::{SubscribeRequest, SubscribeRequestFilterAccounts};
3use tonic::transport::{Channel, ClientTlsConfig};
4use tonic::Request;
5
6#[tokio::main]
7async fn main() -> Result<(), Box<dyn std::error::Error>> {
8    // Note: Use http for whitelisted connections
9    let endpoint = Channel::from_static("http://[IP_ADDRESS]:[PORT]");
10
11    let channel = endpoint.connect().await?;
12    let mut client = GeyserClient::new(channel);
13
14    let request = SubscribeRequest {
15        accounts: [("client".to_string(), SubscribeRequestFilterAccounts {
16            account: vec![],
17            owner: vec![],
18            filters: vec![],
19        })].into_iter().collect(),
20        slots: Default::default(),
21        transactions: Default::default(),
22        blocks: Default::default(),
23        blocks_meta: Default::default(),
24        commitment: Some(1), // Processed
25        entry: Default::default(),
26    };
27
28    let mut stream = client.subscribe(std::iter::once(request)).await?.into_inner();
29
30    while let Some(message) = stream.message().await? {
31        println!("Update received: {:?}", message);
32    }
33
34    Ok(())
35}

Performance Tips

  1. Use Filters: Reduce bandwidth with specific filters
  2. Batch Processing: Process updates in batches
  3. Connection Pooling: Multiple streams for high throughput
  4. Backpressure Handling: Implement flow control

Error Handling

1stream.on('error', (error) => {
2  console.error('Stream error:', error);
3  // Implement reconnection logic
4});
5
6stream.on('end', () => {
7  console.log('Stream ended, reconnecting...');
8  // Reconnect
9});