From f3ae84f91c2028d8e53da0d096867c8cf13a54c4 Mon Sep 17 00:00:00 2001 From: edouardparis Date: Thu, 24 Apr 2025 11:28:25 +0200 Subject: [PATCH 1/2] Move keys service to its own submodule --- liana-gui/src/app/settings.rs | 4 +- liana-gui/src/installer/descriptor.rs | 2 +- liana-gui/src/installer/message.rs | 4 +- liana-gui/src/installer/mod.rs | 2 +- .../installer/step/descriptor/editor/key.rs | 2 +- .../installer/step/descriptor/editor/mod.rs | 2 +- liana-gui/src/installer/step/mod.rs | 4 +- liana-gui/src/installer/view/editor/mod.rs | 6 +- liana-gui/src/services/{ => keys}/api.rs | 0 liana-gui/src/services/keys/mod.rs | 97 ++++++++++++++++++ liana-gui/src/services/mod.rs | 98 +------------------ 11 files changed, 111 insertions(+), 110 deletions(-) rename liana-gui/src/services/{ => keys}/api.rs (100%) create mode 100644 liana-gui/src/services/keys/mod.rs diff --git a/liana-gui/src/app/settings.rs b/liana-gui/src/app/settings.rs index b2b5aba7..a9e08812 100644 --- a/liana-gui/src/app/settings.rs +++ b/liana-gui/src/app/settings.rs @@ -143,8 +143,8 @@ impl From for Provider { } } -impl From for Provider { - fn from(provider: services::api::Provider) -> Self { +impl From for Provider { + fn from(provider: services::keys::api::Provider) -> Self { Self { uuid: provider.uuid, name: provider.name, diff --git a/liana-gui/src/installer/descriptor.rs b/liana-gui/src/installer/descriptor.rs index 7fa05941..f39342e5 100644 --- a/liana-gui/src/installer/descriptor.rs +++ b/liana-gui/src/installer/descriptor.rs @@ -2,7 +2,7 @@ use async_hwi::{DeviceKind, Version}; use liana::miniscript::{bitcoin::bip32::Fingerprint, descriptor::DescriptorPublicKey}; use crate::{ - app::settings::ProviderKey, hw::is_compatible_with_tapminiscript, services::api::KeyKind, + app::settings::ProviderKey, hw::is_compatible_with_tapminiscript, services::keys::api::KeyKind, }; /// Whether to enable cosigner keys on all paths (excluding safety net paths). diff --git a/liana-gui/src/installer/message.rs b/liana-gui/src/installer/message.rs index b00fdc52..615228a8 100644 --- a/liana-gui/src/installer/message.rs +++ b/liana-gui/src/installer/message.rs @@ -52,7 +52,7 @@ pub enum Message { MnemonicWord(usize, String), ImportMnemonic(bool), RedeemNextKey, - KeyRedeemed(ProviderKey, Result<(), services::Error>), + KeyRedeemed(ProviderKey, Result<(), services::keys::Error>), AllKeysRedeemed, BackupWallet, ExportWallet(Result), @@ -176,7 +176,7 @@ pub enum ImportKeyModal { NameEdited(String), ManuallyImportXpub, ConfirmXpub, - UseToken(services::api::KeyKind), + UseToken(services::keys::api::KeyKind), TokenEdited(String), ConfirmToken, SelectKey(usize), diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index b012dead..b60a3607 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -719,7 +719,7 @@ pub enum Error { // DaemonError does not implement Clone. // TODO: maybe Arc is overkill Backend(Arc), - Services(services::Error), + Services(services::keys::Error), Settings(SettingsError), Bitcoind(String), Electrum(String), diff --git a/liana-gui/src/installer/step/descriptor/editor/key.rs b/liana-gui/src/installer/step/descriptor/editor/key.rs index 98234742..3fbac98e 100644 --- a/liana-gui/src/installer/step/descriptor/editor/key.rs +++ b/liana-gui/src/installer/step/descriptor/editor/key.rs @@ -406,7 +406,7 @@ impl super::DescriptorEditModal for EditXpubModal { message::ImportKeyModal::ConfirmToken => { // We have checked that the token has not already been fetched and saved. let token = self.form_token.value.clone(); - let client = services::Client::new(); + let client = services::keys::Client::new(); return Task::perform( async move { (token.clone(), client.get_key_by_token(token).await) }, |(token, res)| { diff --git a/liana-gui/src/installer/step/descriptor/editor/mod.rs b/liana-gui/src/installer/step/descriptor/editor/mod.rs index 13c761fe..fdd47bf7 100644 --- a/liana-gui/src/installer/step/descriptor/editor/mod.rs +++ b/liana-gui/src/installer/step/descriptor/editor/mod.rs @@ -30,7 +30,7 @@ use crate::{ step::{Context, Step}, view, }, - services::api::KeyKind, + services::keys::api::KeyKind, signer::Signer, }; diff --git a/liana-gui/src/installer/step/mod.rs b/liana-gui/src/installer/step/mod.rs index a6b7b082..3f4384d1 100644 --- a/liana-gui/src/installer/step/mod.rs +++ b/liana-gui/src/installer/step/mod.rs @@ -68,7 +68,7 @@ pub struct Final { internal_bitcoind: Option, warning: Option, config_path: Option, - key_redemptions: HashMap>>, + key_redemptions: HashMap>>, } impl Final { @@ -109,7 +109,7 @@ impl Step for Final { match message { Message::RedeemNextKey => { if let Some((pk, _)) = self.key_redemptions.iter().find(|(_, v)| v.is_none()) { - let client = services::Client::new(); + let client = services::keys::Client::new(); let pk = pk.clone(); return Task::perform( async move { (pk.clone(), client.redeem_key(pk.uuid, pk.token).await) }, diff --git a/liana-gui/src/installer/view/editor/mod.rs b/liana-gui/src/installer/view/editor/mod.rs index caeb8d67..6a15deb5 100644 --- a/liana-gui/src/installer/view/editor/mod.rs +++ b/liana-gui/src/installer/view/editor/mod.rs @@ -265,7 +265,7 @@ fn maybe_key_from_token<'a>( has_chosen_signer: bool, form_token: &form::Value, form_token_warning: Option<&'a String>, - key_kind: services::api::KeyKind, + key_kind: services::keys::api::KeyKind, ) -> Option> { if !path_kind.can_choose_key_source_kind(&KeySourceKind::Token(key_kind)) { None @@ -448,8 +448,8 @@ pub fn edit_key_modal<'a>( )) } ) - .push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::SafetyNet)) - .push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::api::KeyKind::Cosigner)) + .push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::keys::api::KeyKind::SafetyNet)) + .push_maybe(maybe_key_from_token(path_kind, form_key_source_kind, chosen_signer.is_some(), form_token, form_token_warning, services::keys::api::KeyKind::Cosigner)) .width(Length::Fill), ) .push_maybe( diff --git a/liana-gui/src/services/api.rs b/liana-gui/src/services/keys/api.rs similarity index 100% rename from liana-gui/src/services/api.rs rename to liana-gui/src/services/keys/api.rs diff --git a/liana-gui/src/services/keys/mod.rs b/liana-gui/src/services/keys/mod.rs new file mode 100644 index 00000000..340ff684 --- /dev/null +++ b/liana-gui/src/services/keys/mod.rs @@ -0,0 +1,97 @@ +pub mod api; + +use reqwest::{self, IntoUrl, Method, RequestBuilder}; +use serde_json::json; + +const KEYS_API_URL: &str = "https://keys.wizardsardine.com"; + +#[derive(Debug, Clone)] +pub enum Error { + Http(Option, String), +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Http(kind, e) => write!(f, "Http error: [{:?}] {}", kind, e), + } + } +} + +impl From for Error { + fn from(error: reqwest::Error) -> Self { + Self::Http(None, error.to_string()) + } +} + +async fn check_response_status(response: reqwest::Response) -> Result { + if !response.status().is_success() { + return Err(Error::Http( + Some(response.status().into()), + response.text().await?, + )); + } + Ok(response) +} + +fn request( + http: &reqwest::Client, + method: reqwest::Method, + url: U, +) -> reqwest::RequestBuilder { + let req = http + .request(method, url) + .header("Content-Type", "application/json") + .header("API-Version", "0.1"); + tracing::debug!("Sending http request: {:?}", req); + req +} + +#[derive(Debug, Clone)] +pub struct Client(reqwest::Client); + +impl Default for Client { + fn default() -> Self { + Self::new() + } +} + +impl Client { + pub fn new() -> Self { + let http = reqwest::Client::new(); + Client(http) + } + + async fn request(&self, method: Method, url: U) -> RequestBuilder { + request(&self.0, method, url) + } + + pub async fn get_key_by_token(&self, token: String) -> Result { + let response = self + .request(Method::GET, &format!("{}/v1/keys", KEYS_API_URL)) + .await + .query(&[("token", token)]) + .send() + .await?; + let response = check_response_status(response).await?; + let key = response.json().await?; + Ok(key) + } + + pub async fn redeem_key(&self, uuid: String, token: String) -> Result { + let response = self + .request( + Method::POST, + &format!("{}/v1/keys/{}/redeem", KEYS_API_URL, uuid), + ) + .await + .json(&json!({ + "token": token, + })) + .send() + .await?; + let response = check_response_status(response).await?; + let key = response.json().await?; + Ok(key) + } +} diff --git a/liana-gui/src/services/mod.rs b/liana-gui/src/services/mod.rs index 340ff684..703bc087 100644 --- a/liana-gui/src/services/mod.rs +++ b/liana-gui/src/services/mod.rs @@ -1,97 +1 @@ -pub mod api; - -use reqwest::{self, IntoUrl, Method, RequestBuilder}; -use serde_json::json; - -const KEYS_API_URL: &str = "https://keys.wizardsardine.com"; - -#[derive(Debug, Clone)] -pub enum Error { - Http(Option, String), -} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::Http(kind, e) => write!(f, "Http error: [{:?}] {}", kind, e), - } - } -} - -impl From for Error { - fn from(error: reqwest::Error) -> Self { - Self::Http(None, error.to_string()) - } -} - -async fn check_response_status(response: reqwest::Response) -> Result { - if !response.status().is_success() { - return Err(Error::Http( - Some(response.status().into()), - response.text().await?, - )); - } - Ok(response) -} - -fn request( - http: &reqwest::Client, - method: reqwest::Method, - url: U, -) -> reqwest::RequestBuilder { - let req = http - .request(method, url) - .header("Content-Type", "application/json") - .header("API-Version", "0.1"); - tracing::debug!("Sending http request: {:?}", req); - req -} - -#[derive(Debug, Clone)] -pub struct Client(reqwest::Client); - -impl Default for Client { - fn default() -> Self { - Self::new() - } -} - -impl Client { - pub fn new() -> Self { - let http = reqwest::Client::new(); - Client(http) - } - - async fn request(&self, method: Method, url: U) -> RequestBuilder { - request(&self.0, method, url) - } - - pub async fn get_key_by_token(&self, token: String) -> Result { - let response = self - .request(Method::GET, &format!("{}/v1/keys", KEYS_API_URL)) - .await - .query(&[("token", token)]) - .send() - .await?; - let response = check_response_status(response).await?; - let key = response.json().await?; - Ok(key) - } - - pub async fn redeem_key(&self, uuid: String, token: String) -> Result { - let response = self - .request( - Method::POST, - &format!("{}/v1/keys/{}/redeem", KEYS_API_URL, uuid), - ) - .await - .json(&json!({ - "token": token, - })) - .send() - .await?; - let response = check_response_status(response).await?; - let key = response.json().await?; - Ok(key) - } -} +pub mod keys; From 7085542066006d1d0debbe6fff0b3463ace834f1 Mon Sep 17 00:00:00 2001 From: edouardparis Date: Thu, 24 Apr 2025 11:38:19 +0200 Subject: [PATCH 2/2] Move lianalite to services::connect module --- liana-gui/src/app/settings.rs | 3 +-- liana-gui/src/backup.rs | 2 +- liana-gui/src/export.rs | 2 +- liana-gui/src/installer/context.rs | 2 +- liana-gui/src/installer/message.rs | 6 ++++-- liana-gui/src/installer/mod.rs | 14 ++++++++------ liana-gui/src/installer/step/backend.rs | 2 +- liana-gui/src/lib.rs | 1 - liana-gui/src/main.rs | 6 +++--- .../{lianalite => services/connect}/client/auth.rs | 0 .../connect}/client/backend/api.rs | 0 .../connect}/client/backend/mod.rs | 0 .../{lianalite => services/connect}/client/mod.rs | 0 .../src/{lianalite => services/connect}/login.rs | 0 .../src/{lianalite => services/connect}/mod.rs | 0 liana-gui/src/services/mod.rs | 1 + 16 files changed, 21 insertions(+), 18 deletions(-) rename liana-gui/src/{lianalite => services/connect}/client/auth.rs (100%) rename liana-gui/src/{lianalite => services/connect}/client/backend/api.rs (100%) rename liana-gui/src/{lianalite => services/connect}/client/backend/mod.rs (100%) rename liana-gui/src/{lianalite => services/connect}/client/mod.rs (100%) rename liana-gui/src/{lianalite => services/connect}/login.rs (100%) rename liana-gui/src/{lianalite => services/connect}/mod.rs (100%) diff --git a/liana-gui/src/app/settings.rs b/liana-gui/src/app/settings.rs index a9e08812..3b10ddc0 100644 --- a/liana-gui/src/app/settings.rs +++ b/liana-gui/src/app/settings.rs @@ -12,8 +12,7 @@ use serde::{Deserialize, Serialize}; use crate::{ backup::{Key, KeyRole, KeyType}, hw::HardwareWalletConfig, - lianalite::client::backend, - services, + services::{self, connect::client::backend}, }; pub const DEFAULT_FILE_NAME: &str = "settings.json"; diff --git a/liana-gui/src/backup.rs b/liana-gui/src/backup.rs index 4a272ab0..57d3ec89 100644 --- a/liana-gui/src/backup.rs +++ b/liana-gui/src/backup.rs @@ -26,7 +26,7 @@ use crate::{ extract_daemon_config, extract_local_gui_settings, extract_remote_gui_settings, Context, RemoteBackend, }, - lianalite::client::backend::api::DEFAULT_LIMIT, + services::connect::client::backend::api::DEFAULT_LIMIT, VERSION, }; diff --git a/liana-gui/src/export.rs b/liana-gui/src/export.rs index 52015dc9..ffa9c805 100644 --- a/liana-gui/src/export.rs +++ b/liana-gui/src/export.rs @@ -44,8 +44,8 @@ use crate::{ model::{HistoryTransaction, Labelled}, Daemon, DaemonBackend, DaemonError, }, - lianalite::client::backend::api::DEFAULT_LIMIT, node::bitcoind::Bitcoind, + services::connect::client::backend::api::DEFAULT_LIMIT, }; const DUMP_LABELS_LIMIT: u32 = 100; diff --git a/liana-gui/src/installer/context.rs b/liana-gui/src/installer/context.rs index 025349bc..c150cb94 100644 --- a/liana-gui/src/installer/context.rs +++ b/liana-gui/src/installer/context.rs @@ -6,8 +6,8 @@ use std::time::Duration; use crate::{ app::settings::KeySetting, backup::Backup, - lianalite::client::backend::{BackendClient, BackendWalletClient}, node::bitcoind::{Bitcoind, InternalBitcoindConfig}, + services::connect::client::backend::{BackendClient, BackendWalletClient}, signer::Signer, }; use async_hwi::DeviceKind; diff --git a/liana-gui/src/installer/message.rs b/liana-gui/src/installer/message.rs index 615228a8..c1ee32ca 100644 --- a/liana-gui/src/installer/message.rs +++ b/liana-gui/src/installer/message.rs @@ -15,12 +15,14 @@ use crate::{ export::ImportExportMessage, hw::HardwareWalletMessage, installer::descriptor::{Key, PathKind}, - lianalite::client::{auth::AuthClient, backend::api}, node::{ bitcoind::{Bitcoind, ConfigField, RpcAuthType}, electrum, NodeType, }, - services, + services::{ + self, + connect::client::{auth::AuthClient, backend::api}, + }, }; #[derive(Debug, Clone)] diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index b60a3607..bb2cf85f 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -29,14 +29,16 @@ use crate::{ daemon::DaemonError, datadir::create_directory, hw::{HardwareWalletConfig, HardwareWallets}, - lianalite::client::{ - auth::AuthError, - backend::{ - api::payload::{Provider, ProviderKey}, - BackendClient, BackendWalletClient, + services::{ + self, + connect::client::{ + auth::AuthError, + backend::{ + api::payload::{Provider, ProviderKey}, + BackendClient, BackendWalletClient, + }, }, }, - services, signer::Signer, }; diff --git a/liana-gui/src/installer/step/backend.rs b/liana-gui/src/installer/step/backend.rs index 169babd9..1b79c24d 100644 --- a/liana-gui/src/installer/step/backend.rs +++ b/liana-gui/src/installer/step/backend.rs @@ -14,7 +14,7 @@ use crate::{ step::Step, view, Error, }, - lianalite::client::{ + services::connect::client::{ self, auth::{AuthClient, AuthError}, backend::{api, BackendClient}, diff --git a/liana-gui/src/lib.rs b/liana-gui/src/lib.rs index 42217a14..df620545 100644 --- a/liana-gui/src/lib.rs +++ b/liana-gui/src/lib.rs @@ -7,7 +7,6 @@ pub mod export; pub mod hw; pub mod installer; pub mod launcher; -pub mod lianalite; pub mod loader; pub mod logger; pub mod node; diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index ec867a14..ae22f735 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -28,12 +28,12 @@ use liana_gui::{ hw::HardwareWalletConfig, installer::{self, Installer}, launcher::{self, Launcher}, - lianalite::{ + loader::{self, Loader}, + logger::Logger, + services::connect::{ client::backend::{api, BackendWalletClient}, login, }, - loader::{self, Loader}, - logger::Logger, VERSION, }; diff --git a/liana-gui/src/lianalite/client/auth.rs b/liana-gui/src/services/connect/client/auth.rs similarity index 100% rename from liana-gui/src/lianalite/client/auth.rs rename to liana-gui/src/services/connect/client/auth.rs diff --git a/liana-gui/src/lianalite/client/backend/api.rs b/liana-gui/src/services/connect/client/backend/api.rs similarity index 100% rename from liana-gui/src/lianalite/client/backend/api.rs rename to liana-gui/src/services/connect/client/backend/api.rs diff --git a/liana-gui/src/lianalite/client/backend/mod.rs b/liana-gui/src/services/connect/client/backend/mod.rs similarity index 100% rename from liana-gui/src/lianalite/client/backend/mod.rs rename to liana-gui/src/services/connect/client/backend/mod.rs diff --git a/liana-gui/src/lianalite/client/mod.rs b/liana-gui/src/services/connect/client/mod.rs similarity index 100% rename from liana-gui/src/lianalite/client/mod.rs rename to liana-gui/src/services/connect/client/mod.rs diff --git a/liana-gui/src/lianalite/login.rs b/liana-gui/src/services/connect/login.rs similarity index 100% rename from liana-gui/src/lianalite/login.rs rename to liana-gui/src/services/connect/login.rs diff --git a/liana-gui/src/lianalite/mod.rs b/liana-gui/src/services/connect/mod.rs similarity index 100% rename from liana-gui/src/lianalite/mod.rs rename to liana-gui/src/services/connect/mod.rs diff --git a/liana-gui/src/services/mod.rs b/liana-gui/src/services/mod.rs index 703bc087..c6c16e26 100644 --- a/liana-gui/src/services/mod.rs +++ b/liana-gui/src/services/mod.rs @@ -1 +1,2 @@ +pub mod connect; pub mod keys;