From 6f44c5c82ead90f58f18e313d9051a1753cf06ed Mon Sep 17 00:00:00 2001 From: Iris Date: Mon, 11 Mar 2024 10:27:13 +0100 Subject: [PATCH] fix: update altcoins config data --- config.template.toml | 41 +++++++++--- src/config.rs | 66 ++++++++++++++++--- src/endpoints/avnu/mod.rs | 1 - src/endpoints/{avnu => }/get_altcoin_quote.rs | 57 ++++++++++------ src/endpoints/mod.rs | 2 +- 5 files changed, 128 insertions(+), 39 deletions(-) delete mode 100644 src/endpoints/avnu/mod.rs rename src/endpoints/{avnu => }/get_altcoin_quote.rs (63%) diff --git a/config.template.toml b/config.template.toml index 4c37d2d..6bd712e 100644 --- a/config.template.toml +++ b/config.template.toml @@ -28,12 +28,35 @@ api_key = "xxxxxx" rpc_url = "https://xxxxxxx.solana-mainnet.quiknode.pro/xxxxxxx" private_key = "xxxxxxx" -[token_support] -whitelisted_tokens = [ - "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", - "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", - "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", -] -max_validity = 1000 # in seconds -private_key="123" \ No newline at end of file +[altcoins] +avnu_api = "https://starknet.impulse.avnu.fi/v1" +private_key = "123" + +# Ethereum (ETH) is not enabled for the moment as it is already supported by default buy. +# [altcoins.ETH] +# address = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" +# min_price = 1 +# max_price = 1 +# decimals = 18 +# max_quote_validity = 3600 # in seconds for ETH + +[altcoins.STRK] +address = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" +min_price = 500 +max_price = 5000 +decimals = 18 +max_quote_validity = 300 # it moves faster so we reduce the quote validity + +[altcoins.USDC] +address = "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8" +min_price = 2000 +max_price = 10000 +decimals = 6 # not sure really +max_quote_validity = 600 + +[altcoins.USDT] +address = "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8" +min_price = 2000 +max_price = 10000 +decimals = 18 +max_quote_validity = 600 \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 3b4757e..ad6f38c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use serde::Deserialize; +use serde::{Deserialize, Deserializer}; use starknet::core::types::FieldElement; use std::collections::HashMap; use std::env; @@ -44,11 +44,26 @@ pub_struct!(Clone, Deserialize; Solana { private_key: FieldElement, }); -pub_struct!(Clone, Deserialize; TokenSupport { +pub_struct!(Clone, Debug, Deserialize; AltcoinData { + address: FieldElement, + min_price: u64, + max_price: u64, + decimals: u32, + max_quote_validity: i64 +}); + +#[derive(Debug, Deserialize)] +struct TempAltcoins { + avnu_api: String, + private_key: FieldElement, + #[serde(flatten)] + data: HashMap, +} + +pub_struct!(Clone, Debug; Altcoins { avnu_api: String, - whitelisted_tokens: Vec, - max_validity: i64, - private_key: FieldElement + private_key: FieldElement, + data: HashMap, }); #[derive(Deserialize)] @@ -59,7 +74,7 @@ struct RawConfig { starkscan: Starkscan, custom_resolvers: HashMap>, solana: Solana, - token_support: TokenSupport, + altcoins: Altcoins, } pub_struct!(Clone, Deserialize; Config { @@ -70,9 +85,44 @@ pub_struct!(Clone, Deserialize; Config { custom_resolvers: HashMap>, reversed_resolvers: HashMap, solana: Solana, - token_support: TokenSupport, + altcoins: Altcoins, }); +impl Altcoins { + fn new(temp: TempAltcoins) -> Self { + let data: HashMap = temp + .data + .into_values() + .map(|val| { + let altcoin_data = AltcoinData { + address: val.address, + min_price: val.min_price, + max_price: val.max_price, + decimals: val.decimals, + max_quote_validity: val.max_quote_validity, + }; + (val.address, altcoin_data) + }) + .collect(); + + Altcoins { + avnu_api: temp.avnu_api, + private_key: temp.private_key, + data, + } + } +} + +impl<'de> Deserialize<'de> for Altcoins { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let temp = TempAltcoins::deserialize(deserializer)?; + Ok(Altcoins::new(temp)) + } +} + impl From for Config { fn from(raw: RawConfig) -> Self { let mut reversed_resolvers = HashMap::new(); @@ -89,7 +139,7 @@ impl From for Config { custom_resolvers: raw.custom_resolvers, reversed_resolvers, solana: raw.solana, - token_support: raw.token_support, + altcoins: raw.altcoins, } } } diff --git a/src/endpoints/avnu/mod.rs b/src/endpoints/avnu/mod.rs deleted file mode 100644 index e6007e2..0000000 --- a/src/endpoints/avnu/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod get_altcoin_quote; diff --git a/src/endpoints/avnu/get_altcoin_quote.rs b/src/endpoints/get_altcoin_quote.rs similarity index 63% rename from src/endpoints/avnu/get_altcoin_quote.rs rename to src/endpoints/get_altcoin_quote.rs index 2cac922..d13b59e 100644 --- a/src/endpoints/avnu/get_altcoin_quote.rs +++ b/src/endpoints/get_altcoin_quote.rs @@ -10,7 +10,10 @@ use axum_auto_routes::route; use chrono::Duration; use serde::Deserialize; use serde_json::json; -use starknet::core::{crypto::{ecdsa_sign, pedersen_hash}, types::FieldElement}; +use starknet::core::{ + crypto::{ecdsa_sign, pedersen_hash}, + types::FieldElement, +}; use crate::{models::AppState, utils::get_error}; @@ -29,25 +32,21 @@ lazy_static::lazy_static! { static ref QUOTE_STR: FieldElement = FieldElement::from_dec_str("724720344857006587549020016926517802128122613457935427138661").unwrap(); } -#[route(get, "/get_altcoin_quote", crate::endpoints::avnu::get_altcoin_quote)] +#[route(get, "/get_altcoin_quote", crate::endpoints::get_altcoin_quote)] pub async fn handler( State(state): State>, Query(query): Query, ) -> impl IntoResponse { // check if erc20_addr is whitelisted - if !state - .conf - .token_support - .whitelisted_tokens - .contains(&query.erc20_addr) - { + if !state.conf.altcoins.data.contains_key(&query.erc20_addr) { return get_error("Token not supported".to_string()); } + let altcoin_data = state.conf.altcoins.data.get(&query.erc20_addr).unwrap(); // fetch quote from avnu api let url = format!( "{}/tokens/short?in=0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - state.conf.token_support.avnu_api + state.conf.altcoins.avnu_api ); let client = reqwest::Client::new(); match client.get(&url).send().await { @@ -62,11 +61,19 @@ pub async fn handler( // compute message hash let now = chrono::Utc::now(); let max_validity_timestamp = (now - + Duration::seconds(state.conf.token_support.max_validity)) + + Duration::seconds(altcoin_data.max_quote_validity)) .timestamp(); let quote = 1.0 / data.currentPrice; + // check if quote is within the valid range + if quote < altcoin_data.min_price as f64 + || quote > altcoin_data.max_price as f64 + { + return get_error("Quote out of range".to_string()); + } // convert current price to wei and return an integer as AVNU api can use more than 18 decimals - let current_price_wei = (quote * (10u128.pow(18) as f64)).to_string(); + let current_price_wei = + ((quote * (10u128.pow(altcoin_data.decimals) as f64)) as u128) + .to_string(); let message_hash = pedersen_hash( &pedersen_hash( &pedersen_hash( @@ -76,23 +83,33 @@ pub async fn handler( ) .unwrap(), ), - &FieldElement::from_dec_str(max_validity_timestamp.to_string().as_str()).unwrap(), + &FieldElement::from_dec_str( + max_validity_timestamp.to_string().as_str(), + ) + .unwrap(), ), "E_STR, ); - match ecdsa_sign(&state.conf.token_support.private_key.clone(), &message_hash) { - Ok(signature) => (StatusCode::OK, Json(json!({ - "quote": current_price_wei, - "r": signature.r, - "s": signature.s, - "max_validity": max_validity_timestamp - }))).into_response(), + match ecdsa_sign( + &state.conf.altcoins.private_key.clone(), + &message_hash, + ) { + Ok(signature) => ( + StatusCode::OK, + Json(json!({ + "quote": current_price_wei, + "r": signature.r, + "s": signature.s, + "max_validity": max_validity_timestamp + })), + ) + .into_response(), Err(e) => get_error(format!( "Error while generating Starknet signature: {}", e )), } - }, + } None => get_error("Token address not found".to_string()), } } diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index c025ee6..42d14df 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -5,7 +5,7 @@ pub mod addr_to_external_domains; pub mod addr_to_full_ids; pub mod addr_to_token_id; pub mod addrs_to_domains; -pub mod avnu; +pub mod get_altcoin_quote; pub mod crosschain; pub mod data_to_ids; pub mod domain_to_addr;