# eth_uninstallFilter - Monad RPC Method

Removes a filter on Monad 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 Monad?** Build on the parallel EVM L1 delivering 10,000 TPS with 400ms blocks and sub-cent gas fees with optimistic parallel execution, MonadBFT consensus, $244M Paradigm-led funding, and consumer-grade validator hardware requirements.

## When to Use This Method

`eth_uninstallFilter` is important for high-performance dApp developers, DeFi builders, and teams requiring Ethereum compatibility at scale:

- **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

## Best Practices

- Always uninstall filters in a `finally` block to guarantee cleanup even when errors occur
- Filters expire automatically after a period of inactivity, but explicit uninstallation is more reliable
- Uninstall all active filters when your application shuts down to avoid leaving orphaned resources

## Request Parameters

- `filterId` (`QUANTITY, required`): The ID of the filter to remove (returned by eth_newFilter, eth_newBlockFilter, or eth_newPendingTransactionFilter)

## Request Example

```json
{
  "jsonrpc": "2.0",
  "method": "eth_uninstallFilter",
  "params": ["0x1"],
  "id": 1
}
```

## Response Fields

- `result` (`Boolean, required`): true if the filter was found and successfully removed, false if the filter ID was not found (already removed or expired)

## Successful Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}
```

## Code Examples

cURL
JavaScript
Python
Go

```bash
curl -X POST https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_uninstallFilter",
    "params": ["0x1"],
    "id": 1
  }'
```

```javascript
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY');

// Create a filter first
const filterId = await provider.send('eth_newBlockFilter', []);
console.log('Created filter:', filterId);

// ... poll with eth_getFilterChanges ...

// Remove the filter when done
const removed = await provider.send('eth_uninstallFilter', [filterId]);
console.log('Filter removed:', removed);
```

```python
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY'))

# Create a filter
filter_id = w3.eth.filter('latest').filter_id

# ... poll for changes ...

# Remove the filter when done
removed = w3.provider.make_request('eth_uninstallFilter', [filter_id])
print(f'Filter removed: {removed["result"]}')

# Using requests directly
import requests

response = requests.post(
    'https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY',
    json={
        'jsonrpc': '2.0',
        'method': 'eth_uninstallFilter',
        'params': ['0x1'],
        'id': 1
    }
)
print(f'Removed: {response.json()["result"]}')
```

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/rpc"
)

func main() {
    client, err := rpc.Dial("https://api-monad-mainnet-full.n.dwellir.com/YOUR_API_KEY")
    if err != nil {
        log.Fatal(err)
    }

    // Create a block filter
    var filterId string
    err = client.CallContext(context.Background(), &filterId, "eth_newBlockFilter")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Created filter: %s\n", filterId)

    // Remove the filter
    var removed bool
    err = client.CallContext(context.Background(), &removed, "eth_uninstallFilter", filterId)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Filter removed: %t\n", removed)
}
```

## Common Use Cases

### 1. Filter Lifecycle Manager

Create a managed filter that automatically cleans up:

```javascript
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:

```javascript
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:

```python
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()
```

## Related Methods

- [`eth_newFilter`](https://www.dwellir.com/docs/monad/eth_newFilter) - Create a log event filter
- [`eth_newBlockFilter`](https://www.dwellir.com/docs/monad/eth_newBlockFilter) - Create a new block filter
- [`eth_newPendingTransactionFilter`](https://www.dwellir.com/docs/monad/eth_newPendingTransactionFilter) - Create a pending transaction filter
- [`eth_getFilterChanges`](https://www.dwellir.com/docs/monad/eth_getFilterChanges) - Poll a filter for new results
- [`eth_getFilterLogs`](https://www.dwellir.com/docs/monad/eth_getFilterLogs) - Get all logs matching a filter
