portal-query-evm-transactions

Installation
SKILL.md

When to Use This Skill

Use this skill when you need to:

  • Track wallet transaction activity (sent/received)
  • Monitor specific function calls to contracts
  • Find transactions by function selector (sighash)
  • Analyze transaction patterns and volumes
  • Get transactions with their related logs and traces

This is the second most common Portal use case - essential for wallet analysis and contract interaction tracking.


Query Structure

Basic EVM transaction query structure:

{
  "type": "evm",
  "fromBlock": 19500000,
  "toBlock": 19500100,
  "transactions": [{
    "to": ["0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"],
    "sighash": ["0x414bf389"]
  }],
  "fields": {
    "transaction": {
      "hash": true,
      "from": true,
      "to": true,
      "value": true,
      "input": true,
      "status": true
    }
  }
}

Field explanations:

  • type: "evm" - Required for EVM chains (not "solana")
  • fromBlock/toBlock - Block range (required)
  • transactions - Array of transaction filter objects
  • to - Recipient address (INDEXED - fast)
  • from - Sender address (INDEXED - fast)
  • sighash - Function selector (first 4 bytes of input, INDEXED)
  • fields - Which fields to include in response

Understanding Function Selectors (Sighash)

Sighash = first 4 bytes of keccak256(function signature)

// Using ethers.js
import { ethers } from 'ethers';
const sighash = ethers.id("swap(uint256,address[])").slice(0, 10);
// Result: "0x414bf389"

Key rules:

  1. Sighash is first 4 bytes of transaction input data
  2. Computed from function name + parameter types (no spaces, no names)
  3. INDEXED field - fast to query

Examples

Example 1: Track Wallet Outgoing Transactions

{
  "type": "evm",
  "fromBlock": 19500000,
  "toBlock": 19500100,
  "transactions": [{
    "from": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"]
  }],
  "fields": {
    "transaction": {
      "hash": true,
      "from": true,
      "to": true,
      "value": true,
      "gasUsed": true,
      "status": true
    },
    "block": {
      "number": true,
      "timestamp": true
    }
  }
}

Dataset: ethereum-mainnet | Use case: Track vitalik.eth transaction activity Notes: value is in wei (divide by 1e18 for ETH); status: 1 = success, 0 = failed (response field, not filter)


Example 2: Find Uniswap V3 Router Swap Calls

{
  "type": "evm",
  "fromBlock": 19500000,
  "toBlock": 19500100,
  "transactions": [{
    "to": ["0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"],
    "sighash": ["0x414bf389"],
    "logs": true
  }],
  "fields": {
    "transaction": {
      "hash": true,
      "from": true,
      "to": true,
      "value": true,
      "input": true,
      "status": true
    },
    "log": {
      "address": true,
      "topics": true,
      "data": true
    }
  }
}

Dataset: ethereum-mainnet | Contract: Uniswap V3 SwapRouter02 Notes: "logs": true in the transaction filter automatically fetches logs emitted by matched transactions


Example 3: Filter by ERC-20 Transfer Function

{
  "type": "evm",
  "fromBlock": 18000000,
  "toBlock": 18010000,
  "transactions": [{
    "to": ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
    "sighash": ["0xa9059cbb"]
  }],
  "fields": {
    "transaction": {
      "hash": true,
      "from": true,
      "to": true,
      "input": true,
      "status": true
    }
  }
}

Dataset: ethereum-mainnet | Contract: USDC | Function: transfer(address,uint256) | Sighash: 0xa9059cbb

More examples: See references/additional-examples.md for contract deployments, status filtering, multi-function tracking, and fetching related logs/traces.


Transaction Filter Fields

Valid filter fields:

  • from - Transaction sender address (INDEXED - fast)
  • to - Transaction recipient address (INDEXED - fast)
  • sighash - Function selector, first 4 bytes of input (INDEXED - fast)
  • firstNonce - Minimum nonce value (range filter)
  • lastNonce - Maximum nonce value (range filter)
  • logs - Boolean, include related logs for matched transactions
  • traces - Boolean, include related traces for matched transactions
  • stateDiffs - Boolean, include related state diffs for matched transactions

⚠️ Important: status is NOT a valid filter field. It is only available as a response field. Filter by status client-side.


Transaction Response Fields

{
  "hash": true,              // Transaction hash
  "transactionIndex": true,  // Position in block
  "from": true,              // Sender address
  "to": true,                // Recipient address (null for contract creation)
  "input": true,             // Transaction input data (calldata)
  "value": true,             // ETH value in wei
  "nonce": true,             // Sender nonce
  "gas": true,               // Gas limit
  "gasUsed": true,           // Gas actually used
  "gasPrice": true,          // Legacy gas price
  "maxFeePerGas": true,      // EIP-1559 max fee
  "maxPriorityFeePerGas": true, // EIP-1559 priority fee
  "contractAddress": true,   // Deployed contract address (if creation)
  "type": true,              // Transaction type (0, 1, 2)
  "status": true,            // 1 = success, 0 = failed
  "sighash": true,           // Function selector
  "chainId": true            // Chain ID
}

Related Data Joins (logs, traces, stateDiffs)

Add logs, traces, or stateDiffs boolean fields inside each transaction filter object to automatically fetch related data:

{
  "transactions": [{
    "to": ["0x..."],
    "logs": true,       // Include logs emitted by this transaction
    "traces": true,     // Include internal calls
    "stateDiffs": true  // Include storage changes
  }]
}

Important: Must also request the corresponding fields in the fields section.

Contract creation: Use "to": [] (empty array) to filter for deployment transactions. The contractAddress field contains the new contract address.


Common Mistakes

❌ Filtering by Input Data Directly

{"transactions": [{"input": ["0x414bf389..."]}]}  // ❌ Not filterable

Fix: Use "sighash": ["0x414bf389"]


❌ Expecting Related Data Without Requesting It in the Filter

{
  "transactions": [{"to": ["0x..."]}],
  "fields": {"log": {"topics": true}}  // ❌ Logs won't be included
}

Fix: Add "logs": true inside the transaction filter object.


❌ Forgetting Block Range

{"type": "evm", "transactions": [{"to": ["0x..."]}]}  // ❌ No fromBlock/toBlock

Fix: Always specify fromBlock and toBlock.


❌ Querying Too Many Transactions

{"fromBlock": 0, "toBlock": 19500000, "transactions": [{}]}  // ❌ Millions of txs

Fix: Always add address/sighash filters and reasonable block ranges (100-100,000 blocks).


Response Format

Portal returns JSON Lines (one JSON object per line):

{"header":{"number":19500000,"hash":"0x...","timestamp":1234567890}}
{"transactions":[{"hash":"0xabc...","from":"0x123...","to":"0x456...","value":"1000000000000000000","status":1}]}

Parsing: Split by newlines, parse each line as JSON. First line = block header.

With "logs": true - transactions that emitted logs will have a logs array in the same JSON object.


MCP Tools vs Raw API

If Portal MCP tools are available in your environment, use them for quick queries before falling back to the raw Stream API:

Approach When to Use
MCP portal_query_transactions Standard queries by sender, recipient, sighash, block range. Fastest path
MCP portal_get_recent_transactions Quick look at recent activity — auto-calculates block ranges from timeframes like '1h', '24h'
MCP portal_get_wallet_summary Overview of a wallet's recent txs + token transfers in one call
Raw Stream API (curl/fetch) Custom field selection, nonce filtering, joining with logs/traces/state-diffs, or streaming large datasets

Example — MCP quick path: Use portal_get_recent_transactions with dataset, from_addresses or to_addresses, and a timeframe. No block number math needed.

Example — when to use raw API: When you need include_logs: true or include_traces: true to get full transaction context in a single query.


Related Skills

  • portal-query-evm-logs - Query logs emitted by these transactions
  • portal-query-evm-traces - Query internal calls within transactions
  • portal-dataset-discovery - Find correct dataset name for your chain

Additional Resources

Related skills
Installs
10
First Seen
Feb 26, 2026