Skip to main content
This guide builds a real filter step by step: watch a wallet’s Jupiter swaps, using program discovery so the filter is correct before you ever open a subscription.
1

Look Up the Program

Guessed instruction names are the most common way a filter silently matches nothing. Call describeProgram first to get the exact names the matcher compares against.
Request
Response
Prefer the program address over a catalog name — more than one catalog entry can share a name, and a name lookup can resolve to an older version of the program. route and shared_accounts_route are the two instructions that cover most Jupiter v6 swaps, so those are what you’ll filter on.
2

Build the Filter

Combine the program id, the instruction names from the previous step, and the wallet you’re watching. Fields combine with AND, so this matches route instructions that touch the wallet’s SOL account:
accounts.roles pins user_transfer_authority to the wallet’s exact position in the instruction, which is stricter than accounts.include alone: a plain address match would also catch the wallet showing up as an unrelated account elsewhere in the instruction. Role names match exactly, so they’re copied from describeProgram’s roles list, not guessed. Leave includeCpi: true (the default) — a swap’s actual token movements happen in inner instructions.
3

Subscribe and Handle Notifications

Open the subscription with the filter, then read each matched instruction’s decoded arguments:
matchedIndexes points only at the instructions your filter hit — skip everything else in the transaction. Check decoded is present before reading it: a route instruction from an unindexed program version arrives with decoded: null and raw fields instead.

Next Steps

Filter Fields Reference

All filter fields, options, and limits.

Handling Reconnects

Keep this subscription alive across disconnects and deploys.