fix: client join urls without trailing '/'

This commit is contained in:
thesimplekid
2023-11-15 20:43:35 +00:00
parent af23f89d96
commit e1264d3ee0
4 changed files with 73 additions and 53 deletions

View File

@@ -19,6 +19,7 @@ use gloo::net::http::Request;
use serde_json::Value;
use url::Url;
use super::join_url;
use crate::client::{Client, Error};
#[derive(Debug, Clone)]
@@ -27,8 +28,8 @@ pub struct HttpClient {}
#[async_trait(?Send)]
impl Client for HttpClient {
/// Get Mint Keys [NUT-01]
async fn get_mint_keys(&self, mint_url: &Url) -> Result<Keys, Error> {
let url = mint_url.join("keys")?;
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error> {
let url = join_url(mint_url, "keys")?;
let keys = Request::get(url.as_str())
.send()
.await
@@ -42,8 +43,8 @@ impl Client for HttpClient {
}
/// Get Keysets [NUT-02]
async fn get_mint_keysets(&self, mint_url: &Url) -> Result<nut02::Response, Error> {
let url = mint_url.join("keysets")?;
async fn get_mint_keysets(&self, mint_url: Url) -> Result<nut02::Response, Error> {
let url = join_url(mint_url, "keysets")?;
let res = Request::get(url.as_str())
.send()
.await
@@ -64,10 +65,10 @@ impl Client for HttpClient {
/// Request Mint [NUT-03]
async fn get_request_mint(
&self,
mint_url: &Url,
mint_url: Url,
amount: Amount,
) -> Result<RequestMintResponse, Error> {
let mut url = mint_url.join("mint")?;
let mut url = join_url(mint_url, "mint")?;
url.query_pairs_mut()
.append_pair("amount", &amount.to_sat().to_string());
@@ -91,11 +92,11 @@ impl Client for HttpClient {
/// Mint Tokens [NUT-04]
async fn post_mint(
&self,
mint_url: &Url,
mint_url: Url,
blinded_messages: BlindedMessages,
hash: &str,
) -> Result<PostMintResponse, Error> {
let mut url = mint_url.join("mint")?;
let mut url = join_url(mint_url, "mint")?;
url.query_pairs_mut().append_pair("hash", hash);
let request = MintRequest {
@@ -124,10 +125,10 @@ impl Client for HttpClient {
/// Check Max expected fee [NUT-05]
async fn post_check_fees(
&self,
mint_url: &Url,
mint_url: Url,
invoice: Bolt11Invoice,
) -> Result<CheckFeesResponse, Error> {
let url = mint_url.join("checkfees")?;
let url = join_url(mint_url, "checkfees")?;
let request = CheckFeesRequest { pr: invoice };
@@ -154,12 +155,12 @@ impl Client for HttpClient {
/// [Nut-08] Lightning fee return if outputs defined
async fn post_melt(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<Proof>,
invoice: Bolt11Invoice,
outputs: Option<Vec<BlindedMessage>>,
) -> Result<MeltResponse, Error> {
let url = mint_url.join("melt")?;
let url = join_url(mint_url, "melt")?;
let request = MeltRequest {
proofs,
@@ -189,10 +190,10 @@ impl Client for HttpClient {
/// Split Token [NUT-06]
async fn post_split(
&self,
mint_url: &Url,
mint_url: Url,
split_request: SplitRequest,
) -> Result<SplitResponse, Error> {
let url = mint_url.join("split")?;
let url = join_url(mint_url, "split")?;
let res = Request::post(url.as_str())
.json(&split_request)
@@ -217,10 +218,10 @@ impl Client for HttpClient {
#[cfg(feature = "nut07")]
async fn post_check_spendable(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<nut00::mint::Proof>,
) -> Result<CheckSpendableResponse, Error> {
let url = mint_url.join("check")?;
let url = join_url(mint_url, "check")?;
let request = CheckSpendableRequest {
proofs: proofs.to_owned(),
};
@@ -246,8 +247,8 @@ impl Client for HttpClient {
/// Get Mint Info [NUT-09]
#[cfg(feature = "nut09")]
async fn get_mint_info(&self, mint_url: &Url) -> Result<MintInfo, Error> {
let url = mint_url.join("info")?;
async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error> {
let url = join_url(mint_url, "info")?;
let res = Request::get(url.as_str())
.send()
.await

View File

@@ -18,6 +18,7 @@ use cashu::{Amount, Bolt11Invoice};
use serde_json::Value;
use url::Url;
use super::join_url;
use crate::client::{Client, Error};
#[derive(Debug, Clone)]
@@ -26,8 +27,8 @@ pub struct HttpClient {}
#[async_trait(?Send)]
impl Client for HttpClient {
/// Get Mint Keys [NUT-01]
async fn get_mint_keys(&self, mint_url: &Url) -> Result<Keys, Error> {
let url = mint_url.join("keys")?;
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error> {
let url = join_url(mint_url, "keys")?;
let keys = minreq::get(url).send()?.json::<Value>()?;
let keys: Keys = serde_json::from_str(&keys.to_string())?;
@@ -35,8 +36,8 @@ impl Client for HttpClient {
}
/// Get Keysets [NUT-02]
async fn get_mint_keysets(&self, mint_url: &Url) -> Result<nut02::Response, Error> {
let url = mint_url.join("keysets")?;
async fn get_mint_keysets(&self, mint_url: Url) -> Result<nut02::Response, Error> {
let url = join_url(mint_url, "keysets")?;
let res = minreq::get(url).send()?.json::<Value>()?;
let response: Result<nut02::Response, serde_json::Error> =
@@ -51,10 +52,10 @@ impl Client for HttpClient {
/// Request Mint [NUT-03]
async fn get_request_mint(
&self,
mint_url: &Url,
mint_url: Url,
amount: Amount,
) -> Result<RequestMintResponse, Error> {
let mut url = mint_url.join("mint")?;
let mut url = join_url(mint_url, "mint")?;
url.query_pairs_mut()
.append_pair("amount", &amount.to_sat().to_string());
@@ -72,11 +73,11 @@ impl Client for HttpClient {
/// Mint Tokens [NUT-04]
async fn post_mint(
&self,
mint_url: &Url,
mint_url: Url,
blinded_messages: BlindedMessages,
hash: &str,
) -> Result<PostMintResponse, Error> {
let mut url = mint_url.join("mint")?;
let mut url = join_url(mint_url, "mint")?;
url.query_pairs_mut().append_pair("hash", hash);
let request = MintRequest {
@@ -100,10 +101,10 @@ impl Client for HttpClient {
/// Check Max expected fee [NUT-05]
async fn post_check_fees(
&self,
mint_url: &Url,
mint_url: Url,
invoice: Bolt11Invoice,
) -> Result<CheckFeesResponse, Error> {
let url = mint_url.join("checkfees")?;
let url = join_url(mint_url, "checkfees")?;
let request = CheckFeesRequest { pr: invoice };
@@ -125,12 +126,12 @@ impl Client for HttpClient {
/// [Nut-08] Lightning fee return if outputs defined
async fn post_melt(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<Proof>,
invoice: Bolt11Invoice,
outputs: Option<Vec<BlindedMessage>>,
) -> Result<MeltResponse, Error> {
let url = mint_url.join("melt")?;
let url = join_url(mint_url, "melt")?;
let request = MeltRequest {
proofs,
@@ -155,10 +156,10 @@ impl Client for HttpClient {
/// Split Token [NUT-06]
async fn post_split(
&self,
mint_url: &Url,
mint_url: Url,
split_request: SplitRequest,
) -> Result<SplitResponse, Error> {
let url = mint_url.join("split")?;
let url = join_url(mint_url, "split")?;
let res = minreq::post(url)
.with_json(&split_request)?
@@ -178,10 +179,10 @@ impl Client for HttpClient {
#[cfg(feature = "nut07")]
async fn post_check_spendable(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<nut00::mint::Proof>,
) -> Result<CheckSpendableResponse, Error> {
let url = mint_url.join("check")?;
let url = join_url(mint_url, "check")?;
let request = CheckSpendableRequest { proofs };
let res = minreq::post(url)
@@ -200,8 +201,9 @@ impl Client for HttpClient {
/// Get Mint Info [NUT-09]
#[cfg(feature = "nut09")]
async fn get_mint_info(&self, mint_url: &Url) -> Result<MintInfo, Error> {
let url = mint_url.join("info")?;
async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error> {
let url = join_url(mint_url, "info")?;
let res = minreq::get(url).send()?.json::<Value>()?;
let response: Result<MintInfo, serde_json::Error> = serde_json::from_value(res.clone());

View File

@@ -84,33 +84,33 @@ pub struct MintErrorResponse {
#[async_trait(?Send)]
pub trait Client {
async fn get_mint_keys(&self, mint_url: &Url) -> Result<Keys, Error>;
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error>;
async fn get_mint_keysets(&self, mint_url: &Url) -> Result<nut02::Response, Error>;
async fn get_mint_keysets(&self, mint_url: Url) -> Result<nut02::Response, Error>;
async fn get_request_mint(
&self,
mint_url: &Url,
mint_url: Url,
amount: Amount,
) -> Result<RequestMintResponse, Error>;
// TODO: Hash should have a type
async fn post_mint(
&self,
mint_url: &Url,
mint_url: Url,
blinded_messages: BlindedMessages,
hash: &str,
) -> Result<PostMintResponse, Error>;
async fn post_check_fees(
&self,
mint_url: &Url,
mint_url: Url,
invoice: Bolt11Invoice,
) -> Result<CheckFeesResponse, Error>;
async fn post_melt(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<Proof>,
invoice: Bolt11Invoice,
outputs: Option<Vec<BlindedMessage>>,
@@ -121,19 +121,36 @@ pub trait Client {
// in but in check spendable and melt the compants are passed in
async fn post_split(
&self,
mint_url: &Url,
mint_url: Url,
split_request: SplitRequest,
) -> Result<SplitResponse, Error>;
#[cfg(feature = "nut07")]
async fn post_check_spendable(
&self,
mint_url: &Url,
mint_url: Url,
proofs: Vec<nut00::mint::Proof>,
) -> Result<CheckSpendableResponse, Error>;
#[cfg(feature = "nut09")]
async fn get_mint_info(&self, mint_url: &Url) -> Result<MintInfo, Error>;
async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error>;
}
#[cfg(any(not(target_arch = "wasm32"), feature = "gloo"))]
fn join_url(url: Url, path: &str) -> Result<Url, Error> {
let mut url = url;
if !url.path().ends_with('/') {
url.path_segments_mut()
.map_err(|_| Error::Custom("Url Path Segmants".to_string()))?
.push(path);
} else {
url.path_segments_mut()
.map_err(|_| Error::Custom("Url Path Segmants".to_string()))?
.pop()
.push(path);
}
Ok(url)
}
#[cfg(test)]

View File

@@ -62,7 +62,7 @@ impl<C: Client> Wallet<C> {
) -> Result<ProofsStatus, Error> {
let spendable = self
.client
.post_check_spendable(&self.mint_url.clone().try_into()?, proofs.clone())
.post_check_spendable(self.mint_url.clone().try_into()?, proofs.clone())
.await?;
// Separate proofs in spent and unspent based on mint response
@@ -81,7 +81,7 @@ impl<C: Client> Wallet<C> {
pub async fn request_mint(&self, amount: Amount) -> Result<RequestMintResponse, Error> {
Ok(self
.client
.get_request_mint(&self.mint_url.clone().try_into()?, amount)
.get_request_mint(self.mint_url.clone().try_into()?, amount)
.await?)
}
@@ -99,7 +99,7 @@ impl<C: Client> Wallet<C> {
let mint_res = self
.client
.post_mint(
&self.mint_url.clone().try_into()?,
self.mint_url.clone().try_into()?,
blinded_messages.clone(),
hash,
)
@@ -119,7 +119,7 @@ impl<C: Client> Wallet<C> {
pub async fn check_fee(&self, invoice: Bolt11Invoice) -> Result<Amount, Error> {
Ok(self
.client
.post_check_fees(&self.mint_url.clone().try_into()?, invoice)
.post_check_fees(self.mint_url.clone().try_into()?, invoice)
.await?
.fee)
}
@@ -137,7 +137,7 @@ impl<C: Client> Wallet<C> {
let keys = if token.mint.to_string().eq(&self.mint_url.to_string()) {
self.mint_keys.clone()
} else {
self.client.get_mint_keys(&token.mint.try_into()?).await?
self.client.get_mint_keys(token.mint.try_into()?).await?
};
// Sum amount of all proofs
@@ -148,7 +148,7 @@ impl<C: Client> Wallet<C> {
let split_response = self
.client
.post_split(
&self.mint_url.clone().try_into()?,
self.mint_url.clone().try_into()?,
split_payload.split_payload,
)
.await?;
@@ -255,7 +255,7 @@ impl<C: Client> Wallet<C> {
let split_response = self
.client
.post_split(
&self.mint_url.clone().try_into()?,
self.mint_url.clone().try_into()?,
split_payload.split_payload,
)
.await?;
@@ -299,7 +299,7 @@ impl<C: Client> Wallet<C> {
let melt_response = self
.client
.post_melt(
&self.mint_url.clone().try_into()?,
self.mint_url.clone().try_into()?,
proofs,
invoice,
Some(blinded.blinded_messages),