Onchain.MEV (onchain v0.7.0)

Copy Markdown View Source

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

FunctionPurpose
send_private_transaction/2Submit one signed tx privately → tx hash
send_bundle/2Submit 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 :message key; relay-level JSON-RPC rejections also carry :code.

API Functions

FunctionArityDescriptionParam Kinds
send_bundle2Submit an atomic bundle of signed transactions via a Flashbots-style relay.raw_txs: exchange_data, opts: value
send_private_transaction2Submit 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

send_bundle(raw_txs, opts \\ [])

@spec send_bundle(
  [String.t()],
  keyword()
) :: {:ok, term()} | {:error, term()}

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.

send_private_transaction(raw_tx, opts \\ [])

@spec send_private_transaction(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}

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.