alloy_provider/ext/mev/
mod.rs

1mod with_auth;
2
3pub use self::with_auth::{
4    sign_flashbots_payload, verify_flashbots_signature, FlashbotsSignatureError, MevBuilder,
5};
6use crate::Provider;
7use alloy_network::Network;
8use alloy_primitives::{hex, TxHash};
9use alloy_rpc_types_mev::{
10    EthBundleHash, EthCallBundle, EthCallBundleResponse, EthCancelBundle,
11    EthCancelPrivateTransaction, EthSendBlobs, EthSendBundle, EthSendEndOfBlockBundle,
12    EthSendPrivateTransaction, MevSendBundle, PrivateTransactionPreferences,
13};
14
15/// The HTTP header used for Flashbots signature authentication.
16pub const FLASHBOTS_SIGNATURE_HEADER: &str = "x-flashbots-signature";
17
18/// This module provides support for interacting with non-standard MEV-related RPC endpoints.
19///
20/// # Important Notes
21///
22/// MEV operations are extremely time-sensitive and should be executed as quickly as possible.
23/// Bundle submissions have strict timing requirements and may fail if submitted too late.
24///
25/// ## Common Limitations
26///
27/// - Bundle size limits vary by relay (typically 1-10 transactions)
28/// - Timeout constraints apply to simulation and execution
29/// - Rate limiting may be enforced by MEV relays
30/// - Authentication is required for most operations
31///
32/// See [Flashbots documentation](https://docs.flashbots.net/flashbots-auction/searchers/advanced/rpc-endpoint) for detailed limitations.
33#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
34#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
35pub trait MevApi<N>: Send + Sync {
36    /// Simulates a bundle of transactions using the `eth_callBundle` RPC method.
37    fn call_bundle(
38        &self,
39        bundle: EthCallBundle,
40    ) -> MevBuilder<(EthCallBundle,), Option<EthCallBundleResponse>>;
41
42    /// Sends a MEV bundle using the `eth_sendBundle` RPC method.
43    /// Returns the resulting bundle hash on success.
44    ///
45    /// # Timing Critical
46    ///
47    /// Bundle submission is extremely time-sensitive. Submit as early as possible
48    /// in the block interval to maximize inclusion probability.
49    fn send_bundle(
50        &self,
51        bundle: EthSendBundle,
52    ) -> MevBuilder<(EthSendBundle,), Option<EthBundleHash>>;
53
54    /// Cancels a previously sent MEV bundle using the `eth_cancelBundle` RPC method.
55    fn cancel_bundle(&self, replacement_uuid: String) -> MevBuilder<(EthCancelBundle,), ()>;
56
57    /// Sends blob transaction permutations using the `eth_sendBlobs` RPC method.
58    fn send_blobs(&self, blobs: EthSendBlobs) -> MevBuilder<(EthSendBlobs,), ()>;
59
60    /// Sends a private transaction using the `eth_sendPrivateTransaction` RPC method.
61    fn send_private_transaction(
62        &self,
63        private_tx: EthSendPrivateTransaction,
64    ) -> MevBuilder<(EthSendPrivateTransaction,), Option<TxHash>>;
65
66    /// Sends a private transaction using the `eth_sendPrivateRawTransaction` RPC method.
67    fn send_private_raw_transaction(
68        &self,
69        encoded_tx: &[u8],
70        preferences: Option<PrivateTransactionPreferences>,
71    ) -> MevBuilder<(String, Option<PrivateTransactionPreferences>), Option<TxHash>>;
72
73    /// Cancels a previously sent private transaction using the `eth_cancelPrivateTransaction` RPC
74    /// method.
75    fn cancel_private_transaction(
76        &self,
77        tx_hash: TxHash,
78    ) -> MevBuilder<(EthCancelPrivateTransaction,), bool>;
79
80    /// Sends end-of-block bundle using the `eth_sendEndOfBlockBundle` RPC method.
81    /// Returns the resulting bundle hash on success.
82    fn send_end_of_block_bundle(
83        &self,
84        bundle: EthSendEndOfBlockBundle,
85    ) -> MevBuilder<(EthSendEndOfBlockBundle,), Option<EthBundleHash>>;
86
87    /// Sends a MEV bundle using the `mev_sendBundle` RPC method.
88    /// Returns the resulting bundle hash on success.
89    ///
90    /// # Timing Critical
91    ///
92    /// Bundle submission is extremely time-sensitive. Submit as early as possible
93    /// in the block interval to maximize inclusion probability.
94    fn send_mev_bundle(
95        &self,
96        bundle: MevSendBundle,
97    ) -> MevBuilder<(MevSendBundle,), Option<EthBundleHash>>;
98}
99
100#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
101#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
102impl<N, P> MevApi<N> for P
103where
104    N: Network,
105    P: Provider<N>,
106{
107    fn call_bundle(
108        &self,
109        bundle: EthCallBundle,
110    ) -> MevBuilder<(EthCallBundle,), Option<EthCallBundleResponse>> {
111        MevBuilder::new_rpc(self.client().request("eth_callBundle", (bundle,)))
112    }
113
114    fn send_bundle(
115        &self,
116        bundle: EthSendBundle,
117    ) -> MevBuilder<(EthSendBundle,), Option<EthBundleHash>> {
118        MevBuilder::new_rpc(self.client().request("eth_sendBundle", (bundle,)))
119    }
120
121    fn cancel_bundle(&self, replacement_uuid: String) -> MevBuilder<(EthCancelBundle,), ()> {
122        MevBuilder::new_rpc(
123            self.client().request("eth_cancelBundle", (EthCancelBundle { replacement_uuid },)),
124        )
125    }
126
127    fn send_blobs(&self, blobs: EthSendBlobs) -> MevBuilder<(EthSendBlobs,), ()> {
128        MevBuilder::new_rpc(self.client().request("eth_sendBlobs", (blobs,)))
129    }
130
131    fn send_private_transaction(
132        &self,
133        private_tx: EthSendPrivateTransaction,
134    ) -> MevBuilder<(EthSendPrivateTransaction,), Option<TxHash>> {
135        MevBuilder::new_rpc(self.client().request("eth_sendPrivateTransaction", (private_tx,)))
136    }
137
138    fn send_private_raw_transaction(
139        &self,
140        encoded_tx: &[u8],
141        preferences: Option<PrivateTransactionPreferences>,
142    ) -> MevBuilder<(String, Option<PrivateTransactionPreferences>), Option<TxHash>> {
143        let rlp_hex = hex::encode_prefixed(encoded_tx);
144        MevBuilder::new_rpc(
145            self.client().request("eth_sendPrivateRawTransaction", (rlp_hex, preferences)),
146        )
147    }
148
149    fn cancel_private_transaction(
150        &self,
151        tx_hash: TxHash,
152    ) -> MevBuilder<(EthCancelPrivateTransaction,), bool> {
153        MevBuilder::new_rpc(
154            self.client().request(
155                "eth_cancelPrivateTransaction",
156                (EthCancelPrivateTransaction { tx_hash },),
157            ),
158        )
159    }
160
161    fn send_end_of_block_bundle(
162        &self,
163        bundle: EthSendEndOfBlockBundle,
164    ) -> MevBuilder<(EthSendEndOfBlockBundle,), Option<EthBundleHash>> {
165        MevBuilder::new_rpc(self.client().request("eth_sendEndOfBlockBundle", (bundle,)))
166    }
167
168    fn send_mev_bundle(
169        &self,
170        bundle: MevSendBundle,
171    ) -> MevBuilder<(MevSendBundle,), Option<EthBundleHash>> {
172        MevBuilder::new_rpc(self.client().request("mev_sendBundle", (bundle,)))
173    }
174}