nyx-chain-watcher: return average price over 24 hours

This commit is contained in:
Mark Sinclair
2024-12-11 15:33:18 +00:00
parent d731384bca
commit 135a9369eb
7 changed files with 72 additions and 43 deletions
Generated
+1 -1
View File
@@ -6935,7 +6935,7 @@ dependencies = [
[[package]]
name = "nyx-chain-watcher"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"axum 0.7.7",
+1 -1
View File
@@ -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
+4 -4
View File
@@ -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)]
+44 -4
View File
@@ -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<PriceHisto
Ok(PriceHistory {
timestamp: result.timestamp,
chf: result.chf as f32,
usd: result.usd as f32,
eur: result.eur as f32,
btc: result.btc as f32,
chf: result.chf,
usd: result.usd,
eur: result.eur,
btc: result.btc,
})
}
pub(crate) async fn get_average_price(pool: &DbPool) -> anyhow::Result<PriceHistory> {
// 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)
}
@@ -1,21 +0,0 @@
use axum::{extract::State, Json, Router};
use crate::http::{error::HttpResult, state::AppState};
pub(crate) fn routes() -> Router<AppState> {
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<AppState>) -> HttpResult<Json<serde_json::Value>> {
Ok(Json(
serde_json::json!({"message": "😎 Nothing to see here, move along 😎"}),
))
}
+1 -8
View File
@@ -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,
+21 -4
View File
@@ -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<AppState> {
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<AppState>) -> HttpResult<Json<PriceHistory>> {
get_latest_price(state.db_pool())
@@ -25,3 +26,19 @@ async fn price(State(state): State<AppState>) -> HttpResult<Json<PriceHistory>>
.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<AppState>) -> HttpResult<Json<PriceHistory>> {
get_average_price(state.db_pool())
.await
.map(Json::from)
.map_err(|_| Error::internal())
}