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.

The examples below use our Frankfurt (FRA) primary IP 88.216.36.71. Your assigned port is provided once your server IP is whitelisted. Additional regional IPs are available on request.

http://88.216.36.71:[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('88.216.36.71:[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://88.216.36.71:[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});