Request Fast Pricefeed

Introduce

Fast Pricefeed is a price feed service that allows decentralized applications (dApps) to request and receive current price information efficiently. The process involves requesting prices and receiving prices through the following steps.

Step-by-Step Guide

  1. Send request Prices. Your contract can request prices from the xOracle contract using the requestPrices function. The request fee must be paid in WETH.

function requestPrices(
        bytes calldata payload, // callback
        uint256 expiration, // expire
        uint256 maxGasPrice, // limit gas price
        uint256 callbackGasLimit // limit gas limit
)
  1. Implementing the callback function to handle the response from xOracle, implement the xOracleCall function. xOracle will callback this function to fulfill the price request and you can execute some logic here.

 function xOracleCall(
         uint256 reqId, // request id
         bool priceUpdate, // must priceUpdate is true
         bytes memory payload // callback payload from request
)
  1. Retrieving the latest price. You can retrieve the latest price using the getLastPrice function from the xOracle contract. This function returns several details including the latest round, current price, latest price, and the timestamp of the price update.

( 
    uint256 latestRound, // round
    uint256 price, // current price
    uint256 latestPrice, // latest price
    uint256 timestamp // fulfill time
) = IXOracle(xOracle).getLastPrice(tokenIndex);

See the Token Index references: Token Index.

Let's start

Example: Requesting Prices with Fast Pricefeed

  1. Import the ERC20 interface and the xOracle interface.

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IXOracle.sol";
  1. Create a function to call requestPrices to the xOracle contract. This function approves the required fee in WETH and makes the request with specific parameters.

function requestPrices() external {
        // allowance req fee
        IERC20(weth).approve(xOracle, type(uint256).max);

        // make payload and call
        bytes memory payload = ""; // no payload
        uint256 expired = 0; // no expiration
        uint256 maxGasPrice = 10e9; // 10 gwei
        uint256 callbackMaxGasLimit = 5000000; // 5M
        IXOracle(xOracle).requestPrices(payload, expired, maxGasPrice, callbackMaxGasLimit);
}
  1. Implement the xOracleCall function to handle the callback from xOracle. In this example we do nothing in callback.

function xOracleCall(
        uint256 /* _reqId */, 
        bool /* _priceUpdate */, 
        bytes memory /* _payload */
) external onlyXOracle {
        // do nothing
        // ...
}

Note: onlyXOracle is a modifier that should be defined to restrict access to this function to the xOracle contract only.

  1. Read the Latest Price. Create a function to get the latest price of a specific token using the getLastPrice function from the xOracle contract.

function getPrice(uint256 _tokenIndex) external view returns (uint256) {
        // get last update price
        (, uint256 price, , ) = IXOracle(xOracle).getLastPrice(_tokenIndex);
        return price;
}

Full Code

Here is the full example code, including the necessary imports and functions.

// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IXOracle.sol";

// ------------------------------
// RequestPrices 
// a simple contract to request price from xOracle
// ------------------------------
contract RequestPrices {
    // xoracle 
    address public xOracle;
    address public weth;

    modifier onlyXOracle() {
        require(msg.sender == xOracle, "xOracleCall: only xOracle callback");
        _;
    }

    constructor(address _xOracle, address _weth) {
        xOracle = _xOracle;
        weth = _weth;
    }

    // Request oracle prices
    function requestPrices() external {
        // allowance req fee
        IERC20(weth).approve(xOracle, type(uint256).max);

        // make payload and call
        bytes memory payload = ""; // no payload
        uint256 expired = 0; // no expiration
        uint256 maxGasPrice = 10e9; // 10 gwei
        uint256 callbackMaxGasLimit = 5000000; // 5M
        IXOracle(xOracle).requestPrices(payload, expired, maxGasPrice, callbackMaxGasLimit);
    }

    // ------------------------------
    // xOracle callback
    // ------------------------------
    function xOracleCall(uint256 /* _reqId */, bool /* _priceUpdate */, bytes memory /* _payload */) external onlyXOracle {
        // do nothing
        // ...
    }

    // ------------------------------
    // view function
    // ------------------------------
    function getPrice(uint256 _tokenIndex) external view returns (uint256) {
        // get last update price
        (, uint256 price, , ) = IXOracle(xOracle).getLastPrice(_tokenIndex);
        return price;
    }
}

For more details, you can refer to the full code on GitHub.

Last updated