|
@@ -1,13 +1,8 @@
|
|
|
-//! Minreq http Client
|
|
|
-
|
|
|
-use async_trait::async_trait;
|
|
|
+use reqwest::Client;
|
|
|
use serde_json::Value;
|
|
|
-use tracing::warn;
|
|
|
use url::Url;
|
|
|
|
|
|
-use super::join_url;
|
|
|
-use crate::client::{Client, Error};
|
|
|
-use crate::error::ErrorResponse;
|
|
|
+use crate::error::{Error, ErrorResponse};
|
|
|
use crate::nuts::{
|
|
|
BlindedMessage, CheckStateRequest, CheckStateResponse, CurrencyUnit, Id, KeySet, KeysResponse,
|
|
|
KeysetResponse, MeltBolt11Request, MeltBolt11Response, MeltQuoteBolt11Request,
|
|
@@ -17,24 +12,61 @@ use crate::nuts::{
|
|
|
};
|
|
|
use crate::{Amount, Bolt11Invoice};
|
|
|
|
|
|
+fn join_url(url: Url, paths: &[&str]) -> Result<Url, Error> {
|
|
|
+ let mut url = url;
|
|
|
+ for path in paths {
|
|
|
+ if !url.path().ends_with('/') {
|
|
|
+ url.path_segments_mut()
|
|
|
+ .map_err(|_| Error::CustomError("Url Path Segmants".to_string()))?
|
|
|
+ .push(path);
|
|
|
+ } else {
|
|
|
+ url.path_segments_mut()
|
|
|
+ .map_err(|_| Error::CustomError("Url Path Segmants".to_string()))?
|
|
|
+ .pop()
|
|
|
+ .push(path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Ok(url)
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Clone)]
|
|
|
-pub struct HttpClient {}
|
|
|
+pub struct HttpClient {
|
|
|
+ inner: Client,
|
|
|
+}
|
|
|
+
|
|
|
+impl Default for HttpClient {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self::new()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl HttpClient {
|
|
|
+ pub fn new() -> Self {
|
|
|
+ Self {
|
|
|
+ inner: Client::new(),
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-#[async_trait(?Send)]
|
|
|
-impl Client for HttpClient {
|
|
|
/// Get Active Mint Keys [NUT-01]
|
|
|
- async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error> {
|
|
|
+ pub async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "keys"])?;
|
|
|
- let keys = minreq::get(url).send()?.json::<Value>()?;
|
|
|
+ let keys = self.inner.get(url).send().await?.json::<Value>().await?;
|
|
|
|
|
|
let keys: KeysResponse = serde_json::from_value(keys)?;
|
|
|
Ok(keys.keysets)
|
|
|
}
|
|
|
|
|
|
/// Get Keyset Keys [NUT-01]
|
|
|
- async fn get_mint_keyset(&self, mint_url: Url, keyset_id: Id) -> Result<KeySet, Error> {
|
|
|
+ pub async fn get_mint_keyset(&self, mint_url: Url, keyset_id: Id) -> Result<KeySet, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "keys", &keyset_id.to_string()])?;
|
|
|
- let keys = minreq::get(url).send()?.json::<KeysResponse>()?;
|
|
|
+ let keys = self
|
|
|
+ .inner
|
|
|
+ .get(url)
|
|
|
+ .send()
|
|
|
+ .await?
|
|
|
+ .json::<KeysResponse>()
|
|
|
+ .await?;
|
|
|
|
|
|
// let keys: KeysResponse = serde_json::from_value(keys)?; //
|
|
|
// serde_json::from_str(&keys.to_string())?;
|
|
@@ -42,9 +74,9 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Get Keysets [NUT-02]
|
|
|
- async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error> {
|
|
|
+ pub async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "keysets"])?;
|
|
|
- let res = minreq::get(url).send()?.json::<Value>()?;
|
|
|
+ let res = self.inner.get(url).send().await?.json::<Value>().await?;
|
|
|
|
|
|
let response: Result<KeysetResponse, serde_json::Error> =
|
|
|
serde_json::from_value(res.clone());
|
|
@@ -56,7 +88,7 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Mint Quote [NUT-04]
|
|
|
- async fn post_mint_quote(
|
|
|
+ pub async fn post_mint_quote(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
amount: Amount,
|
|
@@ -66,22 +98,21 @@ impl Client for HttpClient {
|
|
|
|
|
|
let request = MintQuoteBolt11Request { amount, unit };
|
|
|
|
|
|
- let res = minreq::post(url).with_json(&request)?.send()?;
|
|
|
+ let res = self.inner.post(url).json(&request).send().await?;
|
|
|
+
|
|
|
+ let status = res.status();
|
|
|
|
|
|
let response: Result<MintQuoteBolt11Response, serde_json::Error> =
|
|
|
- serde_json::from_value(res.json()?);
|
|
|
+ serde_json::from_value(res.json().await?);
|
|
|
|
|
|
match response {
|
|
|
Ok(res) => Ok(res),
|
|
|
- Err(_) => {
|
|
|
- warn!("Bolt11 Mint Quote Unexpected response: {:?}", res);
|
|
|
- Err(ErrorResponse::from_json(&res.status_code.to_string())?.into())
|
|
|
- }
|
|
|
+ Err(_) => Err(ErrorResponse::from_json(&status.to_string())?.into()),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// Mint Tokens [NUT-04]
|
|
|
- async fn post_mint(
|
|
|
+ pub async fn post_mint(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
quote: &str,
|
|
@@ -94,10 +125,14 @@ impl Client for HttpClient {
|
|
|
outputs: premint_secrets.blinded_messages(),
|
|
|
};
|
|
|
|
|
|
- let res = minreq::post(url)
|
|
|
- .with_json(&request)?
|
|
|
- .send()?
|
|
|
- .json::<Value>()?;
|
|
|
+ let res = self
|
|
|
+ .inner
|
|
|
+ .post(url)
|
|
|
+ .json(&request)
|
|
|
+ .send()
|
|
|
+ .await?
|
|
|
+ .json::<Value>()
|
|
|
+ .await?;
|
|
|
|
|
|
let response: Result<MintBolt11Response, serde_json::Error> =
|
|
|
serde_json::from_value(res.clone());
|
|
@@ -109,7 +144,7 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Melt Quote [NUT-05]
|
|
|
- async fn post_melt_quote(
|
|
|
+ pub async fn post_melt_quote(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
unit: CurrencyUnit,
|
|
@@ -119,9 +154,9 @@ impl Client for HttpClient {
|
|
|
|
|
|
let request = MeltQuoteBolt11Request { request, unit };
|
|
|
|
|
|
- let value = minreq::post(url).with_json(&request)?.send()?;
|
|
|
+ let value = self.inner.post(url).json(&request).send().await?;
|
|
|
|
|
|
- let value = value.json::<Value>()?;
|
|
|
+ let value = value.json::<Value>().await?;
|
|
|
|
|
|
let response: Result<MeltQuoteBolt11Response, serde_json::Error> =
|
|
|
serde_json::from_value(value.clone());
|
|
@@ -134,7 +169,7 @@ impl Client for HttpClient {
|
|
|
|
|
|
/// Melt [NUT-05]
|
|
|
/// [Nut-08] Lightning fee return if outputs defined
|
|
|
- async fn post_melt(
|
|
|
+ pub async fn post_melt(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
quote: String,
|
|
@@ -149,9 +184,9 @@ impl Client for HttpClient {
|
|
|
outputs,
|
|
|
};
|
|
|
|
|
|
- let value = minreq::post(url).with_json(&request)?.send()?;
|
|
|
+ let value = self.inner.post(url).json(&request).send().await?;
|
|
|
|
|
|
- let value = value.json::<Value>()?;
|
|
|
+ let value = value.json::<Value>().await?;
|
|
|
let response: Result<MeltBolt11Response, serde_json::Error> =
|
|
|
serde_json::from_value(value.clone());
|
|
|
|
|
@@ -162,16 +197,16 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Split Token [NUT-06]
|
|
|
- async fn post_swap(
|
|
|
+ pub async fn post_swap(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
swap_request: SwapRequest,
|
|
|
) -> Result<SwapResponse, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "swap"])?;
|
|
|
|
|
|
- let res = minreq::post(url).with_json(&swap_request)?.send()?;
|
|
|
+ let res = self.inner.post(url).json(&swap_request).send().await?;
|
|
|
|
|
|
- let value = res.json::<Value>()?;
|
|
|
+ let value = res.json::<Value>().await?;
|
|
|
let response: Result<SwapResponse, serde_json::Error> =
|
|
|
serde_json::from_value(value.clone());
|
|
|
|
|
@@ -182,10 +217,10 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Get Mint Info [NUT-06]
|
|
|
- async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error> {
|
|
|
+ pub async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "info"])?;
|
|
|
|
|
|
- let res = minreq::get(url).send()?.json::<Value>()?;
|
|
|
+ let res = self.inner.get(url).send().await?.json::<Value>().await?;
|
|
|
|
|
|
let response: Result<MintInfo, serde_json::Error> = serde_json::from_value(res.clone());
|
|
|
|
|
@@ -196,7 +231,7 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
|
|
|
/// Spendable check [NUT-07]
|
|
|
- async fn post_check_state(
|
|
|
+ pub async fn post_check_state(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
ys: Vec<PublicKey>,
|
|
@@ -204,10 +239,14 @@ impl Client for HttpClient {
|
|
|
let url = join_url(mint_url, &["v1", "checkstate"])?;
|
|
|
let request = CheckStateRequest { ys };
|
|
|
|
|
|
- let res = minreq::post(url)
|
|
|
- .with_json(&request)?
|
|
|
- .send()?
|
|
|
- .json::<Value>()?;
|
|
|
+ let res = self
|
|
|
+ .inner
|
|
|
+ .post(url)
|
|
|
+ .json(&request)
|
|
|
+ .send()
|
|
|
+ .await?
|
|
|
+ .json::<Value>()
|
|
|
+ .await?;
|
|
|
|
|
|
let response: Result<CheckStateResponse, serde_json::Error> =
|
|
|
serde_json::from_value(res.clone());
|
|
@@ -218,17 +257,21 @@ impl Client for HttpClient {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async fn post_restore(
|
|
|
+ pub async fn post_restore(
|
|
|
&self,
|
|
|
mint_url: Url,
|
|
|
request: RestoreRequest,
|
|
|
) -> Result<RestoreResponse, Error> {
|
|
|
let url = join_url(mint_url, &["v1", "restore"])?;
|
|
|
|
|
|
- let res = minreq::post(url)
|
|
|
- .with_json(&request)?
|
|
|
- .send()?
|
|
|
- .json::<Value>()?;
|
|
|
+ let res = self
|
|
|
+ .inner
|
|
|
+ .post(url)
|
|
|
+ .json(&request)
|
|
|
+ .send()
|
|
|
+ .await?
|
|
|
+ .json::<Value>()
|
|
|
+ .await?;
|
|
|
|
|
|
let response: Result<RestoreResponse, serde_json::Error> =
|
|
|
serde_json::from_value(res.clone());
|