diff --git a/Cargo.lock b/Cargo.lock index 4f8d1fcc3f..883c4aa0f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6935,7 +6935,7 @@ dependencies = [ [[package]] name = "nyx-chain-watcher" -version = "0.1.4" +version = "0.1.5" dependencies = [ "anyhow", "axum 0.7.7", diff --git a/nyx-chain-watcher/Cargo.toml b/nyx-chain-watcher/Cargo.toml index 05c43ae147..3b671ad14e 100644 --- a/nyx-chain-watcher/Cargo.toml +++ b/nyx-chain-watcher/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nyx-chain-watcher" -version = "0.1.4" +version = "0.1.5" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/nyx-chain-watcher/src/db/models.rs b/nyx-chain-watcher/src/db/models.rs index 8ad20e97c0..9a433ee8ec 100644 --- a/nyx-chain-watcher/src/db/models.rs +++ b/nyx-chain-watcher/src/db/models.rs @@ -24,10 +24,10 @@ pub(crate) struct PriceRecord { #[derive(Serialize, Deserialize, Debug, ToSchema)] pub(crate) struct PriceHistory { pub(crate) timestamp: i64, - pub(crate) chf: f32, - pub(crate) usd: f32, - pub(crate) eur: f32, - pub(crate) btc: f32, + pub(crate) chf: f64, + pub(crate) usd: f64, + pub(crate) eur: f64, + pub(crate) btc: f64, } #[derive(Serialize, Deserialize, Debug, ToSchema)] diff --git a/nyx-chain-watcher/src/db/queries/price.rs b/nyx-chain-watcher/src/db/queries/price.rs index 7c69863744..f61ee09750 100644 --- a/nyx-chain-watcher/src/db/queries/price.rs +++ b/nyx-chain-watcher/src/db/queries/price.rs @@ -1,5 +1,7 @@ use crate::db::models::{PriceHistory, PriceRecord}; use crate::db::DbPool; +use chrono::Local; +use std::ops::Sub; pub(crate) async fn insert_nym_prices( pool: &DbPool, @@ -38,9 +40,47 @@ pub(crate) async fn get_latest_price(pool: &DbPool) -> anyhow::Result anyhow::Result { + // now less 1 day + let earliest_timestamp = Local::now().sub(chrono::Duration::days(1)).timestamp(); + + let result = sqlx::query!( + "SELECT timestamp, chf, usd, eur, btc FROM price_history WHERE timestamp >= $1;", + earliest_timestamp + ) + .fetch_all(pool) + .await?; + + let count = result.len() as f64; + + let mut price = PriceHistory { + timestamp: Local::now().timestamp(), + chf: 0f64, + usd: 0f64, + eur: 0f64, + btc: 0f64, + }; + + for p in &result { + price.chf += p.chf; + price.usd += p.usd; + price.eur += p.eur; + price.btc += p.btc; + } + + if count > 0f64 { + price.chf /= count; + price.usd /= count; + price.eur /= count; + price.btc /= count; + } + + Ok(price) +} diff --git a/nyx-chain-watcher/src/http/api/mixnodes.rs b/nyx-chain-watcher/src/http/api/mixnodes.rs deleted file mode 100644 index 0d8ffe881a..0000000000 --- a/nyx-chain-watcher/src/http/api/mixnodes.rs +++ /dev/null @@ -1,21 +0,0 @@ -use axum::{extract::State, Json, Router}; - -use crate::http::{error::HttpResult, state::AppState}; - -pub(crate) fn routes() -> Router { - Router::new().route("/", axum::routing::get(mixnodes)) -} - -#[utoipa::path( - tag = "Mixnodes", - get, - path = "/v1/mixnodes", - responses( - (status = 200, body = String) - ) -)] -async fn mixnodes(State(_state): State) -> HttpResult> { - Ok(Json( - serde_json::json!({"message": "😎 Nothing to see here, move along 😎"}), - )) -} diff --git a/nyx-chain-watcher/src/http/api/mod.rs b/nyx-chain-watcher/src/http/api/mod.rs index 4ca198a729..145f07c9ee 100644 --- a/nyx-chain-watcher/src/http/api/mod.rs +++ b/nyx-chain-watcher/src/http/api/mod.rs @@ -7,7 +7,6 @@ use utoipa_swagger_ui::SwaggerUi; use crate::http::{api_docs, server::HttpServer, state::AppState}; -pub(crate) mod mixnodes; pub(crate) mod price; pub(crate) struct RouterBuilder { @@ -25,13 +24,7 @@ impl RouterBuilder { "/", axum::routing::get(|| async { Redirect::permanent("/swagger") }), ) - .nest( - "/v1", - Router::new() - //.nest("/jokes", jokes::routes()) - .nest("/mixnodes", mixnodes::routes()) - .nest("/price", price::routes()), - ); + .nest("/v1", Router::new().nest("/price", price::routes())); Self { unfinished_router: router, diff --git a/nyx-chain-watcher/src/http/api/price.rs b/nyx-chain-watcher/src/http/api/price.rs index 354d3cbfa7..1971f35f7d 100644 --- a/nyx-chain-watcher/src/http/api/price.rs +++ b/nyx-chain-watcher/src/http/api/price.rs @@ -1,23 +1,24 @@ use crate::db::models::PriceHistory; -use crate::db::queries::price::get_latest_price; +use crate::db::queries::price::{get_average_price, get_latest_price}; use crate::http::error::Error; use crate::http::error::HttpResult; use crate::http::state::AppState; use axum::{extract::State, Json, Router}; pub(crate) fn routes() -> Router { - Router::new().route("/", axum::routing::get(price)) + Router::new() + .route("/", axum::routing::get(price)) + .route("/average", axum::routing::get(average_price)) } #[utoipa::path( - tag = "Nym Price", + tag = "NYM Price", get, path = "/v1/price", responses( (status = 200, body = String) ) )] - /// Fetch the latest price cached by this API async fn price(State(state): State) -> HttpResult> { get_latest_price(state.db_pool()) @@ -25,3 +26,19 @@ async fn price(State(state): State) -> HttpResult> .map(Json::from) .map_err(|_| Error::internal()) } + +#[utoipa::path( + tag = "NYM Price", + get, + path = "/v1/price/average", + responses( + (status = 200, body = String) + ) +)] +/// Fetch the average price cached by this API +async fn average_price(State(state): State) -> HttpResult> { + get_average_price(state.db_pool()) + .await + .map(Json::from) + .map_err(|_| Error::internal()) +}