Concordium Integration examples

If you want to integrate Umbrella Network's oracle in Concordium, the first thing you must take into consideration is that the only method available to read data is the Direct Access.
All other smart contract dependencies and architecture remain the same.

Refer to our Integration details page for more information about each read method.

📘

Reference smart contract

For your convenience, a reference smart contract on how to integrate with the Umbrella Network Oracle is available on our repo. Please check readme here.

Below you will find some code snippets that depicts how to use Umbrella Network's oracle.

Dependencies

To start with, some modules are included in the repo that contains useful methods to will help you integrate your project with the Umbrella Network's oracle.

Below you will find a list of dependencies required to be indicated in your code:

use concordium_std::*;
use umbrella_feeds::PriceData;

The umbrella_feeds dependency must be taken from GitHub using the following cargo command:

cargo add --git https://github.com/umbrella-network/phoenix-concordium.git umbrella-feeds

Specific,definitions

Some specific data structures are defined to handle the errors in the reference smart contract. It is at your own discretion to reuse these definitions or have your own error handling.

/// Errors
#[derive(Debug, PartialEq, Eq, Clone, Reject, Serialize, SchemaType)]
pub enum CustomContractError {
    /// Failed parsing the parameter.
    #[from(ParseError)]
    ParseParams, // -1
    /// Failed updating the price because the price fetched from the oracle is
    /// not up to date.
    PriceNotUpToDate, // -2
    /// Failed to invoke a contract.
    InvokeContractError, // -3
    /// Failed because the timestamp overflowed.
    Overflow, // -4
}

/// Mapping errors related to contract invocations to CustomContractError.
impl<T> From<CallContractError<T>> for CustomContractError {
    fn from(_cce: CallContractError<T>) -> Self {
        Self::InvokeContractError
    }
}

Resolve UmbrellaFeeds address

To resolve the address of the latest UmbrellaFeeds instance to use, your project must retrieve the address from the Registry smart contract using the getAddress method. Additionally, the address must be converted for future use.

First we define the UMBRELLA_REGISTRY_CONTRACT which contains the address to the Registry contract. For thsi example we are using the testnet address:

/// Registry contract address on Concordium testnet.
const UMBRELLA_REGISTRY_CONTRACT: ContractAddress = ContractAddress {
    index: 7542,
    subindex: 0,

Once we have the address to the Registry contract, we will use it to read the address of the Umbrella_feeds contract using the invoke_contract_read_only:

let umbrella_feeds_contract = host.invoke_contract_read_only(
        &UMBRELLA_REGISTRY_CONTRACT,
        &String::from("UmbrellaFeeds"),
        EntrypointName::new_unchecked("getAddress"),
        Amount::zero(),
    )?;

The invoke_contract_read_only function returns a bytecode. We need to convert that into something readable. We can achieve this by using the get function (we are also including error handling in the code):

  /// Parse address
  let umbrella_feeds_contract: ContractAddress =
        if let Some(mut umbrella_feeds_contract) = umbrella_feeds_contract {
            umbrella_feeds_contract.get()?
        } else {
            return Err(CustomContractError::InvokeContractError);
        };

At this point, we have the address of the UmbrellaFeeds contract decoded in the umbrell_feeds_contract variable.

Retrieve feed value from UmbrellaFeeds

Once you have obtained the address of the latest instance of the UmbrellaFeeds contract, you can read the latest value for a feed directly from it.

In order to do that, we must pass the key of the desired Feed encoded.

The feed key must be encoded as a String:

let price_feed_name: String::from("CCD-USD");

The Feed value is retrieved invoking the getPriceData method passing the key we just set.

let price = host.invoke_contract_read_only(
        &umbrella_feeds_contract,
        &price_feed_name,
        EntrypointName::new_unchecked("getPriceData"),
        Amount::zero(),
    )?;

Parse feed value

Most probably the value onbtained in above statement must be parsed in order to be used in your smart contract:

let price_data: PriceData = if let Some(mut price) = price {
        price.get()?
    } else {
        return Err(CustomContractError::InvokeContractError);
    };

Feeds available on testnet

The following feeds were made available on Concordium testnet for any project to use. If your project requires another feed, please reach us to [email protected]

FeedDeviation thresholdHeartbeat
USDT-USD0.1%6 hours
USDC-USD0.1%6 hours
WBTC-USD1%1 day
WETH-USD0.5%1 hour
CCD-USD0.5%1 day
MIM-USD0.2%1 day