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