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

# Quickstart

> Get started to build on Pragma

You can get started with Pragma in just a few minutes. This guide will walk you through the process of consuming data from Pragma's oracle network.
Here is a simple contract allowing a user to retrieve the price of an asset, using the Pragma Oracle.

## Add Pragma as a dependency to your scarb/snforge project

```shell theme={null}
scarb add pragma_lib --git https://github.com/astraly-labs/pragma-lib
```

## Overview of the contract

```rust hack_template.cairo [expandable] theme={null}
use starknet::ContractAddress;

#[starknet::interface]
trait HackTemplateABI<TContractState> {
    fn get_asset_price(self: @TContractState, asset_id: felt252) -> u128;
}

#[starknet::contract]
mod HackTemplate {
    use super::{ContractAddress, HackTemplateABI};
    use array::{ArrayTrait, SpanTrait};
    use traits::{Into, TryInto};
    use pragma_lib::abi::{
            IPragmaABIDispatcher, IPragmaABIDispatcherTrait, ISummaryStatsABIDispatcher,
            ISummaryStatsABIDispatcherTrait};
    use pragma_lib::types::{DataType, AggregationMode, PragmaPricesResponse};
    use starknet::get_block_timestamp;
    use option::OptionTrait;
    const ETH_USD: felt252 = 19514442401534788;  //ETH/USD to felt252, can be used as asset_id
    const BTC_USD: felt252 = 18669995996566340;  //BTC/USD


    #[storage]
    struct Storage {
        pragma_contract: ContractAddress,
        summary_stats: ContractAddress,
    }

    #[constructor]
    fn constructor(ref self: ContractState, pragma_address: ContractAddress, summary_stats_address : ContractAddress)
    {
        self.pragma_contract.write(pragma_address);
        self.summary_stats.write(summary_stats_address);
    }
    #[external(v0)]
    impl HackTemplateABIImpl of HackTemplateABI<ContractState> {


        fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 {
            // Retrieve the oracle dispatcher
            let oracle_dispatcher = IPragmaABIDispatcher {
                contract_address: self.pragma_contract.read()
            };

            // Call the Oracle contract, for a spot entry
            let output: PragmaPricesResponse = oracle_dispatcher
                .get_data_median(DataType::SpotEntry(asset_id));

            return output.price;
        }

    }
}


```

Let's break down the code above:

```rust theme={null}
#[starknet::interface]
trait HackTemplateABI<TContractState> {
    fn get_asset_price(self: @TContractState, asset_id: felt252) -> u128;
}
```

Firstly, we defined the interface of our contract. The interface is a set of functions that can be called by other contracts. In this case, we have only one function, `get_asset_price`, which takes as input the asset id of the asset we want to retrieve the price of, and returns the price of the asset. The asset id is a felt252, and can be converted from a string using the `felt252` conversion. The asset id is used to identify the data feed we want to retrieve (for example BTC/USD).

Then comes the contract itself:

```rust theme={null}
#[starknet::contract]
mod HackTemplate {
    use super::{ContractAddress, HackTemplateABI};
    use array::{ArrayTrait, SpanTrait};
    use traits::{Into, TryInto};
    use pragma_lib::abi::{
            IPragmaABIDispatcher, IPragmaABIDispatcherTrait, ISummaryStatsABIDispatcher,
            ISummaryStatsABIDispatcherTrait};
    use pragma_lib::types::{DataType, AggregationMode, PragmaPricesResponse};
    use starknet::get_block_timestamp;
    use option::OptionTrait;
    const ETH_USD: felt252 = 19514442401534788;  //ETH/USD to felt252, can be used as asset_id
    const BTC_USD: felt252 = 18669995996566340;  //BTC/USD


    #[storage]
    struct Storage {
        pragma_contract: ContractAddress,
        summary_stats: ContractAddress,
    }

    #[constructor]
    fn constructor(ref self: ContractState, pragma_address: ContractAddress, summary_stats_address : ContractAddress)
    {
        self.pragma_contract.write(pragma_address);
        self.summary_stats.write(summary_stats_address);
    }
    #[external(v0)]
    impl HackTemplateABIImpl of HackTemplateABI<ContractState> {


        fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 {
            // Retrieve the oracle dispatcher
            let oracle_dispatcher = IPragmaABIDispatcher {
                contract_address: self.pragma_contract.read()
            };

            // Call the Oracle contract, for a spot entry
            let output: PragmaPricesResponse = oracle_dispatcher
                .get_data_median(DataType::SpotEntry(asset_id));

            return output.price;
        }

    }
}
```

This is the general form of a starknet contract, you can learn more about the way to build a Starknet contract [here](https://book.cairo-lang.org/ch100-00-introduction-to-smart-contracts.html#anatomy-of-a-simple-contract).
The notable point here is among the imports:

```rust theme={null}
use pragma_lib::abi::{
            IPragmaABIDispatcher, IPragmaABIDispatcherTrait,
            ISummaryStatsABIDispatcher, ISummaryStatsABIDispatcherTrait
        };
use pragma_lib::types::{DataType, AggregationMode, PragmaPricesResponse};
```

This line imports the dispatcher corresponding to the oracle contract interface and its associated trait. The dispatcher enables the invocation of interface-defined functions. For deeper insights into the dispatcher and its trait, consult the [cairo book](https://book.cairo-lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-calls.html).

Allows the imports of the required structures/enums for executing the function call. These three are the main structures/enums used in most functions of the Pragma oracle contract. The `AggregationMode` enum is used to specify the aggregation mode of the data, the `DataType` enum is used to specify the type of data to be retrieved, and the `PragmaPricesResponse` structure is used to store the response to the function call.

```rust theme={null}
enum DataType {
    SpotEntry: felt252,
    FutureEntry: (felt252, u64),
    GenericEntry: felt252,
}

struct PragmaPricesResponse {
    price: u128,
    decimals: u32,
    last_updated_timestamp: u64,
    num_sources_aggregated: u32,
    expiration_timestamp: Option<u64>,
}

#[derive(Serde, Drop, Copy)]
enum AggregationMode {
    Median: (),
    Mean: (),
    ConversionRate,
    Error,
}
```

We deploying the contract, you will have to specify the oracle contract address and the summary stats contract address. The summary stats is a contract providing [computational feeds](./advanced/overview) (TWAP, Yield Curve, Realized Volatility, ...). In the provided example we will not use the summary stats contract.
The oracle address can be found [here](./development).
The previous contract is a simple contract, allowing a user to retrieve the price of an asset. You can play with a more complete example and deploy using Remix.

<div>
  <a href="https://remix.ethereum.org/#activate=Starknet-cairo1-compiler&gist=8a6bffad23983a0ded7a6bebfa0d7974
  " target="_blank" class="button">Open in Remix</a>
</div>

## Working with Remix

<Steps>
  <Step title="Activate the Starknet Plugin">
    To begin with, you will have to activate the Starknet plugin:

    <img src="https://mintcdn.com/pragma-a70dd633/10WsAM0SCV2mMOnM/images/remix/remix1.webp?fit=max&auto=format&n=10WsAM0SCV2mMOnM&q=85&s=ac2c7f33c0f9df912895f8122ffc8928" alt="starknet-plugin" width="920" height="560" data-path="images/remix/remix1.webp" />
  </Step>

  <Step title="Compile the Code">
    Once the Starknet plugin is activated, the Starknet icon should appear on the left side of the screen. You will then need to compile the code:

    <img src="https://mintcdn.com/pragma-a70dd633/10WsAM0SCV2mMOnM/images/remix/remix2.webp?fit=max&auto=format&n=10WsAM0SCV2mMOnM&q=85&s=841fa4b3b6f4b1f1660880335e77f9e7" alt="compile" width="640" height="505" data-path="images/remix/remix2.webp" />
  </Step>

  <Step title="Deploy the Contract">
    After compiling, create and deploy an account, and use the button to get testnet ETH:

    <img src="https://mintcdn.com/pragma-a70dd633/10WsAM0SCV2mMOnM/images/remix/remix3.webp?fit=max&auto=format&n=10WsAM0SCV2mMOnM&q=85&s=e2e474ff543076df882005c1407d2038" alt="deploy-account" width="640" height="586" data-path="images/remix/remix3.webp" />

    Finally, deploy the contract using the oracle contract address and the summary stats contract address. You can find the oracle address [here](./development) and the summary stats address [here](./advanced/overview).

    <img src="https://mintcdn.com/pragma-a70dd633/10WsAM0SCV2mMOnM/images/remix/remix4.webp?fit=max&auto=format&n=10WsAM0SCV2mMOnM&q=85&s=ad7cb2cd7043c9ddfedb8e4c08d988d9" alt="deploy" width="640" height="385" data-path="images/remix/remix4.webp" />
  </Step>

  <Step title="Interact with the Contract">
    Once deployed, you can interact with the contract:

    <img src="https://mintcdn.com/pragma-a70dd633/10WsAM0SCV2mMOnM/images/remix/remix5.webp?fit=max&auto=format&n=10WsAM0SCV2mMOnM&q=85&s=b398eebb92622524a4aa8a52e1ed28de" alt="interact" width="619" height="640" data-path="images/remix/remix5.webp" />
  </Step>
</Steps>

🎉 Congratulations! You have used Pragma!
