forked from matter-labs/zksync
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ticker): modifies dev ticker to proxy to coingecko
feat(ticker): separates dev and proxy tickers feat(ticker): adds proxy liquidity refactor(ticker): url and path to constants fix(ticker): trimms testnet prefix in loaded token symbol
- Loading branch information
Showing
16 changed files
with
391 additions
and
100 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
pub mod dev_liquidity_provider; | ||
pub mod dev_price_provider; | ||
pub mod proxy_liquidity_provider; | ||
pub mod proxy_price_provider; | ||
mod proxy_utils; |
91 changes: 91 additions & 0 deletions
91
core/bin/zksync_api/src/bin/providers/proxy_liquidity_provider.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use std::{collections::HashMap, fs::read_to_string, path::Path, str::FromStr}; | ||
|
||
use actix_web::{web, HttpResponse, Result}; | ||
use tokio::sync::Mutex; | ||
use zksync_api::fee_ticker::CoinGeckoTypes::AssetPlatform; | ||
use zksync_config::ETHClientConfig; | ||
use zksync_types::{Address, TokenInfo}; | ||
use zksync_utils::remove_prefix; | ||
|
||
use super::proxy_utils::{proxy_request, ProxyState, API_PATH, API_URL}; | ||
|
||
const TESTNET_PLATFORM_ID: &str = "testnet"; | ||
const TESTNET_PLATFORM_NAME: &str = "Rootstock Testnet"; | ||
const TESTNET_PLATFORM_SHORTNAME: &str = "testnet"; | ||
const ROOTSTOCK_PLATFORM_ID: &str = "rootstock"; | ||
|
||
async fn handle_get_asset_platforms() -> Result<HttpResponse> { | ||
Ok(HttpResponse::Ok().json(vec![AssetPlatform { | ||
id: String::from(TESTNET_PLATFORM_ID), | ||
chain_identifier: Some(ETHClientConfig::from_env().chain_id as i64), | ||
name: String::from(TESTNET_PLATFORM_NAME), | ||
shortname: String::from(TESTNET_PLATFORM_SHORTNAME), | ||
}])) | ||
} | ||
|
||
fn load_tokens(path: impl AsRef<Path>) -> Result<Vec<TokenInfo>, serde_json::Error> { | ||
serde_json::from_str(&read_to_string(path).unwrap()) | ||
} | ||
|
||
async fn handle_get_coin_contract( | ||
path: web::Path<(String, String)>, | ||
data: web::Data<AppState>, | ||
) -> HttpResponse { | ||
let (_, contract_address) = path.into_inner(); | ||
let testnet_token_address = Address::from_str(remove_prefix(&contract_address)).unwrap(); | ||
|
||
let testnet_token = data | ||
.testnet_tokens | ||
.iter() | ||
.find(|token| token.address.eq(&testnet_token_address)); | ||
let mainnet_token = match testnet_token { | ||
Some(testnet_token) => data.mainnet_tokens.iter().find(|token| { | ||
let mainnet_symbol = token.symbol.to_uppercase(); | ||
let testnet_symbol = testnet_token.symbol.to_uppercase(); | ||
|
||
mainnet_symbol.eq(match testnet_symbol.len().gt(&mainnet_symbol.len()) { | ||
true => testnet_symbol.trim_start_matches('T'), | ||
false => &testnet_symbol, | ||
}) | ||
}), | ||
None => None, | ||
}; | ||
|
||
let url = format!( | ||
"{}{}/coins/{}/market_chart/{}", | ||
API_URL, | ||
API_PATH, | ||
ROOTSTOCK_PLATFORM_ID, | ||
match mainnet_token { | ||
Some(token) => token.address, | ||
None => testnet_token_address, | ||
}, | ||
); | ||
|
||
proxy_request(&url, &data.proxy_state.cache).await | ||
} | ||
|
||
struct AppState { | ||
mainnet_tokens: Vec<TokenInfo>, | ||
testnet_tokens: Vec<TokenInfo>, | ||
proxy_state: ProxyState, | ||
} | ||
|
||
pub fn config_liquidity_app(cfg: &mut web::ServiceConfig) { | ||
let shared_data = AppState { | ||
mainnet_tokens: load_tokens("etc/tokens/mainnet.json").unwrap(), | ||
testnet_tokens: load_tokens("etc/tokens/testnet.json").unwrap(), | ||
proxy_state: ProxyState { | ||
cache: std::sync::Arc::new(Mutex::new(HashMap::new())), | ||
}, | ||
}; | ||
cfg.app_data(web::Data::new(shared_data)); | ||
cfg.service(web::resource("/asset_platforms").route(web::get().to(handle_get_asset_platforms))); | ||
cfg.service( | ||
web::scope("/coins").service(web::scope("/{platform_id}").service( | ||
web::scope("/contract").service( | ||
web::resource("/{contract_address}").route(web::get().to(handle_get_coin_contract)), | ||
), | ||
)), | ||
); | ||
} |
57 changes: 57 additions & 0 deletions
57
core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use std::collections::HashMap; | ||
use tokio::sync::Mutex; | ||
|
||
use actix_web::{web, HttpResponse, Scope}; | ||
use zksync_api::fee_ticker::CoinGeckoTypes::CoinsListItem; | ||
|
||
use super::proxy_utils::{proxy_request, ProxyState, API_PATH, API_URL}; | ||
|
||
const RIF_TOKEN_TESTNET_ADDRESS: &str = "0x19f64674D8a5b4e652319F5e239EFd3bc969a1FE"; | ||
|
||
async fn fetch_coins_list(_: web::Data<ProxyState>, _: web::Path<(bool,)>) -> HttpResponse { | ||
let rootstock_platform: HashMap<String, Option<String>> = vec![( | ||
"rootstock".to_string(), | ||
Some(RIF_TOKEN_TESTNET_ADDRESS.to_string()), | ||
)] | ||
.into_iter() | ||
.collect(); | ||
let rif_token = CoinsListItem { | ||
id: "rif-token".to_string(), | ||
platforms: Some(rootstock_platform.clone()), | ||
name: "RIF Token".to_string(), | ||
symbol: "RIF".to_string(), | ||
}; | ||
let rbtc = CoinsListItem { | ||
id: "rootstock".to_string(), | ||
symbol: "rbtc".to_string(), | ||
name: "Rootstock RSK".to_string(), | ||
platforms: Some(rootstock_platform), | ||
}; | ||
let coin_list: &[CoinsListItem] = &[rif_token, rbtc]; | ||
|
||
HttpResponse::Ok().json(coin_list) | ||
} | ||
|
||
async fn fetch_market_chart( | ||
data: web::Data<ProxyState>, | ||
path: web::Path<(String,)>, | ||
) -> HttpResponse { | ||
let (coin_id,) = path.into_inner(); | ||
let url = format!("{}{}/coins/{}/market_chart", API_URL, API_PATH, coin_id); | ||
|
||
proxy_request(&url, &data.cache).await | ||
} | ||
|
||
pub(crate) fn create_price_service() -> Scope { | ||
let shared_data = web::Data::new(ProxyState { | ||
cache: std::sync::Arc::new(Mutex::new(HashMap::new())), | ||
}); | ||
|
||
web::scope(API_PATH) | ||
.app_data(web::Data::new(shared_data)) | ||
.route("/coins/list", web::get().to(fetch_coins_list)) | ||
.route( | ||
"/coins/{coin_id}/market_chart", | ||
web::get().to(fetch_market_chart), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use std::{ | ||
collections::HashMap, | ||
sync::Arc, | ||
time::{Duration, Instant}, | ||
}; | ||
use tokio::sync::Mutex; | ||
|
||
use actix_web::HttpResponse; | ||
use serde_json::Value; | ||
use zksync_config::DevTickerConfig; | ||
|
||
pub(crate) const API_URL: &str = "https://api.coingecko.com"; | ||
pub(crate) const API_PATH: &str = "/api/v3"; | ||
|
||
pub(crate) struct ResponseCache<T> { | ||
data: T, | ||
last_fetched: Instant, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub(crate) struct ProxyState { | ||
pub cache: Arc<Mutex<HashMap<String, ResponseCache<Value>>>>, | ||
} | ||
|
||
pub(crate) async fn proxy_request( | ||
url: &str, | ||
cache: &Mutex<HashMap<String, ResponseCache<Value>>>, | ||
) -> HttpResponse { | ||
let mut lock = cache.lock().await; | ||
|
||
// Check cache first | ||
if let Some(cached) = lock.get(url) { | ||
if cached.last_fetched.elapsed() | ||
< Duration::from_secs(DevTickerConfig::from_env().proxy_cache_timout as u64) | ||
{ | ||
// TODO: configure timeout (or use existing one) | ||
return HttpResponse::Ok().json(&cached.data); | ||
} | ||
} | ||
|
||
// Fetch data if not in cache or stale | ||
|
||
match reqwest::get(url).await { | ||
Ok(response) => match response.json::<Value>().await { | ||
Ok(data) => { | ||
// Cache the fetched data | ||
lock.insert( | ||
url.to_string(), | ||
ResponseCache { | ||
data: data.clone(), | ||
last_fetched: Instant::now(), | ||
}, | ||
); | ||
HttpResponse::Ok().json(data) | ||
} | ||
Err(_) => HttpResponse::InternalServerError().finish(), | ||
}, | ||
Err(_) => HttpResponse::InternalServerError().finish(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.