Solana Geyser gRPC - Filters

The Solana Stream SDK is provided as open-source software. For more details, please visit the GitHub repository below.
Overview of gRPC Filters
Solana Geyser gRPC uses filters to efficiently fetch only the data you are interested in, such as specific accounts, programs, transactions, slots, and blocks.
Below, we provide TypeScript examples using the Solana Stream SDK, clearly explaining the specific roles of each filter. The structure and meaning of the filters are identical when using Rust.
Roles and Examples of Each Filter
Subscribe to an account
Subscribe to real-time updates for a specific account. The following example subscribes to the SOL-USDC OpenBook account at the Confirmed commitment level:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {} }, accounts: { 'wsol/usdc': { account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'], }, }, transactions: {}, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.CONFIRMED, }
"wsol/usdc"
is a client-defined label.- Multiple filters for accounts, programs, blocks, and slots can be combined in a single JSON request.
Subscribe to an account with account_data_slice
This example demonstrates retrieving only a specific portion of account data. Instead of fetching the entire data (165 bytes) of a USDC token account, it retrieves 40 bytes starting from offset 32. This range includes information such as the owner and lamports balance.
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: { usdc: { owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'], filters: [ { tokenAccountState: true, }, { memcmp: { offset: 0, data: { base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', }, }, }, ], }, }, transactions: {}, blocks: {}, blocksMeta: {}, entry: {}, commitment: CommitmentLevel.CONFIRMED, accountsDataSlice: [{ offset: 32, length: 40 }], }
Subscribe to a program
This example demonstrates subscribing to account updates associated with a specific program.
Below, we subscribe to account updates for accounts owned by the Solend program at the
Processed
commitment level.import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: { solend: { owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'], }, }, transactions: {}, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
"solend"
is a custom label that can be freely set by the client.- To subscribe to multiple programs, please refer to the next section titled "Subscribe to multiple programs."
Subscribe to multiple programs
This example demonstrates how to subscribe to account updates associated with multiple programs at once.
The example below subscribes to updates for accounts owned by both Solend and Serum programs.
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: { programs: { owner: [ 'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo', '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin', ], }, }, transactions: {}, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
If you prefer assigning individual labels to each program, use the following approach:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: { solend: { owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'], }, serum: { owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'], }, }, transactions: {}, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to all finalized non-vote and non-failed transactions
This example demonstrates subscribing to all transactions at the
Finalized
commitment level, excluding vote transactions and failed transactions.import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: {}, transactions: { alltxs: { vote: false, failed: false, }, }, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.FINALIZED, }
vote: false
excludes vote transactions.failed: false
excludes failed transactions.- If fields are left empty, all transactions are retrieved.
- When multiple fields are specified, they operate with an AND condition.
Subscribe to non-vote transactions mentioning an account
This example demonstrates subscribing to transactions involving a specific account but excluding vote transactions.
The example below subscribes to non-vote transactions mentioning accounts associated with the Serum program.
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: {}, transactions: { serum: { vote: false, accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'], }, }, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to transactions excluding accounts
This example demonstrates subscribing to transactions excluding those involving specific accounts.
The example below retrieves transactions excluding any accounts owned by the Serum and Tokenkeg programs.
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: {}, transactions: { serum: { accountExclude: [ '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin', 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', ], }, }, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to transactions mentioning accounts & excluding certain accounts
This example demonstrates subscribing to transactions involving certain accounts, while explicitly excluding other specified accounts.
The example below subscribes to transactions mentioning Serum's account but excludes a specified account:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { slots: {}, }, accounts: {}, transactions: { serum: { accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'], accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'], }, }, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to a transaction signature
This example demonstrates subscribing to real-time updates for a specific transaction signature, until it reaches the
Confirmed
or Finalized
state.import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: {}, transactions: { sign: { signature: '5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs', }, }, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to slots
This example demonstrates subscribing to notifications of incoming slots. No additional details are required beyond assigning a custom tag name:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: { incoming_slots: {}, }, accounts: {}, transactions: {}, blocks: {}, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to blocks
Subscribe to real-time updates of all generated blocks. By default, all transactions within a block will be retrieved:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: {}, transactions: {}, blocks: { blocks: {}, }, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
To exclude transactions and only retrieve updated account information:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: {}, transactions: {}, blocks: { blocks: { includeTransactions: false, includeAccounts: true, }, }, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
To only retrieve transactions/accounts involving specific accounts:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: {}, transactions: {}, blocks: { blocks: { accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'], }, }, blocksMeta: {}, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Subscribe to block metadata
Subscribe only to block metadata notifications when blocks are processed. Detailed transaction data is not included.
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' const request = { slots: {}, accounts: {}, transactions: {}, blocks: {}, blocksMeta: { blockmetadata: {}, }, accountsDataSlice: [], commitment: CommitmentLevel.PROCESSED, }
Managing commitment levels
The Solana Geyser gRPC stream defaults to the
Processed
commitment level.You can specify higher commitment levels such as
Confirmed
or Finalized
. In these cases, Geyser buffers the data and sends notifications once the specified commitment level is reached.For maximum performance, it is recommended to handle commitment-level management on the client side.
Here's how to specify commitment levels:
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk' enum CommitmentLevel { PROCESSED = 0, CONFIRMED = 1, FINALIZED = 2, }
PROCESSED
: Immediate data after processing. Fast retrieval, but not yet confirmed.CONFIRMED
: Data confirmed by the cluster, providing increased certainty.FINALIZED
: Fully finalized data with no risk of reorganization.
Benefits of working at Processed
The main advantage of the
Processed
commitment level is immediate transaction retrieval, enabling rapid client-side processing. Clients can subsequently detect transitions to Confirmed
or Finalized
, offering quick responsiveness.How to manage Confirmed
and Finalized
When using
Confirmed
or Finalized
levels, events (transactions or account updates) should be buffered per slot.Buffer events slot by slot, subscribe to slot notifications, and release events from the buffer once a specific slot reaches the desired commitment (
Confirmed
or Finalized
).Events will initially be received before a slot reaches
Confirmed
or Finalized
.The special thing about Finalized
Due to Solana Geyser specifications, not all slots receive explicit finalized notifications. Therefore, when you receive a finalized notification for a slot, you must treat all ancestor slots as finalized, even if no notifications were received explicitly.
Specifically, upon receiving a finalized notification, retroactively treat all ancestor slots as finalized.