🌱Sybil: data feeds

Pull based oracle guide

This step-by-step guide will help you understand how to effectively utilize data feeds from the Sybil module. This module is a data fetcher that can be integrated as a pull-based oracle. Additionally, it can be used in conjunction with the Pythia automation module for push-based implementations.

Step 1: API Key Setup

  1. Visit the Sybil API Key Portal: Navigate to Sybil API Key Management.

  2. Top Up Wallet and Generate API Key: Follow the portal instructions to top up your wallet and generate an API key for enhanced access. Optionally, you can whitelist your app domain to streamline the process.

  3. Dynamic Link Calculation: Utilize the dynamic link calculation feature for custom data requests.

Step 2: Fetch Data from Sybil

  • Construct Your Data Request: Define the endpoint to fetch the latest data with proof. Example request format:

    https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/get_xrc_data_with_proof?id=BTC/ETH&bytes=true&cache_ttl=1800&api_key={api_key}
  • Parameters Documentation: Detailed documentation for each method parameter (get_xrc_data_with_proof, get_dxr_data_with_proof, read_logs_with_proof, read_contract_with_proof).

Dynamically fetch requested price feed from exchanges (can calculate routing feeds, like BTC/ICP or WIF/ETH)

id

Price feed id (BTC/USD, BTC/ETH, ...)

api_key (optional)

Your API key

bytes (true / false - optional)

Respond in bytes to pass it easily on-chain and verify. Default is false

cache_ttl (optional)

Cache response for exactly this data feed request to optimize usage. Default is 600 (10 mins)

Step 3: Implement Data Fetching in Frontend

Use TypeScript and the Wagmi library to integrate Sybil data into your dApp:

import { useWriteContract } from 'wagmi';

const API_KEY = {MY_API_KEY};

const { writeContract } = useWriteContract();

// Case 1: Verify price feed data
const interactWithYourDappWithFeed = async () => {
  const dataBytes = fetch(`https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/get_xrc_data_with_proof?id=BTC/ETH&bytes=true&cache_ttl=1800&api_key=${API_KEY}`);
  
  writeContract({
    address: {your contract address},
    abi: {abi of your contract},
    functionName: 'interact',
    args: [dataBytes],
    chainId: {chainId},
  });
}

Step 4: Verify Data in Smart Contracts

Utilize the Orally Solidity SDK to implement verification in your dApp's smart contracts:

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

import "@orally-network/solidity-sdk/IOrallyVerifierOracle.sol";
import "@orally-network/solidity-sdk/OrallyStructs.sol";

contract YourDappContract {
    IOrallyVerifierOracle oracle;

    constructor(address orallyVerifierOracleAddress) {
        oracle = IOrallyVerifierOracle(orallyVerifierOracleAddress);
    }
    
    // price data from
    // https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/get_xrc_data_with_proof?id=DOGE/SHIB&bytes=true&api_key={YOUR_API_KEY}
    function interact(
        bytes memory priceFeedData
    ) public view returns (OrallyStructs.PriceFeed memory) {
        // Verify the price feed data and get the price, decimals, and timestamp.
        OrallyStructs.PriceFeed priceFeed = oracle.verifyPriceFeed(priceFeedData);
        
        // priceFeed.price is the price of DOGE/SHIB
        // priceFeed.decimals is the number of decimals in the price
        // priceFeed.timestamp is the timestamp when price feed was aggregated

        return priceFeed;
    }
    
    // -- or --

    // with cache
    // https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/get_xrc_data_with_proof?id=DOGE/SHIB&bytes=true&API_KEY={YOUR_API_KEY}
    function interact(
        bytes memory priceFeedData
    ) public returns (OrallyStructs.PriceFeed memory) {
        // Verify the price feed data and get the price, decimals, and timestamp.
        oracle.updatePriceFeed(priceFeedData);

        // Get the price feed data from the cache.
        OrallyStructs.PriceFeed priceFeed = oracle.getPriceFeed("DOGE/SHIB");

        // priceFeed.price is the price of DOGE/SHIB
        // priceFeed.decimals is the number of decimals in the price
        // priceFeed.timestamp is the timestamp when price feed was aggregated

        return priceFeed;
    }
    
    // -- or --

    // without API key
    // https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/get_xrc_data_with_proof?id=DOGE/SHIB&bytes=true
    function interact(
        bytes memory priceFeedData
    ) public payable returns (OrallyStructs.PriceFeed memory) {
        // Get the update fee for the price feed data.
        uint256 fee = oracle.getUpdateFee(priceFeedData);
        // Verify the price feed data and get the price, decimals, and timestamp.
        OrallyStructs.PriceFeed priceFeed = oracle.verifyPriceFeedWithFee{ value: fee }(priceFeedData);
        // if this price feed will be needed for later usage you can use `updatePriceFeedWithFee` instead (+90k to gas) and access as `oracle.getPriceFeed("DOGE/SHIB")`

        // priceFeed.price is the price of DOGE/SHIB
        // priceFeed.decimals is the number of decimals in the price
        // priceFeed.timestamp is the timestamp when price feed was aggregated

        return priceFeed;
    }
    
    // -- or verifying chain data example --

    // chain data from
    // https://tysiw-qaaaa-aaaak-qcikq-cai.icp0.io/read_contract_with_proof?chain_id=42161&function_signature="function balanceOf(address account) external view returns (uint256)"&contract_addr=0xA533f744B179F2431f5395978e391107DC76e103&method=balanceOf&params=(0x654DFF41D51c230FA400205A633101C5C1f1969C)&bytes=true
    function getSideChainUserTokenBalance(
        bytes calldata chainData
    ) public view returns (uint256) {
        // Verify the chain data and get the balance of the user.
        (bytes memory dataBytes, bytes memory metaBytes) = oracle.verifyReadContractData(chainData);
        // `verifyReadContractDataWithFee` for paying fee in the same transaction instead of API key

        (uint256 balance) = abi.decode(dataBytes, (uint256));
        (OrallyStructs.ReadContractMetadata memory meta) = abi.decode(metaBytes, (OrallyStructs.ReadContractMetadata));
        
        // balance is the balance of the user of the requested token
        // meta.chainId is the chain id of the side chain
        // meta.contractAddr is the address of the contract on the side chain
        // meta.method is the method that was called on the contract
        // meta.params is the parameters that were passed to the method

        return balance;
    }
}

This Solidity snippet demonstrates how your dApp's contract can interact with the OrallyVerifierOracle contract to verify the data received from Sybil.

Conclusion

This guide outlines the steps to effectively integrate and utilize the Sybil data feeds in your decentralized applications. By following these steps, you can enhance the functionality and reliability of your dApps with secure and verified data from multiple external sources.

OrallyVerifierOracle addresses

ChainContract Address

Ethereum

0x7b348835A12aaE1fDA26E2Ce8CB9746fcf865b18

Linea

0x45f61bAD7e29a6FB9ec307daD7B895e63Db1940B

Aurora

0x45f61bAD7e29a6FB9ec307daD7B895e63Db1940B

Arbitrum

0x096eb773BE73CEDed425029Dc43EC0890DB72507

zkSync

0xeC853A8dab05306e61E58fcc155bB98207eD078B

Manta Pacific Network

0x7b348835A12aaE1fDA26E2Ce8CB9746fcf865b18

Creating a Custom Pair

Orally's Sybil provides existing price feeds and allows you to create your custom price feed pair. The process is straightforward and user-friendly:

  1. Navigate to the Front-End App: Visit the Orally front-end app at Sybil dApp.

  2. Initiate the Custom Pair Creation Flow: Locate and click the button on the main page to initiate the Custom pair creation flow. This will open a modal where you will input details about your custom pair.

  3. Input Pair Details: Provide the necessary details for your custom pair in the modal. These will include the symbol name, the frequency of updates, and the endpoints from which to fetch the price feed for your token. Ensure that these details are accurate, as they will directly influence the behaviour and accuracy of your custom pair's price feed.

  4. Authenticate with SIWE: After inputting the necessary details, authenticate yourself using SIWE (Signing with Ethereum). This step is necessary for security and accountability reasons.

  5. Top Up Balance: After authentication, top up the balance with the specified token. This balance is necessary to cover the execution costs associated with your custom pair's price feed.

  6. Run Your Custom Pair: After completing all the previous steps, you can run your custom pair. Congratulations—you now have your own token price feed!

Following these steps, you can create a custom price feed pair for any token you choose. Orally's Sybil's power truly shines in its versatility and adaptability, making it a highly valuable tool for all developers in the blockchain space.

Last updated