Skip to main content

API Reference

Orderflow

BuilderNet provides these APIs to send orderflow:


eth_sendBundle

You can use eth_sendBundle to send a bundle of transactions to BuilderNet. You can also use it to replace or cancel past bundles.

Transactions sent with eth_sendBundle are eligible for refunds.

What is a bundle

A bundle is a list of signed transactions that are executed atomically. If any transaction in the bundle fails, the entire bundle fails. This is useful for sending multiple transactions that depend on each other.

Request

{
"id": 1,
"jsonrpc": "2.0",
"method": "eth_sendBundle",
"params": [{
txs // Array[String], A list of signed transactions to execute in an atomic bundle.
blockNumber // String, A hex encoded block number for which this bundle is valid on.

// Optional fields
replacementUuid // String, UUID that can be used to cancel/replace this bundle.
replacementNonce // String, Used to order bundles sharing the same replacementUuid. Bundles received with a lower replacementNonce than the latest accepted one are ignored.

revertingTxHashes // Array[String], A list of tx hashes that are allowed to revert.
droppingTxHashes // Array[String], A list of tx hashes that can be removed from the bundle if it's deemed useful (but not revert).
refundTxHashes // Array[String], A list of tx hashes (max 1) that should be considered for MEV refunds. If empty, defaults to the last transaction in the bundle.

minTimestamp // Number, The minimum timestamp for which this bundle is valid, in seconds since the unix epoch.
maxTimestamp // Number, The maximum timestamp for which this bundle is valid, in seconds since the unix epoch.

refundPercent // Number (integer between 1-99), How much of the total priority fee + coinbase payment you want to be refunded for.
refundRecipient // String, The address that the funds from refundPercent will be sent to. If not specified, they will be sent to the from address of the first transaction.
delayedRefund // Boolean, If true, `refundPercent` refund is processed asynchronously via BuilderNet refund pipeline rather than in the same block.

refundIdentity // String, Address that BuilderNet refunds should be sent to instead of the bundle signer.
}]
}

Notes:

  • blockNumber can be:
    1. A specific block number, hex encoded (e.g. 0x1361bd3)
    2. For next block only: "0x" or null or missing field
  • uuid is supported as alias for replacementUuid.

Bundle replacement and cancellation:

  • Replacing bundles: Send another bundle with the same replacementUuid , and it will override any previous one.
  • Cancelling bundles: Send another bundle with the same replacementUuid and an empty list of transactions.

MEV Refunds:

When a searcher makes money by using some user tx, it pays the builder to be included in the block. Part of that payment is refunded to the user. To determine how much the searcher paid the builder, we check the delta in the builder's balance before and after executing a particular tx in the bundle. By checking this delta, we are considering gas payments and also explicit transfers from the searcher to the builder.

These refunds should not be confused with Gas Fee Refunds.

  • refundTxHashes field (optional): Specifies which transaction in the bundle should be analyzed to measure the payment to the builder.

    • If present, specifies which transactions in the bundle should be considered for refund calculations.
    • If empty or not specified, defaults to the last transaction in the bundle.
    • Currently limited to a maximum of 1 transaction hash.
  • refundPercent field:

    • (Optional) An integer between 1-99 which defines how much of the total priority fee + coinbase payment you want to be refunded for.
    • Example: If a bundle pays 0.2 ETH of priority fee plus 1 ETH to coinbase, a refundPercent set to 50 will result in a transaction being appended after the bundle, paying 0.59 ETH back to the EOA. This is assuming the payout tx will cost BuilderNet 0.01 ETH in fees, which are deducted from the 0.6 ETH payout.

Response

The response always contains the bundles unique hash which can then be used to query refunds:

{
"id": 1,
"jsonrpc": "2.0",
"result": {
"bundleHash": "0x..."
}
}

Example request

curl https://rpc.buildernet.org \
--header 'Content-Type: application/json' \
--header 'X-Flashbots-Signature: <public key address>:<signature>' \
--data '{
"id": 1,
"jsonrpc": "2.0",
"method": "eth_sendBundle",
"params": [{
"blockNumber": "0x1361bd3",
"txs": [
"0x100000...",
"0x200000..."
]
}]
}'

See this example Golang code for sending a transaction with a signed request and a pinned server certificate.

Request signature and authentication

eth_sendBundle requests require a X-Flashbots-Signature header for authentication and for the signer to receive refunds:

X-Flashbots-Signature: <public_key_address>:<signature>

The signature is calculated by taking the EIP-191 hash of the json body encoded as UTF-8 bytes. Any valid ECDSA secp256k1 key (i.e. any Ethereum key) can be used to sign the payload. The address associated with this key will be used for Redistribution. For more details and examples on signing the payload, see the documentation here.

Instance TLS certificate

The builder node creates a fresh TLS certificate on each startup, of which the private key is guaranteed to stay inside the TEE instance. You can verify the TEE proof for this certificate using the "TEE Proof Validation API". You can also get the certificate with an unattested curl request:

curl -w %{certs} https://rpc.buildernet.org

Example Golang code

See this example Golang code for sending a signed transaction to a builder node. The example code supports requiring a specific TLS certificate as well as skipping certificate validation.

Bundle Hash

The bundle hash is a unique identifier for a specific bundle of transactions sent to BuilderNet.

It is calculated by taking the Keccak-256 hash of the transactions in a bundle:

// Compute keccak hash over the bundle transactions
hasher := sha3.NewLegacyKeccak256()
for _, rawTx := range b.Txs {
var tx types.Transaction
if err := tx.UnmarshalBinary(rawTx); err != nil {
return common.Hash{}, uuid.Nil, err
}
hasher.Write(tx.Hash().Bytes())
}
hashBytes := hasher.Sum(nil)

References:

You can look up refunds for a specific bundle by using the buildernet_getFeeRefundsByBundle API.


eth_sendRawTransaction

You can use eth_sendRawTransaction to send a single signed transaction to BuilderNet.

Transactions sent with eth_sendRawTransaction are NOT eligible for refunds.

Transactions sent this way are:

  • not sent to the mempool.
  • propagated to other BuilderNet builder nodes.
  • tried to include for up to 5 blocks.
Request
{
"id": 1,
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": ["0x000000..."]
}
Response

The response contains the transaction hash:

{
"id": 1,
"jsonrpc": "2.0",
"result": "0x000000..."
}
Request signature and authentication

eth_sendRawTransaction requests also require a X-Flashbots-Signature header for authentication. For more details, see the relevant section for eth_sendBundle.


TEE Proof Validation API (aTLS)

BuilderNet uses attested TLS (aTLS) to verify the attestation of specific builder node instances.

You can find more details in the Constellation docs:

aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate. Instead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate.

The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS).

In BuilderNet, github.com/flashbots/cvm-reverse-proxy is responsible for attested TLS (aTLS) communication, both towards users as well as within the network. You can use the attested-get tool to receive the builder certificate over an attested channel:

# Install attested-get
go install github.com/flashbots/cvm-reverse-proxy/cmd/attested-get

# Get the builder certificate over an attested channel
attested-get \
--addr=https://rpc.buildernet.org:7936/cert \
--expected-measurements=https://measurements.buildernet.org \
--out-response=builder-cert.pem

See also "Orderflow encryption and attestation" for more details.

Refunds

note

Refund APIs should be queried at https://relay.flashbots.net.

BuilderNet provides these APIs to check refunds data:


buildernet_getFeeRefundTotalsByRecipient

The buildernet_getFeeRefundTotalsByRecipient JSON-RPC method returns the total amount of fee refunds that have been earned by a specific address.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getFeeRefundTotalsByRecipient",
"params": [
recipient, // String, the address to query for fee refunds
]
}

The response contains three fields:

{
"pending":"0x17812ea4fbbe314",
"received":"0x108d1b27b63a213",
"maxBlockNumber":"0x13ddb08"
}
  • pending: the total amount of fee refunds that have been earned but not yet received by the recipient
  • received: the total amount of fee refunds that have been received by the recipient
  • maxBlockNumber: the highest block number for which fee refunds have been processed

buildernet_getFeeRefundsByRecipient

The buildernet_getFeeRefundsByRecipient JSON-RPC method returns detailed information about fee refunds that have been earned by a specific address. Our refund process usually calculates these values with a 4 hour delay.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getFeeRefundsByRecipient",
"params": [
{
recipient, // String, the address to query for fee refunds
cursor, // [optional] String, the cursor to continue from
}
]
}

Responses are paginated and contain the following fields:

{
"refunds": [
{
"hash": "0x...",
"amount": "0x...",
"blockNumber": "0x13ddaa4",
"status": "pending",
"recipient": "0x..."
},
...
],
"cursor": "0x..."
}

The "refunds" field contains an array of per-order fee refunds, each with the following fields:

  • hash: the bundle hash or transaction hash associated with the fee refund
  • amount: the amount of the fee refund, in wei
  • blockNumber: the block number the order was contained in
  • status: the status of the fee refund, either "pending" or "received"
  • recipient: the address the fee refund is credited to, either the bundle signer or transaction sender

The "cursor" field is only included if there are more fee refunds to fetch. To continue fetching fee refunds, include the cursor as the second argument in the next request.

NOTE: This API currently only returns details for bundles included in block 20802497 and later. To see total fee refunds processed for a specific address since inception, use the buildernet_getFeeRefundTotalsByRecipient method.

buildernet_getFeeRefundsByBundle

The buildernet_getFeeRefundsByBundle is similar to buildernet_getFeeRefundsByRecipient but returns result for the given bundle.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getFeeRefundsByBundle",
"params": [
bundle_hash, // String, the hash of the bundle
]
}

buildernet_getFeeRefundsByBlock

The buildernet_getFeeRefundsByBlock is similar to buildernet_getFeeRefundsByRecipient but returns result for the given block.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getFeeRefundsByBlock",
"params": [
{
block_number, // String, hex-encoded block number (e.g. 0x15d0280)
}
]
}

buildernet_setFeeRefundRecipient

The buildernet_setFeeRefundRecipient JSON-RPC method allows a user to "delegate" their fee refunds to a specific wallet address. Two addresses must be provided, the first is the address associated with the signing key used to authenticate your request, while the second is the address to send refunds to.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_setFeeRefundRecipient",
"params": [
"0xD2824D2D7D6399a4b9A47F258B870D2AFb213948",
"0xa273A268CE96E54cF6a7D879B7d016F57E396F48"
]
}

If the first address matches the authentication signature, then a response with from and to fields in the result will be returned:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"from":"0xd2824d2d7d6399a4b9a47f258b870d2afb213948",
"to":"0xa273a268ce96e54cf6a7d879b7d016f57e396f48"
}
}

If the signature is invalid or does not match the first address, an appropriate error will be returned instead.

buildernet_getDelayedRefunds

The buildernet_getDelayedRefunds JSON-RPC method returns detailed information about delayed refunds.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getDelayedRefunds",
"params": [
{
recipient, // String, the address that receives delayed refunds
blockRangeFrom, // [optional] String, hex-encoded block number for the start of the range (inclusive)
blockRangeTo, // [optional] String, hex-encoded block number for the end of the range (inclusive)
cursor, // [optional] String, the cursor to continue from
hash, // [optional] String, bundle hash; if provided, you must also set both blockRangeFrom and blockRangeTo
}
]
}

Responses are paginated and contain the following fields:

{
"refunds": [
{
"amount": "0x...",
"blockNumber": "0x13ddaa4",
"hash": "0x...",
"recipient": "0x...",
"status": "pending"
},
...
],
"nextCursor": "0x..."
"indexedUpTo": "0x..."
}

The "refunds" field contains an array of per-order fee refunds, each with the following fields:

  • amount: the amount of the delayed refund, in wei
  • blockNumber: the block number the order was contained in
  • hash: the bundle hash that generated delayed refund
  • status: the status of the delayed refund, either "pending" or "received"
  • recipient: the address the delayed refund is credited to

The "cursor" field is only included if there are more delayed refunds to fetch, some data might be avaiable in the future. To continue fetching, include the cursor as the second argument in the next request. If response is empty but contains cursor retry later.

"indexedUpTo" contains maximum block number for which delayed refunds are indexed

buildernet_getDelayedRefundTotalsByRecipient

The buildernet_getDelayedRefundTotalsByRecipient JSON-RPC method returns the total amount of delayed refunds that have been earned by a specific address.

{
"jsonrpc": "2.0",
"id": 1,
"method": "buildernet_getDelayedRefundTotalsByRecipient",
"params": [
{
recipient, // String, the address to query for delayed refunds
blockRangeFrom, // [optional] String, hex-encoded block number for the start of the range (inclusive)
blockRangeTo, // [optional] String, hex-encoded block number for the end of the range (inclusive)
}
]
}

The response contains three fields:

{
"indexedUpTo":"0x13ddb08"
"pending":"0x17812ea4fbbe314",
"received":"0x108d1b27b63a213",
}
  • indexedUpTo: the highest block number for which delayed refunds have been processed
  • pending: the total amount of fee refunds that have been earned but not yet received by the recipient
  • received: the total amount of fee refunds that have been received by the recipient