Skip to main content
LaserStream’s tokenAccounts filter lets a gRPC transaction subscription match activity on the associated token accounts (ATAs) a wallet owns, not just transactions where the wallet’s pubkey appears directly. The same filter is available over WebSocket — see Token Account (ATA) Filtering over WebSocket.

The problem: plain account filters miss incoming token transfers

When you watch a wallet with accountInclude: [wallet], you only match transactions where that wallet pubkey appears in the transaction’s account keys. A common case slips through: when someone sends the wallet an SPL token (USDC, for example), the transfer touches the wallet’s associated token account (ATA) — a separate program-derived address — not the wallet pubkey itself. So a plain accountInclude: [wallet] subscription never sees incoming token transfers. You would have to enumerate every ATA the wallet owns up front and add each one to the filter — but ATAs are created on demand (one per mint), so you can’t know the full set in advance.

How tokenAccounts expansion works

Set tokenAccounts on a transaction filter to expand matching so an accountInclude wallet also matches transactions that touch a token account it owns. Matching is owner-based: LaserStream resolves the token accounts owned by your accountInclude addresses at match time, so it catches any token account the wallet owns — including non-canonical ones — not just the derived ATA address. You never have to list the ATAs yourself. Subscriptions that omit tokenAccounts behave exactly as before, so it’s safe to add to an existing filter.

Expansion modes

tokenAccounts takes one of three string values: Start with "balanceChanged". It captures real fund movement at a fraction of the volume of "all".

Use it in LaserStream gRPC

Add tokenAccounts to a transaction filter in your SubscribeRequest. The Helius LaserStream SDK converts the string to the wire-level TokenAccountExpansionControlFlag enum for you (part of yellowstone-grpc-proto 12.5.0+).
See the Transaction Monitoring guide for a fuller example that diffs pre- and post-balances, and the Subscribe Request reference for every transaction filter field.

Reading what matched

Once a transaction matches via ATA expansion, the wallet’s token movement lives in the transaction’s meta.postTokenBalances and meta.preTokenBalances. Filter those entries by owner to isolate the balances your wallet actually owns, then diff preTokenBalances against postTokenBalances on the same accountIndex to see how much each mint moved. The example above shows the filtering step; the Transaction Monitoring guide shows the full diff.

Transaction Monitoring

Full filtering strategies and a runnable wallet-watch example over gRPC.

Token Account Filtering (WebSocket)

The same tokenAccounts field on the WebSocket transactionSubscribe method.

Subscribe Request Reference

Every transaction filter field, including tokenAccounts.

Compressed Filters

Track hundreds of thousands of accounts in one stream.