lescuer97 1 день тому
батько
коміт
88a1a20bda

+ 1 - 1
Cargo.toml

@@ -66,7 +66,7 @@ cdk-signatory = { path = "./crates/cdk-signatory", version = "=0.15.0", default-
 cdk-mintd = { path = "./crates/cdk-mintd", version = "=0.15.0", default-features = false }
 cdk-prometheus = { path = "./crates/cdk-prometheus", version = "=0.15.0", default-features = false }
 cdk-npubcash = { path = "./crates/cdk-npubcash", version = "=0.15.0" }
-cdk-http-client = { path = "./crates/cdk-http-client", version = "=0.15.0" }
+cdk-http-client = { path = "./crates/cdk-http-client", version = "=0.15.0", default-features = false }
 clap = { version = "4.5.31", features = ["derive"] }
 ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
 cbor-diag = "0.1.12"

+ 3 - 2
crates/cdk-common/Cargo.toml

@@ -23,7 +23,6 @@ http = ["dep:cdk-http-client"]
 grpc = ["dep:tonic"]
 
 [dependencies]
-cdk-http-client = { workspace = true, optional = true }
 async-trait.workspace = true
 bitcoin.workspace = true
 cashu.workspace = true
@@ -48,12 +47,14 @@ paste = "1.0.15"
 tonic = { workspace = true, optional = true }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
+cdk-http-client = { workspace = true, optional = true, features = ["bitreq"] }
 tokio = { version = "1", default-features = false, features = ["rt", "rt-multi-thread", "macros", "test-util", "sync"] }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
+cdk-http-client = { workspace = true, optional = true, default-features = false, features = ["reqwest"] }
 uuid = { workspace = true, features = ["js"], optional = true }
 getrandom = { version = "0.2", features = ["js"] }
-tokio.workspace = true
+tokio = { workspace = true, default-features = false }
 wasm-bindgen = "0.2"
 wasm-bindgen-futures = "0.4"
 

+ 13 - 2
crates/cdk-http-client/src/client.rs

@@ -348,6 +348,7 @@ pub struct HttpClientBuilder {
     accept_invalid_certs: bool,
 }
 
+#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
 #[cfg(any(feature = "bitreq", feature = "reqwest"))]
 #[derive(Debug, Clone)]
 pub(crate) struct ProxyConfig {
@@ -385,14 +386,14 @@ pub(crate) fn apply_proxy_if_needed(
 
 impl HttpClientBuilder {
     /// Set a proxy URL (reqwest only)
-    #[cfg(feature = "reqwest")]
+    #[cfg(all(feature = "reqwest", not(target_arch = "wasm32")))]
     pub fn proxy(mut self, url: url::Url) -> Self {
         self.proxy = Some(ProxyConfig { url, matcher: None });
         self
     }
 
     /// Set a proxy URL with a host pattern matcher (reqwest only)
-    #[cfg(feature = "reqwest")]
+    #[cfg(all(feature = "reqwest", not(target_arch = "wasm32")))]
     pub fn proxy_with_matcher(mut self, url: url::Url, pattern: &str) -> Response<Self> {
         let matcher = regex::Regex::new(pattern)
             .map_err(|e| HttpError::Proxy(format!("Invalid proxy pattern: {}", e)))?;
@@ -433,7 +434,11 @@ impl HttpClientBuilder {
     pub fn build(self) -> Response<HttpClient> {
         #[cfg(feature = "reqwest")]
         {
+            #[cfg(not(target_arch = "wasm32"))]
             let mut builder = reqwest::Client::builder();
+            #[cfg(target_arch = "wasm32")]
+            let builder = reqwest::Client::builder();
+            #[cfg(not(target_arch = "wasm32"))]
             if let Some(proxy) = self.proxy {
                 let proxy_url = proxy.url;
                 if let Some(matcher) = proxy.matcher {
@@ -453,6 +458,12 @@ impl HttpClientBuilder {
                     builder = builder.proxy(proxy);
                 }
             }
+            #[cfg(target_arch = "wasm32")]
+            if self.proxy.is_some() {
+                return Err(HttpError::Build(
+                    "proxy configuration is not supported on wasm".to_string(),
+                ));
+            }
             let client = builder
                 .build()
                 .map_err(|e| HttpError::Build(e.to_string()))?;

+ 52 - 0
crates/cdk-http-client/src/request_builder_ext.rs

@@ -9,6 +9,7 @@ use crate::response::{RawResponse, Response};
 ///
 /// This trait abstracts over different HTTP client backends (bitreq, reqwest)
 /// and provides a unified interface for building and sending HTTP requests.
+#[cfg(not(target_arch = "wasm32"))]
 pub trait RequestBuilderExt: Sized + Send {
     /// Add a header to the request
     fn header(self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self;
@@ -28,6 +29,31 @@ pub trait RequestBuilderExt: Sized + Send {
     ) -> impl std::future::Future<Output = Response<R>> + Send;
 }
 
+#[cfg(target_arch = "wasm32")]
+/// Trait for building and sending HTTP requests
+///
+/// This trait abstracts over different HTTP client backends (bitreq, reqwest)
+/// and provides a unified interface for building and sending HTTP requests.
+pub trait RequestBuilderExt: Sized {
+    /// Add a header to the request
+    fn header(self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self;
+
+    /// Set the request body as JSON
+    fn json<T: Serialize>(self, body: &T) -> Self;
+
+    /// Set the request body as form data
+    fn form<T: Serialize>(self, body: &T) -> Self;
+
+    /// Send the request and return a raw response
+    fn send(self) -> impl std::future::Future<Output = Response<RawResponse>>;
+
+    /// Send the request and deserialize the response as JSON
+    fn send_json<R: DeserializeOwned>(
+        self,
+    ) -> impl std::future::Future<Output = Response<R>>;
+}
+
+#[cfg(not(target_arch = "wasm32"))]
 #[allow(clippy::manual_async_fn)]
 impl<T: RequestBuilderExt> RequestBuilderExt for Box<T> {
     fn header(self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self {
@@ -52,3 +78,29 @@ impl<T: RequestBuilderExt> RequestBuilderExt for Box<T> {
         async move { (*self).send_json().await }
     }
 }
+
+#[cfg(target_arch = "wasm32")]
+#[allow(clippy::manual_async_fn)]
+impl<T: RequestBuilderExt> RequestBuilderExt for Box<T> {
+    fn header(self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self {
+        Box::new((*self).header(key, value))
+    }
+
+    fn json<B: Serialize>(self, body: &B) -> Self {
+        Box::new((*self).json(body))
+    }
+
+    fn form<F: Serialize>(self, body: &F) -> Self {
+        Box::new((*self).form(body))
+    }
+
+    fn send(self) -> impl std::future::Future<Output = Response<RawResponse>> {
+        async move { (*self).send().await }
+    }
+
+    fn send_json<R: DeserializeOwned>(
+        self,
+    ) -> impl std::future::Future<Output = Response<R>> {
+        async move { (*self).send_json().await }
+    }
+}

+ 3 - 2
crates/cdk/Cargo.toml

@@ -37,7 +37,6 @@ prometheus = ["dep:cdk-prometheus"]
 [dependencies]
 arc-swap = "1.7.1"
 cdk-common.workspace = true
-cdk-http-client.workspace = true
 cbor-diag.workspace = true
 async-trait.workspace = true
 anyhow.workspace = true
@@ -65,6 +64,7 @@ zeroize = "1"
 tokio-util.workspace = true
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
+cdk-http-client = { workspace = true, features = ["bitreq"] }
 hickory-resolver = { version = "0.25.2", optional = true, features = ["dnssec-ring"] }
 tokio = { workspace = true, features = [
     "rt-multi-thread",
@@ -90,7 +90,8 @@ tls-api = { version = "0.9", optional = true }
 tls-api-native-tls = { version = "0.9", optional = true }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
-tokio = { workspace = true, features = ["rt", "macros", "sync", "time"] }
+cdk-http-client = { workspace = true, default-features = false, features = ["reqwest"] }
+tokio = { workspace = true, default-features = false, features = ["rt", "macros", "sync", "time"] }
 cdk-signatory = { workspace = true, default-features = false }
 getrandom = { version = "0.2", features = ["js"] }
 ring = { version = "0.17.14", features = ["wasm32_unknown_unknown_js"] }

+ 3 - 1
crates/cdk/src/wallet/mint_connector/transport.rs

@@ -1,7 +1,9 @@
 //! HTTP Transport trait with a default implementation
 use std::fmt::Debug;
 
-use cdk_common::{AuthToken, HttpClient, HttpClientBuilder};
+use cdk_common::{AuthToken, HttpClient};
+#[cfg(not(target_arch = "wasm32"))]
+use cdk_common::HttpClientBuilder;
 use cdk_http_client::RequestBuilderExt;
 #[cfg(all(feature = "bip353", not(target_arch = "wasm32")))]
 use hickory_resolver::config::ResolverConfig;