Skip to main content
This guide provides detailed instructions for integrating Chaos price oracles with EVM-compatible blockchains.

How to Use the Push Oracle

This section explains the main methods and patterns for integrating the Chaos push oracle into your EVM smart contracts, including fetching prices, accessing historical data, and subscribing to updates.

1. Set up your environment.

  • Import the Chaos push oracle contract Application Binary Interface (ABI).
  • Identify the deployed contract address for your desired network, such as the Ethereum mainnet and testnets.
Example:
EdgePushOracle oracle = EdgePushOracle(ORACLE_CONTRACT_ADDRESS);

2. Fetch the latest price

Use the latestAnswer() function to obtain the most recent price. The result is an integer representing the price, formatted with the specified number of decimals.
int256 latestPrice = oracle.latestAnswer();

3. Access historical data

Retrieve historical price data for specific rounds using the getRoundData function. Each round provides a comprehensive dataset, including the price, timestamp, and block number.
(int256 price, uint256 reportRoundId, uint256 timestamp, uint256 blockNumber) = oracle.getRoundData(ROUND_ID);

4. Monitor updates in real-time

Subscribe to the NewPriceUpdate event to react to new price reports. This is particularly useful for applications requiring immediate responses to market changes. Example:
event NewPriceUpdate(uint80 indexed roundId, int256 price, uint256 reportRoundId, uint256 timestamp, address transmitter, uint256 numSignatures);

Push Contract Integration

Here’s a basic example demonstrating how to integrate the Chaos push oracle into your smart contract:
The following code is for illustrative purposes only, has not been audited, and should not be used in production without thorough testing.
pragma solidity ^0.8.25;

interface IEdgePushOracle {
    function latestRoundData()
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );
    function decimals() external view returns (uint8);
    function description() external view returns (string memory);
}

contract OracleConsumer {
    IEdgePushOracle public oracle;

    constructor(address oracleAddress) {
        oracle = IEdgePushOracle(oracleAddress);
    }

    /**
     * @notice Fetch the latest price data and metadata from the oracle.
     * @return roundId The round ID of the latest price update.
     * @return answer The latest price reported by the oracle.
     * @return updatedAt The timestamp when the latest price was updated.
     */
    function getLatestPriceData()
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 updatedAt
        )
    {
        (roundId, answer, , updatedAt, ) = oracle.latestRoundData();
        return (roundId, answer, updatedAt);
    }
}

Important Considerations

  • Decimals handling The latestAnswer() and getRoundData() functions return prices as integers. Use the decimals property of the oracle to format the values for display or further calculations.
  • Timestamp validation If the precise timing is crucial, then use the getRoundData() function to validate the timestamp of the data retrieved.
  • Real-time updates Utilize the NewPriceUpdate event to build reactive systems that trigger actions based on price changes.

How to Use the Pull Oracle

To integrate with the pull oracle, you will need to fetch signed price data from the Chaos API and then use it in your smart contract.

Step 1: Obtain API Keys and Signer Address

Before you can fetch data or verify signatures, you must know the oracle’s trusted signer address. Contact the Chaos team to obtain your API keys and the signer address required for verification.

Step 2: Fetch Signed Price Data

Using your API key, make a GET request to the /prices/evm/crypto endpoint to retrieve the latest EVM-signed price data. You can find more details about the endpoint in the API reference. The API response will be a JSON object containing an array of prices. Here is an example of a single price object in the response:
{
  "prices": [
    {
      "feedId": "BTCUSD",
      "price": 11938032500000,
      "ts": 1753084191,
      "expo": -8,
      "signature": "314940ee402ec666daf1ade015066cf5d4ee3010b04a9710c32b48a2c916ca690f621d7bbdd230e32559ee7ac6dafbbc7ef9efb8780ff06efdd5ca5faa2cce8c1c"
    }
  ]
}

Step 3: Verify and Consume the Price On-Chain

The data from the API response must be passed to your smart contract for verification. The contract should hash the price data and verify the signature against the trusted signer address you obtained in Step 1. You can use the following smart contract to verify the signature on-chain. This contract provides functions to hash the price data and verify the ECDSA signature.
The following code is for illustrative purposes only, has not been audited, and should not be used in production without thorough testing.
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

/**
 * @title ChaosCryptoSignatureDecoder
 * @dev Contract to decode and verify crypto price signatures
**/
contract ChaosCryptoSignatureDecoder {
    using ECDSA for bytes32;

    address public constant SIGNER = 0x0;

    function hashEquitiesPriceData(
        string memory feedId,
        uint256 price,
        uint256 timestamp,
        int8 expo
    ) public pure returns (bytes32) {
        // Hash the feed ID 
        bytes32 feedIdHash = keccak256(bytes(feedId));
        bytes memory message = abi.encode(
            feedIdHash, // bytes32
            price, // uint256
            timestamp, // uint256
            expo // int8 
        );

        return keccak256(message);
    }

    /**
     * @dev Verify crypto price signature against expected signer
     */
    function verifyCryptoPrice(
        string memory feedId,
        uint256 price,
        uint256 timestamp,
        int8 expo,
        bytes memory signature
    ) external pure returns (bool) {
        bytes32 messageHash = hashEquitiesPriceData(feedId, price, timestamp, expo);
        address recoveredSigner = messageHash.recover(signature);
        return recoveredSigner == SIGNER;
    }
 
 }
To use the SignatureVerifier, you need to:
  1. Deploy the contract: Deploy the SignatureVerifier contract to your target blockchain.
  2. Hash the data: In your consumer contract, call the hashPriceFeedData function with the parameters from the API response (feedId, price, expo, roundId, timestamp, bid, ask).
  3. Verify the signature: Call the verifySignature function with the hash from the previous step, the signature from the API response, and the oracle’s trusted signer address.

Support

For assistance with EVM integration, contact our support team at [email protected].