Created
May 28, 2025 20:29
-
-
Save gayleQN/33318822542e6e9786d819239f6afa4d to your computer and use it in GitHub Desktop.
EVM Wallet & ERC20 Transfers! QuickNode Streams filter sample code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const CONFIG = { | |
| Wallets: [ | |
| '0xaaaaaa0000000000000000000000000000000000', | |
| '0xbbbbbb0000000000000000000000000000000000' | |
| ], | |
| ERC20: [ | |
| '0xaaaaaa0000000000000000000000000000000000', | |
| '0xbbbbbb0000000000000000000000000000000000' | |
| ] | |
| }; | |
| const ERC20_TRANSFER_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'; | |
| function stripAddress(topic) { | |
| return '0x' + topic.slice(-40).toLowerCase(); | |
| } | |
| function main(payload) { | |
| const wallets = new Set(CONFIG.Wallets.map(w => w.toLowerCase())); | |
| const erc20Contracts = new Set(CONFIG.ERC20.map(c => c.toLowerCase())); | |
| const matchingTransactions = []; | |
| const matchingReceipts = []; | |
| for (const block of payload.data) { | |
| // Native token transfers | |
| for (const tx of block.block?.transactions || []) { | |
| const from = tx.from?.toLowerCase(); | |
| const to = tx.to?.toLowerCase(); | |
| const value = BigInt(tx.value || '0'); | |
| if (value > 0n && (wallets.has(from) || wallets.has(to))) { | |
| matchingTransactions.push(tx); | |
| } | |
| } | |
| // ERC-20 transfers by topic parsing | |
| for (const receipt of block.receipts || []) { | |
| for (const log of receipt.logs || []) { | |
| if ( | |
| log.topics?.[0] === ERC20_TRANSFER_TOPIC && | |
| log.topics.length >= 3 && | |
| erc20Contracts.has(log.address?.toLowerCase()) | |
| ) { | |
| const from = stripAddress(log.topics[1]); | |
| const to = stripAddress(log.topics[2]); | |
| if (wallets.has(from) || wallets.has(to)) { | |
| matchingReceipts.push(receipt); | |
| break; // one match per receipt is enough | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return (matchingTransactions.length || matchingReceipts.length) | |
| ? { | |
| matchingTransactions: matchingTransactions.length ? matchingTransactions : null, | |
| matchingReceipts: matchingReceipts.length ? matchingReceipts : null | |
| } | |
| : null; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Visit https://dashboard.quicknode.com/streams/new to create your stream
Dataset: Block with Receipts