Docs
Supported ChainsCronosJSON-RPC APISmart Contract Methods

eth_newFilter - Cronos RPC Method

Create an event log filter on Cronos. Essential for event monitoring, contract activity tracking, and DeFi event streaming for DeFi protocols, NFT marketplaces, and Crypto.com ecosystem integrations.

Creates a filter object on Cronos based on the given filter options, to notify when the state changes (new logs). The filter monitors for log entries that match the specified criteria — contract addresses, topics, and block ranges. Use eth_getFilterChanges to poll for new matching logs or eth_getFilterLogs to retrieve all matching logs at once.

Why Cronos? Build on the EVM-compatible Crypto.com blockchain with fast finality and deep Crypto.com ecosystem integration.

When to Use This Method

eth_newFilter is essential for Cronos developers building DeFi and payment applications:

  • Event Monitoring — Subscribe to specific contract events on Cronos such as token transfers, approvals, or governance votes
  • Contract Activity Tracking — Watch one or multiple contracts for any emitted events relevant to DeFi protocols, NFT marketplaces, and Crypto.com ecosystem integrations
  • DeFi Event Streaming — Monitor swap events, liquidity changes, or oracle price updates in real time
  • Incremental Indexing — Build event indexes by creating a filter and polling with eth_getFilterChanges for only new logs

Request Parameters

Request
fromBlockQUANTITY|TAG

Starting block number (hex) or tag ("latest", "earliest", "pending"). Defaults to "latest"

toBlockQUANTITY|TAG

Ending block number (hex) or tag. Defaults to "latest"

addressDATA

No

topicsArray<DATA

null>

Response Body

Response
resultQUANTITY

A hex-encoded filter ID used to poll for matching logs via eth_getFilterChanges or eth_getFilterLogs

Error Responses

Errors
Error Response-32000

Code Examples

Bash
# Create a filter for Transfer events on a specific contract
curl -X POST https://api-cronos-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_newFilter",
    "params": [{
      "fromBlock": "latest",
      "address": "0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23",
      "topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
    }],
    "id": 1
  }'

Common Use Cases

1. ERC-20 Token Transfer Monitor

Watch for all transfers of a specific token on Cronos:

JavaScript
async function monitorTokenTransfers(provider, tokenAddress) {
  // keccak256('Transfer(address,address,uint256)')
  const transferTopic = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';

  const filterId = await provider.send('eth_newFilter', [{
    fromBlock: 'latest',
    address: tokenAddress,
    topics: [transferTopic]
  }]);

  console.log(`Monitoring ${tokenAddress} transfers...`);

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

      for (const log of logs) {
        const from = '0x' + log.topics[1].slice(26);
        const to = '0x' + log.topics[2].slice(26);
        const value = BigInt(log.data);

        console.log(`Transfer: ${from} -> ${to} (${value})`);
      }
    } catch (error) {
      if (error.message.includes('filter not found')) {
        console.log('Filter expired — application should recreate');
      }
    }
  }, 3000);

  return filterId;
}

2. Multi-Event DeFi Monitor

Track multiple event types across DEX contracts:

JavaScript
async function monitorDeFiEvents(provider, dexRouterAddress) {
  // Watch for Swap and LiquidityAdded events
  const swapTopic = '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822';
  const syncTopic = '0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1';

  const filterId = await provider.send('eth_newFilter', [{
    fromBlock: 'latest',
    address: dexRouterAddress,
    topics: [[swapTopic, syncTopic]]  // OR matching — either event type
  }]);

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

    for (const log of logs) {
      const eventType = log.topics[0] === swapTopic ? 'SWAP' : 'SYNC';
      console.log(`${eventType} at block ${parseInt(log.blockNumber, 16)}`);
    }
  }, 2000);

  return filterId;
}

3. Filter Lifecycle Manager

Manage filter creation, polling, and cleanup with automatic renewal:

JavaScript
class FilterManager {
  constructor(provider) {
    this.provider = provider;
    this.filters = new Map();
  }

  async createFilter(name, filterParams, callback) {
    const filterId = await this.provider.send('eth_newFilter', [filterParams]);

    const filter = {
      id: filterId,
      params: filterParams,
      callback,
      interval: setInterval(() => this.poll(name), 3000),
      lastPoll: Date.now()
    };

    this.filters.set(name, filter);
    console.log(`Filter "${name}" created: ${filterId}`);
    return filterId;
  }

  async poll(name) {
    const filter = this.filters.get(name);
    if (!filter) return;

    try {
      const logs = await this.provider.send('eth_getFilterChanges', [filter.id]);
      filter.lastPoll = Date.now();

      if (logs.length > 0) {
        await filter.callback(logs);
      }
    } catch (error) {
      if (error.message.includes('filter not found')) {
        console.log(`Filter "${name}" expired — recreating...`);
        const newId = await this.provider.send('eth_newFilter', [filter.params]);
        filter.id = newId;
      }
    }
  }

  async removeFilter(name) {
    const filter = this.filters.get(name);
    if (!filter) return;

    clearInterval(filter.interval);
    await this.provider.send('eth_uninstallFilter', [filter.id]);
    this.filters.delete(name);
    console.log(`Filter "${name}" removed`);
  }

  async removeAll() {
    for (const name of this.filters.keys()) {
      await this.removeFilter(name);
    }
  }
}

// Usage
const manager = new FilterManager(provider);

await manager.createFilter('transfers', {
  fromBlock: 'latest',
  address: '0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23',
  topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef']
}, (logs) => {
  console.log(`${logs.length} new transfer events`);
});

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32000Filter block range too largeReduce the range between fromBlock and toBlock
-32000Too many topicsLimit topics array to 4 entries maximum
-32602Invalid paramsVerify address format (0x-prefixed, 20 bytes) and topic format (0x-prefixed, 32 bytes)
-32603Internal errorNode may be overloaded — retry with exponential backoff
-32005Rate limit exceededReduce filter creation frequency
JavaScript
async function createFilterSafely(provider, params, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const filterId = await provider.send('eth_newFilter', [params]);
      return filterId;
    } catch (error) {
      if (error.message.includes('block range too large')) {
        // Narrow the range — split in half
        const from = parseInt(params.fromBlock, 16);
        const to = parseInt(params.toBlock, 16);
        const mid = Math.floor((from + to) / 2);
        console.warn(`Block range too large — splitting at ${mid}`);
        throw new Error(`Split needed: ${from}-${mid} and ${mid + 1}-${to}`);
      }
      if (error.code === -32005 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000;
        await new Promise(r => setTimeout(r, delay));
      } else {
        throw error;
      }
    }
  }
}