Interacting with Oracle on WasmVM

Overview

This tutorial guides you through fetching oracle prices in a WasmVM on Minitia environment utilizing stargate query. By following this tutorial, developers can understand how to integrate and retrieve real-time financial data within their smart contracts on the Minitia blockchain.

Prerequisites for L2s

Enabling Oracles

Sample Contract Implementation

Using the wasm-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.

fn get_all_currency_pairs(&self, deps: Deps, _env: Env) -> StdResult<GetAllCurrencyPairsResponse> {
    let request = GetAllCurrencyPairsRequest { 
        special_fields: ::protobuf::SpecialFields::new()
    };
    let bytes = request.write_to_bytes().unwrap();

    let data = Binary::from(bytes);
    let request = QueryRequest::<Empty>::Stargate{path: "/slinky.oracle.v1.Query/GetAllCurrencyPairs".to_string(), data};
    let res: GetAllCurrencyPairsResponse = deps.querier.query(&request)?;
    Ok(res)
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[allow(non_snake_case)]
pub struct CurrencyPair {
    pub Base: String,
    pub Quote: String,
}

Get Price

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

fn get_price(&self, deps: Deps, _env: Env, pair_id: String) -> StdResult<GetPriceResponse> {
    let request = GetPriceRequest { 
        currency_pair_selector: Some(Currency_pair_selector::CurrencyPairId(pair_id)),
        special_fields: ::protobuf::SpecialFields::new()
    };
    let bytes = request.write_to_bytes().unwrap();
    
    let data = Binary::from(bytes);
    let request = QueryRequest::Stargate{path: "/slinky.oracle.v1.Query/GetPrice".to_string(), data};
    let res: GetPriceResponseRaw = deps.querier.query(&request)?;
    Ok(convert_raw_price_response(&res))
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct GetPriceResponse {
    pub price: QuotePrice,
    pub nonce: u64,
    pub decimals: u64,
    pub id: u64,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct QuotePrice {
    pub price: Uint256,
    pub block_timestamp: String, // ISO string
    pub block_height: u64,
}

Get Prices

Function to fetch prices for multiple currency pairs.

fn get_prices(&self, deps: Deps, _env: Env, pair_ids: Vec<String>) -> StdResult<GetPricesResponse> {
    let request = GetPricesRequest { 
        currency_pair_ids: pair_ids,
        special_fields: ::protobuf::SpecialFields::new()
    };
    let bytes = request.write_to_bytes().unwrap();
    
    let data = Binary::from(bytes);
    let request = QueryRequest::Stargate{path: "/slinky.oracle.v1.Query/GetPrices".to_string(), data};
    let raw_res: GetPricesResponseRaw = deps.querier.query(&request)?;
    let res = GetPricesResponse {
        prices: raw_res.prices.into_iter().map(|raw| convert_raw_price_response(&raw)).collect()
    };
    Ok(res)
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct GetPricesResponse {
    pub prices: Vec<GetPriceResponse>
}

Conclusion

This contract provides a foundation for integrating real-time oracle data into your blockchain applications, leveraging Cosmos-based oracles within an WasmVM 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.