use alloy_eips::BlockId;
use alloy_network::Network;
use alloy_rpc_types_eth::{
state::StateOverride, BlockOverrides, Bundle, StateContext, TransactionIndex,
};
use serde::ser::SerializeSeq;
use std::borrow::Cow;
#[derive(Clone, Debug)]
pub struct EthCallParams<N: Network> {
data: N::TransactionRequest,
pub(crate) block: Option<BlockId>,
pub(crate) overrides: Option<StateOverride>,
pub(crate) block_overrides: Option<BlockOverrides>,
}
impl<N> EthCallParams<N>
where
N: Network,
{
pub const fn new(data: N::TransactionRequest) -> Self {
Self { data, block: None, overrides: None, block_overrides: None }
}
pub const fn with_block(mut self, block: BlockId) -> Self {
self.block = Some(block);
self
}
pub fn with_overrides(mut self, overrides: StateOverride) -> Self {
self.overrides = Some(overrides);
self
}
pub fn with_overrides_opt(mut self, overrides: Option<StateOverride>) -> Self {
self.overrides = overrides;
self
}
pub const fn overrides(&self) -> Option<&StateOverride> {
self.overrides.as_ref()
}
pub const fn data(&self) -> &N::TransactionRequest {
&self.data
}
pub fn into_data(self) -> N::TransactionRequest {
self.data
}
pub const fn block(&self) -> Option<BlockId> {
self.block
}
pub fn with_block_overrides(mut self, overrides: BlockOverrides) -> Self {
self.block_overrides = Some(overrides);
self
}
pub fn with_block_overrides_opt(mut self, overrides: Option<BlockOverrides>) -> Self {
self.block_overrides = overrides;
self
}
pub const fn block_overrides(&self) -> Option<&BlockOverrides> {
self.block_overrides.as_ref()
}
}
impl<N: Network> serde::Serialize for EthCallParams<N> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let len = if self.block_overrides().is_some() {
4
} else if self.overrides().is_some() {
3
} else if self.block().is_some() {
2
} else {
1
};
let mut seq = serializer.serialize_seq(Some(len))?;
seq.serialize_element(&self.data())?;
if let Some(block_overrides) = self.block_overrides() {
seq.serialize_element(&self.block().unwrap_or_default())?;
seq.serialize_element(self.overrides().unwrap_or(&StateOverride::default()))?;
seq.serialize_element(block_overrides)?;
} else if let Some(overrides) = self.overrides() {
seq.serialize_element(&self.block().unwrap_or_default())?;
seq.serialize_element(overrides)?;
} else if let Some(block) = self.block() {
seq.serialize_element(&block)?;
}
seq.end()
}
}
#[derive(Clone, Debug)]
pub struct EthCallManyParams<'req> {
bundles: Cow<'req, [Bundle]>,
context: Option<StateContext>,
overrides: Option<Cow<'req, StateOverride>>,
}
impl<'req> EthCallManyParams<'req> {
pub const fn new(bundles: &'req [Bundle]) -> Self {
Self { bundles: Cow::Borrowed(bundles), context: None, overrides: None }
}
pub fn with_block(mut self, block: BlockId) -> Self {
let mut context = self.context.unwrap_or_default();
context.block_number = Some(block);
self.context = Some(context);
self
}
pub fn with_transaction_index(mut self, tx_index: TransactionIndex) -> Self {
let mut context = self.context.unwrap_or_default();
context.transaction_index = Some(tx_index);
self.context = Some(context);
self
}
pub const fn with_context(mut self, context: StateContext) -> Self {
self.context = Some(context);
self
}
pub fn with_overrides(mut self, overrides: &'req StateOverride) -> Self {
self.overrides = Some(Cow::Borrowed(overrides));
self
}
pub const fn context(&self) -> Option<&StateContext> {
self.context.as_ref()
}
pub fn bundles(&self) -> &[Bundle] {
&self.bundles
}
pub fn bundles_mut(&mut self) -> &mut Vec<Bundle> {
Cow::to_mut(&mut self.bundles)
}
pub fn overrides(&self) -> Option<&StateOverride> {
self.overrides.as_deref()
}
pub fn into_owned(self) -> EthCallManyParams<'static> {
EthCallManyParams {
bundles: Cow::Owned(self.bundles.into_owned()),
context: self.context,
overrides: self.overrides.map(|o| Cow::Owned(o.into_owned())),
}
}
}
impl serde::Serialize for EthCallManyParams<'_> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let len = if self.overrides().is_some() {
3
} else if self.context().is_some() {
2
} else {
1
};
let mut seq = serializer.serialize_seq(Some(len))?;
seq.serialize_element(&self.bundles())?;
if let Some(context) = self.context() {
seq.serialize_element(context)?;
} else if self.overrides().is_some() {
seq.serialize_element(&StateContext::default())?;
}
if let Some(overrides) = self.overrides() {
seq.serialize_element(overrides)?;
}
seq.end()
}
}