diff --git a/bolt-sidecar/Cargo.lock b/bolt-sidecar/Cargo.lock
index d50b0bb60..5a14a06ab 100644
--- a/bolt-sidecar/Cargo.lock
+++ b/bolt-sidecar/Cargo.lock
@@ -50,19 +50,35 @@ version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "04e9a1892803b02f53e25bea3e414ddd0501f12d97456c9d5ade4edf88f9516f"
 dependencies = [
+ "alloy-rlp",
  "num_enum",
+ "serde",
  "strum",
 ]
 
+[[package]]
+name = "alloy-consensus"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "c-kzg",
+ "serde",
+ "sha2 0.10.8",
+]
+
 [[package]]
 name = "alloy-consensus"
 version = "0.1.0"
 source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e#64feb9bc51c8021ea08535694c44de84222f474e"
 dependencies = [
- "alloy-eips 0.1.0",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "alloy-primitives",
  "alloy-rlp",
- "alloy-serde 0.1.0",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "c-kzg",
  "serde",
 ]
@@ -70,7 +86,7 @@ dependencies = [
 [[package]]
 name = "alloy-consensus"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-eips 0.1.2",
  "alloy-primitives",
@@ -80,6 +96,19 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "alloy-eips"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "c-kzg",
+ "once_cell",
+ "serde",
+]
+
 [[package]]
 name = "alloy-eips"
 version = "0.1.0"
@@ -87,7 +116,7 @@ source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44
 dependencies = [
  "alloy-primitives",
  "alloy-rlp",
- "alloy-serde 0.1.0",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "c-kzg",
  "once_cell",
  "serde",
@@ -97,7 +126,7 @@ dependencies = [
 [[package]]
 name = "alloy-eips"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-primitives",
  "alloy-rlp",
@@ -108,13 +137,23 @@ dependencies = [
  "sha2 0.10.8",
 ]
 
+[[package]]
+name = "alloy-genesis"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-primitives",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "serde",
+]
+
 [[package]]
 name = "alloy-genesis"
 version = "0.1.0"
 source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e#64feb9bc51c8021ea08535694c44de84222f474e"
 dependencies = [
  "alloy-primitives",
- "alloy-serde 0.1.0",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "serde",
  "serde_json",
 ]
@@ -122,7 +161,7 @@ dependencies = [
 [[package]]
 name = "alloy-genesis"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-primitives",
  "alloy-serde 0.1.2",
@@ -132,7 +171,7 @@ dependencies = [
 [[package]]
 name = "alloy-json-rpc"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-primitives",
  "serde",
@@ -144,7 +183,7 @@ dependencies = [
 [[package]]
 name = "alloy-network"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-consensus 0.1.2",
  "alloy-eips 0.1.2",
@@ -163,7 +202,7 @@ dependencies = [
 [[package]]
 name = "alloy-node-bindings"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-genesis 0.1.2",
  "alloy-primitives",
@@ -202,7 +241,7 @@ dependencies = [
 [[package]]
 name = "alloy-provider"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-chains",
  "alloy-consensus 0.1.2",
@@ -235,7 +274,7 @@ dependencies = [
 [[package]]
 name = "alloy-pubsub"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-json-rpc",
  "alloy-primitives",
@@ -275,7 +314,7 @@ dependencies = [
 [[package]]
 name = "alloy-rpc-client"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-json-rpc",
  "alloy-primitives",
@@ -295,17 +334,36 @@ dependencies = [
  "url",
 ]
 
+[[package]]
+name = "alloy-rpc-types"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-genesis 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-sol-types",
+ "itertools 0.12.1",
+ "jsonrpsee-types",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
 [[package]]
 name = "alloy-rpc-types"
 version = "0.1.0"
 source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e#64feb9bc51c8021ea08535694c44de84222f474e"
 dependencies = [
- "alloy-consensus 0.1.0",
- "alloy-eips 0.1.0",
- "alloy-genesis 0.1.0",
+ "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
+ "alloy-genesis 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "alloy-primitives",
  "alloy-rlp",
- "alloy-serde 0.1.0",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "alloy-sol-types",
  "itertools 0.12.1",
  "serde",
@@ -316,7 +374,7 @@ dependencies = [
 [[package]]
 name = "alloy-rpc-types"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-rpc-types-eth",
  "alloy-serde 0.1.2",
@@ -327,9 +385,9 @@ name = "alloy-rpc-types-beacon"
 version = "0.1.0"
 source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e#64feb9bc51c8021ea08535694c44de84222f474e"
 dependencies = [
- "alloy-eips 0.1.0",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "alloy-primitives",
- "alloy-rpc-types-engine 0.1.0",
+ "alloy-rpc-types-engine 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "serde",
  "serde_with",
  "thiserror",
@@ -338,7 +396,7 @@ dependencies = [
 [[package]]
 name = "alloy-rpc-types-beacon"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-eips 0.1.2",
  "alloy-primitives",
@@ -348,17 +406,32 @@ dependencies = [
  "thiserror",
 ]
 
+[[package]]
+name = "alloy-rpc-types-engine"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "jsonrpsee-types",
+ "serde",
+ "thiserror",
+]
+
 [[package]]
 name = "alloy-rpc-types-engine"
 version = "0.1.0"
 source = "git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e#64feb9bc51c8021ea08535694c44de84222f474e"
 dependencies = [
- "alloy-consensus 0.1.0",
- "alloy-eips 0.1.0",
+ "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "alloy-primitives",
  "alloy-rlp",
- "alloy-rpc-types 0.1.0",
- "alloy-serde 0.1.0",
+ "alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=64feb9bc51c8021ea08535694c44de84222f474e)",
  "jsonwebtoken",
  "rand 0.8.5",
  "serde",
@@ -368,7 +441,7 @@ dependencies = [
 [[package]]
 name = "alloy-rpc-types-engine"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-consensus 0.1.2",
  "alloy-eips 0.1.2",
@@ -385,7 +458,7 @@ dependencies = [
 [[package]]
 name = "alloy-rpc-types-eth"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-consensus 0.1.2",
  "alloy-eips 0.1.2",
@@ -399,6 +472,28 @@ dependencies = [
  "thiserror",
 ]
 
+[[package]]
+name = "alloy-rpc-types-trace"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "alloy-serde"
+version = "0.1.0"
+source = "git+https://github.com/alloy-rs/alloy?rev=17633df#17633df04920e07cd7afbd6ee825fcde677fa1d1"
+dependencies = [
+ "alloy-primitives",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "alloy-serde"
 version = "0.1.0"
@@ -412,7 +507,7 @@ dependencies = [
 [[package]]
 name = "alloy-serde"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-primitives",
  "serde",
@@ -422,7 +517,7 @@ dependencies = [
 [[package]]
 name = "alloy-signer"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-primitives",
  "async-trait",
@@ -435,7 +530,7 @@ dependencies = [
 [[package]]
 name = "alloy-signer-local"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-consensus 0.1.2",
  "alloy-network",
@@ -508,7 +603,7 @@ dependencies = [
 [[package]]
 name = "alloy-transport"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-json-rpc",
  "base64 0.22.1",
@@ -525,7 +620,7 @@ dependencies = [
 [[package]]
 name = "alloy-transport-http"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-json-rpc",
  "alloy-transport",
@@ -539,7 +634,7 @@ dependencies = [
 [[package]]
 name = "alloy-transport-ws"
 version = "0.1.2"
-source = "git+https://github.com/alloy-rs/alloy#8aa54828c025a99bbe7e2d4fc9768605d172cc6d"
+source = "git+https://github.com/alloy-rs/alloy#61921bccf676843823164bc7acc31cc9df5d3079"
 dependencies = [
  "alloy-pubsub",
  "alloy-transport",
@@ -553,6 +648,22 @@ dependencies = [
  "ws_stream_wasm",
 ]
 
+[[package]]
+name = "alloy-trie"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "beb28aa4ecd32fdfa1b1bdd111ff7357dd562c6b2372694cf9e613434fcba659"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rlp",
+ "derive_more",
+ "hashbrown 0.14.5",
+ "nybbles",
+ "serde",
+ "smallvec",
+ "tracing",
+]
+
 [[package]]
 name = "android-tzdata"
 version = "0.1.1"
@@ -834,6 +945,16 @@ version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
 
+[[package]]
+name = "aurora-engine-modexp"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5"
+dependencies = [
+ "hex",
+ "num",
+]
+
 [[package]]
 name = "auto_impl"
 version = "1.2.0"
@@ -989,6 +1110,15 @@ dependencies = [
  "url",
 ]
 
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "bimap"
 version = "0.6.3"
@@ -1021,6 +1151,9 @@ name = "bitflags"
 version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
+dependencies = [
+ "serde",
+]
 
 [[package]]
 name = "bitvec"
@@ -1030,6 +1163,7 @@ checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
 dependencies = [
  "funty",
  "radium",
+ "serde",
  "tap",
  "wyz",
 ]
@@ -1101,7 +1235,8 @@ dependencies = [
  "parking_lot",
  "rand 0.8.5",
  "reqwest 0.12.5",
- "secp256k1",
+ "reth-primitives",
+ "secp256k1 0.29.0",
  "serde",
  "serde_json",
  "thiserror",
@@ -1129,6 +1264,12 @@ version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
 
+[[package]]
+name = "bytemuck"
+version = "1.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
+
 [[package]]
 name = "byteorder"
 version = "1.5.0"
@@ -1207,6 +1348,11 @@ name = "cc"
 version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
+dependencies = [
+ "jobserver",
+ "libc",
+ "once_cell",
+]
 
 [[package]]
 name = "cfg-if"
@@ -1307,6 +1453,15 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
 
+[[package]]
+name = "convert_case"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
+dependencies = [
+ "unicode-segmentation",
+]
+
 [[package]]
 name = "core-foundation"
 version = "0.9.4"
@@ -1341,6 +1496,40 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "crc"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
 [[package]]
 name = "crossbeam-utils"
 version = "0.8.20"
@@ -1523,7 +1712,7 @@ version = "0.99.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
 dependencies = [
- "convert_case",
+ "convert_case 0.4.0",
  "proc-macro2",
  "quote",
  "rustc_version 0.4.0",
@@ -1557,6 +1746,12 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
 
+[[package]]
+name = "dyn-clone"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
+
 [[package]]
 name = "ecdsa"
 version = "0.14.8"
@@ -1656,6 +1851,36 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "enr"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4"
+dependencies = [
+ "base64 0.21.7",
+ "bytes",
+ "hex",
+ "k256 0.13.3",
+ "log",
+ "rand 0.8.5",
+ "rlp",
+ "secp256k1 0.27.0",
+ "serde",
+ "sha3",
+ "zeroize",
+]
+
+[[package]]
+name = "enumn"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.67",
+]
+
 [[package]]
 name = "equivalent"
 version = "1.0.1"
@@ -1712,7 +1937,7 @@ dependencies = [
  "blst",
  "bs58",
  "c-kzg",
- "enr",
+ "enr 0.6.2",
  "hex",
  "integer-sqrt",
  "multiaddr",
@@ -2147,6 +2372,7 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
 dependencies = [
  "ahash",
  "allocator-api2",
+ "serde",
 ]
 
 [[package]]
@@ -2588,6 +2814,15 @@ version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 
+[[package]]
+name = "jobserver"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "js-sys"
 version = "0.3.69"
@@ -2597,6 +2832,19 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "jsonrpsee-types"
+version = "0.22.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "150d6168405890a7a3231a3c74843f58b8959471f6df76078db2619ddee1d07d"
+dependencies = [
+ "anyhow",
+ "beef",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
 [[package]]
 name = "jsonwebtoken"
 version = "9.3.0"
@@ -2635,6 +2883,7 @@ dependencies = [
  "elliptic-curve 0.13.8",
  "once_cell",
  "sha2 0.10.8",
+ "signature 2.2.0",
 ]
 
 [[package]]
@@ -2658,9 +2907,12 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin 0.9.8",
+]
 
 [[package]]
 name = "libc"
@@ -2778,6 +3030,27 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "modular-bitfield"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74"
+dependencies = [
+ "modular-bitfield-impl",
+ "static_assertions",
+]
+
+[[package]]
+name = "modular-bitfield-impl"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "multer"
 version = "2.1.0"
@@ -2868,6 +3141,20 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "num"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
+dependencies = [
+ "num-bigint",
+ "num-complex",
+ "num-integer",
+ "num-iter",
+ "num-rational",
+ "num-traits",
+]
+
 [[package]]
 name = "num-bigint"
 version = "0.4.5"
@@ -2878,6 +3165,15 @@ dependencies = [
  "num-traits",
 ]
 
+[[package]]
+name = "num-complex"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+dependencies = [
+ "num-traits",
+]
+
 [[package]]
 name = "num-conv"
 version = "0.1.0"
@@ -2893,6 +3189,28 @@ dependencies = [
  "num-traits",
 ]
 
+[[package]]
+name = "num-iter"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
+dependencies = [
+ "num-bigint",
+ "num-integer",
+ "num-traits",
+]
+
 [[package]]
 name = "num-traits"
 version = "0.2.19"
@@ -2934,6 +3252,19 @@ dependencies = [
  "syn 2.0.67",
 ]
 
+[[package]]
+name = "nybbles"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23"
+dependencies = [
+ "alloy-rlp",
+ "const-hex",
+ "proptest",
+ "serde",
+ "smallvec",
+]
+
 [[package]]
 name = "object"
 version = "0.36.0"
@@ -3385,6 +3716,26 @@ dependencies = [
  "rand_core 0.6.4",
 ]
 
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
 [[package]]
 name = "redox_syscall"
 version = "0.5.2"
@@ -3508,6 +3859,163 @@ dependencies = [
  "winreg 0.52.0",
 ]
 
+[[package]]
+name = "reth-codecs"
+version = "0.2.0-beta.5"
+source = "git+https://github.com/paradigmxyz/reth?rev=71c404d#71c404d9cb7a678d4c0f6442a9c2b8449529fe2a"
+dependencies = [
+ "alloy-primitives",
+ "bytes",
+ "reth-codecs-derive",
+]
+
+[[package]]
+name = "reth-codecs-derive"
+version = "0.2.0-beta.5"
+source = "git+https://github.com/paradigmxyz/reth?rev=71c404d#71c404d9cb7a678d4c0f6442a9c2b8449529fe2a"
+dependencies = [
+ "convert_case 0.6.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.67",
+]
+
+[[package]]
+name = "reth-ethereum-forks"
+version = "0.2.0-beta.5"
+source = "git+https://github.com/paradigmxyz/reth?rev=71c404d#71c404d9cb7a678d4c0f6442a9c2b8449529fe2a"
+dependencies = [
+ "alloy-chains",
+ "alloy-primitives",
+ "alloy-rlp",
+ "crc",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "reth-primitives"
+version = "0.2.0-beta.5"
+source = "git+https://github.com/paradigmxyz/reth?rev=71c404d#71c404d9cb7a678d4c0f6442a9c2b8449529fe2a"
+dependencies = [
+ "alloy-chains",
+ "alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-genesis 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-trie",
+ "byteorder",
+ "bytes",
+ "c-kzg",
+ "cfg-if",
+ "derive_more",
+ "enr 0.10.0",
+ "itertools 0.12.1",
+ "modular-bitfield",
+ "nybbles",
+ "once_cell",
+ "rayon",
+ "reth-codecs",
+ "reth-ethereum-forks",
+ "reth-rpc-types",
+ "revm",
+ "revm-primitives",
+ "roaring",
+ "secp256k1 0.27.0",
+ "serde",
+ "serde_json",
+ "serde_with",
+ "sha2 0.10.8",
+ "strum",
+ "tempfile",
+ "thiserror",
+ "zstd",
+]
+
+[[package]]
+name = "reth-rpc-types"
+version = "0.2.0-beta.5"
+source = "git+https://github.com/paradigmxyz/reth?rev=71c404d#71c404d9cb7a678d4c0f6442a9c2b8449529fe2a"
+dependencies = [
+ "alloy-genesis 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-rpc-types-engine 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=17633df)",
+ "alloy-rpc-types-trace",
+ "enr 0.10.0",
+ "jsonrpsee-types",
+ "secp256k1 0.27.0",
+ "serde",
+ "serde_json",
+ "serde_with",
+ "thiserror",
+ "url",
+]
+
+[[package]]
+name = "revm"
+version = "8.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72a454c1c650b2b2e23f0c461af09e6c31e1d15e1cbebe905a701c46b8a50afc"
+dependencies = [
+ "auto_impl",
+ "cfg-if",
+ "dyn-clone",
+ "revm-interpreter",
+ "revm-precompile",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "revm-interpreter"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d322f2730cd300e99d271a1704a2dfb8973d832428f5aa282aaa40e2473b5eec"
+dependencies = [
+ "revm-primitives",
+ "serde",
+]
+
+[[package]]
+name = "revm-precompile"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "931f692f3f4fc72ec39d5d270f8e9d208c4a6008de7590ee96cf948e3b6d3f8d"
+dependencies = [
+ "aurora-engine-modexp",
+ "c-kzg",
+ "k256 0.13.3",
+ "once_cell",
+ "revm-primitives",
+ "ripemd",
+ "secp256k1 0.28.2",
+ "sha2 0.10.8",
+ "substrate-bn",
+]
+
+[[package]]
+name = "revm-primitives"
+version = "3.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbbc9640790cebcb731289afb7a7d96d16ad94afeb64b5d0b66443bd151e79d6"
+dependencies = [
+ "alloy-primitives",
+ "auto_impl",
+ "bitflags 2.5.0",
+ "bitvec",
+ "c-kzg",
+ "cfg-if",
+ "derive_more",
+ "dyn-clone",
+ "enumn",
+ "hashbrown 0.14.5",
+ "hex",
+ "once_cell",
+ "serde",
+]
+
 [[package]]
 name = "rfc6979"
 version = "0.3.1"
@@ -3559,6 +4067,15 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "ripemd"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
+dependencies = [
+ "digest 0.10.7",
+]
+
 [[package]]
 name = "rlp"
 version = "0.5.2"
@@ -3581,6 +4098,16 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "roaring"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7699249cc2c7d71939f30868f47e9d7add0bdc030d90ee10bfd16887ff8bb1c8"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+]
+
 [[package]]
 name = "ruint"
 version = "1.12.3"
@@ -3802,6 +4329,25 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "secp256k1"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
+dependencies = [
+ "secp256k1-sys 0.8.1",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.28.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10"
+dependencies = [
+ "rand 0.8.5",
+ "secp256k1-sys 0.9.2",
+]
+
 [[package]]
 name = "secp256k1"
 version = "0.29.0"
@@ -3809,7 +4355,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3"
 dependencies = [
  "rand 0.8.5",
- "secp256k1-sys",
+ "secp256k1-sys 0.10.0",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb"
+dependencies = [
+ "cc",
 ]
 
 [[package]]
@@ -3900,6 +4464,7 @@ version = "1.0.117"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
 dependencies = [
+ "indexmap 2.2.6",
  "itoa",
  "ryu",
  "serde",
@@ -4108,6 +4673,9 @@ name = "smallvec"
 version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+dependencies = [
+ "serde",
+]
 
 [[package]]
 name = "socket2"
@@ -4213,6 +4781,19 @@ dependencies = [
  "syn 2.0.67",
 ]
 
+[[package]]
+name = "substrate-bn"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c"
+dependencies = [
+ "byteorder",
+ "crunchy",
+ "lazy_static",
+ "rand 0.8.5",
+ "rustc-hex",
+]
+
 [[package]]
 name = "subtle"
 version = "2.6.0"
@@ -4781,6 +5362,12 @@ dependencies = [
  "tinyvec",
 ]
 
+[[package]]
+name = "unicode-segmentation"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
+
 [[package]]
 name = "unicode-xid"
 version = "0.2.4"
@@ -5305,3 +5892,31 @@ dependencies = [
  "quote",
  "syn 2.0.67",
 ]
+
+[[package]]
+name = "zstd"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "7.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a"
+dependencies = [
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.11+zstd.1.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
diff --git a/bolt-sidecar/Cargo.toml b/bolt-sidecar/Cargo.toml
index ae0cbcf05..379191d7b 100644
--- a/bolt-sidecar/Cargo.toml
+++ b/bolt-sidecar/Cargo.toml
@@ -8,23 +8,17 @@ default-run = "bolt-sidecar"
 # core
 clap = { version = "4.5.4", features = ["derive"] }
 tokio = { version = "1", features = ["full"] }
+axum = { version = "0.7", features = ["macros"] }
 warp = "0.3.7"
 futures = "0.3"
-axum = { version = "0.7", features = ["macros"] }
 
 # crypto
 blst = "0.3.12"
 secp256k1 = { version = "0.29.0", features = ["rand"] }
 
 # alloy
-alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", features = [
-  "reqwest",
-  "ws",
-  "pubsub",
-] }
-alloy-provider = { git = "https://github.com/alloy-rs/alloy", features = [
-  "ws",
-] }
+alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", features = ["reqwest", "ws", "pubsub"] }
+alloy-provider = { git = "https://github.com/alloy-rs/alloy", features = ["ws"] }
 alloy-signer = { git = "https://github.com/alloy-rs/alloy" }
 alloy-signer-local = { git = "https://github.com/alloy-rs/alloy" }
 alloy-transport = { git = "https://github.com/alloy-rs/alloy" }
@@ -34,14 +28,16 @@ alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy" }
 alloy-pubsub = { git = "https://github.com/alloy-rs/alloy" }
 alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy" }
 alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy" }
-alloy-consensus = { git = "https://github.com/alloy-rs/alloy", features = [
-  "k256",
-] }
+alloy-consensus = { git = "https://github.com/alloy-rs/alloy", features = ["k256"] }
 alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy" }
 alloy-primitives = { version = "0.7.1", features = ["rand"] }
 alloy-network = { git = "https://github.com/alloy-rs/alloy" }
 alloy-rlp = "0.3"
 
+# reth
+reth-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "71c404d" }
+# reth-provider = { git = "https://github.com/paradigmxyz/reth", rev = "71c404d" }
+
 reqwest = "0.12"
 ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404" }
 beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404" }
diff --git a/bolt-sidecar/bin/sidecar.rs b/bolt-sidecar/bin/sidecar.rs
index 66cf49646..2ed342d5d 100644
--- a/bolt-sidecar/bin/sidecar.rs
+++ b/bolt-sidecar/bin/sidecar.rs
@@ -1,3 +1,5 @@
+use std::time::Duration;
+
 use bolt_sidecar::{
     crypto::{
         bls::{from_bls_signature_to_consensus_signature, Signer, SignerBLS},
@@ -6,7 +8,7 @@ use bolt_sidecar::{
     json_rpc::{api::ApiError, start_server},
     primitives::{
         BatchedSignedConstraints, ChainHead, CommitmentRequest, ConstraintsMessage,
-        LocalPayloadFetcher, NoopPayloadFetcher, SignedConstraints,
+        LocalPayloadFetcher, SignedConstraints,
     },
     spec::ConstraintsApi,
     start_builder_proxy,
@@ -14,10 +16,9 @@ use bolt_sidecar::{
         fetcher::{StateClient, StateFetcher},
         ExecutionState,
     },
-    BuilderProxyConfig, Config, MevBoostClient, Opts,
+    BuilderProxyConfig, Config, MevBoostClient,
 };
 
-use clap::Parser;
 use tokio::sync::mpsc;
 use tracing::info;
 
@@ -27,31 +28,34 @@ async fn main() -> eyre::Result<()> {
 
     info!("Starting sidecar");
 
-    let opts = Opts::parse();
-    let config = Config::try_from(opts)?;
+    let config = Config::parse_from_cli()?;
 
     let (api_events, mut api_events_rx) = mpsc::channel(1024);
 
+    // TODO: support external signers
     let signer = Signer::new(config.private_key.clone().unwrap());
 
     let state_client = StateClient::new(&config.execution_api, 8);
+    let mevboost_client = MevBoostClient::new(&config.mevboost_url);
 
     let head = state_client.get_head().await?;
-
     let mut execution_state = ExecutionState::new(state_client, ChainHead::new(0, head)).await?;
 
-    let mevboost_client = MevBoostClient::new(config.mevboost_url.clone());
-
     let shutdown_tx = start_server(config, api_events).await?;
 
     let builder_proxy_config = BuilderProxyConfig::default();
 
     let (payload_tx, mut payload_rx) = mpsc::channel(1);
-    let _payload_fetcher = LocalPayloadFetcher::new(payload_tx);
-
-    let _builder_proxy = tokio::spawn(async move {
-        if let Err(e) = start_builder_proxy(NoopPayloadFetcher, builder_proxy_config).await {
-            tracing::error!("Builder proxy failed: {:?}", e);
+    let payload_fetcher = LocalPayloadFetcher::new(payload_tx);
+
+    tokio::spawn(async move {
+        loop {
+            if let Err(e) =
+                start_builder_proxy(payload_fetcher.clone(), builder_proxy_config.clone()).await
+            {
+                tracing::error!("Builder API proxy failed: {:?}", e);
+                tokio::time::sleep(Duration::from_secs(5)).await;
+            }
         }
     });
 
@@ -94,8 +98,18 @@ async fn main() -> eyre::Result<()> {
             }
             Some(request) = payload_rx.recv() => {
                 tracing::info!("Received payload request: {:?}", request);
-                let _response = execution_state.get_block_template(request.slot);
-                // TODO: extract payload & bid
+                let Some(response) = execution_state.get_block_template(request.slot) else {
+                    tracing::warn!("No block template found for slot {} when requested", request.slot);
+                    let _ = request.response.send(None);
+                    continue;
+                };
+
+                // For fallback block building, we need to turn a block template into an actual SignedBuilderBid.
+                // This will also require building the full ExecutionPayload that we want the proposer to commit to.
+                // Once we have that, we need to send it as response to the validator via the pending get_header RPC call.
+                // The validator will then call get_payload with the corresponding SignedBlindedBeaconBlock. We then need to
+                // respond with the full ExecutionPayload inside the BeaconBlock (+ blobs if any).
+
                 let _ = request.response.send(None);
             }
 
diff --git a/bolt-sidecar/src/api/builder.rs b/bolt-sidecar/src/api/builder.rs
index c6d93b452..18e27be19 100644
--- a/bolt-sidecar/src/api/builder.rs
+++ b/bolt-sidecar/src/api/builder.rs
@@ -113,6 +113,8 @@ impl<T: ConstraintsApi, P: PayloadFetcher + Send + Sync> BuilderProxyServer<T, P
         {
             Ok(Ok(header)) => {
                 tracing::debug!(elapsed = ?start.elapsed(), "Returning signed builder bid: {:?}", header);
+                // TODO: verify proofs here. If they are invalid, we should fall back to locally built block
+
                 Ok(Json(header.bid))
             }
             Ok(Err(_)) | Err(_) => {
@@ -210,14 +212,14 @@ impl Default for BuilderProxyConfig {
 pub async fn start_builder_proxy<P: PayloadFetcher + Send + Sync + 'static>(
     payload_fetcher: P,
     config: BuilderProxyConfig,
-) -> Result<(), Box<dyn std::error::Error>> {
+) -> Result<(), eyre::Error> {
     tracing::info!(
         port = config.port,
         target = config.mev_boost_url,
         "Starting builder proxy..."
     );
 
-    let mev_boost = MevBoostClient::new(config.mev_boost_url);
+    let mev_boost = MevBoostClient::new(&config.mev_boost_url);
     let server = Arc::new(BuilderProxyServer::new(mev_boost, payload_fetcher));
     let router = Router::new()
         .route("/", get(index))
diff --git a/bolt-sidecar/src/builder/mod.rs b/bolt-sidecar/src/builder/mod.rs
new file mode 100644
index 000000000..891fda2df
--- /dev/null
+++ b/bolt-sidecar/src/builder/mod.rs
@@ -0,0 +1,4 @@
+pub mod template;
+pub use template::BlockTemplate;
+
+pub mod payload_builder;
diff --git a/bolt-sidecar/src/builder/payload_builder.rs b/bolt-sidecar/src/builder/payload_builder.rs
new file mode 100644
index 000000000..f7206c78e
--- /dev/null
+++ b/bolt-sidecar/src/builder/payload_builder.rs
@@ -0,0 +1,200 @@
+#![allow(missing_docs)]
+#![allow(unused)]
+
+use alloy_consensus::TxEnvelope;
+use alloy_primitives::{Address, Bytes, B256, U256};
+use ethereum_consensus::{
+    capella::spec,
+    crypto::bls::{PublicKey as BlsPublicKey, SecretKey as BlsSecretKey},
+    deneb::mainnet::ExecutionPayloadHeader,
+    ssz::prelude::{ssz_rs, ByteList, ByteVector, List},
+    types::mainnet::ExecutionPayload,
+};
+use reth_primitives::{
+    constants::BEACON_NONCE, proofs, BlockBody, Bloom, Header, SealedBlock, SealedHeader,
+    TransactionSigned, EMPTY_OMMER_ROOT_HASH,
+};
+
+use crate::primitives::{BuilderBid, Slot};
+
+#[derive(Debug, thiserror::Error)]
+pub enum PayloadBuilderError {
+    #[error("Failed to build payload: {0}")]
+    Custom(String),
+}
+
+#[derive(Debug)]
+pub struct FallbackPayloadBuilder<SRP>
+where
+    SRP: StateRootProvider,
+{
+    state_root_provider: SRP,
+
+    fee_recipient: Address,
+
+    // keypair used for signing the payload
+    private_key: BlsSecretKey,
+    public_key: BlsPublicKey,
+}
+
+/// Minimal execution context required to build a valid payload on the target slot.
+#[derive(Debug)]
+pub struct ExecutionContext {
+    head_slot_number: Slot,
+    parent_hash: B256,
+    transactions: Vec<TransactionSigned>,
+    block: NextBlockInfo,
+}
+
+#[derive(Debug)]
+pub struct NextBlockInfo {
+    number: u64,
+    timestamp: u64,
+    prev_randao: B256,
+    base_fee: u64,
+    extra_data: Bytes,
+    gas_limit: u64,
+}
+
+/// Provider that is able to compute the state root over a set of state diffs.
+/// TODO: how do we avoid full access to the state DB here?
+pub trait StateRootProvider {
+    fn get_state_root(&self) -> Result<B256, PayloadBuilderError>;
+}
+
+impl<SRP> FallbackPayloadBuilder<SRP>
+where
+    SRP: StateRootProvider,
+{
+    /// Build a minimal payload to be used as a fallback
+    pub async fn build_fallback_payload(
+        &self,
+        context: ExecutionContext,
+    ) -> Result<BuilderBid, PayloadBuilderError> {
+        // TODO: actually get the state root (needs to count post-state diffs)
+        let state_root = self.state_root_provider.get_state_root()?;
+        let transactions_root = proofs::calculate_transaction_root(&context.transactions);
+
+        // TODO: fill all of these with correct values
+        let withdrawals_root = Some(B256::default());
+        let receipts_root = B256::default();
+        let logs_bloom = Bloom::default();
+        let gas_used = 0;
+        let parent_beacon_root = B256::default();
+        let value = U256::ZERO;
+
+        let header = Header {
+            parent_hash: context.parent_hash,
+            ommers_hash: EMPTY_OMMER_ROOT_HASH,
+            beneficiary: self.fee_recipient,
+            state_root,
+            transactions_root,
+            receipts_root,
+            withdrawals_root,
+            logs_bloom,
+            difficulty: U256::ZERO,
+            number: context.block.number,
+            gas_limit: context.block.gas_limit,
+            gas_used,
+            timestamp: context.block.timestamp,
+            mix_hash: context.block.prev_randao,
+            nonce: BEACON_NONCE,
+            base_fee_per_gas: Some(context.block.base_fee),
+            blob_gas_used: None,
+            excess_blob_gas: None,
+            parent_beacon_block_root: Some(parent_beacon_root),
+            extra_data: context.block.extra_data,
+        };
+
+        let body = BlockBody {
+            transactions: context.transactions,
+            ommers: Vec::new(),
+            withdrawals: None,
+        };
+
+        let sealed_block = SealedBlock::new(header.seal_slow(), body);
+        let submission = BuilderBid {
+            header: to_execution_payload_header(&sealed_block.header),
+            blob_kzg_commitments: List::default(),
+            public_key: self.public_key.clone(),
+            value,
+        };
+
+        Ok(submission)
+    }
+}
+
+pub(crate) fn to_execution_payload_header(value: &SealedHeader) -> ExecutionPayloadHeader {
+    ExecutionPayloadHeader {
+        parent_hash: to_bytes32(value.parent_hash),
+        fee_recipient: to_bytes20(value.beneficiary),
+        state_root: to_bytes32(value.state_root),
+        receipts_root: to_bytes32(value.receipts_root),
+        logs_bloom: to_byte_vector(value.logs_bloom),
+        prev_randao: to_bytes32(value.mix_hash),
+        block_number: value.number,
+        gas_limit: value.gas_limit,
+        gas_used: value.gas_used,
+        timestamp: value.timestamp,
+        extra_data: ByteList::try_from(value.extra_data.as_ref()).unwrap(),
+        base_fee_per_gas: ssz_rs::U256::from(value.base_fee_per_gas.unwrap_or_default()),
+        block_hash: to_bytes32(value.hash()),
+        transactions_root: value.transactions_root,
+        withdrawals_root: value.withdrawals_root.unwrap_or_default(),
+        blob_gas_used: value.blob_gas_used.unwrap_or_default(),
+        excess_blob_gas: value.excess_blob_gas.unwrap_or_default(),
+    }
+}
+
+pub(crate) fn to_execution_payload(value: &SealedBlock) -> ExecutionPayload {
+    let hash = value.hash();
+    let header = &value.header;
+    let transactions = &value.body;
+    let withdrawals = &value.withdrawals;
+    let transactions = transactions
+        .iter()
+        .map(|t| spec::Transaction::try_from(t.envelope_encoded().as_ref()).unwrap())
+        .collect::<Vec<_>>();
+    let withdrawals = withdrawals
+        .as_ref()
+        .unwrap()
+        .iter()
+        .map(|w| spec::Withdrawal {
+            index: w.index as usize,
+            validator_index: w.validator_index as usize,
+            address: to_bytes20(w.address),
+            amount: w.amount,
+        })
+        .collect::<Vec<_>>();
+
+    let payload = spec::ExecutionPayload {
+        parent_hash: to_bytes32(header.parent_hash),
+        fee_recipient: to_bytes20(header.beneficiary),
+        state_root: to_bytes32(header.state_root),
+        receipts_root: to_bytes32(header.receipts_root),
+        logs_bloom: to_byte_vector(header.logs_bloom),
+        prev_randao: to_bytes32(header.mix_hash),
+        block_number: header.number,
+        gas_limit: header.gas_limit,
+        gas_used: header.gas_used,
+        timestamp: header.timestamp,
+        extra_data: ByteList::try_from(header.extra_data.as_ref()).unwrap(),
+        base_fee_per_gas: ssz_rs::U256::from(header.base_fee_per_gas.unwrap_or_default()),
+        block_hash: to_bytes32(hash),
+        transactions: TryFrom::try_from(transactions).unwrap(),
+        withdrawals: TryFrom::try_from(withdrawals).unwrap(),
+    };
+    ExecutionPayload::Capella(payload)
+}
+
+fn to_bytes32(value: B256) -> spec::Bytes32 {
+    spec::Bytes32::try_from(value.as_ref()).unwrap()
+}
+
+fn to_bytes20(value: Address) -> spec::ExecutionAddress {
+    spec::ExecutionAddress::try_from(value.as_ref()).unwrap()
+}
+
+fn to_byte_vector(value: Bloom) -> ByteVector<256> {
+    ByteVector::<256>::try_from(value.as_ref()).unwrap()
+}
diff --git a/bolt-sidecar/src/template/mod.rs b/bolt-sidecar/src/builder/template.rs
similarity index 95%
rename from bolt-sidecar/src/template/mod.rs
rename to bolt-sidecar/src/builder/template.rs
index 84a0c1f68..10c23225e 100644
--- a/bolt-sidecar/src/template/mod.rs
+++ b/bolt-sidecar/src/builder/template.rs
@@ -116,21 +116,6 @@ impl BlockTemplate {
     }
 }
 
-/// StateDiff tracks the intermediate changes to the state according to the block template.
-#[derive(Debug, Default)]
-pub struct StateDiff {
-    diffs: HashMap<Address, (u64, U256)>,
-}
-
-impl StateDiff {
-    /// Returns a tuple of the nonce and balance diff for the given address.
-    /// The nonce diff should be added to the current nonce, the balance diff should be subtracted from
-    /// the current balance.
-    pub fn get_diff(&self, address: &Address) -> Option<(u64, U256)> {
-        self.diffs.get(address).copied()
-    }
-}
-
 impl TryFrom<BlockTemplate> for PayloadAndBid {
     type Error = Box<dyn std::error::Error>;
 
@@ -144,6 +129,28 @@ impl TryFrom<BlockTemplate> for PayloadAndBid {
             },
             signature: todo!(),
         };
+
+        Ok(PayloadAndBid {
+            payload: todo!(),
+            bid,
+        })
+    }
+}
+
+/// StateDiff tracks the intermediate changes to the state according to the block template.
+#[derive(Debug, Default)]
+pub struct StateDiff {
+    /// Map of diffs per address. Each diff is a tuple of the nonce and balance diff
+    /// that should be applied to the current state.
+    diffs: HashMap<Address, (u64, U256)>,
+}
+
+impl StateDiff {
+    /// Returns a tuple of the nonce and balance diff for the given address.
+    /// The nonce diff should be added to the current nonce, the balance diff should be subtracted from
+    /// the current balance.
+    pub fn get_diff(&self, address: &Address) -> Option<(u64, U256)> {
+        self.diffs.get(address).copied()
     }
 }
 
diff --git a/bolt-sidecar/src/client/mevboost.rs b/bolt-sidecar/src/client/mevboost.rs
index 744019b58..61589864e 100644
--- a/bolt-sidecar/src/client/mevboost.rs
+++ b/bolt-sidecar/src/client/mevboost.rs
@@ -29,7 +29,7 @@ pub struct MevBoostClient {
 
 impl MevBoostClient {
     /// Creates a new MEV-Boost client with the given URL.
-    pub fn new(url: String) -> Self {
+    pub fn new(url: &str) -> Self {
         Self {
             url: url.trim_end_matches('/').to_string(),
             client: reqwest::ClientBuilder::new()
diff --git a/bolt-sidecar/src/client/rpc.rs b/bolt-sidecar/src/client/rpc.rs
index 8d628e834..ed084a0d2 100644
--- a/bolt-sidecar/src/client/rpc.rs
+++ b/bolt-sidecar/src/client/rpc.rs
@@ -16,8 +16,8 @@ use reqwest::{Client, Url};
 
 use crate::primitives::AccountState;
 
-/// An HTTP-based JSON-RPC client that supports batching. Implements all methods that are relevant
-/// to Bolt state.
+/// An HTTP-based JSON-RPC client that supports batching.
+/// Implements all methods that are relevant to Bolt state.
 #[derive(Clone, Debug)]
 pub struct RpcClient(alloy::RpcClient<Http<Client>>);
 
diff --git a/bolt-sidecar/src/config.rs b/bolt-sidecar/src/config.rs
index ca2652384..ed8a5ef81 100644
--- a/bolt-sidecar/src/config.rs
+++ b/bolt-sidecar/src/config.rs
@@ -73,6 +73,14 @@ impl Default for Config {
     }
 }
 
+impl Config {
+    /// Parse the command-line options and return a new `Config` instance
+    pub fn parse_from_cli() -> eyre::Result<Self> {
+        let opts = Opts::parse();
+        Self::try_from(opts)
+    }
+}
+
 impl TryFrom<Opts> for Config {
     type Error = eyre::Report;
 
diff --git a/bolt-sidecar/src/lib.rs b/bolt-sidecar/src/lib.rs
index 38c1ce246..ff9b8d0ee 100644
--- a/bolt-sidecar/src/lib.rs
+++ b/bolt-sidecar/src/lib.rs
@@ -20,7 +20,7 @@ mod common;
 /// Functionality for building local block templates that can
 /// be used as a fallback for proposers. It's also used to keep
 /// any intermediary state that is needed to simulate EVM execution
-mod template;
+pub mod builder;
 
 /// Configuration and command-line argument parsing
 mod config;
diff --git a/bolt-sidecar/src/primitives/mod.rs b/bolt-sidecar/src/primitives/mod.rs
index ee6ff68c0..6a5c5369d 100644
--- a/bolt-sidecar/src/primitives/mod.rs
+++ b/bolt-sidecar/src/primitives/mod.rs
@@ -1,6 +1,9 @@
+// TODO: add docs
+#![allow(missing_docs)]
+
 use std::sync::{atomic::AtomicU64, Arc};
 
-use alloy_primitives::{Bytes, TxHash, U256};
+use alloy_primitives::U256;
 use ethereum_consensus::{
     capella,
     crypto::{KzgCommitment, PublicKey as BlsPublicKey, Signature as BlsSignature},
@@ -32,23 +35,6 @@ pub use transaction::TxInfo;
 /// An alias for a Beacon Chain slot number
 pub type Slot = u64;
 
-/// An enum representing all possible (signed) commitments.
-#[derive(Debug)]
-pub enum Commitment {
-    /// Inclusion commitment, accepted and signed by the proposer
-    /// through this sidecar's signer.
-    Inclusion(InclusionCommitment),
-}
-
-#[derive(Debug)]
-pub struct InclusionCommitment {
-    pub slot: Slot,
-    pub tx_hash: TxHash,
-    pub raw_tx: Bytes,
-    // TODO:
-    pub signature: Bytes,
-}
-
 /// Minimal account state needed for commitment validation.
 #[derive(Debug, Clone, Copy)]
 pub struct AccountState {
@@ -79,14 +65,6 @@ pub struct SignedBuilderBidWithProofs {
     pub proofs: List<ConstraintProof, 300>,
 }
 
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct MerkleMultiProof {
-    // We use List here for SSZ, TODO: choose max
-    transaction_hashes: List<Hash32, 300>,
-    generalized_indexes: List<u64, 300>,
-    merkle_hashes: List<Hash32, 1000>,
-}
-
 #[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
 pub struct ConstraintProof {
     #[serde(rename = "txHash")]
@@ -102,6 +80,14 @@ pub struct MerkleProof {
     hashes: List<Hash32, 1000>,
 }
 
+#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
+pub struct MerkleMultiProof {
+    // We use List here for SSZ, TODO: choose max
+    transaction_hashes: List<Hash32, 300>,
+    generalized_indexes: List<u64, 300>,
+    merkle_hashes: List<Hash32, 1000>,
+}
+
 #[derive(Debug)]
 pub struct FetchPayloadRequest {
     pub slot: u64,
@@ -114,6 +100,7 @@ pub struct PayloadAndBid {
     pub payload: GetPayloadResponse,
 }
 
+#[derive(Debug, Clone)]
 pub struct LocalPayloadFetcher {
     tx: mpsc::Sender<FetchPayloadRequest>,
 }
@@ -142,6 +129,7 @@ pub trait PayloadFetcher {
     async fn fetch_payload(&self, slot: u64) -> Option<PayloadAndBid>;
 }
 
+#[derive(Debug)]
 pub struct NoopPayloadFetcher;
 
 #[async_trait::async_trait]
diff --git a/bolt-sidecar/src/state/execution.rs b/bolt-sidecar/src/state/execution.rs
index a9486031c..1f9645959 100644
--- a/bolt-sidecar/src/state/execution.rs
+++ b/bolt-sidecar/src/state/execution.rs
@@ -5,9 +5,9 @@ use std::collections::HashMap;
 use thiserror::Error;
 
 use crate::{
+    builder::BlockTemplate,
     common::{calculate_max_basefee, validate_transaction},
     primitives::{AccountState, ChainHead, CommitmentRequest, Slot},
-    template::BlockTemplate,
 };
 
 use super::{fetcher::StateFetcher, StateError};
diff --git a/bolt-sidecar/src/state/fetcher.rs b/bolt-sidecar/src/state/fetcher.rs
index ecd9501f3..7f1b9f1da 100644
--- a/bolt-sidecar/src/state/fetcher.rs
+++ b/bolt-sidecar/src/state/fetcher.rs
@@ -15,6 +15,7 @@ const MAX_RETRIES: u32 = 8;
 /// The retry backoff in milliseconds.
 const RETRY_BACKOFF_MS: u64 = 200;
 
+/// A trait for fetching state updates.
 pub trait StateFetcher {
     async fn get_state_update(
         &self,
@@ -23,7 +24,9 @@ pub trait StateFetcher {
     ) -> Result<StateUpdate, TransportError>;
 
     async fn get_head(&self) -> Result<u64, TransportError>;
+
     async fn get_basefee(&self, block_number: Option<u64>) -> Result<u128, TransportError>;
+
     async fn get_account_state(
         &self,
         address: &Address,
@@ -31,13 +34,15 @@ pub trait StateFetcher {
     ) -> Result<AccountState, TransportError>;
 }
 
-#[derive(Clone)]
+/// A basic state fetcher that uses an RPC client to fetch state updates.
+#[derive(Clone, Debug)]
 pub struct StateClient {
     client: RpcClient,
     retry_backoff: Duration,
 }
 
 impl StateClient {
+    /// Create a new `StateClient` with the given URL and maximum retries.
     pub fn new(url: &str, max_retries: u32) -> Self {
         let client = RpcClient::new(url);
         Self {
diff --git a/bolt-sidecar/src/types/mod.rs b/bolt-sidecar/src/types/mod.rs
deleted file mode 100644
index a65058857..000000000
--- a/bolt-sidecar/src/types/mod.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-use alloy_primitives::U256;
-use ethereum_consensus::{
-    capella,
-    crypto::KzgCommitment,
-    deneb::mainnet::{BlobsBundle, ExecutionPayloadHeader, MAX_BLOB_COMMITMENTS_PER_BLOCK},
-    primitives::{BlsPublicKey, BlsSignature, Hash32},
-    serde::as_str,
-    ssz::prelude::*,
-    types::mainnet::ExecutionPayload,
-    Fork,
-};
-use tokio::sync::{mpsc, oneshot};
-
-pub mod commitment;
-pub mod constraint;
-pub mod transaction;
-
-/// An alias for a Beacon Chain slot number
-pub type Slot = u64;
-
-/// Minimal account state needed for commitment validation.
-#[derive(Debug, Clone, Copy)]
-pub struct AccountState {
-    /// The nonce of the account. This is the number of transactions sent from this account
-    /// and should be the
-    pub transaction_count: u64,
-    pub balance: U256,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct BuilderBid {
-    pub header: ExecutionPayloadHeader,
-    pub blob_kzg_commitments: List<KzgCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK>,
-    #[serde(with = "as_str")]
-    pub value: U256,
-    #[serde(rename = "pubkey")]
-    pub public_key: BlsPublicKey,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct SignedBuilderBid {
-    pub message: BuilderBid,
-    pub signature: BlsSignature,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct SignedBuilderBidWithProofs {
-    pub bid: SignedBuilderBid,
-    pub proofs: List<ConstraintProof, 300>,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct MerkleMultiProof {
-    // We use List here for SSZ, TODO: choose max
-    transaction_hashes: List<Hash32, 300>,
-    generalized_indexes: List<u64, 300>,
-    merkle_hashes: List<Hash32, 1000>,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct ConstraintProof {
-    #[serde(rename = "txHash")]
-    tx_hash: Hash32,
-    #[serde(rename = "merkleProof")]
-    merkle_proof: MerkleProof,
-}
-
-#[derive(Debug, Default, Clone, SimpleSerialize, serde::Serialize, serde::Deserialize)]
-pub struct MerkleProof {
-    index: u64,
-    // TODO: for now, max 1000
-    hashes: List<Hash32, 1000>,
-}
-
-pub struct FetchPayloadRequest {
-    pub slot: u64,
-    pub response: oneshot::Sender<Option<PayloadAndBid>>,
-}
-
-pub struct PayloadAndBid {
-    pub bid: SignedBuilderBid,
-    pub payload: GetPayloadResponse,
-}
-
-pub struct LocalPayloadFetcher {
-    tx: mpsc::Sender<FetchPayloadRequest>,
-}
-
-#[async_trait::async_trait]
-impl PayloadFetcher for LocalPayloadFetcher {
-    async fn fetch_payload(&self, slot: u64) -> Option<PayloadAndBid> {
-        let (tx, rx) = oneshot::channel();
-
-        let fetch_params = FetchPayloadRequest { slot, response: tx };
-
-        self.tx.send(fetch_params).await.ok()?;
-
-        rx.await.ok().flatten()
-    }
-}
-
-#[async_trait::async_trait]
-pub trait PayloadFetcher {
-    async fn fetch_payload(&self, slot: u64) -> Option<PayloadAndBid>;
-}
-
-pub struct NoopPayloadFetcher;
-
-#[async_trait::async_trait]
-impl PayloadFetcher for NoopPayloadFetcher {
-    async fn fetch_payload(&self, slot: u64) -> Option<PayloadAndBid> {
-        tracing::info!(slot, "Fetch payload called");
-        None
-    }
-}
-
-/// TODO: implement SSZ
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-pub struct PayloadAndBlobs {
-    pub execution_payload: ExecutionPayload,
-    pub blobs_bundle: Option<BlobsBundle>,
-}
-
-impl Default for PayloadAndBlobs {
-    fn default() -> Self {
-        Self {
-            execution_payload: ExecutionPayload::Capella(capella::ExecutionPayload::default()),
-            blobs_bundle: None,
-        }
-    }
-}
-
-#[derive(Debug, serde::Serialize)]
-#[serde(tag = "version", content = "data")]
-pub enum GetPayloadResponse {
-    #[serde(rename = "bellatrix")]
-    Bellatrix(ExecutionPayload),
-    #[serde(rename = "capella")]
-    Capella(ExecutionPayload),
-    #[serde(rename = "deneb")]
-    Deneb(PayloadAndBlobs),
-}
-
-impl GetPayloadResponse {
-    pub fn try_from_execution_payload(exec_payload: &PayloadAndBlobs) -> Option<Self> {
-        match exec_payload.execution_payload.version() {
-            Fork::Capella => Some(GetPayloadResponse::Capella(
-                exec_payload.execution_payload.clone(),
-            )),
-            Fork::Bellatrix => Some(GetPayloadResponse::Bellatrix(
-                exec_payload.execution_payload.clone(),
-            )),
-            Fork::Deneb => Some(GetPayloadResponse::Deneb(exec_payload.clone())),
-            _ => None,
-        }
-    }
-}
-
-impl<'de> serde::Deserialize<'de> for GetPayloadResponse {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: serde::Deserializer<'de>,
-    {
-        let value = serde_json::Value::deserialize(deserializer)?;
-        if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) {
-            return Ok(Self::Capella(inner));
-        }
-        if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) {
-            return Ok(Self::Deneb(inner));
-        }
-        if let Ok(inner) = <_ as serde::Deserialize>::deserialize(&value) {
-            return Ok(Self::Bellatrix(inner));
-        }
-        Err(serde::de::Error::custom(
-            "no variant could be deserialized from input for GetPayloadResponse",
-        ))
-    }
-}