Skip to content

Chainlink Price Feed Reader

Paste a Chainlink aggregator address. Get the latest answer, decimals, and description decoded to a human-readable price in one read.

EthereumBaseBNB Smart Chainno signup · no wallet connect · free

The one query that powered this

cel.bind(d, feed.decimals(), {
  "description": feed.description(),
  "answer":      string(formatUnits(feed.latestAnswer(), d)),
  "decimals":    string(formatUnits(d, 0))
})

One expression. Auto-resolved ABI, EIP-1967 unwound, Multicall3 batched. Run this in your own code →

What this tool does

The Chainlink Price Feed Reader reads any Chainlink aggregator contract and returns the feed description, the latest answer scaled to a human-readable price, and the raw decimals value from one expression. It is built for developers and analysts who need a current price without shipping the Chainlink ABI or hand-rolling the formatUnits math.

How to use it

  1. Paste the Chainlink aggregator address into the form above.
  2. Pick the chain the aggregator is deployed to.
  3. Run the query and read the pair description, latest answer, and decimals in the result panel.

The result panel shows the pair description (for example “ETH / USD”), the latest price formatted with the aggregator’s own decimals, and the raw decimals value for reference.

What is happening under the hood

Every Chainlink aggregator exposes description(), latestAnswer(), and decimals(). They are independent reads, so a naive client makes three sequential eth_call round trips. evmquery batches them into one Multicall3 call and decodes the typed results in a single response.

cel.bind(d, feed.decimals(), {
  "description": feed.description(),
  "answer":      string(formatUnits(feed.latestAnswer(), d)),
  "decimals":    string(formatUnits(d, 0))
})
  • cel.bind(d, feed.decimals(), …) reads decimals() once and reuses it. We need it twice: once to display, once to scale latestAnswer() into a human-readable price.
  • description() returns the pair label directly, such as “ETH / USD”.
  • formatUnits(feed.latestAnswer(), d) divides the raw integer answer by 10 ** decimals server-side, so a raw answer of 350012000000 at 8 decimals returns as "3500.12" ready for display.
  • All three results are returned as strings so they fit in the same map. CEL maps require their values to share a type, and string(formatUnits(…)) is the conversion path that works for both the small decimals int and the large answer value.
  • Multiple reads are auto-batched by Multicall3, so the cost is one round trip regardless of how many fields you ask for.

Build this yourself

Each of the snippets below makes the same POST call to the evmquery REST API. The expression is the one shown above with your aggregator address filled in. The example targets the ETH / USD feed on Ethereum.

REST (curl)

curl -X POST https://api.evmquery.com/api/v1/query \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chain": "evm_ethereum",
    "schema": {
      "contracts": { "feed": { "address": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419" } }
    },
    "expression": "cel.bind(d, feed.decimals(), { \"description\": feed.description(), \"answer\": string(formatUnits(feed.latestAnswer(), d)), \"decimals\": string(formatUnits(d, 0)) })"
  }'

Python

import requests

resp = requests.post(
    "https://api.evmquery.com/api/v1/query",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "chain": "evm_ethereum",
        "schema": {
            "contracts": {"feed": {"address": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"}},
        },
        "expression": (
            "cel.bind(d, feed.decimals(), {"
            ' "description": feed.description(),'
            ' "answer": string(formatUnits(feed.latestAnswer(), d)),'
            ' "decimals": string(formatUnits(d, 0))'
            " })"
        ),
    },
    timeout=10,
)
print(resp.json()["result"])

TypeScript

const resp = await fetch("https://api.evmquery.com/api/v1/query", {
	method: "POST",
	headers: {
		Authorization: `Bearer ${process.env.EVMQUERY_API_KEY}`,
		"Content-Type": "application/json",
	},
	body: JSON.stringify({
		chain: "evm_ethereum",
		schema: {
			contracts: { feed: { address: "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419" } },
		},
		expression:
			'cel.bind(d, feed.decimals(), { "description": feed.description(), "answer": string(formatUnits(feed.latestAnswer(), d)), "decimals": string(formatUnits(d, 0)) })',
	}),
});
const { result } = await resp.json();

The free tier has no monthly cap. Get a free API key to drop these snippets into your project.

Example aggregators

  • ETH / USD (Ethereum)0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
  • ETH / USD (Base)0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70

Swap the address and chain in any of the snippets above to read a different pair or a different chain.

When you would use this

  • Pricing on-chain positions. Pull a live reference price into a treasury dashboard, a liquidation monitor, or a portfolio tracker without running your own oracle client.
  • Sanity-checking a price before a trade. Confirm what an aggregator is currently reporting before you rely on it in a script or a bot.
  • Backtesting and analytics. Read the current answer and decimals to validate assumptions before wiring up historical latestRoundData() queries.
  • Writing developer docs. Show readers a working Chainlink read example without making them set up a node, an ABI file, or a wallet connection.

FAQ

A Chainlink price feed is an on-chain aggregator contract that a network of independent node operators updates with the current market price for an asset pair, such as ETH / USD. Any contract or off-chain client can read the latest value directly from the aggregator without trusting a single source.

What is an aggregator contract?

The aggregator is the specific contract address you query. Each pair, such as ETH / USD or BTC / USD, has its own aggregator per chain. Chainlink also publishes proxy addresses that forward to the current aggregator, so the address you paste can be either and the read still resolves correctly.

What is the difference between latestAnswer and latestRoundData?

latestAnswer() returns just the current price as a raw integer. latestRoundData() returns the same price alongside the round ID and timestamps for staleness checks. This tool reads latestAnswer() because it is the simplest path to a price; if you need staleness data, adjust the expression to call latestRoundData() instead.

How does the decimals scaling work?

Chainlink aggregators store the price as an integer scaled by decimals(), commonly 8 for USD pairs and 18 for ETH pairs. The expression reads decimals() once, reuses it to scale latestAnswer() with formatUnits, and returns both the human-readable price and the raw decimals value so you can verify the scaling yourself.

Where do I find aggregator addresses?

Chainlink publishes the full list of feed and proxy addresses per chain at data.chain.link. Search for the pair you need, copy the proxy or aggregator address for your target chain, and paste it into the form above.

Which chains are supported?

The reader currently runs against Ethereum, Base, and BNB Smart Chain. Additional EVM chains are being added on the evmquery backend. If you need a specific chain prioritized, contact support.

Can I use this tool from my own application?

Yes. The same expression and aggregator address work against the public REST API. The free tier has no monthly cap, and a single read counts as one call because Multicall3 batches all the underlying calls into one round trip. Bring your own API key and the rate limit applied to this page no longer applies.

Limits and accuracy

  • The result reflects the latest answer reported on-chain at the time of the read. There is no historical replay; use latestRoundData() with a specific round ID for that.
  • Chainlink feeds update based on deviation thresholds and heartbeat intervals, not every block. A “latest” answer can be minutes old depending on the feed’s configuration.
  • The demo is rate limited per browser. If you hit the limit, grab a free API key and the limit goes away.
  • Always verify the aggregator address against data.chain.link before relying on a feed in production code.

Run this query in your own code

No monthly cap on the free tier. No credit card needed.