diff --git a/nym-connect/desktop/src-tauri/src/error.rs b/nym-connect/desktop/src-tauri/src/error.rs index 5b324a8850..da7dbd65c3 100644 --- a/nym-connect/desktop/src-tauri/src/error.rs +++ b/nym-connect/desktop/src-tauri/src/error.rs @@ -41,11 +41,6 @@ pub enum BackendError { source: ClientCoreError, }, #[error("{source}")] - ApiClientError { - #[from] - source: crate::operations::growth::api_client::ApiClientError, - }, - #[error("{source}")] EnvError { #[from] source: std::env::VarError, diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index 684c641446..d9a6040466 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -91,13 +91,6 @@ fn main() { crate::operations::directory::services::get_services, crate::operations::export::export_keys, crate::operations::window::hide_window, - crate::operations::growth::test_and_earn::growth_tne_get_client_id, - crate::operations::growth::test_and_earn::growth_tne_take_part, - crate::operations::growth::test_and_earn::growth_tne_get_draws, - crate::operations::growth::test_and_earn::growth_tne_ping, - crate::operations::growth::test_and_earn::growth_tne_submit_wallet_address, - crate::operations::growth::test_and_earn::growth_tne_enter_draw, - crate::operations::growth::test_and_earn::growth_tne_toggle_window, crate::operations::help::log::help_log_toggle_window, ]) .on_menu_event(|event| { diff --git a/nym-connect/desktop/src-tauri/src/operations/export.rs b/nym-connect/desktop/src-tauri/src/operations/export.rs index 3b11891e9c..10a9ef73e3 100644 --- a/nym-connect/desktop/src-tauri/src/operations/export.rs +++ b/nym-connect/desktop/src-tauri/src/operations/export.rs @@ -10,6 +10,7 @@ use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::client::key_manager::KeyManager; use nym_crypto::asymmetric::identity; +#[allow(unused)] pub async fn get_identity_key( state: &tauri::State<'_, Arc>>, ) -> Result> { diff --git a/nym-connect/desktop/src-tauri/src/operations/growth/api_client.rs b/nym-connect/desktop/src-tauri/src/operations/growth/api_client.rs deleted file mode 100644 index c069cb6a9d..0000000000 --- a/nym-connect/desktop/src-tauri/src/operations/growth/api_client.rs +++ /dev/null @@ -1,270 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -#[allow(unused)] -#[derive(Error, Debug)] -pub enum ApiClientError { - #[error("{source}")] - Reqwest { - #[from] - source: reqwest::Error, - }, - #[error("{source}")] - SerdeJson { - #[from] - source: serde_json::Error, - }, - #[error("{0}")] - Status(String), -} - -const API_BASE_URL: &str = "https://growth-api.nymtech.net"; - -// For development mode, switch to this -// const API_BASE_URL: &str = "http://localhost:8000"; - -#[derive(Debug, Clone)] -pub struct GrowthApiClient { - base_url: String, -} - -impl GrowthApiClient { - pub fn new(resource_base: &str) -> Self { - let base_url = std::env::var("API_BASE_URL").unwrap_or_else(|_| API_BASE_URL.to_string()); - GrowthApiClient { - base_url: format!("{base_url}{resource_base}"), - } - } - - pub fn registrations() -> Registrations { - Registrations::new(GrowthApiClient::new("/v1/tne")) - } - - pub fn daily_draws() -> DailyDraws { - DailyDraws::new(GrowthApiClient::new("/v1/tne/daily_draw")) - } - - pub(crate) async fn get(&self, url: &str) -> Result { - log::info!(">>> GET {}", url); - let proxy = reqwest::Proxy::all("socks5h://127.0.0.1:1080")?; - let client = reqwest::Client::builder() - .proxy(proxy) - .timeout(std::time::Duration::from_secs(10)) - .build()?; - - match client.get(format!("{}{}", self.base_url, url)).send().await { - Ok(res) => { - if res.status().is_client_error() || res.status().is_server_error() { - log::error!("<<< {}", res.status()); - return Err(ApiClientError::Status(res.status().to_string())); - } - match res.text().await { - Ok(response_body) => { - log::info!("<<< {}", response_body); - match serde_json::from_str(&response_body) { - Ok(res) => Ok(res), - Err(e) => { - log::error!("<<< JSON parsing error: {}", e); - Err(e.into()) - } - } - } - Err(e) => { - log::error!("<<< Request error: {}", e); - Err(e.into()) - } - } - } - Err(e) => { - log::error!("<<< Response parsing error: {}", e); - Err(e.into()) - } - } - } - - // TODO: use the method in `operations::http` instead - pub(crate) async fn post( - &self, - url: &str, - body: &REQ, - ) -> Result { - log::info!(">>> POST {}", url); - let proxy = reqwest::Proxy::all("socks5h://127.0.0.1:1080")?; - let client = reqwest::Client::builder() - .proxy(proxy) - .timeout(std::time::Duration::from_secs(10)) - .build()?; - - match client - .post(format!("{}{}", self.base_url, url)) - .json(body) - .send() - .await - { - Ok(res) => { - if res.status().is_client_error() || res.status().is_server_error() { - log::error!("<<< {}", res.status()); - return Err(ApiClientError::Status(res.status().to_string())); - } - match res.text().await { - Ok(response_body) => { - log::info!("<<< {}", response_body); - match serde_json::from_str(&response_body) { - Ok(res) => Ok(res), - Err(e) => { - log::error!("<<< JSON parsing error: {}", e); - Err(e.into()) - } - } - } - Err(e) => { - log::error!("<<< Request error: {}", e); - Err(e.into()) - } - } - } - Err(e) => { - log::error!("<<< Response parsing error: {}", e); - Err(e.into()) - } - } - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ClientIdPartial { - pub client_id: String, - pub client_id_signature: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Registration { - pub id: String, - pub client_id: String, - pub timestamp: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Ping { - pub client_id: String, - pub timestamp: String, -} - -pub struct Registrations { - client: GrowthApiClient, -} - -impl Registrations { - pub fn new(client: GrowthApiClient) -> Self { - Registrations { client } - } - - pub async fn register( - &self, - registration: &ClientIdPartial, - ) -> Result { - self.client.post("/register", ®istration).await - } - - #[allow(dead_code)] - pub async fn unregister(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { - self.client.post("/unregister", ®istration).await - } - - #[allow(dead_code)] - pub async fn status(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { - self.client.post("/status", ®istration).await - } - - pub async fn ping(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { - self.client.post("/ping", ®istration).await - } - - #[allow(dead_code)] - pub async fn health(&self) -> Result<(), ApiClientError> { - self.client.get("/health").await - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct DrawEntryPartial { - pub draw_id: String, - pub client_id: String, - pub client_id_signature: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct DrawEntry { - pub id: String, - pub draw_id: String, - pub timestamp: String, - pub status: Option, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct DrawWithWordOfTheDay { - pub id: String, - pub start_utc: String, - pub end_utc: String, - pub word_of_the_day: Option, - pub last_modified: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ClaimPartial { - pub draw_id: String, - pub registration_id: String, - pub client_id: String, - pub client_id_signature: String, - pub wallet_address: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Winner { - pub id: String, - pub client_id: String, - pub draw_id: String, - pub timestamp: String, - pub winner_reg_id: String, - pub winner_wallet_address: Option, - pub winner_claim_timestamp: Option, -} - -pub struct DailyDraws { - client: GrowthApiClient, -} - -impl DailyDraws { - pub fn new(client: GrowthApiClient) -> Self { - DailyDraws { client } - } - - pub async fn current(&self) -> Result { - self.client.get("/current").await - } - - pub async fn next(&self) -> Result { - self.client.get("/next").await - } - - #[allow(dead_code)] - pub async fn status(&self, draw_id: &str) -> Result { - self.client.get(format!("/status/{draw_id}").as_str()).await - } - - pub async fn enter(&self, entry: &DrawEntryPartial) -> Result { - self.client.post("/enter", entry).await - } - - pub async fn entries( - &self, - client_id: &ClientIdPartial, - ) -> Result, ApiClientError> { - self.client.post("/entries", client_id).await - } - - pub async fn claim(&self, claim: &ClaimPartial) -> Result { - self.client.post("/claim", claim).await - } -} diff --git a/nym-connect/desktop/src-tauri/src/operations/growth/assets.rs b/nym-connect/desktop/src-tauri/src/operations/growth/assets.rs deleted file mode 100644 index 752b221916..0000000000 --- a/nym-connect/desktop/src-tauri/src/operations/growth/assets.rs +++ /dev/null @@ -1,57 +0,0 @@ -use rust_embed::RustEmbed; -extern crate yaml_rust; -use yaml_rust::YamlLoader; - -#[derive(RustEmbed)] -#[folder = "../src/components/Growth/content/"] -#[include = "*.yaml"] -#[exclude = "*.mdx"] -struct Asset; - -#[derive(Debug)] -pub struct NotificationContent { - pub title: String, - pub body: String, -} - -#[derive(Debug)] -pub struct Notifications { - pub you_are_in_draw: NotificationContent, - pub take_part: NotificationContent, -} - -pub struct Content {} - -const RESOURCE_ERROR: &str = "❌ RESOURCE ERROR"; - -fn get_as_string_or_error_message(value: &yaml_rust::Yaml) -> String { - value.as_str().unwrap_or(RESOURCE_ERROR).to_string() -} - -impl Content { - pub fn get_notifications() -> Notifications { - let content = Asset::get("en.yaml").unwrap(); - let s = std::str::from_utf8(content.data.as_ref()).unwrap(); - let content = YamlLoader::load_from_str(s).unwrap(); - let content = &content[0]; - - Notifications { - you_are_in_draw: NotificationContent { - title: get_as_string_or_error_message( - &content["testAndEarn"]["notifications"]["youAreInDraw"]["title"], - ), - body: get_as_string_or_error_message( - &content["testAndEarn"]["notifications"]["youAreInDraw"]["body"], - ), - }, - take_part: NotificationContent { - title: get_as_string_or_error_message( - &content["testAndEarn"]["notifications"]["takePart"]["title"], - ), - body: get_as_string_or_error_message( - &content["testAndEarn"]["notifications"]["takePart"]["body"], - ), - }, - } - } -} diff --git a/nym-connect/desktop/src-tauri/src/operations/growth/mod.rs b/nym-connect/desktop/src-tauri/src/operations/growth/mod.rs deleted file mode 100644 index 449c1bcee2..0000000000 --- a/nym-connect/desktop/src-tauri/src/operations/growth/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod api_client; -pub mod assets; -pub mod test_and_earn; diff --git a/nym-connect/desktop/src-tauri/src/operations/growth/test_and_earn.rs b/nym-connect/desktop/src-tauri/src/operations/growth/test_and_earn.rs deleted file mode 100644 index c2216ce245..0000000000 --- a/nym-connect/desktop/src-tauri/src/operations/growth/test_and_earn.rs +++ /dev/null @@ -1,156 +0,0 @@ -use crate::error::BackendError; -use crate::operations::export::get_identity_key; -use crate::operations::growth::api_client::{ - ClaimPartial, ClientIdPartial, DrawEntry, DrawEntryPartial, DrawWithWordOfTheDay, - GrowthApiClient, Registration, Winner, -}; -use crate::State; -use serde::{Deserialize, Serialize}; -use std::sync::Arc; -use tauri::api::notification::Notification; -use tauri::Manager; -use tokio::sync::RwLock; - -async fn get_client_id( - state: &tauri::State<'_, Arc>>, -) -> Result { - let keypair = get_identity_key(state).await?; - let client_id = keypair.public_key().to_base58_string(); - let client_id_signature = keypair - .private_key() - .sign(client_id.as_bytes()) - .to_base58_string(); - Ok(ClientIdPartial { - client_id, - client_id_signature, - }) -} - -#[tauri::command] -pub async fn growth_tne_get_client_id( - state: tauri::State<'_, Arc>>, -) -> Result { - get_client_id(&state).await -} - -#[tauri::command] -pub async fn growth_tne_take_part( - app_handle: tauri::AppHandle, - state: tauri::State<'_, Arc>>, -) -> Result { - let notifications = super::assets::Content::get_notifications(); - - let client_id = get_client_id(&state).await?; - let registration = GrowthApiClient::registrations() - .register(&client_id) - .await?; - - log::info!("<<< Test&Earn: registration details: {:?}", registration); - - if let Err(e) = Notification::new(&app_handle.config().tauri.bundle.identifier) - .title(notifications.take_part.title) - .body(notifications.take_part.body) - .show() - { - log::error!("Could not show notification. Error = {:?}", e); - } - - Ok(registration) -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Draws { - pub current: Option, - pub next: Option, - pub draws: Vec, -} - -#[tauri::command] -pub async fn growth_tne_get_draws(client_details: ClientIdPartial) -> Result { - let draws_api = GrowthApiClient::daily_draws(); - - let current = draws_api.current().await.ok(); - let next = draws_api.next().await.ok(); - let draws = draws_api.entries(&client_details).await?; - - Ok(Draws { - current, - next, - draws, - }) -} - -#[tauri::command] -pub async fn growth_tne_enter_draw( - client_details: ClientIdPartial, - draw_id: String, -) -> Result { - Ok(GrowthApiClient::daily_draws() - .enter(&DrawEntryPartial { - draw_id, - client_id: client_details.client_id, - client_id_signature: client_details.client_id_signature, - }) - .await?) -} - -#[tauri::command] -pub async fn growth_tne_submit_wallet_address( - client_details: ClientIdPartial, - draw_id: String, - wallet_address: String, - registration_id: String, -) -> Result { - Ok(GrowthApiClient::daily_draws() - .claim(&ClaimPartial { - draw_id, - client_id: client_details.client_id, - client_id_signature: client_details.client_id_signature, - wallet_address, - registration_id, - }) - .await?) -} - -#[tauri::command] -pub async fn growth_tne_ping(client_details: ClientIdPartial) -> Result<(), BackendError> { - log::info!("Test&Earn is sending a ping..."); - Ok(GrowthApiClient::registrations() - .ping(&client_details) - .await?) -} - -#[tauri::command] -pub async fn growth_tne_toggle_window( - app_handle: tauri::AppHandle, - window_title: Option, -) -> Result<(), BackendError> { - if let Some(window) = app_handle.windows().get("growth") { - log::info!("Closing growth window..."); - if let Err(e) = window.close() { - log::error!("Unable to close growth window: {:?}", e); - } - return Ok(()); - } - - log::info!("Creating growth window..."); - match tauri::WindowBuilder::new( - &app_handle, - "growth", - tauri::WindowUrl::App("growth.html".into()), - ) - .title(window_title.unwrap_or_else(|| "NymConnect Test&Earn".to_string())) - .build() - { - Ok(window) => { - if let Err(e) = window.set_focus() { - log::error!("Unable to focus growth window: {:?}", e); - } - Ok(()) - } - Err(e) => { - log::error!("Unable to create growth window: {:?}", e); - Err(BackendError::NewWindowError) - } - } -} diff --git a/nym-connect/desktop/src-tauri/src/operations/mod.rs b/nym-connect/desktop/src-tauri/src/operations/mod.rs index 977dcc5110..f20c82770d 100644 --- a/nym-connect/desktop/src-tauri/src/operations/mod.rs +++ b/nym-connect/desktop/src-tauri/src/operations/mod.rs @@ -3,7 +3,6 @@ pub mod config; pub mod connection; pub mod directory; pub mod export; -pub mod growth; pub mod help; pub mod http; pub mod window;