alloy_provider/ext/
erc4337.rsuse crate::Provider;
use alloy_network::Network;
use alloy_primitives::{Address, Bytes};
use alloy_rpc_types_eth::erc4337::{
SendUserOperation, SendUserOperationResponse, UserOperationGasEstimation, UserOperationReceipt,
};
use alloy_transport::{Transport, TransportResult};
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait Erc4337Api<N, T>: Send + Sync {
async fn send_user_operation(
&self,
user_op: SendUserOperation,
entry_point: Address,
) -> TransportResult<SendUserOperationResponse>;
async fn supported_entry_points(&self) -> TransportResult<Vec<Address>>;
async fn get_user_operation_receipt(
&self,
user_op_hash: Bytes,
) -> TransportResult<UserOperationReceipt>;
async fn estimate_user_operation_gas(
&self,
user_op: SendUserOperation,
entry_point: Address,
) -> TransportResult<UserOperationGasEstimation>;
}
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl<N, T, P> Erc4337Api<N, T> for P
where
N: Network,
T: Transport + Clone,
P: Provider<T, N>,
{
async fn send_user_operation(
&self,
user_op: SendUserOperation,
entry_point: Address,
) -> TransportResult<SendUserOperationResponse> {
match user_op {
SendUserOperation::EntryPointV06(user_op) => {
self.client().request("eth_sendUserOperation", (user_op, entry_point)).await
}
SendUserOperation::EntryPointV07(packed_user_op) => {
self.client().request("eth_sendUserOperation", (packed_user_op, entry_point)).await
}
}
}
async fn supported_entry_points(&self) -> TransportResult<Vec<Address>> {
self.client().request("eth_supportedEntryPoints", ()).await
}
async fn get_user_operation_receipt(
&self,
user_op_hash: Bytes,
) -> TransportResult<UserOperationReceipt> {
self.client().request("eth_getUserOperationReceipt", (user_op_hash,)).await
}
async fn estimate_user_operation_gas(
&self,
user_op: SendUserOperation,
entry_point: Address,
) -> TransportResult<UserOperationGasEstimation> {
match user_op {
SendUserOperation::EntryPointV06(user_op) => {
self.client().request("eth_estimateUserOperationGas", (user_op, entry_point)).await
}
SendUserOperation::EntryPointV07(packed_user_op) => {
self.client()
.request("eth_estimateUserOperationGas", (packed_user_op, entry_point))
.await
}
}
}
}