Skip to main content

signet_orders/
order_sender.rs

1use crate::OrderSubmitter;
2use alloy::signers::Signer;
3use signet_constants::SignetSystemConstants;
4use signet_types::{SignedOrder, SigningError, UnsignedOrder};
5use signet_zenith::RollupOrders::Order;
6
7/// Errors returned by [`OrderSender`].
8#[derive(Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum OrderSenderError {
11    /// Order signing failed.
12    #[error("failed to sign order: {0}")]
13    Signing(#[from] SigningError),
14    /// Order submission failed.
15    #[error("failed to submit order: {0}")]
16    Submission(#[source] Box<dyn core::error::Error + Send + Sync>),
17}
18
19/// Sends signed orders to a backend.
20///
21/// `OrderSender` is generic over:
22/// - `Sign`: A [`Signer`] for signing orders
23/// - `Submit`: An [`OrderSubmitter`] for submitting signed orders to a backend
24#[derive(Debug, Clone)]
25pub struct OrderSender<Sign, Submit> {
26    signer: Sign,
27    submitter: Submit,
28    constants: SignetSystemConstants,
29}
30
31impl<Sign, Submit> OrderSender<Sign, Submit> {
32    /// Create a new order sender instance.
33    pub const fn new(signer: Sign, submitter: Submit, constants: SignetSystemConstants) -> Self {
34        Self { signer, submitter, constants }
35    }
36
37    /// Get a reference to the signer.
38    pub const fn signer(&self) -> &Sign {
39        &self.signer
40    }
41
42    /// Get a reference to the submitter.
43    pub const fn submitter(&self) -> &Submit {
44        &self.submitter
45    }
46
47    /// Get a reference to the system constants.
48    pub const fn constants(&self) -> &SignetSystemConstants {
49        &self.constants
50    }
51}
52
53impl<Sign, Submit> OrderSender<Sign, Submit>
54where
55    Sign: Signer,
56{
57    /// Sign an [`Order`] and return a [`SignedOrder`].
58    pub async fn sign_order(&self, order: &Order) -> Result<SignedOrder, OrderSenderError>
59    where
60        Submit: OrderSubmitter,
61    {
62        self.sign_unsigned_order(UnsignedOrder::from(order)).await
63    }
64
65    /// Sign an [`UnsignedOrder`] and return a [`SignedOrder`].
66    pub async fn sign_unsigned_order(
67        &self,
68        order: UnsignedOrder<'_>,
69    ) -> Result<SignedOrder, OrderSenderError>
70    where
71        Submit: OrderSubmitter,
72    {
73        order.with_chain(&self.constants).sign(&self.signer).await.map_err(Into::into)
74    }
75}
76
77impl<Sign, Submit> OrderSender<Sign, Submit>
78where
79    Submit: OrderSubmitter + Send + Sync,
80{
81    /// Submit a signed order to the backend.
82    pub async fn send_order(&self, order: SignedOrder) -> Result<(), OrderSenderError> {
83        self.submitter
84            .submit_order(order)
85            .await
86            .map_err(|error| OrderSenderError::Submission(Box::new(error)))
87    }
88}
89
90impl<Sign, Submit> OrderSender<Sign, Submit>
91where
92    Sign: Signer + Send + Sync,
93    Submit: OrderSubmitter + Send + Sync,
94{
95    /// Sign and submit an order to the backend, returning the signed order.
96    pub async fn sign_and_send_order(&self, order: Order) -> Result<SignedOrder, OrderSenderError> {
97        let signed = self.sign_order(&order).await?;
98        self.send_order(signed.clone()).await?;
99        Ok(signed)
100    }
101}