A social protocol splits at the chain boundary: identity and trades settle onchain, casts and DMs do not. Farcaster registers accounts and signer keys on OP Mainnet, Lens wrote follows and posts to Polygon, friend.tech settled every share trade on Base, and SQD serves those events decoded from one endpoint across 225+ networks. What lives in offchain hubs is out of scope, and the page says which half is which.
Identity and trades settle onchain; casts, follows, and reactions live in offchain hubs, so an indexer serves exactly one slice of a social app and it is worth being precise about which. That slice is small but it is the protocol's root of trust: Farcaster registers accounts and signer keys through three OP Mainnet contracts, Lens wrote its follow and post graph to Polygon, and friend.tech settled every creator-share trade on Base. Reading it the naive way is harder than it looks, because sign-ups route through a bundler so a transaction filter on the registry returns nothing, and a trade contract that indexes only its own signature forces full eth_getLogs pagination against per-call caps. The events are all public; the cost is in how you read them.
Farcaster's architecture is explicitly hybrid: identity settles onchain, content lives in offchain hubs. The onchain half is three contracts on OP Mainnet: the IdRegistry assigns account ids, the KeyRegistry adds the app keys that let a client publish for an account, and the StorageRegistry rents storage. Casts, follows, and reactions never touch the chain. An indexer that promises Farcaster data from the chain serves exactly this slice, and it is worth being precise about which slice that is.
The slice is small, but it is the protocol's root of trust, and it reconciles exactly. Over one 24-hour window (OP Mainnet blocks 153,960,000 to 154,003,199, 2026-07-08 13:52 to 2026-07-09 13:52 UTC) the IdRegistry emitted 163 Register events carrying ids 3,341,237 through 3,341,399: 163 consecutive ids, no gaps. Ids are assigned sequentially by this one contract, so the event stream is the complete account-creation record, not a sample of it.
Where a protocol does write the graph onchain, the same query shape reads it. Lens Protocol recorded follows and posts as Polygon events: in blocks 40,000,000 to 40,010,000 (about six hours of 2023-03-05) the LensHub contract 0xDb46…5a1d emitted 10,277 Followed and 3,006 PostCreated logs, still queryable at that pinned range from the polygon-mainnet dataset.
One registration, pinned to the block it landed in:
The row it returns:
topics[2] is the new account id: 0x32fbb5 is fid 3,341,237, registered to the address in topics[1] with its recovery address in data. The gotcha sits in the transaction underneath: its to is the Bundler (0x00000000fc04…b0aa, which registers the id, adds a key, and rents storage in one call), not the IdRegistry. A transaction filter on the registry address returns nothing; you filter logs by the emitting contract. The same transaction also emits the KeyRegistry Add event carrying the account's new app key.
friend.tech priced creator shares on a bonding curve on Base, and every buy and sell is one Trade event from a single contract, 0xCF20…A4d4. The app's activity collapsed after 2023; the contract record did not. Two same-width windows, 43,200 blocks (24 hours) each, tell it directly:
Reading it needs nothing from the app. The pinned query returns the same three trades in block 4,000,000 today as when they settled in September 2023:
The 512-hex-character data blob is the whole trade. Decoded against the Trade ABI, word by word:
The first of the three logs it returns, from transaction 0xee09…7d7c:
The data value is shown elided at its middle. In full it is 512 hex characters (514 with the 0x prefix), the eight 32-byte ABI words the decoded table lists; the curl above returns it complete.
This is also why the tape is awkward to pull anywhere else: the Trade event indexes nothing but its own signature (one topic), so no node-side filter can narrow it by trader or subject. Over eth_getLogs that means paginating the full event stream through per-call block-range and result caps against an archive node, for a contract that emitted 147,587 events in a single day (the eth_getLogs limits guide measures those caps on live RPCs). From the Portal it is one streamed range request: NDJSON from the contract's first block to the block you pin, decode downstream, filter in your own store.
Farcaster identity is three contracts on OP Mainnet: the IdRegistry assigns account ids, the KeyRegistry adds signer keys, the StorageRegistry rents storage. Sign-ups route through the Bundler contract, so you filter logs by the emitting registry; a transaction-level filter on the registry address returns nothing.
Lens wrote follows and posts to Polygon as LensHub events; friend.tech priced creator shares as Trade events on Base. Both read as decoded logs through the same query shape as any EVM contract, pinned to the per-chain contract address.
Every event a social contract ever emitted stays queryable from genesis, with no dependency on the app or its API. A pinned block range returns the same rows today as the day they settled, which is how a wound-down app stays auditable.
Casts, DMs, and post bodies never touch the chain: Farcaster keeps them in its hub network, and a Lens PostCreated event carries a contentURI pointer, not the content. SQD serves logs, transactions, traces, and state diffs; what a protocol does not emit onchain is out of scope by design.
Every event is public, but a social contract emits only its own signature, often on a chain of its own, so the entire cost is in the reading.
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.
Transfers, mint and burn, and peg signals read from DEX trades.
Issuance, transfers, and the issuer control events a token API omits.
Pool discovery from factory events, and every trade the pools emit.
Item ownership, game currencies, and marketplace settlement onchain.
Deployments as CREATE traces, LP creation, and the first trades.
Private Portal. Dedicated. Validated. Managed. Tell us what you're building, we'll show you what it looks like on SQD.