alloy_provider/provider/eth_call/
caller.rs

1use super::{EthCallManyParams, EthCallParams};
2use crate::ProviderCall;
3use alloy_json_rpc::{RpcRecv, RpcSend};
4use alloy_network::Network;
5use alloy_rpc_client::WeakClient;
6use alloy_transport::{TransportErrorKind, TransportResult};
7
8/// Trait that helpes convert `EthCall` into a `ProviderCall`.
9pub trait Caller<N, Resp>: Send + Sync
10where
11    N: Network,
12    Resp: RpcRecv,
13{
14    /// Method that needs to be implemented to convert to a `ProviderCall`.
15    ///
16    /// This method sends the request to relevant data source and returns a `ProviderCall`.
17    fn call(
18        &self,
19        params: EthCallParams<N>,
20    ) -> TransportResult<ProviderCall<EthCallParams<N>, Resp>>;
21
22    /// Method that needs to be implemented for estimating gas using "eth_estimateGas" for the
23    /// transaction.
24    fn estimate_gas(
25        &self,
26        params: EthCallParams<N>,
27    ) -> TransportResult<ProviderCall<EthCallParams<N>, Resp>>;
28
29    /// Method that needs to be implemented for `"eth_callMany"` RPC requests.
30    fn call_many(
31        &self,
32        params: EthCallManyParams<'_>,
33    ) -> TransportResult<ProviderCall<EthCallManyParams<'static>, Resp>>;
34}
35
36impl<N, Resp> Caller<N, Resp> for WeakClient
37where
38    N: Network,
39    Resp: RpcRecv,
40{
41    fn call(
42        &self,
43        params: EthCallParams<N>,
44    ) -> TransportResult<ProviderCall<EthCallParams<N>, Resp>> {
45        provider_rpc_call(self, "eth_call", params)
46    }
47
48    fn estimate_gas(
49        &self,
50        params: EthCallParams<N>,
51    ) -> TransportResult<ProviderCall<EthCallParams<N>, Resp>> {
52        provider_rpc_call(self, "eth_estimateGas", params)
53    }
54
55    fn call_many(
56        &self,
57        params: EthCallManyParams<'_>,
58    ) -> TransportResult<ProviderCall<EthCallManyParams<'static>, Resp>> {
59        provider_rpc_call(self, "eth_callMany", params.into_owned())
60    }
61}
62
63/// Returns a [`ProviderCall::RpcCall`] from the provided method and [`EthCallParams`].
64fn provider_rpc_call<Req: RpcSend, Resp: RpcRecv>(
65    client: &WeakClient,
66    method: &'static str,
67    params: Req,
68) -> TransportResult<ProviderCall<Req, Resp>> {
69    let client = client.upgrade().ok_or_else(TransportErrorKind::backend_gone)?;
70    let rpc_call = client.request(method, params);
71    Ok(ProviderCall::RpcCall(rpc_call))
72}