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-loaderRust
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
- Use Filters: Reduce bandwidth with specific filters
- Batch Processing: Process updates in batches
- Connection Pooling: Multiple streams for high throughput
- 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});