APRO is building a secure platform by combining off-chain processing with on-chain verification, extending both data access and computational capabilities. This forms the foundation of APRO Data Service, improving data accuracy and efficiency while offering the flexibility to create custom solutions tailored to the specific needs of DApp businesses. Currently, we support 161 Price Feed services across 15 major blockchain networks:

Data Push: APRO Data Push uses a “Push-Based” data model to deliver Price Feed services. Decentralized independent node operators continuously gather and push data updates to the blockchain when certain price thresholds or time intervals are met. This method improves blockchain scalability, supports various data products, and provides timely updates.

We continually refine and optimize our platform to deliver enhanced services and experiences, driving forward the development and application of blockchain technology.

Key Benefits of APRO Data Service

  • Advantages of APRO Combination of Off-Chain Computing and On-Chain Verification APRO platform integrates off-chain computing with on-chain verification to extend computing capabilities and data access while ensuring system security and reliability.

  • Customization of Secure and Trustworthy Computing Logic DApp businesses can customize computing logic according to their needs and run it on the APRO platform, achieving personalized business logic processing without concerns about security issues.

  • Enhancement of Oracle Network Security and Stability We focus on enhancing the security and stability of the Oracle network through various measures to ensure continuous service capability.

  • Hybrid Node Approach Introducing a Hybrid node approach that combines on-chain and off-chain computing resources to improve computing efficiency and performance.

  • Multi-Network Communication Scheme Establishing a multi-centralized network communication scheme ensures network stability and reliability while reducing the risk of single-point failures.

  • TVWAP Price Discovery Mechanism Applying the TVWAP price discovery mechanism ensures fairness and accuracy of data prices, preventing data tampering and malicious manipulation.

Data Push

  • Data Push: Threshold-Based Data Updates APRO Data Push offers a “Push-Based” data model, which we use to provide Price Feed services. In this model, decentralized independent node operators continuously aggregate and push data updates to the blockchain when specific price thresholds or heartbeat intervals are reached. This approach enhances blockchain scalability, supports a broader range of data products, and ensures timely updates.

  • Trusted Data for DeFi APRO Data Push Model is widely utilized in various applications, especially in DeFi protocols and smart contracts, providing highly trusted, real-time, and secure data.

  • Reliable Data Transmission The APRO Data Push model employs multiple high-quality data transmission methods, leveraging a hybrid node architecture, multi-centralized communication networks, the TVWAP price discovery mechanism, and a self-managed multi-signature framework. This ensures the delivery of accurate, tamper-resistant data, safeguarded against vulnerabilities or oracle-based attacks, ensuring reliability across diverse use cases.

Getting Started

You can use APRO Data Push to connect your smart contracts to asset pricing data. These data feeds aggregate information from many independent APRO node operators. Each price feed has an on-chain address and functions that enable contracts to read real-time pricing data directly from that address.

This section explains the Data Push, where APRO pushes real-time data to your contracts, allowing for immediate access to pricing updates without requiring frequent manual requests. This approach optimizes performance by reducing on-chain calls and enhances efficiency for applications that need continuous updates.

You’ll learn how to read Data Feeds and store the value on-chain using Solidity. The code for reading Data Feeds on Tac or other EVM-compatible blockchains remains consistent across different chains and data feed types. You can choose various types of feeds depending on your use case, but the request and response format stays the same. However, the answer’s decimal length and expected value ranges might differ depending on the feed you are using.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import {AggregatorV3Interface} from "./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 DataConsumer {
    AggregatorV3Interface internal dataFeed;

    /**
     * Network: Tac testnet
     * Aggregator: BTC/USD
     * Address: 0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
     */
    constructor() {
        dataFeed = AggregatorV3Interface(
            0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
        );
    }

    /**
     * Returns the latest answer.
     */
    function getDataFeedLatestAnswer() public view returns (int) {
        // prettier-ignore
        (
        /* uint80 roundId */,
        int256 answer,
        /*uint256 startedAt*/,
        /*uint256 timeStamp*/,
        /*uint80 answeredInRound*/
        ) = dataFeed.latestRoundData();
        return answer;
    }

    /**
     * Returns decimals.
     */
    function getDecimals() public view returns (uint8) {
        uint8 decimals = dataFeed.decimals();
        return decimals;
    }
}

This example contract obtains the latest price answer from the BTC / USD feed on the Tac testnet.

EVM Guides

This section provides essential guides for integrating APRO Price Feeds on EVM-compatible blockchains. Whether you’re working with smart contracts or using APIs to fetch price data, these guides will help you implement APRO’s oracle solutions effectively.

Using Price Feed

Learn how to read price feeds on-chain with Solidity and off-chain using Web3.js. This guide walks you through setting up your RPC endpoint, selecting the right Price Feed contract address, and interacting with data feeds for real-time price updates.

The code for reading Data Push is the same across all EVM-compatible blockchains and price feed types. You choose different types of price feed for different uses, but the request and response format are the same. To read a price feed, specify the following variables:

  • RPC endpoint URL: This determines which network your smart contracts will run on. You can use a node provider service or point to your own client. If you are using a Web3 wallet, it is already configured with the RPC endpoints for several networks and the Remix IDE will automatically detect them for you.

  • Feed contract address: This determines which Price 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 Contract 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 Price Feed using the following languages:

Onchain consumer contracts

These code examples demonstrate how to deploy a consumer contract on-chain that reads a data feed and stores the value.

Solidity

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.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.
 */

interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  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: Tac testnet
     * Aggregator: BTC/USD
     * Address: 0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
     */
    constructor() {
        dataFeed = AggregatorV3Interface(
            0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
        );
    }

    /**
     * Returns the latest answer.
     */
    function getDataFeedLatestAnswer() public view returns (int) {
        // prettier-ignore
        (
        /* uint80 roundId */,
        int256 answer,
        /*uint256 startedAt*/,
        /*uint256 timeStamp*/,
        /*uint80 answeredInRound*/
        ) = dataFeed.latestRoundData();
        return answer;
    }

    /**
     * Returns decimals.
     */
    function getDecimals() public view returns (uint8) {
        uint8 decimals = dataFeed.decimals();
        return decimals;
    }
}

The latestRoundData function returns five values representing information about the latest price data. See the Price Feed API Reference for more details.

Offchain reads using Web3.js

These code examples demonstrate how to read data feeds directly off-chain using Web3 packages for each language.

Javascript

This example uses web3.js to retrieve feed data from the BTC / USD feed on the Tac testnet.

/**
 * 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://turin.rpc.tac.build")
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 = "0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD"
const priceFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr)
priceFeed.methods
    .latestRoundData()
    .call()
    .then((roundData) => {
        // Do something with roundData
        console.log("Latest Round Data", roundData)
    })

Price Feed API Reference

A technical reference for using the AggregatorV3Interface to fetch price data. This guide explains how to retrieve feed details like round data, descriptions, and decimal precision, ensuring you can accurately integrate APRO Price Feeds into your dApps.

When you use price feed, retrieve the feeds through the AggregatorV3Interface and the proxy address.

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 Tac you could create the interface object in the constructor of your contract using the following example:

/**
 * Network: Tac testnet
 * Data Feed: BTC/USD
 * Address: 0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
 */
constructor() {
  priceFeed = AggregatorV3Interface(0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD);
}
// SPDX-License-Identifier: MIT
pragma solidity >0.8.0;


interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

}

Functions in AggregatorV3Interface

NameDescription
decimalsThe number of decimals in the response.
descriptionThe description of the aggregator that the proxy points to.
getRoundDataGet data from a specific round.
versionThe version representing the type of aggregator the proxy points to.
decimals

Get the number of decimals present in the response value.

function decimals() external view returns (uint8);
  • RETURN: The number of decimals.
description

Get the description of the underlying aggregator that the proxy points to.

function description() external view returns (string memory);
  • RETURN: The description of the underlying aggregator.
getRoundData

Get data about a specific round, using the roundId.

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: The round Id of the round in which the answer was computed

version

The version representing the type of aggregator the proxy points to.

function version() external view returns (uint256)
  • RETURN: The version number.

Price Feed Contract

APRO is deployed on the TAC test chains as follows:

PairDeviationHeartbeatAddress
BTC/USD0.5%1h0xA840DA91be3f707E8774A04Fc9e346d236F5dbBD
USDT/USD0.1%24h0x8A880Cd417E6782B2d764e54D2e929dbD6f92373

For inquiries regarding Price Feeds for additional chains, check out the Price Feed Contract Documentation.

You can also view details through our browser for Tac testnet details

Was this page helpful?