Skip to main content
PriceCaller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract PriceCaller {
    address public networkCallsPrecompile;
    address public executorAddress;
    constructor(address _networkCallsPrecompile, address _executorAddress) {
        networkCallsPrecompile = _networkCallsPrecompile;
        executorAddress = _executorAddress;
    }
    string public result;

    /// @notice Fetch data from a public API
    /// @dev Fetches the price of Ethereum from CoinGecko
    // Reference: https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd
    function getEthPrice(
        uint64 targetBlockNumber
    ) external returns (string memory) {
        string[] memory requestHeaderKeys = new string[](1);
        requestHeaderKeys[0] = "Content-Type";
        string[] memory requestHeaderValues = new string[](1);
        requestHeaderValues[0] = "application/json";
        bytes memory request = createRequest(
            "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd", // URL
            1, // GET
            requestHeaderKeys,
            requestHeaderValues,
            "", // No body
            100, // TTL
            bytes("") // No secrets
        );
        bytes memory response = sendRequest(targetBlockNumber, request);
        // Decode into HTTP response and validate
        (
            uint16 status,
            string[] memory responseHeaderKeys,
            string[] memory responseHeaderValues,
            string memory responseBody,
            string memory errorMessage
        ) = abi.decode(response, (uint16, string[], string[], string, string));
        require(status == 200, errorMessage);
        result = responseBody;
        return responseBody;
    }
    // Internal function to create a request
    function createRequest(
        string memory url,
        uint8 method,
        string[] memory headerKeys,
        string[] memory headerValues,
        string memory body,
        uint ttl,
        bytes memory secrets
    ) internal view returns (bytes memory) {
        return
            abi.encode(
                executorAddress,
                secrets,
                ttl,
                url,
                method,
                headerKeys,
                headerValues,
                body
            );
    }
    // Internal function to send a request
    function sendRequest(
        // Unused, but required for interface
        uint64 /* blockNumber */,
        bytes memory request
    ) internal returns (bytes memory) {
        (bool success, bytes memory response) = networkCallsPrecompile.call(
            request
        );
        require(success, "Network call failed");
        return response;
    }
}