Skip to main content
DIA is a cross-chain oracle provider that sources granular market data from diverse exchanges, including CEXs and DEXs. Its data sourcing is thorough, enabling unparalleled transparency and customizability for resilient price feeds for 20,000+ assets. Its versatile data processing and delivery ensures adaptability and reliability for any decentralized application.

Token Price Feeds

Oracle details

ChainAddress
Mainnet285zrkZTPpUCpjKg9E3z238VmpUBQEAbESGsJT6yX7Rod
Testnet216wgM3Xi5uBFYwwiw2T7iZoCy9vozPJ4XjToW74nQjbV

Oracle configuration

Pricing MethodologyVWAPIR
Deviation (%) & Refresh Frequency0.2% and 120 seconds
Heartbeat10mins

Asset feeds

Asset TickergetValue(key)Asset Markets
BTCBTC/USDBTC markets
USDCUSDC/USDUSDC markets
ETHETH/USDETH markets
WBTCWBTC/USDWBTC markets
USDTUSDT/USDUSDT markets
ALPHALPH/USDALPH markets
AYINAYIN/USDAYIN markets

How to access data

Locate one of the deployed contracts (either testnet or mainnet) and call the getValue function. This function expects one parameter, which is the symbols of the asset you want to retrieve and a “/USD”, so for example for the Bitcoin price the parameter must be “BTC/USD”. This will return two values:
  1. The price of the asset, with 8 decimals.
  2. The timestamp of the last update in Unix time format, in UTC timezone.
Below is the DIAOracle contract implementation in Ralph:
Contract DIAOracle(
    mut admin: Address
) extends DIAOracleBase(admin) implements IDIAOracle {
    mapping[ByteVec, DIAOracleValue] onchainValues

    event OracleUpdate(key: ByteVec, value: U256, timestamp: U256)

    const MaxBatchSize = 10

    enum ErrorCodes {
        InvalidBatchSize = 1
        InvalidKey = 2
    }

    pub fn getValue(key: ByteVec) -> DIAOracleValue {
        if (!onchainValues.contains!(key)) {
            panic!(ErrorCodes.InvalidKey)
        }

        return onchainValues[key]
    }

    @using(preapprovedAssets = true)
    pub fn setValue(key: ByteVec, value: U256, timestamp: U256) -> () {
        checkAdmin(callerAddress!())
        updateValue{admin -> ALPH: mapEntryDeposit!()}(key, value, timestamp)
    }

    @using(preapprovedAssets = true)
    pub fn setMultipleValues(
        keys: [ByteVec; 10],
        values: [U256; 10],
        timestamps: [U256; 10],
        batchSize: U256
    ) -> () {
        checkAdmin(callerAddress!())
        assert!(batchSize <= MaxBatchSize, ErrorCodes.InvalidBatchSize)

        for (let mut i = 0; i < batchSize; i = i + 1) {
            updateValue{admin -> ALPH: mapEntryDeposit!()}(
                keys[i],
                values[i],
                timestamps[i]
            )
        }
    }

    @using(preapprovedAssets = true)
    fn updateValue(key: ByteVec, value: U256, timestamp: U256) -> () {
        if (!onchainValues.contains!(key)) {
            onchainValues.insert!(admin, key, DIAOracleValue{value, timestamp})
        } else {
            onchainValues[key] = DIAOracleValue{value, timestamp}
        }

        emit OracleUpdate(key, value, timestamp)
    }
}

Verifiable Randomness

Oracle details

ChainAddress
Alephium Mainnetv1v4cBXP9L7M9ryZZCx7tuXuNb9pnDLGb3JJkPBpbR1Z
Alephium Testnet217k7FMPgahEQWCfSA1BN5TaxPsFovjPagpujkyxKDvS3

Oracle configuration

The oracle uses drand randomness from the quicknet mainnet to provide randomness on Alephium.

How to access data

To consume randomness data, you’ll need to invoke the getLastRound method on the oracle contract. It will return the round ID of the latest update. Using this round ID, you can call getRandomValue and will receive a return value of that randomness, the round ID and the BLS signature from the drand API. Note that round IDs are used round-robin and will repeat after 1000 iterations. Below is the DIARandomOracle contract implementation in Ralph:
Contract DIARandomOracle(
    mut admin: Address,
    mut lastRound: U256
) extends DIAOracleBase(admin) implements IDIARandomOracle {

    mapping[U256, DIARandomValue] randomValues

    event OracleUpdate(
        round: U256,
        randomness: ByteVec,
        signature: ByteVec
    )

    const MaxSlot = 1000

    enum ErrorCodes {
        InvalidRound = 1
        RoundKeyNotExist = 2
        RoundIsExpired = 3
    }

    pub fn getLastRound() -> U256 {
        return lastRound
    }

    pub fn getRandomValue(realRound: U256) -> DIARandomValue {
        let roundKey = realRound % MaxSlot
        assert!(randomValues.contains!(roundKey), ErrorCodes.RoundKeyNotExist)

        let randomValue = randomValues[roundKey]
        assert!(randomValue.round == realRound, ErrorCodes.RoundIsExpired)
        return randomValue
    }

    @using(preapprovedAssets = true, updateFields = true)
    pub fn setRandomValue(value: DIARandomValue) -> () {
        checkAdmin(callerAddress!())
        assert!(value.round > lastRound, ErrorCodes.InvalidRound)

        let roundKey = value.round % MaxSlot
        lastRound = value.round

        if (randomValues.contains!(roundKey)) {
            randomValues[roundKey] = value
        } else {
            randomValues.insert!(admin, roundKey, value)
        }

        emit OracleUpdate(value.round, value.randomness, value.signature)
    }
}
You can learn more here.

Oracle Grants Program

The DIA Oracle Grants Program provides zero-cost oracle access for up to 1 year, covering deployment and update costs to accelerate dApp development on Alephium. Learn more about the grant here:

DIA Oracle Grants Program | Apply Now

Request a Custom Oracle

DIA offers highly customizable oracles that are individually tailored to each dApp’s needs. Each oracle can be customized in the following ways, including:
  • Data Sources & Asset Feeds
  • Pricing Methodologies
  • Update Triggers (Frequency, Deviation, Heartbeat, …etc)
Get a tailored oracle for your dApp, request one below:

Support

For developer assistance, connect with the DIA team directly on Discord or Telegram.
I