PriceCaller.sol
Copy
// 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;
}
}