How to send orderflow
Orderflow sent to Flashbots Protect and Flashbots Bundle Relay is shared with BuilderNet. You can also send orderflow directly to a BuilderNet node (and validate its TEE proof)!
The instructions in this document are intended for advanced technical users with strict trust assumptions. As a regular user, you can simply use Flashbots Protect to transact securely through BuilderNet and get refunds for your transactions.
Sending orderflow to BuilderNet directly
You can send orderflow to any BuilderNet node available to you.
Flashbots operates a public BuilderNet node:
- Orderflow endpoint: https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net:443
- TEE proof validation (aTLS): https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net:7936
Supported API methods
Example curl
request
This request sends a signed transaction to BuilderNet:
curl https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net \
--cacert builder-cert.pem \ # or using --insecure
--header 'Content-Type: application/json' \
--header 'X-Flashbots-Signature: <public key address>:<signature>' \
--data '{
"jsonrpc":"2.0",
"method":"eth_sendRawTransaction",
"params":["0x000000..."],
"id":1
}'
See also this example Golang code for sending a transaction with a signed request and a pinned server certificate.
The TLS certificate is generated by the orderflow-proxy server on each service restart. You can get the public certificate (builder-cert.pem
) over an attested channel (see the next section "TEE proof validation") or through an insecure curl
request:
curl -w %{certs} -k https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net/
TEE proof validation
You can verify a builder node is running the correct code and configuration, and inside a specific TEE environment, using the TEE attestation mechanism.
It works by making a HTTPS request through an attested connection. During the TLS handshake, the server proves that it's running inside a TEE with specific measurements and responds with a TLS certificate for future use. Based on the verifiable code and configuration, this provides assurances that this certificate belongs to a specific VM image with specific measurements.
You can use our open-source attested-get
tool to receive the certificate over an attested channel (after verifying the TEE proof) and save it as builder-cert.pem
:
# Install attested-get tool
go install github.com/flashbots/cvm-reverse-proxy/cmd/attested-get
# Get the builder certificate over an attested channel
attested-get \
--addr=https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net:7936/cert \
--expected-measurements=https://measurements.builder.flashbots.net \
--out-response=builder-cert.pem
Example output
time=2025-02-21T14:58:58.978+01:00 level=INFO msg="Loading expected measurements from https://measurements.builder.flashbots.net ..." service=attested-get version=dev
time=2025-02-21T14:58:59.461+01:00 level=INFO msg="Measurements loaded" service=attested-get version=dev measurements=3
time=2025-02-21T14:58:59.461+01:00 level=INFO msg="Executing attested GET request to https://buildernet-flashbots-azure-eastus2-04.builder.flashbots.net:7936/cert ..." service=attested-get version=dev
time=2025-02-21T14:59:00.441+01:00 level=INFO msg="Validating attestation document" service=attested-get version=dev
time=2025-02-21T14:59:02.419+01:00 level=INFO msg="Successfully validated attestation document" service=attested-get version=dev
time=2025-02-21T14:59:02.533+01:00 level=INFO msg="Measurements for azure-tdx with 24 entries:" service=attested-get version=dev
{
"0": "2ade8023eeec241d83eff996830fd33b6b26811a79e8e809def01296337abced",
"1": "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969",
"10": "0000000000000000000000000000000000000000000000000000000000000000",
"11": "84b0ef2e25a43fae992d27602d9c35a3ec66c32fc3d7ea08df543dcc87f287e2",
"12": "0000000000000000000000000000000000000000000000000000000000000000",
"13": "0000000000000000000000000000000000000000000000000000000000000000",
"14": "0000000000000000000000000000000000000000000000000000000000000000",
"15": "0000000000000000000000000000000000000000000000000000000000000000",
"16": "0000000000000000000000000000000000000000000000000000000000000000",
"17": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"18": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"19": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"2": "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969",
"20": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"21": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"22": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"23": "0000000000000000000000000000000000000000000000000000000000000000",
"3": "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969",
"4": "b5fee89a85bf5b168efc4468c18ec4718b26a5c9fc7854bdc34ce25b60add132",
"5": "21b1ad7993b7fafb6325d42feb78edae740559f42fb13bff207b63a03570d7e6",
"6": "5d925f4f3d5191128843b4233fbb5857deeaa01e16678b3da034d8d385e56781",
"7": "124daf47b4d67179a77dc3c1bcca198ae1ee1d094a2a879974842e44ab98bb06",
"8": "0000000000000000000000000000000000000000000000000000000000000000",
"9": "210d55d0e3bd00874faaf0ac45778d53a5fd13d84e3a76720cc19b72b0eefbbc"
}
time=2025-02-21T14:59:02.533+01:00 level=INFO msg="Measurements match expected measurements ✅" service=attested-get version=dev matchedMeasurements=buildernet-v1.2.1-azure-tdx-5ddf9cba5dfe0e3ac097b005145ad789bcfdf262231382909062b02db3d461d4.wic.vhd
time=2025-02-21T14:59:02.533+01:00 level=INFO msg="Response body with 696 bytes:" service=attested-get version=dev
-----BEGIN CERTIFICATE-----
MIIB1TCCAXugAwIBAgIRAIWcROk61DuUAYC2xAqrP9IwCgYIKoZIzj0EAwIwDzEN
MAsGA1UEChMEQWNtZTAeFw0yNTAyMTcxODAwMDBaFw0yNjAyMTcxODAwMDBaMA8x
DTALBgNVBAoTBEFjbWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATycPoG5DUZ
pGIlCVbujGM1IR5nQCHR7EtqKjESP6QRFUcEL1ElKHfqTD7OPK/M8t/xbTsR2eJT
yjKI6Z8vnnTDo4G3MIG0MA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEF
BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQ5TGL/QTbTdnZCpIa64Bgc
7cZ3EjBdBgNVHREEVjBUgglsb2NhbGhvc3SCO2J1aWxkZXJuZXQtZmxhc2hib3Rz
LWF6dXJlLWVhc3R1czItMDQuYnVpbGRlci5mbGFzaGJvdHMubmV0hwR/AAABhwQo
QcO4MAoGCCqGSM49BAMCA0gAMEUCIHVTqjYYzCnH7cF7NzOpavBoh7BWQgN6D5/X
6MReAtIwAiEA5CNGjIXUznOFvXzLMK5udyTHbBPd0WgukT7575KTniA=
-----END CERTIFICATE-----
This returned TLS certificate is now provably tied to the specific VM image, and any server with the corresponding private key is verified to run the correct code and configuration and inside a TEE.
You can use this certificate to securely send orderflow to this node on port 443 (see the previous section).
Request authentication
Requests need a X-Flashbots-Signature
header. 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.
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.
Server TLS certificate
The server uses a TLS certificate that's generated inside the TEE instance, which you can verify with the TEE attestation mechanism. See also "TEE proof validation" for more details.
As an alternative to pinning the specific server certificate, you can also allow self-signed certificates (i.e. with curl
using the --insecure
flag).
See also
Join the discussion in the Flashbots forum!