A report built from the transaction list alone misses value that moves in internal calls: a contract paying out ETH appears in traces, not as a transaction. SQD serves transactions, decoded token transfers, and traces for any address across 225+ networks, with UTC block timestamps and fee fields on every row. Fiat prices and cost-basis math join downstream; the extraction itself is a pinned query anyone can re-run.
A report assembled from an address's transaction list under-reports: a contract paying out ETH does it in an internal call that appears in traces, not as a transaction, and when the recipient is a plain wallet no event log records it either. The complete movement record is three streams filtered by one address: transactions, decoded token transfers, and internal value moves from traces. Any subset silently books zero for the movements it cannot see. SQD serves all three across 225+ networks, with UTC block timestamps and gas-fee fields on every row; fiat prices and cost-basis math join downstream.
On 2026-06-26 at 08:21:35 UTC, one Ethereum transaction paid 15 addresses at once: 0.09 ETH went into the Disperse batch-payment contract (0xd152...2150), which forwarded 0.006 ETH to each recipient inside the same transaction. The chain records one transaction, to Disperse. The 15 payouts are internal calls:
For each of those 15 addresses, the transaction list records nothing. Filter that block by transactions from or to the first recipient and the stream returns a bare header, zero rows:
No event log records it either: an internal ETH transfer to a plain wallet emits nothing, and this block holds no log from the Disperse contract and none that references the recipient in its topics (both checked). A ledger built from transactions and logs alone books zero income for that address on that day. The 0.006 ETH arrived anyway.
The row that does record it is a trace. One filter on internal calls into the address:
Three things to know before booking it: the amount nests under action.value as hex wei (0x1550f7dca70000 is 6,000,000,000,000,000 wei, 0.006 ETH); a trace has no transaction hash of its own, so "transaction": true in the filter is what puts 0xea9b... in the response; and error: null is what says the value actually moved.
Standard JSON-RPC has no address-keyed lookup, and internal calls only exist in the non-standard debug and trace namespaces, so recovering this one row from a node means re-executing blocks and scanning the output yourself, per chain. Here the same trace filter runs unchanged across 225+ networks. Why traces are expensive to pull anywhere else is covered in the internal transactions guide.
A cost-basis engine needs three inputs per movement: how much, when, and what it cost to execute. The same transaction that funded the payout above carries all three, in one row:
The block timestamp is unix seconds, which is UTC by construction: 1782462095 decodes to 2026-06-26 08:21:35 UTC, the key a fiat price lookup joins on. The fee is one multiplication, gasUsed times effectiveGasPrice: 299,196 × 329,342,372 wei = 98,537,920,332,912 wei, about 0.0000985 ETH. Nothing else needs a node call.
Because the query is pinned to block 25,400,576, it returns exactly this row on every run: run it twice and diff the output, byte-identical. An extraction is a command an auditor can re-execute, not a snapshot they have to trust.
Across blocks 25,400,570 to 25,400,590, the trace stream carries 9,634 value-bearing calls, and 6 of them failed with execution reverted, the largest attempting to move exactly 2.73 ETH. A reverted call's value stayed where it was: book only rows where error is null. The opposite holds for fees: a reverted transaction still pays its gas, so the fee is a real cost even when the transfer is not.
SQD serves amounts, counterparties, timestamps, and fees. Fiat prices, tax lots, and cost-basis math join downstream in your accounting tool, with one exception: the executed price of a DEX trade is itself onchain, in the pool's Swap event. There is no balance-at-block field either; a balance on a date folds from the transfer history up to that date, as shown in the wallet history guide.
Transactions, decoded ERC-20, ERC-721, and ERC-1155 transfers, and internal value moves from traces, all filtered by address in one query shape. A history assembled from all three is what balances fold from; any subset silently under-reports.
A contract paying out ETH does it in an internal call: the value appears in traces, not in the transaction list, and when the recipient is a plain wallet no event log exists at all. Filter traces by callTo and callFrom to capture it, and check the error field: a reverted call carries a value that never moved.
Every block carries a unix timestamp in UTC, the key a fiat price lookup joins on. Every transaction carries gasUsed, effectiveGasPrice, and status, so the exact fee is one multiplication. Fiat prices and tax-lot logic are not served; those join downstream in your accounting engine.
A query pinned to a finalized block range returns the same rows on every run, so an extraction is a command an auditor can re-execute, not a snapshot they have to trust. Full history from genesis streams through the same query shape as chain head.
The transactions, transfers, and internal calls are all onchain; the work is in reading the ones a transaction list leaves out.
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.
What an internal transaction is, why event logs and the transaction list miss it, what a trace record contains, and why traces are one of the most expensive things to pull from an RPC node.
Address-keyed access to transaction history, balances, and token holdings. What wallets, accounting tools, and tax software need.
Swaps, liquidations, and the internal calls a log-only feed misses.
Decoded events and traces streamed into the warehouse you already run.
Pre-decoded onchain data for agents, over MCP or plain HTTP.
Address-keyed history: transfers, native and internal value, NFT moves.
Traces and state diffs, the execution footprint logs alone never show.
Private Portal. Dedicated. Validated. Managed. Tell us what you're building, we'll show you what it looks like on SQD.