eth_uninstallFilter - Flow EVM RPC Method
Remove a filter on Flow EVM Gateway created by eth_newFilter, eth_newBlockFilter, or eth_newPendingTransactionFilter. Essential for resource cleanup after event monitoring.
Removes a filter on Flow EVM Gateway that was previously created with eth_newFilter, eth_newBlockFilter, or eth_newPendingTransactionFilter. Should always be called when a filter is no longer needed to free server-side resources.
Why Flow EVM? Build on the EVM-equivalent layer on Flow blockchain enabling Cadence+Solidity composability with full EVM equivalence on Flow, atomic multi-operation transactions, 40% lower gas fees, and 473% contract growth in 2025.
When to Use This Method
eth_uninstallFilter is important for NFT developers, gaming studios, and Solidity devs seeking Cadence interoperability:
- Resource Cleanup — Remove filters you no longer need to free memory and processing on the node
- Post-Monitoring Teardown — Clean up after event monitoring sessions end or when switching to different filter criteria
- Preventing Stale Filters — Proactively remove filters before they auto-expire to maintain clean state
- Connection Management — Uninstall filters before disconnecting to avoid orphaned server-side resources
Code Examples
Common Use Cases
1. Filter Lifecycle Manager
Create a managed filter that automatically cleans up:
class ManagedFilter {
constructor(provider) {
this.provider = provider;
this.filterId = null;
this.polling = false;
}
async createLogFilter(filterOptions) {
this.filterId = await this.provider.send('eth_newFilter', [filterOptions]);
console.log('Filter created:', this.filterId);
return this.filterId;
}
async createBlockFilter() {
this.filterId = await this.provider.send('eth_newBlockFilter', []);
return this.filterId;
}
async poll() {
if (!this.filterId) throw new Error('No active filter');
return await this.provider.send('eth_getFilterChanges', [this.filterId]);
}
async destroy() {
if (this.filterId) {
const removed = await this.provider.send('eth_uninstallFilter', [this.filterId]);
console.log(`Filter ${this.filterId} removed: ${removed}`);
this.filterId = null;
return removed;
}
return false;
}
}
// Usage
const filter = new ManagedFilter(provider);
await filter.createBlockFilter();
try {
const changes = await filter.poll();
console.log('New blocks:', changes);
} finally {
await filter.destroy();
}2. Event Monitor with Cleanup
Monitor events for a limited duration, then clean up all filters:
async function monitorEvents(provider, contractAddress, topics, duration = 60000) {
const filterId = await provider.send('eth_newFilter', [{
address: contractAddress,
topics
}]);
const allEvents = [];
const interval = setInterval(async () => {
const changes = await provider.send('eth_getFilterChanges', [filterId]);
if (changes.length > 0) {
allEvents.push(...changes);
console.log(`Received ${changes.length} new events`);
}
}, 2000);
// Stop monitoring after the specified duration
await new Promise(r => setTimeout(r, duration));
clearInterval(interval);
// Always clean up the filter
const removed = await provider.send('eth_uninstallFilter', [filterId]);
console.log(`Monitoring complete. Filter removed: ${removed}. Total events: ${allEvents.length}`);
return allEvents;
}3. Bulk Filter Cleanup
Remove all tracked filters during application shutdown:
import requests
class FilterRegistry:
def __init__(self, rpc_url):
self.rpc_url = rpc_url
self.active_filters = []
def create_filter(self, filter_type='block'):
method = {
'block': 'eth_newBlockFilter',
'pending': 'eth_newPendingTransactionFilter',
}.get(filter_type, 'eth_newBlockFilter')
response = requests.post(
self.rpc_url,
json={'jsonrpc': '2.0', 'method': method, 'params': [], 'id': 1}
)
filter_id = response.json()['result']
self.active_filters.append(filter_id)
return filter_id
def cleanup_all(self):
removed = 0
for filter_id in self.active_filters:
response = requests.post(
self.rpc_url,
json={'jsonrpc': '2.0', 'method': 'eth_uninstallFilter', 'params': [filter_id], 'id': 1}
)
if response.json().get('result'):
removed += 1
print(f'Cleaned up {removed}/{len(self.active_filters)} filters')
self.active_filters.clear()Error Handling
| Error Code | Description | Solution |
|---|---|---|
| -32602 | Invalid params | Ensure the filter ID is a valid hex string |
| -32603 | Internal error | Node may be starting up — retry after delay |
| -32005 | Rate limit exceeded | Implement backoff between cleanup calls |
false result | Filter not found | Filter already expired or was already removed — safe to ignore |
Related Methods
eth_newFilter— Create a log event filtereth_newBlockFilter— Create a new block filtereth_newPendingTransactionFilter— Create a pending transaction filtereth_getFilterChanges— Poll a filter for new resultseth_getFilterLogs— Get all logs matching a filter
eth_getFilterLogs
Returns all logs matching a previously created filter on Flow EVM Gateway. Essential for initial log retrieval, backfilling event data, and one-time historical queries for consumer NFTs (NBA Top Shot, Disney Pinnacle), gaming dApps, and hybrid Cadence-EVM applications.
eth_newBlockFilter
Create a filter for new block notifications on Flow EVM Gateway. Essential for block monitoring, chain progression tracking, and reorg detection for consumer NFTs (NBA Top Shot, Disney Pinnacle), gaming dApps, and hybrid Cadence-EVM applications.