> ## Documentation Index
> Fetch the complete documentation index at: https://www.diadata.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Alephium

> dApps built on Alephium can leverage DIA oracles to access up-to-date asset price information.

[DIA](https://diadata.org/) 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

| Chain   | Address                                                                                                                                |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Mainnet | [285zrkZTPpUCpjKg9E3z238VmpUBQEAbESGsJT6yX7Rod](https://explorer.alephium.org/addresses/285zrkZTPpUCpjKg9E3z238VmpUBQEAbESGsJT6yX7Rod) |
| Testnet | [216wgM3Xi5uBFYwwiw2T7iZoCy9vozPJ4XjToW74nQjbV](https://testnet.alephium.org/addresses/216wgM3Xi5uBFYwwiw2T7iZoCy9vozPJ4XjToW74nQjbV)  |

## Oracle configuration

|                                       |                                                                                                                            |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Pricing Methodology**               | [VWAPIR](/docs/guides/methodologies/pricing-methodologies/vwapir-volume-weighted-average-price-with-interquartile-range-filter) |
| **Deviation (%) & Refresh Frequency** | 0.2% and 120 seconds                                                                                                       |
| **Heartbeat**                         | 10mins                                                                                                                     |

## Asset feeds

| Asset Ticker | getValue(key) | Asset Markets                                                                                                  |
| ------------ | ------------- | -------------------------------------------------------------------------------------------------------------- |
| BTC          | BTC/USD       | [BTC markets](https://www.diadata.org/app/price/asset/Bitcoin/0x0000000000000000000000000000000000000000/)     |
| USDC         | USDC/USD      | [USDC markets](https://www.diadata.org/app/price/asset/Ethereum/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/)   |
| ETH          | ETH/USD       | [ETH markets](https://www.diadata.org/app/price/asset/Ethereum/0x0000000000000000000000000000000000000000/)    |
| WBTC         | WBTC/USD      | [WBTC markets](https://www.diadata.org/app/price/asset/Ethereum/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/)   |
| USDT         | USDT/USD      | [USDT markets](https://www.diadata.org/app/price/asset/Ethereum/0xdAC17F958D2ee523a2206206994597C13D831ec7/)   |
| ALPH         | ALPH/USD      | [ALPH markets](https://www.diadata.org/app/price/asset/Alephium/tgx7VNFoP9DJiFMFgXXtafQZkUvyEdDHT9ryamHJYrjq/) |
| AYIN         | AYIN/USD      | [AYIN markets](https://www.diadata.org/app/price/asset/Alephium/vT49PY8ksoUL6NcXiZ1t2wAmC7tTPRfFfER8n3UCLvXy/) |

## 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](https://docs.alephium.org/ralph/):

```js theme={"system"}
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

| Chain            | Address                                                                                                                               |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Alephium Mainnet | [v1v4cBXP9L7M9ryZZCx7tuXuNb9pnDLGb3JJkPBpbR1Z](https://explorer.alephium.org/addresses/v1v4cBXP9L7M9ryZZCx7tuXuNb9pnDLGb3JJkPBpbR1Z)  |
| Alephium Testnet | [217k7FMPgahEQWCfSA1BN5TaxPsFovjPagpujkyxKDvS3](https://testnet.alephium.org/addresses/217k7FMPgahEQWCfSA1BN5TaxPsFovjPagpujkyxKDvS3) |

## Oracle configuration

The oracle uses [drand](https://drand.love/) 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](https://docs.alephium.org/ralph/):

```js theme={"system"}
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](/docs/dia-stack/data-products/verifiable-randomness).

***

## 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:

<Card title="DIA Oracle Grants Program | Apply Now" href="https://www.diadata.org/blockchain-oracle-grant/" horizontal />

## 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:

<CardGroup>
  <Card title="Request Custom Oracle" href="/docs/guides/how-to-guides/request-a-custom-oracle" icon="angle-right" iconType="solid" horizontal />
</CardGroup>

## Support

For developer assistance, connect with the DIA team directly on [Discord](https://discord.gg/ZvGjVY5uvs) or [Telegram](https://t.me/diadata_org).
