1
- use crate :: rpc_clients:: { BundlerClient , PaymasterClient } ;
1
+ use crate :: rpc_clients:: { BundlerClient , PaymasterClient , transport :: SharedClientTransportBuilder } ;
2
2
use alloy:: {
3
3
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 } ,
10
8
} ,
11
9
} ;
10
+ use serde:: { Deserialize , Serialize } ;
12
11
13
12
use crate :: error:: EngineError ;
14
13
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
+
15
51
pub trait Chain : Send + Sync {
16
52
fn chain_id ( & self ) -> u64 ;
17
53
fn rpc_url ( & self ) -> Url ;
@@ -21,6 +57,11 @@ pub trait Chain: Send + Sync {
21
57
fn provider ( & self ) -> & RootProvider ;
22
58
fn bundler_client ( & self ) -> & BundlerClient ;
23
59
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 ;
24
65
}
25
66
26
67
pub struct ThirdwebChainConfig < ' a > {
@@ -32,15 +73,22 @@ pub struct ThirdwebChainConfig<'a> {
32
73
pub client_id : & ' a str ,
33
74
}
34
75
76
+ #[ derive( Clone ) ]
35
77
pub struct ThirdwebChain {
78
+ transport_builder : SharedClientTransportBuilder ,
79
+
36
80
chain_id : u64 ,
37
81
rpc_url : Url ,
38
82
bundler_url : Url ,
39
83
paymaster_url : Url ,
40
84
85
+ /// Default clients (these also use the shared connection pool)
41
86
pub bundler_client : BundlerClient ,
42
87
pub paymaster_client : PaymasterClient ,
43
88
pub provider : RootProvider ,
89
+
90
+ pub sensitive_bundler_client : BundlerClient ,
91
+ pub sensitive_paymaster_client : PaymasterClient ,
44
92
}
45
93
46
94
impl Chain for ThirdwebChain {
@@ -71,6 +119,30 @@ impl Chain for ThirdwebChain {
71
119
fn paymaster_client ( & self ) -> & PaymasterClient {
72
120
& self . paymaster_client
73
121
}
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
+ }
74
146
}
75
147
76
148
impl < ' a > ThirdwebChainConfig < ' a > {
@@ -103,36 +175,67 @@ impl<'a> ThirdwebChainConfig<'a> {
103
175
message : format ! ( "Failed to parse Paymaster URL: {}" , e. to_string( ) ) ,
104
176
} ) ?;
105
177
106
- let mut headers = HeaderMap :: new ( ) ;
107
- headers . insert (
178
+ let mut sensitive_headers = HeaderMap :: new ( ) ;
179
+ sensitive_headers . insert (
108
180
"x-client-id" ,
109
181
HeaderValue :: from_str ( & self . client_id ) . map_err ( |e| EngineError :: RpcConfigError {
110
182
message : format ! ( "Unserialisable client-id used: {e}" ) ,
111
183
} ) ?,
112
184
) ;
113
185
114
- headers . insert (
186
+ sensitive_headers . insert (
115
187
"x-secret-key" ,
116
188
HeaderValue :: from_str ( & self . secret_key ) . map_err ( |e| EngineError :: RpcConfigError {
117
189
message : format ! ( "Unserialisable secret-key used: {e}" ) ,
118
190
} ) ?,
119
191
) ;
120
192
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 ( ) ) ;
127
201
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 ) ;
130
217
131
218
Ok ( ThirdwebChain {
219
+ transport_builder,
220
+
132
221
chain_id : self . chain_id ,
133
222
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
+
136
239
provider : ProviderBuilder :: new ( )
137
240
. disable_recommended_fillers ( )
138
241
. connect_http ( rpc_url)
0 commit comments