Subscribe
Bidirectional streaming RPC for real-time account, transaction, slot, block, and entry updates via multiplexed subscriptions.
Type: streaming
Overview
The Subscribe method is the core of the Geyser gRPC interface. It establishes a bidirectional streaming connection that multiplexes all real-time subscriptions into a single gRPC stream. Clients send one or more subscription requests (accounts, transactions, slots, blocks, entries, block metadata) and receive a continuous flow of updates matching their filters.
This is the most commonly used Geyser method for high-frequency trading (HFT), MEV, and real-time indexing applications. It provides sub-millisecond latency for on-chain state changes, significantly faster than polling JSON-RPC or using WebSocket subscriptions.
Parameters
| Name | Type | Description |
|---|---|---|
| accounts | map<string, SubscribeRequestFilterAccounts> | Account subscription filters (owner, pubkey, memcmp) |
| slots | map<string, SubscribeRequestFilterSlots> | Slot subscription filters (commitment level) |
| transactions | map<string, SubscribeRequestFilterTransactions> | Transaction subscription filters |
| blocks | map<string, SubscribeRequestFilterBlocks> | Block subscription filters |
| blocks_meta | map<string, SubscribeRequestFilterBlocksMeta> | Block metadata subscription filters |
| entry | map<string, SubscribeRequestFilterEntry> | Ledger entry subscription filters |
| commitment | CommitmentLevel | Commitment level: processed, confirmed, finalized |
Response
The stream yields SubscribeUpdate messages containing one of the following update types:
| Field | Type | Description |
|---|---|---|
| filters | string[] | Which subscription filter labels matched |
| account | SubscribeUpdateAccount | Account state update |
| slot | SubscribeUpdateSlot | Slot progression update |
| transaction | SubscribeUpdateTransaction | Transaction details |
| block | SubscribeUpdateBlock | Full block data |
| block_meta | SubscribeUpdateBlockMeta | Block metadata only |
| entry | SubscribeUpdateEntry | Ledger entry |
| ping | SubscribeUpdatePing | Keep-alive ping |
Usage Examples
Node.js
1const grpc = require('@grpc/grpc-js');
2const protoLoader = require('@grpc/proto-loader');
3
4const packageDef = protoLoader.loadSync('geyser.proto', {
5 keepCase: true, longs: String, enums: String, defaults: true, oneofs: true
6});
7const proto = grpc.loadPackageDefinition(packageDef).geyser;
8const client = new proto.Geyser('[IP_ADDRESS]:[PORT]', grpc.credentials.createInsecure());
9
10const stream = client.subscribe(new grpc.Metadata());
11stream.on('data', (data) => console.log('Update:', data));
12stream.on('error', (err) => console.error('Error:', err));
13
14stream.write({
15 accounts: { client: { account: [], owner: [], filters: [] } },
16 slots: {}, transactions: {}, blocks: {}, blocksMeta: {},
17 commitment: 'processed', entry: {}
18});Rust
1use yellowstone_grpc_proto::geyser::geyser_client::GeyserClient;
2use yellowstone_grpc_proto::geyser::{SubscribeRequest, SubscribeRequestFilterAccounts};
3use tonic::transport::Channel;
4
5#[tokio::main]
6async fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let channel = Channel::from_static("http://[IP_ADDRESS]:[PORT]")
8 .connect().await?;
9 let mut client = GeyserClient::new(channel);
10
11 let request = SubscribeRequest {
12 accounts: [("client".to_string(), SubscribeRequestFilterAccounts {
13 account: vec![],
14 owner: vec!["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA".to_string()],
15 filters: vec![],
16 })].into_iter().collect(),
17 slots: Default::default(),
18 transactions: Default::default(),
19 blocks: Default::default(),
20 blocks_meta: Default::default(),
21 commitment: Some(1),
22 entry: Default::default(),
23 };
24
25 let mut stream = client.subscribe(std::iter::once(request)).await?.into_inner();
26 while let Some(msg) = stream.message().await? {
27 println!("Update: {:?}", msg);
28 }
29 Ok(())
30}