diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 3ba8741c..74eda5cf 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -121,3 +121,26 @@ pub fn maybe_await(expr: TokenStream) -> TokenStream { quoted.into() } + +/// Awaits if target_arch is "wasm32", uses `tokio::Runtime::block_on()` otherwise +/// +/// Requires the `tokio` crate as a dependecy with `rt-core` or `rt-threaded` to build on non-wasm32 platforms. +#[proc_macro] +pub fn await_or_block(expr: TokenStream) -> TokenStream { + let expr: proc_macro2::TokenStream = expr.into(); + let quoted = quote! { + { + #[cfg(all(not(target_arch = "wasm32"), not(feature = "async-interface")))] + { + tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(#expr) + } + + #[cfg(any(target_arch = "wasm32", feature = "async-interface"))] + { + #expr.await + } + } + }; + + quoted.into() +} diff --git a/src/blockchain/esplora/reqwest.rs b/src/blockchain/esplora/reqwest.rs index 056c3913..df3132da 100644 --- a/src/blockchain/esplora/reqwest.rs +++ b/src/blockchain/esplora/reqwest.rs @@ -106,19 +106,19 @@ impl Blockchain for EsploraBlockchain { } fn get_tx(&self, txid: &Txid) -> Result, Error> { - Ok(self.url_client._get_tx(txid).await?) + Ok(await_or_block!(self.url_client._get_tx(txid))?) } fn broadcast(&self, tx: &Transaction) -> Result<(), Error> { - Ok(self.url_client._broadcast(tx).await?) + Ok(await_or_block!(self.url_client._broadcast(tx))?) } fn get_height(&self) -> Result { - Ok(self.url_client._get_height().await?) + Ok(await_or_block!(self.url_client._get_height())?) } fn estimate_fee(&self, target: usize) -> Result { - let estimates = self.url_client._get_fee_estimates().await?; + let estimates = await_or_block!(self.url_client._get_fee_estimates())?; super::into_fee_rate(target, estimates) } } @@ -287,10 +287,10 @@ impl ElectrumLikeSync for UrlClient { for script in chunk { futs.push(self._script_get_history(script)); } - let partial_results: Vec> = futs.try_collect().await?; + let partial_results: Vec> = await_or_block!(futs.try_collect())?; results.extend(partial_results); } - Ok(stream::iter(results).collect().await) + Ok(await_or_block!(stream::iter(results).collect())) } fn els_batch_transaction_get<'s, I: IntoIterator>( @@ -303,10 +303,10 @@ impl ElectrumLikeSync for UrlClient { for txid in chunk { futs.push(self._get_tx_no_opt(txid)); } - let partial_results: Vec = futs.try_collect().await?; + let partial_results: Vec = await_or_block!(futs.try_collect())?; results.extend(partial_results); } - Ok(stream::iter(results).collect().await) + Ok(await_or_block!(stream::iter(results).collect())) } fn els_batch_block_header>( @@ -319,10 +319,10 @@ impl ElectrumLikeSync for UrlClient { for height in chunk { futs.push(self._get_header(height)); } - let partial_results: Vec = futs.try_collect().await?; + let partial_results: Vec = await_or_block!(futs.try_collect())?; results.extend(partial_results); } - Ok(stream::iter(results).collect().await) + Ok(await_or_block!(stream::iter(results).collect())) } }