Home / Solutions / Gaming
Gaming

Web3 gaming data: items, currencies, and marketplace activity

Most game logic runs offchain; what reaches the chain is the asset layer: items, currencies, and marketplace settlement, emitted as contract events. SQD serves those events decoded across 225+ networks, game-built chains like Immutable zkEVM and DFK Chain included, with history from each contract's first block.

225+ Networks
ERC-721/1155 Item standards
Genesis Full history
4 Transfer signatures
The problem

A web3 game's onchain economy is public event data, and reading it back is the hard part

Item ownership, in-game currencies, and marketplace history are all read back from the events those contracts emit, which means decoding the whole transfer family, where ERC-721 and ERC-20 share one topic0 and ERC-1155 ids and quantities ride in the data payload rather than in topics. Doing it against a node is eth_getLogs paginated over a contract's full history under per-call caps; doing it against a curated NFT API means only the chains and collections that provider has already integrated. The events are onchain already; the cost is in decoding them and folding them into holdings.

How it works

A game economy onchain is one log stream

Immutable zkEVM is a network built for games; the Portal serves it as immutable-zkevm-mainnet. Blocks 40,600,000 to 40,600,999, about 33 minutes of chain time on 2026-07-08, carry 1,134 token-movement logs across the four transfer signatures:

Event signatureLogs
  • ERC-721 Transfer (4 topics)780
  • ERC-20 Transfer (3 topics)336
  • ERC-1155 TransferSingle14
  • ERC-1155 TransferBatch4
Transfer-family logs, Immutable zkEVM blocks 40,600,000-40,600,999 (1,134 total)

Per the network's explorer, 753 of the 780 ERC-721 transfers are the items of three games: Gods Unchained cards (379), Illuvium Illuvials (307), and Habbo furniture and clothing (67). On the fungible side, the two largest movers are bridged ETH (129 transfers) and the GODS token (117), the currency of Gods Unchained. Items and currency arrive in the same stream, keyed by address and topic0.

Pulling one game's item movements is a filter on the collection address and the Transfer signature:

your terminal
curl -s -X POST https://portal.sqd.dev/datasets/immutable-zkevm-mainnet/stream \
-H 'content-type: application/json' \
-d '{
"type": "evm",
"fromBlock": 40600000, "toBlock": 40600999,
"logs": [{ "address": ["0x06d92b637dfcdf95a2faba04ef22b2a096029b69"],
"topic0": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"] }],
"fields": { "block": { "number": true }, "log": { "topics": true, "data": true, "transactionHash": true } }
}'

One gotcha sits in plain sight: ERC-721 and ERC-20 share the same topic0. The difference is the shape, four topics and an empty data field here, because tokenId is indexed and there is no amount; an ERC-20 transfer has three topics and its amount in data. A decoder keyed on the signature alone misreads one as the other. topics[3] is the card, token 298,456,441. Across the window the query returns 379 card movements: 96 mints from the zero address, 145 burns to it, 42 distinct wallets on either side.

The first line back is a bare block header (the stream returns only blocks with matching data, plus chunk-boundary headers). The first card movement lands at block 40,600,013:

first returned row
{
"header": { "number": 40600013 },
"logs": [{
"transactionHash": "0xf8dc5a21c3caaf96a2eaf4b6f899e77a4c6a25a417b06cf919ff8ff114c27336",
"data": "0x",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000044e60c93c38b3fb295016bbddf0a87077d8df63",
"0x00000000000000000000000053deb88b010beb7ac65315fc6f6f1eb560f451a7",
"0x0000000000000000000000000000000000000000000000000000000011ca1579"
]
}]
}

The boundary is worth stating: most game logic never touches the chain. What is onchain is the asset layer, items, currencies, and marketplace settlement, and that layer is what SQD serves.

Batch inventories

One log can move an entire inventory

Stackable game items use ERC-1155, a standard designed for exactly this: one TransferBatch log packs token ids and quantities as two arrays. Sunflower Land's inventory contract on Polygon (0x22d5…7422, pinned in the game's own deploy configuration) shows the production pattern. At block 78,500,026 (2025-11-02), one transaction synced a player's session: two TransferBatch logs, one minting 38 item stacks to 0x47ee…b604, one burning 33 stacks from the same wallet.

ItemidRaw valueQty
  • Potato202238000000000000000000238
  • Pumpkin203250000000000000000000250
  • Magic Mushroom6161000000000000000000010
  • Wheat Cake51422
  • Pirate Cake54088
Five of the 38 stacks minted in the first returned log; names and decimals from the game's published erc1155 metadata

Pulling that session is a filter on the inventory contract and the TransferBatch signature:

your terminal
curl -s -X POST https://portal.sqd.dev/datasets/polygon-mainnet/stream \
-H 'content-type: application/json' \
-d '{
"type": "evm",
"fromBlock": 78500026, "toBlock": 78500026,
"logs": [{ "address": ["0x22d5f9b75c524fec1d6619787e582644cd4d7422"],
"topic0": ["0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb"] }],
"fields": { "block": { "number": true, "timestamp": true }, "log": { "topics": true, "data": true, "transactionHash": true } }
}'

Three gotchas in one row: the ids and quantities arrive ABI-encoded in the data payload (5,120 hex characters on the mint leg), not in topics, so there is no topic-filtering by item id: you filter the contract and decode. One contract mixes denominations: crops like Potato carry 18 decimals while consumables like Wheat Cake carry 0, and only the game's metadata says which is which, so a decoder that assumes either misreads the other. And a batch carrying a single id still emits TransferBatch, not TransferSingle (this contract emitted single-item batches at block 89,900,099 on 2026-07-08), so an indexer that only decodes TransferSingle silently drops moves.

The response is one NDJSON line carrying both logs of transaction 0x89df…ee8b. Decoding the mint leg against the game's published item metadata gives the table above.

mint leg of the returned line
{
"header": { "number": 78500026, "timestamp": 1762104905 },
"logs": [{
"transactionHash": "0x89df96b028ae2d8eb091bf98f1780880bcaf4684029446654eb4026800c1ee8b",
"data": "0x00000000…00000009",
"topics": [
"0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb",
"0x000000000000000000000000f3ab48f12e8ecd8377e0d1f1c2d323cc8635a214",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x00000000000000000000000047ee1580f15b27b601f450aa10bf5638c1b1b604"
]
}]
}

The mint leg's data is elided to its first and last bytes here: it carries 5,120 hex characters of ABI-encoded ids and quantities, and the curl above returns it in full.

Doing this against a node means eth_getLogs with per-call block-range and result caps, paginated over the contract's full history, against an archive endpoint (the caps are concrete). Doing it with a curated NFT API means the chains and collections the provider has integrated; a game on its own network is covered only if that network made the list. The Portal side is one query shape over the served datasets, immutable-zkevm-mainnet, beam-mainnet, dfk-chain, skale-nebula, b3-mainnet, and polygon-mainnet among them, with history from each contract's first block. What it does not return is reconstructed state: no ownerOf, no balance-at-block, no metadata. Holdings are a fold over the transfer history, and item art comes from the game's own endpoints, fetched in your pipeline, the pattern Chillwhales runs for NFT browsing on LUKSO.

Capabilities

Built for Gaming at scale

Item ownership from transfer history

ERC-721 and ERC-1155 items move as Transfer, TransferSingle, and TransferBatch logs. Filter the game's contracts, decode against the ABI, and fold the history into holdings: ERC-721 ownership is the latest transfer per token id; ERC-1155 quantities ride in the data payload, not in topics.

In-game currencies in the same stream

A game currency is an ERC-20: mints from the zero address, burns to it, and player-to-player transfers arrive in the same log stream as the items, keyed by address and topic0. On Immutable zkEVM, Gods Unchained cards and the GODS token are one address filter apart.

Marketplace settlement, decoded

An onchain marketplace fill emits the marketplace's own event plus the item and payment transfers in one transaction. Reading all three from the same stream ties sale price to item movement, without waiting for a curated NFT API to integrate the collection or its chain.

Game networks are served datasets

Immutable zkEVM, Beam, DFK Chain, SKALE Nebula, and B3 are Portal datasets with history from block 0, the same query shape as Ethereum or Polygon. A game on its own network is a dataset name, not a separate integration.

Why SQD

What you would build yourself

The items, currencies, and settlement are public events; the work a provider saves is in reading them across every game and its own network.

  • Full-history reads
    Yourself eth_getLogs against an archive node, paginated over the contract's full history under per-call block-range and result caps.
    With SQD One query shape over the served dataset takes the whole range and returns only the blocks whose logs match, with history from each contract's first block.
  • Game networks
    Yourself A curated NFT API covers a game on its own network only if the provider has already integrated that network.
    With SQD Immutable zkEVM, Beam, DFK Chain, SKALE Nebula, and B3 are served datasets, the same query shape as Ethereum or Polygon.
  • Marketplace fills
    Yourself A curated NFT API surfaces a collection's sales only after it integrates the collection and its chain.
    With SQD The marketplace fill, the item transfer, and the payment transfer land in one transaction and read from the same stream, tying sale price to item movement.

See this on your own contracts

Tell us the chains and contracts you care about, and we will show you the query that returns them.

Use cases

What teams build with SQD

  • Item ownership and holdings folded from transfer history
  • In-game currency dashboards from mint, burn, and transfer events
  • Marketplace activity and sale-history feeds from settlement events
  • Player activity metrics from decoded contract events
  • Wallet inventory views across games and chains
  • Full-history backfills from a game contract's first block

Frequently asked questions

How do I index game assets like ERC-721 and ERC-1155 items?
Filter the game's contract addresses and the three transfer signatures (Transfer, TransferSingle, TransferBatch) in one Portal query, then decode against the ABI. ERC-721 ownership is the latest transfer per token id; ERC-1155 holdings fold quantities across TransferSingle and TransferBatch, whose ids and amounts ride in the data payload rather than in topics. The Portal serves the full history from the contract's first block, so a new indexer backfills and stays current through the same query.
Which gaming blockchains does SQD support?
The Portal dataset list includes networks run by and for games, Immutable zkEVM, Beam, DFK Chain, SKALE Nebula, and B3, alongside the general-purpose chains games deploy on: Ethereum, Polygon, Arbitrum, Base, and the rest of the 225+ supported networks. Each is the same query shape with a different dataset name. See the full chain list.
Can I get player inventories and item metadata from the API?
Not as precomputed fields. The Portal serves the events game contracts emit (transfers, mints, burns, marketplace fills), not reconstructed state: there is no ownerOf or balance-at-block endpoint. Inventories are a fold over the transfer history in your indexer, and item metadata comes from the game's own tokenURI endpoints, fetched and cached in your pipeline. That is the pattern Chillwhales runs for NFT browsing on LUKSO.
Get started

Your blockchain data infrastructure, handled.

Private Portal. Dedicated. Validated. Managed. Tell us what you're building, we'll show you what it looks like on SQD.