Move keys service to its own submodule

This commit is contained in:
edouardparis 2025-04-24 11:28:25 +02:00
parent 1213858489
commit f3ae84f91c
11 changed files with 111 additions and 110 deletions

View File

@ -143,8 +143,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,

View File

@ -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).

View File

@ -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<String, backup::Error>),
@ -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),

View File

@ -719,7 +719,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),

View File

@ -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)| {

View File

@ -30,7 +30,7 @@ use crate::{
step::{Context, Step},
view,
},
services::api::KeyKind,
services::keys::api::KeyKind,
signer::Signer,
};

View File

@ -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) },

View File

@ -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(

View 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)
}
}

View File

@ -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<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 keys;