Account Subscriptions

Stream real-time account state changes directly from the Solana validator. Every time an account's data, lamports, or owner changes, the update is pushed to your client through the gRPC stream -- no polling required.

Account subscriptions are the most commonly used gRPC filter. They power everything from wallet monitors and token balance trackers to DEX pool watchers and program state indexers. You can filter by specific account public keys, program owners, or apply data-level filters like memcmp and dataSize.

Filter Parameters

ParameterTypeRequiredDescription
accountstring[]NoList of specific account public keys to monitor
ownerstring[]NoList of program owner public keys -- streams all accounts owned by these programs
filtersSubscribeRequestFilterAccountsFilter[]NoAdditional data filters (memcmp, dataSize) to narrow results
nonempty_txn_signatureboolNoOnly include updates that have a non-empty transaction signature

You must provide at least account or owner. Omitting both returns no results.

Update Payload

FieldTypeDescription
pubkeybytesThe public key of the updated account
lamportsuint64Current lamport balance
ownerbytesProgram that owns this account
executableboolWhether the account contains a program
rent_epochuint64Epoch at which the account will next owe rent
databytesRaw account data
write_versionuint64Monotonically increasing version number
txn_signaturebytesSignature of the transaction that modified this account
slotuint64Slot in which the update occurred
is_startupboolWhether this is an initial snapshot update during connection startup

Code Examples

Monitor Specific Accounts (Node.js)

1stream.write({
2  accounts: {
3    myFilter: {
4      account: [
5        'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',  // USDC mint
6        'So11111111111111111111111111111111111111112'         // Wrapped SOL
7      ],
8      owner: [],
9      filters: []
10    }
11  },
12  slots: {},
13  transactions: {},
14  transactionsStatus: {},
15  blocks: {},
16  blocksMeta: {},
17  commitment: 1,
18  entry: {},
19  accountsDataSlice: [],
20  ping: null
21});
22
23stream.on('data', (update) => {
24  if (update.account) {
25    const acct = update.account.account;
26    console.log('Account:', Buffer.from(acct.pubkey).toString('base58'));
27    console.log('Lamports:', acct.lamports);
28    console.log('Data length:', acct.data.length);
29    console.log('Write version:', acct.write_version);
30  }
31});

Monitor All Accounts Owned by a Program (Rust)

1use yellowstone_grpc_client::GeyserGrpcClient;
2use yellowstone_grpc_proto::prelude::*;
3use std::collections::HashMap;
4use futures::StreamExt;
5
6#[tokio::main]
7async fn main() -> anyhow::Result<()> {
8    let mut client = GeyserGrpcClient::build_from_uri("http://[IP_ADDRESS]:[PORT]")
9        .connect()
10        .await?;
11
12    let mut accounts = HashMap::new();
13    accounts.insert("raydium".to_string(), SubscribeRequestFilterAccounts {
14        account: vec![],
15        owner: vec!["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8".to_string()],
16        filters: vec![],
17        nonempty_txn_signature: None,
18    });
19
20    let request = SubscribeRequest {
21        accounts,
22        slots: HashMap::new(),
23        transactions: HashMap::new(),
24        transactions_status: HashMap::new(),
25        blocks: HashMap::new(),
26        blocks_meta: HashMap::new(),
27        commitment: Some(CommitmentLevel::Processed as i32),
28        entry: HashMap::new(),
29        accounts_data_slice: vec![],
30        ping: None,
31        from_slot: None,
32    };
33
34    let (_, mut stream) = client.subscribe_with_request(Some(request)).await?;
35
36    while let Some(msg) = stream.next().await {
37        match msg?.update_oneof {
38            Some(UpdateOneof::Account(update)) => {
39                if let Some(account) = update.account {
40                    println!("Account updated: {:?}, lamports: {}", account.pubkey, account.lamports);
41                }
42            }
43            _ => {}
44        }
45    }
46
47    Ok(())
48}

Common Use Cases

Use CaseFilter Configuration
Track wallet balanceaccount: ["walletPubkey"]
Monitor DEX poolaccount: ["poolPubkey"]
Watch all Raydium accountsowner: ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"]
Track all SPL token accountsowner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"] with filters for mint
Monitor USDC holdersowner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"] + memcmp at offset 0 for USDC mint
Watch program upgradesowner: ["BPFLoaderUpgradeab1e11111111111111111111111"]