Merge #1671: Refac services module
7085542066006d1d0debbe6fff0b3463ace834f1 Move lianalite to services::connect module (edouardparis) f3ae84f91c2028d8e53da0d096867c8cf13a54c4 Move keys service to its own submodule (edouardparis) Pull request description: Move the current client implementation for https://keys.wizardsardine.com from `services` to `services::keys`. Move the liana-connect client implementation to `services::connect` ACKs for top commit: jp1ac4: ACK 7085542066006d1d0debbe6fff0b3463ace834f1. Tree-SHA512: 853f8cde9de768f0b087125b7ae9a5aae3fec9a5d6085ccf0ae72e6b75c7833424ddf482bcc9eefeea05f35ef59b65727af8f6e0af1efcf0a95217f3d9b74b2c
This commit is contained in:
commit
b2f28b94d1
@ -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";
|
||||
@ -143,8 +142,8 @@ impl From<backend::api::Provider> for Provider {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<services::api::Provider> for Provider {
|
||||
fn from(provider: services::api::Provider) -> Self {
|
||||
impl From<services::keys::api::Provider> for Provider {
|
||||
fn from(provider: services::keys::api::Provider) -> Self {
|
||||
Self {
|
||||
uuid: provider.uuid,
|
||||
name: provider.name,
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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)]
|
||||
@ -52,7 +54,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<String, backup::Error>),
|
||||
@ -176,7 +178,7 @@ pub enum ImportKeyModal {
|
||||
NameEdited(String),
|
||||
ManuallyImportXpub,
|
||||
ConfirmXpub,
|
||||
UseToken(services::api::KeyKind),
|
||||
UseToken(services::keys::api::KeyKind),
|
||||
TokenEdited(String),
|
||||
ConfirmToken,
|
||||
SelectKey(usize),
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
@ -701,7 +703,7 @@ pub enum Error {
|
||||
// DaemonError does not implement Clone.
|
||||
// TODO: maybe Arc is overkill
|
||||
Backend(Arc<DaemonError>),
|
||||
Services(services::Error),
|
||||
Services(services::keys::Error),
|
||||
Settings(SettingsError),
|
||||
Bitcoind(String),
|
||||
Electrum(String),
|
||||
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
step::Step,
|
||||
view, Error,
|
||||
},
|
||||
lianalite::client::{
|
||||
services::connect::client::{
|
||||
self,
|
||||
auth::{AuthClient, AuthError},
|
||||
backend::{api, BackendClient},
|
||||
|
||||
@ -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)| {
|
||||
|
||||
@ -30,7 +30,7 @@ use crate::{
|
||||
step::{Context, Step},
|
||||
view,
|
||||
},
|
||||
services::api::KeyKind,
|
||||
services::keys::api::KeyKind,
|
||||
signer::Signer,
|
||||
};
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ pub struct Final {
|
||||
internal_bitcoind: Option<Bitcoind>,
|
||||
warning: Option<String>,
|
||||
config_path: Option<PathBuf>,
|
||||
key_redemptions: HashMap<ProviderKey, Option<Result<(), services::Error>>>,
|
||||
key_redemptions: HashMap<ProviderKey, Option<Result<(), services::keys::Error>>>,
|
||||
}
|
||||
|
||||
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) },
|
||||
|
||||
@ -265,7 +265,7 @@ fn maybe_key_from_token<'a>(
|
||||
has_chosen_signer: bool,
|
||||
form_token: &form::Value<String>,
|
||||
form_token_warning: Option<&'a String>,
|
||||
key_kind: services::api::KeyKind,
|
||||
key_kind: services::keys::api::KeyKind,
|
||||
) -> Option<Element<'a, Message>> {
|
||||
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(
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
97
liana-gui/src/services/keys/mod.rs
Normal file
97
liana-gui/src/services/keys/mod.rs
Normal file
@ -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<u16>, 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<reqwest::Error> for Error {
|
||||
fn from(error: reqwest::Error) -> Self {
|
||||
Self::Http(None, error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_response_status(response: reqwest::Response) -> Result<reqwest::Response, Error> {
|
||||
if !response.status().is_success() {
|
||||
return Err(Error::Http(
|
||||
Some(response.status().into()),
|
||||
response.text().await?,
|
||||
));
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
fn request<U: reqwest::IntoUrl>(
|
||||
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<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
||||
request(&self.0, method, url)
|
||||
}
|
||||
|
||||
pub async fn get_key_by_token(&self, token: String) -> Result<api::Key, Error> {
|
||||
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<api::Key, Error> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1,97 +1,2 @@
|
||||
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<u16>, 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<reqwest::Error> for Error {
|
||||
fn from(error: reqwest::Error) -> Self {
|
||||
Self::Http(None, error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_response_status(response: reqwest::Response) -> Result<reqwest::Response, Error> {
|
||||
if !response.status().is_success() {
|
||||
return Err(Error::Http(
|
||||
Some(response.status().into()),
|
||||
response.text().await?,
|
||||
));
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
fn request<U: reqwest::IntoUrl>(
|
||||
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<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
||||
request(&self.0, method, url)
|
||||
}
|
||||
|
||||
pub async fn get_key_by_token(&self, token: String) -> Result<api::Key, Error> {
|
||||
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<api::Key, Error> {
|
||||
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 connect;
|
||||
pub mod keys;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user