pub struct BundleRequest { /* private fields */ }
Expand description

A bundle that can be submitted to a Flashbots relay.

The bundle can include your own transactions and transactions from the mempool.

Additionally, this bundle can be simulated through a relay if simulation parameters are provided using BundleRequest::set_simulation_block and BundleRequest::set_simulation_timestamp.

Please note that some parameters are required, and submitting a bundle without them will get it rejected pre-flight. The required parameters include:

Implementations§

Creates an empty bundle request.

Examples found in repository?
src/middleware.rs (line 269)
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    async fn send_raw_transaction<'a>(
        &'a self,
        tx: Bytes,
    ) -> Result<PendingTransaction<'a, Self::Provider>, Self::Error> {
        let tx_hash = keccak256(&tx);

        // Get the latest block
        let latest_block = self
            .inner
            .get_block(BlockNumber::Latest)
            .await
            .map_err(FlashbotsMiddlewareError::MiddlewareError)?
            .expect("The latest block is pending (this should not happen)");

        // Construct the bundle, assuming that the target block is the
        // next block.
        let bundle = BundleRequest::new().push_transaction(tx.clone()).set_block(
            latest_block
                .number
                .expect("The latest block is pending (this should not happen)")
                + 1,
        );

        self.send_bundle(&bundle).await?;

        Ok(PendingTransaction::new(tx_hash.into(), self.provider())
            .interval(self.provider().get_interval()))
    }

Adds a transaction to the bundle request.

Transactions added to the bundle can either be novel transactions, i.e. transactions that you have crafted, or they can be from one of the mempool APIs.

Examples found in repository?
src/middleware.rs (line 269)
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    async fn send_raw_transaction<'a>(
        &'a self,
        tx: Bytes,
    ) -> Result<PendingTransaction<'a, Self::Provider>, Self::Error> {
        let tx_hash = keccak256(&tx);

        // Get the latest block
        let latest_block = self
            .inner
            .get_block(BlockNumber::Latest)
            .await
            .map_err(FlashbotsMiddlewareError::MiddlewareError)?
            .expect("The latest block is pending (this should not happen)");

        // Construct the bundle, assuming that the target block is the
        // next block.
        let bundle = BundleRequest::new().push_transaction(tx.clone()).set_block(
            latest_block
                .number
                .expect("The latest block is pending (this should not happen)")
                + 1,
        );

        self.send_bundle(&bundle).await?;

        Ok(PendingTransaction::new(tx_hash.into(), self.provider())
            .interval(self.provider().get_interval()))
    }

Adds a revertible transaction to the bundle request.

This differs from BundleRequest::push_transaction in that the bundle will still be considered valid if the transaction reverts.

Get a reference to the transactions currently in the bundle request.

Get a list of transaction hashes in the bundle request.

Examples found in repository?
src/middleware.rs (line 193)
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    pub async fn send_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<PendingBundle<'_, <Self as Middleware>::Provider>, FlashbotsMiddlewareError<M, S>>
    {
        // The target block must be set
        bundle
            .block()
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        // `min_timestamp` and `max_timestamp` must both either be unset or set.
        if bundle.min_timestamp().xor(bundle.max_timestamp()).is_some() {
            return Err(FlashbotsMiddlewareError::MissingParameters);
        }

        let response: SendBundleResponse = self
            .relay
            .request("eth_sendBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)?;

        Ok(PendingBundle::new(
            response.bundle_hash,
            bundle.block().unwrap(),
            bundle.transaction_hashes(),
            self.provider(),
        ))
    }

Get the target block (if any).

Examples found in repository?
src/middleware.rs (line 151)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    pub async fn simulate_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<SimulatedBundle, FlashbotsMiddlewareError<M, S>> {
        bundle
            .block()
            .and(bundle.simulation_block())
            .and(bundle.simulation_timestamp())
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        self.simulation_relay
            .as_ref()
            .unwrap_or(&self.relay)
            .request("eth_callBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)
    }

    /// Send a bundle to the relayer.
    ///
    /// See [`eth_sendBundle`][fb_sendBundle] for more information.
    ///
    /// [fb_sendBundle]: https://docs.flashbots.net/flashbots-auction/searchers/advanced/rpc-endpoint#eth_sendbundle
    pub async fn send_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<PendingBundle<'_, <Self as Middleware>::Provider>, FlashbotsMiddlewareError<M, S>>
    {
        // The target block must be set
        bundle
            .block()
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        // `min_timestamp` and `max_timestamp` must both either be unset or set.
        if bundle.min_timestamp().xor(bundle.max_timestamp()).is_some() {
            return Err(FlashbotsMiddlewareError::MissingParameters);
        }

        let response: SendBundleResponse = self
            .relay
            .request("eth_sendBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)?;

        Ok(PendingBundle::new(
            response.bundle_hash,
            bundle.block().unwrap(),
            bundle.transaction_hashes(),
            self.provider(),
        ))
    }

Set the target block of the bundle.

Examples found in repository?
src/middleware.rs (lines 269-274)
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    async fn send_raw_transaction<'a>(
        &'a self,
        tx: Bytes,
    ) -> Result<PendingTransaction<'a, Self::Provider>, Self::Error> {
        let tx_hash = keccak256(&tx);

        // Get the latest block
        let latest_block = self
            .inner
            .get_block(BlockNumber::Latest)
            .await
            .map_err(FlashbotsMiddlewareError::MiddlewareError)?
            .expect("The latest block is pending (this should not happen)");

        // Construct the bundle, assuming that the target block is the
        // next block.
        let bundle = BundleRequest::new().push_transaction(tx.clone()).set_block(
            latest_block
                .number
                .expect("The latest block is pending (this should not happen)")
                + 1,
        );

        self.send_bundle(&bundle).await?;

        Ok(PendingTransaction::new(tx_hash.into(), self.provider())
            .interval(self.provider().get_interval()))
    }

Get the block that determines the state for bundle simulation (if any).

See eth_callBundle in the Flashbots documentation for more information on bundle simulations.

Examples found in repository?
src/middleware.rs (line 152)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    pub async fn simulate_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<SimulatedBundle, FlashbotsMiddlewareError<M, S>> {
        bundle
            .block()
            .and(bundle.simulation_block())
            .and(bundle.simulation_timestamp())
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        self.simulation_relay
            .as_ref()
            .unwrap_or(&self.relay)
            .request("eth_callBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)
    }

Set the block that determines the state for bundle simulation.

Get the UNIX timestamp used for bundle simulation (if any).

See eth_callBundle in the Flashbots documentation for more information on bundle simulations.

Examples found in repository?
src/middleware.rs (line 153)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    pub async fn simulate_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<SimulatedBundle, FlashbotsMiddlewareError<M, S>> {
        bundle
            .block()
            .and(bundle.simulation_block())
            .and(bundle.simulation_timestamp())
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        self.simulation_relay
            .as_ref()
            .unwrap_or(&self.relay)
            .request("eth_callBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)
    }

Set the UNIX timestamp used for bundle simulation.

Get the base gas fee for bundle simulation (if any).

See eth_callBundle in the Flashbots documentation for more information on bundle simulations.

Set the base gas fee for bundle simulation (if any). Optional: will default to a value chosen by the node if not specified.

Get the minimum timestamp for which this bundle is valid (if any), in seconds since the UNIX epoch.

Examples found in repository?
src/middleware.rs (line 180)
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    pub async fn send_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<PendingBundle<'_, <Self as Middleware>::Provider>, FlashbotsMiddlewareError<M, S>>
    {
        // The target block must be set
        bundle
            .block()
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        // `min_timestamp` and `max_timestamp` must both either be unset or set.
        if bundle.min_timestamp().xor(bundle.max_timestamp()).is_some() {
            return Err(FlashbotsMiddlewareError::MissingParameters);
        }

        let response: SendBundleResponse = self
            .relay
            .request("eth_sendBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)?;

        Ok(PendingBundle::new(
            response.bundle_hash,
            bundle.block().unwrap(),
            bundle.transaction_hashes(),
            self.provider(),
        ))
    }

Set the minimum timestamp for which this bundle is valid (if any), in seconds since the UNIX epoch.

Get the maximum timestamp for which this bundle is valid (if any), in seconds since the UNIX epoch.

Examples found in repository?
src/middleware.rs (line 180)
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    pub async fn send_bundle(
        &self,
        bundle: &BundleRequest,
    ) -> Result<PendingBundle<'_, <Self as Middleware>::Provider>, FlashbotsMiddlewareError<M, S>>
    {
        // The target block must be set
        bundle
            .block()
            .ok_or(FlashbotsMiddlewareError::MissingParameters)?;

        // `min_timestamp` and `max_timestamp` must both either be unset or set.
        if bundle.min_timestamp().xor(bundle.max_timestamp()).is_some() {
            return Err(FlashbotsMiddlewareError::MissingParameters);
        }

        let response: SendBundleResponse = self
            .relay
            .request("eth_sendBundle", [bundle])
            .await
            .map_err(FlashbotsMiddlewareError::RelayError)?;

        Ok(PendingBundle::new(
            response.bundle_hash,
            bundle.block().unwrap(),
            bundle.transaction_hashes(),
            self.provider(),
        ))
    }

Set the maximum timestamp for which this bundle is valid (if any), in seconds since the UNIX epoch.

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
Should always be Self
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more