# eth_newPendingTransactionFilter - Tempo RPC Method

Creates a filter on Tempo that notifies when new pending transactions are added to the mempool. Once created, poll the filter with `eth_getFilterChanges` to receive an array of transaction hashes for pending transactions that have appeared since your last poll.

> **Why Tempo?** Build on a payments-first EVM chain with deterministic settlement and stablecoin-native fees with no native gas token, fees denominated in supported USD stablecoins, and full EVM RPC compatibility.

## When to Use This Method

`eth_newPendingTransactionFilter` is essential for payment application developers, wallet teams, stablecoin issuers, and treasury automation builders:

- **Mempool Monitoring** - Observe unconfirmed transactions on Tempo to understand network activity and congestion
- **Transaction Tracking** - Detect when a specific transaction enters the mempool before it is mined
- **MEV Opportunity Detection** - Identify arbitrage, liquidation, or sandwich opportunities by watching pending transactions
- **Gas Price Estimation** - Analyze pending transactions to estimate optimal gas pricing for merchant settlement, treasury operations, payout automation, and stablecoin-native financial applications

## Best Practices

- High data volume from mempool monitoring requires efficient handling; filter and process selectively
- Use WebSocket `eth_subscribe("newPendingTransactions")` for production-grade pending transaction monitoring
- Pending filter results may include transactions that are never mined; do not treat them as confirmed

## Request Parameters

This method accepts no parameters.

## Request Example

```json
{
  "jsonrpc": "2.0",
  "method": "eth_newPendingTransactionFilter",
  "params": [],
  "id": 1
}
```

## Response Fields

- `result` (`QUANTITY, required`): A hex-encoded filter ID used to poll for pending transactions via eth_getFilterChanges
- `result` (`Array<DATA>, required`): Array of 32-byte transaction hashes for pending transactions since the last poll

## Successful Response

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

## Error Responses

### Error Response

- Code: `-32603`

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Internal error"
  }
}
```

## Code Examples

cURL
JavaScript
Python
Go

```bash
# Create the pending transaction filter
FILTER_ID=$(curl -s -X POST https://api-tempo-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_newPendingTransactionFilter",
    "params": [],
    "id": 1
  }' | jq -r '.result')

echo "Filter ID: $FILTER_ID"

# Poll for pending transactions
curl -X POST https://api-tempo-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"eth_getFilterChanges\",
    \"params\": [\"$FILTER_ID\"],
    \"id\": 2
  }"
```

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

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

// Create a pending transaction filter
const filterId = await provider.send('eth_newPendingTransactionFilter', []);
console.log('Pending tx filter created:', filterId);

// Poll for pending transactions
async function pollPendingTxs(interval = 1000) {
  while (true) {
    const txHashes = await provider.send('eth_getFilterChanges', [filterId]);
    if (txHashes.length > 0) {
      console.log(`${txHashes.length} new pending transactions`);
      for (const hash of txHashes) {
        const tx = await provider.getTransaction(hash);
        if (tx) {
          console.log(`  ${hash} | to: ${tx.to} | value: ${tx.value}`);
        }
      }
    }
    await new Promise(r => setTimeout(r, interval));
  }
}

pollPendingTxs();
```

```python
import requests
import time

RPC_URL = 'https://api-tempo-mainnet.n.dwellir.com/YOUR_API_KEY'

def rpc_call(method, params):
    response = requests.post(RPC_URL, json={
        'jsonrpc': '2.0',
        'method': method,
        'params': params,
        'id': 1
    })
    return response.json()

# Create pending transaction filter
filter_result = rpc_call('eth_newPendingTransactionFilter', [])
filter_id = filter_result['result']
print(f'Pending tx filter created: {filter_id}')

# Poll for pending transactions
while True:
    changes = rpc_call('eth_getFilterChanges', [filter_id])
    tx_hashes = changes.get('result', [])
    if tx_hashes:
        print(f'{len(tx_hashes)} new pending transactions')
        for tx_hash in tx_hashes[:5]:  # Show first 5
            tx = rpc_call('eth_getTransactionByHash', [tx_hash])
            tx_data = tx.get('result', {})
            if tx_data:
                print(f'  {tx_hash} | to: {tx_data.get("to")} | value: {tx_data.get("value")}')
    time.sleep(1)
```

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

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

    // Subscribe to pending transactions
    pendingTxs := make(chan common.Hash)
    sub, err := client.SubscribePendingTransactions(context.Background(), pendingTxs)
    if err != nil {
        log.Fatal("Subscription failed:", err)
    }

    fmt.Println("Monitoring pending transactions on Tempo...")

    for {
        select {
        case err := <-sub.Err():
            log.Fatal(err)
        case txHash := <-pendingTxs:
            tx, isPending, err := client.TransactionByHash(context.Background(), txHash)
            if err == nil && isPending {
                fmt.Printf("Pending tx: %s | to: %s | value: %s\n",
                    txHash.Hex(), tx.To().Hex(), tx.Value().String())
            }
        }
    }
}
```

## Common Use Cases

### 1. Mempool Activity Dashboard

Monitor mempool throughput and transaction types on Tempo:

```javascript
async function mempoolDashboard(provider) {
  const filterId = await provider.send('eth_newPendingTransactionFilter', []);

  const stats = {
    totalSeen: 0,
    contractCalls: 0,
    transfers: 0,
    intervalStart: Date.now()
  };

  setInterval(async () => {
    const txHashes = await provider.send('eth_getFilterChanges', [filterId]);
    stats.totalSeen += txHashes.length;

    for (const hash of txHashes) {
      try {
        const tx = await provider.getTransaction(hash);
        if (!tx) continue;

        if (tx.data && tx.data !== '0x') {
          stats.contractCalls++;
        } else {
          stats.transfers++;
        }
      } catch (e) {
        // Transaction may have been mined or dropped
      }
    }

    const elapsed = (Date.now() - stats.intervalStart) / 1000;
    const txPerSec = (stats.totalSeen / elapsed).toFixed(1);
    console.log(`Mempool: ${stats.totalSeen} txs (${txPerSec}/s) | Calls: ${stats.contractCalls} | Transfers: ${stats.transfers}`);
  }, 2000);
}
```

### 2. Track Specific Address Activity

Watch for pending transactions involving a target address:

```javascript
async function watchAddress(provider, targetAddress) {
  const filterId = await provider.send('eth_newPendingTransactionFilter', []);
  const target = targetAddress.toLowerCase();

  console.log(`Watching pending transactions for ${targetAddress}...`);

  setInterval(async () => {
    const txHashes = await provider.send('eth_getFilterChanges', [filterId]);

    for (const hash of txHashes) {
      try {
        const tx = await provider.getTransaction(hash);
        if (!tx) continue;

        const isFrom = tx.from?.toLowerCase() === target;
        const isTo = tx.to?.toLowerCase() === target;

        if (isFrom || isTo) {
          console.log(`Pending tx detected for ${targetAddress}:`);
          console.log(`  Hash: ${hash}`);
          console.log(`  Direction: ${isFrom ? 'OUTGOING' : 'INCOMING'}`);
          console.log(`  Value: ${tx.value} wei`);
          console.log(`  Gas price: ${tx.gasPrice} wei`);
        }
      } catch (e) {
        // Transaction already mined or dropped
      }
    }
  }, 1000);
}
```

### 3. Large Transaction Alert System

Detect high-value pending transactions:

```javascript
async function largeTransactionAlerts(provider, thresholdEth = 10) {
  const filterId = await provider.send('eth_newPendingTransactionFilter', []);
  const thresholdWei = BigInt(thresholdEth * 1e18);

  setInterval(async () => {
    const txHashes = await provider.send('eth_getFilterChanges', [filterId]);

    for (const hash of txHashes) {
      try {
        const tx = await provider.getTransaction(hash);
        if (!tx || !tx.value) continue;

        if (BigInt(tx.value) >= thresholdWei) {
          const ethValue = Number(BigInt(tx.value)) / 1e18;
          console.log(`LARGE TX: ${ethValue.toFixed(4)} ETH`);
          console.log(`  From: ${tx.from}`);
          console.log(`  To: ${tx.to}`);
          console.log(`  Hash: ${hash}`);
        }
      } catch (e) {
        // Transaction may have already been mined
      }
    }
  }, 1000);
}
```

## Related Methods

- [`eth_getFilterChanges`](https://www.dwellir.com/docs/tempo/eth_getFilterChanges) - Poll this filter for new pending transaction hashes
- [`eth_uninstallFilter`](https://www.dwellir.com/docs/tempo/eth_uninstallFilter) - Remove the filter when no longer needed
- [`eth_getTransactionByHash`](https://www.dwellir.com/docs/tempo/eth_getTransactionByHash) - Fetch full transaction details for hashes returned by the filter
- [`eth_sendRawTransaction`](https://www.dwellir.com/docs/tempo/eth_sendRawTransaction) - Submit a transaction that will appear in the pending pool
