Interacting with Oracle on EVM

Overview

This tutorial demonstrates how to fetch oracle prices in an EVM Minitia environment using Cosmos queries. The integration is facilitated by the COSMOS_CONTRACT from Initia's EVM precompiles that enable querying through a CosmWasm contract. Here, we explore the use of oracle data to obtain currency pair information and prices directly via Cosmos smart contracts.

Prerequisites

Enabling Oracles

Sample Contract Implementation

Through the evm-slinky-query repository, you can fetch oracle prices through a CosmWasm contract.

In this section, we'll provide an example contract and show how to deploy it so that you can call stargate query or directly implement it in your contract.

Get All Currency Pairs

Function to fetch all currency pairs available from the oracle.

function get_all_currency_pairs() external returns (string memory) {
    string memory path = "/slinky.oracle.v1.Query/GetAllCurrencyPairs";
    string memory req = "{}";
    return COSMOS_CONTRACT.query_cosmos(path, req);
}

// response example: '{"currency_pairs":[{"Base":"BITCOIN","Quote":"USD"},{"Base":"INIT","Quote":"USD"}]}'

Get Price

Function to fetch the price of a specific currency pair. pair_id is in a format of {Base}/{Quote} .

function get_price(string memory pair_id) external returns (Price memory) {
    string memory path = "/slinky.oracle.v1.Query/GetPrice";
    string memory req = string.concat(string.concat('{"currency_pair_id":"', pair_id), '"}');
    string memory queryRes = COSMOS_CONTRACT.query_cosmos(path, req);
    
    uint returnValue;
    JsmnSolLib.Token[] memory tokens;
    uint actualNum;
    (returnValue, tokens, actualNum) = JsmnSolLib.parse(queryRes, 15);

    return get_price_from_tokens(queryRes, tokens, 0);
}

Get Prices

Function to fetch prices for multiple currency pairs.

function get_prices(string[] memory pair_ids) external returns (Price[] memory) {
    string memory path = "/slinky.oracle.v1.Query/GetPrices";
    string memory req = string.concat(string.concat('{"currency_pair_ids":["', join(pair_ids, '","')), '"]}');
    uint numberElements = 3 + pair_ids.length * 15;

    string memory queryRes = COSMOS_CONTRACT.query_cosmos(path, req);
    
    uint returnValue;
    JsmnSolLib.Token[] memory tokens;
    uint actualNum;
    (returnValue, tokens, actualNum) = JsmnSolLib.parse(queryRes, numberElements);

    Price[] memory response = new Price[](actualNum / 15);
    uint index = 3;
    while (index < actualNum) {
        response[index / 15] = get_price_from_tokens(queryRes, tokens, index);
        index = index + 15;
    }

    return response;
}

Conclusion

This contract provides a foundation for integrating real-time oracle data into your blockchain applications, leveraging Cosmos-based oracles within an EVM context. It's suitable for financial applications requiring access to up-to-date currency prices and can be expanded or modified to fit specific requirements or additional functionalities.

Last updated

Logo

© 2024 Initia Foundation, All rights reserved.