alloy_provider/ext/mev/
mod.rs

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