alloy_rpc_client/
builder.rs1use crate::{BuiltInConnectionString, ConnectionConfig, RpcClient};
2use alloy_transport::{BoxTransport, IntoBoxTransport, TransportConnect, TransportResult};
3use std::str::FromStr;
4use tower::{
5 layer::util::{Identity, Stack},
6 Layer, ServiceBuilder,
7};
8
9#[derive(Debug)]
18pub struct ClientBuilder<L> {
19 pub(crate) builder: ServiceBuilder<L>,
20}
21
22impl Default for ClientBuilder<Identity> {
23 fn default() -> Self {
24 Self { builder: ServiceBuilder::new() }
25 }
26}
27
28impl<L> ClientBuilder<L> {
29 pub fn layer<M>(self, layer: M) -> ClientBuilder<Stack<M, L>> {
34 ClientBuilder { builder: self.builder.layer(layer) }
35 }
36
37 pub fn transport<T>(self, transport: T, is_local: bool) -> RpcClient
43 where
44 L: Layer<T>,
45 T: IntoBoxTransport,
46 L::Service: IntoBoxTransport,
47 {
48 RpcClient::new_layered(is_local, transport, move |t| self.builder.service(t))
49 }
50
51 #[cfg(all(feature = "reqwest", not(all(target_os = "wasi", target_env = "p1"))))]
54 pub fn http(self, url: url::Url) -> RpcClient
55 where
56 L: Layer<alloy_transport_http::Http<reqwest::Client>>,
57 L::Service: IntoBoxTransport,
58 {
59 let transport = alloy_transport_http::Http::new(url);
60 let is_local = transport.guess_local();
61
62 self.transport(transport, is_local)
63 }
64
65 #[cfg(all(feature = "reqwest", not(all(target_os = "wasi", target_env = "p1"))))]
68 pub fn http_with_client(self, client: reqwest::Client, url: url::Url) -> RpcClient
69 where
70 L: Layer<alloy_transport_http::Http<reqwest::Client>>,
71 L::Service: IntoBoxTransport,
72 {
73 let transport = alloy_transport_http::Http::with_client(client, url);
74 let is_local = transport.guess_local();
75
76 self.transport(transport, is_local)
77 }
78
79 #[cfg(all(not(target_family = "wasm"), feature = "hyper"))]
81 pub fn hyper_http(self, url: url::Url) -> RpcClient
82 where
83 L: Layer<alloy_transport_http::HyperTransport>,
84 L::Service: IntoBoxTransport,
85 {
86 let transport = alloy_transport_http::HyperTransport::new_hyper(url);
87 let is_local = transport.guess_local();
88
89 self.transport(transport, is_local)
90 }
91
92 #[cfg(feature = "pubsub")]
95 pub async fn pubsub<C>(self, pubsub_connect: C) -> TransportResult<RpcClient>
96 where
97 C: alloy_pubsub::PubSubConnect,
98 L: Layer<alloy_pubsub::PubSubFrontend>,
99 L::Service: IntoBoxTransport,
100 {
101 let is_local = pubsub_connect.is_local();
102 let transport = pubsub_connect.into_service().await?;
103 Ok(self.transport(transport, is_local))
104 }
105
106 #[cfg(feature = "ws-base")]
109 pub async fn ws(self, ws_connect: alloy_transport_ws::WsConnect) -> TransportResult<RpcClient>
110 where
111 L: Layer<alloy_pubsub::PubSubFrontend>,
112 L::Service: IntoBoxTransport,
113 {
114 self.pubsub(ws_connect).await
115 }
116
117 #[cfg(feature = "ipc")]
120 pub async fn ipc<T>(
121 self,
122 ipc_connect: alloy_transport_ipc::IpcConnect<T>,
123 ) -> TransportResult<RpcClient>
124 where
125 alloy_transport_ipc::IpcConnect<T>: alloy_pubsub::PubSubConnect,
126 L: Layer<alloy_pubsub::PubSubFrontend>,
127 L::Service: IntoBoxTransport,
128 {
129 self.pubsub(ipc_connect).await
130 }
131
132 pub async fn connect(self, s: &str) -> TransportResult<RpcClient>
136 where
137 L: Layer<BoxTransport>,
138 L::Service: IntoBoxTransport,
139 {
140 self.connect_with(s.parse::<BuiltInConnectionString>()?).await
141 }
142
143 pub async fn connect_with_config(
170 self,
171 s: &str,
172 config: ConnectionConfig,
173 ) -> TransportResult<RpcClient>
174 where
175 L: Layer<BoxTransport>,
176 L::Service: IntoBoxTransport,
177 {
178 let connect = BuiltInConnectionString::from_str(s)?;
179 let is_local = connect.is_local();
180 let transport = connect.connect_boxed_with(config).await?;
181 let transport = self.builder.service(transport);
182 Ok(RpcClient::new(transport.into_box_transport(), is_local))
183 }
184
185 pub async fn connect_with<C>(self, connect: C) -> TransportResult<RpcClient>
187 where
188 C: TransportConnect,
189 L: Layer<BoxTransport>,
190 L::Service: IntoBoxTransport,
191 {
192 let transport = connect.get_transport().await?;
193 Ok(self.transport(transport, connect.is_local()))
194 }
195}