macro_rules! robust_rpc {
(
$(doc_include_error = [$($error_doc:tt)+])?
$(doc_args = [$(($arg_name:ident, $arg_desc:literal)),* $(,)?])?
$(doc_alias = $alias:tt)?
fn $method:ident $(<$($generic:ident $(: $bound:path)?),+ $(,)?>)? ($($($arg:ident: $arg_ty:ty),+ $(,)?)?) -> $ret:ty $(; or $err:ident)?
$(where $($where_ty:ty: $where_bound:path),+ $(,)?)?
) => {
#[doc = concat!("This is a wrapper function for [`Provider::", stringify!($method), "`].")]
$($(
///
/// # Arguments
///
#[doc = concat!("* `", stringify!($arg_name), "` - ", $arg_desc)]
)*)?
$(
#[doc = $($error_doc)+]
)?
$(
#[doc(alias = $alias)]
)?
pub async fn $method $(<$($generic $(: $bound)?),+>)? (&self $(, $($arg: $arg_ty),+)?) -> Result<$ret, Error>
$(where $($where_ty: $where_bound),+)?
{
let result = self
.try_operation_with_failover(
move |provider| async move {
// Call the provider method with turbofish syntax if generics are present
provider.$method $(::<$($generic),+>)? ($($($arg),+)?).await
},
)
.await;
robust_rpc!(@unwrap result $(, $err)?)
}
};
(
$(#[doc = $doc:literal])* $(doc_include_error = [$($error_doc:tt)+])?
$(doc_args = [$(($arg_name:ident, $arg_desc:literal)),* $(,)?])?
$(doc_alias = $alias:tt)?
@clone [$($clone_arg:ident),+ $(,)?] fn $method:ident $(<$($generic:ident $(: $bound:path)?),+ $(,)?>)? (
$($arg:ident: $arg_ty:ty),+ $(,)?
) -> $ret:ty
$(where $($where_ty:ty: $where_bound:path),+ $(,)?)?
$(; or $err:ident)?
) => {
$(#[doc = $doc])*
#[doc = concat!("This is a wrapper function for [`Provider::", stringify!($method), "`].")]
$($(
#[doc = concat!("* `", stringify!($arg_name), "` - ", $arg_desc)]
)*)?
$(
#[doc = $($error_doc)+]
)?
$(
#[doc(alias = $alias)]
)?
pub async fn $method $(<$($generic $(: $bound)?),+>)? (&self, $($arg: $arg_ty),+) -> Result<$ret, Error>
$(where $($where_ty: $where_bound),+)?
{
let result = self
.try_operation_with_failover(
move |provider| {
$(let $clone_arg = $clone_arg.clone();)+
async move {
provider.$method $(::<$($generic),+>)? ($($arg),+).await
}
},
)
.await;
robust_rpc!(@unwrap result $(, $err)?)
}
};
(@unwrap $result:expr) => {
$result.map_err(Error::from)
};
(@unwrap $result:expr, $err:ident) => {
$result?.ok_or(Error::$err)
};
}
#[macro_export]
macro_rules! block_not_found_doc {
() => { "* [`Error::BlockNotFound`] - if the block is not available. This is verified on Anvil, Reth, and Geth; other clients may surface this condition as [`Error::RpcError`]." };
}