use crate::OrderSubmitter;
use alloy::signers::Signer;
use signet_constants::SignetSystemConstants;
use signet_types::{SignedOrder, SigningError, UnsignedOrder};
use signet_zenith::RollupOrders::Order;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum OrderSenderError {
#[error("failed to sign order: {0}")]
Signing(#[from] SigningError),
#[error("failed to submit order: {0}")]
Submission(#[source] Box<dyn core::error::Error + Send + Sync>),
}
#[derive(Debug, Clone)]
pub struct OrderSender<Sign, Submit> {
signer: Sign,
submitter: Submit,
constants: SignetSystemConstants,
}
impl<Sign, Submit> OrderSender<Sign, Submit> {
pub const fn new(signer: Sign, submitter: Submit, constants: SignetSystemConstants) -> Self {
Self { signer, submitter, constants }
}
pub const fn signer(&self) -> &Sign {
&self.signer
}
pub const fn submitter(&self) -> &Submit {
&self.submitter
}
pub const fn constants(&self) -> &SignetSystemConstants {
&self.constants
}
}
impl<Sign, Submit> OrderSender<Sign, Submit>
where
Sign: Signer,
{
pub async fn sign_order(&self, order: &Order) -> Result<SignedOrder, OrderSenderError>
where
Submit: OrderSubmitter,
{
self.sign_unsigned_order(UnsignedOrder::from(order)).await
}
pub async fn sign_unsigned_order(
&self,
order: UnsignedOrder<'_>,
) -> Result<SignedOrder, OrderSenderError>
where
Submit: OrderSubmitter,
{
order.with_chain(&self.constants).sign(&self.signer).await.map_err(Into::into)
}
}
impl<Sign, Submit> OrderSender<Sign, Submit>
where
Submit: OrderSubmitter + Send + Sync,
{
pub async fn send_order(&self, order: SignedOrder) -> Result<(), OrderSenderError> {
self.submitter
.submit_order(order)
.await
.map_err(|error| OrderSenderError::Submission(Box::new(error)))
}
}
impl<Sign, Submit> OrderSender<Sign, Submit>
where
Sign: Signer + Send + Sync,
Submit: OrderSubmitter + Send + Sync,
{
pub async fn sign_and_send_order(&self, order: Order) -> Result<SignedOrder, OrderSenderError> {
let signed = self.sign_order(&order).await?;
self.send_order(signed.clone()).await?;
Ok(signed)
}
}