diff --git a/Cargo.lock b/Cargo.lock index f6fa7b3..05d22c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -153,7 +153,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -384,7 +384,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -395,7 +395,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -482,7 +482,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -502,7 +502,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -578,7 +578,7 @@ dependencies = [ "serde_json", "sha2", "sha3", - "thiserror", + "thiserror 1.0.50", "uuid 0.8.2", ] @@ -741,7 +741,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -1351,7 +1351,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -1472,7 +1472,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -1501,7 +1501,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -1600,6 +1600,7 @@ dependencies = [ "serde_json", "starknet", "strum", + "thiserror 2.0.3", "tokio", "tracing", "tracing-subscriber", @@ -1655,9 +1656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1674,7 +1675,7 @@ dependencies = [ "memchr", "parking_lot", "protobuf", - "thiserror", + "thiserror 1.0.50", ] [[package]] @@ -1880,7 +1881,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.66", + "syn 2.0.89", "unicode-ident", ] @@ -2063,7 +2064,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2145,7 +2146,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2261,7 +2262,7 @@ dependencies = [ "starknet-crypto", "starknet-providers", "starknet-signers", - "thiserror", + "thiserror 1.0.50", ] [[package]] @@ -2276,7 +2277,7 @@ dependencies = [ "starknet-accounts", "starknet-core", "starknet-providers", - "thiserror", + "thiserror 1.0.50", ] [[package]] @@ -2326,7 +2327,7 @@ checksum = "2e179dedc3fa6da064e56811d3e05d446aa2f7459e4eb0e3e49378a337235437" dependencies = [ "starknet-curve", "starknet-types-core", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2345,7 +2346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fe4f8d615329410578cbedcdbaa4a36c7f28f68c3f3ac56006cfbdaeaa2b41" dependencies = [ "starknet-core", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2365,7 +2366,7 @@ dependencies = [ "serde_json", "serde_with", "starknet-core", - "thiserror", + "thiserror 1.0.50", "url", ] @@ -2383,7 +2384,7 @@ dependencies = [ "rand", "starknet-core", "starknet-crypto", - "thiserror", + "thiserror 1.0.50", ] [[package]] @@ -2441,7 +2442,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2463,9 +2464,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2533,7 +2534,16 @@ version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.50", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -2544,7 +2554,18 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] @@ -2637,7 +2658,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2793,7 +2814,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", ] [[package]] @@ -2968,7 +2989,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -3002,7 +3023,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index f700186..2f9c9f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ serde = { version = "1.0.130", features = ["derive"] } serde_json = { version = "1.0.130" } starknet = "0.11.0" strum = { version = "0.25.0", features = ["derive"] } +thiserror = "2.0" tokio = { version = "1", features = ["full"] } tracing = "0.1" tracing-subscriber = "0.3" diff --git a/src/error.rs b/src/error.rs index 59756b4..aafb3f7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,39 +1,31 @@ -use std::{error::Error as StdError, fmt}; - +use diesel::result::Error as DieselError; +use diesel_async::pooled_connection::deadpool::PoolError; use starknet::providers::ProviderError; +use thiserror::Error; -#[derive(Debug)] +#[derive(Error, Debug)] pub enum MonitoringError { + #[error("Price error: {0}")] Price(String), - Database(diesel::result::Error), - Connection(diesel_async::pooled_connection::deadpool::PoolError), + + #[error("Database error: {0}")] + Database(#[from] DieselError), + + #[error("Connection error: {0}")] + Connection(#[from] PoolError), + + #[error("API error: {0}")] Api(String), + + #[error("Conversion error: {0}")] Conversion(String), + + #[error("OnChain error: {0}")] OnChain(String), - Provider(ProviderError), - InvalidTimestamp(u64), -} -impl StdError for MonitoringError {} - -impl fmt::Display for MonitoringError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - MonitoringError::Price(e) => write!(f, "Price Error: {}", e), - MonitoringError::Database(e) => write!(f, "Database Error: {}", e), - MonitoringError::Connection(e) => write!(f, "Connection Error: {}", e), - MonitoringError::Api(e) => write!(f, "API Error: {}", e), - MonitoringError::Conversion(e) => write!(f, "Conversion Error: {}", e), - MonitoringError::OnChain(e) => write!(f, "OnChain Error: {}", e), - MonitoringError::Provider(e) => write!(f, "Provider Error: {}", e), - MonitoringError::InvalidTimestamp(e) => write!(f, "Invalid Timestamp: {}", e), - } - } -} + #[error("Provider error: {0}")] + Provider(#[from] ProviderError), -// Convert diesel error to our custom error -impl From for MonitoringError { - fn from(err: diesel::result::Error) -> MonitoringError { - MonitoringError::Database(err) - } + #[error("Invalid timestamp: {0}")] + InvalidTimestamp(u64), } diff --git a/src/main.rs b/src/main.rs index 0ab36bc..4655400 100644 --- a/src/main.rs +++ b/src/main.rs @@ -292,4 +292,4 @@ pub(crate) async fn vrf_monitor(pool: Pool = futures::future::join_all(tasks).await; log_tasks_results("VRF", results); } -} \ No newline at end of file +} diff --git a/src/monitoring/on_off_deviation.rs b/src/monitoring/on_off_deviation.rs index 45d1a5d..ac86020 100644 --- a/src/monitoring/on_off_deviation.rs +++ b/src/monitoring/on_off_deviation.rs @@ -8,7 +8,7 @@ use starknet::{ providers::Provider, }; -use crate::monitoring::price_deviation::CoinPricesDTO; +use crate::processing::common::query_defillama_api; use crate::{ config::{get_config, DataType}, constants::COINGECKO_IDS, @@ -79,39 +79,7 @@ pub async fn on_off_price_deviation( DataType::Spot => { let coingecko_id = *ids.get(&pair_id).expect("Failed to get coingecko id"); - let api_key = std::env::var("DEFILLAMA_API_KEY"); - - let request_url = if let Ok(api_key) = api_key { - format!( - "https://pro-api.llama.fi/{apikey}/coins/prices/historical/{timestamp}/coingecko:{id}", - timestamp = timestamp, - id = coingecko_id, - apikey = api_key - ) - } else { - format!( - "https://coins.llama.fi/prices/historical/{timestamp}/coingecko:{id}", - timestamp = timestamp, - id = coingecko_id, - ) - }; - - let response = reqwest::get(&request_url) - .await - .map_err(|e| MonitoringError::Api(e.to_string()))?; - - let response_text = response - .text() - .await - .map_err(|e| MonitoringError::Api(format!("Failed to get response text: {}", e)))?; - - let coins_prices: CoinPricesDTO = - serde_json::from_str(&response_text).map_err(|e| { - MonitoringError::Api(format!( - "Failed to parse JSON: {}. Response: {}", - e, response_text - )) - })?; + let coins_prices = query_defillama_api(timestamp, coingecko_id).await?; let api_id = format!("coingecko:{}", coingecko_id); diff --git a/src/monitoring/price_deviation.rs b/src/monitoring/price_deviation.rs index bfb88fe..34ca235 100644 --- a/src/monitoring/price_deviation.rs +++ b/src/monitoring/price_deviation.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; -use crate::{constants::COINGECKO_IDS, error::MonitoringError, types::Entry}; +use crate::{ + constants::COINGECKO_IDS, error::MonitoringError, processing::common::query_defillama_api, + types::Entry, +}; /// Data Transfer Object for Defillama API /// e.g @@ -49,33 +52,11 @@ pub async fn price_deviation( let pair_id = query.pair_id().to_string(); let coingecko_id = *ids.get(&pair_id).expect("Failed to get coingecko id"); - let api_key = std::env::var("DEFILLAMA_API_KEY"); - - let request_url = if let Ok(api_key) = api_key { - format!( - "https://pro-api.llama.fi/{apikey}/coins//prices/historical/{timestamp}/coingecko:{id}?apikey={apikey}", - timestamp = query.timestamp().timestamp(), - id = coingecko_id, - apikey = api_key - ) - } else { - format!( - "https://coins.llama.fi/prices/historical/{timestamp}/coingecko:{id}", - timestamp = query.timestamp().timestamp(), - id = coingecko_id, - ) - }; - - let response = reqwest::get(&request_url) - .await - .map_err(|e| MonitoringError::Api(e.to_string()))?; - - let coins_prices: CoinPricesDTO = response.json().await.map_err(|e| { - MonitoringError::Api(format!( - "Failed to convert to DTO object, got error {:?}", - e.to_string() - )) - })?; + let coins_prices = query_defillama_api( + query.timestamp().timestamp().try_into().unwrap(), + coingecko_id, + ) + .await?; let api_id = format!("coingecko:{}", coingecko_id); @@ -97,33 +78,11 @@ pub async fn raw_price_deviation(pair_id: &String, price: f64) -> Result Result { + let api_key = std::env::var("DEFILLAMA_API_KEY"); + + let request_url = if let Ok(api_key) = api_key { + format!( + "https://pro-api.llama.fi/{apikey}/coins/prices/historical/{timestamp}/coingecko:{id}", + timestamp = timestamp, + id = coingecko_id, + apikey = api_key + ) + } else { + format!( + "https://coins.llama.fi/prices/historical/{timestamp}/coingecko:{id}", + timestamp = timestamp, + id = coingecko_id, + ) + }; + + let response = reqwest::get(&request_url) + .await + .map_err(|e| MonitoringError::Api(e.to_string()))?; + + let response_text = response + .text() + .await + .map_err(|e| MonitoringError::Api(format!("Failed to get response text: {}", e)))?; + + Ok(serde_json::from_str(&response_text).map_err(|e| { + MonitoringError::Api(format!( + "Failed to parse JSON: {}. Response: {}", + e, response_text + )) + })?) +} + pub async fn check_publisher_balance( publisher: String, publisher_address: Felt,