diff --git a/bolt-cli/Cargo.lock b/bolt-cli/Cargo.lock index e1c9d6df7..5621db297 100644 --- a/bolt-cli/Cargo.lock +++ b/bolt-cli/Cargo.lock @@ -30,6 +30,19 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -39,6 +52,228 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "alloy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8ebf106e84a1c37f86244df7da0c7587e697b71a0d565cce079449b85ac6f8" +dependencies = [ + "alloy-consensus", + "alloy-contract", + "alloy-core", + "alloy-eips", + "alloy-genesis", + "alloy-network", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-serde", + "alloy-signer", + "alloy-signer-local", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", +] + +[[package]] +name = "alloy-chains" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4932d790c723181807738cf1ac68198ab581cd699545b155601332541ee47bd" +dependencies = [ + "alloy-primitives 0.8.9", + "num_enum", + "strum", +] + +[[package]] +name = "alloy-consensus" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-contract" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460ab80ce4bda1c80bcf96fe7460520476f2c7b734581c6567fac2708e2a60ef" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-types-eth", + "alloy-sol-types", + "alloy-transport", + "futures", + "futures-util", + "thiserror", +] + +[[package]] +name = "alloy-core" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cce174ca699ddee3bfb2ec1fbd99ad7efd05eca20c5c888d8320db41f7e8f04" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-sol-types", +] + +[[package]] +name = "alloy-dyn-abi" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5647fce5a168f9630f935bf7821c4207b1755184edaeba783cb4e11d35058484" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.8.9", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "itoa", + "serde", + "serde_json", + "winnow", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "derive_more 1.0.0", + "k256 0.13.4", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-genesis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde15e14944a88bd6a57d325e9a49b75558746fe16aaccc79713ae50a6a9574c" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b5671117c38b1c2306891f97ad3828d85487087f54ebe2c7591a055ea5bcea7" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "thiserror", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-serde", + "serde", +] + [[package]] name = "alloy-primitives" version = "0.7.7" @@ -89,16 +324,172 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-provider" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4814d141ede360bb6cd1b4b064f1aab9de391e7c4d0d4d50ac89ea4bc1e25fbd" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "futures-utils-wasm", + "lru", + "parking_lot", + "pin-project", + "reqwest", + "schnellru", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-pubsub" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ba46eb69ddf7a9925b81f15229cb74658e6eebe5dd30a5b74e2cd040380573" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives 0.8.9", + "alloy-transport", + "bimap", + "futures", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower 0.5.1", + "tracing", +] + [[package]] name = "alloy-rlp" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" dependencies = [ + "alloy-rlp-derive", "arrayvec", "bytes", ] +[[package]] +name = "alloy-rlp-derive" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "alloy-rpc-client" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc2bd1e7403463a5f2c61e955bcc9d3072b63aa177442b0f9aa6a6d22a941e3" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives 0.8.9", + "alloy-pubsub", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", + "futures", + "pin-project", + "reqwest", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower 0.5.1", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea9bf1abdd506f985a53533f5ac01296bcd6102c5e139bbc5d40bc468d2c916" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-engine" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886d22d41992287a235af2f3af4299b5ced2bcafb81eb835572ad35747476946" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "derive_more 1.0.0", + "serde", + "strum", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "derive_more 1.0.0", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" +dependencies = [ + "alloy-primitives 0.8.9", + "serde", + "serde_json", +] + [[package]] name = "alloy-signer" version = "0.5.3" @@ -113,6 +504,167 @@ dependencies = [ "thiserror", ] +[[package]] +name = "alloy-signer-local" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6614f02fc1d5b079b2a4a5320018317b506fd0a6d67c1fd5542a71201724986c" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives 0.8.9", + "alloy-signer", + "async-trait", + "k256 0.13.4", + "rand", + "thiserror", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0900b83f4ee1f45c640ceee596afbc118051921b9438fdb5a3175c1a7e05f8b" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41b1e78dde06b5e12e6702fa8c1d30621bf07728ba75b801fb801c9c6a0ba10" +dependencies = [ + "alloy-json-abi", + "alloy-sol-macro-input", + "const-hex", + "heck", + "indexmap 2.6.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.82", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91dc311a561a306664393407b88d3e53ae58581624128afd8a15faa5de3627dc" +dependencies = [ + "alloy-json-abi", + "const-hex", + "dunce", + "heck", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.82", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d1fbee9e698f3ba176b6e7a145f4aefe6d2b746b611e8bb246fe11a0e9f6c4" +dependencies = [ + "serde", + "winnow", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "086f41bc6ebcd8cb15f38ba20e47be38dd03692149681ce8061c35d960dbf850" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.8.9", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-transport" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be77579633ebbc1266ae6fd7694f75c408beb1aeb6865d0b18f22893c265a061" +dependencies = [ + "alloy-json-rpc", + "base64 0.22.1", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower 0.5.1", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-transport-http" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fd1a5d0827939847983b46f2f79510361f901dc82f8e3c38ac7397af142c6e" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest", + "serde_json", + "tower 0.5.1", + "tracing", + "url", +] + +[[package]] +name = "alloy-transport-ipc" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8073d1186bfeeb8fbdd1292b6f1a0731f3aed8e21e1463905abfae0b96a887a6" +dependencies = [ + "alloy-json-rpc", + "alloy-pubsub", + "alloy-transport", + "bytes", + "futures", + "interprocess", + "pin-project", + "serde_json", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "alloy-transport-ws" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f27837bb4a1d6c83a28231c94493e814882f0e9058648a97e908a5f3fc9fcf" +dependencies = [ + "alloy-pubsub", + "alloy-transport", + "futures", + "http", + "rustls", + "serde_json", + "tokio", + "tokio-tungstenite", + "tracing", + "ws_stream_wasm", +] + [[package]] name = "anstream" version = "0.6.15" @@ -346,6 +898,17 @@ dependencies = [ "syn 2.0.82", ] +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.1", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -488,6 +1051,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bimap" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" + [[package]] name = "bindgen" version = "0.69.5" @@ -602,8 +1171,7 @@ dependencies = [ name = "bolt" version = "0.1.0" dependencies = [ - "alloy-primitives 0.8.9", - "alloy-signer", + "alloy", "blst", "clap", "dotenvy", @@ -614,6 +1182,7 @@ dependencies = [ "inquire", "nu-ansi-term 0.50.1", "prost", + "rand", "reqwest", "rustls", "serde", @@ -835,6 +1404,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crossterm" version = "0.25.0" @@ -919,6 +1494,20 @@ dependencies = [ "cipher", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1022,6 +1611,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "doctest-file" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" + [[package]] name = "dotenvy" version = "0.15.7" @@ -1389,6 +1984,21 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -1396,6 +2006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -1404,6 +2015,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -1422,12 +2061,24 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + [[package]] name = "fuzzy-matcher" version = "0.3.7" @@ -1527,13 +2178,28 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" dependencies = [ + "allocator-api2", + "equivalent", "foldhash", + "serde", ] [[package]] @@ -1795,6 +2461,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown 0.15.0", + "serde", ] [[package]] @@ -1824,6 +2491,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "interprocess" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f4e4a06d42fab3e85ab1b419ad32b09eab58b901d40c57935ff92db3287a13" +dependencies = [ + "doctest-file", + "futures-core", + "libc", + "recvmsg", + "tokio", + "widestring", + "windows-sys 0.52.0", +] + [[package]] name = "ipnet" version = "2.10.1" @@ -1987,6 +2669,15 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + [[package]] name = "matchit" version = "0.7.3" @@ -2224,6 +2915,26 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + [[package]] name = "object" version = "0.36.5" @@ -2386,6 +3097,16 @@ dependencies = [ "indexmap 2.6.0", ] +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.1", +] + [[package]] name = "pin-project" version = "1.1.6" @@ -2519,6 +3240,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.82", +] + [[package]] name = "proc-macro2" version = "1.0.87" @@ -2631,6 +3374,7 @@ dependencies = [ "libc", "rand_chacha", "rand_core", + "serde", ] [[package]] @@ -2661,6 +3405,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "recvmsg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" + [[package]] name = "redox_syscall" version = "0.5.7" @@ -2973,6 +3723,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "schnellru" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3066,6 +3827,12 @@ dependencies = [ "pest", ] +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.210" @@ -3133,6 +3900,17 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + [[package]] name = "sha2" version = "0.9.9" @@ -3333,6 +4111,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.82", +] + [[package]] name = "subtle" version = "2.6.1" @@ -3361,6 +4161,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5e0c2ea8db64b2898b62ea2fbd60204ca95e0b2c6bdf53ff768bbe916fbe4d" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.82", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -3550,6 +4362,23 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", ] [[package]] @@ -3757,6 +4586,26 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -3855,6 +4704,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.2" @@ -3980,6 +4835,20 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "wasmtimer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ed9d8b15c7fb594d72bfb4b5a276f3d2029333cd93a932f376f5937f6f80ee" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.72" @@ -3990,6 +4859,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" @@ -4002,6 +4880,12 @@ dependencies = [ "rustix", ] +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + [[package]] name = "winapi" version = "0.3.9" @@ -4211,6 +5095,25 @@ dependencies = [ "memchr", ] +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.1", + "send_wrapper", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/bolt-cli/Cargo.toml b/bolt-cli/Cargo.toml index 747b99575..d40c45d09 100644 --- a/bolt-cli/Cargo.toml +++ b/bolt-cli/Cargo.toml @@ -25,8 +25,7 @@ blst = "0.3.12" # ethereum ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "cf3c404" } lighthouse_eth2_keystore = { package = "eth2_keystore", git = "https://github.com/sigp/lighthouse", rev = "a87f19d" } -alloy-primitives = "0.8.9" -alloy-signer = "0.5.2" +alloy = { version = "0.5.2", features = ["full"] } # utils dotenvy = "0.15.7" @@ -36,6 +35,7 @@ hex = "0.4.3" tracing = "0.1.40" tracing-subscriber = "0.3.18" reqwest = "0.12.8" +rand = "0.8.5" [dev-dependencies] tempfile = "3.13.0" diff --git a/bolt-cli/src/cli.rs b/bolt-cli/src/cli.rs index ca2019436..287c14465 100644 --- a/bolt-cli/src/cli.rs +++ b/bolt-cli/src/cli.rs @@ -2,12 +2,12 @@ use clap::{ builder::styling::{AnsiColor, Color, Style}, Parser, Subcommand, ValueEnum, }; -use serde::Deserialize; +use reqwest::Url; use crate::common::keystore::DEFAULT_KEYSTORE_PASSWORD; /// `bolt` is a CLI tool to interact with Bolt Protocol ✨ -#[derive(Parser, Debug, Clone, Deserialize)] +#[derive(Parser, Debug, Clone)] #[command(author, version, styles = cli_styles(), about, arg_required_else_help(true))] pub struct Opts { /// The subcommand to run. @@ -15,7 +15,7 @@ pub struct Opts { pub command: Commands, } -#[derive(Subcommand, Debug, Clone, Deserialize)] +#[derive(Subcommand, Debug, Clone)] pub enum Commands { /// Generate BLS delegation or revocation messages. Delegate(DelegateCommand), @@ -28,7 +28,7 @@ pub enum Commands { } /// Command for generating BLS delegation or revocation messages. -#[derive(Debug, Clone, Deserialize, Parser)] +#[derive(Debug, Clone, Parser)] pub struct DelegateCommand { /// The BLS public key to which the delegation message should be signed. #[clap(long, env = "DELEGATEE_PUBKEY")] @@ -53,7 +53,7 @@ pub struct DelegateCommand { } /// Command for outputting a list of pubkeys in JSON format. -#[derive(Debug, Clone, Deserialize, Parser)] +#[derive(Debug, Clone, Parser)] pub struct PubkeysCommand { /// The output file for the pubkeys. #[clap(long, env = "OUTPUT_FILE_PATH", default_value = "pubkeys.json")] @@ -65,11 +65,11 @@ pub struct PubkeysCommand { } /// Command for sending a preconfirmation request to a Bolt proposer. -#[derive(Debug, Clone, Deserialize, Parser)] +#[derive(Debug, Clone, Parser)] pub struct SendCommand { - /// Bolt Sidecar RPC URL to send requests to. - #[clap(long, env = "SIDECAR_RPC_URL")] - pub sidecar_rpc_url: String, + /// Bolt RPC URL to send requests to and fetch lookahead info from. + #[clap(long, env = "BOLT_RPC_URL", default_value = "http://135.181.191.125:58017")] + pub bolt_rpc_url: Url, /// The private key to sign the transaction with. #[clap(long, env = "PRIVATE_KEY", hide_env_values = true)] @@ -77,7 +77,7 @@ pub struct SendCommand { } /// The action to perform. -#[derive(Debug, Clone, ValueEnum, Deserialize)] +#[derive(Debug, Clone, ValueEnum)] #[clap(rename_all = "kebab_case")] pub enum Action { /// Create a delegation message. @@ -86,7 +86,7 @@ pub enum Action { Revoke, } -#[derive(Debug, Clone, Parser, Deserialize)] +#[derive(Debug, Clone, Parser)] pub enum KeySource { /// Use local secret keys to generate the signed messages. SecretKeys { @@ -112,7 +112,7 @@ pub enum KeySource { } /// Options for reading a keystore folder. -#[derive(Debug, Clone, Deserialize, Parser)] +#[derive(Debug, Clone, Parser)] pub struct LocalKeystoreOpts { /// The path to the keystore file. #[clap(long, env = "KEYSTORE_PATH", default_value = "validators")] @@ -139,7 +139,7 @@ pub struct LocalKeystoreOpts { } /// Options for connecting to a DIRK keystore. -#[derive(Debug, Clone, Deserialize, Parser)] +#[derive(Debug, Clone, Parser)] pub struct DirkOpts { /// The URL of the DIRK keystore. #[clap(long, env = "DIRK_URL")] @@ -160,7 +160,7 @@ pub struct DirkOpts { } /// TLS credentials for connecting to a remote server. -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Parser)] +#[derive(Debug, Clone, PartialEq, Eq, Parser)] pub struct TlsCredentials { /// Path to the client certificate file. (.crt) #[clap(long, env = "CLIENT_CERT_PATH")] @@ -174,7 +174,7 @@ pub struct TlsCredentials { } /// Supported chains for the CLI -#[derive(Debug, Clone, Copy, ValueEnum, Deserialize)] +#[derive(Debug, Clone, Copy, ValueEnum)] #[clap(rename_all = "kebab_case")] pub enum Chain { Mainnet, diff --git a/bolt-cli/src/commands/delegate.rs b/bolt-cli/src/commands/delegate.rs index e821332ae..4f1d9721d 100644 --- a/bolt-cli/src/commands/delegate.rs +++ b/bolt-cli/src/commands/delegate.rs @@ -1,5 +1,7 @@ -use alloy_primitives::B256; -use alloy_signer::k256::sha2::{Digest, Sha256}; +use alloy::{ + primitives::B256, + signers::k256::sha2::{Digest, Sha256}, +}; use ethereum_consensus::crypto::{ PublicKey as BlsPublicKey, SecretKey as BlsSecretKey, Signature as BlsSignature, }; diff --git a/bolt-cli/src/commands/send.rs b/bolt-cli/src/commands/send.rs index 4ead19080..ecfc53134 100644 --- a/bolt-cli/src/commands/send.rs +++ b/bolt-cli/src/commands/send.rs @@ -1,10 +1,142 @@ -use eyre::Result; +use alloy::{ + eips::eip2718::Encodable2718, + network::{EthereumWallet, TransactionBuilder}, + primitives::{keccak256, B256, U256}, + providers::{ProviderBuilder, SendableTx}, + rpc::types::TransactionRequest, + signers::{local::PrivateKeySigner, Signer}, +}; +use eyre::{bail, Context, Result}; +use rand::Rng; +use reqwest::Url; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tracing::info; use crate::cli::SendCommand; +/// Path to the lookahead endpoint on the Bolt RPC server. +const BOLT_LOOKAHEAD_PATH: &str = "proposers/lookahead?activeOnly=true&futureOnly=true"; + impl SendCommand { /// Run the `send` command. pub async fn run(self) -> Result<()> { + let wallet: PrivateKeySigner = self.private_key.parse().wrap_err("invalid private key")?; + let transaction_signer = EthereumWallet::from(wallet.clone()); + + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .wallet(transaction_signer) + .on_http(self.bolt_rpc_url.clone()); + + // Fetch the lookahead info from the Bolt RPC server + let lookahead_url = self.bolt_rpc_url.join(BOLT_LOOKAHEAD_PATH)?; + let lookahead_res = reqwest::get(lookahead_url).await?.json::>().await?; + if lookahead_res.is_empty() { + println!("no bolt proposer found in the lookahead, try again later 🥲"); + return Ok(()); + } + + // Extract the next preconfirmer slot from the lookahead info + let next_preconfirmer_slot = lookahead_res[0].slot; + info!("Next preconfirmer slot: {}", next_preconfirmer_slot); + + // generate a simple self-transfer of ETH + let random_data = rand::thread_rng().gen::<[u8; 32]>(); + let req = TransactionRequest::default() + .with_to(wallet.address()) + .with_value(U256::from(100_000)) + .with_input(random_data); + + let raw_tx = match provider.fill(req).await? { + SendableTx::Builder(_) => bail!("expected a raw transaction"), + SendableTx::Envelope(raw) => raw.encoded_2718(), + }; + let tx_hash = B256::from(keccak256(&raw_tx)); + + send_rpc_request( + vec![hex::encode(&raw_tx)], + vec![tx_hash], + next_preconfirmer_slot, + self.bolt_rpc_url, + &wallet, + ) + .await?; + Ok(()) } } + +async fn send_rpc_request( + txs_rlp: Vec, + tx_hashes: Vec, + target_slot: u64, + target_sidecar_url: Url, + wallet: &PrivateKeySigner, +) -> Result<()> { + let request = prepare_rpc_request( + "bolt_requestInclusion", + serde_json::json!({ + "slot": target_slot, + "txs": txs_rlp, + }), + ); + + info!(?tx_hashes, target_slot, %target_sidecar_url); + let signature = sign_request(tx_hashes, target_slot, wallet).await?; + + let response = reqwest::Client::new() + .post(target_sidecar_url) + .header("content-type", "application/json") + .header("x-bolt-signature", signature) + .body(serde_json::to_string(&request)?) + .send() + .await?; + + let response = response.text().await?; + + // strip out long series of zeros in the response (to avoid spamming blob contents) + let response = response.replace(&"0".repeat(32), ".").replace(&".".repeat(4), ""); + info!("Response: {:?}", response); + Ok(()) +} + +async fn sign_request( + tx_hashes: Vec, + target_slot: u64, + wallet: &PrivateKeySigner, +) -> eyre::Result { + let digest = { + let mut data = Vec::new(); + let hashes = tx_hashes.iter().map(|hash| hash.as_slice()).collect::>().concat(); + data.extend_from_slice(&hashes); + data.extend_from_slice(target_slot.to_le_bytes().as_slice()); + keccak256(data) + }; + + let signature = hex::encode(wallet.sign_hash(&digest).await?.as_bytes()); + + Ok(format!("{}:0x{}", wallet.address(), signature)) +} + +fn prepare_rpc_request(method: &str, params: Value) -> Value { + serde_json::json!({ + "id": "1", + "jsonrpc": "2.0", + "method": method, + "params": vec![params], + }) +} + +/// Info about a specific slot in the beacon chain lookahead. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LookaheadSlot { + /// Slot number in the beacon chain + pub slot: u64, + /// Validator index that will propose in this slot + pub validator_index: u64, + /// Validator pubkey that will propose in this slot + pub validator_pubkey: String, + /// Optional URL of the Bolt sidecar associated with the proposer + pub sidecar_url: Option, +} diff --git a/bolt-cli/src/common/bolt_manager.rs b/bolt-cli/src/common/bolt_manager.rs new file mode 100644 index 000000000..78550494b --- /dev/null +++ b/bolt-cli/src/common/bolt_manager.rs @@ -0,0 +1,155 @@ +use std::str::FromStr; + +use alloy::{ + contract::{Error as ContractError, Result as ContractResult}, + primitives::{Address, Bytes, B256}, + providers::{ProviderBuilder, RootProvider}, + sol, + sol_types::{Error as SolError, SolInterface}, + transports::{http::Http, TransportError}, +}; +use reqwest::{Client, Url}; +use serde::Serialize; + +use BoltManagerContract::{BoltManagerContractErrors, BoltManagerContractInstance, ProposerStatus}; + +/// Bolt Manager contract bindings. +#[derive(Debug, Clone)] +pub struct BoltManager(BoltManagerContractInstance, RootProvider>>); + +impl BoltManager { + /// Creates a new BoltManager instance. + pub fn new>(execution_client_url: U, manager_address: Address) -> Self { + let provider = ProviderBuilder::new().on_http(execution_client_url.into()); + let manager = BoltManagerContract::new(manager_address, provider); + + Self(manager) + } + + /// Gets the sidecar RPC URL for a given validator index. + /// + /// Returns Ok(None) if the operator is not found in the registry. + pub async fn get_sidecar_rpc_url_for_validator( + &self, + pubkey_hash: B256, + ) -> ContractResult> { + let registrant = self.get_proposer_status(pubkey_hash).await?; + Ok(registrant.and_then(|r| if r.active { Some(r.operatorRPC) } else { None })) + } + + /// Gets the proposer status for a given pubkeyhash. + /// + /// Returns Ok(None) if the proposer is not found in the registry. + pub async fn get_proposer_status( + &self, + pubkey_hash: B256, + ) -> ContractResult> { + let returndata = self.0.getProposerStatus(pubkey_hash).call().await; + + // TODO: clean this after https://github.com/alloy-rs/alloy/issues/787 is merged + let error = match returndata.map(|data| data._0) { + Ok(proposer) => return Ok(Some(proposer)), + Err(error) => match error { + ContractError::TransportError(TransportError::ErrorResp(err)) => { + let data = err.data.unwrap_or_default(); + let data = data.get().trim_matches('"'); + let data = Bytes::from_str(data).unwrap_or_default(); + + BoltManagerContractErrors::abi_decode(&data, true)? + } + e => return Err(e), + }, + }; + + if matches!(error, BoltManagerContractErrors::ValidatorDoesNotExist(_)) { + Ok(None) + } else { + Err(SolError::custom(format!( + "unexpected Solidity error selector: {:?}", + error.selector() + )) + .into()) + } + } +} + +sol! { + #[sol(rpc)] + interface BoltManagerContract { + #[derive(Debug, Default, Serialize)] + struct ProposerStatus { + bytes32 pubkeyHash; + bool active; + address operator; + string operatorRPC; + address[] collaterals; + uint256[] amounts; + } + + function getProposerStatus(bytes32 pubkeyHash) external view returns (ProposerStatus memory); + + error InvalidQuery(); + error ValidatorDoesNotExist(); + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use alloy::primitives::U256; + + use super::*; + + #[tokio::test] + async fn test_get_operators_helder() -> eyre::Result<()> { + let registry = BoltManager::new( + Url::parse("http://remotebeast:4485")?, + Address::from_str("0xdF11D829eeC4C192774F3Ec171D822f6Cb4C14d9")?, + ); + + let sample_pubkey = B256::from_str("0xsamplepubkeyhash").expect("invalid pubkey"); + + let registrant = registry.get_proposer_status(sample_pubkey).await; + assert!(matches!(registrant, Ok(None))); + + let invalid_pubkey = B256::from_str("0xinvalidsamplepubkeyhash").expect("invalid pubkey"); + let registrant = match registry.get_proposer_status(invalid_pubkey).await { + Ok(Some(registrant)) => registrant, + e => panic!("unexpected error reading from registry: {:?}", e), + }; + + let expected = ProposerStatus { + pubkeyHash: sample_pubkey, + active: true, + operator: Address::from_str("0xad3cd1b81c80f4a495d6552ae6423508492a27f8")?, + operatorRPC: "http://sampleoperatorrpc:8000".to_string(), + collaterals: vec![Address::from_str("0xsamplecollateral1")?], + amounts: vec![U256::from(10000000000000000000u128)], + }; + + assert_eq!(registrant.pubkeyHash, expected.pubkeyHash); + assert_eq!(registrant.active, expected.active); + assert_eq!(registrant.operator, expected.operator); + assert_eq!(registrant.operatorRPC, expected.operatorRPC); + assert_eq!(registrant.collaterals, expected.collaterals); + assert_eq!(registrant.amounts, expected.amounts); + + Ok(()) + } + + #[tokio::test] + async fn test_check_validator_helder() -> eyre::Result<()> { + let registry = BoltManager::new( + Url::parse("http://remotebeast:48545")?, + Address::from_str("0xdF11D829eeC4C192774F3Ec171D822f6Cb4C14d9")?, + ); + + let pubkey_hash = B256::from_str("0xsamplepubkeyhash").expect("invalid pubkey"); + let registrant = registry.get_sidecar_rpc_url_for_validator(pubkey_hash).await?; + assert!(registrant.is_some()); + + dbg!(®istrant); + Ok(()) + } +} diff --git a/bolt-cli/src/common/dirk.rs b/bolt-cli/src/common/dirk.rs index dc5e594eb..75148bab8 100644 --- a/bolt-cli/src/common/dirk.rs +++ b/bolt-cli/src/common/dirk.rs @@ -1,6 +1,6 @@ use std::fs; -use alloy_primitives::B256; +use alloy::primitives::B256; use ethereum_consensus::crypto::bls::Signature as BlsSignature; use eyre::{bail, Context, Result}; use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity}; diff --git a/bolt-cli/src/common/mod.rs b/bolt-cli/src/common/mod.rs index efee3e63e..b152a4614 100644 --- a/bolt-cli/src/common/mod.rs +++ b/bolt-cli/src/common/mod.rs @@ -4,6 +4,9 @@ use ethereum_consensus::crypto::PublicKey as BlsPublicKey; use eyre::{Context, Result}; use serde::Serialize; +/// BoltManager contract bindings. +pub mod bolt_manager; + /// Utilities for working with DIRK remote keystores. pub mod dirk; diff --git a/bolt-cli/src/common/signing.rs b/bolt-cli/src/common/signing.rs index 07d3a6590..59c70a220 100644 --- a/bolt-cli/src/common/signing.rs +++ b/bolt-cli/src/common/signing.rs @@ -1,4 +1,4 @@ -use alloy_primitives::B256; +use alloy::primitives::B256; use blst::{min_pk::Signature, BLST_ERROR}; use ethereum_consensus::{ crypto::PublicKey as BlsPublicKey,