Skip to content

Commit

Permalink
feat(theoros_handlers): Get data feeds OK
Browse files Browse the repository at this point in the history
  • Loading branch information
akhercha committed Sep 10, 2024
1 parent 49e1500 commit 5437380
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 54 deletions.
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/pragma-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ rusoto_core = { workspace = true }
hex = { workspace = true }
strum = { workspace = true }
strum_macros = { workspace = true }
serde = { workspace = true, features = ["derive"] }
14 changes: 8 additions & 6 deletions rust/pragma-utils/src/feeds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,18 @@ use std::str::FromStr;

use anyhow::{anyhow, bail, Context};
use hex;
use serde::{Deserialize, Serialize};
use strum_macros::{Display, EnumString};

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Feed {
pub feed_id: String,
pub asset_class: AssetClass,
pub feed_type: FeedType,
pub pair_id: String,
}

#[derive(Debug, PartialEq, Display, EnumString)]
#[derive(Debug, PartialEq, Display, EnumString, Serialize, Deserialize)]
pub enum AssetClass {
Crypto = 1,
}
Expand All @@ -64,7 +66,7 @@ impl TryFrom<u8> for AssetClass {
}
}

#[derive(Debug, PartialEq, Display, EnumString)]
#[derive(Debug, PartialEq, Display, EnumString, Serialize, Deserialize)]
pub enum FeedType {
#[strum(serialize = "Spot Median")]
SpotMedian = 21325,
Expand Down Expand Up @@ -94,8 +96,8 @@ impl FromStr for Feed {
type Err = anyhow::Error;

fn from_str(feed_id: &str) -> anyhow::Result<Self> {
let feed_id = feed_id.strip_prefix("0x").unwrap_or(feed_id);
let mut bytes = hex::decode(feed_id)?;
let stripped_id = feed_id.strip_prefix("0x").unwrap_or(feed_id);
let mut bytes = hex::decode(stripped_id)?;

if bytes.len() < 3 {
bail!("Feed ID is too short");
Expand All @@ -120,7 +122,7 @@ impl FromStr for Feed {
bail!("Empty pair ID");
}

Ok(Feed { asset_class, feed_type, pair_id })
Ok(Feed { feed_id: feed_id.to_owned(), asset_class, feed_type, pair_id })
}
}

Expand Down
52 changes: 31 additions & 21 deletions rust/theoros/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
"version": "0.1.0"
},
"paths": {
"/v1/calldata": {
"/v1/calldata/{feed_id}": {
"get": {
"tags": [
"crate::handlers::get_data_feeds"
"crate::handlers::get_calldata"
],
"operationId": "get_data_feeds",
"operationId": "get_calldata",
"parameters": [],
"responses": {
"200": {
"description": "Get all the available data feeds",
"description": "Constructs the calldata used to update the feed id specified",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GetDataFeedsResponse"
"$ref": "#/components/schemas/GetCalldataResponse"
}
}
}
Expand All @@ -33,22 +33,21 @@
}
}
},
"/v1/calldata/{data_feed_id}": {
"/v1/data_feeds": {
"get": {
"tags": [
"crate::handlers::get_calldata"
"crate::handlers::get_data_feeds"
],
"operationId": "get_calldata",
"parameters": [],
"operationId": "get_data_feeds",
"responses": {
"200": {
"description": "Constructs the calldata used to update the data feed id specified",
"description": "Get all the available feed ids",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GetCalldataResponse"
"$ref": "#/components/schemas/GetDataFeedsResponse"
}
}
}
Expand Down Expand Up @@ -82,19 +81,30 @@
}
},
"GetDataFeedsError": {
"type": "string",
"enum": [
"InternalServerError",
"DatabaseConnection"
"oneOf": [
{
"type": "object",
"required": [
"ParsingFeedId"
],
"properties": {
"ParsingFeedId": {
"type": "string"
}
}
},
{
"type": "string",
"enum": [
"InternalServerError"
]
}
]
},
"GetDataFeedsQuery": {
"type": "object"
},
"GetDataFeedsResponse": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/components/schemas/Feed"
}
}
},
Expand Down Expand Up @@ -124,7 +134,7 @@
"schema": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/components/schemas/Feed"
}
}
}
Expand All @@ -135,7 +145,7 @@
"tags": [
{
"name": "theoros",
"description": "Theoros - the Pragma Consultant"
"description": "Theoros - The Pragma Consultant"
}
]
}
8 changes: 3 additions & 5 deletions rust/theoros/src/errors/data_feeds_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ use utoipa::ToSchema;
#[derive(Debug, thiserror::Error, ToSchema)]
#[allow(unused)]
pub enum GetDataFeedsError {
#[error("could not parse feed id: {0}")]
ParsingFeedId(String),
#[error("internal server error")]
InternalServerError,
#[error("could not establish a connection with the database")]
DatabaseConnection,
}

impl IntoResponse for GetDataFeedsError {
fn into_response(self) -> axum::response::Response {
let (status, err_msg) = match self {
Self::DatabaseConnection => {
(StatusCode::SERVICE_UNAVAILABLE, "Could not establish a connection with the Database".to_string())
}
Self::ParsingFeedId(feed_id) => (StatusCode::PROCESSING, format!("Could not parse feed: {feed_id}")),
_ => (StatusCode::INTERNAL_SERVER_ERROR, String::from("Internal server error")),
};
(status, Json(json!({"resource":"Calldata", "message": err_msg, "happened_at" : chrono::Utc::now() })))
Expand Down
8 changes: 4 additions & 4 deletions rust/theoros/src/handlers/get_calldata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ pub struct GetCalldataResponse {

#[utoipa::path(
get,
path = "/v1/calldata/{data_feed_id}",
path = "/v1/calldata/{feed_id}",
responses(
(
status = 200,
description = "Constructs the calldata used to update the data feed id specified",
description = "Constructs the calldata used to update the feed id specified",
body = [GetCalldataResponse]
)
),
Expand All @@ -31,9 +31,9 @@ pub struct GetCalldataResponse {
)]
pub async fn get_calldata(
State(_state): State<AppState>,
PathExtractor(data_feed_id): PathExtractor<String>,
PathExtractor(feed_id): PathExtractor<String>,
Query(_params): Query<GetCalldataQuery>,
) -> Result<Json<GetCalldataResponse>, GetCalldataError> {
tracing::info!("Received get calldata request for feed: {data_feed_id}");
tracing::info!("Received get calldata request for feed: {feed_id}");
Ok(Json(GetCalldataResponse::default()))
}
24 changes: 12 additions & 12 deletions rust/theoros/src/handlers/get_data_feeds.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
use axum::extract::State;
use axum::Json;
use pragma_utils::feeds::Feed;
use serde::{Deserialize, Serialize};
use utoipa::{ToResponse, ToSchema};

use crate::errors::GetDataFeedsError;
use crate::AppState;

#[derive(Debug, Default, Serialize, Deserialize, ToResponse, ToSchema)]
pub struct FeedId {
r#id: String,
name: String,
}

#[derive(Debug, Default, Serialize, Deserialize, ToResponse, ToSchema)]
pub struct GetDataFeedsResponse(pub Vec<FeedId>);
pub struct GetDataFeedsResponse(pub Vec<Feed>);

#[utoipa::path(
get,
path = "/v1/data_feeds",
responses(
(status = 200, description = "Get all the available data feeds", body = [GetDataFeedsResponse])
(status = 200, description = "Get all the available feed ids", body = [GetDataFeedsResponse])
),
)]
pub async fn get_data_feeds(State(state): State<AppState>) -> Result<Json<GetDataFeedsResponse>, GetDataFeedsError> {
tracing::info!("Received get calldata request");
tracing::info!("Received get all data feeds request");

let stored_feed_ids = state.storage.data_feeds();

let _available_data_feeds = state.storage.data_feeds();
let mut feeds = Vec::with_capacity(stored_feed_ids.len());
for feed_id in stored_feed_ids {
let feed = feed_id.parse().map_err(|_| GetDataFeedsError::ParsingFeedId(feed_id.clone()))?;
feeds.push(feed);
}

// TODO: feeds
let response = GetDataFeedsResponse(vec![]);
let response = GetDataFeedsResponse(feeds);
Ok(Json(response))
}
10 changes: 6 additions & 4 deletions rust/theoros/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const APIBARA_DNA_URL: &str = "https://sepolia.starknet.a5a.ch"; // TODO: Should
const SERVER_HOST: &str = "0.0.0.0";
const SERVER_PORT: u16 = 3000;

const PRAGMA_WRAPPER_CONTRACT_ADDRESS: Felt = Felt::ZERO;
const _PRAGMA_WRAPPER_CONTRACT_ADDRESS: Felt = Felt::ZERO;
const HYPERLANE_CORE_CONTRACT_ADDRESS: Felt = Felt::ZERO;

#[derive(Clone)]
Expand All @@ -55,9 +55,11 @@ async fn main() -> Result<()> {
let rpc_client = StarknetRpc::new(rpc_url);

// New storage + initialization
let theoros_storage =
TheorosStorage::from_rpc_state(&rpc_client, &PRAGMA_WRAPPER_CONTRACT_ADDRESS, &HYPERLANE_CORE_CONTRACT_ADDRESS)
.await?;
// let theoros_storage =
// TheorosStorage::from_rpc_state(&rpc_client, &PRAGMA_WRAPPER_CONTRACT_ADDRESS, &HYPERLANE_CORE_CONTRACT_ADDRESS)
// .await?;
// TODO: remove & uncomment line above when we can fetch from pragma wrapper + hyperlane
let theoros_storage = TheorosStorage::testing_state();

// Theoros metrics
let metrics_service = MetricsService::new(false, METRICS_PORT)?;
Expand Down
2 changes: 1 addition & 1 deletion rust/theoros/src/services/api/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde_json::to_string_pretty;
use utoipa::OpenApi;
use utoipauto::utoipauto;

#[utoipauto(paths = "./theoros/src")]
#[utoipauto(paths = "./theoros/src, ./pragma-utils/src")]
#[derive(OpenApi)]
#[openapi(
tags(
Expand Down
2 changes: 1 addition & 1 deletion rust/theoros/src/services/api/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async fn handler_404() -> impl IntoResponse {
}

fn calldata_routes(state: AppState) -> Router<AppState> {
Router::new().route("/calldata", get(get_calldata)).with_state(state)
Router::new().route("/calldata/:feed_id", get(get_calldata)).with_state(state)
}

fn data_feeds_routes(state: AppState) -> Router<AppState> {
Expand Down
10 changes: 10 additions & 0 deletions rust/theoros/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ pub struct TheorosStorage {
}

impl TheorosStorage {
// TODO: remove this later, only used for now for tests
pub fn testing_state() -> Self {
let constants_data_feeds: HashSet<String> = HashSet::from([
"0x01534d4254432f555344".into(), // BTC/USD
"0x01534d4554482f555344".into(), // ETH/USD
"0x01534d454b55424f2f555344".into(), // EKUBO/USD
]);
Self { data_feeds: constants_data_feeds, ..Default::default() }
}

pub async fn from_rpc_state(
rpc_client: &StarknetRpc,
pragma_wrapper_address: &Felt,
Expand Down

0 comments on commit 5437380

Please sign in to comment.