Docs

eth_newPendingTransactionFilter - Gnosis RPC Method

Create a filter for pending transaction notifications on Gnosis. Essential for mempool monitoring, transaction tracking, and MEV opportunity detection for prediction markets (largest by market cap), Safe wallet infrastructure, CoW Protocol DEX, and Gnosis Pay card integration.

Creates a filter on Gnosis 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 Gnosis? Build on the prediction market pioneer with $260M+ TVL and xDAI stablecoin-based gas fees with stablecoin gas fees for predictable costs, Shutter MEV protection, 150K+ Safe wallets, and Circles decentralized UBI protocol.

When to Use This Method

eth_newPendingTransactionFilter is essential for prediction market builders, DAO tooling developers, and teams building MEV-protected applications:

  • Mempool Monitoring — Observe unconfirmed transactions on Gnosis 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 prediction markets (largest by market cap), Safe wallet infrastructure, CoW Protocol DEX, and Gnosis Pay card integration

Code Examples

Common Use Cases

1. Mempool Activity Dashboard

Monitor mempool throughput and transaction types on Gnosis:

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);
}

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32603Internal errorNode may not expose mempool data — check node configuration
-32000Filter not foundFilter expired (~5 min inactivity) — recreate with eth_newPendingTransactionFilter
-32005Rate limit exceededReduce polling frequency — mempool can be very active
-32601Method not foundNode does not support pending transaction filters — requires a full node with txpool enabled
JavaScript
async function createPendingTxFilter(provider) {
  try {
    const filterId = await provider.send('eth_newPendingTransactionFilter', []);
    return { supported: true, filterId };
  } catch (error) {
    if (error.code === -32601 || error.message.includes('not found')) {
      console.warn('Pending transaction filter not supported by this node');
      console.warn('This method requires a full node with txpool access');
      return { supported: false };
    }
    throw error;
  }
}