# https://docs.chain.link/data-feeds llms-full.txt On this page # [Chainlink Data Feeds](https://docs.chain.link/data-feeds\#overview) Chainlink Data Feeds are the quickest way to connect your smart contracts to real-world data such as asset prices, reserve balances, and L2 sequencer health. If you already started a project and need to integrate Chainlink, you can [add Chainlink to your existing project](https://docs.chain.link/resources/create-a-chainlinked-project?parent=dataFeeds#installing-into-existing-projects) with the [`@chainlink/contracts` NPM package](https://www.npmjs.com/package/@chainlink/contracts). ## [Types of data feeds](https://docs.chain.link/data-feeds\#types-of-data-feeds) Data feeds provide many different types of data for your applications. - [Price Feeds](https://docs.chain.link/data-feeds#price-feeds) - [SmartData Feeds](https://docs.chain.link/data-feeds#smartdata-feeds) - [Rate and Volatility Feeds](https://docs.chain.link/data-feeds#rate-and-volatility-feeds) - [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds#l2-sequencer-uptime-feeds) ### [Price Feeds](https://docs.chain.link/data-feeds\#price-feeds) Smart contracts often act in real-time on data such as prices of assets. This is especially true in [DeFi](https://chain.link/use-cases/defi). For example, lending and borrowing platforms like [Aave](https://aave.com/) utilize Data Feeds to assess collateral value accurately, while perpetual platforms such as [GMX](https://gmx.io/) rely on these feeds to validate offchain data and ensure that each deposit or withdrawal executes at the correct market value. Data Feeds aggregate many data sources and publish them onchain using a combination of the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) and [Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds). To learn how to use Price Feeds, see the [Price Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. See the [Data Feeds Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page for a list of available networks and addresses. ### [SmartData Feeds](https://docs.chain.link/data-feeds\#smartdata-feeds) Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. To learn more about SmartData Feeds, see the [SmartData](https://docs.chain.link/data-feeds/smartdata) documentation. See the [SmartData Contract Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page for a list of available networks and addresses. ### [Rate and Volatility Feeds](https://docs.chain.link/data-feeds\#rate-and-volatility-feeds) Several feeds provide interest rate curve data, APY data, and realized asset price volatility. To learn more, see the [Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds) documentation. See the [Rate and Volatility Contract Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page for a list of available networks and addresses. ### [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds\#l2-sequencer-uptime-feeds) L2 sequencer feeds track the last known status of the sequencer on an L2 network at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to these events. To learn how to use L2 sequencer uptime feeds, see the [L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds) documentation. ## [Components of a data feed](https://docs.chain.link/data-feeds\#components-of-a-data-feed) Data Feeds are an example of a decentralized oracle network and include the following components: - **Consumer**: A consumer is an onchain or offchain application that uses Data Feeds. Consumer contracts use the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) to call functions on the proxy contract and retrieve information from the aggregator contract. For a complete list of functions available in the `AggregatorV3Interface`, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#aggregatorv3interface). - **Proxy contract**: Proxy contracts are onchain proxies that point to the aggregator for a particular data feed. Using proxies enables the underlying aggregator to be upgraded without any service interruption to consuming contracts. Proxy contracts can vary from one data feed to another, but the [`EACAggregatorProxy.sol` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/EACAggregatorProxy.sol) on Github is a common example. - **Aggregator contract**: An aggregator is a contract that receives periodic data updates from the oracle network. Aggregators store aggregated data onchain so that consumers can retrieve it and act upon it within the same transaction. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). To learn how to create a consumer contract that uses an existing data feed, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. ## [Reading proxy and aggregator configurations](https://docs.chain.link/data-feeds\#reading-proxy-and-aggregator-configurations) Because the proxy and aggregator contracts are all onchain, you can see the current configuration by reading the variables through an [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html) or using a blockchain explorer for your network. For example, you can see the [BTC/USD proxy configuration](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) on the Ethereum network using Etherscan. If you read the BTC/USD proxy configuration, you can query all of the functions and variables that are publicly accessible for that contract including the `aggregator` address, `latestRoundData()` function, `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. To see descriptions for the proxy contract variables and functions, see the source code for your specific data feed on [Etherscan](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code#L568). The proxy contract points to an aggregator. This allows you to retrieve data through the proxy even if the aggregator is upgraded. If you view the `aggregator` address defined in the proxy configuration, you can see the aggregator and its configuration. For example, see the [BTC/USD aggregator contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code) in Etherscan. This contract includes several variables and functions, including another `latestRoundData()`. To see descriptions for the aggregator variables and functions, see the source code on [GitHub](https://github.com/smartcontractkit/libocr/blob/master/contract/AccessControlledOffchainAggregator.sol) or [Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code#F1#L1). You can call the `latestRoundData()` function directly on the aggregator, but it is a best practice to use the proxy instead so that changes to the aggregator do not affect your application. Similar to the proxy contract, the aggregator contract has a `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. ## [Components of an aggregator](https://docs.chain.link/data-feeds\#components-of-an-aggregator) The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). ## [Updates to proxy and aggregator contracts](https://docs.chain.link/data-feeds\#updates-to-proxy-and-aggregator-contracts) To accommodate the dynamic nature of offchain environments, Chainlink Data Feeds are updated from time to time to add new features and capabilities as well as respond to externalities such as token migrations, protocol rebrands, extreme market events, and upstream issues with data or node operations. These updates include changes to the aggregator configuration or a complete replacement of the aggregator that the proxy uses. If you consume data feeds through the proxy, your applications can continue to operate during these changes. Proxy and aggregator contracts all have an `owner` address that has permission to change variables and functions. For example, if you read the [BTC/USD proxy contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) in Etherscan, you can see the `owner` address. This address is a [multi-signature safe](https://docs.safe.global/getting-started/readme) (multisig) that you can also inspect. If you [view the multisig contract](https://etherscan.io/address/0x21f73D42Eb58Ba49dDB685dc29D3bF5c0f0373CA#readProxyContract) in Etherscan using the _Read as Proxy_ feature, you can see the full details of the multisig including the list of addresses that can sign and the number of signers required for the multisig to approve actions on any contracts that it owns. The multisig-coordinated upgradability of Chainlink Data Feeds involves time-tested processes that balance collusion-resistance with the flexibility required to implement improvements and swiftly react to external conditions. The approach taken to upgradability will continue to evolve over time to meet user requirements. ## [Monitoring data feeds](https://docs.chain.link/data-feeds\#monitoring-data-feeds) When you build applications and protocols that depend on data feeds, include monitoring and safeguards to protect against the negative impact of extreme market events, possible malicious activity on third-party venues or contracts, potential delays, and outages. Create your own monitoring alerts based on deviations in the answers that data feeds provide. This will notify you when potential issues occur so you can respond to them. ### [Check the latest answer against reasonable limits](https://docs.chain.link/data-feeds\#check-the-latest-answer-against-reasonable-limits) The data feed aggregator includes both [`minAnswer` and `maxAnswer` values](https://github.com/smartcontractkit/libocr/blob/9e4afd8896f365b964bdf769ca28f373a3fb0300/contract/AccessControlledOffchainAggregator.sol#L33). On most data feeds, these values are no longer used and they do not stop your application from reading the most recent answer. For monitoring purposes, you must decide what limits are acceptable for your application. Configure your application to detect when the reported answer is close to reaching reasonable minimum and maximum limits so it can alert you to potential market events. Separately, configure your application to detect and respond to extreme price volatility or prices that are outside of your acceptable limits. ### [Check the timestamp of the latest answer](https://docs.chain.link/data-feeds\#check-the-timestamp-of-the-latest-answer) Chainlink Data Feeds do not provide streaming data. Rather, the aggregator updates its `latestAnswer` when the value deviates beyond a specified threshold or when the heartbeat idle time has passed. You can find the heartbeat and deviation values for each data feed at [data.chain.link](https://data.chain.link/) or in the [Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) lists. Your application should track the `latestTimestamp` variable or use the `updatedAt` value from the `latestRoundData()` function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay. When the node detects that the heartbeat is reached, it initiates the latest round. Depending on congestion and network conditions, there may be a slight delay for the latest round to get onchain. During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application. Users should build applications with the understanding that data feeds for wrapped or liquid staking assets might have different heartbeat and deviation thresholds than that of the underlying asset. Heartbeat and deviation thresholds can also differ for the same asset across different blockchains. Combining data from multiple feeds, even those with a common denominator, might result in a margin of error that users must account for in their risk mitigation practices. To learn more about the heartbeat and deviation threshold, read the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## What's next - [\> Follow the Data Feeds Getting Started guide to learn the basics](https://docs.chain.link/data-feeds/getting-started) - [\> Read the API reference for using Data Feeds](https://docs.chain.link/data-feeds/api-reference) - [\> Find Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Find SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Find Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) - [\> Learn how to use Data Feeds on L2 networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083858328&cv=11&fst=1747083858328&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116025~103130495~103130497~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116025~103200001~103233427~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Chainlink%20Data%20Feeds%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=316603261.1747083858&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using Data Feeds on Starknet](https://docs.chain.link/data-feeds/starknet\#overview) Starknet is a permissionless decentralized Zk-rollup operating as an L2 network over Ethereum. Unlike other Ethereum L2 networks, Starknet is not EVM-compatible and uses [Cairo](https://docs.cairo-lang.org/index.html) as its smart contract language. Chainlink Data Feeds are available on Starknet Sepolia as Cairo smart contracts. ### [Offchain examples](https://docs.chain.link/data-feeds/starknet\#offchain-examples) You can read Chainlink Data Feeds offchain without a Starknet account. Complete these steps using only the [Starkli CLI](https://docs.chain.link/data-feeds/starknet#getting-started-starkli-cli) or the [Starknet Foundry](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/read-data) toolkit. ### [Onchain examples](https://docs.chain.link/data-feeds/starknet\#onchain-examples) You can read Chainlink Data Feeds on Starknet Sepolia using an [onchain contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract) that you compile, declare, and deploy using [Starknet Foundry](https://github.com/foundry-rs/starknet-foundry). ### [Devnet examples](https://docs.chain.link/data-feeds/starknet\#devnet-examples) Experiment with Chainlink Data Feeds on Starknet using [Starknet Devnet RS](https://github.com/0xSpaceShard/starknet-devnet-rs), a local Docker-based testnet environment implemented using Rust. The [Starknet Devnet RS guide](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs) provides code examples and scripts that enable you to compile, declare, and deploy your own aggregator and consumer contracts. You can use a set of pre-funded accounts to interact with Chainlink Data Feeds on Starknet without deploying to a live network. ## [Getting Started (Starkli CLI)](https://docs.chain.link/data-feeds/starknet\#getting-started-starkli-cli) [Starkli](https://github.com/xJonathanLEI/starkli) is a Starknet standalone CLI similar to [cairo-lang](https://github.com/starkware-libs/cairo-lang), but it is written in Rust. It enables interaction with a Starknet network without the need for extra tools or dependencies. In this example, you will use the `starkli call` command to read data from a Chainlink Price Feed on Starknet Sepolia. This command requires the proxy aggregator address, the function selector, and an RPC endpoint for Starknet Sepolia. ### [Requirements](https://docs.chain.link/data-feeds/starknet\#requirements) Make sure you have the Starkli CLI installed. You can check your current version by running `starkli --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal. Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash starkli --version 0.2.8 (f59724e) ``` Follow the official [installation guide](https://docs.chain.link/data-feeds/(https://book.starkli.rs/installation)) if necessary. ### [Read data from a Chainlink Price Feed](https://docs.chain.link/data-feeds/starknet\#read-data-from-a-chainlink-price-feed) Use the following command to call the `latest_round_data` function on the ETH / USD Chainlink Price Feed aggregator proxy: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash starkli call \ 0x228128e84cdfc51003505dd5733729e57f7d1f7e54da679474e73db4ecaad44 \ latest_round_data \ --rpc https://starknet-sepolia.public.blastapi.io/rpc/v0_7 ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash [\ "0x000000000000000000000000000000010000000000000000000000000000320c",\ "0x0000000000000000000000000000000000000000000000000000005293770eb1",\ "0x000000000000000000000000000000000000000000000000000000000000d44d",\ "0x000000000000000000000000000000000000000000000000000000006606b8cc",\ "0x000000000000000000000000000000000000000000000000000000006606b8a2"\ ] ``` The example output contains an array with the hex-encoded latest round data for the ETH / USD Chainlink Price Feed on Starknet Sepolia. The array contains the following values: | Value name | Hex-encoded value | Decoded value | Description | | --- | --- | --- | --- | | `round_id` | `0x000000000000000000000000000000010000000000000000000000000000320c` | `340282366920938463463374607431768224268` | The unique identifier of the data round | | `answer` | `0x0000000000000000000000000000000000000000000000000000005293770eb1` | `354661371569` | The actual data provided by the data feed, representing the latest price of an asset in the case of a price feed | | `block_num` | `0x000000000000000000000000000000000000000000000000000000000000d44d` | `54349` | The block number at which the data was recorded on the blockchain | | `started_at` | `0x000000000000000000000000000000000000000000000000000000006606b8cc` | `1711716556` | The Unix timestamp indicating when the data round started | | `updated_at` | `0x000000000000000000000000000000000000000000000000000000006606b8a2` | `1711716514` | The Unix timestamp indicating when the data was last updated | For a complete list of Chainlink Price Feeds available on Starknet, see the [Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) page. Note: This example uses a [Blast API](https://blastapi.io/public-api/starknet) RPC endpoint. You can interact with the network using any other Starknet Sepolia RPC provider, such as [Alchemy](https://www.alchemy.com/starknet) or [Infura](https://www.infura.io/networks/ethereum/starknet). ## What's next - [\> Starknet Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) - [\> Deploy and interact with a Consumer Contract using Starknet Foundry](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink SmartData Overview [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [SmartData](https://docs.chain.link/data-feeds/smartdata\#overview) Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. You can read these feeds the same way that you read other Data Feeds. Specify the [SmartData feed address](https://docs.chain.link/data-feeds/smartdata/addresses) that you want to read instead of specifying a price feed address. See the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) page to learn more. ## [SmartData Product Types](https://docs.chain.link/data-feeds/smartdata\#smartdata-product-types) - [Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata#proof-of-reserve-feeds) - [NAVLink Feeds](https://docs.chain.link/data-feeds/smartdata#navlink-feeds) - [SmartAUM Feeds](https://docs.chain.link/data-feeds/smartdata#smartaum-feeds) ### [Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata\#proof-of-reserve-feeds) Proof of Reserves feeds provide the status of reserves for stablecoins, wrapped assets, and real world assets. Proof of Reserve Feeds operate similarly to Price Feeds, but provide answers in units of measurement such as ounces (oz) or number of tokens. To find a list of available Proof of Reserve Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. #### [Types of Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata\#types-of-proof-of-reserve-feeds) Reserves are available for both offchain assets and cross-chain assets. This categorization describes the data reporting variations of Proof of Reserve feeds and helps highlight some of the inherent market risks surrounding the data quality of these feeds. ##### [Offchain reserves](https://docs.chain.link/data-feeds/smartdata\#offchain-reserves) Offchain reserves are sourced from APIs through an [external adapter](https://docs.chain.link/chainlink-nodes/external-adapters/external-adapters). ![](https://docs.chain.link/images/data-feed/off-chain-reserves.webp) Offchain reserves provide their data using the following methods: - Third-party: An auditor, accounting firm, or other third party audits and verifies reserves. This is done by combining both fiat and investment assets into a numeric value that is reported against the token. - Custodian: Reserves data are pulled directly from the bank or custodian. The custodian has direct access to the bank or vault holding the assets. Generally, this works when the underlying asset pulled requires no additional valuation and is simply reported onchain. - ⚠️ Self-reported: Reserve data is read from an API that the token issuer hosts. Reserve data reported by an asset issuer's self-hosted API carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ##### [Cross-chain reserves](https://docs.chain.link/data-feeds/smartdata\#cross-chain-reserves) Cross-chain reserves are sourced from the network where the reserves are held. Chainlink node operators can report cross-chain reserves by running an [external adapter](https://docs.chain.link/chainlink-nodes/external-adapters/external-adapters) and querying the source-chain client directly. In some instances, the reserves are composed of a dynamic list of IDs or addresses using a composite adapter. ![](https://docs.chain.link/images/data-feed/cross-chain-reserves.webp) Cross-chain reserves provide their data using the following methods: - Wallet address manager: The project uses the [IPoRAddressList](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/interfaces/PoRAddressList.sol) wallet address manager contract and self-reports which addresses they own. Reserve data reported by an asset issuer's self-reported addresses carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. - Wallet address: The project reports which addresses they own through a self-hosted API. Reserve data reported by an asset issuer's self-reported addresses carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ### [NAVLink Feeds](https://docs.chain.link/data-feeds/smartdata\#navlink-feeds) Chainlink NAVLink Feeds provide real-time, tamper-proof data on the Net Asset Value (NAV) of tokenized assets, funds, or portfolios. NAV is an essential metric in the financial industry for assessing the value of mutual funds, ETFs, and other investment vehicles. It is calculated by subtracting total liabilities from the total assets held within the vehicle. By making NAV data available onchain, developers can build decentralized applications that require accurate and up-to-date valuation metrics. These applications include asset management platforms, DeFi protocols, and investment strategies that rely on NAV for operations such as rebalancing, minting, or redemption. To find a list of available SmartNav Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. ### [SmartAUM Feeds](https://docs.chain.link/data-feeds/smartdata\#smartaum-feeds) Chainlink SmartAUM Feeds provide current data on the total market value of assets managed by an entity on behalf of clients. Assets Under Management (AUM) is a crucial indicator used in financial analyses and decision-making processes. By bringing AUM data onchain, decentralized applications can access information for activities such as risk assessment, performance benchmarking, and investment strategy development. To find a list of available Assets Under Management Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. ## [Using SmartData](https://docs.chain.link/data-feeds/smartdata\#using-smartdata) Read answers from SmartData feeds the same way that you read other Data Feeds. Specify the [SmartData feed address](https://docs.chain.link/data-feeds/smartdata/addresses) that you want to read instead of specifying a Price feed address. See the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) page to learn more. Using Solidity, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds. Example for reading a Proof of Reserve feed: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; contract ReserveConsumerV3 { AggregatorV3Interface internal reserveFeed; /** * Network: Ethereum Mainnet * Aggregator: WBTC PoR * Address: 0xa81FE04086865e63E12dD3776978E49DEEa2ea4e */ constructor() { reserveFeed = AggregatorV3Interface( 0xa81FE04086865e63E12dD3776978E49DEEa2ea4e ); } /** * Returns the latest price */ function getLatestReserve() public view returns (int) { // prettier-ignore ( /*uint80 roundID*/, int reserve, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = reserveFeed.latestRoundData(); return reserve; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/ReserveConsumerV3.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## What's next - [\> Learn how to read answers from Data Feeds](https://docs.chain.link/data-feeds/price-feeds) - [\> Learn how to get Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Find contract addresses for SmartData feeds](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083855179&cv=11&fst=1747083855179&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za200zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116026~103130498~103130500~103200004~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fsmartdata&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=SmartData%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1786633000.1747083855&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&ec_mode=a&fledge=1&capi=1&_tu=Cg&em=tv.1&ct_cookie_present=0) ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Data Feeds on Solana](https://docs.chain.link/data-feeds/solana\#overview) Chainlink provides data feeds on the [Solana](https://solana.com/) network. Chainlink data feeds on Solana employ [Offchain Reporting (OCR)](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds) to aggregate data from data providers who pull from both centralized and decentralized exchanges. Chainlink’s Solana deployment has no dependencies on external blockchain networks such as Ethereum. In Solana, storage and smart contract logic are separate. Programs store all the logic similar to an EVM (Ethereum) smart contract. The accounts store all the data. Compared to Solidity, the combination of an account and a program is equivalent to a smart contract on an EVM chain. State and logic are separate in Solana. Solana programs are stateless, so you don't always need to deploy your program to the network to test it. You can deploy and test your programs on a [Solana Test Validator](https://docs.solana.com/developing/test-validator). However, to use Chainlink products on Solana, you must deploy your contract onchain to one of the [supported Solana clusters](https://docs.chain.link/data-feeds/solana#chainlink-products-and-solana-clusters). To learn how to mitigate risk to your applications, read the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) page. ## [Chainlink products and Solana clusters](https://docs.chain.link/data-feeds/solana\#chainlink-products-and-solana-clusters) [Price Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) are available on the following Solana clusters: - [Solana Mainnet](https://solscan.io/) - [Solana Devnet](https://solscan.io/?cluster=devnet) Solana provides a [Testnet cluster](https://docs.solana.com/clusters#testnet) that runs newer [Solana releases](https://github.com/solana-labs/solana/releases), but Chainlink Data Feeds are not available on this cluster. See the [Solana Data Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) page for a full list of Chainlink data feeds that are available on Solana. To learn when more Chainlink services become available, follow us on [Twitter](https://twitter.com/chainlink) or sign up for our [mailing list](https://docs.chain.link/resources/developer-communications?parent=dataFeeds). ## [Languages, tools, and frameworks](https://docs.chain.link/data-feeds/solana\#languages-tools-and-frameworks) The examples in the Chainlink documentation use the following languages, tools, and frameworks: - [Node.js 14 or higher](https://nodejs.org/en/download/): Used to run client code - [Rust](https://www.rust-lang.org/): A general-purpose programming language designed for performance and memory safety - [Anchor](https://www.anchor-lang.com/): A [Solana Sealevel Framework](https://github.com/coral-xyz/anchor) that provides several developer tools - [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit): An Anchor based program and client that shows developers how to use and interact with Chainlink Data Feeds on Solana - [Solana CLI](https://docs.solana.com/cli): The Solana command line interface - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git): Used to clone the example code repository When developing applications to use Chainlink products on Solana, always use a [Mainnet release](https://github.com/solana-labs/solana/releases) version of the Solana CLI that is equal to or greater than the version currently running on your target cluster. Use `solana --version` and `solana cluster-version` to check CLI and cluster versions: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana --version solana-cli 1.9.28 (src:b576e9cc; feat:320703611) solana cluster-version --url devnet 1.9.25 solana cluster-version --url mainnet-beta 1.9.28 ``` The examples in this documentation use Solana programs in [Rust](https://solana.com/docs/programs/rust). To learn more about the Solana programming model, see the [Solana Documentation](https://solana.com/docs/core). ## [Solana wallets](https://docs.chain.link/data-feeds/solana\#solana-wallets) When you use Chainlink on Solana, you need a [Solana wallet](https://docs.solana.com/wallet-guide/). The Chainlink documentation uses [file system wallets](https://docs.solana.com/wallet-guide/file-system-wallet) and free Devnet SOL tokens to demonstrate examples. When you deploy your programs to the Solana Mainnet, you must use wallets with mainnet lamports. If you have existing wallets that you want to use for the guides in the Chainlink documentation, find your wallet keypair and make it available in your development environment as a file. You can point [Anchor](https://www.anchor-lang.com/) and the [Solana CLI](https://docs.solana.com/cli) to a specific keypair when you deploy or manage your Solana programs. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell anchor build ⋮ anchor deploy --provider.wallet ~/.config/solana/id.json --provider.cluster devnet ⋮ solana program show --programs --keypair ~/.config/solana/id.json --url devnet Program Id | Slot | Authority | Balance 6U4suTp55kiJRKqV7HGAQvFgcLaStLnUA4myg5DRqsKw | 109609728 | E6gKKToCJPgf4zEL1GRLL6T99g2WcfAzJAMvtma1KijT | 2.57751768 SOL ``` When you build your production applications and deploy Solana programs to the Mainnet cluster, always follow the security best practices in the [Solana Wallet Guide](https://docs.solana.com/wallet-guide) for managing your wallets and keypairs. ## What's next - [\> Use data feeds offchain](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain) - [\> Use data feeds onchain](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana) - [\> See the available data feeds on Solana](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds Aptos [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using Data Feeds on Aptos](https://docs.chain.link/data-feeds/aptos\#overview) Aptos is a Layer 1 blockchain that uses the [Move](https://move-language.github.io/move/) programming language for smart contracts. Chainlink Data Feeds on Aptos provides data through a single price feed contract that handles multiple data feeds. You interact with this contract by passing the specific feed ID(s) for the data you need. This contrasts with Chainlink's integration on other blockchains, where each price feed has a separate contract address. ## [Getting Started (CLI)](https://docs.chain.link/data-feeds/aptos\#getting-started-cli) This guide explains how to use Chainlink Data Feeds with your Move smart contracts on Aptos testnet using the `Benchmark` structure provided by the data feeds contract. You will use the [Aptos CLI](https://aptos.dev/en/build/cli) to compile, publish, and interact with your contract. ### [Requirements](https://docs.chain.link/data-feeds/aptos\#requirements) Make sure you have the [Aptos CLI](https://aptos.dev/en/build/cli) installed. You can run `aptos help`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal to verify if the CLI is correctly installed. ### [Integrate Chainlink Data Feeds on Aptos](https://docs.chain.link/data-feeds/aptos\#integrate-chainlink-data-feeds-on-aptos) Create a new directory for your project and navigate to it in your terminal: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash mkdir aptos-data-feeds && cd aptos-data-feeds ``` #### [Set up your Aptos testnet account](https://docs.chain.link/data-feeds/aptos\#set-up-your-aptos-testnet-account) 1. Run the following command in your terminal to create a new account on testnet: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos init --network=testnet --assume-yes ``` 2. You are prompted to enter a private key: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Configuring for profile default Configuring for network Testnet Enter your private key as a hex literal (0x...) [Current: Redacted | No input: Generate new key (or keep one if present)] ``` Press `Enter` to generate a new key pair with the [`ed25519` key scheme](https://aptos.dev/en/network/blockchain/accounts#authentication-key). Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash No key given, generating key... Account 0x35107a273065fc0f428b2db719145682f6b5bf16a32b071ccd649fcd8b1a44e9 doesn't exist, creating it and funding it with 100000000 Octas Account 0x35107a273065fc0f428b2db719145682f6b5bf16a32b071ccd649fcd8b1a44e9 funded successfully --- Aptos CLI is now set up for account 0x35107a273065fc0f428b2db719145682f6b5bf16a32b071ccd649fcd8b1a44e9 as profile default! See the account here: https://explorer.aptoslabs.com/account/0x35107a273065fc0f428b2db719145682f6b5bf16a32b071ccd649fcd8b1a44e9?network=testnet Run `aptos --help` for more information about commands { "Result": "Success" } ``` You now have a funded testnet account on Aptos. #### [Set up your project](https://docs.chain.link/data-feeds/aptos\#set-up-your-project) 1. Initialize a Move package in your `aptos-data-feeds` directory: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos move init --name aptos-data-feeds ``` Expect the following output: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash { "Result": "Success" } ``` You should now have a Move project with the following structure: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```plaintext Move.toml ├── /.aptos ├── /scripts ├── /sources └── /tests ``` 2. Update your `Move.toml` file to include the required dependencies and addresses: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```toml [package] name = "my-app" version = "1.0.0" authors = [] [addresses] sender = "" owner = "" data_feeds = "0xf1099f135ddddad1c065203431be328a408b0ca452ada70374ce26bd2b32fdd3" platform = "0x516e771e1b4a903afe74c27d057c65849ecc1383782f6642d7ff21425f4f9c99" move_stdlib = "0x1" aptos_std = "0x1" [dev-addresses] [dependencies] AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework", rev = "main" } MoveStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/move-stdlib", rev = "main" } ChainlinkDataFeeds = { local = "./ChainlinkDataFeeds" } ``` Where: - `` is your Aptos testnet account address. You can find your address in the `~/.aptos/config.yaml` file. Alternatively, run the following command in your terminal to retrieve it: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos config show-profiles --profile=default ``` - The `data_feeds` address is the Chainlink Data Feeds contract address on Aptos testnet ( `0xf1099f135ddddad1c065203431be328a408b0ca452ada70374ce26bd2b32fdd3`). 3. Run the following command to download the compiled bytecode for the `ChainlinkPlatform` and `ChainlinkDataFeeds` packages: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos move download --account 0x516e771e1b4a903afe74c27d057c65849ecc1383782f6642d7ff21425f4f9c99 --package ChainlinkPlatform && \ aptos move download --account 0xccad6853cabea164842907df3de4f89bb34be5bf249bbf16939f9c90db1bf63b --package ChainlinkDataFeeds ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Saved package with 2 module(s) to `~/aptos-data-feeds/ChainlinkPlatform` { "Result": "Download succeeded" } Saved package with 2 module(s) to `~/aptos-data-feeds/ChainlinkDataFeeds` { "Result": "Download succeeded" } ``` 4. Open the `ChainlinkDataFeeds` package configuration file ( `ChainlinkDataFeeds/Move.toml`) and update the `ChainlinkPlatform` dependency to point to your local path: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```toml ChainlinkPlatform = { local = "../ChainlinkPlatform" } ``` #### [Write the Move contract to interact with Chainlink Data Feeds](https://docs.chain.link/data-feeds/aptos\#write-the-move-contract-to-interact-with-chainlink-data-feeds) In this step, you will develop a Move module that interacts with Chainlink Data Feeds to fetch the latest price and timestamp for a specified feed ID. This module retrieves benchmark data for the given feed ID, extracts the price and timestamp, and stores this information in the invoking account's global storage. You can then retrieve this data using a view function. 1. Create a new Move module in the `sources` directory of your project: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash touch sources/MyOracleContract.move ``` 2. Insert the following code example and save your `MyOracleContract.move` file: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```rust module sender::MyOracleContractTest { use std::vector; use std::signer; use data_feeds::router::get_benchmarks; use data_feeds::registry::{Benchmark, get_benchmark_value, get_benchmark_timestamp}; use move_stdlib::option::{Option, some, none}; struct PriceData has copy, key, store { /// The price value with 18 decimal places of precision price: u256, /// Unix timestamp in seconds timestamp: u256, } // Function to fetch and store the price data for a given feed ID public entry fun fetch_price(account: &signer, feed_id: vector) acquires PriceData { let feed_ids = vector[feed_id]; // Use the passed feed_id let billing_data = vector[]; let benchmarks: vector = get_benchmarks(account, feed_ids, billing_data); let benchmark = vector::pop_back(&mut benchmarks); let price: u256 = get_benchmark_value(&benchmark); let timestamp: u256 = get_benchmark_timestamp(&benchmark); // Check if PriceData exists and update it if (exists(signer::address_of(account))) { let data = borrow_global_mut(signer::address_of(account)); data.price = price; data.timestamp = timestamp; } else { // If PriceData does not exist, create a new one move_to(account, PriceData { price, timestamp }); } } // View function to get the stored price data #[view] public fun get_price_data(account_address: address): Option acquires PriceData { if (exists(account_address)) { let data = borrow_global(account_address); some(*data) } else { none() } } } ``` #### [Compile and publish the contract](https://docs.chain.link/data-feeds/aptos\#compile-and-publish-the-contract) 1. Compile and publish the contract to the Aptos testnet: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos move publish --skip-fetch-latest-git-deps ``` - You are prompted to confirm the transaction details. Type `yes` and press `Enter` to proceed. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Compiling, may take a little while to download git dependencies... INCLUDING DEPENDENCY AptosFramework INCLUDING DEPENDENCY AptosStdlib INCLUDING DEPENDENCY ChainlinkDataFeeds INCLUDING DEPENDENCY ChainlinkKeystone INCLUDING DEPENDENCY MoveStdlib BUILDING my-app package size 2133 bytes Do you want to submit a transaction for a range of [176700 - 265000] Octas at a gas unit price of 100 Octas? [yes/no] > ``` - Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Transaction submitted: https://explorer.aptoslabs.com/txn/0x22a65eedb37ad7e41e195409c06e23b154c71bba11c73e6f67df6ba41e6768a4?network=testnet { "Result": { "transaction_hash": "0x22a65eedb37ad7e41e195409c06e23b154c71bba11c73e6f67df6ba41e6768a4", "gas_used": 1767, "gas_unit_price": 100, "sender": "4006c4623e114a6169b409cc0ad91b0780e62667633ce2e069b31125cc6a5d37", "sequence_number": 0, "success": true, "timestamp_us": 1731707700843776, "version": 6238520375, "vm_status": "Executed successfully" } } ``` **Notes**: - Your `default` profile within the `~/.aptos/config.yaml` file is used by default. You can specify a different profile using the `--profile` flag. - Ensure you have enough testnet APT tokens in your account to cover the deployment fees. You can fund your account with testnet APT tokens using the following command, where the amount used is in Octas (1 APT = 100,000,000 Octas): ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos account fund-with-faucet --account --amount 100000000 ``` #### [Interact with the deployed contract](https://docs.chain.link/data-feeds/aptos\#interact-with-the-deployed-contract) In this step, you will interact with your deployed contract to fetch the BTC/USD price and timestamp. The BTC/USD feed ID on Aptos testnet is: `0x01a0b4d920000332000000000000000000000000000000000000000000000000`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg). You can find the feed ID for other assets in the [Feed Addresses page](https://docs.chain.link/data-feeds/price-feeds/addresses?network=aptos&page=1). 1. Fetch benchmark data for the BTC/USD feed, extract the price and timestamp, and store this information in your account's global storage. - Run the following command, replacing `` with your actual account address: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos move run \ --function-id '::MyOracleContractTest::fetch_price' \ --args hex:0x01a0b4d920000332000000000000000000000000000000000000000000000000 ``` **Note**: `` is your Aptos testnet account address. You can find your address in the `~/.aptos/config.yaml` file. Alternatively, run the following command in your terminal to retrieve it: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos config show-profiles --profile=default ``` - You are prompted to confirm the transaction details. Type `yes` and press `Enter` to proceed: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Do you want to submit a transaction for a range of [47200 - 70800] Octas at a gas unit price of 100 Octas? [yes/no] > ``` - Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Transaction submitted: https://explorer.aptoslabs.com/txn/0x7180e890ececbcab4f052f84ecae21d37f33a31d0e475f566f92fc6df157c725?network=testnet { "Result": { "transaction_hash": "0x7180e890ececbcab4f052f84ecae21d37f33a31d0e475f566f92fc6df157c725", "gas_used": 472, "gas_unit_price": 100, "sender": "4006c4623e114a6169b409cc0ad91b0780e62667633ce2e069b31125cc6a5d37", "sequence_number": 1, "success": true, "timestamp_us": 1731707764586551, "version": 6238524110, "vm_status": "Executed successfully" } } ``` 2. Retrieve this data using the view function: - Run the following command, replacing `` with your actual account address: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash aptos move view \ --function-id '::MyOracleContractTest::get_price_data' \ --args address: ``` - Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash { "Result": [\ {\ "vec": [\ {\ "price": "70376345325832900000000",\ "timestamp": "1730827175"\ }\ ]\ }\ ] } ``` Where: - `price` is the latest BTC/USD price with 18 decimal places. - `timestamp` is the Unix timestamp in seconds when the price is fetched. ## What's next - [\> Aptos Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=aptos) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083854979&cv=11&fst=1747083854979&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103101750~103101752~103116025~103130495~103130497~103200001~103233427~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116026~103200004~103207802~103233427~103251618~103251620~103263073~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Faptos&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Using%20Data%20Feeds%20on%20Aptos%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=2098808994.1747083855&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Using ENS with Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using ENS with Data Feeds](https://docs.chain.link/data-feeds/ens\#overview) ## [Lookup](https://docs.chain.link/data-feeds/ens\#lookup) Pair:Choose PairAAVE / ETHAAVE / USDADA / USDADX / USDANT / ETHAUD / USDBAL / ETHBAT / ETHBCH / USDBNB / USDBNT / ETH (Bancor)BNT / ETHBNT / USDBRENT / USDBTC / ARSBTC DifficultyBTC / ETHBTC / USDBUSD / ETHBZRX / ETHCHF / USDCOMP / ETHCOMP / USDCRO / ETHCRV / ETHDAI / ETHDAI / USDDASH / USDDMG / ETHDOT / USDENJ / ETHEOS / USDETC / USDETH / USDETH / XDREUR / MWhEUR / USDFast Gas / GweiFIL / USDFNX / USDFTM / ETHFTSE / GBPGBP / USDJPY / USDKNC / ETHKNC / USDLEND / ETHLEND / USDLINK / ETH (Bancor)LINK / ETHLINK / USDLRC / ETHLTC / USDMANA / ETHMKR / ETHMLN / ETHN225 / JPYNMR / ETHOrchidOXT / USDREN / ETH (Bancor)REN / ETHREN / USDREP / ETHRLC / ETHsCEX / USDsDEFI / USDSNX / ETHSNX / USDSUSD / ETHSXP / USDTotal Marketcap / USDTRX / USDTUSD / ETHTUSD ReservesTUSD SupplyUMA / ETHUNI / ETHUNI / USDUSDC / ETHUSDK / USDUSDT / ETHWNXM / ETHWOM / ETHWTI / USDXAG / USDXAU / USDXHV / USDXMR / USDXRP / USDXTZ / USDYFI / ETHYFI / USDZRX / ETHENS Name:Address:Hash ID: ## [Manual Lookup](https://docs.chain.link/data-feeds/ens\#manual-lookup) / Lookup ENS Name:Address: ## [Naming structure](https://docs.chain.link/data-feeds/ens\#naming-structure) Chainlink data feeds fall under the `data.eth` naming suffix. To obtain a specific feed address, prefix this with the assets in the feed, separated by a dash (-). | Pair | ENS Domain Name | | --- | --- | | ETH / USD | `eth-usd.data.eth` | | BTC / USD | `btc-usd.data.eth` | | ... | `...` | ### [Subdomains](https://docs.chain.link/data-feeds/ens\#subdomains) By default, the base name structure ( `eth-usd.data.eth`) returns the proxy address for that feed. However, subdomains enable callers to retrieve other associated contract addresses, as shown in the following table. | Contract Addresses | Subdomain Prefix | Example | | --- | --- | --- | | Proxy | `proxy` | `proxy.eth-usd.data.eth` | | Underlying aggregator | `aggregator` | `aggregator.eth-usd.data.eth` | | Proposed aggregator | `proposed` | `proposed.eth-usd.data.eth` | ## [Architecture](https://docs.chain.link/data-feeds/ens\#architecture) ### [Resolver](https://docs.chain.link/data-feeds/ens\#resolver) For each network, there is a single Chainlink resolver, which does not change. Its address can be obtained using the `data.eth` domain. This resolver manages the subdomains associated with `data.eth`. | Network | Resolver Address | | --- | --- | | Ethereum Mainnet | [0x122eb74f9d0F1a5ed587F43D120C1c2BbDb9360B](https://app.ens.domains/address/0x122eb74f9d0F1a5ed587F43D120C1c2BbDb9360B) | ### [Listening for address changes](https://docs.chain.link/data-feeds/ens\#listening-for-address-changes) When a new aggregator is deployed for a specific feed, it is first proposed, and when accepted becomes the aggregator for that feed. During this process, the `proposed` and `aggregator` subdomains for that feed will change. With each change, the resolver emits an `AddrChanged` event, using the feed subdomain (for example: `eth-usd.data.eth`) as the indexed parameter. **Example**: If you want to listen for when the aggregator of the ETH / USD feed changes, set up a listener to track the `AddrChanged` event on the resolver, using a filter like this: `ethers.utils.namehash('aggregator.eth-usd.data.eth')`. ## [Obtaining addresses](https://docs.chain.link/data-feeds/ens\#obtaining-addresses) ### [Javascript](https://docs.chain.link/data-feeds/ens\#javascript) The example below uses Javascript Web3 library to interact with ENS. See the [ENS documentation](https://docs.ens.domains/dapp-developer-guide/resolving-names) for the full list of languages and libraries that support ENS. This example logs the address of the data feed on the Ethereum mainnet for ETH / USD prices. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity const Web3 = require("web3") const web3 = new Web3("https://rpc.ankr.com/eth") web3.eth.ens.getAddress("eth-usd.data.eth").then((address) => { console.log(address) }) ``` ### [Solidity](https://docs.chain.link/data-feeds/ens\#solidity) In Solidity, the address of the ENS registry must be known. According to [ENS documentation](https://docs.ens.domains/ens-deployments), this address is the same across Mainnet and testnet: ENS registry address: [0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e). Also, instead of using readable string names like `eth-usd.data.eth`, resolvers accept bytes32 hash IDs for names. Hash IDs can be retrieved from [this subgraph](https://thegraph.com/explorer/subgraphs/5XqPmWe6gjyrJtFn9cLy237i4cWw2j9HcUJEXsP5qGtH) or via this npm package [eth-ens-namehash](https://www.npmjs.com/package/@ensdomains/eth-ens-namehash). "ETH / USD" hash: `0xf599f4cd075a34b92169cf57271da65a7a936c35e3f31e854447fbb3e7eb736d` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ // ENS Registry Contract interface ENS { function resolver(bytes32 node) external view returns (Resolver); } // Chainlink Resolver interface Resolver { function addr(bytes32 node) external view returns (address); } // Consumer contract contract ENSConsumer { ENS ens; // ENS registry address: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e constructor(address ensAddress) { ens = ENS(ensAddress); } // Use ID Hash instead of readable name // ETH / USD hash: 0xf599f4cd075a34b92169cf57271da65a7a936c35e3f31e854447fbb3e7eb736d function resolve(bytes32 node) public view returns (address) { Resolver resolver = ens.resolver(node); return resolver.addr(node); } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/ENSConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## Get the latest Chainlink content straight to your inbox. Email Address ## Data Feeds API [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference\#overview) When you use data feeds, retrieve the feeds through the `AggregatorV3Interface` and the proxy address. Optionally, you can call variables and functions in the `AccessControlledOffchainAggregator` contract to get information about the aggregator behind the proxy. ## [AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference\#aggregatorv3interface) Import this interface to your contract and use it to run functions in the proxy contract. Create the interface object by pointing to the proxy address. For example, on Sepolia you could create the interface object in the constructor of your contract using the following example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * Network: Sepolia * Data Feed: ETH/USD * Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306 */ constructor() { priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306); } ``` To see examples for how to use this interface, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) guide. You can see the code for the [`AggregatorV3Interface` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) on GitHub. ### [Functions in AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference\#functions-in-aggregatorv3interface) | Name | Description | | --- | --- | | [decimals](https://docs.chain.link/data-feeds/api-reference#decimals) | The number of decimals in the response. | | [description](https://docs.chain.link/data-feeds/api-reference#description) | The description of the aggregator that the proxy points to. | | [getRoundData](https://docs.chain.link/data-feeds/api-reference#getrounddata) | Get data from a specific round. | | [latestRoundData](https://docs.chain.link/data-feeds/api-reference#latestrounddata) | Get data from the latest round. | | [version](https://docs.chain.link/data-feeds/api-reference#version) | The version representing the type of aggregator the proxy points to. | #### [decimals](https://docs.chain.link/data-feeds/api-reference\#decimals) Get the number of decimals present in the response value. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function decimals() external view returns (uint8); ``` - `RETURN`: The number of decimals. #### [description](https://docs.chain.link/data-feeds/api-reference\#description) Get the description of the underlying aggregator that the proxy points to. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function description() external view returns (string memory); ``` - `RETURN`: The description of the underlying aggregator. #### [getRoundData](https://docs.chain.link/data-feeds/api-reference\#getrounddata) Get data about a specific round, using the `roundId`. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); ``` **Parameters:** - `_roundId`: The round ID **Return values:** - `roundId`: The round ID - `answer`: The answer for this round - `startedAt`: Timestamp of when the round started - `updatedAt`: Timestamp of when the round was updated - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed #### [latestRoundData](https://docs.chain.link/data-feeds/api-reference\#latestrounddata) Get the data from the latest round. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) ``` **Return values:** - `roundId`: The round ID. - `answer`: The data that this specific feed provides. Depending on the feed you selected, this answer provides asset prices, reserves, and other types of data. - `startedAt`: Timestamp of when the round started. - `updatedAt`: Timestamp of when the round was updated. - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed #### [version](https://docs.chain.link/data-feeds/api-reference\#version) The version representing the type of aggregator the proxy points to. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function version() external view returns (uint256) ``` - `RETURN`: The version number. ## [AccessControlledOffchainAggregator](https://docs.chain.link/data-feeds/api-reference\#accesscontrolledoffchainaggregator) This is the contract for the aggregator. You can call functions on the aggregator directly, but it is a best practice to use the [AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference#aggregatorv3interface) to run functions on the proxy instead so that changes to the aggregator do not affect your application. Read the aggregator contract only if you need functions that are not available in the proxy. The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. ### [Variables and functions in AccessControlledOffchainAggregator](https://docs.chain.link/data-feeds/api-reference\#variables-and-functions-in-accesscontrolledoffchainaggregator) This contract imports `OffchainAggregator` and `SimpleReadAccessController`, which also include their own imports. The variables and functions lists include the publicly accessible items from these imported contracts. A simple way to read the variables or functions is to get the ABI from a blockchain explorer and point the ABI to the aggregator address. To do this in Remix, follow the [Using the ABI with AtAddress](https://remix-ide.readthedocs.io/en/latest/run.html#using-the-abi-with-ataddress) guide in the Remix documentation. As an example, you can find the ABI for the BTC/USD aggregator by viewing the [contract code in Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code). **Variables:** | Name | Description | | --- | --- | | LINK | The address for the LINK token contract on a specific network. | | billingAccessController | The address for the billingAccessController, which limits access to the [billing configuration](https://github.com/smartcontractkit/libocr/blob/master/contract/OffchainAggregatorBilling.sol) for the aggregator. | | checkEnabled | A boolean that indicates if access is limited to addresses on the internal access list. | | maxAnswer | This value is no longer used on most Data Feeds. Evaluate if your use case for Data Feeds requires a custom circuit breaker and implement it to meet the needs of your application. See the [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) page for more information. | | minAnswer | This value is no longer used on most Data Feeds. Evaluate if your use case for Data Feeds requires a custom circuit breaker and implement it to meet the needs of your application. See the [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) page for more information. | | owner | The address that owns this aggregator contract. This controls which address can execute specific functions. | **Functions:** | Name | Description | | --- | --- | | [decimals](https://docs.chain.link/data-feeds/api-reference#decimals-1) | Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format. | | [description](https://docs.chain.link/data-feeds/api-reference#description-1) | Return a description for this data feed. This is different depending on which feed you select. | | [getAnswer](https://docs.chain.link/data-feeds/api-reference#getanswer) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [getBilling](https://docs.chain.link/data-feeds/api-reference#getbilling) | Retrieve the current billing configuration. | | [getRoundData](https://docs.chain.link/data-feeds/api-reference#getrounddata-1) | Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round. | | [getTimestamp](https://docs.chain.link/data-feeds/api-reference#gettimestamp) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [hasAccess](https://docs.chain.link/data-feeds/api-reference#hasaccess) | Check if an address has internal access. | | [latestAnswer](https://docs.chain.link/data-feeds/api-reference#latestanswer) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestConfigDetails](https://docs.chain.link/data-feeds/api-reference#latestconfigdetails) | Return information about the current offchain reporting protocol configuration. | | [latestRound](https://docs.chain.link/data-feeds/api-reference#latestround) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestRoundData](https://docs.chain.link/data-feeds/api-reference#latestrounddata-1) | Get the full information for the most recent round including the answer and update timestamps. | | [latestTimestamp](https://docs.chain.link/data-feeds/api-reference#latesttimestamp) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestTransmissionDetails](https://docs.chain.link/data-feeds/api-reference#latesttransmissiondetails) | Get information about the most recent answer. | | [linkAvailableForPayment](https://docs.chain.link/data-feeds/api-reference#linkavailableforpayment) | Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations. | | [oracleObservationCount](https://docs.chain.link/data-feeds/api-reference#oracleobservationcount) | Returns the number of observations that oracle is due to be reimbursed for. | | [owedPayment](https://docs.chain.link/data-feeds/api-reference#owedpayment) | Returns how much LINK an oracle is owed for its observations. | | [requesterAccessController](https://docs.chain.link/data-feeds/api-reference#requesteraccesscontroller) | Returns the address for the access controller contract. | | [transmitters](https://docs.chain.link/data-feeds/api-reference#transmitters) | The oracle addresses that can report answers to this aggregator. | | [typeAndVersion](https://docs.chain.link/data-feeds/api-reference#typeandversion) | Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 3.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`. | | [validatorConfig](https://docs.chain.link/data-feeds/api-reference#validatorconfig) | Returns the address and the gas limit for the validator contract. | | [version](https://docs.chain.link/data-feeds/api-reference#version-1) | Returns the contract version. This is different from the `typeAndVersion` for the aggregator. | #### [decimals](https://docs.chain.link/data-feeds/api-reference\#decimals-1) Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function decimals() external view returns (uint8 decimalPlaces); ``` #### [description](https://docs.chain.link/data-feeds/api-reference\#description-1) Return a description for this data feed. Usually this is an asset pair for a price feed. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function description() public view override checkAccess returns (string memory) { return super.description(); } ``` #### [getAnswer](https://docs.chain.link/data-feeds/api-reference\#getanswer) #### [getBilling](https://docs.chain.link/data-feeds/api-reference\#getbilling) Retrieve the current billing configuration. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getBilling() external view returns ( uint32 maximumGasPrice, uint32 reasonableGasPrice, uint32 microLinkPerEth, uint32 linkGweiPerObservation, uint32 linkGweiPerTransmission ) { Billing memory billing = s_billing; return ( billing.maximumGasPrice, billing.reasonableGasPrice, billing.microLinkPerEth, billing.linkGweiPerObservation, billing.linkGweiPerTransmission ); } ``` #### [getRoundData](https://docs.chain.link/data-feeds/api-reference\#getrounddata-1) Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getRoundData( uint80 _roundId ) public view override checkAccess returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) { return super.getRoundData(_roundId); } ``` #### [getTimestamp](https://docs.chain.link/data-feeds/api-reference\#gettimestamp) #### [hasAccess](https://docs.chain.link/data-feeds/api-reference\#hasaccess) Check if an address has internal access. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) { return super.hasAccess(_user, _calldata) || _user == tx.origin; } ``` #### [latestAnswer](https://docs.chain.link/data-feeds/api-reference\#latestanswer) #### [latestConfigDetails](https://docs.chain.link/data-feeds/api-reference\#latestconfigdetails) Return information about the current offchain reporting protocol configuration. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes16 configDigest) { return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest); } ``` #### [latestRound](https://docs.chain.link/data-feeds/api-reference\#latestround) #### [latestRoundData](https://docs.chain.link/data-feeds/api-reference\#latestrounddata-1) Get the full information for the most recent round including the answer and update timestamps. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function latestRoundData() public view override checkAccess returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) { return super.latestRoundData(); } ``` #### [latestTimestamp](https://docs.chain.link/data-feeds/api-reference\#latesttimestamp) #### [latestTransmissionDetails](https://docs.chain.link/data-feeds/api-reference\#latesttransmissiondetails) Get information about the most recent answer. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function latestTransmissionDetails() external view returns (bytes16 configDigest, uint32 epoch, uint8 round, int192 latestAnswer, uint64 latestTimestamp) { require(msg.sender == tx.origin, "Only callable by EOA"); return ( s_hotVars.latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8), uint8(s_hotVars.latestEpochAndRound), s_transmissions[s_hotVars.latestAggregatorRoundId].answer, s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp ); } ``` #### [linkAvailableForPayment](https://docs.chain.link/data-feeds/api-reference\#linkavailableforpayment) Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function linkAvailableForPayment() external view returns (int256 availableBalance) { // there are at most one billion LINK, so this cast is safe int256 balance = int256(LINK.balanceOf(address(this))); // according to the argument in the definition of totalLINKDue, // totalLINKDue is never greater than 2**172, so this cast is safe int256 due = int256(totalLINKDue()); // safe from overflow according to above sizes return int256(balance) - int256(due); } ``` #### [oracleObservationCount](https://docs.chain.link/data-feeds/api-reference\#oracleobservationcount) Returns the number of observations that oracle is due to be reimbursed for. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function oracleObservationCount(address _signerOrTransmitter) external view returns (uint16) { Oracle memory oracle = s_oracles[_signerOrTransmitter]; if (oracle.role == Role.Unset) { return 0; } return s_oracleObservationsCounts[oracle.index] - 1; } ``` #### [owedPayment](https://docs.chain.link/data-feeds/api-reference\#owedpayment) Returns how much LINK an oracle is owed for its observations. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function owedPayment(address _transmitter) public view returns (uint256) { Oracle memory oracle = s_oracles[_transmitter]; if (oracle.role == Role.Unset) { return 0; } Billing memory billing = s_billing; uint256 linkWeiAmount = uint256(s_oracleObservationsCounts[oracle.index] - 1) * uint256(billing.linkGweiPerObservation) * (1 gwei); linkWeiAmount += s_gasReimbursementsLinkWei[oracle.index] - 1; return linkWeiAmount; } ``` #### [requesterAccessController](https://docs.chain.link/data-feeds/api-reference\#requesteraccesscontroller) Returns the address for the access controller contract. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function requesterAccessController() external view returns (AccessControllerInterface) { return s_requesterAccessController; } ``` #### [transmitters](https://docs.chain.link/data-feeds/api-reference\#transmitters) The oracle addresses that can report answers to this aggregator. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function transmitters() external view returns (address[] memory) { return s_transmitters; } ``` #### [typeAndVersion](https://docs.chain.link/data-feeds/api-reference\#typeandversion) Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 2.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function typeAndVersion() external pure virtual override returns (string memory) { return "AccessControlledOffchainAggregator 2.0.0"; } ``` #### [validatorConfig](https://docs.chain.link/data-feeds/api-reference\#validatorconfig) Returns the address and the gas limit for the validator contract. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function validatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) { ValidatorConfig memory vc = s_validatorConfig; return (vc.validator, vc.gasLimit); } ``` #### [version](https://docs.chain.link/data-feeds/api-reference\#version-1) Returns the contract version. This is different from the `typeAndVersion` for the aggregator. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function version() external view returns (uint256); ``` ## Get the latest Chainlink content straight to your inbox. Email Address ## Developer Responsibilities Overview [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Developer Responsibilities: Market Integrity and Application Code Risks](https://docs.chain.link/data-feeds/developer-responsibilities\#overview) Chainlink Data Feeds provide access to highly secure, reliable, and decentralized real-world data published onchain. The assets priced by Chainlink Data Feeds are subject to market conditions beyond the ability of Chainlink node operators to control, as such developers are responsible for ensuring that the operation and performance of Chainlink Data Feeds match expectations. When integrating Chainlink Data Feeds, developers must understand that the performance of feeds is subject to risks associated with both market integrity and application code. - **Market Integrity Risks** are those associated with external market conditions impacting price behavior and data quality in unanticipated ways. Developers are solely responsible for monitoring and mitigating any potential market integrity risks. - **Application Code Risks** are those associated with the quality, reliability, and dependencies of the code on which an application operates. Developers are solely responsible for monitoring and mitigating any potential application code risks. Please [refer to this guide for additional information](https://chain.link/education-hub/market-manipulation-vs-oracle-exploits) about market integrity risks and how developers can protect their applications. ## [Developer Responsibilities](https://docs.chain.link/data-feeds/developer-responsibilities\#developer-responsibilities) Developers are responsible for maintaining the security and user experience of their applications. They must also securely manage all interactions between their applications and third-party services. In particular, developers implementing Chainlink Data Feeds in their code and applications are responsible for their application's market integrity and code risks that may cause unanticipated pricing data behavior. These are described below in more detail. ### [Market Integrity Risks](https://docs.chain.link/data-feeds/developer-responsibilities\#market-integrity-risks) Market conditions can impact the pricing behavior of assets in ways beyond the ability of Chainlink node operators to predict or control. Market integrity risk factors can include but are not limited to, [market manipulation](https://chain.link/education-hub/market-manipulation-vs-oracle-exploits) such as Spoofing, Ramping, Bear Raids, Cross-Market Manipulation, Washtrading, and Frontrunning. All assets are susceptible to [market risk](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories), but in particular, assets with high market risk, such as those with low liquidity, are the most vulnerable to market manipulation. Developers are solely responsible for accounting for such risk factors when integrating Chainlink Data Feeds into their applications. Developers should understand the market risks around the assets they intend their application to support before integrating associated Chainlink Data Feeds and inform their end users about applicable market risks. Developers should reference the following additional information when implementing Chainlink Data Feeds: - [Data Feed Categories](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories) to evaluate market integrity risks associated with specific Chainlink Data Feeds Developers intend to integrate. - [Evaluating Data Source Risks](https://docs.chain.link/data-feeds/selecting-data-feeds#evaluating-data-sources-and-risks) to evaluate risk mitigation techniques associated with Chainlink Data Feeds broadly. ### [Application Code Risks](https://docs.chain.link/data-feeds/developer-responsibilities\#application-code-risks) Developers implementing Chainlink Data Feeds are solely responsible for instituting the requisite [risk mitigation processes](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) including, but not limited to, data quality checks, circuit breakers, and appropriate contingency logic for their use case. - **Code quality and reliability:** Developers must execute code using Chainlink Data Feeds only if the code meets the quality and reliability requirements for their use case and application. - **Code and application audits:** Developers are responsible for auditing their code and applications before deploying to production. Developers must determine the quality of any audits and ensure that they meet the requirements for their application. - **Code dependencies and imports:** Developers are responsible for ensuring the quality, reliability, and security of any dependencies or imported packages that they use with Chainlink Data Feeds, and review and audit these dependencies and packages. ![](https://docs.chain.link/images/developer-responsibilities.webp) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083858364&cv=11&fst=1747083858364&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116026~103130495~103130497~103200004~103233427~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fdeveloper-responsibilities&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Developer%20Responsibilities%3A%20Market%20Integrity%20and%20Application%20Code%20Risks%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=473928914.1747083858&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Flags Registry [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Flags Contract Registry](https://docs.chain.link/data-feeds/contract-registry\#overview) The Chainlink Flags Contract Registry provides a reliable, onchain source of truth for all active Chainlink price feed proxy contracts across supported networks. It serves as a central reference point for identifying which data feeds are **owned and operated by Chainlink**, verifying the authenticity of the feeds your applications rely on. A proxy address that returns `true` when checked against this registry indicates two things: 1. The data feed is officially owned and operated by Chainlink 2. The feed is currently active Inactive feeds are removed from the registry to ensure accuracy. The list is actively maintained as new feeds are deployed, making it a trusted resource for keeping up with the evolving state of Chainlink's oracle infrastructure. ## [Querying Flags Onchain](https://docs.chain.link/data-feeds/contract-registry\#querying-flags-onchain) To check if a proxy address is flagged (owned by Chainlink and active) in your Solidity code, you can call the `getFlag` function on the `Flags` contract deployed on the corresponding network: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity interface IFlags { function getFlag(address) external view returns (bool); } contract Example { IFlags public flags; // Initialize with the correct Flags contract address for your network constructor(address flagsContractAddress) { flags = IFlags(flagsContractAddress); } function isOfficialChainlinkFeed(address proxy) public view returns (bool) { return flags.getFlag(proxy); } } ``` ## [Flags Contract Addresses](https://docs.chain.link/data-feeds/contract-registry\#flags-contract-addresses) Below is a list of all available Flags contracts on the supported networks: | | Chain | ChainFlag Contract Address | | --- | --- | --- | | ![](https://docs.chain.link/assets/chains/arbitrum.svg) | Arbitrum | [0x20551B03c092D998b1410c47BD54004D7C3106D0](https://arbiscan.io/address/0x20551B03c092D998b1410c47BD54004D7C3106D0 "0x20551B03c092D998b1410c47BD54004D7C3106D0")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/avalanche.svg) | Avalanche | [0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd](https://snowtrace.io/address/0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd "0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/base.svg) | Base | [0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd](https://basescan.org/address/0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd "0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/bob.svg) | Bob | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://explorer.gobob.xyz/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/bnb-chain.svg) | BNB Chain (BSC) | [0x141f4278A5D71070Dc09CA276b72809b80F20eF0](https://bscscan.com/address/0x141f4278A5D71070Dc09CA276b72809b80F20eF0 "0x141f4278A5D71070Dc09CA276b72809b80F20eF0")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/celo.svg) | Celo | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://celo.blockscout.com/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/ethereum.svg) | Ethereum | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://etherscan.io/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/gnosis-chain.svg) | Gnosis Chain (xDai) | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://gnosisscan.io/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/ink.svg) | Ink | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://explorer.inkonchain.com/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/linea.svg) | Linea | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://lineascan.build/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/mantle.svg) | Mantle | [0x141f4278A5D71070Dc09CA276b72809b80F20eF0](https://mantlescan.xyz/address/0x141f4278A5D71070Dc09CA276b72809b80F20eF0 "0x141f4278A5D71070Dc09CA276b72809b80F20eF0")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/optimism.svg) | Optimism | [0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd](https://optimistic.etherscan.io/address/0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd "0x71c5CC2aEB9Fa812CA360E9bAC7108FC23312cdd")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/polygon.svg) | Polygon | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://polygonscan.com/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/scroll.svg) | Scroll | [0x141f4278A5D71070Dc09CA276b72809b80F20eF0](https://scrollscan.com/address/0x141f4278A5D71070Dc09CA276b72809b80F20eF0 "0x141f4278A5D71070Dc09CA276b72809b80F20eF0")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/soneium.svg) | Soneium | [0x3DE960FE090BFec72F585347fa0a27CF96a83b36](https://soneium.blockscout.com/address/0x3DE960FE090BFec72F585347fa0a27CF96a83b36 "0x3DE960FE090BFec72F585347fa0a27CF96a83b36")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/sonic.svg) | Sonic | [0x141f4278A5D71070Dc09CA276b72809b80F20eF0](https://sonicscan.org/address/0x141f4278A5D71070Dc09CA276b72809b80F20eF0 "0x141f4278A5D71070Dc09CA276b72809b80F20eF0")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/unichain.svg) | UniChain | [0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e](https://uniscan.xyz/address/0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e "0xaB93491064aEE774BE4b8a1cFFe4421F5B124F4e")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | ![](https://docs.chain.link/assets/chains/zksync.svg) | zkSync | [0xC370405879C1ab0470604679E3275a02bCb89C91](https://explorer.zksync.io/address/0xC370405879C1ab0470604679E3275a02bCb89C91 "0xC370405879C1ab0470604679E3275a02bCb89C91")![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083858661&cv=11&fst=1747083858661&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~102015665~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fcontract-registry&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Flags%20Contract%20Registry%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1693407347.1747083858&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Price Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Price Feeds](https://docs.chain.link/data-feeds/price-feeds\#overview) Chainlink Data Feeds provide data that is aggregated from many data sources by a decentralized set of independent node operators. The [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) describes this in detail. However, there are some exceptions where data for a feed can come only from a single data source or where data values are calculated. Read the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) to learn about the different data feed categories and how to identify them. ## What's next - [\> Learn how to read answers from Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) - [\> Learn how to get Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Find contract addresses for Price Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083858314&cv=11&fst=1747083858314&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116026~103200004~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116025~103130495~103130497~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fprice-feeds&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Price%20Feeds%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=350023175.1747083858&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Historical Data [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Getting Historical Data](https://docs.chain.link/data-feeds/historical-data\#overview) The most common use case for Data Feeds is to [Get the Latest Data](https://docs.chain.link/data-feeds/using-data-feeds) from a feed. However, the [AggregatorV3Interface.sol](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) also has functions to retrieve data of a previous round IDs. There are two parameters that can cause Chainlink nodes to update: | Name | Description | | --- | --- | | Deviation Threshold | Chainlink nodes are monitoring data offchain. The deviation of the real-world data beyond a certain interval triggers all the nodes to update. | | Heartbeat Threshold | If the data values stay within the deviation parameters, it will only trigger an update every _X_ minutes / hours. | You can find these parameters at [data.chain.link](https://data.chain.link/) on an example like [ETH / USD](https://data.chain.link/ethereum/mainnet/crypto-usd/eth-usd). To learn how data feeds update, see the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## [Historical rounds](https://docs.chain.link/data-feeds/historical-data\#historical-rounds) As shown in the [decentralized model](https://docs.chain.link/architecture-overview/architecture-decentralized-model), the consumer contracts call the proxy contract, which abstracts the underlying aggregator contract. The main advantage is to enable upgrades of the aggregator without impacting the consumer contracts. That also means that historical data can can be stored in different aggregators. As shown in the following sequence diagram, to get historical data, call the `getRoundData` [function](https://docs.chain.link/data-feeds/api-reference/#getrounddata) and provide `roundId` as a parameter. ![](https://docs.chain.link/images/data-feed/getRoundData-sequence.png) Note that roundIds have different meanings in proxy contracts and in aggregator contracts. ### [`roundId` in Aggregator (aggregatorRoundId)](https://docs.chain.link/data-feeds/historical-data\#roundid-in-aggregator-aggregatorroundid) Oracles provide periodic data updates to the aggregators. Data feeds are updated in **rounds**. Rounds are identified by their `roundId`, which increases with each new round. This increase may not be monotonic. Knowing the `roundId` of a previous round allows contracts to consume historical data. The examples in this document name the aggregator `roundId` as `aggregatorRoundId` to differentiate it from the proxy `roundId`. ### [`roundId` in proxy](https://docs.chain.link/data-feeds/historical-data\#roundid-in-proxy) Because a proxy has references to current and all previous underlying aggregators, it needs a way to fetch data from the correct aggregator. The `roundId` is computed in the [proxy contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/AggregatorProxy.sol) as shown in the following example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity return uint80(uint256(_phase) << PHASE_OFFSET | _originalId); ``` where: - `_phase` is incremented each time the underlying aggregator implementation is updated. It is used as a key to find the aggregator address. - `_originalId` is the aggregator `roundId`. The ID starts at 1. From the above formula, you can think of it as returning a large number containing the `phase` and the aggregator `roundId`. **Example:** When you query historical data, it is important to know when you reach the end of the history of the underlying aggregator. As an example, if the [`latestRoundData` function](https://docs.chain.link/data-feeds/api-reference/#latestrounddata) of the [LINK / USD Price Feed on Ethereum Mainnet](https://docs.chain.link/data-feeds/price-feeds/addresses/?network=ethereum) returns `roundId = 92233720368547771158`, you can use this value to compute the `phaseId` and `aggregatorRoundId`: - `phaseId = 92233720368547771158 >> 64`: Right shifting an integer by 64 bits is equivalent to dividing it by 2^64: `phaseId = 92233720368547771158/ 2^64 = 5`. The current phase id is 5 , which means that this proxy has had 5 underlying aggregators since its initial deployment. - `aggregatorRoundId = uint64(92233720368547771158)`: This retrieves the first 64 bits from the right. To calculate this offchain, you can use the following JavaScript example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```javascript // First parse to BigInt to perform computation with big integers const num = BigInt("92233720368547771158") const num2 = BigInt("0xFFFFFFFFFFFFFFFF") // Largest 64bits integer console.log(Number(num >> 64n)) // returns 5 (phaseId) console.log(Number(num & num2)) // returns 13078 (aggregatorRoundId) . Use & (AND bitwise operator) which sets each bit to _1_ if both bits are _1_ ``` Using _13078_ as the current aggregator's round, get its historical data by looping over the [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata): - Start from the first round: _92233720368547758081_ (result of _92233720368547771158 - 13078 + 1_) - Continue until the current round: _92233720368547771158_ To get the historical data for previous aggregators, decrement the `phaseId` and start from round _1_. For phase _4_, get the starting `roundId` offchain using the following JavaScript example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```javascript const phaseId = BigInt("4") const aggregatorRoundId = BigInt("1") roundId = (phaseId << 64n) | aggregatorRoundId // returns 73786976294838206465n ``` Loop over the [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata). Start at _73786976294838206465_ and increment it until you get a revert. This means that you reached the last round for the underlying aggregator. The same process could be repeated for previous `phaseIds` (3,2,1). ### [`getRoundData` return values](https://docs.chain.link/data-feeds/historical-data\#getrounddata-return-values) The [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata) returns the following values: - `roundId`: The round in which the answer was updated - `answer`: The answer reflects the data recorded for the specified round - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed - `startedAt`: The timestamp when the round started - `updatedAt`: The timestamp when the answer was computed ### [Solidity](https://docs.chain.link/data-feeds/historical-data\#solidity) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract HistoricalDataConsumerV3 { AggregatorV3Interface internal dataFeed; /** * Network: Sepolia * Aggregator: ETH/USD * Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306 */ constructor() { dataFeed = AggregatorV3Interface( 0x694AA1769357215DE4FAC081bf1f309aDC325306 ); } /** * Returns historical data for a round ID. * roundId is NOT incremental. Not all roundIds are valid. * You must know a valid roundId before consuming historical data. * * ROUNDID VALUES: * InValid: 18446744073709562300 * Valid: 18446744073709554683 * * @dev A timestamp with zero value means the round is not complete and should not be used. */ function getHistoricalData(uint80 roundId) public view returns (int256) { // prettier-ignore ( /*uint80 roundID*/, int answer, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = dataFeed.getRoundData(roundId); return answer; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/HistoricalDataConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ### [Javascript](https://docs.chain.link/data-feeds/historical-data\#javascript) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const Web3 = require("web3") // for nodejs only // Replace the provider URL with your own endpoint URL const web3 = new Web3("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const dataFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr) // Valid roundId must be known. They are NOT incremental. let validId = BigInt("18446744073709554177") dataFeed.methods .getRoundData(validId) .call() .then((historicalRoundData) => { document.getElementById("get-data-field").value = historicalRoundData.answer }) ``` Round 18446744073709551978: Historical Price ### [Python](https://docs.chain.link/data-feeds/historical-data\#python) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity # THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. # THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. # DO NOT USE THIS CODE IN PRODUCTION. from web3 import Web3 # Change this to use your own RPC URL web3 = Web3(Web3.HTTPProvider('https://rpc.ankr.com/eth_sepolia')) # AggregatorV3Interface ABI abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]' # Feed address addr = '0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43' # Set up contract instance contract = web3.eth.contract(address=addr, abi=abi) # Valid roundId must be known. They are NOT incremental. # invalidRoundId = 18446744073709562300 validRoundId = 18446744073709554177 historicalData = contract.functions.getRoundData(validRoundId).call() print(historicalData) ``` ## What's next - [\> API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863201&cv=11&fst=1747083863201&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103101750~103101752~103116025~103200001~103207801~103233427~103251618~103251620~103263070~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116026~103200004~103233427~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fhistorical-data&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Getting%20Historical%20Data%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=896429772.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Data Feeds Guide [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Consuming Data Feeds](https://docs.chain.link/data-feeds/getting-started\#overview) You can use Chainlink Data Feeds to connect your smart contracts to asset pricing data like the [ETH / USD feed](https://data.chain.link/feeds/ethereum/mainnet/eth-usd). These data feeds use data aggregated from many independent Chainlink node operators. Each price feed has an onchain address and functions that enable contracts to read pricing data from that address. This guide shows you how to read Data Feeds and store the value onchain using Solidity. To learn how to read feeds offchain or use different languages, see the [Using Data Feeds on EVM Chains](https://docs.chain.link/data-feeds/using-data-feeds) guide. Alternatively, you can also learn how to use Data Feeds on [Solana](https://docs.chain.link/data-feeds/solana) or [StarkNet](https://docs.chain.link/data-feeds/starknet). The code for reading Data Feeds on Ethereum or other EVM-compatible blockchains is the same for each chain and each Data Feed types. You choose different types of feeds for different uses, but the request and response format are the same. The answer decimal length and expected value ranges might change depending on what feed you use. ## [Before you begin](https://docs.chain.link/data-feeds/getting-started\#before-you-begin) If you are new to smart contract development, learn how to [Deploy Your First Smart Contract](https://docs.chain.link/quickstarts/deploy-your-first-contract/) before you start this guide. ## [Examine the sample contract](https://docs.chain.link/data-feeds/getting-started\#examine-the-sample-contract) This example contract obtains the latest price answer from the [BTC / USD feed](https://docs.chain.link/data-feeds/price-feeds/addresses) on the Sepolia testnet, but you can modify it to read any of the different [Types of Data Feeds](https://docs.chain.link/data-feeds#types-of-data-feeds). ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED * VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ /** * If you are reading data feeds on L2 networks, you must * check the latest answer from the L2 Sequencer Uptime * Feed to ensure that the data is accurate in the event * of an L2 sequencer outage. See the * https://docs.chain.link/data-feeds/l2-sequencer-feeds * page for details. */ contract DataConsumerV3 { AggregatorV3Interface internal dataFeed; /** * Network: Sepolia * Aggregator: BTC/USD * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 */ constructor() { dataFeed = AggregatorV3Interface( 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 ); } /** * Returns the latest answer. */ function getChainlinkDataFeedLatestAnswer() public view returns (int) { // prettier-ignore ( /* uint80 roundId */, int256 answer, /*uint256 startedAt*/, /*uint256 updatedAt*/, /*uint80 answeredInRound*/ ) = dataFeed.latestRoundData(); return answer; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerV3.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) The contract has the following components: - The `import` line imports an interface named `AggregatorV3Interface`. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves. In this case, `AggregatorV3Interface` defines that all v3 Aggregators have the function `latestRoundData`. You can [see the complete code](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) for the `AggregatorV3Interface` on GitHub. - The `constructor() {}` initializes an interface object named `dataFeed` that uses `AggregatorV3Interface` and connects specifically to a proxy aggregator contract that is already deployed at `0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43`. The interface allows your contract to run functions on that deployed aggregator contract. - The `getChainlinkDataFeedLatestAnswer()` function calls your `dataFeed` object and runs the `latestRoundData()` function. When you deploy the contract, it initializes the `dataFeed` object to point to the aggregator at `0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43`, which is the proxy address for the Sepolia BTC / USD data feed. Your contract connects to that address and executes the function. The aggregator connects with several oracle nodes and aggregates the pricing data from those nodes. The response from the aggregator includes several variables, but `getChainlinkDataFeedLatestAnswer()` returns only the `answer` variable. ## [Compile, deploy, and run the contract](https://docs.chain.link/data-feeds/getting-started\#compile-deploy-and-run-the-contract) Deploy the `DataConsumerV3` smart contract on the Sepolia testnet. 1. [Open the example contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerV3.sol) in Remix. Remix opens and shows the contents of the smart contract. [Open the contract in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerV3.sol) 2. Because the code is already written, you can start the compile step. On the left side of Remix, click the **Solidity Compiler** tab to view the compiler settings. ![Screenshot showing the Compiler tab and its settings.](https://docs.chain.link/images/getting-started/selectSolidityCompiler.png) 3. Use the default compiler settings. Click the **Compile DataConsumerV3.sol** button to compile the contract. Remix automatically detects the correct compiler version depending on the `pragma` that you specify in the contract. You can ignore warnings about unused local variables in this example. ![Screenshot of the Compile button.](https://docs.chain.link/images/getting-started/compileDataConsumerV3.png) 4. On the **Deploy** tab, select the **Injected Provider** environment. This contract specifically requires Web3 because it connects with another contract on the blockchain. Running in a JavaScript VM will not work. ![Screenshot showing the Injected Provider environment selected.](https://docs.chain.link/images/getting-started/selectWeb3.png) 5. Because the example contract has several imports, Remix might select another contract to deploy by default. In the **Contract** section, select the `DataConsumerV3` contract to make sure that Remix deploys the correct contract. ![Screenshot showing DataConsumerV3 as the contract to deploy.](https://docs.chain.link/images/getting-started/selectDataConsumerV3.png) 6. Click **Deploy** to deploy the contract to the Sepolia testnet. MetaMask opens and asks you to confirm payment for deploying the contract. Make sure MetaMask is set to the Sepolia network before you accept the transaction. Because these transactions are on the blockchain, they are not reversible. ![Screenshot of the Deploy button for DataConsumerV3.](https://docs.chain.link/images/getting-started/deployDataConsumerV3.png) 7. In the MetaMask prompt, click **Confirm** to approve the transaction and spend your testnet ETH required to deploy the contract. ![Screenshot showing Metamask asking you to confirm the transaction.](https://docs.chain.link/images/getting-started/confirmTransaction.png) 8. After a few seconds, the transaction completes and your contract appears under the **Deployed Contracts** list in Remix. Click the contract dropdown to view its variables and functions. ![Remix Deployed Contracts Section](https://docs.chain.link/images/getting-started/deployedContractDataConsumerV3.png) 9. Click **getChainlinkDataFeedLatestAnswer** to show the latest answer from the aggregator contract. In this example, the answer is the latest price, which appears just below the button. The returned answer is an integer, so it is missing its decimal point. You can find the correct number of decimal places for this answer on the [Price Feed addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page by clicking the **Show more details** checkbox. The answer on the BTC / USD feed uses 8 decimal places, so an answer of `3030914000000` indicates a BTC / USD price of `30309.14`. Each feed uses a different number of decimal places for answers. ![A screenshot showing the deployed contract and the latest answer.](https://docs.chain.link/images/getting-started/getLatestPrice.png) ## What's next - [\> See examples for how to read feeds onchain and offchain](https://docs.chain.link/data-feeds/using-data-feeds) - [\> Learn how to retrieve Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Read the Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863143&cv=11&fst=1747083863143&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103101750~103101752~103116025~103130495~103130497~103200001~103233427~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116026~103200004~103233427~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fgetting-started&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Consuming%20Data%20Feeds%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1488789065.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Feed Registry [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Feed Registry](https://docs.chain.link/data-feeds/feed-registry\#overview) The Chainlink Feed Registry is an onchain mapping of assets to feeds. It enables you to query Chainlink data feeds from asset addresses directly, without needing to know the feed contract addresses. They enable smart contracts to get the latest price of an asset in a single call, from a single contract. ![](https://docs.chain.link/files/feed-registry.png) For a complete list of functions and parameters for the `FeedRegistryInterface` contract, see the [Feed Registry API Reference](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions). ## [Base and Quote](https://docs.chain.link/data-feeds/feed-registry\#base-and-quote) The Feed Registry fully supports the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) API for multiple feeds. It maps feeds from `base` and `quote` address pairs. To get the latest LINK / USD round data from the registry, call: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity latestRoundData(address base, address quote) ``` For example, to get the latest LINK / USD price: - `base`: The LINK token address on that network e.g. `0x514910771AF9Ca656af840dff83E8264EcF986CA` for LINK on Ethereum mainnet - `quote`: A `Denominations.USD` address ( `0x0000000000000000000000000000000000000348`), which is based on [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217). ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity latestRoundData(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0x0000000000000000000000000000000000000348) ``` To get the latest LINK / ETH price on Ethereum: - `base`: The LINK token address on that network e.g. `0x514910771AF9Ca656af840dff83E8264EcF986CA` for LINK on Ethereum mainnet - `quote`: A `Denominations.ETH` address ( `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity latestRoundData(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) ``` ### [Denominations library](https://docs.chain.link/data-feeds/feed-registry\#denominations-library) A [`Denominations`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/Denominations.sol) Solidity library is available for you to fetch currency identifiers which lack a canonical Ethereum address: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; library Denominations { address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant BTC = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB; // Fiat currencies follow https://en.wikipedia.org/wiki/ISO_4217 address public constant USD = address(840); address public constant GBP = address(826); address public constant EUR = address(978); // ... other fiat currencies } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/FeedRegistry/Denominations.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## [Code Examples](https://docs.chain.link/data-feeds/feed-registry\#code-examples) ### [Solidity](https://docs.chain.link/data-feeds/feed-registry\#solidity) To consume price data from the Feed Registry, your smart contract should reference [`FeedRegistryInterface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol), which defines the external functions implemented by the Feed Registry. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {FeedRegistryInterface} from "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol"; import {Denominations} from "@chainlink/contracts/src/v0.8/Denominations.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract PriceConsumer { FeedRegistryInterface internal registry; /** * Network: Ethereum Mainnet * Feed Registry: 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf */ constructor(address _registry) { registry = FeedRegistryInterface(_registry); } /** * Returns the ETH / USD price */ function getEthUsdPrice() public view returns (int) { // prettier-ignore ( /*uint80 roundID*/, int price, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = registry.latestRoundData(Denominations.ETH, Denominations.USD); return price; } /** * Returns the latest price */ function getPrice(address base, address quote) public view returns (int) { // prettier-ignore ( /*uint80 roundID*/, int price, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = registry.latestRoundData(base, quote); return price; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/FeedRegistry/PriceConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ### [Solidity Hardhat Example](https://docs.chain.link/data-feeds/feed-registry\#solidity-hardhat-example) ### [Javascript](https://docs.chain.link/data-feeds/feed-registry\#javascript) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const web3 = new Web3("https://rpc.ankr.com/eth") const feedRegistryInterfaceABI = [\ {\ anonymous: false,\ inputs: [\ { indexed: true, internalType: "address", name: "accessController", type: "address" },\ { indexed: true, internalType: "address", name: "sender", type: "address" },\ ],\ name: "AccessControllerSet",\ type: "event",\ },\ {\ anonymous: false,\ inputs: [\ { indexed: true, internalType: "address", name: "asset", type: "address" },\ { indexed: true, internalType: "address", name: "denomination", type: "address" },\ { indexed: true, internalType: "address", name: "latestAggregator", type: "address" },\ { indexed: false, internalType: "address", name: "previousAggregator", type: "address" },\ { indexed: false, internalType: "uint16", name: "nextPhaseId", type: "uint16" },\ { indexed: false, internalType: "address", name: "sender", type: "address" },\ ],\ name: "FeedConfirmed",\ type: "event",\ },\ {\ anonymous: false,\ inputs: [\ { indexed: true, internalType: "address", name: "asset", type: "address" },\ { indexed: true, internalType: "address", name: "denomination", type: "address" },\ { indexed: true, internalType: "address", name: "proposedAggregator", type: "address" },\ { indexed: false, internalType: "address", name: "currentAggregator", type: "address" },\ { indexed: false, internalType: "address", name: "sender", type: "address" },\ ],\ name: "FeedProposed",\ type: "event",\ },\ {\ anonymous: false,\ inputs: [\ { indexed: true, internalType: "address", name: "from", type: "address" },\ { indexed: true, internalType: "address", name: "to", type: "address" },\ ],\ name: "OwnershipTransferRequested",\ type: "event",\ },\ {\ anonymous: false,\ inputs: [\ { indexed: true, internalType: "address", name: "from", type: "address" },\ { indexed: true, internalType: "address", name: "to", type: "address" },\ ],\ name: "OwnershipTransferred",\ type: "event",\ },\ { inputs: [], name: "acceptOwnership", outputs: [], stateMutability: "nonpayable", type: "function" },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "address", name: "aggregator", type: "address" },\ ],\ name: "confirmFeed",\ outputs: [],\ stateMutability: "nonpayable",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "getAccessController",\ outputs: [{ internalType: "contract AccessControllerInterface", name: "", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint256", name: "roundId", type: "uint256" },\ ],\ name: "getAnswer",\ outputs: [{ internalType: "int256", name: "answer", type: "int256" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "getCurrentPhaseId",\ outputs: [{ internalType: "uint16", name: "currentPhaseId", type: "uint16" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "getFeed",\ outputs: [{ internalType: "contract AggregatorV2V3Interface", name: "aggregator", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint80", name: "roundId", type: "uint80" },\ ],\ name: "getNextRoundId",\ outputs: [{ internalType: "uint80", name: "nextRoundId", type: "uint80" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint16", name: "phaseId", type: "uint16" },\ ],\ name: "getPhase",\ outputs: [\ {\ components: [\ { internalType: "uint16", name: "phaseId", type: "uint16" },\ { internalType: "uint80", name: "startingAggregatorRoundId", type: "uint80" },\ { internalType: "uint80", name: "endingAggregatorRoundId", type: "uint80" },\ ],\ internalType: "struct FeedRegistryInterface.Phase",\ name: "phase",\ type: "tuple",\ },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint16", name: "phaseId", type: "uint16" },\ ],\ name: "getPhaseFeed",\ outputs: [{ internalType: "contract AggregatorV2V3Interface", name: "aggregator", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint16", name: "phaseId", type: "uint16" },\ ],\ name: "getPhaseRange",\ outputs: [\ { internalType: "uint80", name: "startingRoundId", type: "uint80" },\ { internalType: "uint80", name: "endingRoundId", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint80", name: "roundId", type: "uint80" },\ ],\ name: "getPreviousRoundId",\ outputs: [{ internalType: "uint80", name: "previousRoundId", type: "uint80" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "getProposedFeed",\ outputs: [{ internalType: "contract AggregatorV2V3Interface", name: "proposedAggregator", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint80", name: "_roundId", type: "uint80" },\ ],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint80", name: "roundId", type: "uint80" },\ ],\ name: "getRoundFeed",\ outputs: [{ internalType: "contract AggregatorV2V3Interface", name: "aggregator", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint256", name: "roundId", type: "uint256" },\ ],\ name: "getTimestamp",\ outputs: [{ internalType: "uint256", name: "timestamp", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "address", name: "aggregator", type: "address" }],\ name: "isFeedEnabled",\ outputs: [{ internalType: "bool", name: "", type: "bool" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "latestAnswer",\ outputs: [{ internalType: "int256", name: "answer", type: "int256" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "latestRound",\ outputs: [{ internalType: "uint256", name: "roundId", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "latestTimestamp",\ outputs: [{ internalType: "uint256", name: "timestamp", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "owner",\ outputs: [{ internalType: "address", name: "", type: "address" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "address", name: "aggregator", type: "address" },\ ],\ name: "proposeFeed",\ outputs: [],\ stateMutability: "nonpayable",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ { internalType: "uint80", name: "roundId", type: "uint80" },\ ],\ name: "proposedGetRoundData",\ outputs: [\ { internalType: "uint80", name: "id", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "proposedLatestRoundData",\ outputs: [\ { internalType: "uint80", name: "id", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "contract AccessControllerInterface", name: "_accessController", type: "address" }],\ name: "setAccessController",\ outputs: [],\ stateMutability: "nonpayable",\ type: "function",\ },\ {\ inputs: [{ internalType: "address", name: "to", type: "address" }],\ name: "transferOwnership",\ outputs: [],\ stateMutability: "nonpayable",\ type: "function",\ },\ {\ inputs: [],\ name: "typeAndVersion",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "pure",\ type: "function",\ },\ {\ inputs: [\ { internalType: "address", name: "base", type: "address" },\ { internalType: "address", name: "quote", type: "address" },\ ],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf" const feedRegistry = new web3.eth.Contract(feedRegistryInterfaceABI, addr) const LINK = "0x514910771AF9Ca656af840dff83E8264EcF986CA" const USD = "0x0000000000000000000000000000000000000348" feedRegistry.methods .latestRoundData(LINK, USD) .call() .then((roundData) => { // Do something with roundData console.log("Latest Round Data", roundData) }) ``` Latest LINK/USD Price: Latest Price ## [Contract addresses](https://docs.chain.link/data-feeds/feed-registry\#contract-addresses) This section lists the blockchains that Chainlink Feed Registry are currently available on. | Network | Address | | --- | --- | | Ethereum Mainnet | [`0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf`](https://etherscan.io/address/0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf) | ## What's next - [\> Read the Feed Registry API Reference](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions) - [\> See the FeedRegistryInterface contract on GitHub](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863281&cv=11&fst=1747083863281&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116026~103130495~103130497~103200004~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Ffeed-registry&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Feed%20Registry%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1666102102.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Rate Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds\#overview) Chainlink rate and volatility feeds provide data for interest rates, interest rate curves, and asset volatility. You can read these feeds the same way that you read other Data Feeds. Specify the [Rate or Volatility Feed Address](https://docs.chain.link/data-feeds/rates-feeds/addresses) that you want to read instead of specifying a Price Feed address. See the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) page to learn more. The following data types are available: - [Bitcoin Interest Rate Curve](https://docs.chain.link/data-feeds/rates-feeds#bitcoin-interest-rate-curve) - [ETH Staking APR](https://docs.chain.link/data-feeds/rates-feeds#eth-staking-apr) - [Realized Volatility](https://docs.chain.link/data-feeds/rates-feeds#realized-volatility) ## [Bitcoin Interest Rate Curve](https://docs.chain.link/data-feeds/rates-feeds\#bitcoin-interest-rate-curve) Lenders and borrowers use base rates to evaluate interest rate risk for lending and borrowing contracts, asset valuation for derivatives contracts, and an underlying rate for interest rate swap contracts. Bitcoin Interest Rate Curve Data Feeds provide a base rate to assist with market decisions and quantify the risks of using certain protocols and products based on current and predicted baseline interest rates. The curve’s normalized methodology and daily rates introduce more consistency and predictability to the ebb and flow of digital asset markets. Bitcoin Interest Rate Curve Feeds incorporate a wide range of data sources such as OTC lending desks, DeFi lending pools, and perpetual futures markets. To learn more about the use of these interest rate curves in the industry, read the [Bitcoin Interest Rate Curve (CF BIRC)](https://blog.chain.link/cf-bitcoin-interest-rate-curve-cf-birc/) blog post. See the [Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page to find the Bitcoin Interest Rate Curve feeds that are currently available. ## [ETH Staking APR](https://docs.chain.link/data-feeds/rates-feeds\#eth-staking-apr) The ETH Staking APR feeds provide a trust-minimized and tamper-proof source of truth for the global rate of return from staking as a validator to secure the Ethereum network. The annualized rate of return is calculated over 30-day and 90-day rolling windows. Data providers use offchain computation to calculate returns at an epoch level, reach consensus on the APR, and then write the results onchain to be used by decentralized protocols and Web 3 applications. Feeds are currently configured to update at a minimum of once per day. ![A diagram showing how Staking data is obtained and annualized rate of return is confirmed onchain](https://docs.chain.link/images/data-feed/eth-staking-apr-feed-V3.webp) See the [Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page to find the ETH Staking APR feeds that are currently available. If you have questions or would like to request an enhancement to ETH Staking APR feeds, contact us using [this form](https://forms.gle/Jc1MGY5ry1ceYH1X6). ## [Realized volatility](https://docs.chain.link/data-feeds/rates-feeds\#realized-volatility) Realized volatility measures asset price movement over a specific time interval. This value is expressed as a percent of the asset price. The more an asset price moves up or down over time, the higher the realized volatility is for that asset. Please note that realized volatility is not the same as implied volatility, which measures the market’s expectation about future volatility typically derived from options markets. Each data feed reflects the volatility of an asset over a specific rolling window of time. For example, some data feeds provide volatility data for the last 24 hours, 7 days, and 30 days of time. You can compare the data across these windows to infer whether the volatility of an asset is trending up or down. For example, if realized volatility for the 24-hour window is higher than the 7-day window, volatility might increase. The same high-quality data providers used in Chainlink’s price feeds sample price data every 10 minutes to refresh volatility estimates. onchain values are updated when the feed heartbeat or deviation threshold is met. ![A diagram showing how volatility data is obtained and answers for different volatility windows is confirmed onchain](https://docs.chain.link/images/data-feed/realised-volatility-feed-V3.webp) See the [Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page to find heartbeat and deviation information for each feed. If you have questions or would like to request an enhancement to Realized Volatility Feeds, contact us using [this form](https://forms.gle/Jc1MGY5ry1ceYH1X6). ## What's next - [\> Learn how to read answers from Data Feeds](https://docs.chain.link/data-feeds/price-feeds) - [\> Learn how to get Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Find contract addresses for Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds/addresses) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink SVR Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Smart Value Recapture (SVR) Feeds](https://docs.chain.link/data-feeds/svr-feeds\#overview) [Chainlink Smart Value Recapture](https://blog.chain.link/chainlink-smart-value-recapture-svr/) (SVR) Feeds introduce a novel and secure way to recapture Oracle Extractable Value (OEV)—a subset of non-toxic Maximal Extractable Value (MEV) associated with oracle updates that is most commonly observed during the liquidation process of lending protocols. The value recaptured by SVR provides DeFi protocols with an additional revenue stream while also supporting the economic sustainability of Chainlink oracle. SVR Feeds are read in the same manner as standard Chainlink Data Feeds (see [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds)), and simply require that users specify an SVR-enabled feed address. ## [Understanding MEV and OEV](https://docs.chain.link/data-feeds/svr-feeds\#understanding-mev-and-oev) ### [Maximal Extractable Value (MEV)](https://docs.chain.link/data-feeds/svr-feeds\#maximal-extractable-value-mev) Maximal Extractable Value (MEV) refers to the value derived from the ability of block proposers (e.g., validators) to include, exclude, or change the order of transactions in the blocks they produce. Specialized **searchers** typically identify MEV opportunities, such as liquidation or arbitrage, and bid for optimal inclusion in the block via a competitive auction. The value is then captured by the participants of the block building process such as searchers, builders, and validators. ### [Oracle Extractable Value (OEV)](https://docs.chain.link/data-feeds/svr-feeds\#oracle-extractable-value-oev) Oracle Extractable Value (OEV) refers to a subset of MEV created during the transmission of **oracle reports** onchain and their subsequent consumption by onchain applications. For example, when a price oracle report reveals that a collateralized position is at-risk and eligible for liquidation, searchers compete to place a **liquidation transaction** immediately after the oracle update transaction (a process known as **backrunning**). Because oracles supply these price updates, the resulting liquidation MEV is inherently "oracle-related". ## [Chainlink Smart Value Recapture (SVR)](https://docs.chain.link/data-feeds/svr-feeds\#chainlink-smart-value-recapture-svr) Chainlink Smart Value Recapture (SVR) extends standard Chainlink Price Feeds with an **optional private transmission flow**. By sending oracle updates through a **dual aggregator** architecture, SVR enables an **auction** for the opportunity to backrun liquidations. This approach enables **non-toxic MEV** recapture, where the **DeFi protocol** and the **Chainlink Network** share in the payment offered by the searcher for the right to backrun the liquidation instead of letting it leak entirely to third parties. ### [Why Use SVR?](https://docs.chain.link/data-feeds/svr-feeds\#why-use-svr) - **Targeted at Liquidations (Non-Toxic MEV Capture)** SVR is purpose-built for recapturing non-toxic **liquidation-related OEV** via backrunning and cannot be used for harmful forms of MEV such as frontrunning or sandwich attacks. - **Minimal Integration Changes** Chainlink SVR Feeds maintain the **same aggregator interface** and data structure as standard Chainlink Price Feeds. Most protocols can simply point to the new SVR contracts with **minimal** changes required. - **Economic Sustainability** By recapturing OEV that would have otherwise been leaked to third parties, SVR helps support the economic sustainability of the DeFi ecosystem. Recaptured OEV revenue is split between integrating DeFi protocols and the Chainlink Network at a standard rate. - **Fallback Security** Chainlink SVR uses **standard Price Feeds** as a fallback, ensuring pricing data is continually made available to protocols via the public mempool in situations where the private route (e.g., Flashbots) fails. - **Proven Oracle Infrastructure** Chainlink SVR is built on the **Chainlink Decentralized Oracle Network (DON)** infrastructure that has already helped secure tens of billions in DeFi TVL and underpins existing Chainlink Data Feeds. ### [How SVR Works](https://docs.chain.link/data-feeds/svr-feeds\#how-svr-works) ![](https://docs.chain.link/images/data-feed/svr/svr-integration-flow.webp) 1. **Dual Transmission** - **(1a) Standard Feed (Public Route)**: The Chainlink Data DON (triggered by a heartbeat or deviation threshold) sends a price report to the **Standard Aggregator** via the public mempool—this is the traditional Chainlink flow. If anything goes wrong with the private route, the system can still rely on the standard aggregator's updates. - **(1b) SVR Feed (Private Route)**: Simultaneously, the Data DON sends the **same** price report to the **SVR Aggregator** through a private channel (e.g., Flashbots MEV-Share). This private route creates an **auction** for liquidations. 2. **MEV-Share Auction** - **(2) Liquidation Bid**: In the private channel, searchers see the incoming oracle report and bid to backrun the price update with a liquidation transaction. Builders select the highest bid, bundling that liquidation in the same block. If no bid is placed, the price update can still be published onchain without any bundled liquidation. If not, the fallback in the dual aggregator is triggered. 3. **SVR Update and Liquidation** - **(3a) SVR Price Report**: The winning bundle is published onchain, and the **SVR Feed** is updated with the new price. - **(3b) Liquidation Execution**: In the same block, the **backrunning** transaction can use the freshly updated price to liquidate the undercollateralized position. The oracle-related MEV can thereby be partly recaptured by the DeFi protocol and the Chainlink Network. 4. **Token Price Consumption** - **(4) DeFi Protocol**: The updated price from the **SVR Feed** is now available to the DeFi protocol (e.g., Aave) for accurate liquidation logic or other price-dependent actions. **Fail-Safe Fallback Mechanism** If the **private route** fails or times out, the SVR feed automatically **reverts** to the **Standard Feed price** after a configurable delay. This delay can be set to any amount of seconds. This helps ensures the feed doesn't stall and that price data is accessible through the public route if the private channel is unavailable. ## [How Protocols Can Utilize SVR Feeds](https://docs.chain.link/data-feeds/svr-feeds\#how-protocols-can-utilize-svr-feeds) ### [1\. Identify the SVR Feed Address](https://docs.chain.link/data-feeds/svr-feeds\#1-identify-the-svr-feed-address) To get started, please fill out [this form](https://chainlinkcommunity.typeform.com/svr-signup) to ensure protocol compatibility and proper recapture of OEV revenue. In many situations, you only need to point your protocol to an SVR version of the Chainlink Price Feed. To find the correct address for the asset pair you wish to secure with SVR, visit the [Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page and filter the feeds to display only SVR feeds. ### [2\. Read from the SVR Feed](https://docs.chain.link/data-feeds/svr-feeds\#2-read-from-the-svr-feed) In your smart contract, import and reference the **AggregatorV3Interface** just as you normally would, but **use the SVR aggregator's address**. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; contract SVRConsumer { AggregatorV3Interface internal svrFeed; constructor(address _svrFeedAddress) { svrFeed = AggregatorV3Interface(_svrFeedAddress); } function getLatestPrice() public view returns (int256) { ( , /* uint80 roundID */ int256 price /* uint256 startedAt */ /* uint256 timeStamp */ /* uint80 answeredInRound */, , , ) = svrFeed.latestRoundData(); return price; } } ``` This code sample is essentially the same as reading from a standard Chainlink Price Feed. For more details, see [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds). ## [Searcher Guide to Chainlink SVR](https://docs.chain.link/data-feeds/svr-feeds\#searcher-guide-to-chainlink-svr) This guide explains how to identify and bid on **Chainlink SVR** liquidation opportunities through **Flashbots MEV-Share**. SVR Feeds support a private transmission channel for oracle price updates, enabling searchers to backrun new prices with liquidation transactions and compete for profit. ### [Why Chainlink SVR?](https://docs.chain.link/data-feeds/svr-feeds\#why-chainlink-svr) Traditional MEV searching depends on spotting oracle price updates in the public mempool. With SVR, new price reports are shared in a private mempool via Flashbots MEV-Share. Searchers place bids to include liquidation transactions directly **after** the price update in the same block. The highest bidder gets included, capturing the liquidation bonus while sharing part of the winning bid with the DeFi protocol (e.g., Aave) and the Chainlink Network. ### [Example Application: Aave Liquidations](https://docs.chain.link/data-feeds/svr-feeds\#example-application-aave-liquidations) Aave is a lending protocol where collateralized positions must remain above a [threshold](https://aave.com/docs/concepts/liquidations) called their health factor. When an oracle price update reveals a borrower is undercollateralized, the position becomes eligible for liquidation. The searcher liquidates the position in exchange for a liquidation bonus reward. With Chainlink SVR, a searcher's liquidation transaction can be bundled with the new SVR price update through Flashbots. For more background on how Aave liquidations work, see [Aave Documentation](https://docs.aave.com/). To understand how Chainlink SVR adds a structured auction for these Aave liquidation opportunities, read the following sections. ### [Price Update, Auction, and Liquidation Execution Flow](https://docs.chain.link/data-feeds/svr-feeds\#price-update-auction-and-liquidation-execution-flow) ![](https://docs.chain.link/images/data-feed/svr/svr-price-update-auction-liquidation-flow.webp) ### [How to Participate as a Searcher](https://docs.chain.link/data-feeds/svr-feeds\#how-to-participate-as-a-searcher) #### [1\. High-Level Steps for Searchers](https://docs.chain.link/data-feeds/svr-feeds\#1-high-level-steps-for-searchers) 1. **Monitor and Identify SVR Price Updates**: Chainlink SVR sends oracle reports through Flashbots Protect (MEV-Share). Your searcher node must watch private transactions, not just the public mempool. It must also filter by these SVR data feed update events, and determine which feed address the update is for. 2. **Bundle and Bid** - Detect an eligible liquidation (e.g., an undercollateralized Aave position) triggered by the new price update. - Submit your liquidation transaction **in the same bundle** as the price update, placing a bid to entice block builders. 3. **Execute Liquidation**: If your bundle is selected, your liquidation happens **immediately after** the fresh price arrives onchain, capturing the liquidation bonus. Based on the results of the auction, a portion of the MEV is recaptured and split between Aave and the Chainlink Network, while the rest goes to you. #### [2\. Listen for Events on MEV Share](https://docs.chain.link/data-feeds/svr-feeds\#2-listen-for-events-on-mev-share) Chainlink SVR uses forwarder contracts to route feed updates. You typically see **one transaction per event**, which calls the function `forward(address to, bytes callData)` with the function selector `6fadcf72`. This method, in turn, calls the SVR aggregator's `transmitSecondary()` function with the new price data. 1. **Forwarder Contracts**: Each Node Operator Proxy has a unique forwarder contract. That means that feed update transactions may come from different forwarder addresses depending on which proxy sends the transaction. 2. **Function Selector**: In the transaction's `txs` array, look for the selector `6fadcf72` ( `forward(...)`). 3. **callData**: The `callData` includes the parameters for `transmitSecondary()` on the aggregator contract. You can decode this if you need to extract the updated price when the onchain event is not emitted (details in the section below). Below are code examples for setting up a listener that monitors the MEV-Share event stream for SVR feed updates. These examples show how to connect to the stream, filter for relevant transactions with the `6fadcf72` function selector, and process incoming events: TSGo ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```typescript import MevShareClient, { IPendingBundle, IPendingTransaction } from "@flashbots/mev-share-client" const mevShareClient = MevShareClient.useEthereumMainnet(authSigner) const txHandler = mevShareClient.on("transaction", async (tx: IPendingTransaction) => { if (tx.functionSelector === "6fadc72") { // Do something with the pending tx here. } }) // call before your program terminates: txHandler.close() bundleHandler.close() ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```go import "github.com/flashbots/mev-share-node/mevshare" req, err := http.NewRequestWithContext( ctx, "GET", "https://mev-share.flashbots.net", nil, ) // ... read the event data from the response var event mevshare.Hint err := json.Unmarshal(responseData, &event) // ... check if tx is calling the forward method if strings.Compare( strings.ToLower(tx.FunctionSelector.String()), "0x6fadcf72", ) != 0 { continue } ``` #### [3\. Decode `callData` for `forward` and `transmitSecondary`](https://docs.chain.link/data-feeds/svr-feeds\#3-decode-calldata-for-forward-and-transmitsecondary) Once you've identified a potential SVR feed update transaction, you'll need to decode its payload. This step allows you to extract: - The **feed address**: This is required to determine which SVR data feed is being updated. - The **new price data**: This is essential for determining if profitable liquidation opportunities exist. The decoding process involves understanding two function calls: 1. First, the transaction calls the `forward` function: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity forward(address to, bytes callData) ``` 2. Inside the `callData` parameter is the encoded call to `transmitSecondary`, which contains the actual price data: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity transmitSecondary( bytes32[3] calldata reportContext, bytes calldata report, bytes32[] calldata rs, bytes32[] calldata ss, bytes32 rawVs ) ``` The structure of `report` is: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity struct Report { uint32 observationsTimestamp; bytes32 observers; int192[] observations; int192 juelsPerFeeCoin; } ``` Below is an example of an ABI definition for the `forward` and `transmitSecondary` function interfaces to help you decode the function calls: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity [\ {\ "type": "function",\ "name": "forward",\ "inputs": [\ { "name": "to", "type": "address" },\ { "name": "callData", "type": "bytes" }\ ],\ "outputs": [],\ "stateMutability": "nonpayable"\ },\ {\ "type": "function",\ "name": "transmitSecondary",\ "inputs": [\ { "name": "reportContext", "type": "bytes32[3]", "internalType": "bytes32[3]" },\ { "name": "report", "type": "bytes", "internalType": "bytes" },\ { "name": "rs", "type": "bytes32[]", "internalType": "bytes32[]" },\ { "name": "ss", "type": "bytes32[]", "internalType": "bytes32[]" },\ { "name": "rawVs", "type": "bytes32", "internalType": "bytes32" }\ ],\ "outputs": [],\ "stateMutability": "nonpayable"\ }\ ] ``` The following code samples demonstrate the complete decoding process, including extracting the median price from the nested report structure. These implementations show how to: 1. Decode the `forward` function call 2. Extract and decode the `transmitSecondary` function data 3. Parse the report bytes using the `Report` struct 4. Access the median observation (the updated price) TSGo ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```typescript const decodeInterface = new ethers.Interface(EXAMPLE_ABI) function decodeForwarderCall(callData: string) { const decodedForward = decodeInterface.decodeFunctionData("forward", callData) return { to: decodedForward[0], callData: decodedForward[1] } } function decodeTransmitSecondary(callData: string) { try { const decodedTransmitSecondary = decodeInterface.decodeFunctionData("transmitSecondary", callData) return { report: decodedTransmitSecondary[1] } } catch (error) { console.error("not transmit secondary call", error) return {} } } function decodeReport(reportRaw: string) { const decodedReport = ethers.AbiCoder.defaultAbiCoder().decode(["uint32", "bytes32", "int192[]", "int192"], reportRaw) return { observations: decodedReport[2] } } function updatedPrice(observations: bigint[]) { const medianObservation = observations[Math.floor(observations.length / 2)] return medianObservation } async function processTransaction(pendingTx: IPendingTransaction) { if (pendingTx.functionSelector !== CHAINLINK_PRICE_FEED_FUNCTION_SELECTOR) { return null } const { to, callData } = decodeForwarderCall(pendingTx.callData) const { report } = decodeTransmitSecondary(callData) if (report) { const { observations } = decodeReport(report) const newPrice = updatedPrice(observations) } // calculate health factors for affected users ... } ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```go decoded, err := hex.DecodeString(strings.TrimPrefix(strings.ToLower(tx.CallData.String()), "0x")) contractAddress := "0x" + strings.ToLower(strings.TrimLeft(hex.EncodeToString(decoded[4:36]), "0")) ff := strings.ToLower(strings.TrimLeft(hex.EncodeToString(decoded[100:104]), "0")) if strings.Compare(ff, "ba0cb29e") != 0 { return nil, fmt.Errorf("event doesn't invoke svr method: ba0cb29e, instead: %s", ff) } transmitSecondaryElems := make(map[string]interface{}) err := getTransmissionTypes().UnpackIntoMap(transmitSecondaryElems, decoded[104:]) report, exists := transmitSecondaryElems["report"] return MedianFromReport(report.([]byte)) func MedianFromReport(report []byte) (*big.Int, error) { reportElems := map[string]interface{}{} err := getReportTypes().UnpackIntoMap(reportElems, report) observationsIface, ok := reportElems["observations"] observations, ok := observationsIface.([]*big.Int) median := observations[len(observations)/2] return median, nil } func getReportTypes() abi.Arguments { return abi.Arguments([]abi.Argument{ {Name: "observationsTimestamp", Type: mustNewType("uint32")}, {Name: "rawObservers", Type: mustNewType("bytes32")}, {Name: "observations", Type: mustNewType("int192[]")}, {Name: "juelsPerFeeCoin", Type: mustNewType("int192")}, }) } func getTransmissionTypes() abi.Arguments { return abi.Arguments([]abi.Argument{ {Name: "reportContext", Type: mustNewType("bytes32[3]")}, {Name: "report", Type: mustNewType("bytes")}, {Name: "rs", Type: mustNewType("bytes32[]")}, {Name: "ss", Type: mustNewType("bytes32[]")}, {Name: "rawVs", Type: mustNewType("bytes32")}, }) } func mustNewType(t string) abi.Type { result, err := abi.NewType(t, "", nil) return result } ``` #### [4\. Detect SVR-enabled Feeds for the Aave Protocol](https://docs.chain.link/data-feeds/svr-feeds\#4-detect-svr-enabled-feeds-for-the-aave-protocol) When processing forward calls, verify that the `to` address from the code sample above (the destination of the forward call) matches one of these feed addresses. This tells you which SVR data feed the price update is for: | Feed name | Address | | --- | --- | | AAVE/USD | `0xcd07B31D85756098334eDdC92DE755dEae8FE62f`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | BTC/USD | `0xdc715c751f1cc129A6b47fEDC87D9918a4580502`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | | LINK/USD | `0x64c67984A458513C6BAb23a815916B1b1075cf3a`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) | #### [5\. Calculate Updated Price](https://docs.chain.link/data-feeds/svr-feeds\#5-calculate-updated-price) After successfully decoding the transaction data, you need to extract the median price from the `observations` array inside the decoded `report`: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity report.observations[report.observations.length / 2] ``` This formula retrieves the median value from the sorted array of price observations. The middle element represents the median price. This price is the value committed to the blockchain that protocols will use for determining liquidation eligibility. To use this price effectively, convert it to the appropriate decimal representation for the asset pair. #### [6\. Bidding With Flashbots MEV-Share](https://docs.chain.link/data-feeds/svr-feeds\#6-bidding-with-flashbots-mev-share) Once you've detected an SVR update and identified a profitable liquidation opportunity, you need to construct and submit a bundle to Flashbots. Consider these key aspects when preparing your submission: - **Bundle Components**: Your bundle must contain two elements in this exact order: 1. The original oracle update transaction (referenced by its hash) 2. Your liquidation transaction (fully signed transaction bytes) - **Backrun Position**: MEV-Share only permits backruns, meaning your liquidation transaction must come after the target transaction. This order is enforced by the bundle structure. - **Bidding Strategy**: Block builders typically select the highest-paying bundle. Your bid must be competitive while leaving room for profit. The bundle's economic value comes from: - The gas price of your transaction - Any explicit payment you include to the builder - **Inclusion Parameters**: Specify the target block range for your bundle to be considered - Typically target the next block plus a small range for redundancy - A narrow block range can increase chances of inclusion but risks missing execution - **Authentication**: All Flashbots bundles require cryptographic signing with your wallet Below are code examples demonstrating how to construct and submit bundles to the Flashbots relay: TSGo ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```typescript async function sendBackrunBundle(pendingTx: IPendingTransaction) { const currentBlock = await provider.getBlockNumber() const signedBackrunTx = await buildDummyBackrunTx(pendingTx) const bundleParams: BundleParams = { inclusion: { block: currentBlock + 1, maxBlock: currentBlock + TARGET_BUNDLE_BLOCK_DELAY, }, body: [{ hash: pendingTx.hash }, { tx: signedBackrunTx, canRevert: false }], } const sendBundleResult = await mevShareClient.sendBundle(bundleParams) return sendBundleResult } async function buildDummyBackrunTx(pendingTx: IPendingTransaction) { const backrunTx = { data: {}, maxFeePerGas: 22000, maxPriorityFeePerGas: 22000 } const signedBackrunTx = await executorWallet.signTransaction(backrunTx) return signedBackrunTx } ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```go import "github.com/flashbots/mev-share-node/mevshare" // ... create and sign your transaction tx := types.NewTransaction(...) signedTx, err := types.SignTx(tx, ...) txBytes := signedTx.MarshalBinary() bundle := []mevshare.MevBundleBody { { Hash: &event.EventHash, }, { Tx: &txBytes, CanRevert: false, }, } params := mevshare.SendMevBundleArgs { Body: bundle, Inclusion: mevshare.MevBundleInclusion{blockNumber, blockNumber+1}, } byteParams, err := json.Marshal(params) body := []byte(fmt.Sprintf(`{"jsonrpc":"2.0","method":"mev_sendBundle","params":["%s"], "id":1}`, string(byteParams))) bodyReader := bytes.NewReader(body) postReq, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://relay.flashbots.net/", bodyReader) hashedBody := crypto.Keccak256Hash(body).Hex() signedMessage, err := crypto.Sign(accounts.TextHash([]byte(hashedBody)), privKey) postReq.Header.Add("X-Flashbots-signature", address.String()+":"+hexutil.Encode(signedMessage)) resp, err := http.DefaultClient.Do(postReq) ``` For gas management, simulations, and other advanced usage, see the official [Flashbots documentation](https://docs.flashbots.net/). #### [7\. Considerations](https://docs.chain.link/data-feeds/svr-feeds\#7-considerations) - **Competition**: Multiple searchers might detect the same liquidation. The best bid typically wins. - **Profit-Sharing**: A portion of liquidation MEV is recaptured and redirected to the integrating DeFi protocol and the Chainlink Network. - **Gas Efficiency**: Bundles that are too costly might erode the profitability of the proposed transaction. Optimize carefully. - **Non-SVR `forward` calls**: There are other events on the MEV-Share event stream that have the same `forward` function signature. Be sure to filter for the ones that call `transmitSecondary` on the listed SVR feeds. #### [8\. Next Steps for Searchers](https://docs.chain.link/data-feeds/svr-feeds\#8-next-steps-for-searchers) 1. **Set Up Your Searcher Node** - Integrate with [Flashbots MEV-Share](https://docs.flashbots.net/) to read private transactions. - Filter for calls matching function selector `6fadcf72` directed at the correct contract address. 2. **Test Your Bundles** - Construct atomic bundles combining the price update and your liquidation transaction. - Try local simulations or testnet deployments where available. 3. **Stay Updated** - Keep track of any updates to the SVR aggregator address, function signatures, or Flashbots MEV-Share changes. - Monitor for changes in Aave liquidation parameters (e.g., new assets, different collateral thresholds). ## [Economics and Revenue Split](https://docs.chain.link/data-feeds/svr-feeds\#economics-and-revenue-split) When a protocol integrates Chainlink SVR Feeds, the recaptured oracle-related MEV is split between the integrating DeFi protocol and the Chainlink Network. This split provides DeFi protocols with an additional revenue stream while also supporting the economic sustainability of Chainlink oracles. Note that the split may be subject to change, with the goal of generating sustainable economics between DeFi protocols and the oracles that power them. ## [Risk and Disclaimers](https://docs.chain.link/data-feeds/svr-feeds\#risk-and-disclaimers) - **Delay Risks**: SVR introduces a small, configurable delay to allow for the MEV-Share auction. In the unlikely event of a private-route failure, the dual aggregator reverts to the standard feed price update after a delay. To learn more about delay risks, and how you can parameterize your protocol to account for them, refer to [this research blog](https://blog.chain.link/chainlink-svr-analysis/). - **Liquidation Competition**: Multiple liquidations triggered by the same price update compete for blockspace. SVR is agnostic to which liquidator wins. SVR maximizes for the highest payment, and thus the highest recapture rate, on the auction. - **MEV Does Not Disappear**: SVR recaptures only the oracle-related portion of MEV. Protocol builders should remain MEV-aware when designing their applications. - **Dynamic Recapture Rates**: SVR aims to recapture as high a portion of oracle-update-related MEV as possible. Actual results depend on market conditions, competition among searchers, and factors such as protocol design. ## What's next - [\> Learn how to read answers from Data Feeds](https://docs.chain.link/data-feeds/price-feeds) - [\> Find contract addresses for Price Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863112&cv=11&fst=1747083863112&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103101750~103101752~103116025~103200001~103233427~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509157~103101750~103101752~103116026~103200004~103233427~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fsvr-feeds&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Smart%20Value%20Recapture%20(SVR)%20Feeds%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1316532171.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Data Feeds Guide [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using Data Feeds on EVM Chains](https://docs.chain.link/data-feeds/using-data-feeds\#overview) The code for reading Data Feeds is the same across all EVM-compatible blockchains and Data Feed types. You choose different types of feeds for different uses, but the request and response format are the same. To read a feed, specify the following variables: - **RPC endpoint URL:** This determines which network that your smart contracts will run on. You can use a [node provider service](https://ethereum.org/en/developers/docs/nodes-and-clients/nodes-as-a-service/) or point to your own [client](https://ethereum.org/en/developers/docs/nodes-and-clients/). If you are using a Web3 wallet, it is already configured with the RPC endpoints for several networks and the [Remix IDE](https://remix-project.org/) will automatically detect them for you. - **LINK token contract address:** The address for the LINK token contract is different for each network. You can find the full list of addresses for all supported networks on the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. - **Feed contract address:** This determines which data feed your smart contract will read. Contract addresses are different for each network. You can find the available contract addresses on the following pages: - [Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) The examples in this document indicate these variables, but you can modify the examples to work on different networks and read different feeds. This guide shows example code that reads data feeds using the following languages: - Onchain consumer contracts: - [Solidity](https://docs.chain.link/data-feeds/using-data-feeds#solidity) - [Vyper](https://docs.chain.link/data-feeds/using-data-feeds#vyper) - Offchain reads using Web3 packages: - [Javascript](https://docs.chain.link/data-feeds/using-data-feeds#javascript) with [web3.js](https://web3js.readthedocs.io/) - [Python](https://docs.chain.link/data-feeds/using-data-feeds#python) with [Web3.py](https://web3py.readthedocs.io/en/stable/) - [Golang](https://docs.chain.link/data-feeds/using-data-feeds#golang) with [go-ethereum](https://github.com/ethereum/go-ethereum) ## [Reading data feeds onchain](https://docs.chain.link/data-feeds/using-data-feeds\#reading-data-feeds-onchain) These code examples demonstrate how to deploy a consumer contract onchain that reads a data feed and stores the value. ### [Solidity](https://docs.chain.link/data-feeds/using-data-feeds\#solidity) To consume price data, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED * VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ /** * If you are reading data feeds on L2 networks, you must * check the latest answer from the L2 Sequencer Uptime * Feed to ensure that the data is accurate in the event * of an L2 sequencer outage. See the * https://docs.chain.link/data-feeds/l2-sequencer-feeds * page for details. */ contract DataConsumerV3 { AggregatorV3Interface internal dataFeed; /** * Network: Sepolia * Aggregator: BTC/USD * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 */ constructor() { dataFeed = AggregatorV3Interface( 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 ); } /** * Returns the latest answer. */ function getChainlinkDataFeedLatestAnswer() public view returns (int) { // prettier-ignore ( /* uint80 roundId */, int256 answer, /*uint256 startedAt*/, /*uint256 updatedAt*/, /*uint80 answeredInRound*/ ) = dataFeed.latestRoundData(); return answer; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerV3.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) The `latestRoundData` function returns five values representing information about the latest price data. See the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) for more details. ### [Vyper](https://docs.chain.link/data-feeds/using-data-feeds\#vyper) To consume price data, your smart contract should import `AggregatorV3Interface` which defines the external functions implemented by Data Feeds. You can find it [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/interfaces/AggregatorV3Interface.vy). You can find a `PriceConsumer` example [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/PriceConsumer.vy). Read the _**apeworx-starter-kit**_ [README](https://github.com/smartcontractkit/apeworx-starter-kit) to learn how to run the example. ## [Reading data feeds offchain](https://docs.chain.link/data-feeds/using-data-feeds\#reading-data-feeds-offchain) These code examples demonstrate how to read data feeds directly off chain using Web3 packages for each language. ### [Javascript](https://docs.chain.link/data-feeds/using-data-feeds\#javascript) This example uses [web3.js](https://web3js.readthedocs.io/) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. web3.jsethers.js ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const Web3 = require("web3") // for nodejs only const web3 = new Web3("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const priceFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr) priceFeed.methods .latestRoundData() .call() .then((roundData) => { // Do something with roundData console.log("Latest Round Data", roundData) }) ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const { ethers } = require("ethers") // for nodejs only const provider = new ethers.providers.JsonRpcProvider("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const priceFeed = new ethers.Contract(addr, aggregatorV3InterfaceABI, provider) priceFeed.latestRoundData().then((roundData) => { // Do something with roundData console.log("Latest Round Data", roundData) }) ``` Latest Price: Latest Price ### [Python](https://docs.chain.link/data-feeds/using-data-feeds\#python) This example uses [Web3.py](https://web3py.readthedocs.io/en/stable/) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity # THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. # THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. # DO NOT USE THIS CODE IN PRODUCTION. from web3 import Web3 # Change this to use your own RPC URL web3 = Web3(Web3.HTTPProvider('https://rpc.ankr.com/eth_sepolia')) # AggregatorV3Interface ABI abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]' # Price Feed address addr = '0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43' # Set up contract instance contract = web3.eth.contract(address=addr, abi=abi) # Make call to latestRoundData() latestData = contract.functions.latestRoundData().call() print(latestData) ``` ### [Golang](https://docs.chain.link/data-feeds/using-data-feeds\#golang) You can find an example with all the source files [here](https://github.com/smartcontractkit/smart-contract-examples/tree/main/pricefeed-golang). This example uses [go-ethereum](https://github.com/ethereum/go-ethereum) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. To learn how to run the example, see the [README](https://github.com/smartcontractkit/smart-contract-examples/blob/main/pricefeed-golang/README.md). ## [Getting a different price denomination](https://docs.chain.link/data-feeds/using-data-feeds\#getting-a-different-price-denomination) Chainlink Data Feeds can be used in combination to derive denominated price pairs in other currencies. If you require a denomination other than what is provided, you can use two data feeds to derive the pair that you need. For example, if you needed a BTC / EUR price, you could take the BTC / USD feed and the EUR / USD feed and derive BTC / EUR using division. ![Request Model Diagram](https://docs.chain.link/images/price-feed-conversion-equation.gif) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * Network: Sepolia * Base: BTC/USD * Base Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 * Quote: EUR/USD * Quote Address: 0x1a81afB8146aeFfCFc5E50e8479e826E7D55b910 * Decimals: 8 */ /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract PriceConverter { function getDerivedPrice( address _base, address _quote, uint8 _decimals ) public view returns (int256) { require( _decimals > uint8(0) && _decimals <= uint8(18), "Invalid _decimals" ); int256 decimals = int256(10 ** uint256(_decimals)); (, int256 basePrice, , , ) = AggregatorV3Interface(_base) .latestRoundData(); uint8 baseDecimals = AggregatorV3Interface(_base).decimals(); basePrice = scalePrice(basePrice, baseDecimals, _decimals); (, int256 quotePrice, , , ) = AggregatorV3Interface(_quote) .latestRoundData(); uint8 quoteDecimals = AggregatorV3Interface(_quote).decimals(); quotePrice = scalePrice(quotePrice, quoteDecimals, _decimals); return (basePrice * decimals) / quotePrice; } function scalePrice( int256 _price, uint8 _priceDecimals, uint8 _decimals ) internal pure returns (int256) { if (_priceDecimals < _decimals) { return _price * int256(10 ** uint256(_decimals - _priceDecimals)); } else if (_priceDecimals > _decimals) { return _price / int256(10 ** uint256(_priceDecimals - _decimals)); } return _price; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/PriceConverter.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## [More aggregator functions](https://docs.chain.link/data-feeds/using-data-feeds\#more-aggregator-functions) Getting the latest price is not the only data that aggregators can retrieve. You can also retrieve historical price data. To learn more, see the [Historical Price Data](https://docs.chain.link/data-feeds/historical-data) page. To understand different use cases for Chainlink Price Feeds, refer to [Other Tutorials](https://docs.chain.link/getting-started/other-tutorials). ## What's next - [\> Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863124&cv=11&fst=1747083863124&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5591h2v891173849z8847174275za200zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116025~103200001~103207802~103233424~103251618~103251620~103263073~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116026~103130498~103130500~103200004~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fusing-data-feeds&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Using%20Data%20Feeds%20on%20EVM%20Chains%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1776517066.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&ec_mode=a&fledge=1&capi=1&_tu=Cg&em=tv.1&ct_cookie_present=0) ## Selecting Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#overview) When you design your applications, consider the quality of the data that you use in your smart contracts. Ultimately you are responsible for identifying and assessing the accuracy, availability, and quality of data that you choose to consume via the Chainlink Network. Note that all feeds contain some inherent risk. Read the [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) and [Evaluating Data Sources](https://docs.chain.link/data-feeds/selecting-data-feeds#evaluating-data-sources-and-risks) sections when making design decisions. Chainlink lists decentralized data feeds in the documentation to help developers build new applications integrated with data. ## [Data Feed Categories](https://docs.chain.link/data-feeds/selecting-data-feeds\#data-feed-categories) This categorization is put in place to inform users about the intended use cases of feeds and help highlight some of the inherent market integrity risks surrounding the data quality of these feeds. All feeds published on [docs.chain.link](http://docs.chain.link/) are monitored and maintained to the same levels and standards. Each feed goes through a rigorous assessment process when implemented. The assessment criteria can vary depending on the product type of feed being deployed or change over time as the understanding of market integrity risks evolves. Market price feeds incorporate three layers of aggregation at the data source, node operator, and oracle network layers, providing industry-standard security and reliability on the price data they reference. To learn more about the three layers of data aggregation, see the blog post about [Data Aggregation in Chainlink Price Feeds](https://blog.chain.link/levels-of-data-aggregation-in-chainlink-price-feeds/). Additional information about how Chainlink Data Feeds are secured can be seen in the blog post about [How Chainlink Price Feeds Secure the DeFi Ecosystem](https://blog.chain.link/chainlink-price-feeds-secure-defi/). Data feeds are grouped into the following categories based on the level of market integrity risk from lowest to highest: - [🟢 Low Market Risk](https://docs.chain.link/data-feeds/selecting-data-feeds#-low-market-risk-feeds) - [🟡 Medium Market Risk](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds) - [🔴 High Market Risk](https://docs.chain.link/data-feeds/selecting-data-feeds#-high-market-risk-feeds) - [🟠 New Token Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#-new-token-feeds) - [🔵 Custom Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#-custom-feeds) - [⭕ Deprecating](https://docs.chain.link/data-feeds/selecting-data-feeds#-deprecating) ### [🟢 Low Market Risk Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#-low-market-risk-feeds) These are data feeds that follow a standardized data feeds workflow to report market prices for an asset pair. Chainlink node operators each query several sources for the market price and aggregate the estimates provided by those sources. Low Market Risk feeds have the following characteristics: - Highly resilient to disruption - Leverage many data sources - High volumes across a large number of markets enable consistent price discovery While market risk may be low, other risks might still exist based on your use case, the blockchain on which the feed is deployed, and the conditions on that chain. ### [🟡 Medium Market Risk Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#-medium-market-risk-feeds) These feeds also follow a standardized data feeds workflow to report market prices for an asset pair. The pair in question may have features that make it more challenging to reliably price, or potentially subject it to volatility which may pose a risk in some use cases. While the architecture of these feeds is resilient and distributed, these feeds carry additional market risk. Types of market risk that may lead to a feed being categorized as Medium Market Risk include: - Lower or inconsistent asset volume may result in periods of low liquidity in the market for such assets. This, in turn, can lead to volatile price movements - A spread between the price for this asset on different trading venues or liquidity pools. - Market Concentration Risk: If the volume for a given asset is excessively concentrated on a single exchange, that trading venue could become a single point of failure for the feed. - Cross-Rate Risk: The base asset trades in large volumes against assets that are not pegged to the quote asset. As a result, the price of this specific asset pair may fluctuate even if the underlying asset is not being traded. - The asset is going through a significant market event such as a token or liquidity migration. - The asset has a high spread between data providers, the root cause of which is often one of the above factors. ### [🔴 High Market Risk Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#-high-market-risk-feeds) These feeds also follow a standardized data feeds workflow to report market prices for an asset pair. However, the pair in question often exhibits a heightened degree of some of the risk factors outlined under “Medium Market Risk”, or a separate risk that makes the market price subject to uncertainty or volatility. In using a High Market Risk data feed you acknowledge that you understand the risks associated with such a feed and that you are solely responsible for monitoring and mitigating such risks. Types of market risk that may lead to a feed being categorized as High Market Risk include: - The asset is going through a significant market event such as a hack, bridge failure, or a delisting from a major exchange. - The asset or project is being deprecated in the market. - Volumes have dropped to extremely low levels. ### [🟠 New Token Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#-new-token-feeds) When a token is newly launched, the historical data required to implement a rigorous risk assessment framework that would allow the categorization of a market data feed for that token as low, medium, or high market risk is unavailable. Consistent price discovery may involve an indeterminate amount of time. Users must understand the additional [market and volatility risks](https://docs.chain.link/data-feeds/selecting-data-feeds#evaluating-data-sources-and-risks) inherent with such assets. Users of new token feeds are responsible for independently verifying the liquidity and stability of the assets priced by the feeds that they use. At the end of a probationary period, the status of new token feeds may be adjusted to high/medium/low market risk or in rare cases be deprecated entirely. ### [🔵 Custom Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#-custom-feeds) Custom Feeds are built to serve a specific use case and might not be suitable for general use or your use case's risk parameters. Users must evaluate the properties of a feed to make sure it aligns with their intended use case. [Contact the Chainlink Labs team](https://chain.link/contact?ref_id=DataFeed) if you want more detail on any specific feeds in this category. Custom feeds have the following categories and compositions: - Onchain single source feeds: These feeds take their data from an onchain source, however, the feed has only a single data provider currently supporting the feed. - Onchain Proof of Reserve Feeds: Chainlink Proof of Reserve uses a large decentralized collection of security-reviewed and Sybil-resistant node operators to acquire and verify reserve data. In this use case, reserves reside onchain. - Exchange Rate Feeds: These feeds read an exchange rate from an external contract onchain that is designed to allow conversion from one token to another. Chainlink does not own or control these contracts in any way. They are not equivalent to market price feeds. - Technical Feeds: Feeds within this category measure a particular technical metric from a specified blockchain. For example, Fast Gas or Block Difficulty. - Total Value Locked Feeds: These feeds measure the total value locked in a particular protocol. - Custom Index Feeds: An index calculates a function of the values for multiple underlying assets. The function is specific to that index and is typically calculated by node operators following an agreed formula. - Offchain Single Source Feeds: Some data providers use a single data source, which might be necessary if only one source exists offchain for a specific type of data. - Offchain Proof of Reserve Feeds: Chainlink Proof of Reserve uses a large decentralized collection of security-reviewed and Sybil-resistant node operators to acquire and verify reserve data. In this use case, reserves reside offchain. - LP Token Feeds: These feeds use a decentralized feed for the underlying asset as well as calculations to value the liquidity pool (LP) tokens. - Wrapped Calculated Feeds: These feeds are typically pegged 1:1 to the underlying token or asset. Under normal market conditions, these feeds track their underlying value accurately. However, given that the price is a derivative formed from a calculated method, the derivative asset may not always precisely track the value of the underlying token or asset precisely. If you plan on using one of these feeds and would like to get a more detailed understanding, [contact the Chainlink Labs team](https://chain.link/contact?ref_id=DataFeed). ### [⭕ Deprecating](https://docs.chain.link/data-feeds/selecting-data-feeds\#-deprecating) These feeds are being deprecated. To find the deprecation dates for specific feeds, see the [Feeds Scheduled For Deprecation](https://docs.chain.link/data-feeds/deprecating-feeds) page. #### [Data Feed Shutdown Policy](https://docs.chain.link/data-feeds/selecting-data-feeds\#data-feed-shutdown-policy) Data feeds managed by Chainlink Labs will be considered for deprecation if they pose a risk to the Chainlink Community and broader ecosystem, if the asset or assets on the feed have significantly deteriorated and no longer meet our Quality Assurance standards, or if the data feed has become economically unsustainable to support. Known users of these feeds will be contacted directly about the feeds' deprecation. Notifications will also be posted on the [Feeds Scheduled For Deprecation](https://docs.chain.link/data-feeds/deprecating-feeds) page and on our [Discord channel](https://discord.com/channels/592041321326182401/991444378335838318) with two weeks of notice before they are shut down. ## [Market hours](https://docs.chain.link/data-feeds/selecting-data-feeds\#market-hours) In addition to categories, be aware that markets for several assets are actively traded only during certain hours. Listed data feeds include an attribute describing their market hours. Chainlink Labs recommends using these feeds only during their specified hours: | Feed | Hours | | --- | --- | | **Crypto** | 24/7/365 - No market close. | | **US\_Equities** | Standard US equity market hours: 09:30 - 16:00 ET M-F excluding US equity market holidays. | | **UK\_ETF** | Standard UK equity market hours: 08:00 - 16:30 UK time M-F excluding UK equity market holidays. | | **Forex** | 18:00 ET Sunday to 17:00 ET Friday.
The feeds also follow the global Forex market Christmas and New Year's Day holiday schedule. Many non-G12 currencies primarily trade during local market hours. It is recommended to use those feeds only during local trading hours. | | **Precious\_Metals** | 18:00 ET Sunday to 17:00 ET Friday with a one-hour break Monday through Thursday from 17:00 to 18:00.
The feeds also follow the global Forex market holiday schedule for Christmas and New Year's Day. | | **NYMEX** (US OIL) | 18:00 ET Sunday to 17:00 ET Friday, with a one-hour break Monday through Thursday from 17:00 to 18:00.
The feed also follows the NYMEX market holiday schedule. | | **COMEX** (Non precious metals) | 18:00 ET Sunday to 17:00 ET Friday with a one-hour break Monday through Thursday from 17:00 to 18:00.
The feed also follows the COMEX market holiday schedule. | | **CBOT** (Agricultural) | Monday - Thursday 00:00-08:45, 09:30-00:00 and Friday 00:00-08:45, 09:30-14:00 ET, excluding CBOT market holidays. | | **MI\_ETF** | Standard Milan equity market hours. 09:00-17:30 CET time M-F, excluding Milan equity market holidays. | | **XETRA\_ETF** | Deutsche Börse Xetra equity market hours. 09:00-17:30 CET time M-F, excluding Xetra equity market holidays. | ## [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds\#risk-mitigation) As a development best practice, design your systems and smart contracts to be resilient and mitigate risk to your protocol and your users. Ensure that your systems can tolerate known and unknown exceptions that might occur. Some examples include but are not limited to volatile market conditions, the degraded performance of infrastructure, chains, or networks, and any other upstream outage related to data providers or node operators. You bear responsibility for any manner in which you use the Chainlink Network, its software, and documentation. To help you prepare for unforeseen market events, you should take additional steps to protect your application or protocol regardless of the market risk categorization of the Data Feeds your application consumes. The below tooling is put in place to mitigate extreme market events, possible malicious activity on third-party venues or contracts, potential delays, performance degradation, and outages. Below are some examples of tooling that Chainlink users have put in place: - **Circuit breakers:** In the case of an extreme price event, the contract would pause operations for a limited period of time. [Chainlink Automation](https://docs.chain.link/chainlink-automation) is able to monitor data feeds to identify unexpected events. If an event were to occur, the Automation network can send an onchain transaction to pause or halt contract functionality. - **Contract update delays:** Contracts would not update until the protocol had received a recent fresh input from the data feed. - **Manual kill switch:** If a vulnerability or bug is discovered in one of the upstream contracts, the user can manually cease operation and temporarily sever the connection to the data feed. - **Monitoring:** Some users create their own monitoring alerts based on deviations in the data feeds that they are using. - **Soak testing:** Users are strongly advised to thoroughly test price feed integrations and incorporate a [soak period](https://en.wikipedia.org/wiki/Soak_testing) prior to providing access to end users or securing value. For more detailed information about some of these examples, see the [Monitoring data feeds](https://docs.chain.link/data-feeds/#monitoring-data-feeds) documentation. For important updates regarding the use of Chainlink Price Feeds, users should join the official Chainlink Discord and subscribe to the [data-feeds-user-notifications channel](https://discord.gg/Dqy5N9UbsR). ## [Chainlink Community Deployments](https://docs.chain.link/data-feeds/selecting-data-feeds\#chainlink-community-deployments) Chainlink technology is used by many within the blockchain community to support their use cases. Deployments built and run by community members are not tracked in the Chainlink documentation. Chainlink's community is continuously growing, and they play a vital role in developing the ecosystem, so the software and tooling are developed for anyone to use. Users have a wide variety of options for choosing how to deliver data onchain. They can deploy Chainlink nodes themselves or via the extensive network of node operators that offer services and access one of the community-managed oracle networks that support the supply of various types of data onchain. Chainlink Labs does not take responsibility for the use of Chainlink node software. It is always recommended that you conduct a thorough analysis of your requirements and carry out appropriate due diligence on any partners you wish to use with your project. The Chainlink Labs team does not monitor community deployments and users should use best practices in observability, monitoring, and risk mitigation as appropriate for your application's stage of development and use case. As your usage of data feeds evolves and requirements for higher availability and greater security increases, such as securing substantive value, the reliability properties of your data feed will become crucial. [Contact Chainlink Labs team](https://chain.link/contact?ref_id=DataFeed) for services to ensure deployments meet the highest levels of availability and security. **High Risk: Forked, modified, or custom software:** As Chainlink is open source, independent forks and modifications may exist. Chainlink Labs and development teams are not involved in these and do not track or maintain visibility on them. Chainlink Labs is not responsible for updates, enhancements, or bug fixes for these versions, and Chainlink Labs does not monitor them. Their use might pose risks that can do harm to your project. Users are responsible for thoroughly vetting and validating such deployments and determining their suitability. ## [Evaluating Data Sources and Risks](https://docs.chain.link/data-feeds/selecting-data-feeds\#evaluating-data-sources-and-risks) If your smart contracts use data feeds, assess those data feeds for the following characteristics: - [Liquidity and its Distribution](https://docs.chain.link/data-feeds/selecting-data-feeds#liquidity-and-its-distribution) - [Single Source Data Providers](https://docs.chain.link/data-feeds/selecting-data-feeds#single-source-data-providers) - [Crypto and Blockchain Actions](https://docs.chain.link/data-feeds/selecting-data-feeds#crypto-and-blockchain-actions) - [Market Failures Resulting from Extreme Events](https://docs.chain.link/data-feeds/selecting-data-feeds#market-failures-resulting-from-extreme-events) - [Periods of High Network Congestion](https://docs.chain.link/data-feeds/selecting-data-feeds#periods-of-high-network-congestion) - [Unknown and Known Users](https://docs.chain.link/data-feeds/selecting-data-feeds#unknown-and-known-users) - [DEX volumes](https://docs.chain.link/data-feeds/selecting-data-feeds#dex-volumes) ### [Liquidity and its Distribution](https://docs.chain.link/data-feeds/selecting-data-feeds\#liquidity-and-its-distribution) If your smart contract relies on pricing data for a specific asset, make sure that the asset has a sufficiently healthy level of liquidity in the market to avoid price and market manipulation. Assets with low liquidity or volume can be volatile, which might negatively impact your application and its users. Malicious actors might try to exploit volatility or periods of reduced trading activity to take advantage of the logic in a smart contract and cause it to execute in a way that you did not intend. Some data feeds obtain their pricing data from individual exchanges rather than from aggregated price tracking services that gather their data from multiple exchanges. These are marked as such in the docs page for that feed. Assess the liquidity and reliability of that specific exchange. Liquidity migrations occur when a project moves its tokens from one liquidity provider (such as a DEX, a CEX, or a new DeFi application) to another. When liquidity migrations occur, it can result in low liquidity in the original pool, making the asset susceptible to market manipulation. If your project is considering a liquidity migration, you should coordinate with relevant stakeholders, including liquidity providers, exchanges, oracle node operators, Data Feed providers, and users, to ensure prices are accurately reported throughout the migration. Feeds for assets with low market liquidity or volume where data providers exhibit an abnormal price spread may, on occasion, see a price oscillate between two or more price points within regular intervals. To mitigate risk associated with such price oscillation, users must regularly monitor & assess the quality of an asset's liquidity. Similarly, assets with low market liquidity may experience abnormal or volatile price movements due to erroneous trades. Design and test your contracts to handle price spikes and implement risk management measures to protect your assets. For example, create mock tests that return various oracle responses. ### [Single Source Data Providers](https://docs.chain.link/data-feeds/selecting-data-feeds\#single-source-data-providers) Some data providers use a single data source, which might be necessary if only one source exists onchain or offchain for a specific type of data. Evaluate data providers to make sure they provide high-quality data that your smart contracts can rely on. Any error or omission in the provider's data might negatively impact your application and its users. ### [Crypto and Blockchain Actions](https://docs.chain.link/data-feeds/selecting-data-feeds\#crypto-and-blockchain-actions) Price data quality is subject to crypto actions by the crypto and blockchain project teams. Crypto actions are similar to [corporate actions](https://en.wikipedia.org/wiki/Corporate_action) but are specific to cryptocurrency and blockchain projects, such as token renaming, token swaps, redenominations, splits, reverse splits, network upgrades, and other migrations that teams or communities who govern the blockchain or token might undertake. Sustaining data quality is dependent on data sources implementing the necessary adjustments related to such actions. For example, when a project upgrades to a new version of their token, this results in a token migration. When token migrations occur, they require building a new Data Feed to ensure that the token price is accurately reported. Similarly, actions by blockchain project teams or communities, such as forks or upgrades to the network, may require new Data Feeds to ensure continuity and data quality. When considering a token migration, fork, network upgrade, or other crypto action, projects should proactively reach out to relevant stakeholders to ensure the asset price is accurately reported throughout the process. ### [Market Failures Resulting from Extreme Events](https://docs.chain.link/data-feeds/selecting-data-feeds\#market-failures-resulting-from-extreme-events) Users are strongly advised to set up monitoring and alerts in the event of unexpected market failures. Black swan events, hacks, coordinated attacks, or extreme market conditions may trigger unanticipated outcomes such as liquidity pools becoming unbalanced, unexpected re-weighting of indices, abnormal behavior by centralized or decentralized exchanges, or the de-pegging of synthetic assets, stablecoins, and currencies from their intended exchange rates. Circuit breakers can be created using [Chainlink Automation](https://docs.chain.link/chainlink-automation). Circuit breakers are safety measures that monitor data feeds for unexpected scenarios such as stale prices, drastic price changes, or prices approaching a predetermined min/max threshold. If an unexpected scenario occurs, the circuit breaker can send an onchain transaction to pause or halt contract functionality. ### [Periods of High Network Congestion](https://docs.chain.link/data-feeds/selecting-data-feeds\#periods-of-high-network-congestion) Data Feed performance relies on the chains they are deployed on. Periods of high network congestion or network downtime might impact the frequency of Chainlink Data Feeds. It is advised that you configure your applications to detect such chain performance or reliability issues and to respond appropriately. ### [Unknown and Known Users](https://docs.chain.link/data-feeds/selecting-data-feeds\#unknown-and-known-users) Routine maintenance is carried out on Chainlink Data Feeds, including decommissioning, on an ad-hoc basis. These maintenance periods might require users to take action in order to maintain business continuity. Notifications are sent to inform known users regarding such occurrences, and it is strongly encouraged for all users, including those users utilizing data feeds for offchain purposes, [to provide their contact information](https://chain.link/contact?ref_id=DataFeed) before utilizing data feeds. Without providing contact information, users will be unable to receive notifications regarding important Data Feed updates. If you are using Data Feeds but have not provided your contact information, you can do so [here](https://chain.link/contact?ref_id=DataFeed). Users that fail to provide notification information do so at their own risk. ### [DEX Volumes](https://docs.chain.link/data-feeds/selecting-data-feeds\#dex-volumes) Assets with a significant market presence on decentralized exchanges (DEXs) face distinct risks related to unique market structure. The market integrity can be compromised by flash loan-funded attacks, volume shifts to different onchain or offchain exchanges, or a well-capitalized actor temporarily manipulating the price on that exchange. Additionally, DEX trades can result in slippage due to liquidity migrations and trade size. The likelihood of high-slippage trades being accurately reflected in market prices depends on the trading patterns of the asset. Generally, a lower risk of deviant trades impacting aggregated prices is associated with assets having multiple DEX pools with healthy volumes and consistent trading activity across different time windows. ## [Evaluating Wrapped or Bridged Assets](https://docs.chain.link/data-feeds/selecting-data-feeds\#evaluating-wrapped-or-bridged-assets) ### [Assessing how to Price Wrapped or Bridged Assets](https://docs.chain.link/data-feeds/selecting-data-feeds\#assessing-how-to-price-wrapped-or-bridged-assets) When assessing a Chainlink Data Feed for a wrapped or bridged asset such as WBTC, users should evaluate the tradeoffs between using a Data Feed specifically built for the wrapped or bridged asset or a Data Feed built for the underlying asset. Decisions should be made on a case-by-case basis considering the liquidity, depth, and trading volatility of the underlying asset compared to its derivative. In addition, users must consider the security mechanism that is designed to keep the wrapped or bridged asset coupled to its underlying asset. Review these parameters regularly as asset dynamics continuously evolve. ### [Extreme Events Causing Price Deviations in Wrapped or Bridged Assets](https://docs.chain.link/data-feeds/selecting-data-feeds\#extreme-events-causing-price-deviations-in-wrapped-or-bridged-assets) Chainlink Data Feeds are designed to provide the market-wide price of various assets, as determined by a volume-weighted average across a wide range of exchanges. On blockchain networks where assets are wrapped and/or bridged from another environment using a cross-chain token bridge, Chainlink Data Feeds built for the underlying asset will continue to report the market-wide price of the underlying asset as opposed to the price of the wrapped/bridged asset. This methodology reduces risks around market manipulation because wrapped/bridged tokens are often less liquid than the underlying asset. However, users should be aware that certain extreme events may result in price deviations between the wrapped/bridged asset and its underlying counterpart. For example, the exploitation or hack of a cross-chain token bridge may cause a collapse in demand for a particular wrapped asset. As such, users should construct their applications with safeguards, such as circuit breakers to proactively pause functionality to mitigate risk during such scenarios. Circuit breakers can be created using Chainlink Automation to monitor data feeds for unexpected scenarios. An additional mechanism for securing a protocol utilizing wrapped assets is by incorporating [Chainlink Proof of Reserve](https://chain.link/proof-of-reserve). Chainlink Proof of Reserve enables the real-time reserve monitoring of offchain and cross-chain assets, including those that have been wrapped/bridged. By comparing the wrapped token’s supply against a Chainlink Proof of Reserve feed, protocols can ensure that these assets are properly collateralized at all times. ### [Front Running Risk](https://docs.chain.link/data-feeds/selecting-data-feeds\#front-running-risk) Front running (when a third party benefits from prior access to information about a transaction) is a known risk inherent to specific blockchain applications. Chainlink Data Feeds are optimized to prioritize high levels of data quality and reliability over latency. To mitigate the risk associated with front running, users building highly latency-dependent applications should assess whether the configuration of data feeds meets their needed specifications for speed and frequency. [Chainlink Data Streams](https://docs.chain.link/data-streams) serve as an alternative solution to Data Feeds for latency-sensitive applications, providing low-latency delivery of market data offchain that can be verified onchain while mitigating front running. ## [Exchange Rate Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#exchange-rate-feeds) The architecture of exchange rate feeds differs from that of standard market rate Chainlink Price Feeds. **Market rate feeds** (e.g., Chainlink Price Feeds) deliver price updates based on the volume-based aggregated market price of a specific asset. Price data is [aggregated from across multiple sources](https://blog.chain.link/chainlink-price-feeds-secure-defi/), including centralized and decentralized exchanges, to provide an accurate representation of an asset's market-wide price. **Exchange rate feeds** are tied to specific protocols or ecosystems and report the internal redemption rates for an asset (i.e., the value/rate at which an asset can be redeemed or exchanged within that protocol's ecosystem). This data is sourced directly from a specified smart contract on a source chain and relayed to a destination chain. Exchange rate feeds are useful in circumstances such as: - **Pricing yield-bearing assets:** Multiplying a yield-bearing asset's exchange rate by the underlying asset's market rate can be used to calculate the yield-bearing asset's current price. This methodology can reduce certain pricing volatility risks associated with lower-liquidity yield-bearing assets. - **Enabling cross-chain staking:** For example, liquid staking tokens (LSTs) or liquid restaking tokens (LRTs) can be minted at the exchange rate on a layer 2, while Chainlink CCIP transfers the underlying asset to a layer 1 for staking. - **Improving liquidity pool performance for yield-bearing assets:** Exchange rate feeds can be utilized to programmatically adjust swap curves to maximize liquidity efficiency. ## [ETF and Forex feeds](https://docs.chain.link/data-feeds/selecting-data-feeds\#etf-and-forex-feeds) When you use Data Feeds for ETFs or Foreign Exchange (Forex) data, be aware of the following best practices: - Offchain equity and ETF assets are traded only during [standard market hours](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours). Do not use these feeds outside those windows. - Assets on the Forex (Foreign Exchange) markets are traded only during [defined market hours](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours). Additionally, some currencies might trade only during local banking hours. Do not use Forex feeds outside market hours for the specific currency. - UK ETF price feed answers are 15 minutes delayed from their original published source. Assets are traded only during [standard market hours](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours). Do not use these feeds outside their specified hours. ## Get the latest Chainlink content straight to your inbox. Email Address ## Price Feed Addresses [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1\#overview) To learn how to use these feeds, see the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) guide. For LINK token and Faucet details, see the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. ### [Data Feed Best Practices](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1\#data-feed-best-practices) Before you use Data Feeds, read and understand the best practices on the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) page. For best practices about data for specific asset types, see the following sections: - [Best Practices for ETF and Forex feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#etf-and-forex-feeds) - [Best Practices for Exchange Rate Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#exchange-rate-feeds) - [Risk Categories](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories) ## [Networks](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1\#networks) ![](https://docs.chain.link/assets/chains/aptos.svg)Aptos![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum![](https://docs.chain.link/assets/chains/avalanche.svg)Avalanche![](https://docs.chain.link/assets/chains/base.svg)Base![](https://docs.chain.link/assets/chains/bnb-chain.svg)BNB Chain![](https://docs.chain.link/assets/chains/botanix.svg)Botanix![](https://docs.chain.link/assets/chains/celo.svg)Celo![](https://docs.chain.link/assets/chains/ethereum.svg)Ethereum![](https://docs.chain.link/assets/chains/fantom.svg)Fantom![](https://docs.chain.link/assets/chains/gnosis-chain.svg)Gnosis Chain (xDai)![](https://docs.chain.link/assets/chains/hedera.svg)Hedera![](https://docs.chain.link/assets/chains/linea.svg)Linea![](https://docs.chain.link/assets/chains/mantle.svg)Mantle![](https://docs.chain.link/assets/chains/metis.svg)Metis![](https://docs.chain.link/assets/chains/monad.svg)Monad![](https://docs.chain.link/assets/chains/moonbeam.svg)Moonbeam![](https://docs.chain.link/assets/chains/moonriver.svg)Moonriver![](https://docs.chain.link/assets/chains/optimism.svg)OP![](https://docs.chain.link/assets/chains/polygon.svg)Polygon![](https://docs.chain.link/assets/chains/polygonzkevm.svg)Polygon zkEVM![](https://docs.chain.link/assets/chains/ronin.svg)Ronin![](https://docs.chain.link/assets/chains/scroll.svg)Scroll![](https://docs.chain.link/assets/chains/soneium.svg)Soneium![](https://docs.chain.link/assets/chains/solana.svg)Solana![](https://docs.chain.link/assets/chains/sonic.svg)Sonic![](https://docs.chain.link/assets/chains/starknet.svg)Starknet![](https://docs.chain.link/assets/chains/tron.svg)TRON![](https://docs.chain.link/assets/chains/unichain.svg)Unichain![](https://docs.chain.link/assets/chains/xlayer.svg)X Layer![](https://docs.chain.link/assets/chains/zksync.svg)ZKsync Track the status of this network at [https://ethstats.dev/](https://ethstats.dev/) ### [Ethereum Mainnet](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1\#ethereum-mainnet) Data Feed Categories Show more detailsShow SVR-enabled feeds | Pair | Deviation | Heartbeat | Dec | Address and info | | --- | --- | --- | --- | --- | | [🟡](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds)1INCH / ETH | 2% | 86400s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8](https://etherscan.io/address/0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8)
Asset name:1inch
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🟡](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds)1INCH / USD | 1% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xc929ad75B72593967DE83E7F7Cda0493458261D9](https://etherscan.io/address/0xc929ad75B72593967DE83E7F7Cda0493458261D9)
Asset name:1inch
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🟡](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds)AAVE / ETH | 2% | 86400s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012](https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012)
Asset name:Aave
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🟢](https://docs.chain.link/data-feeds/selecting-data-feeds#-low-market-risk-feeds)AAVE / USD
[SVR](https://docs.chain.link/data-feeds/svr-feeds) | 1% | 3600s | 8 | Standard Proxy:
![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xbd7F896e60B650C01caf2d7279a1148189A68884](https://etherscan.io/address/0xbd7F896e60B650C01caf2d7279a1148189A68884)
Asset name:Aave
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours)
AAVE SVR Proxy:![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xF02C1e2A3B77c1cacC72f72B44f7d0a4c62e4a85](https://etherscan.io/address/0xF02C1e2A3B77c1cacC72f72B44f7d0a4c62e4a85)
**⚠️ Aave Dedicated Feed:** This SVR proxy feed is dedicated exclusively for use by the Aave protocol. Learn more about [SVR-enabled Feeds](https://docs.chain.link/data-feeds/svr-feeds). | | [🟢](https://docs.chain.link/data-feeds/selecting-data-feeds#-low-market-risk-feeds)AAVE / USD | 1% | 3600s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x547a514d5e3769680Ce22B2361c10Ea13619e8a9](https://etherscan.io/address/0x547a514d5e3769680Ce22B2361c10Ea13619e8a9)
Asset name:Aave
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🟡](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds)ALCX / ETH | 2% | 86400s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x194a9AaF2e0b67c35915cD01101585A33Fe25CAa](https://etherscan.io/address/0x194a9AaF2e0b67c35915cD01101585A33Fe25CAa)
Asset name:Alchemix
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🔵](https://docs.chain.link/data-feeds/selecting-data-feeds#-custom-feeds)AMPL / USD | 1000% | 172800s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xe20CA8D7546932360e37E9D72c1a47334af57706](https://etherscan.io/address/0xe20CA8D7546932360e37E9D72c1a47334af57706)
Asset name:Ampleforth
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | [🟡](https://docs.chain.link/data-feeds/selecting-data-feeds#-medium-market-risk-feeds)APE / ETH | 2% | 86400s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xc7de7f4d4C9c991fF62a07D18b3E31e349833A18](https://etherscan.io/address/0xc7de7f4d4C9c991fF62a07D18b3E31e349833A18)
Asset name:APECoin
Asset type:Crypto
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | Prev Showing 1 to 8 of 169 entries Next ### [Sepolia Testnet](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1\#sepolia-testnet) Show more details | Pair | Deviation | Heartbeat | Dec | Address and info | | --- | --- | --- | --- | --- | | AUD / USD | 0.15% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xB0C712f98daE15264c8E26132BCC91C40aD4d5F9](https://sepolia.etherscan.io/address/0xB0C712f98daE15264c8E26132BCC91C40aD4d5F9) | | BTC / ETH | 1% | 3600s | 18 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x5fb1616F78dA7aFC9FF79e0371741a747D2a7F22](https://sepolia.etherscan.io/address/0x5fb1616F78dA7aFC9FF79e0371741a747D2a7F22) | | BTC / USD | 1% | 3600s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) | | CSPX / USD | 2% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x4b531A318B0e44B549F3b2f824721b3D0d51930A](https://sepolia.etherscan.io/address/0x4b531A318B0e44B549F3b2f824721b3D0d51930A) | | CZK / USD | 0.5% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xC32f0A9D70A34B9E7377C10FDAd88512596f61EA](https://sepolia.etherscan.io/address/0xC32f0A9D70A34B9E7377C10FDAd88512596f61EA) | | DAI / USD | 1% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x14866185B1962B63C3Ea9E03Bc1da838bab34C19](https://sepolia.etherscan.io/address/0x14866185B1962B63C3Ea9E03Bc1da838bab34C19) | | ETH / USD | 1% | 3600s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x694AA1769357215DE4FAC081bf1f309aDC325306](https://sepolia.etherscan.io/address/0x694AA1769357215DE4FAC081bf1f309aDC325306) | | EUR / USD | 0.5% | 86400s | 8 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x1a81afB8146aeFfCFc5E50e8479e826E7D55b910](https://sepolia.etherscan.io/address/0x1a81afB8146aeFfCFc5E50e8479e826E7D55b910) | Prev Showing 1 to 8 of 33 entries Next ## Get the latest Chainlink content straight to your inbox. Email Address [iframe](https://td.doubleclick.net/td/rul/346357746?random=1747083863243&cv=11&fst=1747083863243&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be5580v891173849z8847174275za201zb882454074&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509156~103101750~103101752~103116026~103200004~103233424~103251618~103251620~103284320~103284322~103301114~103301116&ptag_exp=101509156~103101750~103101752~103116025~103200001~103233424~103251618~103251620~103284320~103284322~103301114~103301116&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fdata-feeds%2Fprice-feeds%2Faddresses&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=Price%20Feed%20Contract%20Addresses%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=376338084.1747083863&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.92%7CGoogle%2520Chrome%3B136.0.7103.92%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&fledge=1&capi=1&_tu=Cg&ct_cookie_present=0) ## Chainlink Data Feeds Tutorials [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Data Feeds guides (Starknet Foundry)](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry\#overview) You can explore several comprehensive guides to learn how to use Data Feeds on Starknet using [Starknet Foundry](https://github.com/foundry-rs/starknet-foundry). These tutorials provide step-by-step guidance to help you understand how to locally experiment with or integrate Chainlink Data Feeds into your Starknet projects. ## [Guides](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry\#guides) - [Read Data from Chainlink Data Feeds](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/read-data) - [Deploy and interact with a Consumer Contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract) - [Experiment with Data Feeds using Starknet Devnet RS](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Rate Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses?page=1&testnetPage=1\#overview) To learn how to use these feeds, see the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) guide. For LINK token and Faucet details, see the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. ## [Networks](https://docs.chain.link/data-feeds/rates-feeds/addresses?page=1&testnetPage=1\#networks) ![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum![](https://docs.chain.link/assets/chains/avalanche.svg)Avalanche![](https://docs.chain.link/assets/chains/ethereum.svg)Ethereum Track the status of this network at [https://ethstats.dev/](https://ethstats.dev/) ### [Sepolia Testnet](https://docs.chain.link/data-feeds/rates-feeds/addresses?page=1&testnetPage=1\#sepolia-testnet) Show more details | Pair | Deviation | Heartbeat | Dec | Address and info | | --- | --- | --- | --- | --- | | 30-Day ETH APR | 50% | 86400s | 7 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xceA6Aa74E6A86a7f85B571Ce1C34f1A60B77CD29](https://sepolia.etherscan.io/address/0xceA6Aa74E6A86a7f85B571Ce1C34f1A60B77CD29)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | 90-Day ETH APR | 50% | 86400s | 7 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x7422A64372f95F172962e2C0f371E0D9531DF276](https://sepolia.etherscan.io/address/0x7422A64372f95F172962e2C0f371E0D9531DF276)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | BTC-USD 24hr Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x28f9134a15cf0aAC9e1F0CD09E17f32925254C77](https://sepolia.etherscan.io/address/0x28f9134a15cf0aAC9e1F0CD09E17f32925254C77)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | BTC-USD 30-Day Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xabfe1e28F54Ac40776DfCf2dF0874D37254D5F59](https://sepolia.etherscan.io/address/0xabfe1e28F54Ac40776DfCf2dF0874D37254D5F59)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | BTC-USD 7-Day Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x88163626786Ee98AA1De65BD2A76599e71598FD9](https://sepolia.etherscan.io/address/0x88163626786Ee98AA1De65BD2A76599e71598FD9)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | ETH-USD 24hr Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x31D04174D0e1643963b38d87f26b0675Bb7dC96e](https://sepolia.etherscan.io/address/0x31D04174D0e1643963b38d87f26b0675Bb7dC96e)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | ETH-USD 30-Day Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0x8e604308BD61d975bc6aE7903747785Db7dE97e2](https://sepolia.etherscan.io/address/0x8e604308BD61d975bc6aE7903747785Db7dE97e2)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | | ETH-USD 7-Day Realized Volatility | 50% | 3600s | 5 | ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg)[0xF3140662cE17fDee0A6675F9a511aDbc4f394003](https://sepolia.etherscan.io/address/0xF3140662cE17fDee0A6675F9a511aDbc4f394003)
Market hours:[Crypto](https://docs.chain.link/data-feeds/selecting-data-feeds#market-hours) | Prev Showing 1 to 8 of 11 entries Next ## Get the latest Chainlink content straight to your inbox. Email Address ## L2 Sequencer Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # [L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#overview) Optimistic rollups (e.g., Arbitrum, Optimism) and many ZK-rollups rely on sequencers to efficiently manage transaction ordering, execution, and batching before submitting them to Layer 1 (L1) blockchains like Ethereum. The sequencer plays a crucial role in optimizing transaction throughput, reducing fees, and ensuring fast transaction confirmations on L2 networks, making it a key component of their scalability and performance. However, if the sequencer becomes unavailable, users will lose access to the standard read/write APIs, preventing them from interacting with applications on the L2 network. Although the L2 chain's security and state commitments remain enforced by Layer 1, no new batched blocks will be produced by the sequencer. Users with sufficient technical expertise can still interact directly with the network through the underlying rollup contracts on L1. However, this process is more complex and costly, creating an unfair advantage for those who can bypass the sequencer. This imbalance in access can lead to disruptions or distortions in applications, such as liquidations or market operations that rely on timely transactions. To mitigate these risks, your applications can integrate a **Sequencer Uptime Data Feed**, which continuously monitors and records the last known status of the sequencer. By utilizing this feed, you can: - Detect sequencer downtime in real time. - Implement a grace period to prevent mass liquidations or unexpected disruptions. - Ensure fair access to services by temporarily pausing operations during sequencer failures. This proactive approach enhances the resilience and fairness of applications operating on L2 networks, ensuring a more stable and equitable user experience. ## [Supported Networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#supported-networks) You can find proxy addresses for the L2 sequencer feeds at the following addresses: ### [![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#arbitrum) Arbitrum Mainnet: [0xFdB631F5EE196F0ed6FAa767959853A9F217697D](https://arbiscan.io/address/0xFdB631F5EE196F0ed6FAa767959853A9F217697D) ### [![](https://docs.chain.link/assets/chains/base.svg)BASE](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#base) BASE Mainnet: [0xBCF85224fc0756B9Fa45aA7892530B47e10b6433](https://basescan.org/address/0xBCF85224fc0756B9Fa45aA7892530B47e10b6433) ### [![](https://docs.chain.link/assets/chains/mantle.svg)Mantle](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#mantle) Mantle Mainnet: [0xaDE1b9AbB98c6A542E4B49db2588a3Ec4bF7Cdf0](https://mantlescan.xyz/address/0xaDE1b9AbB98c6A542E4B49db2588a3Ec4bF7Cdf0) ### [![](https://docs.chain.link/assets/chains/metis.svg)Metis](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#metis) Andromeda Mainnet: [0x58218ea7422255EBE94e56b504035a784b7AA204](https://andromeda-explorer.metis.io/address/0x58218ea7422255EBE94e56b504035a784b7AA204) ### [![](https://docs.chain.link/assets/chains/optimism.svg)OP](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#op) OP Mainnet: [0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389](https://optimistic.etherscan.io/address/0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389) ### [![](https://docs.chain.link/assets/chains/scroll.svg)Scroll](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#scroll) Scroll Mainnet: [0x45c2b8C204568A03Dc7A2E32B71D67Fe97F908A9](https://scrollscan.com/address/0x45c2b8C204568A03Dc7A2E32B71D67Fe97F908A9) ### [![](https://docs.chain.link/assets/chains/soneium.svg)Soneium](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#soneium) Soneium Mainnet: [0xaDE1b9AbB98c6A542E4B49db2588a3Ec4bF7Cdf0](https://soneium.blockscout.com/address/0xaDE1b9AbB98c6A542E4B49db2588a3Ec4bF7Cdf0) ### [![](https://docs.chain.link/assets/chains/zksync.svg)ZKsync](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#zksync) zkSync Mainnet: [0x0E6AC8B967393dcD3D36677c126976157F993940](https://explorer.zksync.io/address/0x0E6AC8B967393dcD3D36677c126976157F993940) ## [Real-time Monitoring Process](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#real-time-monitoring-process) ### [Arbitrum](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#arbitrum-1) The diagram below shows how these feeds update and how a consumer retrieves the status of the Arbitrum sequencer. ![](https://docs.chain.link/images/data-feed/l2-diagram-arbitrum.webp) 1. Chainlink nodes trigger an OCR round every 30s and update the sequencer status by calling the `validate` function in the [`ArbitrumValidator` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol) by calling it through the [`ValidatorProxy` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.8/ValidatorProxy.sol). 2. The `ArbitrumValidator` checks to see if the latest update is different from the previous update. If it detects a difference, it places a message in the [Arbitrum inbox contract](https://developer.offchainlabs.com/docs/inside_arbitrum#the-big-picture). 3. The inbox contract sends the message to the [`ArbitrumSequencerUptimeFeed` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol). The message calls the `updateStatus` function in the `ArbitrumSequencerUptimeFeed` contract and updates the latest sequencer status to 0 if the sequencer is up and 1 if it is down. It also records the block timestamp to indicate when the message was sent from the L1 network. 4. A consumer contract on the L2 network can read these values from the [`ArbitrumUptimeFeedProxy` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/EACAggregatorProxy.sol), which reads values from the `ArbitrumSequencerUptimeFeed` contract. #### [Handling Arbitrum Outages](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#handling-arbitrum-outages) If the Arbitrum network becomes unavailable, the `ArbitrumValidator` contract continues to send messages to the L2 network through the delayed inbox on L1. This message stays there until the sequencer is back up again. When the sequencer comes back online after downtime, it processes all transactions from the delayed inbox before it accepts new transactions. The message that signals when the sequencer is down will be processed before any new messages with transactions that require the sequencer to be operational. ### [Other Supported Networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#other-supported-networks) On BASE, Mantle, Metis, OP, Scroll, Soneium and zkSync, the sequencer's status is relayed from L1 to L2 where the consumer can retrieve it. ![](https://docs.chain.link/images/data-feed/l2-diagram-optimism-metis.webp) **On the L1 network:** 1. A network of node operators runs the external adapter to post the latest sequencer status to the `AggregatorProxy` contract and relays the status to the `Aggregator` contract. The `Aggregator` contract calls the `validate` function in the `OptimismValidator` contract. 2. The `OptimismValidator` contract calls the `sendMessage` function in the `L1CrossDomainMessenger` contract. This message contains instructions to call the `updateStatus(bool status, uint64 timestamp)` function in the sequencer uptime feed deployed on the L2 network. 3. The `L1CrossDomainMessenger` contract calls the `enqueue` function to enqueue a new message to the `CanonicalTransactionChain`. 4. The `Sequencer` processes the transaction enqueued in the `CanonicalTransactionChain` contract to send it to the L2 contract. **On the L2 network:** 1. The `Sequencer` posts the message to the `L2CrossDomainMessenger` contract. 2. The `L2CrossDomainMessenger` contract relays the message to the `OptimismSequencerUptimeFeed` contract. 3. The message relayed by the `L2CrossDomainMessenger` contains instructions to call `updateStatus` in the `OptimismSequencerUptimeFeed` contract. 4. Consumers can then read from the `AggregatorProxy` contract, which fetches the latest round data from the `OptimismSequencerUptimeFeed` contract. #### [Handling Other Supported Network Outages](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#handling-other-supported-network-outages) If the sequencer is down, messages cannot be transmitted from L1 to L2 and **no L2 transactions are executed**. Instead, messages are enqueued in the `CanonicalTransactionChain` on L1 and only processed in the order they arrived later when the sequencer comes back up. As long as the message from the validator on L1 is already enqueued in the `CTC`, the flag on the sequencer uptime feed on L2 will be guaranteed to be flipped prior to any subsequent transactions. The transaction that flips the flag on the uptime feed will be executed before transactions that were enqueued after it. This is further explained in the diagrams below. When the Sequencer is down, all L2 transactions sent from the L1 network wait in the pending queue. 1. **Transaction 3** contains Chainlink’s transaction to set the status of the sequencer as being down on L2. 2. **Transaction 4** is a transaction made by a consumer that is dependent on the sequencer status. ![](https://docs.chain.link/images/data-feed/seq-down-1.webp) After the sequencer comes back up, it moves all transactions in the pending queue to the processed queue. 1. Transactions are processed in the order they arrived so **Transaction 3** is processed before **Transaction 4**. 2. Because **Transaction 3** happens before **Transaction 4**, **Transaction 4** will read the status of the Sequencer as being down and responds accordingly. ![](https://docs.chain.link/images/data-feed/seq-down-2.webp) ## [Example Consumer Contract](https://docs.chain.link/data-feeds/l2-sequencer-feeds\#example-consumer-contract) This example code works on any network that supports Solidity. Create the consumer contract for sequencer uptime feeds similarly to the contracts that you use for other [Chainlink Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds). Configure the constructor using the following variables: - Configure the `sequencerUptimeFeed` object with the [sequencer uptime feed proxy address](https://docs.chain.link/data-feeds/l2-sequencer-feeds#supported-networks) for your L2 network. - Configure the `dataFeed` object with one of the [Data Feed proxy addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) that are available for your network. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV2V3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV2V3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract DataConsumerWithSequencerCheck { AggregatorV2V3Interface internal dataFeed; AggregatorV2V3Interface internal sequencerUptimeFeed; uint256 private constant GRACE_PERIOD_TIME = 3600; error SequencerDown(); error GracePeriodNotOver(); /** * Network: OP Mainnet * Data Feed: BTC/USD * Data Feed address: 0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593 * Uptime Feed address: 0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389 * For a list of available Sequencer Uptime Feed proxy addresses, see: * https://docs.chain.link/docs/data-feeds/l2-sequencer-feeds */ constructor() { dataFeed = AggregatorV2V3Interface( 0xD702DD976Fb76Fffc2D3963D037dfDae5b04E593 ); sequencerUptimeFeed = AggregatorV2V3Interface( 0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389 ); } // Check the sequencer status and return the latest data function getChainlinkDataFeedLatestAnswer() public view returns (int) { // prettier-ignore ( /*uint80 roundID*/, int256 answer, uint256 startedAt, /*uint256 updatedAt*/, /*uint80 answeredInRound*/ ) = sequencerUptimeFeed.latestRoundData(); // Answer == 0: Sequencer is up // Answer == 1: Sequencer is down bool isSequencerUp = answer == 0; if (!isSequencerUp) { revert SequencerDown(); } // Make sure the grace period has passed after the // sequencer is back up. uint256 timeSinceUp = block.timestamp - startedAt; if (timeSinceUp <= GRACE_PERIOD_TIME) { revert GracePeriodNotOver(); } // prettier-ignore ( /*uint80 roundID*/, int data, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = dataFeed.latestRoundData(); return data; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerWithSequencerCheck.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) The `sequencerUptimeFeed` object returns the following values: - `answer`: A variable with a value of either `0` or `1` - 0: The sequencer is up - 1: The sequencer is down - `startedAt`: This timestamp indicates when the sequencer feed changed status. When the sequencer comes back up after an outage, wait for the `GRACE_PERIOD_TIME` to pass before accepting answers from the data feed. Subtract `startedAt` from `block.timestamp` and revert the request if the result is less than the `GRACE_PERIOD_TIME`. - The `startedAt` variable returns `0` only on Arbitrum when the Sequencer Uptime contract is not yet initialized. For L2 chains other than Arbitrum, `startedAt` is set to `block.timestamp` on construction and `startedAt` is never `0`. After the feed begins rounds, the `startedAt` timestamp will always indicate when the sequencer feed last changed status. If the sequencer is up and the `GRACE_PERIOD_TIME` has passed, the function retrieves the latest answer from the data feed using the `dataFeed` object. ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds Solana [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using Data Feeds Onchain (Solana)](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#overview) Chainlink Data Feeds are the quickest way to connect your smart contracts to the real-world market prices of assets. This guide demonstrates how to deploy a program to the Solana Devnet cluster and access Data Feeds onchain using the [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). To learn how to read price feed data using offchain applications, see the [Using Data Feeds Offchain](https://docs.chain.link/solana/using-data-feeds-off-chain) guide. To get the full list of available Chainlink Data Feeds on Solana, see the [Solana Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) page. View the program that owns the Chainlink Data Feeds in the [Solana Devnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), or the [Solana Mainnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny). ## [The Chainlink Data Feeds OCR2 program](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#the-chainlink-data-feeds-ocr2-program) The program that owns the data feeds on both Devnet and Mainnet is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet). This is the program ID that you use to retrieve Chainlink Price Data onchain in your program. The source code for this program is available in the [smartcontractkit/chainlink-solana](https://github.com/smartcontractkit/chainlink-solana/tree/develop/contracts/programs/ocr_2) repository on GitHub. You can [add data feeds to an existing project](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana#adding-data-feeds-onchain-in-an-existing-project) or [use the Solana Starter Kit](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana#using-the-solana-starter-kit). ## [Adding Data Feeds onchain in an existing project](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#adding-data-feeds-onchain-in-an-existing-project) You can read Chainlink Data Feed data onchain in your existing project using the [Chainlink Solana Crate](https://crates.io/crates/chainlink_solana). Import the Chainlink Solana Crate into your project and use the code sample to make function calls. 1. Add the Chainlink Solana Crate as an entry in your `Cargo.toml` file dependencies section, as shown in the [starter kit Cargo.toml example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/programs/chainlink_solana_demo/Cargo.toml). ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```toml [dependencies] chainlink_solana = "1.0.0" ``` 2. Use the following code sample to query price data. Each function call to the Chainlink Solana library takes two parameters: - The [feed account](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) that you want to query. - The [Chainlink Data Feeds OCR2 Program](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana#the-chainlink-data-feeds-ocr2-program) for the network. This is a static value that never changes. The code sample has the following components: - `latest_round_data`: Returns the latest round information for the specified price pair including the latest price - `description`: Returns a price pair description such as SOL/USD - `decimals`: Returns the precision of the price, as in how many numbers the price is padded out to - `Display`: A helper function that formats the padded out price data into a human-readable price ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ use chainlink_solana as chainlink; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey, }; struct Decimal { pub value: i128, pub decimals: u32, } impl Decimal { pub fn new(value: i128, decimals: u32) -> Self { Decimal { value, decimals } } } impl std::fmt::Display for Decimal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut scaled_val = self.value.to_string(); if scaled_val.len() <= self.decimals as usize { scaled_val.insert_str( 0, &vec!["0"; self.decimals as usize - scaled_val.len()].join(""), ); scaled_val.insert_str(0, "0."); } else { scaled_val.insert(scaled_val.len() - self.decimals as usize, '.'); } f.write_str(&scaled_val) } } // Declare and export the program's entrypoint entrypoint!(process_instruction); // Program entrypoint's implementation pub fn process_instruction( _program_id: &Pubkey, // Ignored accounts: &[AccountInfo], _instruction_data: &[u8], // Ignored ) -> ProgramResult { msg!("Chainlink Price Feed Consumer entrypoint"); let accounts_iter = &mut accounts.iter(); // This is the account of the price feed data to read from let feed_account = next_account_info(accounts_iter)?; // This is the chainlink solana program ID let chainlink_program = next_account_info(accounts_iter)?; let round = chainlink::latest_round_data( chainlink_program.clone(), feed_account.clone(), )?; let description = chainlink::description( chainlink_program.clone(), feed_account.clone(), )?; let decimals = chainlink::decimals( chainlink_program.clone(), feed_account.clone(), )?; let decimal_print = Decimal::new(round.answer, u32::from(decimals)); msg!("{} price is {}", description, decimal_print); Ok(()) } ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ use anchor_lang::prelude::*; use chainlink_solana as chainlink; //Program ID required by Anchor. Replace with your unique program ID once you build your project declare_id!("HPuUpM1bKbaqx7yY2EJ4hGBaA3QsfP5cofHHK99daz85"); #[account] pub struct Decimal { pub value: i128, pub decimals: u32, } impl Decimal { pub fn new(value: i128, decimals: u32) -> Self { Decimal { value, decimals } } } impl std::fmt::Display for Decimal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut scaled_val = self.value.to_string(); if scaled_val.len() <= self.decimals as usize { scaled_val.insert_str( 0, &vec!["0"; self.decimals as usize - scaled_val.len()].join(""), ); scaled_val.insert_str(0, "0."); } else { scaled_val.insert(scaled_val.len() - self.decimals as usize, '.'); } f.write_str(&scaled_val) } } #[program] pub mod chainlink_solana_demo { use super::*; pub fn execute(ctx: Context) -> Result<()> { let round = chainlink::latest_round_data( ctx.accounts.chainlink_program.to_account_info(), ctx.accounts.chainlink_feed.to_account_info(), )?; let description = chainlink::description( ctx.accounts.chainlink_program.to_account_info(), ctx.accounts.chainlink_feed.to_account_info(), )?; let decimals = chainlink::decimals( ctx.accounts.chainlink_program.to_account_info(), ctx.accounts.chainlink_feed.to_account_info(), )?; // write the latest price to the program output let decimal_print = Decimal::new(round.answer, u32::from(decimals)); msg!("{} price is {}", description, decimal_print); Ok(()) } } #[derive(Accounts)] pub struct Execute<'info> { /// CHECK: We're reading data from this chainlink feed account pub chainlink_feed: AccountInfo<'info>, /// CHECK: This is the Chainlink program library pub chainlink_program: AccountInfo<'info> } ``` Program Transaction logs: RustRust with Anchor ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell > Program logged: "Chainlink Price Feed Consumer entrypoint" > Program logged: "SOL / USD price is 83.99000000" > Program consumed: 95953 of 1400000 compute units > Program return: HNYSbr77Jc9LhHeb9tx53SrWbWfNBnQzQrM4b3BB3PCR CA== ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell Fetching transaction logs... [ 'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny\ consumed 1826 of 1306895 compute units', 'Program return: HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny CA==',\ 'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny success', 'Program log: SOL / USD price is 93.76988029', ] ``` To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://www.anchor-lang.com/). ## [Using the Solana starter kit](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#using-the-solana-starter-kit) This guide demonstrates the following tasks: - Write and deploy programs to the [Solana Devnet](https://solscan.io/?cluster=devnet) cluster using Anchor. - Retrieve price data data using the [Solana Web3 JavaScript API](https://www.npmjs.com/package/@solana/web3.js) with Node.js. This example shows a full end to end example of using Chainlink Price Feeds on Solana. It includes an onchain program written in rust, as well as an offchain client written in JavaScript. The client passes in an account to the program, the program then looks up the latest price of the specified price feed account, and then stores the result in the passed in account. The offchain client then reads the value stored in the account. ### [Install the required tools](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#install-the-required-tools) Before you begin, set up your environment for development on Solana: 1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if it is not already configured on your system. 2. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node --version ``` 3. Install [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to simplify package management and run code samples. 4. Install a C compiler such as the one included in [GCC](https://gcc.gnu.org/install/). Some of the dependencies require a C compiler. 5. Install [Rust](https://www.rust-lang.org/tools/install): ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && source $HOME/.cargo/env ``` 6. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell sh -c "$(curl -sSfL https://release.solana.com/v1.13.6/install)" && export PATH="~/.local/share/solana/install/active_release/bin:$PATH" ``` Run `solana --version` to make sure the Solana CLI is installed correctly. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana --version ``` 7. [Install Anchor](https://www.anchor-lang.com/docs/installation). On some operating systems, you might need to build and install Anchor locally. See the [Anchor documentation](https://www.anchor-lang.com/docs) for instructions. After you install the required tools, build and deploy the example program from the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository. ### [Deploy the example program](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#deploy-the-example-program) This example includes a contract written in Rust. Deploy the contract to the Solana Devnet cluster. 1. In a terminal, clone the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository and change to the `solana-starter-kit` directory: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell git clone https://github.com/smartcontractkit/solana-starter-kit && cd ./solana-starter-kit ``` You can see the complete code for the example on [GitHub](https://github.com/smartcontractkit/solana-starter-kit/). 2. In the `./solana-starter-kit` directory, install Node.js dependencies defined in the `package.json` file: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn install ``` 3. Create a temporary Solana wallet to use for this example. Use a temporary wallet to isolate development from your other wallets and prevent you from unintentionally using lamports on the Solana Mainnet. Alternatively, if you have an existing wallet that you want to use, locate the path to your keypair file and use it as the keypair for the rest of this guide. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana-keygen new --outfile ./id.json ``` When you build your production applications and deploy Solana programs to the Mainnet cluster, always follow the security best practices in the [Solana Wallet Guide](https://docs.solana.com/wallet-guide) for managing your wallets and keypairs. 4. Fund your Solana wallet. On Devnet, use `solana airdrop` to add tokens to your account. The contract requires at least 4 SOL to deploy and the faucet limits each request to 2 SOL, so you must make two requests to get a total of 4 SOL on your wallet: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana airdrop 2 --keypair ./id.json --url devnet && solana airdrop 2 --keypair ./id.json --url devnet ``` - If the command line faucet does not work, run `solana address` on the temporary wallet to print the public key value for the wallet and request tokens from [SolFaucet](https://solfaucet.com/): ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana address -k ./id.json ``` 5. Run `anchor build` to build the example program. If you receive the `no such subcommand: 'build-bpf'` error, restart your terminal session and run `anchor build` again: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell anchor build ``` 6. The build process generates the keypair for your program's account. Before you deploy your program, you must add this public key to the `lib.rs` file: 1. Get the keypair from the `./target/deploy/chainlink_solana_demo-keypair.json` file that Anchor generated: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana address -k ./target/deploy/chainlink_solana_demo-keypair.json ``` 2. Edit the `./programs/chainlink_solana_demo/src/lib.rs` file and replace the keypair in the `declare_id!()` definition: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell vi ./programs/chainlink_solana_demo/src/lib.rs ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell declare_id!("JC16qi56dgcLoaTVe4BvnCoDL6FhH5NtahA7jmWZFdqm"); ``` 7. With the new program ID added, run `anchor build` again. This recreates the necessary program files with the correct program ID: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell anchor build ``` 8. Run `anchor deploy` to deploy the program to the Solana Devnet. Remember to specify the keypair file for your wallet and override the default. This wallet is the account owner (authority) for the program: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell anchor deploy --provider.wallet ./id.json --provider.cluster devnet ``` 9. To confirm that the program deployed correctly, run `solana program show --programs` to get a list of deployed programs that your wallet owns. For this example, check the list of deployed programs for the `id.json` wallet on the Solana Devnet: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana program show --programs --keypair ./id.json --url devnet ``` The command prints the program ID, slot number, the wallet address that owns the program, and the program balance: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell Program Id | Slot | Authority | Balance GRt21UnJFHZvcaWLbcUrXaTCFMREewDrm1DweDYBak3Z | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 3.07874904 SOL ``` To see additional details of your deployed program, copy the program ID and look it up in the [Solana Devnet Explorer](https://solscan.io/?cluster=devnet). Now that the program is onchain, you can call it. ### [Call the deployed program](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#call-the-deployed-program) Use your deployed program to retrieve price data from a Chainlink data feed on Solana Devnet. For this example, call your deployed program using the [`client.js` example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/client.js) code. 1. Set the [Anchor environment variables](https://www.twilio.com/en-us/blog/how-to-set-environment-variables-html). Anchor uses these to determine which wallet to use and Solana cluster to use. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com && export ANCHOR_WALLET=./id.json ``` 2. Run the `client.js` example and pass the program address in using the `--program` flag: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node client.js --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json) ``` If the script executes correctly, you will see output with the current price of SOL / USD. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell ⋮ Price Is: 96.79778375 Success ⋮ ``` 3. Each request costs an amount of SOL that is subtracted from the `id.json` wallet. Run `solana balance` to check the remaining balance for your temporary wallet on Devnet. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana balance --keypair ./id.json --url devnet ``` 4. To get prices for a different asset pair, run `client.js` again and add the `--feed` flag with one of the available [Chainlink data feeds](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana). For example, to get the price of BTC / USD on Devnet, use the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node client.js \ --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json) \ --feed CzZQBrJCLqjXRfMjRN3fhbxur2QYHUzkpaRwkWsiPqbz ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell Price Is: 12.4215826 Success ``` The program that owns the data feeds is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), which you can see defined for `const CHAINLINK_PROGRAM_ID` in the `client.js` file. ### [Clean up](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana\#clean-up) After you are done with your deployed contract and no longer need it, it is nice to close the program and withdraw the Devnet SOL tokens for future use. In a production environment, you will want to withdraw unused SOL tokens from any Solana program that you no longer plan to use, so it is good to practice the process when you are done with programs on Devnet. 1. Run `solana program show` to see the list of deployed programs that your wallet owns and the balances for each of those programs: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana program show --programs --keypair ./id.json --url devnet ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell Program Id | Slot | Authority | Balance GRt21UnJFHZvcaWLbcUrXaTCFMREewDrm1DweDYBak3Z | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 3.07874904 SOL ``` 2. Run `solana program close` and specify the program that you want to close: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet ``` The program closes and the remaining SOL is transferred to your temporary wallet. 3. If you have deployments that failed, they might still be in the buffer holding SOL tokens. Run `solana program show` again with the `--buffers` flag: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana program show --buffers --keypair ./id.json --url devnet ``` If you have open buffers, they will appear in the list. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell Buffer Address | Authority | Balance CSc9hnBqYJoYtBgsryJAmrjAE6vZ918qaFhL6N6BdEmB | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 1.28936088 SOL ``` 4. If you have any buffers that you do not plan to finish deploying, run the same `solana program close` command to close them and retrieve the unused SOL tokens: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet ``` 5. Check the balance on your temporary wallet. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana balance --keypair ./id.json --url devnet ``` 6. If you are done using this wallet for examples and testing, you can use [`solana transfer`](https://docs.solana.com/cli/transfer-tokens) to send the remaining SOL tokens to your default wallet or another Solana wallet that you use. For example, if your default wallet keypair is at `~/.config/solana/id.json`, you can send `ALL` of the temporary wallet's balance with the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana transfer ~/.config/solana/id.json ALL --keypair ./id.json --url devnet ``` Alternatively, you can send the remaining balance to a web wallet. Specify the public key for your wallet instead of the path the default wallet keypair. Now you can use those Devnet funds for other examples and development. To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://www.anchor-lang.com/). ## What's next - [\> Use Data Feeds Offchain](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain) - [\> See the available data feeds on Solana](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) ## Get the latest Chainlink content straight to your inbox. Email Address ## Read Data from Starknet [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # [Read Data from Data Feeds on Starknet using Starknet Foundry](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/read-data\#overview) In this example, you will read from a Chainlink price feed on Starknet using the Starknet Foundry toolkit. You will call the `latest_round_data` function on the ETH / USD aggregator proxy contract to read the latest round of data. ## [Requirements](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/read-data\#requirements) Make sure you have the [Starknet Foundry](https://github.com/foundry-rs/starknet-foundry) toolkit installed. You can check your current version by running `snforge --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) or `sncast --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal. Follow the [installation](https://github.com/foundry-rs/starknet-foundry#installation) guide if necessary. ## [Tutorial](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/read-data\#tutorial) Run the following command to read data from the ETH / USD data feed proxy contract: ```bash sncast \ --url https://starknet-sepolia.public.blastapi.io/rpc/v0_7 \ call \ --contract-address 0x228128e84cdfc51003505dd5733729e57f7d1f7e54da679474e73db4ecaad44 \ --function "latest_round_data" \ ``` Expect an output similar to the following: ```bash command: call response: [0x10000000000000000000000000000320c, 0x5293770eb1, 0xd44d, 0x6606b8cc, 0x6606b8a2] ``` The example output contains an array with the hex-encoded latest round of data for the ETH / USD price feed. The array contains the following values: | Value name | Hex-encoded value | Decoded value | Description | | --- | --- | --- | --- | | `round_id` | `0x10000000000000000000000000000320c` | `340282366920938463463374607431768224268` | The unique identifier of the data round | | `answer` | `0x5293770eb1` | `354661371569` | The actual data provided by the data feed, representing the latest price of an asset in the case of a price feed | | `block_num` | `0xd44d` | `54349` | The block number at which the data was recorded on the blockchain | | `started_at` | `0x6606b8cc` | `1711716556` | The Unix timestamp indicating when the data round started | | `updated_at` | `0x6606b8a2` | `1711716514` | The Unix timestamp indicating when the data was last updated | For a complete list of Chainlink Price Feeds available on Starknet, see the [Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) page. Note: This example uses a [Blast API](https://blastapi.io/public-api/starknet) RPC endpoint. You can interact with the network using any other Starknet Sepolia RPC provider, such as [Alchemy](https://www.alchemy.com/starknet) or [Infura](https://www.infura.io/networks/ethereum/starknet). ## What's next - [\> Starknet Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) - [\> Deploy and interact with a Consumer Contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract) - [\> Experiment with Starknet Devnet RS](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs) ## Get the latest Chainlink content straight to your inbox. Email Address ## Starknet Consumer Contract Guide [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Deploy and Interact with a Consumer Contract using Starknet Foundry](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#overview) This example uses a local OpenZeppelin account to deploy and interact with a consumer contract onchain. This contract retrieves data from a specified Chainlink data feed on Starknet Sepolia and stores the information for the latest round of data. ## [Requirements](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#requirements) ### [Set up your environment](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#set-up-your-environment) This guide uses the [Starknet Foundry](https://github.com/foundry-rs/starknet-foundry) toolkit and the [Scarb](https://github.com/software-mansion/scarb) project management tool so you can compile, deploy, and interact with your Starknet smart contracts. - **Starknet Foundry**: Install Starknet Foundry **v0.21.0**. You can check your current version by running `snforge --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) or `sncast --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal and [install the required version](https://github.com/foundry-rs/starknet-foundry#installation) if necessary. - **Scarb**: Install Scarb **v2.6.4**. You can check your current version by running `scarb --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal and [install the required version](https://docs.swmansion.com/scarb/download.html#install-via-installation-script) if necessary. Alternatively, you can use the [asdf](https://asdf-vm.com/guide/introduction.html) tool version manager to install both Starknet Foundry and Scarb. Read the setup instructions for [Starknet Foundry](https://github.com/foundry-rs/asdf-starknet-foundry) and [Scarb](https://docs.swmansion.com/scarb/download.html#install-via-asdf) for more information. ### [Clone and configure the code examples repository](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#clone-and-configure-the-code-examples-repository) 1. Clone the [chainlink-starknet](https://github.com/smartcontractkit/chainlink-starknet/) repository, which includes the example contracts for this guide: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash git clone https://github.com/smartcontractkit/chainlink-starknet.git ``` 2. Navigate to the `aggregator_consumer` directory: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash cd chainlink-starknet/examples/contracts/aggregator_consumer/ ``` After you prepare the requirements, make sure the required tools are configured correctly by running the tests: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make test ``` The contracts should compile successfully and the tests should pass. ## [Tutorial](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#tutorial) ### [Create, deploy, and fund an account](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#create-deploy-and-fund-an-account) 1. Run the [`create-account`](https://github.com/smartcontractkit/chainlink-starknet/blob/c97baa6e52c7e6e01ea0235bf0e71abae23e3c00/examples/contracts/aggregator_consumer/Makefile#L22) script to create a new OpenZeppelin local account for the Sepolia testnet: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make create-account ``` The account details are stored locally in your `~/.starknet_accounts/starknet_open_zeppelin_accounts.json` file. Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash command: account create address: 0x3e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d max_fee: 9529927566560 message: Account successfully created. Prefund generated address with at least tokens. It is good to send more in the case of higher demand. Your accounts: { "alpha-sepolia": { "testnet-account": { "address": "0x3e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d", "class_hash": "0x4c6d6cf894f8bc96bb9c525e6853e5483177841f7388f74a46cfda6f028c755", "deployed": false, "legacy": false, "private_key": , "public_key": "0x2972c3cb7aa85403fa1e038f9ce7a93f025ea57017eb7ef735bae989bfb15bd", "salt": "0x61a062d2dd4e7656" } } } ``` From the output, note: - Your account address. In this example, it is `0x03e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d`, with an added zero after `0x`. - The `max_fee` value, which is the minimum amount of testnet ETH required to deploy the account. 2. Fund the newly created account with testnet ETH to cover the account deployment, the consumer contract deployment, and the network interaction costs. Go to the Blast [Starknet Sepolia ETH Faucet](https://blastapi.io/faucets/starknet-sepolia-eth) and enter your account address to receive testnet ETH. Wait a few seconds for the transaction to complete. Alternatively, you can transfer ETH tokens from a Starknet-compatible wallet, such as [Argent](https://www.argent.xyz/) or [Braavos](https://braavos.app/), or use the [StarkGate bridge](https://starkgate.starknet.io/) to transfer testnet ETH from Ethereum Sepolia to Starknet Sepolia. If you need testnet ETH on Ethereum Sepolia, you can use the [Chainlink faucet](https://faucets.chain.link/sepolia). 3. Deploy your account to Starknet Sepolia: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make deploy-account ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash command: account deploy transaction_hash: 0x541ffae49f77dd942376391286052d9fb87dc8d6848139ab1508c114e3aa005 ``` Wait a few seconds for the transaction to complete. ### [Deploy and interact with a consumer contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/consumer-contract\#deploy-and-interact-with-a-consumer-contract) The consumer contract contains two functions that you interact with in this example: - `set_answer` retrieves the latest `answer` from the specified aggregator contract and stores it in the `_answer` internal storage variable. - `read_answer` reads the stored `_answer` value. 1. Navigate to `/scripts/src/consumer/` and open the [`deploy_aggregator_consumer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/deploy_aggregator_consumer.cairo) script. 2. Update the `aggregator_address` variable within the `main` function with the ETH / USD Chainlink proxy aggregator contract address on Starknet Sepolia : `0x228128e84cdfc51003505dd5733729e57f7d1f7e54da679474e73db4ecaad44`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg). 3. Run the [`deploy_aggregator_consumer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/deploy_aggregator_consumer.cairo) script to deploy a consumer contract to Starknet Sepolia. Use the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ac-deploy NETWORK=testnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Declaring and deploying AggregatorConsumer Declaring contract... Class hash = 2231728956022539490111802723283413449895905447951536434260474920103409356221 Deploying contract... Transaction hash = 0x46b39d79cf90ed75fbae5d097d6026cf7ab1184e852d36aed336528fc77220d Waiting for transaction to be accepted (59 retries / 295s left until timeout) AggregatorConsumer deployed at address: 2956260449156927152048242588422796467290585049226993045191257886158889626959 command: script run status: success ``` The consumer address is represented in its decimal form: `2956260449156927152048242588422796467290585049226993045191257886158889626959`. You can use a [converter tool](https://www.rapidtables.com/convert/number/decimal-to-hex.html) to get the hexadecimal format. In this example, the hexadecimal equivalent is `0x06892f22691473dc5a413a7626062604155516ec91a82d3734dc68bcf3d72d4f`. Save your consumer address for the next steps. 4. In `/scripts/src/consumer/`, open the [`set_answer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/set_answer.cairo) script and update the `consumer_address` variable with your deployed consumer address. 5. Run the following command to update the answer: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ac-set-answer NETWORK=testnet ``` This command runs the [`set_answer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/set_answer.cairo) script to retrieve the latest `answer` from the ETH / USD aggregator contract and stores it in the internal storage variable `_answer` of your consumer contract. Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Result::Ok(CallResult { data: [3374557091160001179079409876363576078229871685244120671563970051729036896526] }) Result::Ok(CallResult { data: [340282366920938463463374607431768224268, 354661371569, 54349, 1711716556, 1711716514] }) Transaction hash = 0x20edd6388041d78a36f153a7694fd8c0849d81aff3fc2d5a0606d7275ea4837 Waiting for transaction to be accepted (59 retries / 295s left until timeout) Result::Ok(InvokeResult { transaction_hash: 930889525374955449815155593419397099236202282693723934594292211164864202807 }) command: script run status: success ``` 6. In `/scripts/src/consumer/`, open the [`read_answer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/read_answer.cairo) script and update the `consumer_address` variable with your deployed consumer address. 7. Run the following command to read the stored `answer` value from your consumer contract: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ac-read-answer NETWORK=testnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Result::Ok(CallResult { data: [354661371569] }) command: script run status: success ``` The answer on the ETH / USD feed uses 8 decimal places, so an answer of `354661371569` indicates an ETH / USD price of `3546.61371569`. Each feed uses a different number of decimal places for answers. You can find the correct number of decimal places on the [Price Feed addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) page by clicking the Show more details checkbox. ## What's next - [\> Starknet Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) - [\> Experiment with Starknet Devnet RS](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs) ## Get the latest Chainlink content straight to your inbox. Email Address ## SmartData Feed Addresses [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses?page=1&testnetPage=1\#overview) To learn how to use these feeds, see the [SmartData Feeds documentation.](https://docs.chain.link/data-feeds/smartdata/) For LINK token and Faucet details, see the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. ### [Risks for Proof of Reserve feeds using the wallet address manager](https://docs.chain.link/data-feeds/smartdata/addresses?page=1&testnetPage=1\#risks-for-proof-of-reserve-feeds-using-the-wallet-address-manager) Cross-chain Proof of Reserve feeds using wallet address manager contracts can vary in their configurations. If the wallet address manager is self-reporting, these feeds might include reserve balances from onchain addresses that have not been cryptographically verified to show ownership or control. In circumstances where cryptographically verified ownership is not provided, there is a risk that token issuers could manipulate the value of a Proof of Reserve feed by adding more addresses to the address list even if they do not directly control these addresses. Each feed’s specific configuration is documented in the contract address section. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ### [Data Feed Best Practices](https://docs.chain.link/data-feeds/smartdata/addresses?page=1&testnetPage=1\#data-feed-best-practices) Before you use Data Feeds, read and understand the best practices on the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) page. For best practices about data for specific asset types, see the following sections: - [Best Practices for ETF and Forex feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#etf-and-forex-feeds) - [Best Practices for Exchange Rate Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#exchange-rate-feeds) - [Risk Categories](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories) ## [Networks](https://docs.chain.link/data-feeds/smartdata/addresses?page=1&testnetPage=1\#networks) ![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum![](https://docs.chain.link/assets/chains/avalanche.svg)Avalanche![](https://docs.chain.link/assets/chains/base.svg)Base![](https://docs.chain.link/assets/chains/bnb-chain.svg)BNB Chain![](https://docs.chain.link/assets/chains/ethereum.svg)Ethereum![](https://docs.chain.link/assets/chains/polygon.svg)Polygon![](https://docs.chain.link/assets/chains/scroll.svg)Scroll![](https://docs.chain.link/assets/chains/solana.svg)Solana Track the status of this network at [https://ethstats.dev/](https://ethstats.dev/) ### [Ethereum Mainnet](https://docs.chain.link/data-feeds/smartdata/addresses?page=1&testnetPage=1\#ethereum-mainnet) SmartData Type Show more details ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds Offchain [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Using Data Feeds Offchain (Solana)](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#overview) Chainlink Data Feeds are the quickest way to access market prices for real-world assets. This guide demonstrates how to read Chainlink Data Feeds on the Solana Devnet using offchain examples in the [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). To learn how to use Data Feeds in your onchain Solana programs, see the [Using Data Feeds onchain](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana) guide. To get the full list of Chainlink Data Feeds on Solana, see the [Solana Feeds](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) page. ## [The Chainlink Data Feeds Store Program](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#the-chainlink-data-feeds-store-program) The program that contains the logic required for the storing and retrieval of Chainlink Data Feeds data on both Devnet and Mainnet is [cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ](https://solscan.io/account/cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ?cluster=devnet). This is the program ID that you use to read price data from offchain. You can find the source code for this program in the [smartcontractkit/chainlink-solana](https://github.com/smartcontractkit/chainlink-solana/tree/develop/contracts/programs/store/src) on GitHub. You can [add data feeds to an existing offchain project](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain#adding-data-feeds-to-an-existing-offchain-project) or [use the Solana Starter Kit](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain#using-the-solana-starter-kit). ## [Adding Data Feeds to an existing offchain project](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#adding-data-feeds-to-an-existing-offchain-project) You can read Chainlink Data Feeds offchain in your existing project by using the [Chainlink Solana NPM library](https://www.npmjs.com/package/@chainlink/solana-sdk). Install the necessary components and include the example code in your project. Optionally, you can run the example code by itself to learn how it works before you integrate it with your project. 1. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell sh -c "$(curl -sSfL https://release.solana.com/v1.13.6/install)" && export PATH="~/.local/share/solana/install/active_release/bin:$PATH" ``` Run `solana --version` to make sure the Solana CLI is installed correctly. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana --version ``` 2. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node --version ``` 3. Change to your project directory or create a new directory. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell mkdir off-chain-project && cd off-chain-project ``` 4. Optionally [install Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to use as a package manager and initialize yarn if your project does not already have a `package.json` file: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell npm install -g yarn && yarn init ``` 5. Add the [Anchor library](https://www.npmjs.com/package/@project-serum/anchor) to your project: npmyarn ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell npm i @project-serum/anchor ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn add @project-serum/anchor ``` 6. Add the [Chainlink Solana NPM library](https://www.npmjs.com/package/@chainlink/solana-sdk) to your project: npmyarn ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell npm i -g @chainlink/solana-sdk ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn add @chainlink/solana-sdk ``` 7. [Create a temporary Solana wallet](https://solana.com/docs/intro/installation#create-wallet) to use for this example. Alternatively, if you have an existing wallet that you want to use, locate the path to your keypair file and use it as the keypair for the rest of this guide. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana-keygen new --outfile ./id.json ``` 8. Set the [Anchor environment variables](https://www.twilio.com/en-us/blog/how-to-set-environment-variables-html). Anchor uses these to determine which wallet to use and how to get a connection to a Solana cluster. Because this example does not generate or sign any transactions, no lamports are required. The wallet is required only by the Anchor library. For a list of available networks and endpoints, see the [Solana Cluster RPC Endpoints](https://docs.solana.com/cluster/rpc-endpoints) documentation. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com && export ANCHOR_WALLET=./id.json ``` 9. Copy the sample code into your project. This example queries price data offchain. By default, the script reads the SOL/USD feed, but you can change the `CHAINLINK_FEED_ADDRESS` variable to point to the [feed account addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) that you want to query. You can take the components of these code samples and integrate them with your existing project. Because these examples read data feeds without making any onchain changes, no lamports are required to run them. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const anchor = require("@project-serum/anchor") const chainlink = require("@chainlink/solana-sdk") const provider = anchor.AnchorProvider.env() async function main() { anchor.setProvider(provider) const CHAINLINK_FEED_ADDRESS = "99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR" const CHAINLINK_PROGRAM_ID = new anchor.web3.PublicKey("cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ") const feedAddress = new anchor.web3.PublicKey(CHAINLINK_FEED_ADDRESS) //SOL-USD Devnet Feed //load the data feed account let dataFeed = await chainlink.OCR2Feed.load(CHAINLINK_PROGRAM_ID, provider) let listener = null //listen for events agains the price feed, and grab the latest rounds price data listener = dataFeed.onRound(feedAddress, (event) => { console.log(event.answer.toNumber()) }) //block execution and keep waiting for events to be emitted with price data await new Promise(function () {}) } main().then( () => process.exit(), (err) => { console.error(err) process.exit(-1) } ) ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ import * as anchor from "@project-serum/anchor" import { OCR2Feed } from "@chainlink/solana-sdk" async function main() { const provider = anchor.AnchorProvider.env() anchor.setProvider(provider) const CHAINLINK_FEED_ADDRESS = "99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR" const CHAINLINK_PROGRAM_ID = new anchor.web3.PublicKey("cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ") const feedAddress = new anchor.web3.PublicKey(CHAINLINK_FEED_ADDRESS) //SOL-USD Devnet Feed //load the data feed account let dataFeed = await OCR2Feed.load(CHAINLINK_PROGRAM_ID, provider) let listener: null | number = null //listen for events agains the price feed, and grab the latest rounds price data listener = dataFeed.onRound(feedAddress, (event) => { console.log(event.answer.toNumber()) }) //block execution and keep waiting for events to be emitted with price data await new Promise(function () {}) } main().then( () => process.exit(), (err) => { console.error(err) process.exit(-1) } ) ``` You can run these examples using the following commands: JavascriptTypescript ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node javascript-example.js ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn add ts-node typescript && yarn ts-node typescript-example.ts ``` To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://book.anchor-lang.com/). ## [Using the Solana Starter Kit](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#using-the-solana-starter-kit) This example reads price data from an offchain client using the [Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). ### [Install the required tools](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#install-the-required-tools) Before you begin, set up your environment for development on Solana: 1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if it is not already configured on your system. 2. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell sh -c "$(curl -sSfL https://release.solana.com/v1.13.6/install)" && export PATH="~/.local/share/solana/install/active_release/bin:$PATH" ``` Run `solana --version` to make sure the Solana CLI is installed correctly. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana --version ``` 3. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node --version ``` 4. [Install Anchor](https://www.anchor-lang.com/docs/installation). On some operating systems, you might need to build and install Anchor locally. See the [Anchor documentation](https://www.anchor-lang.com/docs) for instructions. 5. Install [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to simplify package management and run code samples in the Starter Kit. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell npm install -g yarn ``` ### [Run the example program](https://docs.chain.link/data-feeds/solana/using-data-feeds-off-chain\#run-the-example-program) After you install the required tools, clone the example code from the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository. 1. In a terminal, clone the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository and change to the `solana-starter-kit` directory: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell git clone https://github.com/smartcontractkit/solana-starter-kit && cd ./solana-starter-kit ``` You can see the complete code for the example on [GitHub](https://github.com/smartcontractkit/solana-starter-kit/). 2. In the `./solana-starter-kit` directory, install Node.js dependencies defined in the `package.json` file: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn install ``` 3. Create a temporary Solana wallet file to use for this example. Because your application runs offchain and does not run any functions or alter data onchain, the wallet does not require any SOL tokens to function. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell solana-keygen new --outfile ./id.json ``` 4. Set the [Anchor environment variables](https://www.twilio.com/en-us/blog/how-to-set-environment-variables-html). Anchor uses these to determine which wallet to use and Solana cluster to use. Take note that because we are not generating or signing any transactions, the wallet isn't used, it's just required by the Anchor library. For a list of available networks and endpoints, see the [Solana Cluster RPC Endpoints](https://docs.solana.com/cluster/rpc-endpoints) documentation. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com && export ANCHOR_WALLET=./id.json ``` 5. Run the example: JavascriptTypescript ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell node read-data.js ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```shell yarn run read-data ``` The example code retrieves and prints the current price feed data until you close the application: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```plaintext 4027000000 4026439929 4026476542 4023000000 ``` To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://book.anchor-lang.com/). ## What's next - [\> Use data feeds onchain](https://docs.chain.link/data-feeds/solana/using-data-feeds-solana) - [\> See the available data feeds on Solana](https://docs.chain.link/data-feeds/price-feeds/addresses?network=solana) ## Get the latest Chainlink content straight to your inbox. Email Address ## Starknet Devnet RS Guide [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Experiment with Data Feeds using Starknet Foundry and Starknet Devnet RS](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#overview) This guide employs [Starknet Devnet RS](https://github.com/0xSpaceShard/starknet-devnet-rs), a local Docker-based testnet environment for Starknet. It provides code examples, [scripts](https://github.com/smartcontractkit/chainlink-starknet/tree/develop/examples/contracts/aggregator_consumer/scripts/src), and [commands](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/Makefile) that enable you to deploy and experiment with your own aggregator and consumer contracts. You can use a set of prefunded accounts to interact with Chainlink Data Feeds on Starknet without deploying to a live network. ## [Requirements](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#requirements) ### [Set up your environment](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#set-up-your-environment) This guide uses the [Starknet Foundry](https://github.com/foundry-rs/starknet-foundry) toolkit and the [Scarb](https://github.com/software-mansion/scarb) project management tool so you can compile, deploy, and interact with your Starknet smart contracts. - **Starknet Foundry**: Install Starknet Foundry **v0.21.0**. You can check your current version by running `snforge --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) or `sncast --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal and [install the required version](https://github.com/foundry-rs/starknet-foundry#installation) if necessary. - **Scarb**: Install Scarb **v2.6.4**. You can check your current version by running `scarb --version`![Copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) in your terminal and [install the required version](https://docs.swmansion.com/scarb/download.html#install-via-installation-script) if necessary. Alternatively, you can use the [asdf](https://asdf-vm.com/guide/introduction.html) tool version manager to install both Starknet Foundry and Scarb. Read the setup instructions for [Starknet Foundry](https://github.com/foundry-rs/asdf-starknet-foundry) and [Scarb](https://docs.swmansion.com/scarb/download.html#install-via-asdf) for more information. - **Docker**: Install [Docker Desktop](https://docs.docker.com/get-docker/). You will run Starknet Devnet RS in a Docker container. ### [Clone and configure the code examples repository](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#clone-and-configure-the-code-examples-repository) 1. Clone the [chainlink-starknet](https://github.com/smartcontractkit/chainlink-starknet/) repository, which includes the example contracts for this guide: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash git clone https://github.com/smartcontractkit/chainlink-starknet.git ``` 2. Navigate to the `aggregator_consumer` directory: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash cd chainlink-starknet/examples/contracts/aggregator_consumer/ ``` 3. Open your `snfoundry.toml` file and locate the `[sncast.devnet]` section. Make sure the `url` points to the correct endpoint for connecting to the Starknet node running inside the Docker container. By default, it is: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash [sncast.default] url = "http://127.0.0.1:5050/rpc" ``` After you prepare the requirements, check to make sure the required tools are configured correctly by running the tests: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make test ``` The contracts should compile successfully and the tests should pass. ## [Tutorial](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#tutorial) ### [Run Starknet Devnet RS and add a prefunded account](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#run-starknet-devnet-rs-and-add-a-prefunded-account) 1. Make sure Docker Desktop is running. 2. Execute the following command to run a Starknet Devnet RS container: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make devnet ``` Note: Executing this command when a container is running stops and recreates the container, which helps restart from a clean state. 3. The Starknet devnet container includes a set of prefunded accounts. To execute the scripts from this guide, add one of these accounts to a local `accounts.json` file by running the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make add-account ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Importing a prefunded account from starknet devnet container... command: account add Your accounts: { "alpha-goerli": { "devnet-account": { "address": "0x4b3f4ba8c00a02b66142a4b1dd41a4dfab4f92650922a3280977b0f03c75ee1", "class_hash": "0x61dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f", "deployed": true, "legacy": false, "private_key": "0x57b2f8431c772e647712ae93cc616638", "public_key": "0x374f7fcb50bc2d6b8b7a267f919232e3ac68354ce3eafe88d3df323fc1deb23" } } } ``` ### [Deploy and interact with a mock aggregator contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#deploy-and-interact-with-a-mock-aggregator-contract) 1. Declare and deploy a mock aggregator contract to the devnet by using the [`deploy_mock_aggregator`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/mock_aggregator/deploy_mock_aggregator.cairo) script. Run the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ma-deploy NETWORK=devnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Declaring and deploying MockAggregator Declaring contract... Transaction hash = 0x1d4cb925322e0f9645cf0bf4028b7fca963b5325cc685784c0f6e22628de8ad Class hash = 3238358970964595466962588940073124312643094641461979698784985925711454737896 Deploying contract... Transaction hash = 0x6b065766a26105fbd9bf55be46675d2c2b4b0dd9a85db5ab0b6a1f8ad04f743 MockAggregator deployed at address: 1708487128334545444076626254389547159540422020354796381590079145465639129383 command: script run status: success ``` 2. Read the latest round of data by using the [`read_latest_round`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/aggregator/read_latest_round.cairo) script. Run the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make agg-read-latest-round NETWORK=devnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Result::Ok(CallResult { data: [0, 0, 0, 0, 0] }) command: script run status: success ``` The default data on the mock aggregator contract is all set to zeros. 3. Set the latest round of data to values defined in the [`set_latest_round`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/mock_aggregator/set_latest_round.cairo) script. Run the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ma-set-latest-round NETWORK=devnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Transaction hash = 0x3f01f4595dcf20b4f355720540d5279efc0fff306d4e848dda4550cdd2a5367 Result::Ok(InvokeResult { transaction_hash: 1781197671452105104356220458359085564429259248315865550090042149835146679143 }) command: script run status: success ``` 4. Read the latest round of data again to verify the updated values: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make agg-read-latest-round NETWORK=devnet ``` Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Result::Ok(CallResult { data: [1, 1, 12345, 1711716556, 1711716514] }) command: script run status: success ``` ### [Deploy and interact with a mock aggregator and a mock consumer contract](https://docs.chain.link/data-feeds/starknet/tutorials/snfoundry/sn-devnet-rs\#deploy-and-interact-with-a-mock-aggregator-and-a-mock-consumer-contract) The mock aggregator consumer contract is initialized with the address of an aggregator mock contract during the contract's constructor call and contains two functions: - `set_answer` retrieves the latest `answer` from the specified aggregator contract and stores it in the internal storage variable `_answer`. - `read_answer` reads the stored `_answer` value. 1. Run the following command to (re)start the Starknet Devnet RS container: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make devnet ``` 2. If you haven't already, add a prefunded account to the local `accounts.json` file using the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make add-account ``` 3. Declare and deploy both a mock aggregator and a consumer contracts to the devnet by running the following command: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make devnet-deploy ``` This command executes both [`deploy_mock_aggregator`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/mock_aggregator/deploy_mock_aggregator.cairo) and [`deploy_aggregator_consumer`](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/scripts/src/consumer/deploy_aggregator_consumer.cairo) scripts. Expect an output similar to the following: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash Declaring and deploying MockAggregator Declaring contract... Transaction hash = 0x568d29d07128cba750845b57a4bb77a31f628b6f4288861d8b31d12e71e4c3b Deploying contract... Transaction hash = 0xfbc49eb82894a704ce536ab904cdee0fd021b0fba335900f8b9b12cfcd005f MockAggregator deployed at address: 1566652744716179301065270359129119857774335542042051464747302084192731701184 command: script run status: success Declaring and deploying AggregatorConsumer Declaring contract... Transaction hash = 0x3f11f08103e263690b1eeac76c25ce7b003c86d2d1c0492815d1ddb39f58e8e Deploying contract... Transaction hash = 0xfe5b1ed51a435117098343b5d0fdc1c32fd493f1220ff2c69c732f5bb805d8 AggregatorConsumer deployed at address: 2775662320989421053891107164335108610292525354452508848326323790006553228656 command: script run status: success ``` Once the contracts are deployed, experiment with both contracts and the available [scripts](https://github.com/smartcontractkit/chainlink-starknet/tree/develop/examples/contracts/aggregator_consumer/scripts/src) and [commands](https://github.com/smartcontractkit/chainlink-starknet/blob/develop/examples/contracts/aggregator_consumer/Makefile) as needed for your projects. For instance, you can set new values for the latest round of data on the aggregator contract, retrieve and set the `answer` on the consumer contract, and read the `answer` from the consumer contract: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```bash make ma-set-latest-round NETWORK=devnet && make ac-set-answer NETWORK=devnet && make ac-read-answer NETWORK=devnet ``` ## What's next - [\> Starknet Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=starknet) ## Get the latest Chainlink content straight to your inbox. Email Address ## Deprecation of Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Deprecation of Chainlink Data Feeds](https://docs.chain.link/data-feeds/deprecating-feeds\#overview) The smart contract ecosystem is constantly evolving. As a result, Data Feeds within the Chainlink ecosystem are continuously evaluated for their usage and economic viability across all the blockchains and layer-2 networks they are deployed on. Data Feeds with low or no usage or feeds that do not have a viable path to economic sustainability may be scheduled for deprecation. Doing so helps preserve blockchains as public goods by optimizing blockspace usage. It also helps to reduce unnecessary costs incurred by Chainlink node operators. This process is part of a broader ecosystem shift towards Chainlink Economics 2.0, designed to maximize the adoption of the Chainlink protocol while optimizing for cost-efficiency and long-term economic sustainability. Over time, new Data Feeds may be launched or relocated to alternative blockchains/layer-2s that better reflect current user demand. For status updates regarding Data Feeds, users should join the official Chainlink Discord and subscribe to the [data-feeds-user-notifications channel](https://discord.gg/Dqy5N9UbsR). Users with additional questions are encouraged to reach out [here](https://chainlinkcommunity.typeform.com/s/dataFeedQs). A list of data feeds designated for deprecation along with their corresponding shutdown date can be found below. ## [Networks](https://docs.chain.link/data-feeds/deprecating-feeds\#networks) **No data feeds are scheduled for deprecation at this time.** ## Get the latest Chainlink content straight to your inbox. Email Address ## Price Feed Addresses [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Price Feed Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=bnb-chain&page=1&search=0xa767f745331D267c7751297D982b050c93985627\#overview) To learn how to use these feeds, see the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) guide. For LINK token and Faucet details, see the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. ### [Data Feed Best Practices](https://docs.chain.link/data-feeds/price-feeds/addresses?network=bnb-chain&page=1&search=0xa767f745331D267c7751297D982b050c93985627\#data-feed-best-practices) Before you use Data Feeds, read and understand the best practices on the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) page. For best practices about data for specific asset types, see the following sections: - [Best Practices for ETF and Forex feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#etf-and-forex-feeds) - [Best Practices for Exchange Rate Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#exchange-rate-feeds) - [Risk Categories](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories) ## [Networks](https://docs.chain.link/data-feeds/price-feeds/addresses?network=bnb-chain&page=1&search=0xa767f745331D267c7751297D982b050c93985627\#networks) ![](https://docs.chain.link/assets/chains/aptos.svg)Aptos![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum![](https://docs.chain.link/assets/chains/avalanche.svg)Avalanche![](https://docs.chain.link/assets/chains/base.svg)Base![](https://docs.chain.link/assets/chains/bnb-chain.svg)BNB Chain![](https://docs.chain.link/assets/chains/botanix.svg)Botanix![](https://docs.chain.link/assets/chains/celo.svg)Celo![](https://docs.chain.link/assets/chains/ethereum.svg)Ethereum![](https://docs.chain.link/assets/chains/fantom.svg)Fantom![](https://docs.chain.link/assets/chains/gnosis-chain.svg)Gnosis Chain (xDai)![](https://docs.chain.link/assets/chains/hedera.svg)Hedera![](https://docs.chain.link/assets/chains/linea.svg)Linea![](https://docs.chain.link/assets/chains/mantle.svg)Mantle![](https://docs.chain.link/assets/chains/metis.svg)Metis![](https://docs.chain.link/assets/chains/monad.svg)Monad![](https://docs.chain.link/assets/chains/moonbeam.svg)Moonbeam![](https://docs.chain.link/assets/chains/moonriver.svg)Moonriver![](https://docs.chain.link/assets/chains/optimism.svg)OP![](https://docs.chain.link/assets/chains/polygon.svg)Polygon![](https://docs.chain.link/assets/chains/polygonzkevm.svg)Polygon zkEVM![](https://docs.chain.link/assets/chains/ronin.svg)Ronin![](https://docs.chain.link/assets/chains/scroll.svg)Scroll![](https://docs.chain.link/assets/chains/soneium.svg)Soneium![](https://docs.chain.link/assets/chains/solana.svg)Solana![](https://docs.chain.link/assets/chains/sonic.svg)Sonic![](https://docs.chain.link/assets/chains/starknet.svg)Starknet![](https://docs.chain.link/assets/chains/tron.svg)TRON![](https://docs.chain.link/assets/chains/unichain.svg)Unichain![](https://docs.chain.link/assets/chains/xlayer.svg)X Layer![](https://docs.chain.link/assets/chains/zksync.svg)ZKsync Track the status of this network at [https://ethstats.dev/](https://ethstats.dev/) ### [Ethereum Mainnet](https://docs.chain.link/data-feeds/price-feeds/addresses?network=bnb-chain&page=1&search=0xa767f745331D267c7751297D982b050c93985627\#ethereum-mainnet) Data Feed Categories Show more detailsShow SVR-enabled feeds ### [Sepolia Testnet](https://docs.chain.link/data-feeds/price-feeds/addresses?network=bnb-chain&page=1&search=0xa767f745331D267c7751297D982b050c93985627\#sepolia-testnet) Show more details ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Feed Registry [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Feed Registry API Reference](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#overview) This guide outlines the functions which can be used with Chainlink's Feed Registry. You can learn more about the feed registry [here](https://docs.chain.link/data-feeds/feed-registry). ## [Functions](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#functions) | Name | Description | | --- | --- | | [decimals](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#decimals) | The number of decimals in the response. | | [description](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#description) | The description of the aggregator that the proxy points to. | | [getRoundData](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getrounddata) | Get data from a specific round. | | [latestRoundData](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#latestrounddata) | Get data from the latest round. | | [version](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#version) | The version representing the type of aggregator the proxy points to. | | [getFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getfeed) | Returns the primary aggregator address of a base / quote pair. | | [getPhaseFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getphasefeed) | Returns the aggregator address of a base / quote pair at a specified phase. | | [isFeedEnabled](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#isfeedenabled) | Returns true if an aggregator is enabled as primary on the registry. | | [getPhase](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getphase) | Returns the raw starting and ending aggregator round ids of a base / quote pair. | | [getRoundFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getroundfeed) | Returns the underlying aggregator address of a base / quote pair at a specified round. | | [getPhaseRange](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getphaserange) | Returns the starting and ending round ids of a base / quote pair at a specified phase. | | [getPreviousRoundId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getpreviousroundid) | Returns the previous round id of a base / quote pair given a specified round. | | [getNextRoundId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getnextroundid) | Returns the next round id of a base / quote pair given a specified round. | | [getCurrentPhaseId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions#getcurrentphaseid) | Returns the current phase id of a base / quote pair. | * * * ### [decimals](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#decimals) Get the number of decimals present in the response value. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function decimals(address base, address quote) external view returns (uint8) ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters) - `base`: The base asset address. - `quote`: The quote asset address. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values) - `RETURN`: The number of decimals. ### [description](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#description) Get the description of the underlying aggregator that the proxy points to. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function description(address base, address quote) external view returns (string memory) ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-1) - `base`: The base asset address. - `quote`: The quote asset address. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-1) - `RETURN`: The description of the underlying aggregator. ### [getRoundData](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getrounddata) Get data about a specific round, using the `roundId`. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getRoundData(address base, address quote, uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-2) - `base`: The base asset address. - `quote`: The quote asset address. - `roundId`: The round ID. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-2) - `roundId`: The round ID. - `answer`: The price. - `startedAt`: Timestamp of when the round started. - `updatedAt`: Timestamp of when the round was updated. - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed ### [latestRoundData](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#latestrounddata) Get the price from the latest round. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function latestRoundData(address base, address quote) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) ``` #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-3) - `roundId`: The round ID. - `answer`: The price. - `startedAt`: Timestamp of when the round started. - `updatedAt`: Timestamp of when the round was updated. - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed ### [version](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#version) The version representing the type of aggregator the proxy points to. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function version(address base, address quote) external view returns (uint256) ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-3) - `base`: The base asset address. - `quote`: The quote asset address. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-4) - `RETURN`: The version number. ### [getFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getfeed) Returns the primary aggregator address of a base / quote pair. Note that onchain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getFeed(address base, address quote) external view returns (AggregatorV2V3Interface aggregator); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-4) - `base`: The base asset address. - `quote`: The quote asset address. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-5) - `aggregator`: The primary aggregator address. ### [getPhaseFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getphasefeed) Returns the underlying aggregator address of a base / quote pair at a specified phase. Note that onchain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts. Phase ids start at `1`. You can get the current Phase by calling `getCurrentPhaseId()`. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getPhaseFeed( address base, address quote, uint16 phaseId ) external view returns (AggregatorV2V3Interface aggregator); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-5) - `base`: The base asset address. - `quote`: The quote asset address. - `phaseId`: The phase id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-6) - `aggregator`: The primary aggregator address at the specified phase. ### [isFeedEnabled](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#isfeedenabled) Returns true if an aggregator is enabled as primary on the feed registry. This is useful to check if you should index events from an aggregator contract, because you want to only index events of primary aggregators. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function isFeedEnabled(address aggregator) external view returns (bool); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-6) - `aggregator`: The aggregator address #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-7) - `RETURN`: `true` if the supplied aggregator is a primary aggregator for any base / quote pair. ### [getPhase](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getphase) Returns the starting and ending aggregator round ids of a base / quote pair. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getPhase(address base, address quote, uint16 phaseId) external view returns (Phase memory phase); ``` Phases hold the following information: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity struct Phase { uint16 phaseId; uint80 startingAggregatorRoundId; uint80 endingAggregatorRoundId; } ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-7) - `base`: The base asset address. - `quote`: The quote asset address. - `phaseId`: The phase id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-8) - `RETURN`: `Phase` details of a base / quote pair. ### [getRoundFeed](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getroundfeed) Returns the underlying aggregator address of a base / quote pair at a specified round. Note that onchain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getRoundFeed( address base, address quote, uint80 roundId ) external view returns (AggregatorV2V3Interface aggregator); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-8) - `base`: The base asset address. - `quote`: The quote asset address. - `roundId`: The round id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-9) - `aggregator`: The underlying aggregator address of a base / quote pair at the specified round. ### [getPhaseRange](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getphaserange) Returns the starting and ending round ids of a base / quote pair at a specified phase. Please note that this `roundId` is calculated from the phase id and the underlying aggregator's round id. To get the raw aggregator round ids of a phase for indexing purposes, please use `getPhase()`. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getPhaseRange( address base, address quote, uint16 phaseId ) external view returns (uint80 startingRoundId, uint80 endingRoundId); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-9) - `base`: The base asset address. - `quote`: The quote asset address. - `phaseId`: The phase id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-10) - `startingRoundId`: The starting round id - `endingRoundId`: The ending round id ### [getPreviousRoundId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getpreviousroundid) Returns the previous round id of a base / quote pair given a specified round. Note that rounds are non-monotonic across phases. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getPreviousRoundId(address base, address quote, uint80 roundId) external view returns (uint80 previousRoundId); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-10) - `base`: The base asset address. - `quote`: The quote asset address. - `roundId`: The round id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-11) - `previousRoundId`: The previous round id of a base / quote pair. ### [getNextRoundId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getnextroundid) Returns the next round id of a base / quote pair given a specified round. Note that rounds are non-monotonic across phases. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getNextRoundId(address base, address quote, uint80 roundId) external view returns (uint80 nextRoundId); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-11) - `base`: The base asset address. - `quote`: The quote asset address. - `roundId`: The round id. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-12) - `nextRoundId`: The next round id of a base / quote pair. ### [getCurrentPhaseId](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#getcurrentphaseid) Returns the current phase id of a base / quote pair. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity function getCurrentPhaseId(address base, address quote) external view returns (uint16 currentPhaseId); ``` #### [Parameters](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#parameters-12) - `base`: The base asset address. - `quote`: The quote asset address. #### [Return values](https://docs.chain.link/data-feeds/feed-registry/feed-registry-functions\#return-values-13) - `phaseId`: The current phase id of a base / quote pair. ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds Guide [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # [Using Data Feeds on EVM Chains](https://docs.chain.link/data-feeds/using-data-feeds\#overview) The code for reading Data Feeds is the same across all EVM-compatible blockchains and Data Feed types. You choose different types of feeds for different uses, but the request and response format are the same. To read a feed, specify the following variables: - **RPC endpoint URL:** This determines which network that your smart contracts will run on. You can use a [node provider service](https://ethereum.org/en/developers/docs/nodes-and-clients/nodes-as-a-service/) or point to your own [client](https://ethereum.org/en/developers/docs/nodes-and-clients/). If you are using a Web3 wallet, it is already configured with the RPC endpoints for several networks and the [Remix IDE](https://remix-project.org/) will automatically detect them for you. - **LINK token contract address:** The address for the LINK token contract is different for each network. You can find the full list of addresses for all supported networks on the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. - **Feed contract address:** This determines which data feed your smart contract will read. Contract addresses are different for each network. You can find the available contract addresses on the following pages: - [Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) The examples in this document indicate these variables, but you can modify the examples to work on different networks and read different feeds. This guide shows example code that reads data feeds using the following languages: - Onchain consumer contracts: - [Solidity](https://docs.chain.link/data-feeds/using-data-feeds#solidity) - [Vyper](https://docs.chain.link/data-feeds/using-data-feeds#vyper) - Offchain reads using Web3 packages: - [Javascript](https://docs.chain.link/data-feeds/using-data-feeds#javascript) with [web3.js](https://web3js.readthedocs.io/) - [Python](https://docs.chain.link/data-feeds/using-data-feeds#python) with [Web3.py](https://web3py.readthedocs.io/en/stable/) - [Golang](https://docs.chain.link/data-feeds/using-data-feeds#golang) with [go-ethereum](https://github.com/ethereum/go-ethereum) ## [Reading data feeds onchain](https://docs.chain.link/data-feeds/using-data-feeds\#reading-data-feeds-onchain) These code examples demonstrate how to deploy a consumer contract onchain that reads a data feed and stores the value. ### [Solidity](https://docs.chain.link/data-feeds/using-data-feeds\#solidity) To consume price data, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED * VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ /** * If you are reading data feeds on L2 networks, you must * check the latest answer from the L2 Sequencer Uptime * Feed to ensure that the data is accurate in the event * of an L2 sequencer outage. See the * https://docs.chain.link/data-feeds/l2-sequencer-feeds * page for details. */ contract DataConsumerV3 { AggregatorV3Interface internal dataFeed; /** * Network: Sepolia * Aggregator: BTC/USD * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 */ constructor() { dataFeed = AggregatorV3Interface( 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 ); } /** * Returns the latest answer. */ function getChainlinkDataFeedLatestAnswer() public view returns (int) { // prettier-ignore ( /* uint80 roundId */, int256 answer, /*uint256 startedAt*/, /*uint256 updatedAt*/, /*uint80 answeredInRound*/ ) = dataFeed.latestRoundData(); return answer; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/DataConsumerV3.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) The `latestRoundData` function returns five values representing information about the latest price data. See the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) for more details. ### [Vyper](https://docs.chain.link/data-feeds/using-data-feeds\#vyper) To consume price data, your smart contract should import `AggregatorV3Interface` which defines the external functions implemented by Data Feeds. You can find it [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/interfaces/AggregatorV3Interface.vy). You can find a `PriceConsumer` example [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/PriceConsumer.vy). Read the _**apeworx-starter-kit**_ [README](https://github.com/smartcontractkit/apeworx-starter-kit) to learn how to run the example. ## [Reading data feeds offchain](https://docs.chain.link/data-feeds/using-data-feeds\#reading-data-feeds-offchain) These code examples demonstrate how to read data feeds directly off chain using Web3 packages for each language. ### [Javascript](https://docs.chain.link/data-feeds/using-data-feeds\#javascript) This example uses [web3.js](https://web3js.readthedocs.io/) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. web3.jsethers.js ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const Web3 = require("web3") // for nodejs only const web3 = new Web3("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const priceFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr) priceFeed.methods .latestRoundData() .call() .then((roundData) => { // Do something with roundData console.log("Latest Round Data", roundData) }) ``` ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const { ethers } = require("ethers") // for nodejs only const provider = new ethers.providers.JsonRpcProvider("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const priceFeed = new ethers.Contract(addr, aggregatorV3InterfaceABI, provider) priceFeed.latestRoundData().then((roundData) => { // Do something with roundData console.log("Latest Round Data", roundData) }) ``` Latest Price: Latest Price ### [Python](https://docs.chain.link/data-feeds/using-data-feeds\#python) This example uses [Web3.py](https://web3py.readthedocs.io/en/stable/) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity # THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. # THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. # DO NOT USE THIS CODE IN PRODUCTION. from web3 import Web3 # Change this to use your own RPC URL web3 = Web3(Web3.HTTPProvider('https://rpc.ankr.com/eth_sepolia')) # AggregatorV3Interface ABI abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]' # Price Feed address addr = '0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43' # Set up contract instance contract = web3.eth.contract(address=addr, abi=abi) # Make call to latestRoundData() latestData = contract.functions.latestRoundData().call() print(latestData) ``` ### [Golang](https://docs.chain.link/data-feeds/using-data-feeds\#golang) You can find an example with all the source files [here](https://github.com/smartcontractkit/smart-contract-examples/tree/main/pricefeed-golang). This example uses [go-ethereum](https://github.com/ethereum/go-ethereum) to retrieve feed data from the [BTC / USD feed](https://sepolia.etherscan.io/address/0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43) on the Sepolia testnet. To learn how to run the example, see the [README](https://github.com/smartcontractkit/smart-contract-examples/blob/main/pricefeed-golang/README.md). ## [Getting a different price denomination](https://docs.chain.link/data-feeds/using-data-feeds\#getting-a-different-price-denomination) Chainlink Data Feeds can be used in combination to derive denominated price pairs in other currencies. If you require a denomination other than what is provided, you can use two data feeds to derive the pair that you need. For example, if you needed a BTC / EUR price, you could take the BTC / USD feed and the EUR / USD feed and derive BTC / EUR using division. ![Request Model Diagram](https://docs.chain.link/images/price-feed-conversion-equation.gif) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * Network: Sepolia * Base: BTC/USD * Base Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 * Quote: EUR/USD * Quote Address: 0x1a81afB8146aeFfCFc5E50e8479e826E7D55b910 * Decimals: 8 */ /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract PriceConverter { function getDerivedPrice( address _base, address _quote, uint8 _decimals ) public view returns (int256) { require( _decimals > uint8(0) && _decimals <= uint8(18), "Invalid _decimals" ); int256 decimals = int256(10 ** uint256(_decimals)); (, int256 basePrice, , , ) = AggregatorV3Interface(_base) .latestRoundData(); uint8 baseDecimals = AggregatorV3Interface(_base).decimals(); basePrice = scalePrice(basePrice, baseDecimals, _decimals); (, int256 quotePrice, , , ) = AggregatorV3Interface(_quote) .latestRoundData(); uint8 quoteDecimals = AggregatorV3Interface(_quote).decimals(); quotePrice = scalePrice(quotePrice, quoteDecimals, _decimals); return (basePrice * decimals) / quotePrice; } function scalePrice( int256 _price, uint8 _priceDecimals, uint8 _decimals ) internal pure returns (int256) { if (_priceDecimals < _decimals) { return _price * int256(10 ** uint256(_decimals - _priceDecimals)); } else if (_priceDecimals > _decimals) { return _price / int256(10 ** uint256(_priceDecimals - _decimals)); } return _price; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/PriceConverter.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## [More aggregator functions](https://docs.chain.link/data-feeds/using-data-feeds\#more-aggregator-functions) Getting the latest price is not the only data that aggregators can retrieve. You can also retrieve historical price data. To learn more, see the [Historical Price Data](https://docs.chain.link/data-feeds/historical-data) page. To understand different use cases for Chainlink Price Feeds, refer to [Other Tutorials](https://docs.chain.link/getting-started/other-tutorials). ## What's next - [\> Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Chainlink Data Feeds](https://docs.chain.link/data-feeds\#overview) Chainlink Data Feeds are the quickest way to connect your smart contracts to real-world data such as asset prices, reserve balances, and L2 sequencer health. If you already started a project and need to integrate Chainlink, you can [add Chainlink to your existing project](https://docs.chain.link/resources/create-a-chainlinked-project?parent=dataFeeds#installing-into-existing-projects) with the [`@chainlink/contracts` NPM package](https://www.npmjs.com/package/@chainlink/contracts). ## [Types of data feeds](https://docs.chain.link/data-feeds\#types-of-data-feeds) Data feeds provide many different types of data for your applications. - [Price Feeds](https://docs.chain.link/data-feeds#price-feeds) - [SmartData Feeds](https://docs.chain.link/data-feeds#smartdata-feeds) - [Rate and Volatility Feeds](https://docs.chain.link/data-feeds#rate-and-volatility-feeds) - [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds#l2-sequencer-uptime-feeds) ### [Price Feeds](https://docs.chain.link/data-feeds\#price-feeds) Smart contracts often act in real-time on data such as prices of assets. This is especially true in [DeFi](https://chain.link/use-cases/defi). For example, lending and borrowing platforms like [Aave](https://aave.com/) utilize Data Feeds to assess collateral value accurately, while perpetual platforms such as [GMX](https://gmx.io/) rely on these feeds to validate offchain data and ensure that each deposit or withdrawal executes at the correct market value. Data Feeds aggregate many data sources and publish them onchain using a combination of the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) and [Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds). To learn how to use Price Feeds, see the [Price Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. See the [Data Feeds Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page for a list of available networks and addresses. ### [SmartData Feeds](https://docs.chain.link/data-feeds\#smartdata-feeds) Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. To learn more about SmartData Feeds, see the [SmartData](https://docs.chain.link/data-feeds/smartdata) documentation. See the [SmartData Contract Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page for a list of available networks and addresses. ### [Rate and Volatility Feeds](https://docs.chain.link/data-feeds\#rate-and-volatility-feeds) Several feeds provide interest rate curve data, APY data, and realized asset price volatility. To learn more, see the [Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds) documentation. See the [Rate and Volatility Contract Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page for a list of available networks and addresses. ### [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds\#l2-sequencer-uptime-feeds) L2 sequencer feeds track the last known status of the sequencer on an L2 network at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to these events. To learn how to use L2 sequencer uptime feeds, see the [L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds) documentation. ## [Components of a data feed](https://docs.chain.link/data-feeds\#components-of-a-data-feed) Data Feeds are an example of a decentralized oracle network and include the following components: - **Consumer**: A consumer is an onchain or offchain application that uses Data Feeds. Consumer contracts use the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) to call functions on the proxy contract and retrieve information from the aggregator contract. For a complete list of functions available in the `AggregatorV3Interface`, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#aggregatorv3interface). - **Proxy contract**: Proxy contracts are onchain proxies that point to the aggregator for a particular data feed. Using proxies enables the underlying aggregator to be upgraded without any service interruption to consuming contracts. Proxy contracts can vary from one data feed to another, but the [`EACAggregatorProxy.sol` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/EACAggregatorProxy.sol) on Github is a common example. - **Aggregator contract**: An aggregator is a contract that receives periodic data updates from the oracle network. Aggregators store aggregated data onchain so that consumers can retrieve it and act upon it within the same transaction. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). To learn how to create a consumer contract that uses an existing data feed, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. ## [Reading proxy and aggregator configurations](https://docs.chain.link/data-feeds\#reading-proxy-and-aggregator-configurations) Because the proxy and aggregator contracts are all onchain, you can see the current configuration by reading the variables through an [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html) or using a blockchain explorer for your network. For example, you can see the [BTC/USD proxy configuration](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) on the Ethereum network using Etherscan. If you read the BTC/USD proxy configuration, you can query all of the functions and variables that are publicly accessible for that contract including the `aggregator` address, `latestRoundData()` function, `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. To see descriptions for the proxy contract variables and functions, see the source code for your specific data feed on [Etherscan](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code#L568). The proxy contract points to an aggregator. This allows you to retrieve data through the proxy even if the aggregator is upgraded. If you view the `aggregator` address defined in the proxy configuration, you can see the aggregator and its configuration. For example, see the [BTC/USD aggregator contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code) in Etherscan. This contract includes several variables and functions, including another `latestRoundData()`. To see descriptions for the aggregator variables and functions, see the source code on [GitHub](https://github.com/smartcontractkit/libocr/blob/master/contract/AccessControlledOffchainAggregator.sol) or [Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code#F1#L1). You can call the `latestRoundData()` function directly on the aggregator, but it is a best practice to use the proxy instead so that changes to the aggregator do not affect your application. Similar to the proxy contract, the aggregator contract has a `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. ## [Components of an aggregator](https://docs.chain.link/data-feeds\#components-of-an-aggregator) The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). ## [Updates to proxy and aggregator contracts](https://docs.chain.link/data-feeds\#updates-to-proxy-and-aggregator-contracts) To accommodate the dynamic nature of offchain environments, Chainlink Data Feeds are updated from time to time to add new features and capabilities as well as respond to externalities such as token migrations, protocol rebrands, extreme market events, and upstream issues with data or node operations. These updates include changes to the aggregator configuration or a complete replacement of the aggregator that the proxy uses. If you consume data feeds through the proxy, your applications can continue to operate during these changes. Proxy and aggregator contracts all have an `owner` address that has permission to change variables and functions. For example, if you read the [BTC/USD proxy contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) in Etherscan, you can see the `owner` address. This address is a [multi-signature safe](https://docs.safe.global/getting-started/readme) (multisig) that you can also inspect. If you [view the multisig contract](https://etherscan.io/address/0x21f73D42Eb58Ba49dDB685dc29D3bF5c0f0373CA#readProxyContract) in Etherscan using the _Read as Proxy_ feature, you can see the full details of the multisig including the list of addresses that can sign and the number of signers required for the multisig to approve actions on any contracts that it owns. The multisig-coordinated upgradability of Chainlink Data Feeds involves time-tested processes that balance collusion-resistance with the flexibility required to implement improvements and swiftly react to external conditions. The approach taken to upgradability will continue to evolve over time to meet user requirements. ## [Monitoring data feeds](https://docs.chain.link/data-feeds\#monitoring-data-feeds) When you build applications and protocols that depend on data feeds, include monitoring and safeguards to protect against the negative impact of extreme market events, possible malicious activity on third-party venues or contracts, potential delays, and outages. Create your own monitoring alerts based on deviations in the answers that data feeds provide. This will notify you when potential issues occur so you can respond to them. ### [Check the latest answer against reasonable limits](https://docs.chain.link/data-feeds\#check-the-latest-answer-against-reasonable-limits) The data feed aggregator includes both [`minAnswer` and `maxAnswer` values](https://github.com/smartcontractkit/libocr/blob/9e4afd8896f365b964bdf769ca28f373a3fb0300/contract/AccessControlledOffchainAggregator.sol#L33). On most data feeds, these values are no longer used and they do not stop your application from reading the most recent answer. For monitoring purposes, you must decide what limits are acceptable for your application. Configure your application to detect when the reported answer is close to reaching reasonable minimum and maximum limits so it can alert you to potential market events. Separately, configure your application to detect and respond to extreme price volatility or prices that are outside of your acceptable limits. ### [Check the timestamp of the latest answer](https://docs.chain.link/data-feeds\#check-the-timestamp-of-the-latest-answer) Chainlink Data Feeds do not provide streaming data. Rather, the aggregator updates its `latestAnswer` when the value deviates beyond a specified threshold or when the heartbeat idle time has passed. You can find the heartbeat and deviation values for each data feed at [data.chain.link](https://data.chain.link/) or in the [Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) lists. Your application should track the `latestTimestamp` variable or use the `updatedAt` value from the `latestRoundData()` function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay. When the node detects that the heartbeat is reached, it initiates the latest round. Depending on congestion and network conditions, there may be a slight delay for the latest round to get onchain. During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application. Users should build applications with the understanding that data feeds for wrapped or liquid staking assets might have different heartbeat and deviation thresholds than that of the underlying asset. Heartbeat and deviation thresholds can also differ for the same asset across different blockchains. Combining data from multiple feeds, even those with a common denominator, might result in a margin of error that users must account for in their risk mitigation practices. To learn more about the heartbeat and deviation threshold, read the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## What's next - [\> Follow the Data Feeds Getting Started guide to learn the basics](https://docs.chain.link/data-feeds/getting-started) - [\> Read the API reference for using Data Feeds](https://docs.chain.link/data-feeds/api-reference) - [\> Find Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Find SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Find Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) - [\> Learn how to use Data Feeds on L2 networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # Chainlink Data Feeds Chainlink Data Feeds are the quickest way to connect your smart contracts to real-world data such as asset prices, reserve balances, and L2 sequencer health. If you already started a project and need to integrate Chainlink, you can [add Chainlink to your existing project](https://docs.chain.link/resources/create-a-chainlinked-project?parent=dataFeeds#installing-into-existing-projects) with the [`@chainlink/contracts` NPM package](https://www.npmjs.com/package/@chainlink/contracts). ## [Types of data feeds](https://docs.chain.link/data-feeds\#types-of-data-feeds) Data feeds provide many different types of data for your applications. - [Price Feeds](https://docs.chain.link/data-feeds#price-feeds) - [SmartData Feeds](https://docs.chain.link/data-feeds#smartdata-feeds) - [Rate and Volatility Feeds](https://docs.chain.link/data-feeds#rate-and-volatility-feeds) - [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds#l2-sequencer-uptime-feeds) ### [Price Feeds](https://docs.chain.link/data-feeds\#price-feeds) Smart contracts often act in real-time on data such as prices of assets. This is especially true in [DeFi](https://chain.link/use-cases/defi). For example, lending and borrowing platforms like [Aave](https://aave.com/) utilize Data Feeds to assess collateral value accurately, while perpetual platforms such as [GMX](https://gmx.io/) rely on these feeds to validate offchain data and ensure that each deposit or withdrawal executes at the correct market value. Data Feeds aggregate many data sources and publish them onchain using a combination of the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) and [Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds). To learn how to use Price Feeds, see the [Price Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. See the [Data Feeds Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page for a list of available networks and addresses. ### [SmartData Feeds](https://docs.chain.link/data-feeds\#smartdata-feeds) Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. To learn more about SmartData Feeds, see the [SmartData](https://docs.chain.link/data-feeds/smartdata) documentation. See the [SmartData Contract Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page for a list of available networks and addresses. ### [Rate and Volatility Feeds](https://docs.chain.link/data-feeds\#rate-and-volatility-feeds) Several feeds provide interest rate curve data, APY data, and realized asset price volatility. To learn more, see the [Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds) documentation. See the [Rate and Volatility Contract Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page for a list of available networks and addresses. ### [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds\#l2-sequencer-uptime-feeds) L2 sequencer feeds track the last known status of the sequencer on an L2 network at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to these events. To learn how to use L2 sequencer uptime feeds, see the [L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds) documentation. ## [Components of a data feed](https://docs.chain.link/data-feeds\#components-of-a-data-feed) Data Feeds are an example of a decentralized oracle network and include the following components: - **Consumer**: A consumer is an onchain or offchain application that uses Data Feeds. Consumer contracts use the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) to call functions on the proxy contract and retrieve information from the aggregator contract. For a complete list of functions available in the `AggregatorV3Interface`, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#aggregatorv3interface). - **Proxy contract**: Proxy contracts are onchain proxies that point to the aggregator for a particular data feed. Using proxies enables the underlying aggregator to be upgraded without any service interruption to consuming contracts. Proxy contracts can vary from one data feed to another, but the [`EACAggregatorProxy.sol` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/EACAggregatorProxy.sol) on Github is a common example. - **Aggregator contract**: An aggregator is a contract that receives periodic data updates from the oracle network. Aggregators store aggregated data onchain so that consumers can retrieve it and act upon it within the same transaction. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). To learn how to create a consumer contract that uses an existing data feed, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. ## [Reading proxy and aggregator configurations](https://docs.chain.link/data-feeds\#reading-proxy-and-aggregator-configurations) Because the proxy and aggregator contracts are all onchain, you can see the current configuration by reading the variables through an [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html) or using a blockchain explorer for your network. For example, you can see the [BTC/USD proxy configuration](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) on the Ethereum network using Etherscan. If you read the BTC/USD proxy configuration, you can query all of the functions and variables that are publicly accessible for that contract including the `aggregator` address, `latestRoundData()` function, `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. To see descriptions for the proxy contract variables and functions, see the source code for your specific data feed on [Etherscan](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code#L568). The proxy contract points to an aggregator. This allows you to retrieve data through the proxy even if the aggregator is upgraded. If you view the `aggregator` address defined in the proxy configuration, you can see the aggregator and its configuration. For example, see the [BTC/USD aggregator contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code) in Etherscan. This contract includes several variables and functions, including another `latestRoundData()`. To see descriptions for the aggregator variables and functions, see the source code on [GitHub](https://github.com/smartcontractkit/libocr/blob/master/contract/AccessControlledOffchainAggregator.sol) or [Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code#F1#L1). You can call the `latestRoundData()` function directly on the aggregator, but it is a best practice to use the proxy instead so that changes to the aggregator do not affect your application. Similar to the proxy contract, the aggregator contract has a `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. ## [Components of an aggregator](https://docs.chain.link/data-feeds\#components-of-an-aggregator) The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). ## [Updates to proxy and aggregator contracts](https://docs.chain.link/data-feeds\#updates-to-proxy-and-aggregator-contracts) To accommodate the dynamic nature of offchain environments, Chainlink Data Feeds are updated from time to time to add new features and capabilities as well as respond to externalities such as token migrations, protocol rebrands, extreme market events, and upstream issues with data or node operations. These updates include changes to the aggregator configuration or a complete replacement of the aggregator that the proxy uses. If you consume data feeds through the proxy, your applications can continue to operate during these changes. Proxy and aggregator contracts all have an `owner` address that has permission to change variables and functions. For example, if you read the [BTC/USD proxy contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) in Etherscan, you can see the `owner` address. This address is a [multi-signature safe](https://docs.safe.global/getting-started/readme) (multisig) that you can also inspect. If you [view the multisig contract](https://etherscan.io/address/0x21f73D42Eb58Ba49dDB685dc29D3bF5c0f0373CA#readProxyContract) in Etherscan using the _Read as Proxy_ feature, you can see the full details of the multisig including the list of addresses that can sign and the number of signers required for the multisig to approve actions on any contracts that it owns. The multisig-coordinated upgradability of Chainlink Data Feeds involves time-tested processes that balance collusion-resistance with the flexibility required to implement improvements and swiftly react to external conditions. The approach taken to upgradability will continue to evolve over time to meet user requirements. ## [Monitoring data feeds](https://docs.chain.link/data-feeds\#monitoring-data-feeds) When you build applications and protocols that depend on data feeds, include monitoring and safeguards to protect against the negative impact of extreme market events, possible malicious activity on third-party venues or contracts, potential delays, and outages. Create your own monitoring alerts based on deviations in the answers that data feeds provide. This will notify you when potential issues occur so you can respond to them. ### [Check the latest answer against reasonable limits](https://docs.chain.link/data-feeds\#check-the-latest-answer-against-reasonable-limits) The data feed aggregator includes both [`minAnswer` and `maxAnswer` values](https://github.com/smartcontractkit/libocr/blob/9e4afd8896f365b964bdf769ca28f373a3fb0300/contract/AccessControlledOffchainAggregator.sol#L33). On most data feeds, these values are no longer used and they do not stop your application from reading the most recent answer. For monitoring purposes, you must decide what limits are acceptable for your application. Configure your application to detect when the reported answer is close to reaching reasonable minimum and maximum limits so it can alert you to potential market events. Separately, configure your application to detect and respond to extreme price volatility or prices that are outside of your acceptable limits. ### [Check the timestamp of the latest answer](https://docs.chain.link/data-feeds\#check-the-timestamp-of-the-latest-answer) Chainlink Data Feeds do not provide streaming data. Rather, the aggregator updates its `latestAnswer` when the value deviates beyond a specified threshold or when the heartbeat idle time has passed. You can find the heartbeat and deviation values for each data feed at [data.chain.link](https://data.chain.link/) or in the [Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) lists. Your application should track the `latestTimestamp` variable or use the `updatedAt` value from the `latestRoundData()` function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay. When the node detects that the heartbeat is reached, it initiates the latest round. Depending on congestion and network conditions, there may be a slight delay for the latest round to get onchain. During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application. Users should build applications with the understanding that data feeds for wrapped or liquid staking assets might have different heartbeat and deviation thresholds than that of the underlying asset. Heartbeat and deviation thresholds can also differ for the same asset across different blockchains. Combining data from multiple feeds, even those with a common denominator, might result in a margin of error that users must account for in their risk mitigation practices. To learn more about the heartbeat and deviation threshold, read the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## What's next - [\> Follow the Data Feeds Getting Started guide to learn the basics](https://docs.chain.link/data-feeds/getting-started) - [\> Read the API reference for using Data Feeds](https://docs.chain.link/data-feeds/api-reference) - [\> Find Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Find SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Find Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) - [\> Learn how to use Data Feeds on L2 networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # [Chainlink Data Feeds](https://docs.chain.link/data-feeds\#overview) Chainlink Data Feeds are the quickest way to connect your smart contracts to real-world data such as asset prices, reserve balances, and L2 sequencer health. If you already started a project and need to integrate Chainlink, you can [add Chainlink to your existing project](https://docs.chain.link/resources/create-a-chainlinked-project?parent=dataFeeds#installing-into-existing-projects) with the [`@chainlink/contracts` NPM package](https://www.npmjs.com/package/@chainlink/contracts). ## [Types of data feeds](https://docs.chain.link/data-feeds\#types-of-data-feeds) Data feeds provide many different types of data for your applications. - [Price Feeds](https://docs.chain.link/data-feeds#price-feeds) - [SmartData Feeds](https://docs.chain.link/data-feeds#smartdata-feeds) - [Rate and Volatility Feeds](https://docs.chain.link/data-feeds#rate-and-volatility-feeds) - [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds#l2-sequencer-uptime-feeds) ### [Price Feeds](https://docs.chain.link/data-feeds\#price-feeds) Smart contracts often act in real-time on data such as prices of assets. This is especially true in [DeFi](https://chain.link/use-cases/defi). For example, lending and borrowing platforms like [Aave](https://aave.com/) utilize Data Feeds to assess collateral value accurately, while perpetual platforms such as [GMX](https://gmx.io/) rely on these feeds to validate offchain data and ensure that each deposit or withdrawal executes at the correct market value. Data Feeds aggregate many data sources and publish them onchain using a combination of the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds) and [Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting?parent=dataFeeds). To learn how to use Price Feeds, see the [Price Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. See the [Data Feeds Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) page for a list of available networks and addresses. ### [SmartData Feeds](https://docs.chain.link/data-feeds\#smartdata-feeds) Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. To learn more about SmartData Feeds, see the [SmartData](https://docs.chain.link/data-feeds/smartdata) documentation. See the [SmartData Contract Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page for a list of available networks and addresses. ### [Rate and Volatility Feeds](https://docs.chain.link/data-feeds\#rate-and-volatility-feeds) Several feeds provide interest rate curve data, APY data, and realized asset price volatility. To learn more, see the [Rate and Volatility Feeds](https://docs.chain.link/data-feeds/rates-feeds) documentation. See the [Rate and Volatility Contract Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) page for a list of available networks and addresses. ### [L2 sequencer uptime feeds](https://docs.chain.link/data-feeds\#l2-sequencer-uptime-feeds) L2 sequencer feeds track the last known status of the sequencer on an L2 network at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to these events. To learn how to use L2 sequencer uptime feeds, see the [L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds) documentation. ## [Components of a data feed](https://docs.chain.link/data-feeds\#components-of-a-data-feed) Data Feeds are an example of a decentralized oracle network and include the following components: - **Consumer**: A consumer is an onchain or offchain application that uses Data Feeds. Consumer contracts use the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) to call functions on the proxy contract and retrieve information from the aggregator contract. For a complete list of functions available in the `AggregatorV3Interface`, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#aggregatorv3interface). - **Proxy contract**: Proxy contracts are onchain proxies that point to the aggregator for a particular data feed. Using proxies enables the underlying aggregator to be upgraded without any service interruption to consuming contracts. Proxy contracts can vary from one data feed to another, but the [`EACAggregatorProxy.sol` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/EACAggregatorProxy.sol) on Github is a common example. - **Aggregator contract**: An aggregator is a contract that receives periodic data updates from the oracle network. Aggregators store aggregated data onchain so that consumers can retrieve it and act upon it within the same transaction. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). To learn how to create a consumer contract that uses an existing data feed, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) documentation. ## [Reading proxy and aggregator configurations](https://docs.chain.link/data-feeds\#reading-proxy-and-aggregator-configurations) Because the proxy and aggregator contracts are all onchain, you can see the current configuration by reading the variables through an [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html) or using a blockchain explorer for your network. For example, you can see the [BTC/USD proxy configuration](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) on the Ethereum network using Etherscan. If you read the BTC/USD proxy configuration, you can query all of the functions and variables that are publicly accessible for that contract including the `aggregator` address, `latestRoundData()` function, `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. To see descriptions for the proxy contract variables and functions, see the source code for your specific data feed on [Etherscan](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code#L568). The proxy contract points to an aggregator. This allows you to retrieve data through the proxy even if the aggregator is upgraded. If you view the `aggregator` address defined in the proxy configuration, you can see the aggregator and its configuration. For example, see the [BTC/USD aggregator contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code) in Etherscan. This contract includes several variables and functions, including another `latestRoundData()`. To see descriptions for the aggregator variables and functions, see the source code on [GitHub](https://github.com/smartcontractkit/libocr/blob/master/contract/AccessControlledOffchainAggregator.sol) or [Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code#F1#L1). You can call the `latestRoundData()` function directly on the aggregator, but it is a best practice to use the proxy instead so that changes to the aggregator do not affect your application. Similar to the proxy contract, the aggregator contract has a `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. ## [Components of an aggregator](https://docs.chain.link/data-feeds\#components-of-an-aggregator) The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference/#accesscontrolledoffchainaggregator). ## [Updates to proxy and aggregator contracts](https://docs.chain.link/data-feeds\#updates-to-proxy-and-aggregator-contracts) To accommodate the dynamic nature of offchain environments, Chainlink Data Feeds are updated from time to time to add new features and capabilities as well as respond to externalities such as token migrations, protocol rebrands, extreme market events, and upstream issues with data or node operations. These updates include changes to the aggregator configuration or a complete replacement of the aggregator that the proxy uses. If you consume data feeds through the proxy, your applications can continue to operate during these changes. Proxy and aggregator contracts all have an `owner` address that has permission to change variables and functions. For example, if you read the [BTC/USD proxy contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) in Etherscan, you can see the `owner` address. This address is a [multi-signature safe](https://docs.safe.global/getting-started/readme) (multisig) that you can also inspect. If you [view the multisig contract](https://etherscan.io/address/0x21f73D42Eb58Ba49dDB685dc29D3bF5c0f0373CA#readProxyContract) in Etherscan using the _Read as Proxy_ feature, you can see the full details of the multisig including the list of addresses that can sign and the number of signers required for the multisig to approve actions on any contracts that it owns. The multisig-coordinated upgradability of Chainlink Data Feeds involves time-tested processes that balance collusion-resistance with the flexibility required to implement improvements and swiftly react to external conditions. The approach taken to upgradability will continue to evolve over time to meet user requirements. ## [Monitoring data feeds](https://docs.chain.link/data-feeds\#monitoring-data-feeds) When you build applications and protocols that depend on data feeds, include monitoring and safeguards to protect against the negative impact of extreme market events, possible malicious activity on third-party venues or contracts, potential delays, and outages. Create your own monitoring alerts based on deviations in the answers that data feeds provide. This will notify you when potential issues occur so you can respond to them. ### [Check the latest answer against reasonable limits](https://docs.chain.link/data-feeds\#check-the-latest-answer-against-reasonable-limits) The data feed aggregator includes both [`minAnswer` and `maxAnswer` values](https://github.com/smartcontractkit/libocr/blob/9e4afd8896f365b964bdf769ca28f373a3fb0300/contract/AccessControlledOffchainAggregator.sol#L33). On most data feeds, these values are no longer used and they do not stop your application from reading the most recent answer. For monitoring purposes, you must decide what limits are acceptable for your application. Configure your application to detect when the reported answer is close to reaching reasonable minimum and maximum limits so it can alert you to potential market events. Separately, configure your application to detect and respond to extreme price volatility or prices that are outside of your acceptable limits. ### [Check the timestamp of the latest answer](https://docs.chain.link/data-feeds\#check-the-timestamp-of-the-latest-answer) Chainlink Data Feeds do not provide streaming data. Rather, the aggregator updates its `latestAnswer` when the value deviates beyond a specified threshold or when the heartbeat idle time has passed. You can find the heartbeat and deviation values for each data feed at [data.chain.link](https://data.chain.link/) or in the [Contract Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) lists. Your application should track the `latestTimestamp` variable or use the `updatedAt` value from the `latestRoundData()` function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay. When the node detects that the heartbeat is reached, it initiates the latest round. Depending on congestion and network conditions, there may be a slight delay for the latest round to get onchain. During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application. Users should build applications with the understanding that data feeds for wrapped or liquid staking assets might have different heartbeat and deviation thresholds than that of the underlying asset. Heartbeat and deviation thresholds can also differ for the same asset across different blockchains. Combining data from multiple feeds, even those with a common denominator, might result in a margin of error that users must account for in their risk mitigation practices. To learn more about the heartbeat and deviation threshold, read the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## What's next - [\> Follow the Data Feeds Getting Started guide to learn the basics](https://docs.chain.link/data-feeds/getting-started) - [\> Read the API reference for using Data Feeds](https://docs.chain.link/data-feeds/api-reference) - [\> Find Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses) - [\> Find SmartData Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Find Rate and Volatility Feed Addresses](https://docs.chain.link/data-feeds/rates-feeds/addresses) - [\> Learn how to use Data Feeds on L2 networks](https://docs.chain.link/data-feeds/l2-sequencer-feeds) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Data Feeds [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # Data Feeds API Reference When you use data feeds, retrieve the feeds through the `AggregatorV3Interface` and the proxy address. Optionally, you can call variables and functions in the `AccessControlledOffchainAggregator` contract to get information about the aggregator behind the proxy. ## [AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference\#aggregatorv3interface) Import this interface to your contract and use it to run functions in the proxy contract. Create the interface object by pointing to the proxy address. For example, on Sepolia you could create the interface object in the constructor of your contract using the following example: ```solidity /** * Network: Sepolia * Data Feed: ETH/USD * Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306 */ constructor() { priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306); } ``` To see examples for how to use this interface, read the [Using Data Feeds](https://docs.chain.link/data-feeds/price-feeds) guide. You can see the code for the [`AggregatorV3Interface` contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) on GitHub. ### [Functions in AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference\#functions-in-aggregatorv3interface) | Name | Description | | --- | --- | | [decimals](https://docs.chain.link/data-feeds/api-reference#decimals) | The number of decimals in the response. | | [description](https://docs.chain.link/data-feeds/api-reference#description) | The description of the aggregator that the proxy points to. | | [getRoundData](https://docs.chain.link/data-feeds/api-reference#getrounddata) | Get data from a specific round. | | [latestRoundData](https://docs.chain.link/data-feeds/api-reference#latestrounddata) | Get data from the latest round. | | [version](https://docs.chain.link/data-feeds/api-reference#version) | The version representing the type of aggregator the proxy points to. | #### [decimals](https://docs.chain.link/data-feeds/api-reference\#decimals) Get the number of decimals present in the response value. ```solidity function decimals() external view returns (uint8); ``` - `RETURN`: The number of decimals. #### [description](https://docs.chain.link/data-feeds/api-reference\#description) Get the description of the underlying aggregator that the proxy points to. ```solidity function description() external view returns (string memory); ``` - `RETURN`: The description of the underlying aggregator. #### [getRoundData](https://docs.chain.link/data-feeds/api-reference\#getrounddata) Get data about a specific round, using the `roundId`. ```solidity function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); ``` **Parameters:** - `_roundId`: The round ID **Return values:** - `roundId`: The round ID - `answer`: The answer for this round - `startedAt`: Timestamp of when the round started - `updatedAt`: Timestamp of when the round was updated - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed #### [latestRoundData](https://docs.chain.link/data-feeds/api-reference\#latestrounddata) Get the data from the latest round. ```solidity function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) ``` **Return values:** - `roundId`: The round ID. - `answer`: The data that this specific feed provides. Depending on the feed you selected, this answer provides asset prices, reserves, and other types of data. - `startedAt`: Timestamp of when the round started. - `updatedAt`: Timestamp of when the round was updated. - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed #### [version](https://docs.chain.link/data-feeds/api-reference\#version) The version representing the type of aggregator the proxy points to. ```solidity function version() external view returns (uint256) ``` - `RETURN`: The version number. ## [AccessControlledOffchainAggregator](https://docs.chain.link/data-feeds/api-reference\#accesscontrolledoffchainaggregator) This is the contract for the aggregator. You can call functions on the aggregator directly, but it is a best practice to use the [AggregatorV3Interface](https://docs.chain.link/data-feeds/api-reference#aggregatorv3interface) to run functions on the proxy instead so that changes to the aggregator do not affect your application. Read the aggregator contract only if you need functions that are not available in the proxy. The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running. Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008D658dbB40745BBEc89A93c253f9B882#code) is different from the aggregators on other networks. For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub. ### [Variables and functions in AccessControlledOffchainAggregator](https://docs.chain.link/data-feeds/api-reference\#variables-and-functions-in-accesscontrolledoffchainaggregator) This contract imports `OffchainAggregator` and `SimpleReadAccessController`, which also include their own imports. The variables and functions lists include the publicly accessible items from these imported contracts. A simple way to read the variables or functions is to get the ABI from a blockchain explorer and point the ABI to the aggregator address. To do this in Remix, follow the [Using the ABI with AtAddress](https://remix-ide.readthedocs.io/en/latest/run.html#using-the-abi-with-ataddress) guide in the Remix documentation. As an example, you can find the ABI for the BTC/USD aggregator by viewing the [contract code in Etherscan](https://etherscan.io/address/0xAe74faA92cB67A95ebCAB07358bC222e33A34dA7#code). **Variables:** | Name | Description | | --- | --- | | LINK | The address for the LINK token contract on a specific network. | | billingAccessController | The address for the billingAccessController, which limits access to the [billing configuration](https://github.com/smartcontractkit/libocr/blob/master/contract/OffchainAggregatorBilling.sol) for the aggregator. | | checkEnabled | A boolean that indicates if access is limited to addresses on the internal access list. | | maxAnswer | This value is no longer used on most Data Feeds. Evaluate if your use case for Data Feeds requires a custom circuit breaker and implement it to meet the needs of your application. See the [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) page for more information. | | minAnswer | This value is no longer used on most Data Feeds. Evaluate if your use case for Data Feeds requires a custom circuit breaker and implement it to meet the needs of your application. See the [Risk Mitigation](https://docs.chain.link/data-feeds/selecting-data-feeds#risk-mitigation) page for more information. | | owner | The address that owns this aggregator contract. This controls which address can execute specific functions. | **Functions:** | Name | Description | | --- | --- | | [decimals](https://docs.chain.link/data-feeds/api-reference#decimals-1) | Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format. | | [description](https://docs.chain.link/data-feeds/api-reference#description-1) | Return a description for this data feed. This is different depending on which feed you select. | | [getAnswer](https://docs.chain.link/data-feeds/api-reference#getanswer) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [getBilling](https://docs.chain.link/data-feeds/api-reference#getbilling) | Retrieve the current billing configuration. | | [getRoundData](https://docs.chain.link/data-feeds/api-reference#getrounddata-1) | Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round. | | [getTimestamp](https://docs.chain.link/data-feeds/api-reference#gettimestamp) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [hasAccess](https://docs.chain.link/data-feeds/api-reference#hasaccess) | Check if an address has internal access. | | [latestAnswer](https://docs.chain.link/data-feeds/api-reference#latestanswer) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestConfigDetails](https://docs.chain.link/data-feeds/api-reference#latestconfigdetails) | Return information about the current offchain reporting protocol configuration. | | [latestRound](https://docs.chain.link/data-feeds/api-reference#latestround) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestRoundData](https://docs.chain.link/data-feeds/api-reference#latestrounddata-1) | Get the full information for the most recent round including the answer and update timestamps. | | [latestTimestamp](https://docs.chain.link/data-feeds/api-reference#latesttimestamp) | ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Do not use this function. | | [latestTransmissionDetails](https://docs.chain.link/data-feeds/api-reference#latesttransmissiondetails) | Get information about the most recent answer. | | [linkAvailableForPayment](https://docs.chain.link/data-feeds/api-reference#linkavailableforpayment) | Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations. | | [oracleObservationCount](https://docs.chain.link/data-feeds/api-reference#oracleobservationcount) | Returns the number of observations that oracle is due to be reimbursed for. | | [owedPayment](https://docs.chain.link/data-feeds/api-reference#owedpayment) | Returns how much LINK an oracle is owed for its observations. | | [requesterAccessController](https://docs.chain.link/data-feeds/api-reference#requesteraccesscontroller) | Returns the address for the access controller contract. | | [transmitters](https://docs.chain.link/data-feeds/api-reference#transmitters) | The oracle addresses that can report answers to this aggregator. | | [typeAndVersion](https://docs.chain.link/data-feeds/api-reference#typeandversion) | Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 3.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`. | | [validatorConfig](https://docs.chain.link/data-feeds/api-reference#validatorconfig) | Returns the address and the gas limit for the validator contract. | | [version](https://docs.chain.link/data-feeds/api-reference#version-1) | Returns the contract version. This is different from the `typeAndVersion` for the aggregator. | #### [decimals](https://docs.chain.link/data-feeds/api-reference\#decimals-1) Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format. ```solidity function decimals() external view returns (uint8 decimalPlaces); ``` #### [description](https://docs.chain.link/data-feeds/api-reference\#description-1) Return a description for this data feed. Usually this is an asset pair for a price feed. ```solidity function description() public view override checkAccess returns (string memory) { return super.description(); } ``` #### [getAnswer](https://docs.chain.link/data-feeds/api-reference\#getanswer) #### [getBilling](https://docs.chain.link/data-feeds/api-reference\#getbilling) Retrieve the current billing configuration. ```solidity function getBilling() external view returns ( uint32 maximumGasPrice, uint32 reasonableGasPrice, uint32 microLinkPerEth, uint32 linkGweiPerObservation, uint32 linkGweiPerTransmission ) { Billing memory billing = s_billing; return ( billing.maximumGasPrice, billing.reasonableGasPrice, billing.microLinkPerEth, billing.linkGweiPerObservation, billing.linkGweiPerTransmission ); } ``` #### [getRoundData](https://docs.chain.link/data-feeds/api-reference\#getrounddata-1) Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round. ```solidity function getRoundData( uint80 _roundId ) public view override checkAccess returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) { return super.getRoundData(_roundId); } ``` #### [getTimestamp](https://docs.chain.link/data-feeds/api-reference\#gettimestamp) #### [hasAccess](https://docs.chain.link/data-feeds/api-reference\#hasaccess) Check if an address has internal access. ```solidity function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) { return super.hasAccess(_user, _calldata) || _user == tx.origin; } ``` #### [latestAnswer](https://docs.chain.link/data-feeds/api-reference\#latestanswer) #### [latestConfigDetails](https://docs.chain.link/data-feeds/api-reference\#latestconfigdetails) Return information about the current offchain reporting protocol configuration. ```solidity function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes16 configDigest) { return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest); } ``` #### [latestRound](https://docs.chain.link/data-feeds/api-reference\#latestround) #### [latestRoundData](https://docs.chain.link/data-feeds/api-reference\#latestrounddata-1) Get the full information for the most recent round including the answer and update timestamps. ```solidity function latestRoundData() public view override checkAccess returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) { return super.latestRoundData(); } ``` #### [latestTimestamp](https://docs.chain.link/data-feeds/api-reference\#latesttimestamp) #### [latestTransmissionDetails](https://docs.chain.link/data-feeds/api-reference\#latesttransmissiondetails) Get information about the most recent answer. ```solidity function latestTransmissionDetails() external view returns (bytes16 configDigest, uint32 epoch, uint8 round, int192 latestAnswer, uint64 latestTimestamp) { require(msg.sender == tx.origin, "Only callable by EOA"); return ( s_hotVars.latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8), uint8(s_hotVars.latestEpochAndRound), s_transmissions[s_hotVars.latestAggregatorRoundId].answer, s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp ); } ``` #### [linkAvailableForPayment](https://docs.chain.link/data-feeds/api-reference\#linkavailableforpayment) Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations. ```solidity function linkAvailableForPayment() external view returns (int256 availableBalance) { // there are at most one billion LINK, so this cast is safe int256 balance = int256(LINK.balanceOf(address(this))); // according to the argument in the definition of totalLINKDue, // totalLINKDue is never greater than 2**172, so this cast is safe int256 due = int256(totalLINKDue()); // safe from overflow according to above sizes return int256(balance) - int256(due); } ``` #### [oracleObservationCount](https://docs.chain.link/data-feeds/api-reference\#oracleobservationcount) Returns the number of observations that oracle is due to be reimbursed for. ```solidity function oracleObservationCount(address _signerOrTransmitter) external view returns (uint16) { Oracle memory oracle = s_oracles[_signerOrTransmitter]; if (oracle.role == Role.Unset) { return 0; } return s_oracleObservationsCounts[oracle.index] - 1; } ``` #### [owedPayment](https://docs.chain.link/data-feeds/api-reference\#owedpayment) Returns how much LINK an oracle is owed for its observations. ```solidity function owedPayment(address _transmitter) public view returns (uint256) { Oracle memory oracle = s_oracles[_transmitter]; if (oracle.role == Role.Unset) { return 0; } Billing memory billing = s_billing; uint256 linkWeiAmount = uint256(s_oracleObservationsCounts[oracle.index] - 1) * uint256(billing.linkGweiPerObservation) * (1 gwei); linkWeiAmount += s_gasReimbursementsLinkWei[oracle.index] - 1; return linkWeiAmount; } ``` #### [requesterAccessController](https://docs.chain.link/data-feeds/api-reference\#requesteraccesscontroller) Returns the address for the access controller contract. ```solidity function requesterAccessController() external view returns (AccessControllerInterface) { return s_requesterAccessController; } ``` #### [transmitters](https://docs.chain.link/data-feeds/api-reference\#transmitters) The oracle addresses that can report answers to this aggregator. ```solidity function transmitters() external view returns (address[] memory) { return s_transmitters; } ``` #### [typeAndVersion](https://docs.chain.link/data-feeds/api-reference\#typeandversion) Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 2.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`. ```solidity function typeAndVersion() external pure virtual override returns (string memory) { return "AccessControlledOffchainAggregator 2.0.0"; } ``` #### [validatorConfig](https://docs.chain.link/data-feeds/api-reference\#validatorconfig) Returns the address and the gas limit for the validator contract. ```solidity function validatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) { ValidatorConfig memory vc = s_validatorConfig; return (vc.validator, vc.gasLimit); } ``` #### [version](https://docs.chain.link/data-feeds/api-reference\#version-1) Returns the contract version. This is different from the `typeAndVersion` for the aggregator. ```solidity function version() external view returns (uint256); ``` ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink Historical Data [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [Getting Historical Data](https://docs.chain.link/data-feeds/historical-data\#overview) The most common use case for Data Feeds is to [Get the Latest Data](https://docs.chain.link/data-feeds/using-data-feeds) from a feed. However, the [AggregatorV3Interface.sol](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol) also has functions to retrieve data of a previous round IDs. There are two parameters that can cause Chainlink nodes to update: | Name | Description | | --- | --- | | Deviation Threshold | Chainlink nodes are monitoring data offchain. The deviation of the real-world data beyond a certain interval triggers all the nodes to update. | | Heartbeat Threshold | If the data values stay within the deviation parameters, it will only trigger an update every _X_ minutes / hours. | You can find these parameters at [data.chain.link](https://data.chain.link/) on an example like [ETH / USD](https://data.chain.link/ethereum/mainnet/crypto-usd/eth-usd). To learn how data feeds update, see the [Decentralized Data Model](https://docs.chain.link/architecture-overview/architecture-decentralized-model?parent=dataFeeds#aggregator) page. ## [Historical rounds](https://docs.chain.link/data-feeds/historical-data\#historical-rounds) As shown in the [decentralized model](https://docs.chain.link/architecture-overview/architecture-decentralized-model), the consumer contracts call the proxy contract, which abstracts the underlying aggregator contract. The main advantage is to enable upgrades of the aggregator without impacting the consumer contracts. That also means that historical data can can be stored in different aggregators. As shown in the following sequence diagram, to get historical data, call the `getRoundData` [function](https://docs.chain.link/data-feeds/api-reference/#getrounddata) and provide `roundId` as a parameter. ![](https://docs.chain.link/images/data-feed/getRoundData-sequence.png) Note that roundIds have different meanings in proxy contracts and in aggregator contracts. ### [`roundId` in Aggregator (aggregatorRoundId)](https://docs.chain.link/data-feeds/historical-data\#roundid-in-aggregator-aggregatorroundid) Oracles provide periodic data updates to the aggregators. Data feeds are updated in **rounds**. Rounds are identified by their `roundId`, which increases with each new round. This increase may not be monotonic. Knowing the `roundId` of a previous round allows contracts to consume historical data. The examples in this document name the aggregator `roundId` as `aggregatorRoundId` to differentiate it from the proxy `roundId`. ### [`roundId` in proxy](https://docs.chain.link/data-feeds/historical-data\#roundid-in-proxy) Because a proxy has references to current and all previous underlying aggregators, it needs a way to fetch data from the correct aggregator. The `roundId` is computed in the [proxy contract](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.0.0/contracts/src/v0.6/AggregatorProxy.sol) as shown in the following example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity return uint80(uint256(_phase) << PHASE_OFFSET | _originalId); ``` where: - `_phase` is incremented each time the underlying aggregator implementation is updated. It is used as a key to find the aggregator address. - `_originalId` is the aggregator `roundId`. The ID starts at 1. From the above formula, you can think of it as returning a large number containing the `phase` and the aggregator `roundId`. **Example:** When you query historical data, it is important to know when you reach the end of the history of the underlying aggregator. As an example, if the [`latestRoundData` function](https://docs.chain.link/data-feeds/api-reference/#latestrounddata) of the [LINK / USD Price Feed on Ethereum Mainnet](https://docs.chain.link/data-feeds/price-feeds/addresses/?network=ethereum) returns `roundId = 92233720368547771158`, you can use this value to compute the `phaseId` and `aggregatorRoundId`: - `phaseId = 92233720368547771158 >> 64`: Right shifting an integer by 64 bits is equivalent to dividing it by 2^64: `phaseId = 92233720368547771158/ 2^64 = 5`. The current phase id is 5 , which means that this proxy has had 5 underlying aggregators since its initial deployment. - `aggregatorRoundId = uint64(92233720368547771158)`: This retrieves the first 64 bits from the right. To calculate this offchain, you can use the following JavaScript example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```javascript // First parse to BigInt to perform computation with big integers const num = BigInt("92233720368547771158") const num2 = BigInt("0xFFFFFFFFFFFFFFFF") // Largest 64bits integer console.log(Number(num >> 64n)) // returns 5 (phaseId) console.log(Number(num & num2)) // returns 13078 (aggregatorRoundId) . Use & (AND bitwise operator) which sets each bit to _1_ if both bits are _1_ ``` Using _13078_ as the current aggregator's round, get its historical data by looping over the [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata): - Start from the first round: _92233720368547758081_ (result of _92233720368547771158 - 13078 + 1_) - Continue until the current round: _92233720368547771158_ To get the historical data for previous aggregators, decrement the `phaseId` and start from round _1_. For phase _4_, get the starting `roundId` offchain using the following JavaScript example: ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```javascript const phaseId = BigInt("4") const aggregatorRoundId = BigInt("1") roundId = (phaseId << 64n) | aggregatorRoundId // returns 73786976294838206465n ``` Loop over the [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata). Start at _73786976294838206465_ and increment it until you get a revert. This means that you reached the last round for the underlying aggregator. The same process could be repeated for previous `phaseIds` (3,2,1). ### [`getRoundData` return values](https://docs.chain.link/data-feeds/historical-data\#getrounddata-return-values) The [`getRoundData` function](https://docs.chain.link/data-feeds/api-reference/#getrounddata) returns the following values: - `roundId`: The round in which the answer was updated - `answer`: The answer reflects the data recorded for the specified round - `answeredInRound`: ![](https://docs.chain.link/_astro/alert-icon.CcK7cCMv.svg) Deprecated - Previously used when answers could take multiple rounds to be computed - `startedAt`: The timestamp when the round started - `updatedAt`: The timestamp when the answer was computed ### [Solidity](https://docs.chain.link/data-feeds/historical-data\#solidity) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract HistoricalDataConsumerV3 { AggregatorV3Interface internal dataFeed; /** * Network: Sepolia * Aggregator: ETH/USD * Address: 0x694AA1769357215DE4FAC081bf1f309aDC325306 */ constructor() { dataFeed = AggregatorV3Interface( 0x694AA1769357215DE4FAC081bf1f309aDC325306 ); } /** * Returns historical data for a round ID. * roundId is NOT incremental. Not all roundIds are valid. * You must know a valid roundId before consuming historical data. * * ROUNDID VALUES: * InValid: 18446744073709562300 * Valid: 18446744073709554683 * * @dev A timestamp with zero value means the round is not complete and should not be used. */ function getHistoricalData(uint80 roundId) public view returns (int256) { // prettier-ignore ( /*uint80 roundID*/, int answer, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = dataFeed.getRoundData(roundId); return answer; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/HistoricalDataConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ### [Javascript](https://docs.chain.link/data-feeds/historical-data\#javascript) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity /** * THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ const Web3 = require("web3") // for nodejs only // Replace the provider URL with your own endpoint URL const web3 = new Web3("https://rpc.ankr.com/eth_sepolia") const aggregatorV3InterfaceABI = [\ {\ inputs: [],\ name: "decimals",\ outputs: [{ internalType: "uint8", name: "", type: "uint8" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "description",\ outputs: [{ internalType: "string", name: "", type: "string" }],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [{ internalType: "uint80", name: "_roundId", type: "uint80" }],\ name: "getRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "latestRoundData",\ outputs: [\ { internalType: "uint80", name: "roundId", type: "uint80" },\ { internalType: "int256", name: "answer", type: "int256" },\ { internalType: "uint256", name: "startedAt", type: "uint256" },\ { internalType: "uint256", name: "updatedAt", type: "uint256" },\ { internalType: "uint80", name: "answeredInRound", type: "uint80" },\ ],\ stateMutability: "view",\ type: "function",\ },\ {\ inputs: [],\ name: "version",\ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],\ stateMutability: "view",\ type: "function",\ },\ ] const addr = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43" const dataFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr) // Valid roundId must be known. They are NOT incremental. let validId = BigInt("18446744073709554177") dataFeed.methods .getRoundData(validId) .call() .then((historicalRoundData) => { document.getElementById("get-data-field").value = historicalRoundData.answer }) ``` Round 18446744073709551978: Historical Price ### [Python](https://docs.chain.link/data-feeds/historical-data\#python) ![copy to clipboard](https://docs.chain.link/assets/icons/copyIcon.svg) ```solidity # THIS IS EXAMPLE CODE THAT USES HARDCODED VALUES FOR CLARITY. # THIS IS EXAMPLE CODE THAT USES UN-AUDITED CODE. # DO NOT USE THIS CODE IN PRODUCTION. from web3 import Web3 # Change this to use your own RPC URL web3 = Web3(Web3.HTTPProvider('https://rpc.ankr.com/eth_sepolia')) # AggregatorV3Interface ABI abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]' # Feed address addr = '0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43' # Set up contract instance contract = web3.eth.contract(address=addr, abi=abi) # Valid roundId must be known. They are NOT incremental. # invalidRoundId = 18446744073709562300 validRoundId = 18446744073709554177 historicalData = contract.functions.getRoundData(validRoundId).call() print(historicalData) ``` ## What's next - [\> API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address ## Chainlink SmartData Overview [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) On this page # SmartData Chainlink SmartData is a suite of onchain data offerings designed to unlock the utility, accessibility, and reliability of tokenized real-world assets (RWAs). By providing secure minting assurances alongside essential real-world data such as reserves, Net Asset Value (NAV), and Assets Under Management (AUM) data, the SmartData suite embeds security and enriches data into tokenized RWA offerings. You can read these feeds the same way that you read other Data Feeds. Specify the [SmartData feed address](https://docs.chain.link/data-feeds/smartdata/addresses) that you want to read instead of specifying a price feed address. See the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) page to learn more. ## [SmartData Product Types](https://docs.chain.link/data-feeds/smartdata\#smartdata-product-types) - [Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata#proof-of-reserve-feeds) - [NAVLink Feeds](https://docs.chain.link/data-feeds/smartdata#navlink-feeds) - [SmartAUM Feeds](https://docs.chain.link/data-feeds/smartdata#smartaum-feeds) ### [Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata\#proof-of-reserve-feeds) Proof of Reserves feeds provide the status of reserves for stablecoins, wrapped assets, and real world assets. Proof of Reserve Feeds operate similarly to Price Feeds, but provide answers in units of measurement such as ounces (oz) or number of tokens. To find a list of available Proof of Reserve Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. #### [Types of Proof of Reserve Feeds](https://docs.chain.link/data-feeds/smartdata\#types-of-proof-of-reserve-feeds) Reserves are available for both offchain assets and cross-chain assets. This categorization describes the data reporting variations of Proof of Reserve feeds and helps highlight some of the inherent market risks surrounding the data quality of these feeds. ##### [Offchain reserves](https://docs.chain.link/data-feeds/smartdata\#offchain-reserves) Offchain reserves are sourced from APIs through an [external adapter](https://docs.chain.link/chainlink-nodes/external-adapters/external-adapters). ![](https://docs.chain.link/images/data-feed/off-chain-reserves.webp) Offchain reserves provide their data using the following methods: - Third-party: An auditor, accounting firm, or other third party audits and verifies reserves. This is done by combining both fiat and investment assets into a numeric value that is reported against the token. - Custodian: Reserves data are pulled directly from the bank or custodian. The custodian has direct access to the bank or vault holding the assets. Generally, this works when the underlying asset pulled requires no additional valuation and is simply reported onchain. - ⚠️ Self-reported: Reserve data is read from an API that the token issuer hosts. Reserve data reported by an asset issuer's self-hosted API carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ##### [Cross-chain reserves](https://docs.chain.link/data-feeds/smartdata\#cross-chain-reserves) Cross-chain reserves are sourced from the network where the reserves are held. Chainlink node operators can report cross-chain reserves by running an [external adapter](https://docs.chain.link/chainlink-nodes/external-adapters/external-adapters) and querying the source-chain client directly. In some instances, the reserves are composed of a dynamic list of IDs or addresses using a composite adapter. ![](https://docs.chain.link/images/data-feed/cross-chain-reserves.webp) Cross-chain reserves provide their data using the following methods: - Wallet address manager: The project uses the [IPoRAddressList](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/interfaces/PoRAddressList.sol) wallet address manager contract and self-reports which addresses they own. Reserve data reported by an asset issuer's self-reported addresses carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. - Wallet address: The project reports which addresses they own through a self-hosted API. Reserve data reported by an asset issuer's self-reported addresses carries additional risks. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ### [NAVLink Feeds](https://docs.chain.link/data-feeds/smartdata\#navlink-feeds) Chainlink NAVLink Feeds provide real-time, tamper-proof data on the Net Asset Value (NAV) of tokenized assets, funds, or portfolios. NAV is an essential metric in the financial industry for assessing the value of mutual funds, ETFs, and other investment vehicles. It is calculated by subtracting total liabilities from the total assets held within the vehicle. By making NAV data available onchain, developers can build decentralized applications that require accurate and up-to-date valuation metrics. These applications include asset management platforms, DeFi protocols, and investment strategies that rely on NAV for operations such as rebalancing, minting, or redemption. To find a list of available SmartNav Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. ### [SmartAUM Feeds](https://docs.chain.link/data-feeds/smartdata\#smartaum-feeds) Chainlink SmartAUM Feeds provide current data on the total market value of assets managed by an entity on behalf of clients. Assets Under Management (AUM) is a crucial indicator used in financial analyses and decision-making processes. By bringing AUM data onchain, decentralized applications can access information for activities such as risk assessment, performance benchmarking, and investment strategy development. To find a list of available Assets Under Management Feeds, see the [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses) page. ## [Using SmartData](https://docs.chain.link/data-feeds/smartdata\#using-smartdata) Read answers from SmartData feeds the same way that you read other Data Feeds. Specify the [SmartData feed address](https://docs.chain.link/data-feeds/smartdata/addresses) that you want to read instead of specifying a Price feed address. See the [Using Data Feeds](https://docs.chain.link/data-feeds/using-data-feeds) page to learn more. Using Solidity, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds. Example for reading a Proof of Reserve feed: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; contract ReserveConsumerV3 { AggregatorV3Interface internal reserveFeed; /** * Network: Ethereum Mainnet * Aggregator: WBTC PoR * Address: 0xa81FE04086865e63E12dD3776978E49DEEa2ea4e */ constructor() { reserveFeed = AggregatorV3Interface( 0xa81FE04086865e63E12dD3776978E49DEEa2ea4e ); } /** * Returns the latest price */ function getLatestReserve() public view returns (int) { // prettier-ignore ( /*uint80 roundID*/, int reserve, /*uint startedAt*/, /*uint timeStamp*/, /*uint80 answeredInRound*/ ) = reserveFeed.latestRoundData(); return reserve; } } ``` [Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataFeeds/ReserveConsumerV3.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix) ## What's next - [\> Learn how to read answers from Data Feeds](https://docs.chain.link/data-feeds/price-feeds) - [\> Learn how to get Historical Price Data](https://docs.chain.link/data-feeds/historical-data) - [\> Find contract addresses for SmartData feeds](https://docs.chain.link/data-feeds/smartdata/addresses) - [\> Data Feeds API Reference](https://docs.chain.link/data-feeds/api-reference) ## Get the latest Chainlink content straight to your inbox. Email Address ## SmartData Feed Addresses [iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T) Finance is on at SmartCon in NYC. [Get notified when tickets go live.](https://smartcon.chain.link/?utm_source=docs) On this page # [SmartData Feed Addresses](https://docs.chain.link/data-feeds/smartdata/addresses\#overview) To learn how to use these feeds, see the [SmartData Feeds documentation.](https://docs.chain.link/data-feeds/smartdata/) For LINK token and Faucet details, see the [LINK Token Contracts](https://docs.chain.link/resources/link-token-contracts?parent=dataFeeds) page. ### [Risks for Proof of Reserve feeds using the wallet address manager](https://docs.chain.link/data-feeds/smartdata/addresses\#risks-for-proof-of-reserve-feeds-using-the-wallet-address-manager) Cross-chain Proof of Reserve feeds using wallet address manager contracts can vary in their configurations. If the wallet address manager is self-reporting, these feeds might include reserve balances from onchain addresses that have not been cryptographically verified to show ownership or control. In circumstances where cryptographically verified ownership is not provided, there is a risk that token issuers could manipulate the value of a Proof of Reserve feed by adding more addresses to the address list even if they do not directly control these addresses. Each feed’s specific configuration is documented in the contract address section. Chainlink Labs is not responsible for the accuracy of self-reported reserves data. Users must do their own risk assessment for asset issuer risk. ### [Data Feed Best Practices](https://docs.chain.link/data-feeds/smartdata/addresses\#data-feed-best-practices) Before you use Data Feeds, read and understand the best practices on the [Selecting Quality Data Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds) page. For best practices about data for specific asset types, see the following sections: - [Best Practices for ETF and Forex feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#etf-and-forex-feeds) - [Best Practices for Exchange Rate Feeds](https://docs.chain.link/data-feeds/selecting-data-feeds#exchange-rate-feeds) - [Risk Categories](https://docs.chain.link/data-feeds/selecting-data-feeds#data-feed-categories) ## [Networks](https://docs.chain.link/data-feeds/smartdata/addresses\#networks) ![](https://docs.chain.link/assets/chains/arbitrum.svg)Arbitrum![](https://docs.chain.link/assets/chains/avalanche.svg)Avalanche![](https://docs.chain.link/assets/chains/base.svg)Base![](https://docs.chain.link/assets/chains/bnb-chain.svg)BNB Chain![](https://docs.chain.link/assets/chains/ethereum.svg)Ethereum![](https://docs.chain.link/assets/chains/polygon.svg)Polygon![](https://docs.chain.link/assets/chains/scroll.svg)Scroll![](https://docs.chain.link/assets/chains/solana.svg)Solana Track the status of this network at [https://ethstats.dev/](https://ethstats.dev/) ### [Ethereum Mainnet](https://docs.chain.link/data-feeds/smartdata/addresses\#ethereum-mainnet) SmartData Type Show more details ## Get the latest Chainlink content straight to your inbox. Email Address