⚠️ Alpha · testnets only. ChainRender is in active alpha and deployed on testnets only — Ethereum Sepolia, the Robinhood Chain Testnet, and the Circle Arc Testnet — not on any mainnet. Contracts, addresses, and APIs may change. Do not use with real funds or production assets.
Reference

Data Sources & Integrations

ChainRender apps show live on-chain data through resolvers — small view contracts that read chain state at render time. This page covers the built integrations for real protocols. All are fully on-chain and Grade A: a live read is still an on-chain read.

Chainlink price feeds

Two built integrations turn Chainlink feeds into live UI:

Live price value (ChainlinkFeedResolver)

Reads a Chainlink AggregatorV3 feed and renders the current price — honestly. A stale feed is never presented as current: the value is marked/badged when the round is old, and a non-positive or non-contract feed fails closed to "unavailable" rather than showing a fabricated price.

Live price-history chart (ChainlinkChartSource)

An IChartData source that turns a Chainlink feed into a live, reactive on-chain chart series. Each render reads current chain state (latestRoundData() + recent rounds), so the chart genuinely updates as new rounds are written on-chain — a Chainlink heartbeat or deviation update moves the chart. Bind it to a chart component:

// a chart bound to a Chainlink feed's on-chain price history
compose.slot("chart", { resolver: chainlinkChartSource, arg: encodedFeedArg });

This is the honest kind of "live chart": no off-chain data provider, no CDN — the series is the on-chain feed's round history, read at render time.

Uniswap V3 prices (UniswapV3PriceResolver)

Reads a Uniswap V3 pool to render a live spot/TWAP-derived price on-chain — an alternative price source to an oracle feed, straight from the AMM.

Aave (AaveReserveResolver)

Reads an Aave lending-pool reserve to render live DeFi state (rates, reserve data) — protocol state as on-chain UI.

Token balances & metadata

  • Erc20BalanceResolver — a live ERC-20 balance for an address, formatted with the token's own decimals.
  • Erc721MetadataResolver / NftImageResolver — on-chain NFT metadata + media (reference-and-resolve).

ENS

  • EnsProfileResolver — live ENS identity as UI (name, avatar, records), reverse-resolution with forward-verification (a reverse name whose forward record points elsewhere is refused — no spoofed identities).
  • EnsRecordResolver / EnsV2Resolver — ENS text/records and the ENS-v2 (CCIP / offchain-lookup) path.

Attestations (EAS)

  • AttestationAdapter — reads Ethereum Attestation Service (EAS) attestations, so an app can render "this subject holds attestation X from attester Y" — the on-chain trust/identity signal, rendered honestly and fail-closed on a missing/invalid attestation.

Generic reads (build your own)

For anything not covered by a named integration:

  • CallResolver — a single view call → a rendered value.
  • MultiCallResolver — several reads combined (join/sum/reduce).
  • ComputeResolver — a derived value from a small on-chain computation.

Or write a custom resolver — it's a tiny view contract.

The client read path (how reads are fetched)

The resolvers above define what is read and when (render time). The runtime client hardens how those reads reach an RPC — all transparent, and none of it changes what a resolver returns (the on-chain floor is unchanged):

  • Multicall batching (aggregate3). Many reads in a render collapse into a single eth_call to a chain's Multicall3 via aggregate3, so a data-heavy app is one round-trip instead of dozens. Per-call failures come back individually, so one reverting read still fails closed on its own without sinking the batch.
  • Block-pinning. A batch is pinned to one block number, so every value in a render is a consistent snapshot of the same block — no tearing between reads taken microseconds apart.
  • Caching with honest freshness. Results are cached in-memory with a TTL that is clamped to the source's maxStaleSeconds — a value can never be served staler than the resolver itself would allow. Reads a caller marks immutable can opt into a persistent (IndexedDB) cache; everything else stays per-session.
  • RPC failover + bounded retry. Each request has a timeout and a bounded retry, and the client fails over across a chain's configured RPCs, so a single flaky endpoint doesn't blank the UI.

None of this is a trust concession: the grade, the fail-closed behaviour, and the escaping below all still hold — these mechanisms only make the same on-chain reads faster and more resilient.

The common guarantee

Every integration is a view read → Grade A (an on-chain read never lowers the grade), fail-closed (a reverting/stale/missing source shows an honest fallback, never a fabricated value), and escaped (a source can never inject markup). Live data, fully on-chain.

Related