diff --git a/Cargo.lock b/Cargo.lock index e883539c..227a6e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992a9d0732a0e0e1a34d61a6553ad28f761c9049bb46572d3916f172348d2cb7" +checksum = "2e2a5d689ccd182f1d138a61f081841b905034e0089f5278f6c200f2bcdab00a" dependencies = [ "alloy-consensus", "alloy-contract", @@ -51,9 +51,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2672194d5865f00b03e5c7844d2c6f172a842e5c3bc49d7f9b871c42c95ae65" +checksum = "ef8ff73a143281cb77c32006b04af9c047a6b8fe5860e85a88ad325328965355" dependencies = [ "alloy-primitives", "num_enum", @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35f021a55afd68ff2364ccfddaa364fc9a38a72200cdc74fcfb8dc3231d38f2c" +checksum = "d213580c17d239ae83c0d897ac3315db7cda83d2d4936a9823cc3517552f2e24" dependencies = [ "alloy-eips", "alloy-primitives", @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0ecca7a71b1f88e63d19e2d9397ce56949d3dd3484fd73c73d0077dc5c93d4" +checksum = "81443e3b8dccfeac7cd511aced15928c97ff253f4177acbb97de97178e543f6c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -101,9 +101,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd26132cbfa6e5f191a01f7b9725eaa0680a953be1fd005d588b0e9422c16456" +checksum = "de217ab604f1bcfa2e3b0aff86d50812d5931d47522f9f0a949cc263ec2d108e" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7473a19f02b25f8e1e8c69d35f02c07245694d11bd91bfe00e9190ac106b3838" +checksum = "2a15b4b0f6bab47aae017d52bb5a739bda381553c09fb9918b7172721ef5f5de" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -204,14 +204,16 @@ dependencies = [ "derive_more", "either", "serde", + "serde_with", "sha2", + "thiserror 2.0.17", ] [[package]] name = "alloy-genesis" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b2c29f25098bfa4cd3d9ec7806e1506716931e188c7c0843284123831c2cf1" +checksum = "33ba1cbc25a07e0142e8875fcbe80e1fdb02be8160ae186b90f4b9a69a72ed2b" dependencies = [ "alloy-eips", "alloy-primitives", @@ -235,9 +237,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4d1f49fdf9780b60e52c20ffcc1e352d8d27885cc8890620eb584978265dd9" +checksum = "f8882ec8e4542cfd02aadc6dccbe90caa73038f60016d936734eb6ced53d2167" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -250,9 +252,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2991c432e149babfd996194f8f558f85d7326ac4cf52c55732d32078ff0282d4" +checksum = "51d6d87d588bda509881a7a66ae77c86514bd1193ac30fbff0e0f24db95eb5a5" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -276,9 +278,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d540d962ddbc3e95153bafe56ccefeb16dfbffa52c5f7bdd66cd29ec8f52259" +checksum = "5b14fa9ba5774e0b30ae6a04176d998211d516c8af69c9c530af7c6c42a8c508" dependencies = [ "alloy-consensus", "alloy-eips", @@ -316,9 +318,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e96d8084a1cf96be2df6219ac407275ac20c1136fa01f911535eb489aa006e8" +checksum = "475a5141313c3665b75d818be97d5fa3eb5e0abb7e832e9767edd94746db28e3" dependencies = [ "alloy-chains", "alloy-consensus", @@ -377,9 +379,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194ff51cd1d2e65c66b98425e0ca7eb559ca1a579725834c986d84faf8e224c0" +checksum = "25289674cd8c58fcca2568b5350423cb0dd7bca8c596c5e2869bfe4c5c57ed14" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -400,9 +402,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d4fe522f6fc749c8afce721bdc8f73b715d317c3c02fcb9b51f7a143e4401dd" +checksum = "39676beaa50db545cf15447fc94ec5513b64e85a48357a0625b9a04aef08a910" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -412,9 +414,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "124b742619519d5932e586631f11050028b29c30e3e195f2bb04228c886253d6" +checksum = "01bac57c987c93773787619e20f89167db74d460a2d1d40f591d94fb7c22c379" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -423,9 +425,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781d4d5020bea8f020e164f5593101c2e2f790d66d04a0727839d03bc4411ed7" +checksum = "1cd1e1b4dcdf13eaa96343e5c0dafc2d2e8ce5d20b90347169d46a1df0dec210" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -444,9 +446,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30be84f45d4f687b00efaba1e6290cbf53ccc8f6b8fbb54e4c2f9d2a0474ce95" +checksum = "f1b3b1078b8775077525bc9fe9f6577e815ceaecd6c412a4f3b4d8aa2836e8f6" dependencies = [ "alloy-primitives", "serde", @@ -455,9 +457,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8c24b883fe56395db64afcd665fca32dcdef670a59e5338de6892c2e38d7e9" +checksum = "10ab1b8d4649bf7d0db8ab04e31658a6cc20364d920795484d886c35bed3bab4" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -472,15 +474,16 @@ dependencies = [ [[package]] name = "alloy-signer-aws" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b806737bea3c5091982b8571f36d0ee324f0dcbaef7fedf6bbffbb63f04c5653" +checksum = "a46118173eb381b2911202a83dc4f39267027b0fe7d3533449f5e4ebc0eadcab" dependencies = [ "alloy-consensus", "alloy-network", "alloy-primitives", "alloy-signer", "async-trait", + "aws-config", "aws-sdk-kms", "k256", "spki", @@ -490,9 +493,9 @@ dependencies = [ [[package]] name = "alloy-signer-gcp" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ebe6b2f97da5e3033be4d2936ba01f3ea82b0573814cb14bf4778db3fde42f5" +checksum = "b8a6aae8a120c191cc5b333bafa9877b3d5ccb2174ea25b6c2c08df28ca9d64b" dependencies = [ "alloy-consensus", "alloy-network", @@ -508,9 +511,9 @@ dependencies = [ [[package]] name = "alloy-signer-ledger" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d1c7a2c6d8d6532235b65fb40a298fe55df73311c212d368d48fb8ed9b03ce" +checksum = "feb0444055415b5d97c84b0f5d7a611849e68b63caa574aa1737035310dc1dba" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -528,9 +531,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05724615fd2ec3417f5cd07cab908300cbb3aae5badc1b805ca70c555b26775f" +checksum = "7bdeec36c8d9823102b571b3eab8b323e053dc19c12da14a9687bd474129bf2a" dependencies = [ "alloy-consensus", "alloy-network", @@ -617,9 +620,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b7f8b6c540b55e858f958d3a92223494cf83c4fb43ff9b26491edbeb3a3b71" +checksum = "dce5129146a76ca6139a19832c75ad408857a56bcd18cd2c684183b8eacd78d8" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -641,9 +644,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260e9584dfd7998760d7dfe1856c6f8f346462b9e7837287d7eddfb3922ef275" +checksum = "e2379d998f46d422ec8ef2b61603bc28cda931e5e267aea1ebe71f62da61d101" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -672,12 +675,12 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e29436068f836727d4e7c819ae6bf6f9c9e19a32e96fc23e814709a277f23a" +checksum = "3b5becb9c269a7d05a2f28d549f86df5a5dbc923e2667eff84fdecac8cda534c" dependencies = [ "alloy-primitives", - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", @@ -851,15 +854,13 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6448dfb3960f0b038e88c781ead1e7eb7929dfc3a71a1336ec9086c00f6d1e75" +checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" dependencies = [ "compression-codecs", "compression-core", - "flate2", "futures-core", - "memchr", "pin-project-lite", "tokio", ] @@ -920,11 +921,36 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-config" +version = "1.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bc1b40fb26027769f16960d2f4a6bc20c4bb755d403e552c8c1a73af433c246" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 1.3.1", + "time", + "tokio", + "tracing", + "url", +] + [[package]] name = "aws-credential-types" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1541072f81945fa1251f8795ef6c92c4282d74d59f88498ae7d4bf00f0ebdad9" +checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -958,9 +984,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.84.0" +version = "1.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98037a2a0745914d2f0fee41acb6cf88a76f0ed31dd75753b4dc318aa5a4da39" +checksum = "15e7ef7189e532a6d7654befd668b535d31f261c61342397da47ccfa3fb0505a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -978,6 +1004,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "aws-sdk-sts" +version = "1.85.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410309ad0df4606bc721aff0d89c3407682845453247213a0ccc5ff8801ee107" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] + [[package]] name = "aws-sigv4" version = "1.3.4" @@ -1033,9 +1082,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.61.4" +version = "0.61.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16e040799d29c17412943bdbf488fd75db04112d0c0d4b9290bacf5ae0014b9" +checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" dependencies = [ "aws-smithy-types", ] @@ -1049,11 +1098,21 @@ dependencies = [ "aws-smithy-runtime-api", ] +[[package]] +name = "aws-smithy-query" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + [[package]] name = "aws-smithy-runtime" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d57c8b53a72d15c8e190475743acf34e4996685e346a3448dd54ef696fc6e0" +checksum = "d3946acbe1ead1301ba6862e712c7903ca9bb230bdf1fbd1b5ac54158ef2ab1f" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -1112,6 +1171,15 @@ dependencies = [ "time", ] +[[package]] +name = "aws-smithy-xml" +version = "0.60.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db87b96cb1b16c024980f133968d52882ca0daaee3a086c6decc500f6c99728" +dependencies = [ + "xmlparser", +] + [[package]] name = "aws-types" version = "1.3.8" @@ -1243,9 +1311,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitvec" @@ -1352,10 +1420,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.34" +version = "1.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "590f9024a68a8c40351881787f1934dc11afd69090f5edb6831464694d836ea3" dependencies = [ + "find-msvc-tools", "shlex", ] @@ -1422,22 +1491,20 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46cc6539bf1c592cff488b9f253b30bc0ec50d15407c2cf45e27bd8f308d5905" +checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" dependencies = [ "compression-core", "flate2", - "futures-core", "memchr", - "pin-project-lite", ] [[package]] name = "compression-core" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2957e823c15bde7ecf1e8b64e537aa03a6be5fda0e2334e99887669e75b12e01" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "const-hex" @@ -1610,7 +1677,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a707ceda8652f6c7624f2be725652e9524c815bf3b9d55a0b2320be2303f9c11" dependencies = [ - "darling", + "darling 0.20.11", "proc-macro2", "quote", "syn 2.0.106", @@ -1623,8 +1690,18 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -1641,13 +1718,39 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim", + "syn 2.0.106", +] + [[package]] name = "darling_macro" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core", + "darling_core 0.20.11", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", "quote", "syn 2.0.106", ] @@ -1685,9 +1788,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", "serde", @@ -1911,6 +2014,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e178e4fba8a2726903f6ba98a6d221e76f9c12c650d5dc0e6afdc50677b49650" + [[package]] name = "firestorm" version = "0.5.1" @@ -2151,7 +2260,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.3+wasi-0.2.4", ] [[package]] @@ -2167,6 +2276,7 @@ dependencies = [ "anyhow", "assert_matches", "axum", + "base64", "custom_debug", "faster-hex", "futures", @@ -2954,9 +3064,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "loom" @@ -3212,7 +3322,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -3450,9 +3560,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3545,7 +3655,7 @@ checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.3", + "bitflags 2.9.4", "lazy_static", "num-traits", "rand 0.9.2", @@ -3758,7 +3868,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -3971,7 +4081,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", @@ -4160,7 +4270,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -4173,7 +4283,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -4297,7 +4407,7 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" dependencies = [ - "darling", + "darling 0.20.11", "proc-macro2", "quote", "syn 2.0.106", @@ -4601,7 +4711,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4779,12 +4889,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde", @@ -4794,15 +4903,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -5001,7 +5110,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-util", "http 1.3.1", @@ -5198,6 +5307,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -5206,9 +5321,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -5265,11 +5380,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] @@ -5358,9 +5473,9 @@ dependencies = [ [[package]] name = "wasmtimer" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d49b5d6c64e8558d9b1b065014426f35c18de636895d24893dbbd329743446" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", @@ -5765,13 +5880,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" [[package]] name = "writeable" @@ -5788,6 +5900,12 @@ dependencies = [ "tap", ] +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yoke" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 8369c46b..d041840e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ axum = { version = "0.8.1", default-features = false, features = [ "tokio", "http1", ] } +base64 = "0.22.1" custom_debug = "0.6.1" faster-hex = "0.10.0" futures = "0.3" @@ -46,8 +47,8 @@ serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0.116", features = ["raw_value"] } serde_with = "3.8.1" snmalloc-rs = "0.3" -tap_graph = "0.3.3" -thegraph-core = { version = "0.15", features = [ +tap_graph = { version = "0.3.4", features = ["v2"] } +thegraph-core = { version = "0.15.1", features = [ "alloy-contract", "alloy-signer-local", "attestation", diff --git a/README.md b/README.md index 01f13dcc..a7e1bf28 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ client query. Indexer fees are clamped to a maximum of the gateway's budget. For an overview of TAP see https://github.com/semiotic-ai/timeline-aggregation-protocol. -The gateway acts as a TAP sender, where each indexer request is sent with a TAP receipt. The gateway +This is a horizon-ready gateway that generates TAP v2 receipts exclusively. The gateway acts as a TAP sender, where each indexer request is sent with a TAP v2 receipt. The gateway operator is expected to run 2 additional services: - [tap-aggregator](https://github.com/semiotic-ai/timeline-aggregation-protocol/tree/main/tap_aggregator): @@ -113,7 +113,7 @@ operator is expected to run 2 additional services: The gateway operator is also expected to manage at least 2 wallets: - sender: requires ETH for transaction gas and GRT to allocate into TAP escrow balances for paying indexers -- authorized signer: used by the gateway and tap-aggregator to sign receipts and RAVs +- authorized signer: used by the gateway and tap-aggregator to sign v2 receipts and RAVs ## operational notes diff --git a/src/client_query.rs b/src/client_query.rs index 281c69d7..71c0f8a8 100644 --- a/src/client_query.rs +++ b/src/client_query.rs @@ -285,7 +285,10 @@ async fn run_indexer_queries( let min_fee = *(min_fee.0 * grt_per_usd * one_grt) / selections.len() as f64; let indexer_fee = selection.fee.as_f64() * budget as f64; let fee = indexer_fee.max(min_fee) as u128; - let receipt = match ctx.receipt_signer.create_receipt(largest_allocation, fee) { + let receipt = match ctx + .receipt_signer + .create_receipt(largest_allocation, *indexer, fee) + { Ok(receipt) => receipt, Err(err) => { tracing::error!(?indexer, %deployment, error=?err, "failed to create receipt"); @@ -303,7 +306,11 @@ async fn run_indexer_queries( let start_time = Instant::now(); // URL checked: ref df8e647b-1e6e-422a-8846-dc9ee7e0dcc2 let deployment_url = url.join(&format!("subgraphs/id/{deployment}")).unwrap(); - let auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain); + let auth = IndexerAuth::Paid( + &receipt, + ctx.attestation_domain, + ctx.legacy_attestation_domain, + ); let result = indexer_client .query_indexer(deployment_url, auth, &indexer_query) .in_current_span() @@ -682,7 +689,7 @@ pub async fn handle_indexer_query( let fee = *(ctx.budgeter.query_fees_target.0 * grt_per_usd * one_grt) as u128; let allocation = indexing.largest_allocation; - let receipt = match ctx.receipt_signer.create_receipt(allocation, fee) { + let receipt = match ctx.receipt_signer.create_receipt(allocation, *indexer, fee) { Ok(receipt) => receipt, Err(err) => { return Err(Error::Internal(anyhow!("failed to create receipt: {err}"))); @@ -695,7 +702,11 @@ pub async fn handle_indexer_query( .url .join(&format!("subgraphs/id/{deployment}")) .unwrap(); - let indexer_auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain); + let indexer_auth = IndexerAuth::Paid( + &receipt, + ctx.attestation_domain, + ctx.legacy_attestation_domain, + ); let indexer_start_time = Instant::now(); let result = ctx diff --git a/src/client_query/context.rs b/src/client_query/context.rs index 99737a53..644c67f9 100644 --- a/src/client_query/context.rs +++ b/src/client_query/context.rs @@ -18,5 +18,6 @@ pub struct Context { pub network: NetworkService, pub indexing_perf: IndexingPerformance, pub attestation_domain: &'static Eip712Domain, + pub legacy_attestation_domain: &'static Eip712Domain, pub reporter: mpsc::UnboundedSender, } diff --git a/src/config.rs b/src/config.rs index 1a0c0672..44064466 100644 --- a/src/config.rs +++ b/src/config.rs @@ -46,7 +46,7 @@ pub struct Config { /// Minimum indexer-service version that will receive queries #[serde_as(as = "DisplayFromStr")] pub min_indexer_version: Version, - /// Indexers used to query the network subgraph + /// Trusted indexers that can serve the network subgraph for free pub trusted_indexers: Vec, /// Maximum acceptable lag (in seconds) for network subgraph responses (default: 120) #[serde(default = "default_network_subgraph_max_lag_seconds")] @@ -61,6 +61,8 @@ pub struct Config { #[serde(deserialize_with = "deserialize_not_nan_f64")] pub query_fees_target: NotNan, pub receipts: Receipts, + /// Address for the Subgraph Service + pub subgraph_service: Address, } /// Default network subgraph max lag threshold (120 seconds) @@ -128,6 +130,7 @@ pub enum BlocklistEntry { pub struct AttestationConfig { pub chain_id: String, pub dispute_manager: Address, + pub legacy_dispute_manager: Address, } /// The exchange rate provider. @@ -183,6 +186,8 @@ impl From for rdkafka::config::ClientConfig { pub struct Receipts { /// TAP verifier contract chain pub chain_id: U256, + /// TAP payer address + pub payer: Address, /// TAP signer key pub signer: B256, /// TAP verifier contract address diff --git a/src/indexer_client.rs b/src/indexer_client.rs index b6d27944..104ae2dc 100644 --- a/src/indexer_client.rs +++ b/src/indexer_client.rs @@ -35,7 +35,7 @@ pub struct IndexerClient { } pub enum IndexerAuth<'a> { - Paid(&'a Receipt, &'a Eip712Domain), + Paid(&'a Receipt, &'a Eip712Domain, &'a Eip712Domain), Free(&'a str), } @@ -47,7 +47,7 @@ impl IndexerClient { query: &str, ) -> Result { let (auth_key, auth_value) = match auth { - IndexerAuth::Paid(receipt, _) => ("Tap-Receipt", receipt.serialize()), + IndexerAuth::Paid(receipt, _, _) => ("tap-receipt", receipt.serialize()), IndexerAuth::Free(token) => (AUTHORIZATION.as_str(), format!("Bearer {token}")), }; @@ -113,18 +113,26 @@ impl IndexerClient { return Err(BadResponse(format!("unattestable response: {error}"))); } - if let IndexerAuth::Paid(receipt, attestation_domain) = auth { + if let IndexerAuth::Paid(receipt, attestation_domain, legacy_attestation_domain) = auth { match &payload.attestation { Some(attestation) => { let allocation = receipt.allocation(); - if let Err(err) = attestation::verify( + if let Err(legacy_err) = attestation::verify( + legacy_attestation_domain, + attestation, + &allocation, + query, + &original_response, + ) && let Err(err) = attestation::verify( attestation_domain, attestation, &allocation, query, &original_response, ) { - return Err(BadResponse(format!("bad attestation: {err}"))); + return Err(BadResponse(format!( + "bad attestation: {legacy_err} - {err}" + ))); } } None => { diff --git a/src/main.rs b/src/main.rs index aaf12ed8..328dcada 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,6 +104,15 @@ async fn main() { conf.attestations.dispute_manager, ))); + let legacy_attestation_domain: &'static Eip712Domain = + Box::leak(Box::new(attestation::eip712_domain( + conf.attestations + .chain_id + .parse::() + .expect("failed to parse attestation domain chain_id"), + conf.attestations.legacy_dispute_manager, + ))); + let indexer_client = IndexerClient { client: http_client.clone(), }; @@ -134,9 +143,11 @@ async fn main() { network.wait_until_ready().await; let receipt_signer: &'static ReceiptSigner = Box::leak(Box::new(ReceiptSigner::new( + conf.receipts.payer, receipt_signer, conf.receipts.chain_id, conf.receipts.verifier, + conf.subgraph_service, ))); let auth_service = init_auth_service( @@ -171,6 +182,7 @@ async fn main() { indexing_perf, network, attestation_domain, + legacy_attestation_domain, reporter, }; diff --git a/src/network/subgraph_client.rs b/src/network/subgraph_client.rs index 87b44899..535ed8bd 100644 --- a/src/network/subgraph_client.rs +++ b/src/network/subgraph_client.rs @@ -94,7 +94,7 @@ pub mod types { #[serde_as] #[derive(Clone, CustomDebug, Deserialize)] pub struct TrustedIndexer { - /// network subgraph endpoint + /// Complete network subgraph endpoint URL (e.g., http://indexer:7601/subgraphs/id/Qmc2Cb...) #[debug(with = std::fmt::Display::fmt)] #[serde_as(as = "serde_with::DisplayFromStr")] pub url: Url, diff --git a/src/receipts.rs b/src/receipts.rs index 63dc333a..cfff6d7c 100644 --- a/src/receipts.rs +++ b/src/receipts.rs @@ -1,9 +1,10 @@ use std::time::SystemTime; -use rand::RngCore; -use tap_graph::{Receipt as TapReceipt, SignedReceipt}; +use base64::{Engine as _, prelude::BASE64_STANDARD}; +use prost::Message as _; +use rand::RngCore as _; use thegraph_core::{ - AllocationId, + AllocationId, CollectionId, alloy::{ dyn_abi::Eip712Domain, primitives::{Address, U256}, @@ -11,7 +12,8 @@ use thegraph_core::{ }, }; -pub struct Receipt(SignedReceipt); +#[derive(Debug, Clone)] +pub struct Receipt(pub tap_graph::v2::SignedReceipt); impl Receipt { pub fn value(&self) -> u128 { @@ -19,56 +21,121 @@ impl Receipt { } pub fn allocation(&self) -> Address { - self.0.message.allocation_id + // TAP v2 receipts use collection ids which are 32 bytes. + // For the Subgraph Service these are 20 byte allocation ids with zero padding. + CollectionId::from(self.0.message.collection_id).as_address() } pub fn serialize(&self) -> String { - serde_json::to_string(&self.0).unwrap() + #[derive(prost::Message)] + struct ReceiptMessage { + #[prost(bytes, tag = "1")] + collection_id: Vec, + #[prost(bytes, tag = "2")] + payer: Vec, + #[prost(bytes, tag = "3")] + data_service: Vec, + #[prost(bytes, tag = "4")] + service_provider: Vec, + #[prost(uint64, tag = "5")] + timestamp_ns: u64, + #[prost(uint64, tag = "6")] + nonce: u64, + #[prost(message, optional, tag = "7")] + value: Option, + } + #[derive(prost::Message)] + struct Uint128 { + #[prost(uint64, tag = "1")] + high: u64, + #[prost(uint64, tag = "2")] + low: u64, + } + #[derive(prost::Message)] + struct SignedReceipt { + #[prost(message, optional, tag = "1")] + message: Option, + #[prost(bytes, tag = "2")] + signature: Vec, + } + let receipt_message = ReceiptMessage { + collection_id: self.0.message.collection_id.to_vec(), + payer: self.0.message.payer.to_vec(), + data_service: self.0.message.data_service.to_vec(), + service_provider: self.0.message.service_provider.to_vec(), + timestamp_ns: self.0.message.timestamp_ns, + nonce: self.0.message.nonce, + value: Some(Uint128 { + high: (self.0.message.value >> 64) as u64, + low: self.0.message.value as u64, + }), + }; + let signature_bytes = self.0.signature.as_bytes().to_vec(); + + let signed_receipt = SignedReceipt { + message: Some(receipt_message), + signature: signature_bytes, + }; + + BASE64_STANDARD.encode(signed_receipt.encode_to_vec()) } } pub struct ReceiptSigner { + payer: Address, signer: PrivateKeySigner, domain: Eip712Domain, + data_service: Address, } impl ReceiptSigner { - pub fn new(signer: PrivateKeySigner, chain_id: U256, verifying_contract: Address) -> Self { + pub fn new( + payer: Address, + signer: PrivateKeySigner, + chain_id: U256, + verifying_contract: Address, + data_service: Address, + ) -> Self { + let domain = Eip712Domain { + name: Some("GraphTallyCollector".into()), + version: Some("1".into()), + chain_id: Some(chain_id), + verifying_contract: Some(verifying_contract), + salt: None, + }; Self { + payer, signer, - domain: Eip712Domain { - name: Some("TAP".into()), - version: Some("1".into()), - chain_id: Some(chain_id), - verifying_contract: Some(verifying_contract), - salt: None, - }, + domain, + data_service, } } - pub fn create_receipt(&self, allocation: AllocationId, fee: u128) -> anyhow::Result { - // Nonce generated with CSPRNG (ChaCha12), to avoid collision with receipts generated by - // other gateway processes. - // See https://docs.rs/rand/latest/rand/rngs/index.html#our-generators. + pub fn create_receipt( + &self, + allocation: AllocationId, + indexer: Address, + fee: u128, + ) -> anyhow::Result { let nonce = rand::rng().next_u64(); - let timestamp_ns = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_nanos() .try_into() .map_err(|_| anyhow::anyhow!("failed to convert timestamp to ns"))?; - - let receipt = TapReceipt { - allocation_id: allocation.0.0.into(), + let receipt = tap_graph::v2::Receipt { + collection_id: CollectionId::from(allocation).0.into(), + payer: self.payer, + data_service: self.data_service, + service_provider: indexer, timestamp_ns, nonce, value: fee, }; - let signed = SignedReceipt::new(&self.domain, receipt, &self.signer) - .map_err(|e| anyhow::anyhow!("failed to sign receipt: {:?}", e))?; - - Ok(Receipt(signed)) + tap_graph::v2::SignedReceipt::new(&self.domain, receipt, &self.signer) + .map(Receipt) + .map_err(|e| anyhow::anyhow!("failed to sign v2 receipt: {:?}", e)) } } @@ -81,25 +148,51 @@ mod tests { use super::*; - #[test] - fn create_receipt() { - //* Given + fn create_test_signer() -> ReceiptSigner { let secret_key = PrivateKeySigner::from_slice(&[0xcd; 32]).expect("invalid secret key"); - let signer = ReceiptSigner::new( + ReceiptSigner::new( + address!("1111111111111111111111111111111111111111"), secret_key, 1.try_into().expect("invalid chain id"), address!("177b557b12f22bb17a9d73dcc994d978dd6f5f89"), - ); + address!("2222222222222222222222222222222222222222"), + ) + } + #[test] + fn create_v2_receipt() { + let signer = create_test_signer(); let allocation = allocation_id!("89b23fea4e46d40e8a4c6cca723e2a03fdd4bec2"); let fee = 1000; - //* When - let res = signer.create_receipt(allocation, fee); + let receipt = signer + .create_receipt( + allocation, + address!("3333333333333333333333333333333333333333"), + fee, + ) + .expect("failed to create v2 receipt"); + + assert_eq!(receipt.value(), fee); + assert_eq!(AllocationId::from(receipt.allocation()), allocation); + } + + #[test] + fn test_receipt_serialization() { + let signer = create_test_signer(); + let allocation = allocation_id!("89b23fea4e46d40e8a4c6cca723e2a03fdd4bec2"); + let fee = 1000; - //* Then - let receipt = res.expect("failed to create tap receipt"); + let receipt = signer + .create_receipt( + allocation, + address!("3333333333333333333333333333333333333333"), + fee, + ) + .expect("failed to create v2 receipt"); + let serialized = receipt.serialize(); + assert!(!serialized.is_empty()); assert_eq!(receipt.value(), fee); } }