# Apollo: request feeds from EVM

<figure><img src="https://3198212384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnekehI12De2gMP6eOBPI%2Fuploads%2FcIij6etQuWLujb1VT3UM%2Fapollo.png?alt=media&#x26;token=c9b07675-e676-44d5-aeb3-b9e3bfccc703" alt=""><figcaption><p>Apollo architecture</p></figcaption></figure>

**Apollo** is an intricate module developed to bridge the gap between EVM (Ethereum Virtual Machine) contracts and the data-rich environment of the Orally platform, particularly its [Sybil](https://docs.orally.network/orally-products/sybil) component. Beyond mere data provisioning, Apollo is also configured to provide a level of [randomness](https://docs.orally.network/utilised-icp-features/random-tape) through a cryptographic measure, utilizing the unpredictable BLS signatures inherent to the Internet Computer (ICP) execution layer.

**Integration Steps:**

1. To start using the Apollo module, your smart contract needs to inherit from [`ApolloReceiver`](https://github.com/orally-network/evm-oracle/blob/main/src/apollo/ApolloReceiver.sol). This setup allows your contract to receive data from the Apollo network:

```solidity
// Import the ApolloReceiver contract
import {ApolloReceiver} from "../apollo/ApolloReceiver.sol";

// Your contract inherits from ApolloReceiver
contract YourContract is ApolloReceiver {
    // Constructor initializes the ApolloReceiver with registry and coordinator addresses
    constructor(address _executorsRegistry, address _apolloCoordinator) 
        ApolloReceiver(_executorsRegistry, _apolloCoordinator) {}
}
```

2. To request data, such as a price feed, use the `requestDataFeed` (or `requestRandomFeed` for randomness) function from the [`ApolloCoordinator`](https://github.com/orally-network/evm-oracle/blob/main/src/apollo/ApolloCoordinator.sol) ([interface](https://github.com/orally-network/evm-oracle/blob/main/src/interfaces/IApolloCoordinator.sol)). This function emits an event that the Apollo network listens for to provide the requested data.&#x20;

{% tabs %}
{% tab title="Random Feed" %}

```solidity
// Example function to request a price feed
// `apolloCoordinator` is passing as public var from ApolloReceiver contract
function requestRandomFeed() public {
        // Requesting the randomness with a specified callback gas limit and number of random words
        apolloCoordinator.requestRandomFeed(300000, 1);
}
```

{% endtab %}

{% tab title="Data Feed" %}

```solidity
// Example function to request a price feed
// `apolloCoordinator` is passing as public var from ApolloReceiver contract
function requestPriceFeed() public {
        // Requesting the ICP/USD price feed with a specified callback gas limit
        apolloCoordinator.requestDataFeed("ICP/USD", 300000);
}
```

{% endtab %}
{% endtabs %}

3. Override the `fulfillData` function to define how your contract should handle the incoming data. This function is called when the Apollo network delivers the data to your contract.

{% tabs %}
{% tab title="Random Feed" %}

```solidity
contract YourContract is ApolloReceiver {
    // ...

    // Overriding the fulfillData function to handle incoming data
    function fulfillData(bytes memory data) internal override {
        (, uint256[] memory randomWords) = abi.decode(data, (uint256, uint256[]));

        // transform the result to a number between 1 and 20 inclusively
        uint256 randomNumber = (randomWords[0] % entries.length) + 1;

        pickWinner(randomNumber);
    }
}
```

{% endtab %}

{% tab title="Data Feed" %}

```solidity
contract YourContract is ApolloReceiver {
    // Data storage variables
    uint256 public requestId;
    string public dataFeedId;
    uint256 public rate;
    uint256 public decimals;
    uint256 public timestamp;

    // Overriding the fulfillData function to handle incoming data
    function fulfillData(bytes memory data) internal override {
        (
            uint256 _requestId,
            string memory _dataFeedId,
            uint256 _rate,
            uint256 _decimals,
            uint256 _timestamp
        ) = abi.decode(data, (
            uint256,
            string,
            uint256,
            uint256,
            uint256
        ));


        requestId = _requestId;
        dataFeedId = _dataFeedId;
        rate = _rate;
        decimals = _decimals;
        timestamp = _timestamp;
    }
}
```

{% endtab %}
{% endtabs %}

That's it! You successfully requested data and received it in the callback.&#x20;

Here are contract addresses for [IApolloCoordinator](https://github.com/orally-network/evm-oracle/blob/main/src/interfaces/IApolloCoordinator.sol) and [IOrallyExecutorRegistry](https://github.com/orally-network/evm-oracle/blob/main/src/interfaces/IOrallyExecutorsRegistry.sol).&#x20;

{% tabs %}
{% tab title="Sepolia" %}

<table><thead><tr><th width="349">Contract</th><th></th></tr></thead><tbody><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/apollo/ApolloCoordinator.sol">ApolloCoordinator</a></td><td><a href="https://sepolia.etherscan.io/address/0xDC88B1919AF3AD86AAcE0FB19F125cb3Db3543e2"><code>0xDC88B1919AF3AD86AAcE0FB19F125cb3Db3543e2</code></a></td></tr><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/OrallyExecutorsRegistry.sol">OrallyExecutorsRegistry</a></td><td><a href="https://sepolia.etherscan.io/address/0x4531112808f8C0068768cC3fAE0939e0c05719D1"><code>0x4531112808f8C0068768cC3fAE0939e0c05719D1</code></a></td></tr></tbody></table>
{% endtab %}

{% tab title="Zircuit" %}

<table><thead><tr><th width="349">Contract</th><th></th></tr></thead><tbody><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/apollo/ApolloCoordinator.sol">ApolloCoordinator</a></td><td><a href="https://explorer.zircuit.com/address/0x45f61bAD7e29a6FB9ec307daD7B895e63Db1940B"><code>0x45f61bAD7e29a6FB9ec307daD7B895e63Db1940B</code></a></td></tr><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/OrallyExecutorsRegistry.sol">OrallyExecutorsRegistry</a></td><td><a href="https://explorer.zircuit.com/address/0x76d67e374391DF6363B72dA8530035Ee5f27a3Da"><code>0x76d67e374391DF6363B72dA8530035Ee5f27a3Da</code></a></td></tr></tbody></table>
{% endtab %}

{% tab title="Taiko Katla" %}

<table><thead><tr><th width="349">Contract</th><th></th></tr></thead><tbody><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/apollo/ApolloCoordinator.sol">ApolloCoordinator</a></td><td>0x1FEa4E134c8BcDF6E1323C1Bf2Aa0899049CC754</td></tr><tr><td><a href="https://github.com/orally-network/evm-oracle/blob/main/src/OrallyExecutorsRegistry.sol">OrallyExecutorsRegistry</a></td><td>0x81f8573B46895f65C7658Aa3A0eB90578F7F2dC9</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

Here are Apollo consumer examples:

* [RaffleExample](https://github.com/orally-network/evm-oracle/blob/main/src/examples/RaffleExample.sol) (randomness)
* [ApolloConsumerExample](https://github.com/orally-network/evm-oracle/blob/main/src/examples/ApolloConsumerExample.sol) (price feed)
