MEV protection via private transaction submission to Flashbots-style relays.
Routes signed transactions (or atomic bundles) to a private relay endpoint
instead of the public mempool, preventing front-running and sandwiching of
DEX trades. The request envelope follows the Flashbots Auction JSON-RPC API
(eth_sendPrivateTransaction, eth_sendBundle) — see
https://docs.flashbots.net/flashbots-auction/advanced/rpc-endpoint.
Endpoint and auth are caller-supplied
Unlike Onchain.RPC, there is no fallback to the configured public node.
Silently leaking a would-be-private transaction to the public RPC defeats the
entire purpose, so the relay URL is a required :endpoint option — omitting it
returns {:error, :missing_endpoint} rather than broadcasting.
Relay authentication (Flashbots requires an X-Flashbots-Signature: <addr>:<sig>
header signed with an arbitrary secp256k1 reputation key) is not computed
here. The caller passes whatever headers the relay needs via :headers, e.g.
Onchain.MEV.send_bundle(txs,
endpoint: "https://relay.flashbots.net",
block_number: 19_000_000,
headers: [{"X-Flashbots-Signature", "0xabc...:0xsig..."}]
)Functions
| Function | Purpose |
|---|---|
send_private_transaction/2 | Submit one signed tx privately → tx hash |
send_bundle/2 | Submit an atomic bundle of signed txs → bundle response |
Options
:endpoint— relay URL (required, no default):headers— extra request headers for relay auth (e.g.X-Flashbots-Signature):timeout— request timeout in ms (default 30_000):max_block_number— (private tx) highest block the tx may be included in:preferences— (private tx) MEV-Share preferences map, passed through verbatim:block_number— (bundle) target block (required for bundles):min_timestamp/:max_timestamp— (bundle) validity window in unix seconds:reverting_tx_hashes— (bundle) tx hashes allowed to revert
Error Format
- Missing relay URL:
{:error, :missing_endpoint} - Invalid relay URL:
{:error, {:invalid_endpoint, input}} - Invalid signed tx hex:
{:error, {:invalid_data, input}} - Empty bundle:
{:error, :empty_bundle} - Non-list bundle:
{:error, {:invalid_bundle, input}} - Bundle missing target block:
{:error, :missing_block_number} - Invalid block value:
{:error, {:invalid_block, input}} - Relay / transport errors:
{:error, {:rpc_error, map}}— the map always has a:messagekey; relay-level JSON-RPC rejections also carry:code.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
send_bundle | 2 | Submit an atomic bundle of signed transactions via a Flashbots-style relay. | raw_txs: exchange_data, opts: value |
send_private_transaction | 2 | Submit a signed transaction privately via a Flashbots-style relay. | raw_tx: exchange_data, opts: value |
Summary
Functions
Submit an atomic bundle of signed transactions to a private relay (eth_sendBundle).
Submit a single signed transaction to a private relay (eth_sendPrivateTransaction).
Functions
Submit an atomic bundle of signed transactions to a private relay (eth_sendBundle).
Requires both :endpoint (relay URL) and :block_number (target block); the
bundle is only valid for that block. See the module docs for the full option list.
Submit a single signed transaction to a private relay (eth_sendPrivateTransaction).
Requires the :endpoint option (the relay URL); see the module docs for the
full option list and why there is no public-node fallback.