@@ -12,6 +12,7 @@ use alloy::{
1212 SimpleNonceManager , WalletFiller ,
1313 } ,
1414 } ,
15+ rpc:: client:: BuiltInConnectionString ,
1516} ;
1617use eyre:: Result ;
1718use init4_bin_base:: {
@@ -63,11 +64,19 @@ pub struct BuilderConfig {
6364 pub ru_chain_id : u64 ,
6465
6566 /// URL for Host RPC node.
66- #[ from_env( var = "HOST_RPC_URL" , desc = "URL for Host RPC node" , infallible) ]
67+ #[ from_env(
68+ var = "HOST_RPC_URL" ,
69+ desc = "URL for Host RPC node. This MUST be a valid HTTP or WS URL, starting with http://, https://, ws:// or wss://" ,
70+ infallible
71+ ) ]
6772 pub host_rpc_url : Cow < ' static , str > ,
6873
6974 /// URL for the Rollup RPC node.
70- #[ from_env( var = "ROLLUP_RPC_URL" , desc = "URL for Rollup RPC node" , infallible) ]
75+ #[ from_env(
76+ var = "ROLLUP_RPC_URL" ,
77+ desc = "URL for Rollup RPC node. This MUST be a valid WS url starting with ws:// or wss://. Http providers are not supported." ,
78+ infallible
79+ ) ]
7180 pub ru_rpc_url : Cow < ' static , str > ,
7281
7382 /// URL of the tx pool to poll for incoming transactions.
@@ -176,14 +185,25 @@ impl BuilderConfig {
176185 }
177186
178187 /// Connect to the Rollup rpc provider.
179- pub fn connect_ru_provider ( & self ) -> RootProvider < Ethereum > {
180- static ONCE : std:: sync:: OnceLock < RootProvider < Ethereum > > = std:: sync:: OnceLock :: new ( ) ;
188+ pub async fn connect_ru_provider ( & self ) -> eyre:: Result < RootProvider < Ethereum > > {
189+ static ONCE : tokio:: sync:: OnceCell < RootProvider < Ethereum > > =
190+ tokio:: sync:: OnceCell :: const_new ( ) ;
181191
182- ONCE . get_or_init ( || {
183- let url = url:: Url :: parse ( & self . ru_rpc_url ) . expect ( "failed to parse URL" ) ;
184- RootProvider :: new_http ( url)
192+ ONCE . get_or_try_init ( || async {
193+ let url = url:: Url :: parse ( & self . ru_rpc_url ) ?;
194+
195+ let scheme = url. scheme ( ) ;
196+ eyre:: ensure!(
197+ scheme == "ws" || scheme == "wss" ,
198+ "Invalid Rollup RPC URL scheme: {scheme}. Expected ws:// or wss://"
199+ ) ;
200+
201+ RootProvider :: connect_with ( BuiltInConnectionString :: Ws ( url, None ) )
202+ . await
203+ . map_err ( Into :: into)
185204 } )
186- . clone ( )
205+ . await
206+ . cloned ( )
187207 }
188208
189209 /// Connect to the Host rpc provider.
@@ -245,9 +265,9 @@ impl BuilderConfig {
245265 }
246266
247267 /// Create an [`EnvTask`] using this config.
248- pub fn env_task ( & self ) -> EnvTask {
249- let ru_provider = self . connect_ru_provider ( ) ;
250- EnvTask :: new ( self . clone ( ) , ru_provider)
268+ pub async fn env_task ( & self ) -> eyre :: Result < EnvTask > {
269+ let ru_provider = self . connect_ru_provider ( ) . await ? ;
270+ Ok ( EnvTask :: new ( self . clone ( ) , ru_provider) )
251271 }
252272
253273 /// Create a [`SignetCfgEnv`] using this config.
0 commit comments