You can use X Layer data feeds to connect your smart contracts to asset pricing data such as the BTC/USD
. These data feeds use data aggregated from many independent data sources. Each price feed has an onchain address and functions that enable contracts to read pricing data from that address.
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:
The following guide will show an example that reads data feeds using the following languages:
These code examples demonstrate how to deploy a consumer contract onchain that reads a data feed and stores the value.
To consume price data, your smart contract should reference AggregatorV3Interface, which defines the external functions implemented by data feeds.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* Aggregator Interface that is compatible with Chainlink’s AggregatorV3Interface
*/
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
contract DataConsumer {
AggregatorV3Interface internal dataFeed;
/**
* Network: XLayer Testnet
* Aggregator: WBTC/USD
* Address: 0x03e29FB6DBb5e0600AD062e5F80Cf50e651571B3
*/
constructor() {
dataFeed = AggregatorV3Interface(
0x03e29FB6DBb5e0600AD062e5F80Cf50e651571B3
);
}
function getWbtcFeedLatestAnswer() public view returns (int256) {
// prettier-ignore
(
/* uint80 roundID */,
int answer,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = dataFeed.latestRoundData();
return answer;
}
}
To use the price data, your smart contract should import AggregatorV3Interface
which defines the external functions implemented by data feeds. You can find it here. You can also find a PriceConsumer
example here. Read the apeworx-starter-kit README to learn how to run the example code.
The feed registry is an onchain mapping of assets to feeds. It enables you to query 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.
For a complete list of functions and parameters for the FeedRegistryInterface
, see the Feed Registry API Reference.
To use the price data from the feed registry, your smart contract should reference FeedRegistryInterface
, which defines the external functions implemented by the feed registry.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IFeedRegistry {
// V3 AggregatorV3Interface
function decimals(
address base,
address quote
) external view returns (uint8);
function description(
address base,
address quote
) external view returns (string memory);
function version(
address base,
address quote
) external view returns (uint256);
function latestRoundData(
address base,
address quote
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function getRoundData(
address base,
address quote,
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
contract PriceConsumer {
IFeedRegistry internal registry;
/**
* Following fiat currency standards of https://en.wikipedia.org/wiki/ISO_4217
*/
address internal constant USD = address(840);
address internal constant WETH = 0x5A77f1443D16ee5761d310e38b62f77f726bC71c;
/**
* Network: XLayer Mainnet
* Feed Registry: 0xfe3240995c771f10D2583e8fa95F92ee40E15150
* WETH: 0x5A77f1443D16ee5761d310e38b62f77f726bC71c
*/
constructor() {
registry = IFeedRegistry(0xfe3240995c771f10D2583e8fa95F92ee40E15150);
}
/**
* Returns the WETH / USD price
*/
function getWethUsdPrice() public view returns (int256) {
// prettier-ignore
(
/*uint80 roundID*/,
int price,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = registry.latestRoundData(WETH, 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;
}
}
To ensure accurate data is fed to the smart contracts in a timely manner, X Layer oracle will feed the price to the smart contracts in regards to two parameters: deviation threshold and heartbeat threshold:
Fiat currencies lack a canonical EVM address on-chain, and are configured on X Layer to maintain the following standard
Currency | Address |
---|---|
USD | 0x0000000000000000000000000000000000000840 |
Network | Feed registry address |
---|---|
X Layer mainnet | 0xfe3240995c771f10D2583e8fa95F92ee40E15150 |
Network | Deviation threshold | Heartbeat | Feed adapter address |
---|---|---|---|
WBTC/USD | 0.5% | 3600s | 0x3C7dCE5F83E99452CD399a1bCa5542BEd979E6CA |
WETH/USD | 0.5% | 3600s | 0x98ff91433c992153A8D6507cEA5b791Df69d7c99 |
OKB/USD | 0.5% | 3600s | 0x90AB4bc4991c71889A67F25eec044fD90E255e77 |
USDT/USD | 0.5% | 3600s | 0xB249978EfdB8E01D5266F926409870c1Ec7336EA |
USDC/USD | 0.5% | 3600s | 0xc975719d0ec39bb8880444acea9cc8d29a35e4d4 |
DAI/USD | 0.5% | 3600s | 0x960cF115eeEAFBF5B184070DE9eD89593c712B71 |
Network | Feed registry address |
---|---|
X Layer testnet | 0x038969dD2036270c22D9F5ABE840cd5CDC079848 |
Network | Deviation threshold | Heartbeat | Feed adapter address |
---|---|---|---|
WBTC/USD | 0.5% | 3600s | 0x03e29fb6dbb5e0600ad062e5f80cf50e651571b3 |
WETH/USD | 0.5% | 3600s | 0x258b77b31dF0eF3C2F1495152b81e305bD83Aab8 |
OKB/USD | 0.5% | 3600s | 0x92ac502FC54356868C4EAc1B2eF0f941C2895dd0 |
USDT/USD | 0.5% | 3600s | 0xA774557280A45E4433a1208f6E5c0dA718a84b7C |
USDC/USD | 0.5% | 3600s | 0xa8f52bbb506E0bD05253e007A46f6A1d8a4000cf |
DAI/USD | 0.5% | 3600s | 0x185919669101D4748423B3Ce7C07A0207e6d99e8 |