1- use crate :: rpc_clients:: { BundlerClient , PaymasterClient } ;
1+ use crate :: rpc_clients:: { BundlerClient , PaymasterClient , transport :: SharedClientTransportBuilder } ;
22use alloy:: {
33 providers:: { ProviderBuilder , RootProvider } ,
4- transports:: http:: {
5- Http ,
6- reqwest:: {
7- ClientBuilder as HttpClientBuilder , Url ,
8- header:: { HeaderMap , HeaderValue } ,
9- } ,
4+ rpc:: client:: RpcClient ,
5+ transports:: http:: reqwest:: {
6+ ClientBuilder as HttpClientBuilder , Url ,
7+ header:: { HeaderMap , HeaderValue } ,
108 } ,
119} ;
10+ use serde:: { Deserialize , Serialize } ;
1211
1312use crate :: error:: EngineError ;
1413
14+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
15+ pub struct ThirdwebClientIdAndServiceKey {
16+ pub client_id : String ,
17+ pub service_key : String ,
18+ }
19+
20+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
21+ pub enum ThirdwebRpcCredentials {
22+ ClientIdServiceKey ( ThirdwebClientIdAndServiceKey ) ,
23+ }
24+
25+ impl ThirdwebRpcCredentials {
26+ pub fn to_header_map ( & self ) -> Result < HeaderMap , EngineError > {
27+ match self {
28+ ThirdwebRpcCredentials :: ClientIdServiceKey ( creds) => {
29+ let mut headers = HeaderMap :: new ( ) ;
30+ headers. insert ( "x-client-id" , HeaderValue :: from_str ( & creds. client_id ) ?) ;
31+ headers. insert ( "x-service-key" , HeaderValue :: from_str ( & creds. service_key ) ?) ;
32+ Ok ( headers)
33+ }
34+ }
35+ }
36+ }
37+
38+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
39+ pub enum RpcCredentials {
40+ Thirdweb ( ThirdwebRpcCredentials ) ,
41+ }
42+
43+ impl RpcCredentials {
44+ pub fn to_header_map ( & self ) -> Result < HeaderMap , EngineError > {
45+ match self {
46+ RpcCredentials :: Thirdweb ( creds) => creds. to_header_map ( ) ,
47+ }
48+ }
49+ }
50+
1551pub trait Chain : Send + Sync {
1652 fn chain_id ( & self ) -> u64 ;
1753 fn rpc_url ( & self ) -> Url ;
@@ -21,6 +57,11 @@ pub trait Chain: Send + Sync {
2157 fn provider ( & self ) -> & RootProvider ;
2258 fn bundler_client ( & self ) -> & BundlerClient ;
2359 fn paymaster_client ( & self ) -> & PaymasterClient ;
60+
61+ fn bundler_client_with_headers ( & self , headers : HeaderMap ) -> BundlerClient ;
62+ fn paymaster_client_with_headers ( & self , headers : HeaderMap ) -> PaymasterClient ;
63+
64+ fn with_new_default_headers ( & self , headers : HeaderMap ) -> Self ;
2465}
2566
2667pub struct ThirdwebChainConfig < ' a > {
@@ -32,15 +73,22 @@ pub struct ThirdwebChainConfig<'a> {
3273 pub client_id : & ' a str ,
3374}
3475
76+ #[ derive( Clone ) ]
3577pub struct ThirdwebChain {
78+ transport_builder : SharedClientTransportBuilder ,
79+
3680 chain_id : u64 ,
3781 rpc_url : Url ,
3882 bundler_url : Url ,
3983 paymaster_url : Url ,
4084
85+ /// Default clients (these also use the shared connection pool)
4186 pub bundler_client : BundlerClient ,
4287 pub paymaster_client : PaymasterClient ,
4388 pub provider : RootProvider ,
89+
90+ pub sensitive_bundler_client : BundlerClient ,
91+ pub sensitive_paymaster_client : PaymasterClient ,
4492}
4593
4694impl Chain for ThirdwebChain {
@@ -71,6 +119,30 @@ impl Chain for ThirdwebChain {
71119 fn paymaster_client ( & self ) -> & PaymasterClient {
72120 & self . paymaster_client
73121 }
122+
123+ fn bundler_client_with_headers ( & self , headers : HeaderMap ) -> BundlerClient {
124+ let transport = self
125+ . transport_builder
126+ . with_headers ( self . bundler_url . clone ( ) , headers) ;
127+ let rpc_client = RpcClient :: builder ( ) . transport ( transport, false ) ;
128+ BundlerClient { inner : rpc_client }
129+ }
130+
131+ fn paymaster_client_with_headers ( & self , headers : HeaderMap ) -> PaymasterClient {
132+ let transport = self
133+ . transport_builder
134+ . with_headers ( self . paymaster_url . clone ( ) , headers) ;
135+ let rpc_client = RpcClient :: builder ( ) . transport ( transport, false ) ;
136+ PaymasterClient { inner : rpc_client }
137+ }
138+
139+ fn with_new_default_headers ( & self , headers : HeaderMap ) -> Self {
140+ let mut new_self = self . to_owned ( ) ;
141+ new_self. bundler_client = self . bundler_client_with_headers ( headers. clone ( ) ) ;
142+ new_self. paymaster_client = self . paymaster_client_with_headers ( headers. clone ( ) ) ;
143+
144+ new_self
145+ }
74146}
75147
76148impl < ' a > ThirdwebChainConfig < ' a > {
@@ -103,36 +175,67 @@ impl<'a> ThirdwebChainConfig<'a> {
103175 message : format ! ( "Failed to parse Paymaster URL: {}" , e. to_string( ) ) ,
104176 } ) ?;
105177
106- let mut headers = HeaderMap :: new ( ) ;
107- headers . insert (
178+ let mut sensitive_headers = HeaderMap :: new ( ) ;
179+ sensitive_headers . insert (
108180 "x-client-id" ,
109181 HeaderValue :: from_str ( & self . client_id ) . map_err ( |e| EngineError :: RpcConfigError {
110182 message : format ! ( "Unserialisable client-id used: {e}" ) ,
111183 } ) ?,
112184 ) ;
113185
114- headers . insert (
186+ sensitive_headers . insert (
115187 "x-secret-key" ,
116188 HeaderValue :: from_str ( & self . secret_key ) . map_err ( |e| EngineError :: RpcConfigError {
117189 message : format ! ( "Unserialisable secret-key used: {e}" ) ,
118190 } ) ?,
119191 ) ;
120192
121- let reqwest_client = HttpClientBuilder :: new ( )
122- . default_headers ( headers)
123- . build ( )
124- . map_err ( |e| EngineError :: RpcConfigError {
125- message : format ! ( "Failed to build HTTP client: {e}" ) ,
126- } ) ?;
193+ let reqwest_client =
194+ HttpClientBuilder :: new ( )
195+ . build ( )
196+ . map_err ( |e| EngineError :: RpcConfigError {
197+ message : format ! ( "Failed to build HTTP client: {e}" ) ,
198+ } ) ?;
199+
200+ let transport_builder = SharedClientTransportBuilder :: new ( reqwest_client. clone ( ) ) ;
127201
128- let paymaster_transport = Http :: with_client ( reqwest_client. clone ( ) , paymaster_url. clone ( ) ) ;
129- let bundler_transport = Http :: with_client ( reqwest_client, bundler_url. clone ( ) ) ;
202+ let paymaster_transport = transport_builder. default_transport ( paymaster_url. clone ( ) ) ;
203+ let bundler_transport = transport_builder. default_transport ( bundler_url. clone ( ) ) ;
204+
205+ let sensitive_bundler_transport =
206+ transport_builder. with_headers ( bundler_url. clone ( ) , sensitive_headers. clone ( ) ) ;
207+ let sensitive_paymaster_transport =
208+ transport_builder. with_headers ( paymaster_url. clone ( ) , sensitive_headers) ;
209+
210+ let paymaster_rpc_client = RpcClient :: builder ( ) . transport ( paymaster_transport, false ) ;
211+ let bundler_rpc_client = RpcClient :: builder ( ) . transport ( bundler_transport, false ) ;
212+
213+ let sensitive_bundler_rpc_client =
214+ RpcClient :: builder ( ) . transport ( sensitive_bundler_transport, false ) ;
215+ let sensitive_paymaster_rpc_client =
216+ RpcClient :: builder ( ) . transport ( sensitive_paymaster_transport, false ) ;
130217
131218 Ok ( ThirdwebChain {
219+ transport_builder,
220+
132221 chain_id : self . chain_id ,
133222 rpc_url : rpc_url. clone ( ) ,
134- bundler_client : BundlerClient :: new ( bundler_transport) ,
135- paymaster_client : PaymasterClient :: new ( paymaster_transport) ,
223+
224+ bundler_client : BundlerClient {
225+ inner : bundler_rpc_client,
226+ } ,
227+ paymaster_client : PaymasterClient {
228+ inner : paymaster_rpc_client,
229+ } ,
230+
231+ sensitive_bundler_client : BundlerClient {
232+ inner : sensitive_bundler_rpc_client,
233+ } ,
234+
235+ sensitive_paymaster_client : PaymasterClient {
236+ inner : sensitive_paymaster_rpc_client,
237+ } ,
238+
136239 provider : ProviderBuilder :: new ( )
137240 . disable_recommended_fillers ( )
138241 . connect_http ( rpc_url)
0 commit comments