Skip to content

Stream USDC transfers

Stream Ethereum USDC contract activity through a standard Substreams package.

Stream the activity of one Ethereum contract, USDC, as the input to a transfer index or activity feed. This guide passes the contract address to a package module as a parameter, then shows how to pick Transfer events out of the output.

The pinned module returns event addresses, topics, and transaction hashes, not decoded amounts. Your consumer filters and stores the transfer records, then commits them with the block's cursor.

Prerequisites

  • A Substreams API key.
  • A consumer that can decode the module's eth.event.v1.Events output type.
  • A durable store for transfer rows and cursors.

Stream the contract's events

USDC on Ethereum mainnet:

0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

--params passes the address to map_contract_events, which then returns only that contract's events. The CLI tab is a complete command over 100 blocks. The Go, Rust, and TypeScript tabs show the values a standard Substreams client library needs, including the module parameter.

export SUBSTREAMS_API_KEY="<GRAPHOPS_API_KEY>"

substreams run \
  -e "https://1.evm.substreams.graphops.xyz" \
  "https://github.com/streamingfast/substreams-explorers/releases/download/v1.0.1/ethereum-explorer-v0.1.2.spkg" \
  "map_contract_events" \
  --start-block 18000000 \
  --stop-block +100 \
  --params "map_contract_events=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" \
  -o json

Read the output

CLI JSON places the events inside @data and identifies the output type with @type. Addresses, topics, and transaction hashes are lowercase hexadecimal strings without a 0x prefix. The values below are illustrative.

{
  "@module": "map_contract_events",
  "@block": 18000000,
  "@type": "eth.event.v1.Events",
  "@data": {
    "events": [
      {
        "address": "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "topics": [
          "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
          "0000000000000000000000001111111111111111111111111111111111111111",
          "0000000000000000000000002222222222222222222222222222222222222222"
        ],
        "txHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
      }
    ]
  }
}
  • topics[0] identifies the event. ddf252ad… is the ERC-20 Transfer signature; keep events that match it.
  • topics[1] and topics[2] are the sender and recipient, left-padded to 32 bytes. The last 40 hex characters are the address.
  • txHash links the event to its transaction.

This module does not include the log data field, so transfer amounts are not available. Use a package that emits full logs or decoded transfers when your consumer needs amounts.

Before production

  • Commit a block's transfer rows and its cursor together.
  • Handle undo signals if you follow blocks near the chain head; see Cursors and reorgs.
  • Backfill history with finite ranges, then continue live; see Backfill a range.
  • Watch bytes out. Event-heavy modules can produce large responses.

Next steps