Documentation Index Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
Transaction monitoring lets you track transaction execution, success/failure status, program interactions, and token balance changes across Solana in real-time. This guide covers filtering strategies and practical implementations using the helius-laserstream SDK.
Transaction Filtering Options
LaserStream uses the same filter shape as Yellowstone gRPC. The four key fields you’ll set inside transactions.<label>:
accountInclude — match if any of these accounts appears (logical OR)
accountRequired — match only if all of these accounts appear (logical AND)
accountExclude — drop if any of these accounts appears
vote / failed — boolean flags for vote and failed transactions
Program Filtering
Account-Specific
Advanced Filtering
Monitor transactions involving specific programs Track all transactions that touch programs you care about: import { subscribe , CommitmentLevel , LaserstreamConfig , SubscribeRequest } from 'helius-laserstream' ;
const subscriptionRequest : SubscribeRequest = {
transactions: {
"program-filter" : {
accountInclude: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" , // Token Program
"11111111111111111111111111111111" , // System Program
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8" // Your program
],
accountExclude: [],
accountRequired: [],
vote: false ,
failed: false
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {},
slots: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
};
Best for: Program-specific monitoring, DeFi protocol tracking, smart contract interactions.
Monitor transactions affecting specific accounts const subscriptionRequest : SubscribeRequest = {
transactions: {
"wallet-filter" : {
accountInclude: [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" , // USDC mint
"YourWalletAddress" // Your wallet
],
accountExclude: [],
accountRequired: [],
vote: false ,
failed: true // Include failures to track errors
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {}, slots: {}, transactionsStatus: {},
blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};
Use case: Wallet monitoring, token mint tracking, account activity dashboards.
Combine multiple filter criteria const subscriptionRequest : SubscribeRequest = {
transactions: {
"advanced-filter" : {
accountInclude: [ "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ],
accountRequired: [ "YourProgramId" ], // Must include this program
accountExclude: [ "VoteProgram" ], // Exclude vote-related txs
vote: false ,
failed: false
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {}, slots: {}, transactionsStatus: {},
blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};
Filter logic: accountInclude (OR) AND accountRequired (AND) AND NOT accountExclude.
Practical Examples
Example 1: Monitor DEX Transactions
Track transactions touching popular DEX programs:
import { subscribe , CommitmentLevel , LaserstreamConfig , SubscribeRequest } from 'helius-laserstream' ;
import bs58 from 'bs58' ;
async function monitorDEXTransactions () {
const subscriptionRequest : SubscribeRequest = {
transactions: {
"dex-filter" : {
accountInclude: [
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8" , // Raydium
"CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK" , // Raydium CLMM
"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // Jupiter
],
accountExclude: [],
accountRequired: [],
vote: false ,
failed: false
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {}, slots: {}, transactionsStatus: {},
blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};
const config : LaserstreamConfig = {
apiKey: 'YOUR_API_KEY' ,
endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com' , // Choose your closest region
};
await subscribe ( config , subscriptionRequest , async ( data ) => {
if ( ! data . transaction ?. transaction ) return ;
const tx = data . transaction . transaction ;
console . log ( ` \n 🔄 DEX Transaction:` );
console . log ( ` Signature: ${ bs58 . encode ( tx . signature ) } ` );
console . log ( ` Slot: ${ data . transaction . slot } ` );
console . log ( ` Status: ${ tx . meta ?. err ? 'Failed' : 'Success' } ` );
console . log ( ` Fee: ${ tx . meta ?. fee || 0 } lamports` );
console . log ( ` Compute Units: ${ tx . meta ?. computeUnitsConsumed || 0 } ` );
// Token balance changes
if ( tx . meta ?. preTokenBalances ?. length > 0 ) {
console . log ( ` Token Balance Changes:` );
tx . meta . preTokenBalances . forEach (( preBalance : any , index : number ) => {
const postBalance = tx . meta . postTokenBalances [ index ];
if ( preBalance && postBalance ) {
const change = postBalance . uiTokenAmount . uiAmount - preBalance . uiTokenAmount . uiAmount ;
if ( change !== 0 ) {
console . log ( ` ${ preBalance . mint } : ${ change > 0 ? '+' : '' }${ change } ` );
}
}
});
}
}, async ( error ) => {
console . error ( 'Stream error:' , error );
});
}
monitorDEXTransactions (). catch ( console . error );
See all 57 lines
Example 2: Monitor Failed Transactions
Track failed transactions to surface application issues:
async function monitorFailedTransactions () {
const subscriptionRequest : SubscribeRequest = {
transactions: {
"failures" : {
accountInclude: [ "YourProgramId" ],
accountExclude: [],
accountRequired: [],
vote: false ,
failed: true // Only failed transactions
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {}, slots: {}, transactionsStatus: {},
blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};
const config : LaserstreamConfig = {
apiKey: 'YOUR_API_KEY' ,
endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com' ,
};
await subscribe ( config , subscriptionRequest , async ( data ) => {
if ( ! data . transaction ?. transaction ?. meta ?. err ) return ;
const tx = data . transaction . transaction ;
console . log ( ` \n ❌ Failed Transaction:` );
console . log ( ` Signature: ${ bs58 . encode ( tx . signature ) } ` );
console . log ( ` Slot: ${ data . transaction . slot } ` );
console . log ( ` Error: ${ JSON . stringify ( tx . meta . err ) } ` );
console . log ( ` Fee: ${ tx . meta . fee } lamports` );
console . log ( ` Compute Units: ${ tx . meta . computeUnitsConsumed || 0 } ` );
}, async ( error ) => {
console . error ( 'Stream error:' , error );
});
}
See all 34 lines
Example 3: Monitor High-Value Transactions
Track transactions with significant SOL transfers:
async function monitorHighValueTransactions () {
const subscriptionRequest : SubscribeRequest = {
transactions: {
"system-program" : {
accountInclude: [ "11111111111111111111111111111111" ],
accountExclude: [],
accountRequired: [],
vote: false ,
failed: false
}
},
commitment: CommitmentLevel . CONFIRMED ,
accounts: {}, slots: {}, transactionsStatus: {},
blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};
const config : LaserstreamConfig = {
apiKey: 'YOUR_API_KEY' ,
endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com' ,
};
await subscribe ( config , subscriptionRequest , async ( data ) => {
if ( ! data . transaction ?. transaction ?. meta ) return ;
const tx = data . transaction . transaction ;
const preBalances = tx . meta . preBalances || [];
const postBalances = tx . meta . postBalances || [];
let maxChange = 0 ;
preBalances . forEach (( preBalance : number , index : number ) => {
const postBalance = postBalances [ index ] || 0 ;
maxChange = Math . max ( maxChange , Math . abs ( postBalance - preBalance ));
});
const changeInSOL = maxChange / 1e9 ;
if ( changeInSOL > 10 ) {
console . log ( ` \n 💰 High-Value Transaction:` );
console . log ( ` Signature: ${ bs58 . encode ( tx . signature ) } ` );
console . log ( ` Slot: ${ data . transaction . slot } ` );
console . log ( ` Max SOL Transfer: ${ changeInSOL . toFixed ( 2 ) } SOL` );
console . log ( ` Fee: ${ tx . meta . fee / 1e9 } SOL` );
}
}, async ( error ) => {
console . error ( 'Stream error:' , error );
});
}
See all 45 lines
Transaction Data Structure
Transaction Message Structure
{
signature : string ;
isVote : boolean ;
transaction : {
message : {
accountKeys : string []; // All accounts involved
instructions : Instruction []; // Program instructions
recentBlockhash : string ;
};
signatures : string [];
};
meta : {
err : any ; // Error details if failed
fee : number ; // Transaction fee in lamports
computeUnitsConsumed : number ;
preBalances : number [];
postBalances : number [];
preTokenBalances : TokenBalance [];
postTokenBalances : TokenBalance [];
logMessages : string [];
};
}
{
accountIndex : number ;
mint : string ;
owner : string ;
uiTokenAmount : {
amount : string ;
decimals : number ;
uiAmount : number ;
uiAmountString : string ;
};
}
{
programIdIndex : number ; // Index in accountKeys array
accounts : number [];
data : string ; // Instruction data (base58)
}
Filter Logic Reference
Include Logic (OR) accountInclude: Transaction must involve ANY of these accounts.["A", "B"] matches transactions involving account A OR account B.
Required Logic (AND) accountRequired: Transaction must involve ALL of these accounts.["A", "B"] matches transactions involving account A AND account B.
Exclude Logic (NOT) accountExclude: Transaction must NOT involve any of these accounts.
Combined Logic Final filter: (accountInclude OR empty) AND (accountRequired AND all) AND NOT (accountExclude OR any).
Volume Management
Data Processing
Transaction streams can be high-volume. To keep up:
Start with specific program filters (don’t subscribe to “all transactions”)
Use confirmed over processed when you can tolerate ~1.5s extra latency
Monitor your processing capacity with a counter
Consider running parallel consumers behind a queue
let count = 0 ;
const startTime = Date . now ();
// inside your subscribe handler:
count ++ ;
if ( count % 100 === 0 ) {
const elapsed = ( Date . now () - startTime ) / 1000 ;
console . log ( `Processing ${ ( count / elapsed ). toFixed ( 1 ) } tx/sec` );
}
Extract only what you need to keep memory low: import bs58 from 'bs58' ;
function extractTransactionData ( tx : any ) {
return {
signature: bs58 . encode ( tx . signature ),
slot: tx . slot ,
success: ! tx . meta ?. err ,
fee: tx . meta ?. fee || 0 ,
computeUnits: tx . meta ?. computeUnitsConsumed || 0 ,
};
}
Error Handling
Symptom: Overwhelming transaction volume.Solutions: Add stricter filters (accountRequired, accountExclude); use higher commitment; implement sampling or rate limiting; process asynchronously.
Symptom: Expected transactions not appearing.Solutions: Verify program addresses are correct; check that the transactions actually exist; try processed for faster updates; loosen restrictive accountRequired/accountExclude filters.
Symptom: Cannot parse transaction data.Solutions: Handle missing fields gracefully; validate structure before processing; wrap parsing in try/catch; see Decoding Transaction Data .
Next Steps
Slot & Block Monitoring Track network consensus and block production.
Stream Pump AMM Data Real-world example: monitor Pump.fun AMM transactions.
Decoding Transaction Data Parse the binary transaction payloads into readable Solana transactions.
Yellowstone protocol reference The same workflow against the raw Yellowstone gRPC protocol.