Overview
Account subscriptions deliver real-time updates whenever an account’s lamport balance, data, or owner changes. You can monitor specific addresses, all accounts owned by a program, or apply byte-level data filters.
Filter Parameters
| Parameter | Type | Description |
|---|
account | string[] | Specific account public keys to monitor. Matches any in the list (logical OR). |
owner | string[] | Monitor all accounts owned by these program IDs (logical OR). |
filters | object[] | Additional data filters — dataSize and/or memcmp (logical AND). |
nonemptyTxnSignature | boolean | Only emit updates that are part of a transaction. |
dataSize Filter
Only receive updates for accounts whose data length matches exactly:
filters: [{ dataSize: 165 }]
memcmp Filter
Match accounts by a specific byte sequence at a given offset (useful for discriminators):
filters: [
{
memcmp: {
offset: 0,
bytes: "base58EncodedBytes",
},
},
]
When combining multiple filter types, they operate as logical AND. Within account or owner arrays, values operate as logical OR.
Example: Monitor a Specific Wallet
import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";
const GRPC_URL = "https://your-endpoint.grpc.orbitflare.com";
const X_TOKEN = "YOUR_GRPC_TOKEN";
const PING_INTERVAL_MS = 30_000;
const client = new Client(GRPC_URL, X_TOKEN, {
"grpc.max_receive_message_length": 64 * 1024 * 1024,
});
async function main() {
const stream = await client.subscribe();
const streamClosed = new Promise<void>((resolve, reject) => {
stream.on("error", (error) => { reject(error); stream.end(); });
stream.on("end", () => resolve());
stream.on("close", () => resolve());
});
stream.on("data", (data) => {
if (data.account) {
const { account, slot } = data.account;
console.log(`Account update at slot ${slot}:`);
console.log(` Pubkey: ${account.pubkey}`);
console.log(` Lamports: ${account.lamports}`);
console.log(` Owner: ${account.owner}`);
console.log(` Data length: ${account.data.length} bytes`);
} else if (data.pong) {
console.log("Pong received");
}
});
const request: SubscribeRequest = {
accounts: {
walletMonitor: {
account: ["YourWalletPublicKeyHere"],
owner: [],
filters: [],
},
},
commitment: CommitmentLevel.CONFIRMED,
accountsDataSlice: [],
transactions: {},
transactionsStatus: {},
slots: {},
blocks: {},
blocksMeta: {},
entry: {},
ping: { id: 1 },
};
await new Promise<void>((resolve, reject) => {
stream.write(request, (err) => {
if (err == null) resolve(); else reject(err);
});
});
// Ping to keep alive
setInterval(() => {
stream.write({ ping: { id: 1 }, accounts: {}, accountsDataSlice: [], transactions: {}, transactionsStatus: {}, slots: {}, blocks: {}, blocksMeta: {}, entry: {} }, () => {});
}, PING_INTERVAL_MS);
await streamClosed;
}
main();
Example: Monitor All Token Accounts by Owner Program
const request: SubscribeRequest = {
accounts: {
tokenAccounts: {
account: [],
owner: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // SPL Token program
],
filters: [
{ dataSize: 165 }, // Standard token account size
],
},
},
commitment: CommitmentLevel.CONFIRMED,
accountsDataSlice: [],
transactions: {},
transactionsStatus: {},
slots: {},
blocks: {},
blocksMeta: {},
entry: {},
};
Optimizing with accountsDataSlice
If you only need a portion of the account data (e.g. the first 64 bytes for a discriminator), use accountsDataSlice to reduce bandwidth:
const request: SubscribeRequest = {
accounts: {
myFilter: {
account: ["AccountPubkeyHere"],
owner: [],
filters: [],
},
},
accountsDataSlice: [
{ offset: 0, length: 64 }, // Only receive the first 64 bytes
],
commitment: CommitmentLevel.CONFIRMED,
transactions: {},
transactionsStatus: {},
slots: {},
blocks: {},
blocksMeta: {},
entry: {},
};
Common Use Cases
| Use Case | Approach |
|---|
| Track wallet balance | Filter by account with specific pubkeys |
| Monitor all token mints | Filter by owner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"] + dataSize: 82 |
| Watch a specific program’s state | Filter by owner: ["YourProgramId"] |
| Detect new AMM pool creation | Filter by owner + dataSize matching pool account size |