diff --git a/Cargo.lock b/Cargo.lock index 52cf71f..3f416e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,7 +356,6 @@ dependencies = [ "tracing", "unimock", "web3", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -372,7 +371,6 @@ dependencies = [ "node-interface", "thiserror 1.0.69", "unimock", - "workspace-hack", "zk-primitives", ] @@ -383,7 +381,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -449,9 +446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b163ff4acf0eac29af05a911397cc418a76e153467b859398adc26cb9335a611" dependencies = [ "alloy-primitives", - "alloy-rlp", "num_enum", - "serde", "strum 0.27.2", ] @@ -541,7 +536,6 @@ dependencies = [ "alloy-primitives", "alloy-sol-type-parser", "alloy-sol-types", - "derive_more 2.1.1", "itoa 1.0.17", "serde", "serde_json", @@ -582,9 +576,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "borsh", - "k256", "serde", - "serde_with", "thiserror 2.0.17", ] @@ -618,8 +610,6 @@ dependencies = [ "c-kzg", "derive_more 2.1.1", "either", - "ethereum_ssz", - "ethereum_ssz_derive", "serde", "serde_with", "sha2", @@ -719,7 +709,6 @@ dependencies = [ "const-hex", "derive_more 2.1.1", "foldhash 0.2.0", - "getrandom 0.4.1", "hashbrown 0.16.1", "indexmap 2.14.0", "itoa 1.0.17", @@ -748,17 +737,12 @@ dependencies = [ "alloy-network", "alloy-network-primitives", "alloy-primitives", - "alloy-pubsub", "alloy-rpc-client", - "alloy-rpc-types-debug", "alloy-rpc-types-eth", - "alloy-rpc-types-trace", "alloy-signer", "alloy-sol-types", "alloy-transport", "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", "async-stream", "async-trait", "auto_impl", @@ -779,28 +763,6 @@ dependencies = [ "wasmtimer", ] -[[package]] -name = "alloy-pubsub" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8bd82953194dec221aa4cbbbb0b1e2df46066fe9d0333ac25b43a311e122d13" -dependencies = [ - "alloy-json-rpc", - "alloy-primitives", - "alloy-transport", - "auto_impl", - "bimap", - "futures", - "parking_lot 0.12.5", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tower", - "tracing", - "wasmtimer", -] - [[package]] name = "alloy-rlp" version = "0.3.13" @@ -831,11 +793,8 @@ checksum = "f2792758a93ae32a32e9047c843d536e1448044f78422d71bf7d7c05149e103f" dependencies = [ "alloy-json-rpc", "alloy-primitives", - "alloy-pubsub", "alloy-transport", "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", "futures", "pin-project", "reqwest 0.12.28", @@ -856,7 +815,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79cff039bf01a17d76c0aace3a3a773d5f895eb4c68baaae729ec9da9e86c99c" dependencies = [ "alloy-primitives", - "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-serde", "serde", @@ -873,38 +831,6 @@ dependencies = [ "alloy-serde", ] -[[package]] -name = "alloy-rpc-types-debug" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b21e1ad18ff1b31ff1030e046462ab8168cf8894e6778cd805c8bdfe2bd649" -dependencies = [ - "alloy-primitives", - "derive_more 2.1.1", - "serde", - "serde_with", -] - -[[package]] -name = "alloy-rpc-types-engine" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10620d600cc46538f613c561ac9a923843c6c74c61f054828dcdb8dd18c72ec4" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "alloy-serde", - "derive_more 2.1.1", - "ethereum_ssz", - "ethereum_ssz_derive", - "jsonwebtoken", - "rand 0.8.5", - "serde", - "strum 0.27.2", -] - [[package]] name = "alloy-rpc-types-eth" version = "1.7.3" @@ -926,20 +852,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "alloy-rpc-types-trace" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad79f1e27e161943b5a4f99fe5534ef0849876214be411e0032c12f38e94daa" -dependencies = [ - "alloy-primitives", - "alloy-rpc-types-eth", - "alloy-serde", - "serde", - "serde_json", - "thiserror 2.0.17", -] - [[package]] name = "alloy-serde" version = "1.7.3" @@ -977,12 +889,9 @@ dependencies = [ "alloy-primitives", "alloy-signer", "async-trait", - "coins-bip32", - "coins-bip39", "k256", "rand 0.8.5", "thiserror 2.0.17", - "zeroize", ] [[package]] @@ -1097,43 +1006,6 @@ dependencies = [ "url", ] -[[package]] -name = "alloy-transport-ipc" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ef85688e5ac2da72afc804e0a1f153a1f309f05a864b1998bbbed7804dbaab" -dependencies = [ - "alloy-json-rpc", - "alloy-pubsub", - "alloy-transport", - "bytes", - "futures", - "interprocess", - "pin-project", - "serde", - "serde_json", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "alloy-transport-ws" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f00445db69d63298e2b00a0ea1d859f00e6424a3144ffc5eba9c31da995e16" -dependencies = [ - "alloy-pubsub", - "alloy-transport", - "futures", - "http 1.4.0", - "serde_json", - "tokio", - "tokio-tungstenite", - "tracing", - "ws_stream_wasm", -] - [[package]] name = "alloy-trie" version = "0.9.4" @@ -1157,7 +1029,7 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fa0c53e8c1e1ef4d01066b01c737fb62fc9397ab52c6e7bb5669f97d281b9bc" dependencies = [ - "darling 0.21.3", + "darling", "proc-macro2", "quote", "syn 2.0.112", @@ -1237,15 +1109,6 @@ dependencies = [ "object 0.32.2", ] -[[package]] -name = "arc-swap" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" -dependencies = [ - "rustversion", -] - [[package]] name = "argon2" version = "0.5.3" @@ -1266,7 +1129,6 @@ checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", "ark-ff 0.5.0", - "ark-r1cs-std", "ark-std 0.5.0", ] @@ -1444,35 +1306,6 @@ dependencies = [ "hashbrown 0.15.5", ] -[[package]] -name = "ark-r1cs-std" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1" -dependencies = [ - "ark-ec", - "ark-ff 0.5.0", - "ark-relations", - "ark-std 0.5.0", - "educe", - "num-bigint", - "num-integer", - "num-traits", - "tracing", -] - -[[package]] -name = "ark-relations" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" -dependencies = [ - "ark-ff 0.5.0", - "ark-std 0.5.0", - "tracing", - "tracing-subscriber 0.2.25", -] - [[package]] name = "ark-serialize" version = "0.3.0" @@ -1645,19 +1478,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-compression" -version = "0.4.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" -dependencies = [ - "compression-codecs", - "compression-core", - "futures-core", - "pin-project-lite", - "tokio", -] - [[package]] name = "async-io" version = "2.6.0" @@ -1755,17 +1575,6 @@ dependencies = [ "syn 2.0.112", ] -[[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 = "asynchronous-codec" version = "0.6.2" @@ -1927,7 +1736,6 @@ dependencies = [ "rpc", "tokio", "tracing", - "workspace-hack", ] [[package]] @@ -1948,7 +1756,6 @@ dependencies = [ "tracing", "url", "webpki-roots 0.26.11", - "workspace-hack", ] [[package]] @@ -1960,7 +1767,6 @@ dependencies = [ "primitives", "serde", "thiserror 1.0.69", - "workspace-hack", ] [[package]] @@ -1975,7 +1781,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tracing", - "workspace-hack", ] [[package]] @@ -1996,7 +1801,6 @@ dependencies = [ "tower", "unimock", "url", - "workspace-hack", ] [[package]] @@ -2009,7 +1813,6 @@ dependencies = [ "tempfile", "tokio", "tracing", - "workspace-hack", ] [[package]] @@ -2019,7 +1822,6 @@ dependencies = [ "async-trait", "thiserror 1.0.69", "unimock", - "workspace-hack", ] [[package]] @@ -2032,7 +1834,6 @@ dependencies = [ "lazy_static", "polybase_bb_rs", "tokio", - "workspace-hack", ] [[package]] @@ -2125,15 +1926,8 @@ dependencies = [ "url", "wasmi", "web3", - "workspace-hack", ] -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - [[package]] name = "benchy" version = "0.1.1" @@ -2181,12 +1975,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bimap" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" - [[package]] name = "binary-merge" version = "0.1.2" @@ -2334,9 +2122,6 @@ name = "bitflags" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" -dependencies = [ - "serde_core", -] [[package]] name = "bitmaps" @@ -2355,7 +2140,6 @@ checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", - "serde", "tap", "wyz", ] @@ -2420,15 +2204,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - [[package]] name = "block-store" version = "1.3.0" @@ -2442,7 +2217,6 @@ dependencies = [ "thiserror 1.0.69", "tracing", "wire-message", - "workspace-hack", ] [[package]] @@ -2559,7 +2333,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2", "tinyvec", ] @@ -2600,7 +2373,6 @@ dependencies = [ "serde_urlencoded 0.7.1", "thiserror 1.0.69", "unimock", - "workspace-hack", ] [[package]] @@ -2621,7 +2393,6 @@ dependencies = [ "tokio", "tracing", "url", - "workspace-hack", "zk-primitives", ] @@ -2872,7 +2643,6 @@ dependencies = [ "serde_json", "tokio", "tracing", - "workspace-hack", ] [[package]] @@ -2886,7 +2656,6 @@ dependencies = [ "parking_lot 0.12.5", "rpc", "tokio", - "workspace-hack", ] [[package]] @@ -2928,57 +2697,6 @@ dependencies = [ "unicode-width 0.1.14", ] -[[package]] -name = "coins-bip32" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2073678591747aed4000dd468b97b14d7007f7936851d3f2f01846899f5ebf08" -dependencies = [ - "bs58 0.5.1", - "coins-core", - "digest 0.10.7", - "hmac", - "k256", - "serde", - "sha2", - "thiserror 1.0.69", -] - -[[package]] -name = "coins-bip39" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b169b26623ff17e9db37a539fe4f15342080df39f129ef7631df7683d6d9d4" -dependencies = [ - "bitvec", - "coins-bip32", - "hmac", - "once_cell", - "pbkdf2", - "rand 0.8.5", - "sha2", - "thiserror 1.0.69", -] - -[[package]] -name = "coins-core" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b962ad8545e43a28e14e87377812ba9ae748dd4fd963f4c10e9fcc6d13475b" -dependencies = [ - "base64 0.21.7", - "bech32", - "bs58 0.5.1", - "const-hex", - "digest 0.10.7", - "generic-array", - "ripemd", - "serde", - "sha2", - "sha3", - "thiserror 1.0.69", -] - [[package]] name = "color-eyre" version = "0.6.5" @@ -3023,26 +2741,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "compression-codecs" -version = "0.4.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" -dependencies = [ - "brotli", - "compression-core", - "flate2", - "memchr", - "zstd", - "zstd-safe", -] - -[[package]] -name = "compression-core" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -3129,9 +2827,6 @@ checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "constants" version = "0.1.0" -dependencies = [ - "workspace-hack", -] [[package]] name = "contextful" @@ -3141,7 +2836,6 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "workspace-hack", ] [[package]] @@ -3150,7 +2844,6 @@ version = "0.1.0" dependencies = [ "quote", "syn 2.0.112", - "workspace-hack", ] [[package]] @@ -3178,7 +2871,6 @@ dependencies = [ "tokio", "tracing", "web3", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -3219,16 +2911,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -3252,7 +2934,6 @@ dependencies = [ "serde", "strum 0.27.2", "strum_macros 0.27.2", - "workspace-hack", ] [[package]] @@ -3297,12 +2978,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -3403,7 +3078,6 @@ dependencies = [ "strum_macros 0.27.2", "thiserror 1.0.69", "ts-rs", - "workspace-hack", ] [[package]] @@ -3446,38 +3120,14 @@ dependencies = [ "syn 2.0.112", ] -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "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]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.112", + "darling_core", + "darling_macro", ] [[package]] @@ -3495,24 +3145,13 @@ dependencies = [ "syn 2.0.112", ] -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core 0.20.11", - "quote", - "syn 2.0.112", -] - [[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", + "darling_core", "quote", "syn 2.0.112", ] @@ -3548,7 +3187,6 @@ dependencies = [ "strum 0.27.2", "ts-rs", "uuid 1.19.0", - "workspace-hack", ] [[package]] @@ -3592,7 +3230,6 @@ dependencies = [ "serial_test", "tokio", "tokio-postgres", - "workspace-hack", ] [[package]] @@ -3733,35 +3370,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "1.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ - "derive_more-impl 1.0.0", + "derive_more-impl", ] [[package]] -name = "derive_more" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" -dependencies = [ - "derive_more-impl 2.1.1", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.112", -] - -[[package]] -name = "derive_more-impl" +name = "derive_more-impl" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" @@ -3796,7 +3413,6 @@ name = "diesel-util" version = "0.1.0" dependencies = [ "diesel", - "workspace-hack", ] [[package]] @@ -3913,12 +3529,6 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" -[[package]] -name = "doctest-file" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" - [[package]] name = "doomslug" version = "1.3.0" @@ -3930,7 +3540,6 @@ dependencies = [ "sha3", "thiserror 1.0.69", "tracing", - "workspace-hack", ] [[package]] @@ -4010,7 +3619,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd122633e4bef06db27737f21d3738fb89c8f6d5360d6d9d7635dda142a7757e" dependencies = [ - "darling 0.21.3", + "darling", "either", "heck 0.5.0", "proc-macro2", @@ -4127,7 +3736,6 @@ dependencies = [ "tokio", "tracing", "web3", - "workspace-hack", ] [[package]] @@ -4158,7 +3766,6 @@ dependencies = [ "serde_json", "test-strategy", "ts-rs", - "workspace-hack", ] [[package]] @@ -4173,7 +3780,6 @@ dependencies = [ "ff", "generic-array", "group", - "hkdf", "pem-rfc7468", "pkcs8", "rand_core 0.6.4", @@ -4204,7 +3810,6 @@ version = "0.1.0" dependencies = [ "crypto_secretbox", "thiserror 1.0.69", - "workspace-hack", "x25519-dalek 2.0.1", ] @@ -4286,7 +3891,6 @@ dependencies = [ "ethereum-types", "secp256k1 0.28.2", "sha3", - "workspace-hack", ] [[package]] @@ -4314,10 +3918,8 @@ checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", "fixed-hash", - "impl-codec", "impl-rlp", "impl-serde", - "scale-info", "tiny-keccak", ] @@ -4329,54 +3931,12 @@ checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ "ethbloom", "fixed-hash", - "impl-codec", "impl-rlp", "impl-serde", "primitive-types", - "scale-info", "uint 0.9.5", ] -[[package]] -name = "ethereum_serde_utils" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc1355dbb41fbbd34ec28d4fb2a57d9a70c67ac3c19f6a5ca4d4a176b9e997a" -dependencies = [ - "alloy-primitives", - "hex", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "ethereum_ssz" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dcddb2554d19cde19b099fadddde576929d7a4d0c1cd3512d1fd95cf174375c" -dependencies = [ - "alloy-primitives", - "ethereum_serde_utils", - "itertools 0.13.0", - "serde", - "serde_derive", - "smallvec", - "typenum", -] - -[[package]] -name = "ethereum_ssz_derive" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a657b6b3b7e153637dc6bdc6566ad9279d9ee11a15b12cfb24a2e04360637e9f" -dependencies = [ - "darling 0.20.11", - "proc-macro2", - "quote", - "syn 2.0.112", -] - [[package]] name = "ethnum" version = "1.5.2" @@ -4520,10 +4080,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" dependencies = [ "atomic", - "parking_lot 0.12.5", "pear", "serde", - "tempfile", "toml 0.8.23", "uncased", "version_check", @@ -4778,10 +4336,6 @@ name = "futures-timer" version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] [[package]] name = "futures-util" @@ -4892,18 +4446,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "group" version = "0.13.0" @@ -4937,7 +4479,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "uuid 1.19.0", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -4965,7 +4506,6 @@ dependencies = [ "serde_json", "thiserror 1.0.69", "uuid 1.19.0", - "workspace-hack", "zk-primitives", ] @@ -5041,7 +4581,6 @@ dependencies = [ "rand_chacha 0.3.1", "rand_xorshift 0.4.0", "serde", - "workspace-hack", ] [[package]] @@ -5056,7 +4595,6 @@ dependencies = [ "rand_chacha 0.3.1", "rand_xorshift 0.4.0", "serde", - "workspace-hack", ] [[package]] @@ -5114,16 +4652,6 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" -[[package]] -name = "hdrhistogram" -version = "7.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" -dependencies = [ - "byteorder", - "num-traits", -] - [[package]] name = "headers" version = "0.3.9" @@ -5225,15 +4753,6 @@ dependencies = [ "paste", ] -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - [[package]] name = "hmac" version = "0.12.1" @@ -5344,15 +4863,8 @@ dependencies = [ "serde_json", "thiserror 1.0.69", "unimock", - "workspace-hack", ] -[[package]] -name = "http-range-header" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" - [[package]] name = "http-types" version = "2.12.0" @@ -5485,9 +4997,7 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "hyper-util", - "log", "rustls 0.23.35", - "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", @@ -5738,7 +5248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38" dependencies = [ "async-io", - "core-foundation 0.9.4", + "core-foundation", "fnv", "futures", "if-addrs", @@ -5869,7 +5379,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "block-padding", "generic-array", ] @@ -5906,21 +5415,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "interprocess" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53bf2b0e0785c5394a7392f66d7c4fb9c653633c29b27a932280da3cb344c66a" -dependencies = [ - "doctest-file", - "futures-core", - "libc", - "recvmsg", - "tokio", - "widestring", - "windows-sys 0.52.0", -] - [[package]] name = "ipconfig" version = "0.3.2" @@ -5992,15 +5486,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -6061,7 +5546,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tracing", - "workspace-hack", ] [[package]] @@ -6072,7 +5556,6 @@ dependencies = [ "serde", "serde_json", "tracing", - "workspace-hack", ] [[package]] @@ -6130,21 +5613,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "jsonwebtoken" -version = "9.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" -dependencies = [ - "base64 0.22.1", - "js-sys", - "pem 3.0.6", - "ring 0.17.14", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "k256" version = "0.13.4" @@ -6194,16 +5662,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "ts-rs", - "workspace-hack", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -dependencies = [ - "regex-automata", ] [[package]] @@ -6656,7 +6114,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", - "libc", "pkg-config", "vcpkg", ] @@ -6709,7 +6166,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ "scopeguard", - "serde", ] [[package]] @@ -6896,7 +6352,6 @@ dependencies = [ "ff", "halo2curves", "lazy_static", - "workspace-hack", ] [[package]] @@ -7049,10 +6504,10 @@ dependencies = [ "libc", "log", "openssl", - "openssl-probe 0.1.6", + "openssl-probe", "openssl-sys", "schannel", - "security-framework 2.11.1", + "security-framework", "security-framework-sys", "tempfile", ] @@ -7134,7 +6589,6 @@ dependencies = [ "ts-rs", "uuid 1.19.0", "veil", - "workspace-hack", ] [[package]] @@ -7259,10 +6713,9 @@ dependencies = [ "tokio-postgres", "tokio-stream", "tracing", - "tracing-subscriber 0.3.22", + "tracing-subscriber", "web3", "wire-message", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -7281,7 +6734,6 @@ dependencies = [ "serde", "tokio", "unimock", - "workspace-hack", "zk-primitives", ] @@ -7299,7 +6751,6 @@ dependencies = [ "thiserror 1.0.69", "ts-rs", "unimock", - "workspace-hack", "zk-primitives", ] @@ -7318,7 +6769,6 @@ dependencies = [ "serde", "serde_json", "syn 2.0.112", - "workspace-hack", ] [[package]] @@ -7534,7 +6984,6 @@ dependencies = [ "thiserror 1.0.69", "unimock", "uuid 1.19.0", - "workspace-hack", "zk-primitives", ] @@ -7573,17 +7022,6 @@ 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-traits" version = "0.2.19" @@ -7626,15 +7064,6 @@ dependencies = [ "syn 2.0.112", ] -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - [[package]] name = "nybbles" version = "0.4.8" @@ -7827,10 +7256,6 @@ name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -dependencies = [ - "critical-section", - "portable-atomic", -] [[package]] name = "once_cell_polyfill" @@ -7882,21 +7307,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-probe" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" - -[[package]] -name = "openssl-src" -version = "300.5.5+3.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.111" @@ -7905,7 +7315,6 @@ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -8055,7 +7464,6 @@ dependencies = [ "tracing", "whitelist-ips", "wire-message", - "workspace-hack", ] [[package]] @@ -8067,7 +7475,6 @@ dependencies = [ "arrayvec", "bitvec", "byte-slice-cast", - "bytes", "const_format", "impl-trait-for-tuples", "parity-scale-codec-derive", @@ -8156,7 +7563,6 @@ dependencies = [ "thiserror 1.0.69", "ts-rs", "web3", - "workspace-hack", ] [[package]] @@ -8232,7 +7638,6 @@ dependencies = [ "sha3", "thiserror 1.0.69", "tokio", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -8246,7 +7651,6 @@ dependencies = [ "contextful", "payy-evm-client-interface", "tokio", - "workspace-hack", ] [[package]] @@ -8263,7 +7667,6 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "workspace-hack", "zk-primitives", ] @@ -8277,7 +7680,6 @@ dependencies = [ "element", "payy-evm-client-prover-interface", "tokio", - "workspace-hack", "zk-circuits", ] @@ -8290,7 +7692,6 @@ dependencies = [ "payy-evm-client-interface", "serde", "thiserror 1.0.69", - "workspace-hack", ] [[package]] @@ -8301,7 +7702,6 @@ dependencies = [ "element", "payy-evm-client-interface", "sha3", - "workspace-hack", "zk-primitives", ] @@ -8313,20 +7713,9 @@ dependencies = [ "serde", "serde_json", "unimock", - "workspace-hack", "zk-primitives", ] -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac", -] - [[package]] name = "pear" version = "0.2.9" @@ -8365,16 +7754,6 @@ dependencies = [ "base64 0.13.1", ] -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64 0.22.1", - "serde_core", -] - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -8455,16 +7834,6 @@ dependencies = [ "serde", ] -[[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 = "phf" version = "0.11.3" @@ -8639,7 +8008,7 @@ dependencies = [ "num-bigint", "thiserror 1.0.69", "tracing", - "tracing-subscriber 0.3.22", + "tracing-subscriber", ] [[package]] @@ -8654,12 +8023,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - [[package]] name = "postgres-native-tls" version = "0.5.2" @@ -8769,7 +8132,6 @@ dependencies = [ "serde", "thiserror 1.0.69", "unimock", - "workspace-hack", ] [[package]] @@ -8791,7 +8153,6 @@ dependencies = [ "impl-codec", "impl-rlp", "impl-serde", - "scale-info", "uint 0.9.5", ] @@ -8819,7 +8180,6 @@ dependencies = [ "ts-rs", "uint 0.10.0", "web3", - "workspace-hack", ] [[package]] @@ -9118,7 +8478,6 @@ dependencies = [ "tokio", "tracing", "web3", - "workspace-hack", "zk-circuits", "zk-primitives", ] @@ -9313,7 +8672,6 @@ dependencies = [ "unimock", "uuid 1.19.0", "veil", - "workspace-hack", "zk-primitives", ] @@ -9516,7 +8874,6 @@ version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2988730ee014541157f48ce4dcc603940e00915edc3c7f9a8d78092256bb2493" dependencies = [ - "rand 0.9.2", "rustversion", ] @@ -9546,7 +8903,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ - "pem 1.1.1", + "pem", "ring 0.16.20", "time", "yasna", @@ -9561,12 +8918,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[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.2.16" @@ -9684,7 +9035,6 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-compression", "base64 0.21.7", "bytes", "encoding_rs", @@ -9711,7 +9061,6 @@ dependencies = [ "system-configuration 0.5.1", "tokio", "tokio-native-tls", - "tokio-util", "tower-service", "url", "wasm-bindgen", @@ -9749,7 +9098,6 @@ dependencies = [ "pin-project-lite", "quinn", "rustls 0.23.35", - "rustls-native-certs", "rustls-pki-types", "serde", "serde_json", @@ -9815,15 +9163,6 @@ 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" @@ -9831,7 +9170,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ "bytes", - "rlp-derive", "rustc-hex", ] @@ -9845,17 +9183,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "rmp" version = "0.8.15" @@ -9921,8 +9248,7 @@ dependencies = [ "tracing", "tracing-opentelemetry", "tracing-stackdriver", - "tracing-subscriber 0.3.22", - "workspace-hack", + "tracing-subscriber", ] [[package]] @@ -9933,7 +9259,6 @@ dependencies = [ "quote", "serde_json", "syn 2.0.112", - "workspace-hack", ] [[package]] @@ -10053,9 +9378,6 @@ name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -dependencies = [ - "rand 0.8.5", -] [[package]] name = "rustc-hex" @@ -10150,18 +9472,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-native-certs" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" -dependencies = [ - "openssl-probe 0.2.0", - "rustls-pki-types", - "schannel", - "security-framework 3.5.1", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -10315,30 +9625,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scale-info" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" -dependencies = [ - "cfg-if", - "derive_more 1.0.0", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.112", -] - [[package]] name = "scc" version = "2.4.0" @@ -10498,20 +9784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.10.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -10552,10 +9825,6 @@ name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -dependencies = [ - "serde", - "serde_core", -] [[package]] name = "semver-parser" @@ -10566,18 +9835,6 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - [[package]] name = "sentry" version = "0.46.0" @@ -10679,7 +9936,7 @@ dependencies = [ "sentry-backtrace", "sentry-core", "tracing-core", - "tracing-subscriber 0.3.22", + "tracing-subscriber", ] [[package]] @@ -10886,7 +10143,7 @@ version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ - "darling 0.21.3", + "darling", "proc-macro2", "quote", "syn 2.0.112", @@ -10897,7 +10154,6 @@ name = "serde_yaml" version = "0.9.36" dependencies = [ "serde_yaml_ng", - "workspace-hack", ] [[package]] @@ -11113,20 +10369,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] -name = "simple_asn1" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror 2.0.17", - "time", -] - -[[package]] -name = "siphasher" -version = "0.3.11" +name = "siphasher" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" @@ -11218,7 +10462,6 @@ dependencies = [ "tokio", "tracing", "wire-message", - "workspace-hack", ] [[package]] @@ -11312,7 +10555,6 @@ dependencies = [ "reqwest 0.12.28", "sha2", "thiserror 1.0.69", - "workspace-hack", ] [[package]] @@ -11335,9 +10577,8 @@ dependencies = [ "tokio", "tokio-stream", "tracing", - "tracing-subscriber 0.3.22", + "tracing-subscriber", "uint 0.10.0", - "workspace-hack", ] [[package]] @@ -11360,7 +10601,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "url", - "workspace-hack", ] [[package]] @@ -11372,7 +10612,6 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "workspace-hack", ] [[package]] @@ -11768,7 +11007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "system-configuration-sys 0.5.0", ] @@ -11779,7 +11018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.10.0", - "core-foundation 0.9.4", + "core-foundation", "system-configuration-sys 0.6.0", ] @@ -11790,7 +11029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags 2.10.0", - "core-foundation 0.9.4", + "core-foundation", "system-configuration-sys 0.6.0", ] @@ -11870,7 +11109,6 @@ dependencies = [ "serde", "test-spy-macros", "tokio", - "workspace-hack", ] [[package]] @@ -11880,7 +11118,6 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.112", - "workspace-hack", ] [[package]] @@ -11902,7 +11139,6 @@ dependencies = [ "once_cell", "reqwest 0.12.28", "tokio", - "workspace-hack", ] [[package]] @@ -11980,9 +11216,7 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa 1.0.17", - "libc", "num-conv", - "num_threads", "powerfmt", "serde_core", "time-core", @@ -12125,23 +11359,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "tokio-tungstenite" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" -dependencies = [ - "futures-util", - "log", - "rustls 0.23.35", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tungstenite", - "webpki-roots 0.26.11", -] - [[package]] name = "tokio-util" version = "0.7.17" @@ -12153,7 +11370,6 @@ dependencies = [ "futures-io", "futures-sink", "pin-project-lite", - "slab", "tokio", ] @@ -12328,7 +11544,6 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "hdrhistogram", "indexmap 2.14.0", "pin-project-lite", "slab", @@ -12346,29 +11561,16 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "async-compression", - "base64 0.22.1", "bitflags 2.10.0", "bytes", - "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", - "http-body-util", - "http-range-header", - "httpdate", "iri-string", - "mime", - "mime_guess", - "percent-encoding", "pin-project-lite", - "tokio", - "tokio-util", "tower", "tower-layer", "tower-service", - "tracing", - "uuid 1.19.0", ] [[package]] @@ -12423,7 +11625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", - "tracing-subscriber 0.3.22", + "tracing-subscriber", ] [[package]] @@ -12452,7 +11654,7 @@ dependencies = [ "tracing", "tracing-core", "tracing-log", - "tracing-subscriber 0.3.22", + "tracing-subscriber", "web-time", ] @@ -12479,21 +11681,12 @@ dependencies = [ "thiserror 1.0.69", "time", "tracing-core", - "tracing-subscriber 0.3.22", + "tracing-subscriber", "url", "valuable", "valuable-serde", ] -[[package]] -name = "tracing-subscriber" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "tracing-core", -] - [[package]] name = "tracing-subscriber" version = "0.3.22" @@ -12521,7 +11714,6 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" dependencies = [ - "arc-swap", "serde", "stable_deref_trait", ] @@ -12603,25 +11795,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "tungstenite" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" -dependencies = [ - "bytes", - "data-encoding", - "http 1.4.0", - "httparse", - "log", - "rand 0.9.2", - "rustls 0.23.35", - "rustls-pki-types", - "sha1 0.10.6", - "thiserror 2.0.17", - "utf-8", -] - [[package]] name = "typenum" version = "1.20.0" @@ -13023,7 +12196,6 @@ dependencies = [ "serde_json", "tokio", "web3", - "workspace-hack", "zk-primitives", ] @@ -13042,7 +12214,6 @@ dependencies = [ "ts-rs", "uuid 1.19.0", "wallet-primitives", - "workspace-hack", "zk-primitives", ] @@ -13056,7 +12227,6 @@ dependencies = [ "serde_json", "sha3", "thiserror 1.0.69", - "workspace-hack", "zk-primitives", ] @@ -13467,7 +12637,6 @@ version = "1.3.0" dependencies = [ "libp2p", "tracing", - "workspace-hack", ] [[package]] @@ -13885,7 +13054,6 @@ dependencies = [ "strum 0.27.2", "strum_macros 0.27.2", "wire-message-macro", - "workspace-hack", ] [[package]] @@ -13895,7 +13063,6 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.112", - "workspace-hack", ] [[package]] @@ -13992,261 +13159,12 @@ dependencies = [ "wasmparser 0.244.0", ] -[[package]] -name = "workspace-hack" -version = "0.1.0" -dependencies = [ - "actix-router", - "aead", - "ahash", - "aho-corasick", - "allocator-api2", - "alloy-chains", - "alloy-consensus", - "alloy-dyn-abi", - "alloy-eip7702", - "alloy-eips", - "alloy-json-abi", - "alloy-primitives", - "alloy-provider", - "alloy-rlp", - "alloy-rpc-client", - "alloy-rpc-types", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "alloy-signer-local", - "alloy-sol-macro", - "alloy-sol-macro-expander", - "alloy-sol-macro-input", - "alloy-sol-type-parser", - "alloy-sol-types", - "alloy-transport-http", - "ark-bn254", - "ark-ec", - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", - "arrayvec", - "async-compression", - "axum", - "base64 0.13.1", - "bindgen 0.71.1", - "bitflags 2.10.0", - "bitvec", - "blst", - "bs58 0.5.1", - "bumpalo", - "byteorder", - "bytes", - "c-kzg", - "cc", - "chrono", - "cipher", - "clang-sys", - "clap", - "clap_builder", - "compression-codecs", - "concurrent-queue", - "const-hex", - "crossbeam-epoch", - "crossbeam-utils", - "crunchy", - "crypto-common 0.1.7", - "curve25519-dalek 4.1.3", - "darling 0.21.3", - "darling_core 0.21.3", - "dashmap", - "data-encoding", - "der", - "derive_more 2.1.1", - "derive_more-impl 2.1.1", - "digest 0.10.7", - "ecdsa", - "ed25519", - "ed25519-dalek", - "either", - "elliptic-curve", - "errno", - "ethbloom", - "ethereum-types", - "ff", - "figment", - "foldhash 0.1.5", - "form_urlencoded", - "futures", - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-timer", - "futures-util", - "generic-array", - "getrandom 0.2.16", - "getrandom 0.3.4", - "group", - "hashbrown 0.13.2", - "hashbrown 0.14.5", - "hashbrown 0.15.5", - "hashbrown 0.16.1", - "hex", - "hmac", - "httparse", - "hyper 1.8.1", - "hyper-rustls", - "hyper-util", - "idna 1.1.0", - "indexmap 2.14.0", - "inout", - "insta", - "itertools 0.11.0", - "itertools 0.13.0", - "itertools 0.14.0", - "k256", - "keccak", - "lalrpop-util", - "lazy_static", - "libc", - "libm", - "libz-sys", - "linux-raw-sys 0.11.0", - "linux-raw-sys 0.4.15", - "lock_api", - "log", - "memchr", - "miniz_oxide", - "mio", - "native-tls", - "nom", - "num-bigint", - "num-integer", - "num-iter", - "num-traits", - "num_enum", - "num_enum_derive", - "nybbles", - "once_cell", - "openssl", - "openssl-sys", - "p256", - "parity-scale-codec", - "parking_lot 0.12.5", - "percent-encoding", - "phf_shared 0.11.3", - "portable-atomic", - "postgres-types", - "ppv-lite86", - "prettyplease", - "primitive-types", - "proc-macro2", - "prost 0.13.5", - "quote", - "rand 0.8.5", - "rand 0.9.2", - "rand_chacha 0.3.1", - "rand_chacha 0.9.0", - "rand_core 0.6.4", - "rand_core 0.9.3", - "regex", - "regex-automata", - "regex-syntax 0.8.8", - "reqwest 0.11.27", - "reqwest 0.12.28", - "ring 0.17.14", - "rlp 0.5.2", - "ruint", - "rustc-hash 2.1.1", - "rustc-hex", - "rustix 0.38.44", - "rustix 1.1.3", - "rustls 0.23.35", - "rustls-webpki", - "scopeguard", - "sec1", - "security-framework 2.11.1", - "security-framework 3.5.1", - "security-framework-sys", - "semver 1.0.27", - "serde", - "serde_core", - "serde_json", - "serde_spanned 1.0.4", - "serde_with", - "sha1 0.10.6", - "sha2", - "sha3", - "signature", - "similar", - "smallvec", - "socket2 0.5.10", - "socket2 0.6.1", - "spin 0.9.8", - "spki", - "strum 0.27.2", - "subtle", - "syn 1.0.109", - "syn 2.0.112", - "sync_wrapper 1.0.2", - "thiserror 2.0.17", - "time", - "tiny-keccak", - "tokio", - "tokio-postgres", - "tokio-rustls", - "tokio-stream", - "tokio-tungstenite", - "tokio-util", - "toml 0.9.11+spec-1.1.0", - "tower", - "tower-http", - "tracing", - "tracing-core", - "tracing-subscriber 0.3.22", - "triomphe", - "unicode-bidi", - "unicode-normalization", - "url", - "uuid 1.19.0", - "winapi", - "windows-sys 0.48.0", - "windows-sys 0.52.0", - "windows-sys 0.59.0", - "windows-sys 0.60.2", - "windows-sys 0.61.2", - "winnow 0.7.14", - "x25519-dalek 2.0.1", - "zeroize", - "zstd", - "zstd-safe", - "zstd-sys", -] - [[package]] name = "writeable" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" -[[package]] -name = "ws_stream_wasm" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" -dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version 0.4.1", - "send_wrapper 0.6.0", - "thiserror 2.0.17", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wyz" version = "0.5.1" @@ -14316,7 +13234,6 @@ dependencies = [ "thiserror 1.0.69", "toml 0.9.11+spec-1.1.0", "which", - "workspace-hack", ] [[package]] @@ -14498,7 +13415,6 @@ dependencies = [ "tokio", "unimock", "url", - "workspace-hack", "zk-primitives", ] @@ -14519,7 +13435,6 @@ dependencies = [ "sha3", "ts-rs", "web3", - "workspace-hack", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 58e0c49..295cd61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,6 @@ resolver = "2" members = ["pkg/*", "app/packages/react-native-rust-bridge/cpp/rustbridge"] -[workspace.metadata.cargo-machete] -ignored = ["workspace-hack"] - [workspace.metadata.cargo-machete.renamed] async-stripe = "stripe" @@ -13,10 +10,6 @@ async-stripe = "stripe" [profile.dev] opt-level = 1 -[profile.dev.package.workspace-hack] -# Fixes some spurious rebuilds of workspace-hack -incremental = false - # `opt-level = 3` has a large impact on perf, but does impact compile times. However, we only apply it to dependencies, # so incremental compilation makes this choice essentially "free" after the first compile #[profile.dev.package."*"] @@ -58,6 +51,9 @@ currency = { path = "./pkg/currency" } database = { path = "./pkg/database", default-features = false } data = { path = "./pkg/data" } diesel-util = { path = "./pkg/diesel-util" } +dstack-client-http = { path = "./pkg/dstack-client-http" } +dstack-interface = { path = "./pkg/dstack-interface" } +dstack-test-support = { path = "./pkg/dstack-test-support" } doomslug = { path = "./pkg/doomslug" } document-ai-google = { path = "./pkg/document-ai-google" } document-ai-interface = { path = "./pkg/document-ai-interface" } @@ -111,13 +107,20 @@ price-cache-pg = { path = "./pkg/price-cache-pg" } posthog-interface = { path = "./pkg/posthog-interface" } posthog = { path = "./pkg/posthog" } kyc = { path = "./pkg/kyc" } +kms-core = { path = "./pkg/kms-core" } +kms-dev = { path = "./pkg/kms-dev" } +kms-interface = { path = "./pkg/kms-interface" } +kms-phala = { path = "./pkg/kms-phala" } +kms-test-support = { path = "./pkg/kms-test-support" } primitives = { path = "./pkg/primitives" } payy-auth-embedded-wallet-document = { path = "./pkg/payy-auth-embedded-wallet-document" } payy-auth-app-admission-interface = { path = "./pkg/payy-auth-app-admission-interface" } payy-auth-app-admission-catalog = { path = "./pkg/payy-auth-app-admission-catalog" } +payy-auth-app-catalog = { path = "./pkg/payy-auth-app-catalog" } payy-auth-app-catalog-interface = { path = "./pkg/payy-auth-app-catalog-interface" } -payy-auth-app-catalog-memory = { path = "./pkg/payy-auth-app-catalog-memory" } payy-auth-app-catalog-server = { path = "./pkg/payy-auth-app-catalog-server" } +payy-auth-app-catalog-storage-interface = { path = "./pkg/payy-auth-app-catalog-storage-interface" } +payy-auth-app-catalog-storage-memory = { path = "./pkg/payy-auth-app-catalog-storage-memory" } payy-auth-app-catalog-test-support = { path = "./pkg/payy-auth-app-catalog-test-support" } payy-auth-app-client-scope-interface = { path = "./pkg/payy-auth-app-client-scope-interface" } payy-auth-app-client-scope = { path = "./pkg/payy-auth-app-client-scope" } @@ -127,6 +130,7 @@ payy-auth-client-access-test-support = { path = "./pkg/payy-auth-client-access-t payy-auth-user-interface = { path = "./pkg/payy-auth-user-interface" } payy-auth-session-interface = { path = "./pkg/payy-auth-session-interface" } payy-auth-login-commit-interface = { path = "./pkg/payy-auth-login-commit-interface" } +payy-auth-login-commit = { path = "./pkg/payy-auth-login-commit" } payy-auth-login-commit-policy-catalog = { path = "./pkg/payy-auth-login-commit-policy-catalog" } payy-auth-login-commit-test-support = { path = "./pkg/payy-auth-login-commit-test-support" } payy-auth-refresh-session-core = { path = "./pkg/payy-auth-refresh-session-core" } @@ -139,16 +143,14 @@ payy-auth-passwordless-rate-limit-allow-all = { path = "./pkg/payy-auth-password payy-auth-passwordless-policy-catalog = { path = "./pkg/payy-auth-passwordless-policy-catalog" } payy-auth-passwordless-fail-closed = { path = "./pkg/payy-auth-passwordless-fail-closed" } payy-auth-passwordless-email = { path = "./pkg/payy-auth-passwordless-email" } -payy-auth-session-memory = { path = "./pkg/payy-auth-session-memory" } payy-auth-api-request-interface = { path = "./pkg/payy-auth-api-request-interface" } payy-auth-api-gate = { path = "./pkg/payy-auth-api-gate" } payy-auth-wallet-interface = { path = "./pkg/payy-auth-wallet-interface" } payy-auth-wallet = { path = "./pkg/payy-auth-wallet" } payy-auth-wallet-p256 = { path = "./pkg/payy-auth-wallet-p256" } -payy-auth-wallet-custody-local = { path = "./pkg/payy-auth-wallet-custody-local" } +payy-auth-wallet-custody-kms = { path = "./pkg/payy-auth-wallet-custody-kms" } payy-auth-wallet-storage-core = { path = "./pkg/payy-auth-wallet-storage-core" } -payy-auth-wallet-storage-json = { path = "./pkg/payy-auth-wallet-storage-json" } -payy-auth-wallet-storage-memory = { path = "./pkg/payy-auth-wallet-storage-memory" } +payy-auth-wallet-storage-sqlite = { path = "./pkg/payy-auth-wallet-storage-sqlite" } payy-auth-wallet-test-support = { path = "./pkg/payy-auth-wallet-test-support" } payy-auth-wallet-transaction-evm-json-rpc = { path = "./pkg/payy-auth-wallet-transaction-evm-json-rpc" } payy-auth-api-bin = { path = "./pkg/payy-auth-api-bin" } @@ -159,8 +161,9 @@ payy-auth-local = { path = "./pkg/payy-auth-local" } payy-auth-runtime-system = { path = "./pkg/payy-auth-runtime-system" } payy-auth-session = { path = "./pkg/payy-auth-session" } payy-auth-session-test-support = { path = "./pkg/payy-auth-session-test-support" } -payy-auth-session-storage-memory = { path = "./pkg/payy-auth-session-storage-memory" } +payy-auth-session-storage-sqlite = { path = "./pkg/payy-auth-session-storage-sqlite" } payy-auth-backend-interface = { path = "./pkg/payy-auth-backend-interface" } +payy-auth-user-projection = { path = "./pkg/payy-auth-user-projection" } payy-auth-api-server = { path = "./pkg/payy-auth-api-server" } prover = { path = "./pkg/prover" } providers-interface = { path = "./pkg/providers-interface" } @@ -235,7 +238,6 @@ reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2" } reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2" } -workspace-hack = "0.1" ts-rs = { version = "^11.1.0", features = ["format", "chrono-impl", "uuid-impl"] } actix-cors = "0.6.4" actix-server = "2.3.0" @@ -245,9 +247,12 @@ tower = "0.5" tower-http = "0.6" http-body-util = "0.1" hyper = "1" +hyper-util = { version = "0.1.20", features = ["client-legacy", "http1", "tokio"] } +hyperlocal = "0.9.1" veil = "0.2.0" alloy = { version = "1.0.24", features = ["std", "essentials", "reqwest-rustls-tls", "signers"] } alloy-consensus = "1.4.3" +alloy-dyn-abi = { version = "1.4.3", features = ["eip712"] } alloy-eips = "1.4.3" alloy-evm = "0.26.3" alloy-genesis = "1.4.3" @@ -306,11 +311,12 @@ diesel-async = "0.7.4" diesel_migrations = "2.3" tokio-postgres = { version = "0.7.16" } postgres-native-tls = "0.5.0" -native-tls = "0.2.15" +native-tls = { version = "0.2.15", default-features = false, features = ["alpn"] } derive_more = "0.99.17" dirs = "5.0.1" dotenvy = "0.15.7" duct = "1.1" +ed25519-dalek = "2.2.0" ethereum-types = "0.14.1" ethers-solc = "2.0.14" ethnum = "1.5.0" @@ -326,6 +332,7 @@ halo2curves = "0.1.0" hex = { version = "0.4", features = ["serde"] } hpke = "0.13.0" hmac = "0.12" +hkdf = "0.12.4" home = "0.5.11" indoc = "2" indexmap = { version = "2.14", features = ["serde"] } @@ -363,12 +370,17 @@ quickcheck = "1.0.3" rand = "0.8.5" rand_chacha = "0.3.1" rand_chacha_09 = { package = "rand_chacha", version = "0.9.0" } +rand_core_09 = { package = "rand_core", version = "0.9.3", default-features = false, features = [ + "os_rng", + "std", +] } rand_xorshift = "0.4" reqwest = { version = "0.12", features = ["json", "multipart", "stream"] } rlp = "0.6.1" rmp-serde = "1.3.1" rocksdb = "0.21" rpassword = "7.4.0" +rusqlite = { version = "0.39.0", features = ["bundled"] } rustc-hex = "2.1.0" rust-i18n = "3" rsa = { version = "0.9", features = ["sha1"] } @@ -437,7 +449,7 @@ tracing-opentelemetry = "0.32.0" x25519-dalek = { version = "2.0.1", features = ["static_secrets"] } # utilities for deriving stuff on macros -strum = "0.27" +strum = { version = "0.27", features = ["derive"] } strum_macros = "0.27.2" rayon = "1" derivative = "2" @@ -462,7 +474,6 @@ http = "1.4" [patch.crates-io] # rust-i18n uses a deprecated serde_yaml dependency, so we use our shim instead serde_yaml = { path = "pkg/serde_yaml" } -workspace-hack = { path = "pkg/workspace-hack" } [workspace.metadata.i18n] load-path = "./pkg/wallet-core/locales" diff --git a/README.md b/README.md index b472e08..f8d298c 100644 --- a/README.md +++ b/README.md @@ -361,17 +361,13 @@ cargo test integration_test docker build -f ./docker/Dockerfile.node --target tester . ``` -### Workspace hack crate +### Workspace dependencies -We use [`cargo-hakari`](https://docs.rs/cargo-hakari) to keep a unified `workspace-hack` crate in sync across all `Cargo.toml` files. Run the following after adding or modifying workspace dependencies and before opening a pull request: - -``` -cargo hakari generate -cargo hakari manage-deps --yes -``` - -The `Rust / Hakari Check` GitHub workflow enforces that the crate stays synchronized; if it fails, re-run the commands above and commit the resulting changes. -The main `Test` workflow also verifies `Cargo.lock` during its clippy run by adding `--locked` to `cargo hack clippy`; if that check reports that the lockfile needs updates, regenerate and commit `Cargo.lock` before retrying CI. +Workspace crates should inherit shared dependencies from the root +`[workspace.dependencies]` table. Run `cargo xtask lint` after changing +manifests; it validates workspace dependency inheritance across Cargo workspace +members. CI runs `cargo run --locked --bin xtask -q -- lint --check`, which +rejects stale `Cargo.lock` state during clippy. ## Contributing diff --git a/beam-apps/apps/uniswap/src/api.rs b/beam-apps/apps/uniswap/src/api.rs index c8f66cf..f9e872f 100644 --- a/beam-apps/apps/uniswap/src/api.rs +++ b/beam-apps/apps/uniswap/src/api.rs @@ -1,4 +1,4 @@ -use serde_json::{Value, json}; +use serde_json::{Number, Value, json}; use crate::{Error, Result}; @@ -55,58 +55,82 @@ pub fn check_approval_payload(request: &QuoteRequest) -> Value { pub fn quote_payload(request: &QuoteRequest) -> Value { json!({ "amount": request.amount, + "permitAmount": "EXACT", "protocols": ["V2", "V3", "V4"], "recipient": request.recipient, - "slippageTolerance": request.slippage_bps, + "routingPreference": "BEST_PRICE", + "slippageTolerance": slippage_tolerance(request.slippage_bps), + "swapper": request.wallet, "tokenIn": request.token_in, "tokenInChainId": request.chain_id, "tokenOut": request.token_out, "tokenOutChainId": request.chain_id, "type": "EXACT_INPUT", - "walletAddress": request.wallet, + "urgency": "normal", }) } -pub fn swap_payload(quote: &QuoteResponse, wallet: &str) -> Value { +pub fn swap_payload(quote: &QuoteResponse, _wallet: &str) -> Value { json!({ "quote": quote.quote, + "refreshGasPrice": true, "simulateTransaction": true, - "walletAddress": wallet, + "urgency": "normal", }) } pub fn parse_quote(value: Value, request: &QuoteRequest) -> Result { + let quote = value.get("quote").cloned().unwrap_or_else(|| value.clone()); validate_optional_field( - &value, + "e, &["tokenInChainId", "chainId"], + &[], &request.chain_id.to_string(), )?; - validate_optional_field(&value, &["tokenOutChainId"], &request.chain_id.to_string())?; - validate_optional_field(&value, &["tokenIn", "inputToken"], &request.token_in)?; - validate_optional_field(&value, &["tokenOut", "outputToken"], &request.token_out)?; - let amount_out = - first_string(&value, &["amountOut", "output", "quoteAmount"]).ok_or_else(|| { - Error::InvalidUniswapResponse { - reason: "quote missing output amount".to_string(), - } - })?; - let quote_id = first_string(&value, &["quoteId", "requestId", "routingId"]) + validate_optional_field( + "e, + &["tokenOutChainId"], + &[], + &request.chain_id.to_string(), + )?; + validate_optional_field( + "e, + &["tokenIn", "inputToken"], + &[&["input", "token"]], + &request.token_in, + )?; + validate_optional_field( + "e, + &["tokenOut", "outputToken"], + &[&["output", "token"]], + &request.token_out, + )?; + let amount_out = first_string_or_path( + "e, + &["amountOut", "quoteAmount"], + &[&["output", "amount"]], + ) + .ok_or_else(|| Error::InvalidUniswapResponse { + reason: "quote missing output amount".to_string(), + })?; + let quote_id = first_string("e, &["quoteId", "requestId", "routingId"]) + .or_else(|| first_string(&value, &["quoteId", "requestId", "routingId"])) .unwrap_or_else(|| "uniswap-quote".to_string()); - let route = first_string(&value, &["routing", "routeString", "route"]) + let route = first_string(&value, &["routing"]) + .or_else(|| first_string("e, &["routing", "routeString", "route"])) .unwrap_or_else(|| "classic".to_string()); - if route.to_ascii_lowercase().contains("dutch") - || route.to_ascii_lowercase().contains("uniswapx") - { + if is_order_route(&route) { return Err(Error::UnsupportedUniswapRoute { route }); } Ok(QuoteResponse { amount_out, - minimum_amount_out: first_string( - &value, + minimum_amount_out: first_string_or_path( + "e, &["amountOutMinimum", "minimumAmountOut", "minAmountOut"], + &[&["output", "minAmount"]], ), - quote: value, + quote, quote_id, route, valid_for_seconds: 180, @@ -140,8 +164,13 @@ pub fn approval_spender(data: &str) -> Option { Some(format!("0x{}", &data[8 + 24..8 + 64])) } -fn validate_optional_field(value: &Value, keys: &[&str], expected: &str) -> Result<()> { - let Some(actual) = first_string(value, keys) else { +fn validate_optional_field( + value: &Value, + keys: &[&str], + paths: &[&[&str]], + expected: &str, +) -> Result<()> { + let Some(actual) = first_string_or_path(value, keys, paths) else { return Ok(()); }; if !actual.eq_ignore_ascii_case(expected) { @@ -153,6 +182,16 @@ fn validate_optional_field(value: &Value, keys: &[&str], expected: &str) -> Resu Ok(()) } +fn slippage_tolerance(slippage_bps: u32) -> Value { + let value = f64::from(slippage_bps) / 100.0; + Value::Number(Number::from_f64(value).unwrap_or_else(|| Number::from(0))) +} + +fn is_order_route(route: &str) -> bool { + let route = route.to_ascii_lowercase(); + route.contains("dutch") || route.contains("uniswapx") || route == "priority" +} + fn parse_transaction(value: &Value) -> Option { Some(UniswapTransaction { data: first_string(value, &["data", "calldata", "input"])?, @@ -172,3 +211,16 @@ fn first_string(value: &Value, keys: &[&str]) -> Option { }) }) } + +fn first_string_or_path(value: &Value, keys: &[&str], paths: &[&[&str]]) -> Option { + first_string(value, keys).or_else(|| paths.iter().find_map(|path| path_string(value, path))) +} + +fn path_string(value: &Value, path: &[&str]) -> Option { + let value = path.iter().try_fold(value, |value, key| value.get(key))?; + match value { + Value::String(value) => Some(value.clone()), + Value::Number(value) => Some(value.to_string()), + _ => None, + } +} diff --git a/beam-apps/apps/uniswap/src/host.rs b/beam-apps/apps/uniswap/src/host.rs index 671c17d..9419add 100644 --- a/beam-apps/apps/uniswap/src/host.rs +++ b/beam-apps/apps/uniswap/src/host.rs @@ -5,6 +5,7 @@ use crate::{Error, Result, selector}; const HOST_API_VERSION: u32 = 1; const HOST_RESPONSE_CAPACITY: usize = 2 * 1024 * 1024; +const MAX_ERROR_BODY_CHARS: usize = 500; #[derive(Clone, Debug, Eq, PartialEq)] pub struct PlanContext { @@ -38,6 +39,8 @@ pub struct HostMetadata { pub app_version: String, pub chain: String, pub chain_id: u64, + #[serde(default)] + pub debug: bool, pub host_api_version: u32, pub manifest_sha256: String, pub now: u64, @@ -230,10 +233,18 @@ pub fn http_json(method: &str, url: &str, value: &Value) -> Result { name: "content-type".to_string(), value: "application/json".to_string(), }, + HttpHeader { + name: "accept".to_string(), + value: "application/json".to_string(), + }, HttpHeader { name: "x-api-key".to_string(), value: crate::public_api_key().to_string(), }, + HttpHeader { + name: "x-permit2-disabled".to_string(), + value: "true".to_string(), + }, ], body, }))?; @@ -243,8 +254,14 @@ pub fn http_json(method: &str, url: &str, value: &Value) -> Result { } })?; if !(200..300).contains(&response.status) { + let detail = error_body(&response.body) + .map(|body| format!(": {body}")) + .unwrap_or_default(); return Err(Error::HostCallFailed { - message: format!("{} returned status {}", response.url, response.status), + message: format!( + "{} returned status {}{}", + response.url, response.status, detail + ), }); } serde_json::from_slice(&response.body).map_err(|err| Error::InvalidHostResponse { @@ -252,6 +269,14 @@ pub fn http_json(method: &str, url: &str, value: &Value) -> Result { }) } +fn error_body(body: &[u8]) -> Option { + let body = core::str::from_utf8(body).ok()?.trim(); + if body.is_empty() { + return None; + } + Some(body.chars().take(MAX_ERROR_BODY_CHARS).collect()) +} + pub fn resolve_address(value: Option<&str>) -> Result { let response = host_call(HostRequest::ResolveAddress { value: value.map(str::to_string), diff --git a/beam-apps/apps/uniswap/src/lib.rs b/beam-apps/apps/uniswap/src/lib.rs index 2b5a361..0c8747e 100644 --- a/beam-apps/apps/uniswap/src/lib.rs +++ b/beam-apps/apps/uniswap/src/lib.rs @@ -94,12 +94,21 @@ fn run_guest(input_ptr: *const u8, input_len: usize) -> Result { } fn run_swap(invocation: GuestInvocation) -> Result { + let debug_enabled = invocation.metadata.debug; + debug(debug_enabled, "swap:start"); let args = SwapArgs::parse(&invocation.args)?; + debug(debug_enabled, "swap:args:parsed"); let chain = invocation.metadata.chain.clone(); let wallet = invocation.metadata.wallet.clone(); + debug(debug_enabled, "swap:recipient:resolve"); let recipient = host::resolve_address(args.recipient.as_deref())?; + debug(debug_enabled, "swap:recipient:resolved"); + debug(debug_enabled, "swap:sell-token:metadata"); let sell = host::token_metadata(&chain, &args.sell_token)?; + debug(debug_enabled, "swap:sell-token:metadata-loaded"); + debug(debug_enabled, "swap:buy-token:metadata"); let buy = host::token_metadata(&chain, &args.buy_token)?; + debug(debug_enabled, "swap:buy-token:metadata-loaded"); let amount_raw = amount_to_raw(&args.amount, sell.decimals)?; let min_receive_raw = args .min_receive @@ -115,37 +124,53 @@ fn run_swap(invocation: GuestInvocation) -> Result { token_out: buy.address.clone(), wallet: wallet.clone(), }; - let quote = parse_quote( - host::http_json( - "POST", - "https://trade-api.gateway.uniswap.org/v1/quote", - "e_payload("e_request), - )?, - "e_request, + debug(debug_enabled, "swap:quote:request"); + let quote_value = host::http_json( + "POST", + "https://trade-api.gateway.uniswap.org/v1/quote", + "e_payload("e_request), )?; + debug(debug_enabled, "swap:quote:response"); + let quote = parse_quote(quote_value, "e_request)?; + debug(debug_enabled, "swap:quote:parsed"); let approval = if sell.is_native { + debug(debug_enabled, "swap:approval:skipped-native-token"); None } else { + debug(debug_enabled, "swap:approval:request"); let value = host::http_json( "POST", "https://trade-api.gateway.uniswap.org/v1/check_approval", &check_approval_payload("e_request), )?; + debug(debug_enabled, "swap:approval:response"); Some(ApprovalResponse { transaction: find_transaction(&value), }) }; - let allowance = approval + let allowance = match approval .as_ref() .and_then(|approval| approval.transaction.as_ref()) .and_then(|transaction| approval_spender(&transaction.data)) - .map(|spender| host::allowance(&chain, &sell.address, &spender)) - .transpose()?; + { + Some(spender) => { + debug(debug_enabled, "swap:allowance:request"); + let allowance = host::allowance(&chain, &sell.address, &spender)?; + debug(debug_enabled, "swap:allowance:response"); + Some(allowance) + } + None => { + debug(debug_enabled, "swap:allowance:skipped"); + None + } + }; + debug(debug_enabled, "swap:swap:request"); let swap_value = host::http_json( "POST", "https://trade-api.gateway.uniswap.org/v1/swap", &swap_payload("e, &wallet), )?; + debug(debug_enabled, "swap:swap:response"); let mut swap = SwapResponse { transaction: find_transaction(&swap_value).ok_or_else(|| { Error::InvalidUniswapResponse { @@ -154,7 +179,9 @@ fn run_swap(invocation: GuestInvocation) -> Result { })?, raw: swap_value, }; + debug(debug_enabled, "swap:transaction:parsed"); if swap.transaction.gas_limit.is_none() || swap.transaction.gas_price.is_none() { + debug(debug_enabled, "swap:gas:request"); let (gas_limit, gas_price) = host::gas( &chain, &swap.transaction.to, @@ -163,10 +190,17 @@ fn run_swap(invocation: GuestInvocation) -> Result { )?; swap.transaction.gas_limit = swap.transaction.gas_limit.or(gas_limit); swap.transaction.gas_price = swap.transaction.gas_price.or(Some(gas_price)); + debug(debug_enabled, "swap:gas:response"); } - simulate_best_effort(&chain, approval.as_ref(), &swap); + debug(debug_enabled, "swap:simulation:start"); + simulate_best_effort(debug_enabled, &chain, approval.as_ref(), &swap); + debug(debug_enabled, "swap:simulation:complete"); + debug(debug_enabled, "swap:balance:request"); + let sell_balance = host::balance(&chain, &sell.address)?; + debug(debug_enabled, "swap:balance:response"); - build_swap_plan(SwapPlanInput { + debug(debug_enabled, "swap:plan:build"); + let plan = build_swap_plan(SwapPlanInput { allowance, amount_raw, args, @@ -175,18 +209,27 @@ fn run_swap(invocation: GuestInvocation) -> Result { expires_at: invocation.metadata.now, min_receive_raw, quote, - sell_balance: host::balance(&chain, &sell.address)?, + sell_balance, sell, approval, swap, - }) + })?; + debug(debug_enabled, "swap:plan:built"); + + Ok(plan) } -fn simulate_best_effort(chain: &str, approval: Option<&ApprovalResponse>, swap: &SwapResponse) { +fn simulate_best_effort( + debug_enabled: bool, + chain: &str, + approval: Option<&ApprovalResponse>, + swap: &SwapResponse, +) { if let Some(transaction) = approval .and_then(|approval| approval.transaction.as_ref()) .filter(|transaction| approval_spender(&transaction.data).is_some()) { + debug(debug_enabled, "swap:simulation:approval:request"); let spender = approval_spender(&transaction.data); if let Err(err) = host::simulate( chain, @@ -196,8 +239,11 @@ fn simulate_best_effort(chain: &str, approval: Option<&ApprovalResponse>, swap: spender.as_deref(), ) { let _ = host::diagnostic("warn", &format!("approval simulation skipped: {err}")); + } else { + debug(debug_enabled, "swap:simulation:approval:response"); } } + debug(debug_enabled, "swap:simulation:swap:request"); if let Err(err) = host::simulate( chain, &swap.transaction.to, @@ -206,6 +252,14 @@ fn simulate_best_effort(chain: &str, approval: Option<&ApprovalResponse>, swap: None, ) { let _ = host::diagnostic("warn", &format!("swap simulation skipped: {err}")); + } else { + debug(debug_enabled, "swap:simulation:swap:response"); + } +} + +fn debug(enabled: bool, message: &str) { + if enabled { + let _ = host::diagnostic("debug", message); } } diff --git a/beam-apps/apps/uniswap/src/plan.rs b/beam-apps/apps/uniswap/src/plan.rs index 3a63ca3..b716c47 100644 --- a/beam-apps/apps/uniswap/src/plan.rs +++ b/beam-apps/apps/uniswap/src/plan.rs @@ -131,15 +131,7 @@ fn swap_step(input: &SwapPlanInput) -> ActionStep { let transaction = &input.swap.transaction; ActionStep { kind: "transaction".to_string(), - metadata: json!({ - "buy": input.buy.label, - "quote_id": input.quote.quote_id, - "route": input.quote.route, - "sell": input.sell.label, - "slippage_bps": input.args.slippage_bps, - "swap": input.swap.raw, - "transaction": transaction_json(transaction), - }), + metadata: swap_metadata(input, transaction), selector: selector(&transaction.data), spender: None, summary: format!( @@ -151,6 +143,33 @@ fn swap_step(input: &SwapPlanInput) -> ActionStep { } } +fn swap_metadata(input: &SwapPlanInput, transaction: &UniswapTransaction) -> Value { + let mut metadata = json!({ + "buy": input.buy.label, + "quote_id": input.quote.quote_id, + "route": input.quote.route, + "sell": input.sell.label, + "slippage_bps": input.args.slippage_bps, + "transaction": transaction_json(transaction), + }); + if let Some(request_id) = raw_string(&input.swap.raw, "requestId") { + metadata["request_id"] = json!(request_id); + } + if let Some(gas_fee) = raw_string(&input.swap.raw, "gasFee") { + metadata["gas_fee"] = json!(gas_fee); + } + + metadata +} + +fn raw_string(value: &Value, key: &str) -> Option { + match value.get(key)? { + Value::Number(value) => Some(value.to_string()), + Value::String(value) => Some(value.clone()), + _ => None, + } +} + fn ensure_balance(input: &SwapPlanInput) -> Result<()> { if parse_uint(&input.sell_balance)? < parse_uint(&input.amount_raw)? { return Err(Error::InsufficientBalance { diff --git a/beam-apps/apps/uniswap/src/tests.rs b/beam-apps/apps/uniswap/src/tests.rs index 2742d68..47d6b7f 100644 --- a/beam-apps/apps/uniswap/src/tests.rs +++ b/beam-apps/apps/uniswap/src/tests.rs @@ -2,7 +2,8 @@ use serde_json::json; use crate::{ ApprovalResponse, PlanContext, QuoteRequest, SwapArgs, SwapPlanInput, SwapResponse, SwapToken, - UniswapTransaction, approval_spender, build_swap_plan, parse_quote, public_api_key, selector, + UniswapTransaction, approval_spender, build_swap_plan, parse_quote, public_api_key, + quote_payload, selector, swap_payload, }; #[test] @@ -73,6 +74,80 @@ fn public_api_key_is_embed_ready() { assert!(!key.contains('\r')); } +#[test] +fn quote_payload_uses_current_uniswap_schema() { + let payload = quote_payload("e_request()); + + assert_eq!( + payload["swapper"].as_str(), + Some("0x3333333333333333333333333333333333333333") + ); + assert_eq!(payload.get("walletAddress"), None); + assert_eq!(payload["slippageTolerance"].as_f64(), Some(0.5)); + assert_eq!(payload["permitAmount"].as_str(), Some("EXACT")); +} + +#[test] +fn quote_parser_accepts_nested_current_response() { + let request = quote_request(); + let quote = parse_quote( + json!({ + "requestId": "request-1", + "routing": "CLASSIC", + "quote": { + "chainId": 8453, + "input": { + "amount": "10000000", + "token": "0x1111111111111111111111111111111111111111", + }, + "output": { + "amount": "100", + "minAmount": "99", + "token": "0x0000000000000000000000000000000000000000", + }, + "quoteId": "quote-1", + "routeString": "[V3] USDC -- 0.05% ETH", + "swapper": "0x3333333333333333333333333333333333333333", + } + }), + &request, + ) + .expect("parse current quote response"); + + assert_eq!(quote.amount_out, "100"); + assert_eq!(quote.minimum_amount_out.as_deref(), Some("99")); + assert_eq!(quote.quote_id, "quote-1"); + assert_eq!(quote.route, "CLASSIC"); + assert_eq!( + quote.quote["swapper"].as_str(), + Some(request.wallet.as_str()) + ); +} + +#[test] +fn swap_payload_omits_legacy_wallet_address() { + let quote = parse_quote( + json!({ + "amountOut": "100", + "quoteId": "quote-1", + "route": "classic", + "tokenInChainId": 8453, + "tokenOutChainId": 8453, + "tokenIn": "0x1111111111111111111111111111111111111111", + "tokenOut": "0x0000000000000000000000000000000000000000", + }), + "e_request(), + ) + .expect("parse quote"); + + let payload = swap_payload("e, "0x3333333333333333333333333333333333333333"); + + assert_eq!(payload.get("walletAddress"), None); + assert_eq!(payload["simulateTransaction"].as_bool(), Some(true)); + assert_eq!(payload["refreshGasPrice"].as_bool(), Some(true)); + assert_eq!(payload["quote"]["quoteId"].as_str(), Some("quote-1")); +} + #[test] fn builds_approval_and_swap_action_plan() { let args = SwapArgs::parse(&[ @@ -120,7 +195,16 @@ fn builds_approval_and_swap_action_plan() { transaction: Some(transaction("0x095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba30000000000000000000000000000000000000000000000000000000000989680")), }), swap: SwapResponse { - raw: json!({ "transaction": { "to": "0x2222222222222222222222222222222222222222" } }), + raw: json!({ + "gasFee": "123", + "quote": { + "route": [ + { "protocol": "V3", "tokenIn": "USDC", "tokenOut": "ETH" }, + ], + }, + "requestId": "swap-request-1", + "transaction": { "to": "0x2222222222222222222222222222222222222222" }, + }), transaction: transaction("0x3593564c"), }, }) @@ -129,6 +213,13 @@ fn builds_approval_and_swap_action_plan() { assert_eq!(plan.steps.len(), 2); assert_eq!(plan.steps[0].kind, "erc20-approval"); assert_eq!(plan.steps[1].kind, "transaction"); + assert_eq!(plan.steps[1].metadata.get("swap"), None); + assert_eq!(plan.steps[1].metadata.get("quote"), None); + assert_eq!( + plan.steps[1].metadata["request_id"].as_str(), + Some("swap-request-1") + ); + assert_eq!(plan.steps[1].metadata["gas_fee"].as_str(), Some("123")); assert!( plan.bindings .iter() diff --git a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json index 64199df..123dc1e 100644 --- a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "0.2.1", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -219,6 +219,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:847162262ed6ee2a090a77fdc0b7caa2bf90cbfc385fb4f18b271c00a9558f36" + "value": "sha256:e27bed5240e9eeb775f4830f1e46149e514057c6e4b4ca3574f027fa12d9daa1" } } diff --git a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/broad-wildcard/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/broad-wildcard/index.json b/beam-apps/fixtures/broad-wildcard/index.json index d6d0817..b3923c1 100644 --- a/beam-apps/fixtures/broad-wildcard/index.json +++ b/beam-apps/fixtures/broad-wildcard/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", - "module_sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "module_sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } } diff --git a/beam-apps/fixtures/broad-wildcard/index.json.sig b/beam-apps/fixtures/broad-wildcard/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/broad-wildcard/index.json.sig +++ b/beam-apps/fixtures/broad-wildcard/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json index 5ec8c40..4b4bf56 100644 --- a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "0.2.1", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -290,6 +290,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } } diff --git a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/invalid-digest/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/invalid-digest/index.json b/beam-apps/fixtures/invalid-digest/index.json index d689508..ff3fde0 100644 --- a/beam-apps/fixtures/invalid-digest/index.json +++ b/beam-apps/fixtures/invalid-digest/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", "module_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:293d1e56cb7ac2c07c4136e2fd94afd9a8d175702bb8e8bd9c5afce93184fa7a" + "value": "sha256:1d37a1f8f1729015d06f67214042aed05298a44e21bc07c63c266cb19e3f421d" } } diff --git a/beam-apps/fixtures/invalid-digest/index.json.sig b/beam-apps/fixtures/invalid-digest/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/invalid-digest/index.json.sig +++ b/beam-apps/fixtures/invalid-digest/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json index 007c650..200fe0c 100644 --- a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "0.2.1", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -221,6 +221,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:bb1fb10740ad500c6a37064acf750be47297a8a8889c2d4df6333accbb5a8ff6" + "value": "sha256:8e136bd9b04f736be0593506305b42957f53f8ee94b21857275645315d52dc32" } } diff --git a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/malformed-permissions/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/malformed-permissions/index.json b/beam-apps/fixtures/malformed-permissions/index.json index d6d0817..b3923c1 100644 --- a/beam-apps/fixtures/malformed-permissions/index.json +++ b/beam-apps/fixtures/malformed-permissions/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", - "module_sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "module_sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } } diff --git a/beam-apps/fixtures/malformed-permissions/index.json.sig b/beam-apps/fixtures/malformed-permissions/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/malformed-permissions/index.json.sig +++ b/beam-apps/fixtures/malformed-permissions/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json index e1b0e0b..475d76c 100644 --- a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "0.2.1", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -129,6 +129,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:2baa744c8f1d81ebe4e28aff957d05f1371ed81e22c604ed4fc4a9dabce0c1d8" + "value": "sha256:ce538d2a143e48a1d5dd7bd36896f3727f4148e589ddca7d601e6d5b4b5d5f9b" } } diff --git a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/missing-fields/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/missing-fields/index.json b/beam-apps/fixtures/missing-fields/index.json index d6d0817..b3923c1 100644 --- a/beam-apps/fixtures/missing-fields/index.json +++ b/beam-apps/fixtures/missing-fields/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", - "module_sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "module_sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } } diff --git a/beam-apps/fixtures/missing-fields/index.json.sig b/beam-apps/fixtures/missing-fields/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/missing-fields/index.json.sig +++ b/beam-apps/fixtures/missing-fields/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json index 4c68d88..b418ab9 100644 --- a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "999.0.0", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -290,6 +290,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:0b2b6fa6ae3017fbc1316892bd357652c70f66a9b3f9dabe7e313946c604b07f" + "value": "sha256:29e99d1f0d955b6002cc80bc9f4e3c4d7fb80d62da8e153b582ba18529d0a0a0" } } diff --git a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/unsupported-beam/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/unsupported-beam/index.json b/beam-apps/fixtures/unsupported-beam/index.json index d6d0817..b3923c1 100644 --- a/beam-apps/fixtures/unsupported-beam/index.json +++ b/beam-apps/fixtures/unsupported-beam/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", - "module_sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "module_sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } } diff --git a/beam-apps/fixtures/unsupported-beam/index.json.sig b/beam-apps/fixtures/unsupported-beam/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/unsupported-beam/index.json.sig +++ b/beam-apps/fixtures/unsupported-beam/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json index 5ec8c40..4b4bf56 100644 --- a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json +++ b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json @@ -7,7 +7,7 @@ "description": "Prepare public Uniswap swaps through Beam-mediated HTTP, chain, approval, and transaction planning.", "min_beam_version": "0.2.1", "wasm": { - "sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "entrypoint": "beam_app_main" }, "catalog": { @@ -290,6 +290,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } } diff --git a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json.sig b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json.sig index d927149..53eeada 100644 --- a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json.sig +++ b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/manifest.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:a7bac552c206a4a3a86a0261d6e8efe4e374b62780e692669d4055c7f2933178" + "value": "sha256:a529b79e6b23e784176b3f2f78334d26b5d7b8dba15b66262829eda3b15d360b" } diff --git a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/module.wasm b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/module.wasm index 852d975..4d88a6a 100644 Binary files a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/module.wasm and b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/module.wasm differ diff --git a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/version.json.sig b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/version.json.sig index 2a5951d..250c2e2 100644 --- a/beam-apps/fixtures/valid/apps/uniswap/1.0.2/version.json.sig +++ b/beam-apps/fixtures/valid/apps/uniswap/1.0.2/version.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } diff --git a/beam-apps/fixtures/valid/index.json b/beam-apps/fixtures/valid/index.json index d6d0817..b3923c1 100644 --- a/beam-apps/fixtures/valid/index.json +++ b/beam-apps/fixtures/valid/index.json @@ -12,13 +12,13 @@ "version": "1.0.2", "min_beam_version": "0.2.1", "manifest_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/manifest.json", - "manifest_sha256": "sha256:07b1223ee0855508eb0c46743a3345e96422f97a7cf12175c504bfee8850341b", + "manifest_sha256": "sha256:b3bee997c062dbf20de57c4176a010b3578bf4a5e7c8a57017733bd5a95e2b73", "module_url": "https://registry.beam.payy.network/apps/uniswap/1.0.2/module.wasm", - "module_sha256": "sha256:18aa6e8845772beccef895e83bbf2d1f3783d24fbf0fb8feee75d1eacfa1a7f9", + "module_sha256": "sha256:58c5dbc8343f5281392269b72e0193b2c39f6a4b36942df1bea464699a36cdc2", "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:c066a56b6703a1d421195be37474192a11a960ce259991ff3cb91fd2f062c8de" + "value": "sha256:447860c5bbc66e4f9b418bb2c67155a5c276812828da8c417a20387882fee0dc" } } ] @@ -27,6 +27,6 @@ "signature": { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } } diff --git a/beam-apps/fixtures/valid/index.json.sig b/beam-apps/fixtures/valid/index.json.sig index 1593252..4193503 100644 --- a/beam-apps/fixtures/valid/index.json.sig +++ b/beam-apps/fixtures/valid/index.json.sig @@ -1,5 +1,5 @@ { "algorithm": "sha256-dev", "key_id": "payy-dev-2026-05", - "value": "sha256:02b57fe91af9b8247f4b71214bbe382ea4b09a63461bd05c5e59e61987a5c98d" + "value": "sha256:f1ad11d143f310620be1bc78a9d02fb7db7ec51d05acae195c1115167aef3dee" } diff --git a/docker/Dockerfile.payy-auth-api-bin b/docker/Dockerfile.payy-auth-api-bin new file mode 100644 index 0000000..e236626 --- /dev/null +++ b/docker/Dockerfile.payy-auth-api-bin @@ -0,0 +1,86 @@ +FROM rust:1-bookworm AS builder +ARG SCCACHE_GCS_BUCKET +ARG SCCACHE_GCS_KEY_PREFIX +ARG SCCACHE_BUCKET +ARG SCCACHE_S3_KEY_PREFIX +ARG SCCACHE_REGION +ARG SCCACHE_ENDPOINT +ARG SCCACHE_S3_USE_SSL + +# libclang is required by bindgen (zstd-sys, aws-lc-sys build scripts); +# cmake is required by aws-lc-sys. +RUN apt-get update \ + && apt-get install -y --no-install-recommends libclang-dev cmake \ + && rm -rf /var/lib/apt/lists/* + +# Conditional sccache setup: only if remote cache settings are provided +RUN if [ -n "$SCCACHE_GCS_BUCKET" ] || [ -n "$SCCACHE_BUCKET" ]; then \ + wget https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz && \ + tar -xzf sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz && \ + mv sccache-v0.10.0-x86_64-unknown-linux-musl/sccache /usr/local/cargo/bin/sccache && \ + rm -rf sccache-v0.10.0-x86_64-unknown-linux-musl sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz && \ + chmod +x /usr/local/cargo/bin/sccache; \ + fi +ENV SCCACHE_GCS_BUCKET=$SCCACHE_GCS_BUCKET +ENV SCCACHE_GCS_KEY_PREFIX=$SCCACHE_GCS_KEY_PREFIX +ENV SCCACHE_GCS_RW_MODE=READ_WRITE +ENV SCCACHE_BUCKET=$SCCACHE_BUCKET +ENV SCCACHE_S3_KEY_PREFIX=$SCCACHE_S3_KEY_PREFIX +ENV SCCACHE_REGION=$SCCACHE_REGION +ENV SCCACHE_ENDPOINT=$SCCACHE_ENDPOINT +ENV SCCACHE_S3_USE_SSL=$SCCACHE_S3_USE_SSL + +WORKDIR /build + +COPY rust-toolchain.toml ./ +COPY .cargo/config.toml .cargo/config.toml +COPY Cargo.toml Cargo.lock ./ +COPY pkg ./pkg + +# The workspace lists the react-native rust bridge as a member; it is not part +# of this binary's dependency closure and its sources are outside the copied +# context, so drop it from the member list. +RUN sed 's|, "app/packages/react-native-rust-bridge/cpp/rustbridge"||g' Cargo.toml > Cargo.toml.tmp \ + && mv Cargo.toml.tmp Cargo.toml + +# Ensure the toolchain specified in rust-toolchain.toml is installed +RUN rustup show + +RUN --mount=type=secret,id=gcs_sa_key_base64,required=false \ + --mount=type=secret,id=aws_access_key_id,required=false \ + --mount=type=secret,id=aws_secret_access_key,required=false \ + if [ -n "$SCCACHE_BUCKET" ] && [ -n "$SCCACHE_ENDPOINT" ] && [ -f /run/secrets/aws_access_key_id ] && [ -f /run/secrets/aws_secret_access_key ]; then \ + echo "Using sccache with S3"; \ + AWS_ACCESS_KEY_ID="$(cat /run/secrets/aws_access_key_id)" \ + AWS_SECRET_ACCESS_KEY="$(cat /run/secrets/aws_secret_access_key)" \ + RUSTC_WRAPPER=/usr/local/cargo/bin/sccache cargo build --release -p payy-auth-api-bin; \ + elif [ -n "$SCCACHE_GCS_BUCKET" ] && [ -f /run/secrets/gcs_sa_key_base64 ]; then \ + echo "Using sccache with GCS"; \ + base64 -d /run/secrets/gcs_sa_key_base64 > /tmp/sccache-gcs-key.json && \ + SCCACHE_GCS_KEY_PATH=/tmp/sccache-gcs-key.json \ + RUSTC_WRAPPER=/usr/local/cargo/bin/sccache cargo build --release -p payy-auth-api-bin && \ + rm -f /tmp/sccache-gcs-key.json; \ + else \ + echo "Skipping sccache (missing required vars)"; \ + cargo build --release -p payy-auth-api-bin; \ + fi + +FROM debian:bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates libssl3 \ + && rm -rf /var/lib/apt/lists/* + +RUN adduser --disabled-password --gecos "" --uid 1001 payy + +# Wallet storage mount point; first use of a named volume copies this +# ownership so the non-root user can write. +RUN install -d -o payy -g payy /data + +COPY --from=builder /build/target/release/payy-auth-api-bin /usr/local/bin/payy-auth-api-bin + +USER payy + +EXPOSE 8787 + +CMD ["payy-auth-api-bin"] diff --git a/docker/docker-compose.payy-auth-phala.yml b/docker/docker-compose.payy-auth-phala.yml new file mode 100644 index 0000000..8e6b8a3 --- /dev/null +++ b/docker/docker-compose.payy-auth-phala.yml @@ -0,0 +1,57 @@ +# Phala Cloud / dstack deployment manifest for payy-auth-api-bin. +# +# The compose text is part of the attested measurement, so pin the image by +# digest: a mutable tag lets image contents drift under an unchanged compose +# hash. The payy-auth.release.phala.yaml workflow substitutes the digest of +# the freshly pushed image before deploying; for a manual deploy, replace the +# placeholder with a real digest yourself. +services: + payy-auth: + image: ghcr.io/polybase/payy-auth-api-bin@sha256:REPLACE_WITH_DIGEST + ports: + - "8787:8787" + volumes: + # dstack guest agent socket; kms-phala fetches all key material from it + # at startup and the binary fails closed when it is unavailable. + - /var/run/dstack.sock:/var/run/dstack.sock + # Wallet lifecycle facts and KMS custody allocations persist here so + # wallets survive restarts and upgrades. Records hold no private key + # material, and the CVM's data disk is LUKS-encrypted by dstack. + - payy-auth-data:/data + environment: + PAYY_AUTH_KMS: phala + PAYY_AUTH_STORAGE_DIR: /data + # The default bind address is 127.0.0.1, which the dstack gateway cannot + # reach from outside the container. + PAYY_AUTH_API_ADDR: 0.0.0.0:8787 + # Public deployment profile: this origin becomes the JWT issuer, PAT + # audience, and trusted wallet-RPC origin, and requests must carry an + # allowlisted Origin header (curl smokes included). The hostname is the + # dstack gateway name for this CVM: -.. + PAYY_AUTH_PUBLIC_ORIGIN: https://3964805fd025d1d17e4bf900849d6eadf892ab0f-8787.dstack-pha-prod9.phala.network + # EVM eth_sendTransaction broadcast endpoints, one entry per chain the + # deployment can send on. The Alchemy URLs embed the same kind of + # publicly-shipped API key the app bundle already ships to browsers, so + # they are not secrets and are safe in this attested compose text. A + # non-public backend RPC would instead have to be passed as an encrypted + # dstack env var (like the DSTACK_DOCKER_* pull credentials), never baked + # in here. Each app_id must match the seeded app id (PAYY_AUTH_APP_ID, + # default app-local). + PAYY_AUTH_EVM_RPC_ENDPOINTS: >- + [ + {"app_id": "app-local", "caip2": "eip155:1", "endpoint_id": "ethereum-mainnet", "base_url": "https://eth-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"}, + {"app_id": "app-local", "caip2": "eip155:137", "endpoint_id": "polygon-mainnet", "base_url": "https://polygon-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"}, + {"app_id": "app-local", "caip2": "eip155:8453", "endpoint_id": "base-mainnet", "base_url": "https://base-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"}, + {"app_id": "app-local", "caip2": "eip155:42161", "endpoint_id": "arbitrum-one", "base_url": "https://arb-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"}, + {"app_id": "app-local", "caip2": "eip155:10", "endpoint_id": "optimism-mainnet", "base_url": "https://opt-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"}, + {"app_id": "app-local", "caip2": "eip155:43114", "endpoint_id": "avalanche-c-chain", "base_url": "https://avax-mainnet.g.alchemy.com/v2/tM35lzH9DscymagwCy2GQ"} + ] + # Smoke-box only: re-exposes plaintext login codes at + # GET /_local/passwordless/emails, which the public profile hides by + # default. Remove as soon as real email delivery lands or this CVM + # serves anyone but us. + PAYY_AUTH_DEV_INBOX: "1" + restart: unless-stopped + +volumes: + payy-auth-data: diff --git a/docker/prelaunch.payy-auth-phala.sh b/docker/prelaunch.payy-auth-phala.sh new file mode 100644 index 0000000..591dc69 --- /dev/null +++ b/docker/prelaunch.payy-auth-phala.sh @@ -0,0 +1,339 @@ +#!/bin/bash +# Phala Cloud pre-launch script for the payy-auth CVM. +# +# Based on the dashboard-generated "Phala Cloud Pre-Launch Script v0.0.15", +# with fixes: +# 1. GHCR pull-access verification handles digest-pinned images +# (repo@sha256:...); the original mangled the repo path and always got +# HTTP 404 for digest refs. +# 2. `unset $VAR` -> `unset VAR` in the SSH key section; the original +# expanded key material as identifier names, which fails under `set -e`. +# +# The payy-auth.release.phala.yaml workflow passes this file on every deploy +# via `phala deploy --pre-launch-script`, so this copy is canonical. +echo "----------------------------------------------" +echo "Running Phala Cloud Pre-Launch Script v0.0.15-payy.1" +echo "----------------------------------------------" +set -e + +# Function: notify host + +notify_host() { + if command -v dstack-util >/dev/null 2>&1; then + dstack-util notify-host -e "$1" -d "$2" + else + tdxctl notify-host -e "$1" -d "$2" + fi +} + +notify_host_hoot_info() { + notify_host "boot.progress" "$1" +} + +notify_host_hoot_error() { + notify_host "boot.error" "$1" +} + +# Function: Perform Docker cleanup +perform_cleanup() { + echo "Pruning unused images" + docker image prune -af + echo "Pruning unused volumes" + docker volume prune -f + notify_host_hoot_info "docker cleanup completed" +} + +# Function: Check Docker login status without exposing credentials +check_docker_login() { + local registry="$1" + + # When registry is specified, check auth entry for that registry in Docker config + if [[ -n "$registry" ]]; then + local docker_config_path="${DOCKER_CONFIG:-$HOME/.docker}/config.json" + if [[ -f "$docker_config_path" ]] && grep -q "$registry" "$docker_config_path"; then + return 0 + else + return 1 + fi + fi + + # Fallback check when no explicit registry is provided + if docker info 2>/dev/null | grep -q "Username"; then + return 0 + else + return 1 + fi +} + +# Main logic starts here +echo "Starting login process..." + +# Check if Docker credentials exist +if [[ -n "$DSTACK_DOCKER_USERNAME" && -n "$DSTACK_DOCKER_PASSWORD" ]]; then + echo "Docker credentials found" + DOCKER_REGISTRY_TARGET="${DSTACK_DOCKER_REGISTRY:-docker.io}" + echo "Target Docker registry: $DOCKER_REGISTRY_TARGET" + + # Check if already logged in + if check_docker_login "$DSTACK_DOCKER_REGISTRY"; then + echo "Already logged in to Docker registry: $DOCKER_REGISTRY_TARGET" + else + echo "Logging in to Docker registry: $DOCKER_REGISTRY_TARGET" + # Login without exposing password in process list + if [[ -n "$DSTACK_DOCKER_REGISTRY" ]]; then + echo "$DSTACK_DOCKER_PASSWORD" | docker login -u "$DSTACK_DOCKER_USERNAME" --password-stdin "$DSTACK_DOCKER_REGISTRY" + else + echo "$DSTACK_DOCKER_PASSWORD" | docker login -u "$DSTACK_DOCKER_USERNAME" --password-stdin + fi + + if [ $? -eq 0 ]; then + echo "Docker login successful: $DOCKER_REGISTRY_TARGET" + else + echo "Docker login failed: $DOCKER_REGISTRY_TARGET" + notify_host_hoot_error "docker login failed" + exit 1 + fi + fi +# Check if AWS ECR credentials exist +elif [[ -n "$DSTACK_AWS_ACCESS_KEY_ID" && -n "$DSTACK_AWS_SECRET_ACCESS_KEY" && -n "$DSTACK_AWS_REGION" && -n "$DSTACK_AWS_ECR_REGISTRY" ]]; then + echo "AWS ECR credentials found" + + # Check if AWS CLI is installed + if [ ! -f "./aws/dist/aws" ]; then + notify_host_hoot_info "awscli not installed, installing..." + echo "AWS CLI not installed, installing..." + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.24.14.zip" -o "awscliv2.zip" + echo "6ff031a26df7daebbfa3ccddc9af1450 awscliv2.zip" | md5sum -c + if [ $? -ne 0 ]; then + echo "MD5 checksum failed" + notify_host_hoot_error "awscli install failed" + exit 1 + fi + unzip awscliv2.zip &> /dev/null + else + echo "AWS CLI is already installed: ./aws/dist/aws" + fi + + # Set AWS credentials as environment variables + export AWS_ACCESS_KEY_ID="$DSTACK_AWS_ACCESS_KEY_ID" + export AWS_SECRET_ACCESS_KEY="$DSTACK_AWS_SECRET_ACCESS_KEY" + export AWS_DEFAULT_REGION="$DSTACK_AWS_REGION" + + # Set session token if provided (for temporary credentials) + if [[ -n "$DSTACK_AWS_SESSION_TOKEN" ]]; then + echo "AWS session token found, using temporary credentials" + export AWS_SESSION_TOKEN="$DSTACK_AWS_SESSION_TOKEN" + fi + + # Test AWS credentials before attempting ECR login + echo "Testing AWS credentials..." + if ! ./aws/dist/aws sts get-caller-identity &> /dev/null; then + echo "AWS credentials test failed" + # For session token credentials, this might be expected if they're expired + # Log warning but don't fail startup + if [[ -n "$DSTACK_AWS_SESSION_TOKEN" ]]; then + echo "Warning: AWS temporary credentials may have expired, continuing startup" + notify_host_hoot_info "AWS temporary credentials may have expired" + else + echo "AWS credentials test failed" + notify_host_hoot_error "Invalid AWS credentials" + exit 1 + fi + else + echo "Logging in to AWS ECR..." + ./aws/dist/aws ecr get-login-password --region $DSTACK_AWS_REGION | docker login --username AWS --password-stdin "$DSTACK_AWS_ECR_REGISTRY" + if [ $? -eq 0 ]; then + echo "AWS ECR login successful" + notify_host_hoot_info "AWS ECR login successful" + else + echo "AWS ECR login failed" + # For session token credentials, don't fail startup if login fails + if [[ -n "$DSTACK_AWS_SESSION_TOKEN" ]]; then + echo "Warning: AWS ECR login failed with temporary credentials, continuing startup" + notify_host_hoot_info "AWS ECR login failed with temporary credentials" + else + notify_host_hoot_error "AWS ECR login failed" + exit 1 + fi + fi + fi +fi + +perform_cleanup + +# +# GHCR image pull access verification (pure HTTP, no docker daemon) +# +if [[ "$DOCKER_REGISTRY_TARGET" == "ghcr.io" && -n "$DSTACK_DOCKER_USERNAME" && -n "$DSTACK_DOCKER_PASSWORD" ]]; then + COMPOSE_IMAGES=$(grep 'image:' /dstack/docker-compose.yaml 2>/dev/null | awk '{print $2}' | tr -d '"'"'" || true) + for img in $COMPOSE_IMAGES; do + [[ "$img" != ghcr.io/* ]] && continue + ref="${img#ghcr.io/}" + # Digest-pinned refs (repo@sha256:...) use the digest as the manifest + # reference; tag refs (repo:tag) use the tag, defaulting to latest. + if [[ "$ref" == *@* ]]; then + repo="${ref%%@*}" + reference="${ref#*@}" + else + repo="${ref%%:*}" + reference="${ref##*:}" + [[ "$reference" == "$ref" ]] && reference="latest" + fi + echo "Verifying GHCR pull access: $img" + token=$(curl -sf -u "$DSTACK_DOCKER_USERNAME:$DSTACK_DOCKER_PASSWORD" "https://ghcr.io/token?service=ghcr.io&scope=repository:${repo}:pull" | jq -r '.token // empty' || true) + if [[ -z "$token" ]]; then + echo "ERROR: GHCR token exchange failed for $img" + notify_host_hoot_error "GHCR token exchange failed: $img" + exit 1 + fi + http_code=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.docker.distribution.manifest.v2+json" "https://ghcr.io/v2/${repo}/manifests/${reference}") + if [[ "$http_code" != "200" ]]; then + echo "ERROR: GHCR pull access denied for $img (HTTP $http_code)" + notify_host_hoot_error "GHCR pull access denied: $img (HTTP $http_code)" + exit 1 + fi + echo "GHCR pull access OK: $img" + done +fi + +# +# Pull latest images from docker-compose.yaml so existing CVMs pick up new tags. +# Pull is fail-soft: short-lived tokens may expire between login and pull, but +# falling back to already-cached images is preferable to blocking boot. +# +echo "Images before pull:" +docker images --format '{{.Repository}}:{{.Tag}} {{.ID}} ({{.CreatedSince}})' + +echo "Pulling latest images from /dstack/docker-compose.yaml..." +if docker compose -f /dstack/docker-compose.yaml pull; then + echo "docker compose pull completed" + notify_host_hoot_info "docker compose pull completed" +else + echo "WARNING: docker compose pull failed; continuing with existing images" + notify_host_hoot_info "docker compose pull failed; using existing images" +fi + +echo "Images after pull:" +docker images --format '{{.Repository}}:{{.Tag}} {{.ID}} ({{.CreatedSince}})' + +# +# Set root password. +# +echo "Setting root password.." + +# Check if password files are writable +PASSWD_WRITABLE=true +if [ ! -w /etc/passwd ]; then + echo "Warning: /etc/passwd is read-only" + PASSWD_WRITABLE=false +fi +if [ ! -w /etc/shadow ]; then + echo "Warning: /etc/shadow is read-only" + PASSWD_WRITABLE=false +fi + +if [ "$PASSWD_WRITABLE" = "false" ]; then + echo "Skipping password setup due to read-only file system" +else + # Check if chpasswd is available + if command -v chpasswd >/dev/null 2>&1; then + echo "Using chpasswd method" + + if [ -n "$DSTACK_ROOT_PASSWORD" ]; then + echo "Setting root password from user.." + echo "root:$DSTACK_ROOT_PASSWORD" | chpasswd + unset DSTACK_ROOT_PASSWORD + echo "Root password set/updated from DSTACK_ROOT_PASSWORD" + elif [ -z "$(grep '^root:' /etc/shadow 2>/dev/null | cut -d: -f2)" ]; then + echo "Setting random root password.." + DSTACK_ROOT_PASSWORD=$( + LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | dd bs=1 count=32 2>/dev/null + ) + echo "root:$DSTACK_ROOT_PASSWORD" | chpasswd + unset DSTACK_ROOT_PASSWORD + echo "Root password set (random auto-init)" + else + echo "Root password already set; no changes." + fi + else + echo "Using passwd method" + + if [ -n "$DSTACK_ROOT_PASSWORD" ]; then + echo "Setting root password from user.." + echo "$DSTACK_ROOT_PASSWORD" | passwd --stdin root 2>/dev/null \ + || printf '%s\n%s\n' "$DSTACK_ROOT_PASSWORD" "$DSTACK_ROOT_PASSWORD" | passwd root + unset DSTACK_ROOT_PASSWORD + echo "Root password set/updated from DSTACK_ROOT_PASSWORD" + elif [ -z "$(grep '^root:' /etc/shadow 2>/dev/null | cut -d: -f2)" ]; then + echo "Setting random root password.." + DSTACK_ROOT_PASSWORD=$( + LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | dd bs=1 count=32 2>/dev/null + ) + echo "$DSTACK_ROOT_PASSWORD" | passwd --stdin root 2>/dev/null \ + || printf '%s\n%s\n' "$DSTACK_ROOT_PASSWORD" "$DSTACK_ROOT_PASSWORD" | passwd root + unset DSTACK_ROOT_PASSWORD + echo "Root password set (random auto-init)" + else + echo "Root password already set; no changes." + fi + fi +fi + +# +# Set SSH authorized keys +# +if mkdir -p /home/root/.ssh 2>/dev/null; then + if [[ -n "$DSTACK_ROOT_PUBLIC_KEY" ]]; then + echo "$DSTACK_ROOT_PUBLIC_KEY" > /home/root/.ssh/authorized_keys + unset DSTACK_ROOT_PUBLIC_KEY + echo "Root public key set" + fi + if [[ -n "$DSTACK_AUTHORIZED_KEYS" ]]; then + echo "$DSTACK_AUTHORIZED_KEYS" > /home/root/.ssh/authorized_keys + unset DSTACK_AUTHORIZED_KEYS + echo "Root authorized_keys set" + fi + + if [[ -f /dstack/user_config ]] && jq empty /dstack/user_config 2>/dev/null; then + if [[ $(jq 'has("ssh_authorized_keys")' /dstack/user_config 2>/dev/null) == "true" ]]; then + jq -j '.ssh_authorized_keys' /dstack/user_config >> /home/root/.ssh/authorized_keys + # Remove duplicates if there are multiple keys + if [[ $(cat /home/root/.ssh/authorized_keys | wc -l) -gt 1 ]]; then + sort -u /home/root/.ssh/authorized_keys > /home/root/.ssh/authorized_keys.tmp + mv /home/root/.ssh/authorized_keys.tmp /home/root/.ssh/authorized_keys + fi + echo "Set root authorized_keys from user preferences, total" $(cat /home/root/.ssh/authorized_keys | wc -l) "keys" + fi + fi +else + echo "Warning: Cannot create /home/root/.ssh directory (read-only file system?)" + echo "Skipping SSH key setup" +fi + +if [[ -S /var/run/dstack.sock ]]; then + export DSTACK_APP_ID=$(curl -s --unix-socket /var/run/dstack.sock http://dstack/Info | jq -j .app_id) +elif [[ -S /var/run/tappd.sock ]]; then + export DSTACK_APP_ID=$(curl -s --unix-socket /var/run/tappd.sock http://dstack/prpc/Tappd.Info | jq -j .app_id) +fi +# Check if DSTACK_GATEWAY_DOMAIN is not set, try to get it from user_config or app-compose.json +# Priority: user_config > app-compose.json +if [[ -z "$DSTACK_GATEWAY_DOMAIN" ]]; then + # First try to get from /dstack/user_config if it exists and is valid JSON + if [[ -f /dstack/user_config ]] && jq empty /dstack/user_config 2>/dev/null; then + if [[ $(jq 'has("default_gateway_domain")' /dstack/user_config 2>/dev/null) == "true" ]]; then + export DSTACK_GATEWAY_DOMAIN=$(jq -j '.default_gateway_domain' /dstack/user_config) + fi + fi + + # If still not set, try to get from app-compose.json + if [[ -z "$DSTACK_GATEWAY_DOMAIN" ]] && [[ $(jq 'has("default_gateway_domain")' app-compose.json) == "true" ]]; then + export DSTACK_GATEWAY_DOMAIN=$(jq -j '.default_gateway_domain' app-compose.json) + fi +fi +if [[ -n "$DSTACK_GATEWAY_DOMAIN" ]]; then + export DSTACK_APP_DOMAIN=$DSTACK_APP_ID"."$DSTACK_GATEWAY_DOMAIN +fi + +echo "----------------------------------------------" +echo "Script execution completed" +echo "----------------------------------------------" diff --git a/pkg/aggregator-interface/Cargo.toml b/pkg/aggregator-interface/Cargo.toml index 37c6cc9..84cc7cf 100644 --- a/pkg/aggregator-interface/Cargo.toml +++ b/pkg/aggregator-interface/Cargo.toml @@ -14,4 +14,3 @@ zk-primitives = { workspace = true } async-trait = { workspace = true } thiserror = { workspace = true } unimock = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/aggregator/Cargo.toml b/pkg/aggregator/Cargo.toml index e35e3d7..655cab2 100644 --- a/pkg/aggregator/Cargo.toml +++ b/pkg/aggregator/Cargo.toml @@ -24,7 +24,6 @@ futures = { workspace = true } async-trait = { workspace = true } tracing = { workspace = true } thiserror = { workspace = true } -workspace-hack.workspace = true web3 = { workspace = true } unimock = { workspace = true } diff --git a/pkg/barretenberg-api-bin/Cargo.toml b/pkg/barretenberg-api-bin/Cargo.toml index 234f025..e3b0eab 100644 --- a/pkg/barretenberg-api-bin/Cargo.toml +++ b/pkg/barretenberg-api-bin/Cargo.toml @@ -12,4 +12,3 @@ clap = { workspace = true } rpc = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-api-client/Cargo.toml b/pkg/barretenberg-api-client/Cargo.toml index 1293e57..4d40c9a 100644 --- a/pkg/barretenberg-api-client/Cargo.toml +++ b/pkg/barretenberg-api-client/Cargo.toml @@ -9,7 +9,7 @@ barretenberg-api-interface = { workspace = true } barretenberg-interface = { workspace = true } contextful = { workspace = true } thiserror = { workspace = true } -rustls = { workspace = true } +rustls = { workspace = true, features = ["ring"] } tokio-rustls = { workspace = true } webpki-roots = { workspace = true } httparse = { workspace = true } @@ -18,4 +18,3 @@ serde_json = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } url = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-api-interface/Cargo.toml b/pkg/barretenberg-api-interface/Cargo.toml index 7199715..06048d2 100644 --- a/pkg/barretenberg-api-interface/Cargo.toml +++ b/pkg/barretenberg-api-interface/Cargo.toml @@ -9,4 +9,3 @@ barretenberg-interface = { workspace = true } thiserror = { workspace = true } primitives = { workspace = true } serde = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-api-server/Cargo.toml b/pkg/barretenberg-api-server/Cargo.toml index 703c4dd..d022376 100644 --- a/pkg/barretenberg-api-server/Cargo.toml +++ b/pkg/barretenberg-api-server/Cargo.toml @@ -12,4 +12,3 @@ serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-api-tests/Cargo.toml b/pkg/barretenberg-api-tests/Cargo.toml index 320c1f8..01e6bb1 100644 --- a/pkg/barretenberg-api-tests/Cargo.toml +++ b/pkg/barretenberg-api-tests/Cargo.toml @@ -18,4 +18,3 @@ tokio = { workspace = true } tower = { workspace = true, features = ["util"] } unimock = { workspace = true } url = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-cli/Cargo.toml b/pkg/barretenberg-cli/Cargo.toml index 57cbdd9..a6f7588 100644 --- a/pkg/barretenberg-cli/Cargo.toml +++ b/pkg/barretenberg-cli/Cargo.toml @@ -10,4 +10,3 @@ tempfile = { workspace = true } tracing = { workspace = true } async-trait = { workspace = true } tokio = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-interface/Cargo.toml b/pkg/barretenberg-interface/Cargo.toml index 9567313..c741738 100644 --- a/pkg/barretenberg-interface/Cargo.toml +++ b/pkg/barretenberg-interface/Cargo.toml @@ -7,4 +7,3 @@ edition = "2024" thiserror = { workspace = true } unimock = { workspace = true } async-trait = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/barretenberg-rs/Cargo.toml b/pkg/barretenberg-rs/Cargo.toml index c651764..b731499 100644 --- a/pkg/barretenberg-rs/Cargo.toml +++ b/pkg/barretenberg-rs/Cargo.toml @@ -10,7 +10,6 @@ lazy_static = { workspace = true } async-trait = { workspace = true } contextful = { workspace = true } tokio = { workspace = true } -workspace-hack.workspace = true [features] default = [] diff --git a/pkg/beam-cli/Cargo.toml b/pkg/beam-cli/Cargo.toml index 29bacbc..6f974e4 100644 --- a/pkg/beam-cli/Cargo.toml +++ b/pkg/beam-cli/Cargo.toml @@ -46,7 +46,6 @@ tokio = { workspace = true } url = { workspace = true } wasmi = { workspace = true } web3 = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] insta = { workspace = true } diff --git a/pkg/beam-cli/src/apps/host.rs b/pkg/beam-cli/src/apps/host.rs index 38eee14..f342d8e 100644 --- a/pkg/beam-cli/src/apps/host.rs +++ b/pkg/beam-cli/src/apps/host.rs @@ -33,6 +33,8 @@ pub struct HostMetadata { pub app_version: String, pub chain: String, pub chain_id: u64, + #[serde(default)] + pub debug: bool, pub host_api_version: u32, pub manifest_sha256: String, pub now: u64, diff --git a/pkg/beam-cli/src/apps/runtime.rs b/pkg/beam-cli/src/apps/runtime.rs index 8a175e6..6e8ff04 100644 --- a/pkg/beam-cli/src/apps/runtime.rs +++ b/pkg/beam-cli/src/apps/runtime.rs @@ -2,29 +2,30 @@ use std::path::Path; use contextful::ResultContextExt; -use serde::{Deserialize, Serialize}; -use serde_json::Value; use wasmi::{Config, Engine, Linker, Module, Store}; use crate::{ apps::{ Error, Result, host::HostMetadata, - model::{ActionPlan, AppManifest, InstalledApp}, + model::{AppManifest, InstalledApp}, store::now, }, - output::{CommandOutput, OutputMode}, runtime::BeamApp, }; +mod command; +mod debug; mod guest; -use guest::{HostState, guest_alloc, register_host_imports, typed_func, unpack_ptr_len}; +pub use command::GuestCommandResult; +use command::{CommandRun, run_guest_command}; +use debug::{app_debug, app_debug_enabled}; +use guest::{HostState, register_host_imports, typed_func}; const WASM_MAGIC: &[u8; 4] = b"\0asm"; -const HOST_API_VERSION: u32 = 1; -const MAX_GUEST_RESPONSE_BYTES: usize = 2 * 1024 * 1024; -const WASM_FUEL: u64 = 30_000_000; +pub(super) const HOST_API_VERSION: u32 = 1; +pub(super) const WASM_FUEL: u64 = 30_000_000; pub fn validate_wasm_module(app_id: &str, entrypoint: &str, path: &Path) -> Result<()> { let bytes = std::fs::read(path).context("read beam app wasm module")?; @@ -99,81 +100,25 @@ impl AppRuntime { module_path: &Path, args: &[String], ) -> Result { - let bytes = std::fs::read(module_path).context("read beam app wasm module")?; - let module = Module::new(&self.engine, &bytes).context("compile beam app wasm module")?; + app_debug(&format!( + "run command start app={} version={} args={}", + manifest.id, + manifest.version, + args.len() + )); let metadata = self.metadata(app, manifest, installed).await?; - let invocation = GuestInvocation { + run_guest_command(CommandRun { + app: app.clone(), args: args.to_vec(), - host_api_version: HOST_API_VERSION, - metadata: metadata.clone(), - output_mode: output_mode_label(app.output_mode).to_string(), - }; - let mut store = Store::new( - &self.engine, - HostState::new(app.clone(), manifest.permissions.clone(), metadata), - ); - store - .set_fuel(WASM_FUEL) - .context("set beam app wasm fuel")?; - store.limiter(|state| &mut state.limits); - let mut linker = >::new(&self.engine); - register_host_imports(&mut linker)?; - let instance = linker - .instantiate_and_start(&mut store, &module) - .context("instantiate beam app wasm module")?; - - let memory = - instance - .get_memory(&store, "memory") - .ok_or_else(|| Error::MissingWasmExport { - app: manifest.id.clone(), - export: "memory".to_string(), - })?; - let alloc = typed_func::(&store, &instance, "beam_alloc", &manifest.id)?; - let free = typed_func::<(i32, i32), ()>(&store, &instance, "beam_free", &manifest.id)?; - let main = typed_func::<(i32, i32), i64>( - &store, - &instance, - &manifest.wasm.entrypoint, - &manifest.id, - )?; - let input = serde_json::to_vec(&invocation).context("serialize beam app invocation")?; - let input_ptr = guest_alloc(&mut store, &alloc, input.len())?; - memory - .write(&mut store, input_ptr, &input) - .context("write beam app invocation")?; - let packed = main - .call(&mut store, (input_ptr as i32, input.len() as i32)) - .context("call beam app command")?; - free.call(&mut store, (input_ptr as i32, input.len() as i32)) - .context("free beam app invocation")?; - let (output_ptr, output_len) = unpack_ptr_len(packed)?; - if output_len > MAX_GUEST_RESPONSE_BYTES { - return Err(Error::InvalidGuestOutput { - reason: format!("guest response too large: {output_len} bytes"), - }); - } - let mut output = vec![0_u8; output_len]; - memory - .read(&store, output_ptr, &mut output) - .context("read beam app command output")?; - free.call(&mut store, (output_ptr as i32, output_len as i32)) - .context("free beam app command output")?; - - let response = - serde_json::from_slice::(&output).context("decode beam app output")?; - match response { - GuestResponse::ActionPlan { plan } => Ok(GuestCommandResult::ActionPlan(*plan)), - GuestResponse::Output { value } => { - let text = value - .get("message") - .and_then(Value::as_str) - .unwrap_or("App command completed") - .to_string(); - Ok(GuestCommandResult::Output(CommandOutput::new(text, value))) - } - GuestResponse::Error { message } => Err(Error::GuestCommandFailed { message }), - } + engine: self.engine.clone(), + entrypoint: manifest.wasm.entrypoint.clone(), + manifest_id: manifest.id.clone(), + metadata, + module_path: module_path.to_path_buf(), + output_mode: app.output_mode, + permissions: manifest.permissions.clone(), + runtime_handle: tokio::runtime::Handle::current(), + }) } async fn metadata( @@ -192,6 +137,7 @@ impl AppRuntime { app_version: manifest.version.clone(), chain: chain.entry.key, chain_id: chain.entry.chain_id, + debug: app_debug_enabled(), host_api_version: HOST_API_VERSION, manifest_sha256: installed.manifest_sha256.clone(), now: now(), @@ -200,36 +146,3 @@ impl AppRuntime { }) } } - -#[derive(Debug)] -pub enum GuestCommandResult { - ActionPlan(ActionPlan), - Output(CommandOutput), -} - -#[derive(Serialize)] -struct GuestInvocation { - args: Vec, - host_api_version: u32, - metadata: HostMetadata, - output_mode: String, -} - -#[derive(Deserialize)] -#[serde(tag = "kind", rename_all = "kebab-case")] -enum GuestResponse { - ActionPlan { plan: Box }, - Output { value: Value }, - Error { message: String }, -} - -fn output_mode_label(mode: OutputMode) -> &'static str { - match mode { - OutputMode::Default => "default", - OutputMode::Json => "json", - OutputMode::Yaml => "yaml", - OutputMode::Markdown => "markdown", - OutputMode::Compact => "compact", - OutputMode::Quiet => "quiet", - } -} diff --git a/pkg/beam-cli/src/apps/runtime/command.rs b/pkg/beam-cli/src/apps/runtime/command.rs new file mode 100644 index 0000000..ed3f465 --- /dev/null +++ b/pkg/beam-cli/src/apps/runtime/command.rs @@ -0,0 +1,184 @@ +use std::{path::PathBuf, thread}; + +use contextful::ResultContextExt; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tokio::runtime::Handle; +use wasmi::{Engine, Linker, Module, Store}; + +use crate::{ + apps::{ + Error, Result, + host::HostMetadata, + model::{ActionPlan, AppPermissions}, + }, + output::{CommandOutput, OutputMode}, + runtime::BeamApp, +}; + +use super::{ + HOST_API_VERSION, WASM_FUEL, + debug::app_debug, + guest::{HostState, guest_alloc, register_host_imports, typed_func, unpack_ptr_len}, +}; + +const MAX_GUEST_RESPONSE_BYTES: usize = 2 * 1024 * 1024; +// wasmi uses native stack while interpreting long guest calls; run app execution +// off the main thread with enough headroom for JSON-heavy app flows. +const WASM_THREAD_STACK_BYTES: usize = 512 * 1024 * 1024; + +pub(super) struct CommandRun { + pub(super) app: BeamApp, + pub(super) args: Vec, + pub(super) engine: Engine, + pub(super) entrypoint: String, + pub(super) manifest_id: String, + pub(super) metadata: HostMetadata, + pub(super) module_path: PathBuf, + pub(super) output_mode: OutputMode, + pub(super) permissions: AppPermissions, + pub(super) runtime_handle: Handle, +} + +#[derive(Debug)] +pub enum GuestCommandResult { + ActionPlan(ActionPlan), + Output(CommandOutput), +} + +pub(super) fn run_guest_command(input: CommandRun) -> Result { + let thread_name = format!("beam-app-wasm-{}", input.manifest_id); + let thread = thread::Builder::new() + .name(thread_name) + .stack_size(WASM_THREAD_STACK_BYTES) + .spawn(|| run_guest_command_on_thread(input)) + .context("spawn beam app wasm thread")?; + + thread.join().map_err(|_| Error::InvalidGuestOutput { + reason: "beam app wasm thread panicked".to_string(), + })? +} + +fn run_guest_command_on_thread(input: CommandRun) -> Result { + let bytes = std::fs::read(&input.module_path).context("read beam app wasm module")?; + app_debug(&format!("wasm module read bytes={}", bytes.len())); + let module = Module::new(&input.engine, &bytes).context("compile beam app wasm module")?; + app_debug("wasm module compiled"); + let invocation = GuestInvocation { + args: input.args, + host_api_version: HOST_API_VERSION, + metadata: input.metadata.clone(), + output_mode: output_mode_label(input.output_mode).to_string(), + }; + let mut store = Store::new( + &input.engine, + HostState::new( + input.app, + input.permissions, + input.metadata, + input.runtime_handle, + ), + ); + store + .set_fuel(WASM_FUEL) + .context("set beam app wasm fuel")?; + store.limiter(|state| &mut state.limits); + let mut linker = >::new(&input.engine); + register_host_imports(&mut linker)?; + let instance = linker + .instantiate_and_start(&mut store, &module) + .context("instantiate beam app wasm module")?; + app_debug("wasm module instantiated"); + + let memory = instance + .get_memory(&store, "memory") + .ok_or_else(|| Error::MissingWasmExport { + app: input.manifest_id.clone(), + export: "memory".to_string(), + })?; + let alloc = typed_func::(&store, &instance, "beam_alloc", &input.manifest_id)?; + let free = typed_func::<(i32, i32), ()>(&store, &instance, "beam_free", &input.manifest_id)?; + let main = + typed_func::<(i32, i32), i64>(&store, &instance, &input.entrypoint, &input.manifest_id)?; + let input_json = serde_json::to_vec(&invocation).context("serialize beam app invocation")?; + app_debug(&format!( + "guest invocation serialized bytes={}", + input_json.len() + )); + let input_ptr = guest_alloc(&mut store, &alloc, input_json.len())?; + memory + .write(&mut store, input_ptr, &input_json) + .context("write beam app invocation")?; + app_debug("calling guest entrypoint"); + let packed = main + .call(&mut store, (input_ptr as i32, input_json.len() as i32)) + .context("call beam app command")?; + app_debug("guest entrypoint returned"); + free.call(&mut store, (input_ptr as i32, input_json.len() as i32)) + .context("free beam app invocation")?; + read_guest_response(&mut store, &memory, &free, packed) +} + +fn read_guest_response( + store: &mut Store, + memory: &wasmi::Memory, + free: &wasmi::TypedFunc<(i32, i32), ()>, + packed: i64, +) -> Result { + let (output_ptr, output_len) = unpack_ptr_len(packed)?; + app_debug(&format!("guest output ptr={output_ptr} bytes={output_len}")); + if output_len > MAX_GUEST_RESPONSE_BYTES { + return Err(Error::InvalidGuestOutput { + reason: format!("guest response too large: {output_len} bytes"), + }); + } + let mut output = vec![0_u8; output_len]; + memory + .read(&*store, output_ptr, &mut output) + .context("read beam app command output")?; + free.call(store, (output_ptr as i32, output_len as i32)) + .context("free beam app command output")?; + + let response = + serde_json::from_slice::(&output).context("decode beam app output")?; + app_debug("guest output decoded"); + match response { + GuestResponse::ActionPlan { plan } => Ok(GuestCommandResult::ActionPlan(*plan)), + GuestResponse::Output { value } => { + let text = value + .get("message") + .and_then(Value::as_str) + .unwrap_or("App command completed") + .to_string(); + Ok(GuestCommandResult::Output(CommandOutput::new(text, value))) + } + GuestResponse::Error { message } => Err(Error::GuestCommandFailed { message }), + } +} + +#[derive(Serialize)] +struct GuestInvocation { + args: Vec, + host_api_version: u32, + metadata: HostMetadata, + output_mode: String, +} + +#[derive(Deserialize)] +#[serde(tag = "kind", rename_all = "kebab-case")] +enum GuestResponse { + ActionPlan { plan: Box }, + Output { value: Value }, + Error { message: String }, +} + +fn output_mode_label(mode: OutputMode) -> &'static str { + match mode { + OutputMode::Default => "default", + OutputMode::Json => "json", + OutputMode::Yaml => "yaml", + OutputMode::Markdown => "markdown", + OutputMode::Compact => "compact", + OutputMode::Quiet => "quiet", + } +} diff --git a/pkg/beam-cli/src/apps/runtime/debug.rs b/pkg/beam-cli/src/apps/runtime/debug.rs new file mode 100644 index 0000000..1595a49 --- /dev/null +++ b/pkg/beam-cli/src/apps/runtime/debug.rs @@ -0,0 +1,95 @@ +use std::env; + +use serde_json::Value; + +use crate::apps::host::HostRequest; + +pub(super) fn app_debug_enabled() -> bool { + env::var("BEAM_APP_DEBUG") + .map(|value| { + let value = value.to_ascii_lowercase(); + matches!(value.as_str(), "1" | "true" | "yes" | "on") + }) + .unwrap_or(false) +} + +pub(super) fn app_debug(message: &str) { + if app_debug_enabled() { + eprintln!("[beam-cli/apps/debug] {message}"); + } +} + +pub(super) fn host_request_summary(request: &HostRequest) -> String { + match request { + HostRequest::AppMetadata => "app-metadata".to_string(), + HostRequest::Args { args } => format!("args count={}", args.len()), + HostRequest::StructuredOutput { value } => { + format!("structured-output {}", value_shape(value)) + } + HostRequest::Diagnostic { level, message } => { + format!("diagnostic level={level} message={message}") + } + HostRequest::HttpFetch(request) => format!( + "http-fetch method={} url={} request_bytes={}", + request.method, + request.url, + request.body.len() + ), + HostRequest::ChainRead(request) => format!( + "chain-read operation={:?} chain={} target={} selector={}", + request.operation, + request.chain, + optional_value(&request.target), + optional_value(&request.selector) + ), + HostRequest::SimulateTransaction(transaction) => format!( + "simulate-transaction chain={} target={} selector={} spender={}", + transaction.chain, + transaction.target, + optional_value(&transaction.selector), + optional_value(&transaction.spender) + ), + HostRequest::SubmitTransaction(transaction) => format!( + "submit-transaction chain={} target={} selector={}", + transaction.chain, + transaction.target, + optional_value(&transaction.selector) + ), + HostRequest::PollReceipt { tx_hash } => format!("poll-receipt tx_hash={tx_hash}"), + HostRequest::ResolveAddress { value } => { + format!("resolve-address provided={}", value.is_some()) + } + HostRequest::AppStorageGet { key } => format!("storage-get key={key}"), + HostRequest::AppStorageSet { key, value } => { + format!("storage-set key={key} {}", value_shape(value)) + } + HostRequest::AppStorageRemove { key } => format!("storage-remove key={key}"), + } +} + +pub(super) fn host_value_summary(value: &Value) -> String { + if let Some(status) = value.get("status").and_then(Value::as_u64) { + let body_bytes = value + .get("body") + .and_then(Value::as_array) + .map(Vec::len) + .unwrap_or_default(); + return format!("status={status} response_bytes={body_bytes}"); + } + value_shape(value) +} + +fn value_shape(value: &Value) -> String { + match value { + Value::Array(values) => format!("array_len={}", values.len()), + Value::Object(values) => format!("object_keys={}", values.len()), + Value::String(value) => format!("string_len={}", value.len()), + Value::Number(_) => "number".to_string(), + Value::Bool(_) => "bool".to_string(), + Value::Null => "null".to_string(), + } +} + +fn optional_value(value: &Option) -> &str { + value.as_deref().unwrap_or("") +} diff --git a/pkg/beam-cli/src/apps/runtime/guest.rs b/pkg/beam-cli/src/apps/runtime/guest.rs index 4cf1394..24e8ed1 100644 --- a/pkg/beam-cli/src/apps/runtime/guest.rs +++ b/pkg/beam-cli/src/apps/runtime/guest.rs @@ -16,6 +16,8 @@ use crate::{ runtime::BeamApp, }; +use super::debug::{app_debug, app_debug_enabled, host_request_summary, host_value_summary}; + const MAX_WASM_MEMORY_BYTES: usize = 64 * 1024 * 1024; pub(super) struct HostState { @@ -24,11 +26,17 @@ pub(super) struct HostState { pub(super) limits: StoreLimits, metadata: Option, permissions: Option, + runtime_handle: Option, structured_output: Option, } impl HostState { - pub(super) fn new(app: BeamApp, permissions: AppPermissions, metadata: HostMetadata) -> Self { + pub(super) fn new( + app: BeamApp, + permissions: AppPermissions, + metadata: HostMetadata, + runtime_handle: Handle, + ) -> Self { Self { app: Some(app), diagnostics: Vec::new(), @@ -37,6 +45,7 @@ impl HostState { .build(), metadata: Some(metadata), permissions: Some(permissions), + runtime_handle: Some(runtime_handle), structured_output: None, } } @@ -50,6 +59,7 @@ impl HostState { .build(), metadata: None, permissions: None, + runtime_handle: None, structured_output: None, } } @@ -148,6 +158,10 @@ fn host_call( .context("read beam app host request")?; let request = serde_json::from_slice::(&request_bytes) .context("decode beam app host request")?; + let request_summary = app_debug_enabled().then(|| host_request_summary(&request)); + if let Some(summary) = &request_summary { + app_debug(&format!("host call start {summary}")); + } let app = caller .data() .app @@ -172,18 +186,33 @@ fn host_call( })?; let mut structured_output = caller.data().structured_output.clone(); let mut diagnostics = caller.data().diagnostics.clone(); - let result = tokio::task::block_in_place(|| { - Handle::current().block_on(handle_host_request( - &app, - &permissions, - &metadata, - request, - &mut structured_output, - &mut diagnostics, - )) - }); + let runtime_handle = + caller + .data() + .runtime_handle + .clone() + .ok_or_else(|| Error::InvalidHostRequest { + reason: "host runtime handle missing".to_string(), + })?; + let result = runtime_handle.block_on(handle_host_request( + &app, + &permissions, + &metadata, + request, + &mut structured_output, + &mut diagnostics, + )); caller.data_mut().structured_output = structured_output; caller.data_mut().diagnostics = diagnostics; + if let Some(summary) = &request_summary { + match &result { + Ok(value) => app_debug(&format!( + "host call ok {summary}; {}", + host_value_summary(value) + )), + Err(error) => app_debug(&format!("host call error {summary}; {error}")), + } + } let response = match result { Ok(value) => HostCallResponse::ok(value), Err(error) => HostCallResponse::error(format_error_chain(&error)), diff --git a/pkg/block-store/Cargo.toml b/pkg/block-store/Cargo.toml index 867c98b..feb914b 100644 --- a/pkg/block-store/Cargo.toml +++ b/pkg/block-store/Cargo.toml @@ -15,7 +15,6 @@ borsh = { workspace = true } rocksdb = { workspace = true } thiserror = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] tempdir = { workspace = true } diff --git a/pkg/bungee-interface/Cargo.toml b/pkg/bungee-interface/Cargo.toml index ce9b91e..445f2a2 100644 --- a/pkg/bungee-interface/Cargo.toml +++ b/pkg/bungee-interface/Cargo.toml @@ -16,7 +16,6 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } unimock = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] insta = { workspace = true } diff --git a/pkg/burn-substitutor/Cargo.toml b/pkg/burn-substitutor/Cargo.toml index 02c1612..8a9e065 100644 --- a/pkg/burn-substitutor/Cargo.toml +++ b/pkg/burn-substitutor/Cargo.toml @@ -20,4 +20,3 @@ serde = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } -workspace-hack = { workspace = true } diff --git a/pkg/client-http-longpoll/Cargo.toml b/pkg/client-http-longpoll/Cargo.toml index 77d53d0..0174aa1 100644 --- a/pkg/client-http-longpoll/Cargo.toml +++ b/pkg/client-http-longpoll/Cargo.toml @@ -12,4 +12,3 @@ async-stream = { workspace = true } tokio = { workspace = true } chrono = { workspace = true } futures = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/client-http/Cargo.toml b/pkg/client-http/Cargo.toml index 9d9b1bf..ed88dbd 100644 --- a/pkg/client-http/Cargo.toml +++ b/pkg/client-http/Cargo.toml @@ -13,4 +13,3 @@ serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/constants/Cargo.toml b/pkg/constants/Cargo.toml index 97216b3..ed8dd56 100644 --- a/pkg/constants/Cargo.toml +++ b/pkg/constants/Cargo.toml @@ -4,4 +4,3 @@ version = "0.1.0" edition = "2024" [dependencies] -workspace-hack.workspace = true diff --git a/pkg/contextful-macros/Cargo.toml b/pkg/contextful-macros/Cargo.toml index e9b595e..bcfb8db 100644 --- a/pkg/contextful-macros/Cargo.toml +++ b/pkg/contextful-macros/Cargo.toml @@ -12,4 +12,3 @@ proc-macro = true [dependencies] quote = { workspace = true } syn = { workspace = true, features = ["full"] } -workspace-hack.workspace = true diff --git a/pkg/contextful/Cargo.toml b/pkg/contextful/Cargo.toml index ec0c526..725f0bd 100644 --- a/pkg/contextful/Cargo.toml +++ b/pkg/contextful/Cargo.toml @@ -9,7 +9,6 @@ repository = "https://github.com/polybase/zk-rollup" [dependencies] serde = { workspace = true } contextful-macros = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/contracts/Cargo.toml b/pkg/contracts/Cargo.toml index 1768773..3f12c37 100644 --- a/pkg/contracts/Cargo.toml +++ b/pkg/contracts/Cargo.toml @@ -22,7 +22,6 @@ thiserror = { workspace = true } tokio = { workspace = true } web3 = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] zk-circuits = { workspace = true } diff --git a/pkg/country/Cargo.toml b/pkg/country/Cargo.toml index 2038ea9..549ec50 100644 --- a/pkg/country/Cargo.toml +++ b/pkg/country/Cargo.toml @@ -10,7 +10,6 @@ diesel = ["dep:diesel"] serde = { workspace = true } strum_macros = { workspace = true } strum = { workspace = true } -workspace-hack.workspace = true diesel = { workspace = true, optional = true } diff --git a/pkg/currency/Cargo.toml b/pkg/currency/Cargo.toml index fc1c5af..a58f79d 100644 --- a/pkg/currency/Cargo.toml +++ b/pkg/currency/Cargo.toml @@ -17,7 +17,6 @@ strum_macros = { workspace = true } strum = { workspace = true } thiserror = { workspace = true } ts-rs = { workspace = true, optional = true } -workspace-hack.workspace = true [package.metadata.cargo-machete] ignored = ["strum"] diff --git a/pkg/data/Cargo.toml b/pkg/data/Cargo.toml index 7a491f4..2963782 100644 --- a/pkg/data/Cargo.toml +++ b/pkg/data/Cargo.toml @@ -36,6 +36,5 @@ serde_json = { workspace = true } strum = { workspace = true } ts-rs = { workspace = true, optional = true } uuid = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] diff --git a/pkg/database/Cargo.toml b/pkg/database/Cargo.toml index ace3eb1..9d6a460 100644 --- a/pkg/database/Cargo.toml +++ b/pkg/database/Cargo.toml @@ -9,7 +9,6 @@ diesel = ["dep:diesel"] [dependencies] diesel = { workspace = true, optional = true, features = ["postgres"] } -workspace-hack.workspace = true [dev-dependencies] contextful = { workspace = true } diff --git a/pkg/diesel-util/Cargo.toml b/pkg/diesel-util/Cargo.toml index e7aac15..6964586 100644 --- a/pkg/diesel-util/Cargo.toml +++ b/pkg/diesel-util/Cargo.toml @@ -8,4 +8,3 @@ diesel = ["dep:diesel"] [dependencies] diesel = { workspace = true, optional = true } -workspace-hack.workspace = true diff --git a/pkg/doomslug/Cargo.toml b/pkg/doomslug/Cargo.toml index 75d4173..6544485 100644 --- a/pkg/doomslug/Cargo.toml +++ b/pkg/doomslug/Cargo.toml @@ -14,4 +14,3 @@ borsh = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } sha3 = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/eip7702/Cargo.toml b/pkg/eip7702/Cargo.toml index 277a2b6..7393fee 100644 --- a/pkg/eip7702/Cargo.toml +++ b/pkg/eip7702/Cargo.toml @@ -20,7 +20,6 @@ hex = { workspace = true } test-spy = { workspace = true } tracing = { workspace = true } client-http = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] testutil = { workspace = true } diff --git a/pkg/element/Cargo.toml b/pkg/element/Cargo.toml index f45e0a7..5518218 100644 --- a/pkg/element/Cargo.toml +++ b/pkg/element/Cargo.toml @@ -14,7 +14,6 @@ rand = { workspace = true, optional = true } serde = { workspace = true, optional = true, features = ["derive"] } borsh = { workspace = true, optional = true } ts-rs = { workspace = true, optional = true } -workspace-hack.workspace = true [dev-dependencies] test-strategy = { workspace = true } diff --git a/pkg/encrypt/Cargo.toml b/pkg/encrypt/Cargo.toml index ccc1878..29b114b 100644 --- a/pkg/encrypt/Cargo.toml +++ b/pkg/encrypt/Cargo.toml @@ -8,4 +8,3 @@ edition = "2024" thiserror = { workspace = true } crypto_secretbox = { workspace = true } x25519-dalek = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/eth-util/Cargo.toml b/pkg/eth-util/Cargo.toml index db35c46..ef33cb0 100644 --- a/pkg/eth-util/Cargo.toml +++ b/pkg/eth-util/Cargo.toml @@ -8,4 +8,3 @@ element = { workspace = true } sha3 = { workspace = true } secp256k1 = { workspace = true } ethereum-types = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/guild-client-http/Cargo.toml b/pkg/guild-client-http/Cargo.toml index 3e9cc09..9d4b62b 100644 --- a/pkg/guild-client-http/Cargo.toml +++ b/pkg/guild-client-http/Cargo.toml @@ -24,7 +24,6 @@ reqwest = { workspace = true } parking_lot = { workspace = true } thiserror = { workspace = true } uuid = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["rt", "macros"] } diff --git a/pkg/guild-interface/Cargo.toml b/pkg/guild-interface/Cargo.toml index 011bb0b..54f4327 100644 --- a/pkg/guild-interface/Cargo.toml +++ b/pkg/guild-interface/Cargo.toml @@ -25,7 +25,6 @@ serde_json = { workspace = true } thiserror = { workspace = true } uuid = { workspace = true } kyc = { workspace = true } -workspace-hack.workspace = true [features] ts-rs = [ diff --git a/pkg/hash-poseidon/Cargo.toml b/pkg/hash-poseidon/Cargo.toml index 5e37a79..d5fea4f 100644 --- a/pkg/hash-poseidon/Cargo.toml +++ b/pkg/hash-poseidon/Cargo.toml @@ -8,7 +8,6 @@ element = { workspace = true } minimal-poseidon = { workspace = true } serde = { workspace = true } hex = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] insta = { workspace = true } diff --git a/pkg/hash/Cargo.toml b/pkg/hash/Cargo.toml index f6c241e..8f6d2ac 100644 --- a/pkg/hash/Cargo.toml +++ b/pkg/hash/Cargo.toml @@ -10,7 +10,6 @@ rand = { workspace = true, optional = true } serde = { workspace = true } hex = { workspace = true } bn254_blackbox_solver = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] insta = { workspace = true } diff --git a/pkg/http-interface/Cargo.toml b/pkg/http-interface/Cargo.toml index d61bfba..1e4cc93 100644 --- a/pkg/http-interface/Cargo.toml +++ b/pkg/http-interface/Cargo.toml @@ -12,4 +12,3 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } unimock = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/json-store/Cargo.toml b/pkg/json-store/Cargo.toml index df12a8d..3c61e12 100644 --- a/pkg/json-store/Cargo.toml +++ b/pkg/json-store/Cargo.toml @@ -9,7 +9,6 @@ serde_json = { workspace = true } tokio = { workspace = true } thiserror = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["test-util"] } diff --git a/pkg/json-with-logging/Cargo.toml b/pkg/json-with-logging/Cargo.toml index 0dc7cf3..7663763 100644 --- a/pkg/json-with-logging/Cargo.toml +++ b/pkg/json-with-logging/Cargo.toml @@ -8,4 +8,3 @@ actix-web = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/kyc/Cargo.toml b/pkg/kyc/Cargo.toml index eb3c950..a93a2c0 100644 --- a/pkg/kyc/Cargo.toml +++ b/pkg/kyc/Cargo.toml @@ -21,7 +21,6 @@ base64 = { workspace = true } diesel = { workspace = true, optional = true } ts-rs = { workspace = true, optional = true } -workspace-hack.workspace = true [dev-dependencies] tokio = { workspace = true } diff --git a/pkg/minimal-poseidon/Cargo.toml b/pkg/minimal-poseidon/Cargo.toml index 2a3edbf..6626f51 100644 --- a/pkg/minimal-poseidon/Cargo.toml +++ b/pkg/minimal-poseidon/Cargo.toml @@ -7,4 +7,3 @@ edition = "2024" halo2curves = { workspace = true, features = ["derive_serde"] } ff = { workspace = true } lazy_static = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/network/Cargo.toml b/pkg/network/Cargo.toml index 82b53fe..4d30784 100644 --- a/pkg/network/Cargo.toml +++ b/pkg/network/Cargo.toml @@ -16,7 +16,6 @@ strum = { workspace = true } thiserror = { workspace = true } uuid = { workspace = true, features = ["serde"] } veil = { workspace = true } -workspace-hack.workspace = true [dependencies.ts-rs] workspace = true diff --git a/pkg/node-client-http/Cargo.toml b/pkg/node-client-http/Cargo.toml index 5174c99..6b0229f 100644 --- a/pkg/node-client-http/Cargo.toml +++ b/pkg/node-client-http/Cargo.toml @@ -14,7 +14,6 @@ zk-primitives = { workspace = true } async-trait = { workspace = true } serde = { workspace = true } reqwest = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/pkg/node-interface/Cargo.toml b/pkg/node-interface/Cargo.toml index 64dbf70..c61aa7d 100644 --- a/pkg/node-interface/Cargo.toml +++ b/pkg/node-interface/Cargo.toml @@ -15,7 +15,6 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } unimock = { workspace = true } -workspace-hack.workspace = true [dependencies.ts-rs] workspace = true diff --git a/pkg/node/Cargo.toml b/pkg/node/Cargo.toml index d097d4b..6044bc6 100644 --- a/pkg/node/Cargo.toml +++ b/pkg/node/Cargo.toml @@ -64,7 +64,6 @@ tokio-postgres = { workspace = true } postgres-native-tls = { workspace = true } native-tls = { workspace = true } scopeguard = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] dotenvy = { workspace = true } diff --git a/pkg/noir-abi-inputs-macro/Cargo.toml b/pkg/noir-abi-inputs-macro/Cargo.toml index a8df1a1..2fd21c3 100644 --- a/pkg/noir-abi-inputs-macro/Cargo.toml +++ b/pkg/noir-abi-inputs-macro/Cargo.toml @@ -16,4 +16,3 @@ quote = { workspace = true } syn = { workspace = true, features = ["full"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/notes-interface/Cargo.toml b/pkg/notes-interface/Cargo.toml index 143f16a..60f5df7 100644 --- a/pkg/notes-interface/Cargo.toml +++ b/pkg/notes-interface/Cargo.toml @@ -29,7 +29,6 @@ thiserror = { workspace = true } unimock = { workspace = true } uuid = { workspace = true } zk-primitives = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/p2p2/Cargo.toml b/pkg/p2p2/Cargo.toml index 00c2b34..69a8fe6 100644 --- a/pkg/p2p2/Cargo.toml +++ b/pkg/p2p2/Cargo.toml @@ -20,4 +20,3 @@ borsh = { workspace = true } wire-message = { workspace = true } strum = { workspace = true } whitelist-ips = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/parse-link/Cargo.toml b/pkg/parse-link/Cargo.toml index 47e9834..d7f1c8c 100644 --- a/pkg/parse-link/Cargo.toml +++ b/pkg/parse-link/Cargo.toml @@ -14,7 +14,6 @@ thiserror = { workspace = true } web3 = { workspace = true } ts-rs = { workspace = true, optional = true } hash = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/payy-evm-client-alloy/Cargo.toml b/pkg/payy-evm-client-alloy/Cargo.toml index e70dccf..e9f4299 100644 --- a/pkg/payy-evm-client-alloy/Cargo.toml +++ b/pkg/payy-evm-client-alloy/Cargo.toml @@ -9,4 +9,3 @@ async-trait = { workspace = true } contextful = { workspace = true } payy-evm-client-interface = { workspace = true } tokio = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/payy-evm-client-interface/Cargo.toml b/pkg/payy-evm-client-interface/Cargo.toml index 28949b8..cabf2a1 100644 --- a/pkg/payy-evm-client-interface/Cargo.toml +++ b/pkg/payy-evm-client-interface/Cargo.toml @@ -14,7 +14,6 @@ num-traits = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } zk-primitives = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/payy-evm-client-prover-bb/Cargo.toml b/pkg/payy-evm-client-prover-bb/Cargo.toml index e682943..772345f 100644 --- a/pkg/payy-evm-client-prover-bb/Cargo.toml +++ b/pkg/payy-evm-client-prover-bb/Cargo.toml @@ -10,7 +10,6 @@ contextful = { workspace = true } element = { workspace = true } payy-evm-client-prover-interface = { workspace = true } zk-circuits = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] tokio = { workspace = true } diff --git a/pkg/payy-evm-client-prover-interface/Cargo.toml b/pkg/payy-evm-client-prover-interface/Cargo.toml index 530e606..c8e69a6 100644 --- a/pkg/payy-evm-client-prover-interface/Cargo.toml +++ b/pkg/payy-evm-client-prover-interface/Cargo.toml @@ -9,4 +9,3 @@ contextful = { workspace = true } payy-evm-client-interface = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/payy-evm-client/Cargo.toml b/pkg/payy-evm-client/Cargo.toml index 53138be..f8ff52c 100644 --- a/pkg/payy-evm-client/Cargo.toml +++ b/pkg/payy-evm-client/Cargo.toml @@ -32,7 +32,6 @@ thiserror = { workspace = true } tokio = { workspace = true } zk-circuits = { workspace = true } zk-primitives = { workspace = true } -workspace-hack.workspace = true [features] default = ["bb-cli"] diff --git a/pkg/payy-evm-parse-link/Cargo.toml b/pkg/payy-evm-parse-link/Cargo.toml index 5608b46..5f85e3f 100644 --- a/pkg/payy-evm-parse-link/Cargo.toml +++ b/pkg/payy-evm-parse-link/Cargo.toml @@ -9,4 +9,3 @@ element = { workspace = true } payy-evm-client-interface = { workspace = true } sha3 = { workspace = true } zk-primitives = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/payy-note/Cargo.toml b/pkg/payy-note/Cargo.toml index 9f187e6..15cdd12 100644 --- a/pkg/payy-note/Cargo.toml +++ b/pkg/payy-note/Cargo.toml @@ -8,7 +8,6 @@ element = { workspace = true } serde = { workspace = true } unimock = { workspace = true } zk-primitives = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/price-cache-interface/Cargo.toml b/pkg/price-cache-interface/Cargo.toml index 1b36909..6551600 100644 --- a/pkg/price-cache-interface/Cargo.toml +++ b/pkg/price-cache-interface/Cargo.toml @@ -12,4 +12,3 @@ currency = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } unimock = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/primitives/Cargo.toml b/pkg/primitives/Cargo.toml index b2c5e31..d68b3d5 100644 --- a/pkg/primitives/Cargo.toml +++ b/pkg/primitives/Cargo.toml @@ -25,12 +25,14 @@ web3 = { workspace = true } futures = { workspace = true } thiserror = { workspace = true } diesel = { workspace = true, optional = true } -workspace-hack.workspace = true [dependencies.ts-rs] workspace = true optional = true +[dev-dependencies] +tokio = { workspace = true, features = ["macros", "rt", "test-util", "time"] } + [features] ts-rs = ["dep:ts-rs"] diesel = ["dep:diesel"] diff --git a/pkg/prover/Cargo.toml b/pkg/prover/Cargo.toml index f832d68..96314e9 100644 --- a/pkg/prover/Cargo.toml +++ b/pkg/prover/Cargo.toml @@ -22,7 +22,6 @@ borsh = { workspace = true } # TODO: why are we using this instead of hex lib? rustc-hex = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] expect-test = { workspace = true } diff --git a/pkg/ramps-interface/Cargo.toml b/pkg/ramps-interface/Cargo.toml index 1c154a9..da6adea 100644 --- a/pkg/ramps-interface/Cargo.toml +++ b/pkg/ramps-interface/Cargo.toml @@ -51,4 +51,3 @@ zk-primitives = { workspace = true } diesel = { workspace = true, optional = true } diesel-util = { workspace = true, optional = true } ts-rs = { workspace = true, optional = true } -workspace-hack.workspace = true diff --git a/pkg/rpc-error-convert/Cargo.toml b/pkg/rpc-error-convert/Cargo.toml index 234b65a..7545116 100644 --- a/pkg/rpc-error-convert/Cargo.toml +++ b/pkg/rpc-error-convert/Cargo.toml @@ -11,4 +11,3 @@ serde_json = { workspace = true } syn = { workspace = true, features = ["full"] } quote = { workspace = true } proc-macro2 = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/rpc/Cargo.toml b/pkg/rpc/Cargo.toml index 9e3f368..03353e6 100644 --- a/pkg/rpc/Cargo.toml +++ b/pkg/rpc/Cargo.toml @@ -25,7 +25,6 @@ strum_macros = { workspace = true } strum = { workspace = true } rpc-error-convert = { workspace = true } contextful = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] thiserror = { workspace = true } diff --git a/pkg/serde_yaml/Cargo.toml b/pkg/serde_yaml/Cargo.toml index 2f0b0c2..3cccf95 100644 --- a/pkg/serde_yaml/Cargo.toml +++ b/pkg/serde_yaml/Cargo.toml @@ -10,4 +10,3 @@ path = "lib.rs" [dependencies] serde_yaml_ng = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/smirk/Cargo.toml b/pkg/smirk/Cargo.toml index ab9b44a..367f86a 100644 --- a/pkg/smirk/Cargo.toml +++ b/pkg/smirk/Cargo.toml @@ -20,7 +20,6 @@ strum = { workspace = true } rayon = { workspace = true } dashmap = { workspace = true } tracing = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] serde_json = { workspace = true } diff --git a/pkg/solc-tooling/Cargo.toml b/pkg/solc-tooling/Cargo.toml index 7c1458c..08300af 100644 --- a/pkg/solc-tooling/Cargo.toml +++ b/pkg/solc-tooling/Cargo.toml @@ -10,4 +10,3 @@ hex = { workspace = true } home = { workspace = true } sha2 = { workspace = true } reqwest = { workspace = true, features = ["blocking"] } -workspace-hack.workspace = true diff --git a/pkg/solid/Cargo.toml b/pkg/solid/Cargo.toml index d45f0dc..5abe1e6 100644 --- a/pkg/solid/Cargo.toml +++ b/pkg/solid/Cargo.toml @@ -19,7 +19,6 @@ tokio = { workspace = true } tokio-stream = { workspace = true } uint = { workspace = true } borsh = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] proptest = { workspace = true } diff --git a/pkg/sourcify-client-reqwest/Cargo.toml b/pkg/sourcify-client-reqwest/Cargo.toml index ae16a93..16cec2d 100644 --- a/pkg/sourcify-client-reqwest/Cargo.toml +++ b/pkg/sourcify-client-reqwest/Cargo.toml @@ -12,7 +12,6 @@ serde_json = { workspace = true } sourcify-interface = { workspace = true } thiserror = { workspace = true } url = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] httpmock = { workspace = true } diff --git a/pkg/sourcify-interface/Cargo.toml b/pkg/sourcify-interface/Cargo.toml index 28fda9a..1847b98 100644 --- a/pkg/sourcify-interface/Cargo.toml +++ b/pkg/sourcify-interface/Cargo.toml @@ -9,4 +9,3 @@ contextful = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/test-spy-macros/Cargo.toml b/pkg/test-spy-macros/Cargo.toml index 528b157..2c020e2 100644 --- a/pkg/test-spy-macros/Cargo.toml +++ b/pkg/test-spy-macros/Cargo.toml @@ -10,4 +10,3 @@ proc-macro = true quote = { workspace = true } proc-macro2 = { workspace = true } syn = { workspace = true, features = ["full", "extra-traits"] } -workspace-hack.workspace = true diff --git a/pkg/test-spy/Cargo.toml b/pkg/test-spy/Cargo.toml index 7118b29..4cb949c 100644 --- a/pkg/test-spy/Cargo.toml +++ b/pkg/test-spy/Cargo.toml @@ -9,7 +9,6 @@ edition = "2024" test-spy-macros = { workspace = true } parking_lot = { workspace = true } serde = { workspace = true, features = ["derive"] } -workspace-hack.workspace = true [dev-dependencies] async-trait = { workspace = true } diff --git a/pkg/testutil/Cargo.toml b/pkg/testutil/Cargo.toml index 63082cc..362a8c4 100644 --- a/pkg/testutil/Cargo.toml +++ b/pkg/testutil/Cargo.toml @@ -7,4 +7,3 @@ edition = "2024" once_cell = { workspace = true } reqwest = { workspace = true } tokio = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/wallet-data-dep/Cargo.toml b/pkg/wallet-data-dep/Cargo.toml index 17f4a91..829a548 100644 --- a/pkg/wallet-data-dep/Cargo.toml +++ b/pkg/wallet-data-dep/Cargo.toml @@ -15,7 +15,6 @@ chrono = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } uuid = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] insta = { workspace = true, features = ["yaml", "redactions"] } diff --git a/pkg/wallet-primitives/Cargo.toml b/pkg/wallet-primitives/Cargo.toml index 40f2243..5d7a263 100644 --- a/pkg/wallet-primitives/Cargo.toml +++ b/pkg/wallet-primitives/Cargo.toml @@ -12,4 +12,3 @@ serde = { workspace = true } serde_json = { workspace = true } sha3 = { workspace = true } thiserror = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/wallet/Cargo.toml b/pkg/wallet/Cargo.toml index 2dc2429..b91b244 100644 --- a/pkg/wallet/Cargo.toml +++ b/pkg/wallet/Cargo.toml @@ -17,4 +17,3 @@ serde_json = { workspace = true } tokio = { workspace = true } web3 = { workspace = true } clap = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/whitelist-ips/Cargo.toml b/pkg/whitelist-ips/Cargo.toml index d933719..23e0302 100644 --- a/pkg/whitelist-ips/Cargo.toml +++ b/pkg/whitelist-ips/Cargo.toml @@ -8,4 +8,3 @@ edition = "2024" [dependencies] libp2p.workspace = true tracing.workspace = true -workspace-hack.workspace = true diff --git a/pkg/wire-message-macro/Cargo.toml b/pkg/wire-message-macro/Cargo.toml index 8331974..8c3c8fd 100644 --- a/pkg/wire-message-macro/Cargo.toml +++ b/pkg/wire-message-macro/Cargo.toml @@ -10,4 +10,3 @@ proc-macro = true quote = { workspace = true } proc-macro2 = { workspace = true } syn = { workspace = true, features = ["full"] } -workspace-hack.workspace = true diff --git a/pkg/wire-message/Cargo.toml b/pkg/wire-message/Cargo.toml index 85e60bc..c386a41 100644 --- a/pkg/wire-message/Cargo.toml +++ b/pkg/wire-message/Cargo.toml @@ -11,7 +11,6 @@ wire-message-macro = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true } static_assertions = { workspace = true } -workspace-hack.workspace = true [features] test-api = [] diff --git a/pkg/workspace-hack/Cargo.toml b/pkg/workspace-hack/Cargo.toml deleted file mode 100644 index 08a07b3..0000000 --- a/pkg/workspace-hack/Cargo.toml +++ /dev/null @@ -1,538 +0,0 @@ -[package] -name = "workspace-hack" -version = "0.1.0" -edition = "2024" -description = "Workspace hack crate maintained by cargo-hakari" -publish = false - -[features] -default = [] - -### BEGIN HAKARI SECTION -[dependencies] -actix-router = { version = "0.5", default-features = false, features = ["http", "unicode"] } -aead = { version = "0.5", features = ["alloc", "getrandom"] } -ahash = { version = "0.8", default-features = false, features = ["runtime-rng"] } -aho-corasick = { version = "1" } -allocator-api2 = { version = "0.2" } -alloy-chains = { version = "0.2", default-features = false, features = ["rlp", "serde", "std"] } -alloy-consensus = { version = "1", features = ["k256", "kzg", "serde", "serde-bincode-compat"] } -alloy-dyn-abi = { version = "1", features = ["eip712"] } -alloy-eip7702 = { version = "0.6", default-features = false, features = ["k256", "serde", "serde-bincode-compat", "std"] } -alloy-eips = { version = "1", features = ["k256", "kzg", "serde", "serde-bincode-compat", "ssz"] } -alloy-json-abi = { version = "1", features = ["serde_json"] } -alloy-primitives = { version = "1", features = ["k256", "map-indexmap", "rand", "rlp", "serde"] } -alloy-provider = { version = "1", default-features = false, features = ["debug-api", "ipc", "reqwest", "ws"] } -alloy-rlp = { version = "0.3", features = ["arrayvec", "core-error", "core-net", "derive"] } -alloy-rpc-client = { version = "1", default-features = false, features = ["ipc", "reqwest", "ws"] } -alloy-rpc-types = { version = "1", default-features = false, features = ["engine", "eth"] } -alloy-rpc-types-engine = { version = "1", features = ["kzg", "ssz"] } -alloy-rpc-types-eth = { version = "1", features = ["serde-bincode-compat"] } -alloy-signer-local = { version = "1", default-features = false, features = ["mnemonic"] } -alloy-sol-type-parser = { version = "1", default-features = false, features = ["eip712", "serde", "std"] } -alloy-sol-types = { version = "1", features = ["eip712-serde", "json"] } -alloy-transport-http = { version = "1", default-features = false, features = ["reqwest", "reqwest-rustls-tls"] } -ark-bn254 = { version = "0.5", default-features = false, features = ["curve", "std"] } -ark-ec = { version = "0.5", default-features = false, features = ["std"] } -ark-ff = { version = "0.5", default-features = false, features = ["asm", "std"] } -ark-serialize = { version = "0.5", default-features = false, features = ["derive", "std"] } -ark-std = { version = "0.5", default-features = false, features = ["std"] } -arrayvec = { version = "0.7", features = ["serde"] } -async-compression = { version = "0.4", default-features = false, features = ["brotli", "gzip", "tokio", "zlib", "zstd"] } -axum = { version = "0.7", features = ["macros"] } -base64 = { version = "0.13", features = ["alloc"] } -bitflags = { version = "2", default-features = false, features = ["serde", "std"] } -bitvec = { version = "1", features = ["serde"] } -blst = { version = "0.3", features = ["portable"] } -bs58 = { version = "0.5", features = ["check"] } -bumpalo = { version = "3", features = ["allocator-api2", "collections"] } -byteorder = { version = "1", features = ["i128"] } -bytes = { version = "1", features = ["serde"] } -c-kzg = { version = "2", features = ["serde"] } -chrono = { version = "0.4", features = ["serde"] } -cipher = { version = "0.4", default-features = false, features = ["block-padding", "zeroize"] } -clap = { version = "4", features = ["derive", "env", "string"] } -clap_builder = { version = "4", default-features = false, features = ["color", "env", "help", "std", "string", "suggestions", "usage"] } -compression-codecs = { version = "0.4", default-features = false, features = ["brotli", "gzip", "zlib", "zstd"] } -concurrent-queue = { version = "2" } -const-hex = { version = "1", features = ["core-error", "hex", "serde"] } -crossbeam-epoch = { version = "0.9" } -crossbeam-utils = { version = "0.8" } -crunchy = { version = "0.2", features = ["limit_256", "std"] } -crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } -curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "digest", "precomputed-tables", "zeroize"] } -dashmap = { version = "6", default-features = false, features = ["inline"] } -data-encoding = { version = "2" } -der = { version = "0.7", default-features = false, features = ["oid", "pem", "std"] } -derive_more = { version = "2", features = ["full"] } -digest = { version = "0.10", features = ["mac", "oid", "std"] } -ecdsa = { version = "0.16", default-features = false, features = ["pem", "serde", "signing", "std", "verifying"] } -ed25519 = { version = "2", default-features = false, features = ["alloc", "pkcs8", "std"] } -ed25519-dalek = { version = "2", features = ["pkcs8", "rand_core"] } -either = { version = "1", features = ["serde", "use_std"] } -elliptic-curve = { version = "0.13", default-features = false, features = ["ecdh", "hazmat", "pem", "serde", "std"] } -ethbloom = { version = "0.13", default-features = false, features = ["codec", "rlp", "serialize", "std"] } -ethereum-types = { version = "0.14", features = ["codec"] } -ff = { version = "0.13" } -figment = { version = "0.10", default-features = false, features = ["env", "test", "toml"] } -foldhash = { version = "0.1" } -form_urlencoded = { version = "1" } -futures = { version = "0.3", features = ["bilock", "thread-pool", "unstable"] } -futures-channel = { version = "0.3", features = ["sink", "unstable"] } -futures-core = { version = "0.3", features = ["unstable"] } -futures-executor = { version = "0.3", features = ["thread-pool"] } -futures-io = { version = "0.3", features = ["unstable"] } -futures-sink = { version = "0.3" } -futures-task = { version = "0.3", default-features = false, features = ["std", "unstable"] } -futures-timer = { version = "3", default-features = false, features = ["wasm-bindgen"] } -futures-util = { version = "0.3", features = ["bilock", "channel", "io", "sink", "unstable"] } -generic-array = { version = "0.14", default-features = false, features = ["more_lengths", "zeroize"] } -getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["std"] } -group = { version = "0.13" } -hashbrown-3575ec1268b04181 = { package = "hashbrown", version = "0.15" } -hashbrown-582f2526e08bb6a0 = { package = "hashbrown", version = "0.14", features = ["raw"] } -hashbrown-594e8ee84c453af0 = { package = "hashbrown", version = "0.13", features = ["raw"] } -hashbrown-986da7b5efc2b80e = { package = "hashbrown", version = "0.16", features = ["serde"] } -hex = { version = "0.4", features = ["serde"] } -hmac = { version = "0.12", default-features = false, features = ["reset"] } -httparse = { version = "1" } -hyper = { version = "1", features = ["client", "http1", "http2", "server"] } -hyper-util = { version = "0.1", features = ["client-legacy", "server-auto", "service"] } -idna = { version = "1", default-features = false, features = ["compiled_data", "std"] } -indexmap = { version = "2", features = ["serde"] } -inout = { version = "0.1", default-features = false, features = ["block-padding"] } -insta = { version = "1", features = ["json", "redactions", "yaml"] } -itertools-582f2526e08bb6a0 = { package = "itertools", version = "0.14" } -itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13" } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } -k256 = { version = "0.13", features = ["serde"] } -keccak = { version = "0.1", default-features = false, features = ["asm"] } -lalrpop-util = { version = "0.20" } -lazy_static = { version = "1", default-features = false, features = ["spin_no_std"] } -libc = { version = "0.2" } -libm = { version = "0.2" } -libz-sys = { version = "1", default-features = false, features = ["libc", "static"] } -lock_api = { version = "0.4", features = ["arc_lock", "serde"] } -log = { version = "0.4", default-features = false, features = ["std"] } -memchr = { version = "2" } -mio = { version = "1", features = ["net", "os-ext"] } -native-tls = { version = "0.2", default-features = false, features = ["alpn"] } -nom = { version = "7" } -num-bigint = { version = "0.4", features = ["serde"] } -num-integer = { version = "0.1", features = ["i128"] } -num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] } -num-traits = { version = "0.2", features = ["i128", "libm"] } -num_enum = { version = "0.7" } -nybbles = { version = "0.4", default-features = false, features = ["rlp", "serde", "std"] } -once_cell = { version = "1", features = ["critical-section"] } -p256 = { version = "0.13", features = ["ecdh"] } -parity-scale-codec = { version = "3", features = ["bytes", "derive", "max-encoded-len"] } -parking_lot = { version = "0.12", features = ["arc_lock", "send_guard", "serde"] } -percent-encoding = { version = "2" } -phf_shared = { version = "0.11" } -portable-atomic = { version = "1" } -postgres-types = { version = "0.2", default-features = false, features = ["with-uuid-1"] } -ppv-lite86 = { version = "0.2", default-features = false, features = ["simd", "std"] } -primitive-types = { version = "0.12", default-features = false, features = ["byteorder", "rlp", "rustc-hex", "scale-info", "serde_no_std", "std"] } -proc-macro2 = { version = "1", features = ["span-locations"] } -prost = { version = "0.13", features = ["prost-derive"] } -rand-274715c4dabd11b0 = { package = "rand", version = "0.9", features = ["serde"] } -rand-c38e5c1d305a1b54 = { package = "rand", version = "0.8", features = ["serde", "small_rng"] } -rand_chacha-274715c4dabd11b0 = { package = "rand_chacha", version = "0.9" } -rand_chacha-468e82937335b1c9 = { package = "rand_chacha", version = "0.3" } -rand_core-274715c4dabd11b0 = { package = "rand_core", version = "0.9", default-features = false, features = ["os_rng", "serde", "std"] } -rand_core-3b31131e45eafb45 = { package = "rand_core", version = "0.6", default-features = false, features = ["std"] } -regex = { version = "1" } -regex-automata = { version = "0.4", default-features = false, features = ["dfa-build", "dfa-onepass", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } -regex-syntax = { version = "0.8" } -reqwest-5ef9efb8ec2df382 = { package = "reqwest", version = "0.12", features = ["blocking", "json", "multipart", "rustls-tls", "rustls-tls-native-roots", "stream"] } -reqwest-a6292c17cd707f01 = { package = "reqwest", version = "0.11", default-features = false, features = ["default-tls", "gzip", "json"] } -ring = { version = "0.17", features = ["std"] } -rlp = { version = "0.5", features = ["derive"] } -ruint = { version = "1", default-features = false, features = ["alloy-rlp", "rand-09", "serde", "std"] } -rustc-hash = { version = "2", features = ["rand"] } -rustc-hex = { version = "2" } -rustls = { version = "0.23", features = ["ring"] } -rustls-webpki = { version = "0.103", default-features = false, features = ["aws-lc-rs", "ring", "std"] } -scopeguard = { version = "1" } -sec1 = { version = "0.7", features = ["pem", "serde", "std", "subtle"] } -semver = { version = "1", features = ["serde"] } -serde = { version = "1", features = ["alloc", "derive", "rc"] } -serde_core = { version = "1", features = ["alloc", "rc"] } -serde_json = { version = "1", features = ["alloc", "float_roundtrip", "raw_value", "unbounded_depth"] } -serde_spanned = { version = "1", default-features = false, features = ["serde", "std"] } -serde_with = { version = "3", features = ["base64"] } -sha1 = { version = "0.10", features = ["oid"] } -sha2 = { version = "0.10", features = ["compress", "oid"] } -sha3 = { version = "0.10", features = ["asm"] } -signature = { version = "2", default-features = false, features = ["digest", "rand_core", "std"] } -similar = { version = "2", features = ["inline"] } -smallvec = { version = "1", default-features = false, features = ["const_new", "serde", "union"] } -socket2-3b31131e45eafb45 = { package = "socket2", version = "0.6", default-features = false, features = ["all"] } -socket2-d8f496e17d97b5cb = { package = "socket2", version = "0.5", default-features = false, features = ["all"] } -spin = { version = "0.9", default-features = false, features = ["once", "rwlock", "spin_mutex", "std"] } -spki = { version = "0.7", default-features = false, features = ["pem", "std"] } -strum = { version = "0.27", features = ["derive"] } -subtle = { version = "2" } -sync_wrapper = { version = "1", default-features = false, features = ["futures"] } -thiserror = { version = "2" } -time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } -tiny-keccak = { version = "2", features = ["keccak", "sha3"] } -tokio = { version = "1", features = ["full", "test-util"] } -tokio-postgres = { version = "0.7", features = ["with-uuid-1"] } -tokio-rustls = { version = "0.26", features = ["ring"] } -tokio-stream = { version = "0.1", features = ["sync"] } -tokio-util = { version = "0.7", features = ["codec", "compat", "io", "time"] } -toml = { version = "0.9" } -tower = { version = "0.5", default-features = false, features = ["full", "log"] } -tracing = { version = "0.1", features = ["log", "valuable"] } -tracing-core = { version = "0.1", features = ["valuable"] } -tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } -triomphe = { version = "0.1", features = ["arc-swap"] } -unicode-bidi = { version = "0.3" } -unicode-normalization = { version = "0.1" } -url = { version = "2", features = ["serde"] } -uuid = { version = "1", features = ["serde", "v4"] } -winnow = { version = "0.7" } -x25519-dalek = { version = "2", features = ["static_secrets"] } -zeroize = { version = "1", features = ["zeroize_derive"] } -zstd = { version = "0.13", features = ["experimental"] } -zstd-safe = { version = "7", default-features = false, features = ["arrays", "experimental", "legacy", "std", "zdict_builder"] } -zstd-sys = { version = "2", features = ["experimental", "std"] } - -[build-dependencies] -actix-router = { version = "0.5", default-features = false, features = ["http", "unicode"] } -aead = { version = "0.5", features = ["alloc", "getrandom"] } -ahash = { version = "0.8", default-features = false, features = ["runtime-rng"] } -aho-corasick = { version = "1" } -allocator-api2 = { version = "0.2" } -alloy-chains = { version = "0.2", default-features = false, features = ["rlp", "serde", "std"] } -alloy-consensus = { version = "1", features = ["k256", "kzg", "serde", "serde-bincode-compat"] } -alloy-dyn-abi = { version = "1", features = ["eip712"] } -alloy-eip7702 = { version = "0.6", default-features = false, features = ["k256", "serde", "serde-bincode-compat", "std"] } -alloy-eips = { version = "1", features = ["k256", "kzg", "serde", "serde-bincode-compat", "ssz"] } -alloy-json-abi = { version = "1", features = ["serde_json"] } -alloy-primitives = { version = "1", features = ["k256", "map-indexmap", "rand", "rlp", "serde"] } -alloy-provider = { version = "1", default-features = false, features = ["debug-api", "ipc", "reqwest", "ws"] } -alloy-rlp = { version = "0.3", features = ["arrayvec", "core-error", "core-net", "derive"] } -alloy-rpc-client = { version = "1", default-features = false, features = ["ipc", "reqwest", "ws"] } -alloy-rpc-types = { version = "1", default-features = false, features = ["engine", "eth"] } -alloy-rpc-types-engine = { version = "1", features = ["kzg", "ssz"] } -alloy-rpc-types-eth = { version = "1", features = ["serde-bincode-compat"] } -alloy-signer-local = { version = "1", default-features = false, features = ["mnemonic"] } -alloy-sol-macro = { version = "1", default-features = false, features = ["json"] } -alloy-sol-macro-expander = { version = "1", default-features = false, features = ["json"] } -alloy-sol-macro-input = { version = "1", default-features = false, features = ["json"] } -alloy-sol-type-parser = { version = "1", default-features = false, features = ["eip712", "serde", "std"] } -alloy-sol-types = { version = "1", features = ["eip712-serde", "json"] } -alloy-transport-http = { version = "1", default-features = false, features = ["reqwest", "reqwest-rustls-tls"] } -ark-bn254 = { version = "0.5", default-features = false, features = ["curve", "std"] } -ark-ec = { version = "0.5", default-features = false, features = ["std"] } -ark-ff = { version = "0.5", default-features = false, features = ["asm", "std"] } -ark-serialize = { version = "0.5", default-features = false, features = ["derive", "std"] } -ark-std = { version = "0.5", default-features = false, features = ["std"] } -arrayvec = { version = "0.7", features = ["serde"] } -async-compression = { version = "0.4", default-features = false, features = ["brotli", "gzip", "tokio", "zlib", "zstd"] } -axum = { version = "0.7", features = ["macros"] } -base64 = { version = "0.13", features = ["alloc"] } -bindgen = { version = "0.71" } -bitflags = { version = "2", default-features = false, features = ["serde", "std"] } -bitvec = { version = "1", features = ["serde"] } -blst = { version = "0.3", features = ["portable"] } -bs58 = { version = "0.5", features = ["check"] } -bumpalo = { version = "3", features = ["allocator-api2", "collections"] } -byteorder = { version = "1", features = ["i128"] } -bytes = { version = "1", features = ["serde"] } -c-kzg = { version = "2", features = ["serde"] } -cc = { version = "1", default-features = false, features = ["parallel"] } -chrono = { version = "0.4", features = ["serde"] } -cipher = { version = "0.4", default-features = false, features = ["block-padding", "zeroize"] } -clang-sys = { version = "1", default-features = false, features = ["clang_11_0", "runtime"] } -clap = { version = "4", features = ["derive", "env", "string"] } -clap_builder = { version = "4", default-features = false, features = ["color", "env", "help", "std", "string", "suggestions", "usage"] } -compression-codecs = { version = "0.4", default-features = false, features = ["brotli", "gzip", "zlib", "zstd"] } -concurrent-queue = { version = "2" } -const-hex = { version = "1", features = ["core-error", "hex", "serde"] } -crossbeam-epoch = { version = "0.9" } -crossbeam-utils = { version = "0.8" } -crunchy = { version = "0.2", features = ["limit_256", "std"] } -crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } -curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "digest", "precomputed-tables", "zeroize"] } -darling = { version = "0.21", features = ["serde"] } -darling_core = { version = "0.21", default-features = false, features = ["serde", "suggestions"] } -dashmap = { version = "6", default-features = false, features = ["inline"] } -data-encoding = { version = "2" } -der = { version = "0.7", default-features = false, features = ["oid", "pem", "std"] } -derive_more = { version = "2", features = ["full"] } -derive_more-impl = { version = "2", features = ["add", "add_assign", "as_ref", "constructor", "debug", "deref", "deref_mut", "display", "eq", "error", "from", "from_str", "index", "index_mut", "into", "into_iterator", "is_variant", "mul", "mul_assign", "not", "sum", "try_from", "try_into", "try_unwrap", "unwrap"] } -digest = { version = "0.10", features = ["mac", "oid", "std"] } -ecdsa = { version = "0.16", default-features = false, features = ["pem", "serde", "signing", "std", "verifying"] } -ed25519 = { version = "2", default-features = false, features = ["alloc", "pkcs8", "std"] } -ed25519-dalek = { version = "2", features = ["pkcs8", "rand_core"] } -either = { version = "1", features = ["serde", "use_std"] } -elliptic-curve = { version = "0.13", default-features = false, features = ["ecdh", "hazmat", "pem", "serde", "std"] } -ethbloom = { version = "0.13", default-features = false, features = ["codec", "rlp", "serialize", "std"] } -ethereum-types = { version = "0.14", features = ["codec"] } -ff = { version = "0.13" } -figment = { version = "0.10", default-features = false, features = ["env", "test", "toml"] } -foldhash = { version = "0.1" } -form_urlencoded = { version = "1" } -futures = { version = "0.3", features = ["bilock", "thread-pool", "unstable"] } -futures-channel = { version = "0.3", features = ["sink", "unstable"] } -futures-core = { version = "0.3", features = ["unstable"] } -futures-executor = { version = "0.3", features = ["thread-pool"] } -futures-io = { version = "0.3", features = ["unstable"] } -futures-sink = { version = "0.3" } -futures-task = { version = "0.3", default-features = false, features = ["std", "unstable"] } -futures-timer = { version = "3", default-features = false, features = ["wasm-bindgen"] } -futures-util = { version = "0.3", features = ["bilock", "channel", "io", "sink", "unstable"] } -generic-array = { version = "0.14", default-features = false, features = ["more_lengths", "zeroize"] } -getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["std"] } -group = { version = "0.13" } -hashbrown-3575ec1268b04181 = { package = "hashbrown", version = "0.15" } -hashbrown-582f2526e08bb6a0 = { package = "hashbrown", version = "0.14", features = ["raw"] } -hashbrown-594e8ee84c453af0 = { package = "hashbrown", version = "0.13", features = ["raw"] } -hashbrown-986da7b5efc2b80e = { package = "hashbrown", version = "0.16", features = ["serde"] } -hex = { version = "0.4", features = ["serde"] } -hmac = { version = "0.12", default-features = false, features = ["reset"] } -httparse = { version = "1" } -hyper = { version = "1", features = ["client", "http1", "http2", "server"] } -hyper-util = { version = "0.1", features = ["client-legacy", "server-auto", "service"] } -idna = { version = "1", default-features = false, features = ["compiled_data", "std"] } -indexmap = { version = "2", features = ["serde"] } -inout = { version = "0.1", default-features = false, features = ["block-padding"] } -insta = { version = "1", features = ["json", "redactions", "yaml"] } -itertools-582f2526e08bb6a0 = { package = "itertools", version = "0.14" } -itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13" } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } -k256 = { version = "0.13", features = ["serde"] } -keccak = { version = "0.1", default-features = false, features = ["asm"] } -lalrpop-util = { version = "0.20" } -lazy_static = { version = "1", default-features = false, features = ["spin_no_std"] } -libc = { version = "0.2" } -libm = { version = "0.2" } -libz-sys = { version = "1", default-features = false, features = ["libc", "static"] } -lock_api = { version = "0.4", features = ["arc_lock", "serde"] } -log = { version = "0.4", default-features = false, features = ["std"] } -memchr = { version = "2" } -mio = { version = "1", features = ["net", "os-ext"] } -native-tls = { version = "0.2", default-features = false, features = ["alpn"] } -nom = { version = "7" } -num-bigint = { version = "0.4", features = ["serde"] } -num-integer = { version = "0.1", features = ["i128"] } -num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] } -num-traits = { version = "0.2", features = ["i128", "libm"] } -num_enum = { version = "0.7" } -num_enum_derive = { version = "0.7", default-features = false, features = ["std"] } -nybbles = { version = "0.4", default-features = false, features = ["rlp", "serde", "std"] } -once_cell = { version = "1", features = ["critical-section"] } -p256 = { version = "0.13", features = ["ecdh"] } -parity-scale-codec = { version = "3", features = ["bytes", "derive", "max-encoded-len"] } -parking_lot = { version = "0.12", features = ["arc_lock", "send_guard", "serde"] } -percent-encoding = { version = "2" } -phf_shared = { version = "0.11" } -portable-atomic = { version = "1" } -postgres-types = { version = "0.2", default-features = false, features = ["with-uuid-1"] } -ppv-lite86 = { version = "0.2", default-features = false, features = ["simd", "std"] } -prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] } -primitive-types = { version = "0.12", default-features = false, features = ["byteorder", "rlp", "rustc-hex", "scale-info", "serde_no_std", "std"] } -proc-macro2 = { version = "1", features = ["span-locations"] } -prost = { version = "0.13", features = ["prost-derive"] } -quote = { version = "1" } -rand-274715c4dabd11b0 = { package = "rand", version = "0.9", features = ["serde"] } -rand-c38e5c1d305a1b54 = { package = "rand", version = "0.8", features = ["serde", "small_rng"] } -rand_chacha-274715c4dabd11b0 = { package = "rand_chacha", version = "0.9" } -rand_chacha-468e82937335b1c9 = { package = "rand_chacha", version = "0.3" } -rand_core-274715c4dabd11b0 = { package = "rand_core", version = "0.9", default-features = false, features = ["os_rng", "serde", "std"] } -rand_core-3b31131e45eafb45 = { package = "rand_core", version = "0.6", default-features = false, features = ["std"] } -regex = { version = "1" } -regex-automata = { version = "0.4", default-features = false, features = ["dfa-build", "dfa-onepass", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } -regex-syntax = { version = "0.8" } -reqwest-5ef9efb8ec2df382 = { package = "reqwest", version = "0.12", features = ["blocking", "json", "multipart", "rustls-tls", "rustls-tls-native-roots", "stream"] } -reqwest-a6292c17cd707f01 = { package = "reqwest", version = "0.11", default-features = false, features = ["default-tls", "gzip", "json"] } -ring = { version = "0.17", features = ["std"] } -rlp = { version = "0.5", features = ["derive"] } -ruint = { version = "1", default-features = false, features = ["alloy-rlp", "rand-09", "serde", "std"] } -rustc-hash = { version = "2", features = ["rand"] } -rustc-hex = { version = "2" } -rustls = { version = "0.23", features = ["ring"] } -rustls-webpki = { version = "0.103", default-features = false, features = ["aws-lc-rs", "ring", "std"] } -scopeguard = { version = "1" } -sec1 = { version = "0.7", features = ["pem", "serde", "std", "subtle"] } -semver = { version = "1", features = ["serde"] } -serde = { version = "1", features = ["alloc", "derive", "rc"] } -serde_core = { version = "1", features = ["alloc", "rc"] } -serde_json = { version = "1", features = ["alloc", "float_roundtrip", "raw_value", "unbounded_depth"] } -serde_spanned = { version = "1", default-features = false, features = ["serde", "std"] } -serde_with = { version = "3", features = ["base64"] } -sha1 = { version = "0.10", features = ["oid"] } -sha2 = { version = "0.10", features = ["compress", "oid"] } -sha3 = { version = "0.10", features = ["asm"] } -signature = { version = "2", default-features = false, features = ["digest", "rand_core", "std"] } -similar = { version = "2", features = ["inline"] } -smallvec = { version = "1", default-features = false, features = ["const_new", "serde", "union"] } -socket2-3b31131e45eafb45 = { package = "socket2", version = "0.6", default-features = false, features = ["all"] } -socket2-d8f496e17d97b5cb = { package = "socket2", version = "0.5", default-features = false, features = ["all"] } -spin = { version = "0.9", default-features = false, features = ["once", "rwlock", "spin_mutex", "std"] } -spki = { version = "0.7", default-features = false, features = ["pem", "std"] } -strum = { version = "0.27", features = ["derive"] } -subtle = { version = "2" } -syn-dff4ba8e3ae991db = { package = "syn", version = "1", features = ["extra-traits", "full", "visit"] } -syn-f595c2ba2a3f28df = { package = "syn", version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } -sync_wrapper = { version = "1", default-features = false, features = ["futures"] } -thiserror = { version = "2" } -time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } -tiny-keccak = { version = "2", features = ["keccak", "sha3"] } -tokio = { version = "1", features = ["full", "test-util"] } -tokio-postgres = { version = "0.7", features = ["with-uuid-1"] } -tokio-rustls = { version = "0.26", features = ["ring"] } -tokio-stream = { version = "0.1", features = ["sync"] } -tokio-util = { version = "0.7", features = ["codec", "compat", "io", "time"] } -toml = { version = "0.9" } -tower = { version = "0.5", default-features = false, features = ["full", "log"] } -tracing = { version = "0.1", features = ["log", "valuable"] } -tracing-core = { version = "0.1", features = ["valuable"] } -tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } -triomphe = { version = "0.1", features = ["arc-swap"] } -unicode-bidi = { version = "0.3" } -unicode-normalization = { version = "0.1" } -url = { version = "2", features = ["serde"] } -uuid = { version = "1", features = ["serde", "v4"] } -winnow = { version = "0.7" } -x25519-dalek = { version = "2", features = ["static_secrets"] } -zeroize = { version = "1", features = ["zeroize_derive"] } -zstd = { version = "0.13", features = ["experimental"] } -zstd-safe = { version = "7", default-features = false, features = ["arrays", "experimental", "legacy", "std", "zdict_builder"] } -zstd-sys = { version = "2", features = ["experimental", "std"] } - -[target.x86_64-unknown-linux-gnu.dependencies] -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "prctl", "system"] } -linux-raw-sys-a6292c17cd707f01 = { package = "linux-raw-sys", version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl", "system"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -openssl = { version = "0.10", features = ["vendored"] } -openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } -rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["param", "process", "system", "thread"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "param", "process", "system", "thread"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.x86_64-unknown-linux-gnu.build-dependencies] -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "prctl", "system"] } -linux-raw-sys-a6292c17cd707f01 = { package = "linux-raw-sys", version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl", "system"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -openssl = { version = "0.10", features = ["vendored"] } -openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } -rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["param", "process", "system", "thread"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "param", "process", "system", "thread"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-darwin.dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-darwin.build-dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-7b89eefb6aaa9bf3 = { package = "security-framework", version = "3", features = ["OSX_10_14"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-ios.dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-ios.build-dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-ios-sim.dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.aarch64-apple-ios-sim.build-dependencies] -errno = { version = "0.3" } -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } -security-framework-f595c2ba2a3f28df = { package = "security-framework", version = "2", features = ["alpn"] } -security-framework-sys = { version = "2", features = ["OSX_10_14"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } - -[target.x86_64-pc-windows-msvc.dependencies] -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } -winapi = { version = "0.3", default-features = false, features = ["cfg", "consoleapi", "errhandlingapi", "evntrace", "fileapi", "handleapi", "in6addr", "inaddr", "knownfolders", "libloaderapi", "memoryapi", "minwinbase", "minwindef", "ntsecapi", "ntstatus", "objbase", "processenv", "processthreadsapi", "profileapi", "psapi", "shlobj", "std", "synchapi", "sysinfoapi", "winbase", "wincon", "windef", "winerror", "winioctl", "winnt", "ws2ipdef", "ws2tcpip"] } -windows-sys-4db8c43aad08e7ae = { package = "windows-sys", version = "0.60", features = ["Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse"] } -windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Memory", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_UI_Input_KeyboardAndMouse"] } -windows-sys-b21d60becc0929df = { package = "windows-sys", version = "0.52", features = ["Win32_Foundation", "Win32_Networking_WinSock", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_Environment", "Win32_System_IO", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Shell"] } -windows-sys-c8eced492e86ede7 = { package = "windows-sys", version = "0.48", features = ["Win32_Foundation", "Win32_Globalization", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Diagnostics_Debug", "Win32_System_Memory", "Win32_System_Registry", "Win32_System_Time", "Win32_UI_Shell"] } -windows-sys-d4189bed749088b6 = { package = "windows-sys", version = "0.61", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Wdk_System_IO", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] } - -[target.x86_64-pc-windows-msvc.build-dependencies] -getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "native-tokio", "ring", "tls12", "webpki-tokio"] } -hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } -tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] } -tower-http = { version = "0.6", features = ["full"] } -winapi = { version = "0.3", default-features = false, features = ["cfg", "consoleapi", "errhandlingapi", "evntrace", "fileapi", "handleapi", "in6addr", "inaddr", "knownfolders", "libloaderapi", "memoryapi", "minwinbase", "minwindef", "ntsecapi", "ntstatus", "objbase", "processenv", "processthreadsapi", "profileapi", "psapi", "shlobj", "std", "synchapi", "sysinfoapi", "winbase", "wincon", "windef", "winerror", "winioctl", "winnt", "ws2ipdef", "ws2tcpip"] } -windows-sys-4db8c43aad08e7ae = { package = "windows-sys", version = "0.60", features = ["Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse"] } -windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Memory", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_UI_Input_KeyboardAndMouse"] } -windows-sys-b21d60becc0929df = { package = "windows-sys", version = "0.52", features = ["Win32_Foundation", "Win32_Networking_WinSock", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_Environment", "Win32_System_IO", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Shell"] } -windows-sys-c8eced492e86ede7 = { package = "windows-sys", version = "0.48", features = ["Win32_Foundation", "Win32_Globalization", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Diagnostics_Debug", "Win32_System_Memory", "Win32_System_Registry", "Win32_System_Time", "Win32_UI_Shell"] } -windows-sys-d4189bed749088b6 = { package = "windows-sys", version = "0.61", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Wdk_System_IO", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] } - -### END HAKARI SECTION diff --git a/pkg/workspace-hack/src/lib.rs b/pkg/workspace-hack/src/lib.rs deleted file mode 100644 index 9ac8670..0000000 --- a/pkg/workspace-hack/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -// Workspace hack crate intentionally empty. diff --git a/pkg/xtask/Cargo.toml b/pkg/xtask/Cargo.toml index d131d28..6ef8d2c 100644 --- a/pkg/xtask/Cargo.toml +++ b/pkg/xtask/Cargo.toml @@ -21,4 +21,3 @@ serde_json = { workspace = true } indoc = { workspace = true } solc-tooling = { workspace = true } toml = { workspace = true } -workspace-hack.workspace = true diff --git a/pkg/xtask/src/test/metadata.rs b/pkg/xtask/src/cargo_metadata.rs similarity index 61% rename from pkg/xtask/src/test/metadata.rs rename to pkg/xtask/src/cargo_metadata.rs index c8c0736..9a05367 100644 --- a/pkg/xtask/src/test/metadata.rs +++ b/pkg/xtask/src/cargo_metadata.rs @@ -11,20 +11,28 @@ use crate::error::{Result, XTaskError}; pub struct Metadata { packages: HashMap, workspace_members: Vec, - workspace_member_set: HashSet, - resolve: HashMap>, } #[derive(Debug)] pub struct Package { pub name: String, manifest_dir_abs: PathBuf, + manifest_path_abs: PathBuf, + workspace_dependency_ids: Vec, } impl Package { pub fn manifest_dir_abs(&self) -> &Path { &self.manifest_dir_abs } + + pub fn manifest_path_abs(&self) -> &Path { + &self.manifest_path_abs + } + + pub fn workspace_dependency_ids(&self) -> &[String] { + &self.workspace_dependency_ids + } } impl Metadata { @@ -41,29 +49,12 @@ impl Metadata { pub fn package_by_name(&self, name: &str) -> Option<&Package> { self.packages.values().find(|package| package.name == name) } - - pub fn workspace_member_ids(&self) -> &[String] { - &self.workspace_members - } - - pub fn is_workspace_member(&self, id: &str) -> bool { - self.workspace_member_set.contains(id) - } - - pub fn dependencies_for(&self, id: &str) -> impl Iterator { - self.resolve - .get(id) - .map(|deps| deps.iter()) - .into_iter() - .flatten() - } } #[derive(Deserialize)] struct RawMetadata { packages: Vec, workspace_members: Vec, - resolve: Option, } #[derive(Deserialize)] @@ -71,22 +62,28 @@ struct RawPackage { id: String, name: String, manifest_path: PathBuf, + #[serde(default)] + dependencies: Vec, } #[derive(Deserialize)] -struct RawResolve { - nodes: Vec, +struct RawDependency { + path: Option, } -#[derive(Deserialize)] -struct RawNode { +struct WorkspaceRawPackage { id: String, - dependencies: Vec, + name: String, + manifest_dir_abs: PathBuf, + manifest_path_abs: PathBuf, + dependencies: Vec, } -pub fn load_metadata(repo_root: &Path) -> Result { - let output = Command::new("cargo") - .args(["metadata", "--format-version", "1"]) +pub fn load_workspace_metadata(repo_root: &Path) -> Result { + let mut command = Command::new("cargo"); + command.args(["metadata", "--format-version", "1", "--no-deps"]); + + let output = command .current_dir(repo_root) .output() .context("spawn cargo metadata command")?; @@ -105,7 +102,7 @@ pub fn load_metadata(repo_root: &Path) -> Result { .cloned() .collect::>(); - let mut packages = HashMap::new(); + let mut raw_workspace_packages = Vec::new(); for raw_package in raw.packages { if !workspace_member_set.contains(&raw_package.id) { continue; @@ -127,32 +124,45 @@ pub fn load_metadata(repo_root: &Path) -> Result { path: manifest_dir_abs.clone(), })?; + raw_workspace_packages.push(WorkspaceRawPackage { + id: raw_package.id, + name: raw_package.name, + manifest_dir_abs, + manifest_path_abs: raw_package.manifest_path, + dependencies: raw_package.dependencies, + }); + } + + let package_id_by_manifest_dir = raw_workspace_packages + .iter() + .map(|package| (package.manifest_dir_abs.clone(), package.id.clone())) + .collect::>(); + + let mut packages = HashMap::new(); + for raw_package in raw_workspace_packages { + let workspace_dependency_ids = raw_package + .dependencies + .iter() + .filter_map(|dependency| dependency.path.as_ref()) + .filter_map(|path| package_id_by_manifest_dir.get(path)) + .cloned() + .collect::>(); + packages.insert( raw_package.id.clone(), Package { name: raw_package.name, - manifest_dir_abs, + manifest_dir_abs: raw_package.manifest_dir_abs, + manifest_path_abs: raw_package.manifest_path_abs, + workspace_dependency_ids, }, ); } - let resolve_nodes = raw - .resolve - .map(|resolve| { - resolve - .nodes - .into_iter() - .map(|node| (node.id, node.dependencies)) - .collect() - }) - .unwrap_or_default(); - let workspace_members = raw.workspace_members; Ok(Metadata { packages, workspace_members, - workspace_member_set, - resolve: resolve_nodes, }) } diff --git a/pkg/xtask/src/git.rs b/pkg/xtask/src/git.rs index 5fc29a5..cfadacc 100644 --- a/pkg/xtask/src/git.rs +++ b/pkg/xtask/src/git.rs @@ -15,7 +15,7 @@ pub fn collect_changed_files(repo_root: &Path) -> Result> { if line.len() < 4 { continue; } - if !include_unstaged_status(line) { + if !include_changed_status(line) { continue; } let path = line[3..].trim(); @@ -106,7 +106,7 @@ fn git_output(repo_root: &Path, args: &[&str]) -> Result { Ok(String::from_utf8(output.stdout).context("parse git stdout as utf-8")?) } -fn include_unstaged_status(line: &str) -> bool { +fn include_changed_status(line: &str) -> bool { if line.len() < 2 { return false; } @@ -121,6 +121,6 @@ fn include_unstaged_status(line: &str) -> bool { match (first, second) { ('?', '?') => true, ('!', '!') => false, - (_, status) => status != ' ', + (index_status, worktree_status) => index_status != ' ' || worktree_status != ' ', } } diff --git a/pkg/xtask/src/lint/file_length.rs b/pkg/xtask/src/lint/file_length.rs new file mode 100644 index 0000000..b371fe1 --- /dev/null +++ b/pkg/xtask/src/lint/file_length.rs @@ -0,0 +1,195 @@ +use std::fs::{self, File}; +use std::io::{BufRead, BufReader}; +use std::path::{Path, PathBuf}; +use std::time::Instant; + +use contextful::ResultContextExt; + +use crate::error::Result; +use crate::lint::steps::StepResult; + +mod report; + +use report::{Violation, render_failure}; + +const DEFAULT_LIMIT: usize = 200; +const MAX_OVERRIDE_SCAN_LINES: usize = 20; +const TARGET_DIR: &str = "pkg"; + +pub fn run(repo_root: &Path) -> Result { + let start = Instant::now(); + let target_dir = repo_root.join(TARGET_DIR); + + if !target_dir.is_dir() { + return Ok(StepResult::failed( + "File length", + format!("pkg directory not found at {}", target_dir.display()), + start.elapsed(), + )); + } + + let files = collect_rust_files(&target_dir)?; + if files.is_empty() { + return Ok(StepResult::success( + "File length", + "No Rust files found under pkg/.".to_owned(), + start.elapsed(), + )); + } + + let mut checked_files = 0usize; + let mut violations = Vec::new(); + + for path in files { + match inspect_file(&path)? { + FileInspection::Generated => {} + FileInspection::Checked { line_count, limit } => { + checked_files += 1; + if line_count > limit { + violations.push(Violation { + path, + line_count, + limit, + }); + } + } + } + } + + if violations.is_empty() { + return Ok(StepResult::success( + "File length", + format!("Checked {checked_files} Rust file(s); all within length limits"), + start.elapsed(), + )); + } + + let summary = format!("{} file(s) exceed configured limits", violations.len()); + + Ok(StepResult::failed("File length", summary, start.elapsed()) + .with_extra_output(render_failure(repo_root, &violations))) +} + +fn collect_rust_files(target_dir: &Path) -> Result> { + let mut files = Vec::new(); + collect_rust_files_in(target_dir, &mut files)?; + files.sort(); + Ok(files) +} + +fn collect_rust_files_in(dir: &Path, files: &mut Vec) -> Result<()> { + let entries = fs::read_dir(dir).with_context(|| format!("list {}", dir.display()))?; + + for entry in entries { + let entry = entry.with_context(|| format!("iterate {}", dir.display()))?; + let path = entry.path(); + let file_type = entry + .file_type() + .with_context(|| format!("read file type for {}", path.display()))?; + + if file_type.is_dir() { + collect_rust_files_in(&path, files)?; + } else if file_type.is_file() && path.extension().and_then(|ext| ext.to_str()) == Some("rs") + { + files.push(path); + } + } + + Ok(()) +} + +enum FileInspection { + Generated, + Checked { line_count: usize, limit: usize }, +} + +fn inspect_file(path: &Path) -> Result { + let file = File::open(path).with_context(|| format!("open {}", path.display()))?; + let mut reader = BufReader::new(file); + let mut buffer = Vec::new(); + let mut logical_line = 0usize; + let mut line_count = 0usize; + let mut limit = DEFAULT_LIMIT; + let mut override_seen = false; + + loop { + buffer.clear(); + let bytes_read = reader + .read_until(b'\n', &mut buffer) + .with_context(|| format!("read {}", path.display()))?; + if bytes_read == 0 { + break; + } + + logical_line += 1; + if buffer.ends_with(b"\n") { + line_count += 1; + } + + if logical_line == 1 && is_generated_line(&buffer) { + return Ok(FileInspection::Generated); + } + + if logical_line <= MAX_OVERRIDE_SCAN_LINES + && !override_seen + && let Some(override_limit) = parse_override_limit(&buffer) + { + limit = override_limit; + override_seen = true; + } + } + + Ok(FileInspection::Checked { line_count, limit }) +} + +fn is_generated_line(line: &[u8]) -> bool { + let line = line_without_ending(line); + let Some(rest) = line.strip_prefix(b"//") else { + return false; + }; + + trim_ascii_start(rest).starts_with(b"@generated") +} + +fn parse_override_limit(line: &[u8]) -> Option { + let mut rest = trim_ascii_start(line_without_ending(line)).strip_prefix(b"//")?; + rest = trim_ascii_start(rest); + rest = rest.strip_prefix(b"lint-long-file-override")?; + rest = strip_required_ascii_whitespace(rest)?; + rest = rest.strip_prefix(b"allow-max-lines")?; + rest = trim_ascii_start(rest).strip_prefix(b"=")?; + rest = trim_ascii_start(rest); + + let digit_count = rest.iter().take_while(|byte| byte.is_ascii_digit()).count(); + if digit_count == 0 { + return None; + } + + std::str::from_utf8(&rest[..digit_count]) + .ok()? + .parse::() + .ok() +} + +fn strip_required_ascii_whitespace(bytes: &[u8]) -> Option<&[u8]> { + bytes + .first() + .filter(|byte| byte.is_ascii_whitespace()) + .map(|_| trim_ascii_start(bytes)) +} + +fn trim_ascii_start(bytes: &[u8]) -> &[u8] { + let first_non_whitespace = bytes + .iter() + .position(|byte| !byte.is_ascii_whitespace()) + .unwrap_or(bytes.len()); + &bytes[first_non_whitespace..] +} + +fn line_without_ending(line: &[u8]) -> &[u8] { + let line = line.strip_suffix(b"\n").unwrap_or(line); + line.strip_suffix(b"\r").unwrap_or(line) +} + +#[cfg(test)] +mod tests; diff --git a/pkg/xtask/src/lint/file_length/report.rs b/pkg/xtask/src/lint/file_length/report.rs new file mode 100644 index 0000000..dd16602 --- /dev/null +++ b/pkg/xtask/src/lint/file_length/report.rs @@ -0,0 +1,44 @@ +use std::path::{Path, PathBuf}; + +pub struct Violation { + pub path: PathBuf, + pub line_count: usize, + pub limit: usize, +} + +pub fn render_failure(repo_root: &Path, violations: &[Violation]) -> Vec { + let mut lines = Vec::new(); + lines.push( + "File length check failed. The following files exceed their configured limits:".to_owned(), + ); + lines.push(String::new()); + + for violation in violations { + lines.push(format!( + "- {} has {} lines (limit {})", + relative_display(repo_root, &violation.path), + violation.line_count, + violation.limit + )); + } + + lines.push(String::new()); + lines.push("Primary hint: Refactor large files to reduce their length.".to_owned()); + lines.push( + "Secondary hint: If the additional length is justified, add an override comment at the top of the file." + .to_owned(), + ); + lines.push( + " Example override comment: '// lint-long-file-override allow-max-lines=300' to bump the limit to 300 lines" + .to_owned(), + ); + lines.push(" Bump the limits in increments of 100.".to_owned()); + lines +} + +pub fn relative_display(repo_root: &Path, path: &Path) -> String { + path.strip_prefix(repo_root) + .unwrap_or(path) + .to_string_lossy() + .replace('\\', "/") +} diff --git a/pkg/xtask/src/lint/file_length/tests.rs b/pkg/xtask/src/lint/file_length/tests.rs new file mode 100644 index 0000000..3f94b9c --- /dev/null +++ b/pkg/xtask/src/lint/file_length/tests.rs @@ -0,0 +1,150 @@ +use std::fs; +use std::path::Path; + +use tempfile::tempdir; + +use super::{ + DEFAULT_LIMIT, FileInspection, collect_rust_files, inspect_file, parse_override_limit, + report::relative_display, +}; + +#[test] +fn collects_rust_files_recursively_in_sorted_order() { + let temp = tempdir().expect("tempdir"); + write_file(temp.path().join("pkg/z.rs"), ""); + write_file(temp.path().join("pkg/a/nested.rs"), ""); + write_file(temp.path().join("pkg/a/ignored.txt"), ""); + + let files = collect_rust_files(&temp.path().join("pkg")).expect("collect files"); + let relative = files + .iter() + .map(|path| relative_display(temp.path(), path)) + .collect::>(); + + assert_eq!(relative, vec!["pkg/a/nested.rs", "pkg/z.rs"]); +} + +#[test] +fn detects_default_limit_violation() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("long.rs"); + write_file(&path, lines(DEFAULT_LIMIT + 1)); + + let FileInspection::Checked { line_count, limit } = inspect_file(&path).expect("inspect file") + else { + panic!("file should be checked"); + }; + + assert_eq!(line_count, DEFAULT_LIMIT + 1); + assert_eq!(limit, DEFAULT_LIMIT); +} + +#[test] +fn honors_override_in_first_twenty_lines() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("overridden.rs"); + let source = format!( + " // lint-long-file-override allow-max-lines = 250\n{}", + lines(DEFAULT_LIMIT + 1) + ); + write_file(&path, source); + + let FileInspection::Checked { line_count, limit } = inspect_file(&path).expect("inspect file") + else { + panic!("file should be checked"); + }; + + assert_eq!(line_count, DEFAULT_LIMIT + 2); + assert_eq!(limit, 250); +} + +#[test] +fn uses_first_override_in_first_twenty_lines() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("multiple_overrides.rs"); + let source = format!( + "// lint-long-file-override allow-max-lines=250\n// lint-long-file-override allow-max-lines=300\n{}", + lines(DEFAULT_LIMIT + 1) + ); + write_file(&path, source); + + let FileInspection::Checked { limit, .. } = inspect_file(&path).expect("inspect file") else { + panic!("file should be checked"); + }; + + assert_eq!(limit, 250); +} + +#[test] +fn ignores_override_after_first_twenty_lines() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("late_override.rs"); + let source = format!( + "{}// lint-long-file-override allow-max-lines=300\n", + lines(20) + ); + write_file(&path, source); + + let FileInspection::Checked { limit, .. } = inspect_file(&path).expect("inspect file") else { + panic!("file should be checked"); + }; + + assert_eq!(limit, DEFAULT_LIMIT); +} + +#[test] +fn skips_generated_first_line_files() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("generated.rs"); + write_file( + &path, + format!("// @generated\n{}", lines(DEFAULT_LIMIT + 1)), + ); + + assert!(matches!( + inspect_file(&path).expect("inspect file"), + FileInspection::Generated + )); +} + +#[test] +fn preserves_wc_line_count_semantics() { + let temp = tempdir().expect("tempdir"); + let path = temp.path().join("partial.rs"); + write_file(&path, "one\ntwo"); + + let FileInspection::Checked { line_count, .. } = inspect_file(&path).expect("inspect file") + else { + panic!("file should be checked"); + }; + + assert_eq!(line_count, 1); +} + +#[test] +fn parses_override_limit_like_the_shell_pattern() { + assert_eq!( + parse_override_limit(b"\t// lint-long-file-override allow-max-lines = 300"), + Some(300) + ); + assert_eq!( + parse_override_limit(b"// lint-long-file-overrideallow-max-lines=300"), + None + ); + assert_eq!( + parse_override_limit(b"// lint-long-file-override allow-max-lines = nope"), + None + ); +} + +fn lines(count: usize) -> String { + "line\n".repeat(count) +} + +fn write_file(path: impl AsRef, contents: impl AsRef<[u8]>) { + let path = path.as_ref(); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent).expect("create parent dir"); + } + fs::write(path, contents).expect("write file"); +} diff --git a/pkg/xtask/src/lint/mod.rs b/pkg/xtask/src/lint/mod.rs index c27fc86..5247428 100644 --- a/pkg/xtask/src/lint/mod.rs +++ b/pkg/xtask/src/lint/mod.rs @@ -1,4 +1,5 @@ // lint-long-file-override allow-max-lines=250 +mod file_length; mod i18n; mod steps; @@ -8,7 +9,7 @@ use clap::{ArgGroup, Args, ValueEnum}; use crate::error::{Result, XTaskError, workspace_root}; use crate::lint::steps::{ - StepResult, print_step, run_ast_grep, run_claude_doc, run_clippy, run_file_length, run_hakari, + StepResult, print_step, run_ast_grep, run_claude_doc, run_clippy, run_file_length, run_i18n_consistency, run_rustfmt, run_spec_lint, run_taplo_check, run_taplo_fmt, run_workspace_deps, }; @@ -31,8 +32,6 @@ pub enum LinterType { FileLength, /// Internationalization locale consistency I18nConsistency, - /// Cargo Hakari workspace-hack consistency - Hakari, /// Workspace dependency inheritance validator WorkspaceDeps, } @@ -67,6 +66,12 @@ pub enum LintMode { CheckOnly, } +impl LintMode { + pub fn is_check_only(self) -> bool { + matches!(self, LintMode::CheckOnly) + } +} + pub fn run_lint(args: LintArgs) -> Result<()> { let repo_root = workspace_root()?; println!("Running xtask lint..."); @@ -133,17 +138,11 @@ fn run_sync_linters( LinterType::WorkspaceDeps, Box::new(|| run_workspace_deps(repo_root)), )?; - run_conditional_linter( - filters, - results, - LinterType::Hakari, - Box::new(|| run_hakari(repo_root, mode)), - )?; run_conditional_linter( filters, results, LinterType::Clippy, - Box::new(|| run_clippy(repo_root)), + Box::new(|| run_clippy(repo_root, mode)), )?; Ok(()) diff --git a/pkg/xtask/src/lint/steps/checks.rs b/pkg/xtask/src/lint/steps/checks.rs index b12c623..ef2c2b6 100644 --- a/pkg/xtask/src/lint/steps/checks.rs +++ b/pkg/xtask/src/lint/steps/checks.rs @@ -1,10 +1,10 @@ -// lint-long-file-override allow-max-lines=240 use std::io::ErrorKind; use std::path::Path; use std::time::Instant; use crate::error::{Result, XTaskError}; +use crate::lint::file_length; use crate::lint::i18n; use crate::lint::steps::{StepResult, run_command}; @@ -67,67 +67,9 @@ pub fn run_ast_grep(repo_root: &Path) -> Result { } pub fn run_file_length(repo_root: &Path) -> Result { - let start = Instant::now(); - let status = match run_command(repo_root, "scripts/check-file-length.sh", &[]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "File length", - "scripts/check-file-length.sh not found; skipping length check".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if status.success() { - Ok(StepResult::success( - "File length", - "All files within length limits".to_string(), - start.elapsed(), - )) - } else { - Ok(StepResult::failed( - "File length", - "scripts/check-file-length.sh reported issues".to_string(), - start.elapsed(), - )) - } + file_length::run(repo_root) } pub fn run_i18n_consistency(repo_root: &Path) -> Result { i18n::run(repo_root) } - -pub fn run_clippy(repo_root: &Path) -> Result { - let start = Instant::now(); - let status = match run_command( - repo_root, - "cargo", - &["clippy", "--all-targets", "--quiet", "--", "-D", "warnings"], - ) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "Cargo clippy", - "cargo not found; skipping clippy step".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if status.success() { - Ok(StepResult::success( - "Cargo clippy", - "All checks passed".to_string(), - start.elapsed(), - )) - } else { - Ok(StepResult::failed( - "Cargo clippy", - "cargo clippy reported issues".to_string(), - start.elapsed(), - )) - } -} diff --git a/pkg/xtask/src/lint/steps/clippy.rs b/pkg/xtask/src/lint/steps/clippy.rs new file mode 100644 index 0000000..3349a5a --- /dev/null +++ b/pkg/xtask/src/lint/steps/clippy.rs @@ -0,0 +1,68 @@ +mod selection; + +use std::io::ErrorKind; +use std::path::Path; +use std::time::Instant; + +use crate::error::{Result, XTaskError}; +use crate::lint::LintMode; +use crate::lint::steps::clippy::selection::{ + ClippySelection, build_clippy_args, print_selection, select_clippy_packages, + selection_failure_detail, selection_success_detail, +}; +use crate::lint::steps::{StepResult, run_command_with_env}; + +pub fn run_clippy(repo_root: &Path, mode: LintMode) -> Result { + let start = Instant::now(); + let target_dir = repo_root.join("target/clippy"); + let target_dir = target_dir.to_string_lossy(); + let selection = select_clippy_packages(repo_root, mode)?; + if let ClippySelection::Skip { detail } = &selection { + return Ok(StepResult::skipped( + "Cargo clippy", + detail.clone(), + start.elapsed(), + )); + } + + let Some(args) = build_clippy_args(mode, &selection) else { + return Ok(StepResult::skipped( + "Cargo clippy", + "No clippy command selected".to_owned(), + start.elapsed(), + )); + }; + + print_selection(&selection); + let args_ref = args.iter().map(String::as_str).collect::>(); + let status = match run_command_with_env( + repo_root, + "cargo", + &args_ref, + &[("CARGO_TARGET_DIR", target_dir.as_ref())], + ) { + Ok(status) => status, + Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { + return Ok(StepResult::skipped( + "Cargo clippy", + "cargo not found; skipping clippy step".to_owned(), + start.elapsed(), + )); + } + Err(error) => return Err(error), + }; + + if status.success() { + Ok(StepResult::success( + "Cargo clippy", + selection_success_detail(&selection), + start.elapsed(), + )) + } else { + Ok(StepResult::failed( + "Cargo clippy", + selection_failure_detail(&selection), + start.elapsed(), + )) + } +} diff --git a/pkg/xtask/src/lint/steps/clippy/selection.rs b/pkg/xtask/src/lint/steps/clippy/selection.rs new file mode 100644 index 0000000..88f1d54 --- /dev/null +++ b/pkg/xtask/src/lint/steps/clippy/selection.rs @@ -0,0 +1,198 @@ +use std::collections::BTreeSet; +use std::path::Path; + +use crate::cargo_metadata::load_workspace_metadata; +use crate::error::Result; +use crate::git::collect_changed_files; +use crate::lint::LintMode; +use crate::workspace_changes::{ + DependencyGraph, RootManifestBehavior, calculate_affected_crates, determine_changed_crates, + sorted_list, +}; + +pub enum ClippySelection { + Workspace { + reason: String, + }, + Packages { + direct: BTreeSet, + additional: BTreeSet, + packages: Vec, + unmatched: Vec, + }, + Skip { + detail: String, + }, +} + +pub fn select_clippy_packages(repo_root: &Path, mode: LintMode) -> Result { + if mode.is_check_only() { + return Ok(ClippySelection::Workspace { + reason: "--check runs the full workspace".to_owned(), + }); + } + + let changed_files = collect_changed_files(repo_root)?; + if changed_files.is_empty() { + return Ok(ClippySelection::Skip { + detail: "No changed files detected".to_owned(), + }); + } + + if let Some(path) = changed_files + .iter() + .find(|path| is_global_clippy_input(Path::new(path))) + { + return Ok(ClippySelection::Workspace { + reason: format!("{path} affects workspace clippy configuration"), + }); + } + + let metadata = load_workspace_metadata(repo_root)?; + let changed = determine_changed_crates( + &metadata, + repo_root, + &changed_files, + RootManifestBehavior::TreatAsUnmatched, + ); + + if changed.direct.is_empty() { + if changed_files.contains("Cargo.toml") { + return Ok(ClippySelection::Workspace { + reason: "root Cargo.toml changed without package changes".to_owned(), + }); + } + + if changed_files.contains("Cargo.lock") { + return Ok(ClippySelection::Workspace { + reason: "Cargo.lock changed without a package change".to_owned(), + }); + } + + if has_rust_relevant_unmatched(&changed.unmatched) { + return Ok(ClippySelection::Workspace { + reason: format!( + "Rust-relevant files outside workspace crates changed: {}", + changed.unmatched.join(", ") + ), + }); + } + + return Ok(ClippySelection::Skip { + detail: "No changed workspace crates detected".to_owned(), + }); + } + + let graph = DependencyGraph::build(&metadata); + let affected = calculate_affected_crates(&graph, &changed.direct); + let packages = affected.ordered_package_names(); + + Ok(ClippySelection::Packages { + direct: affected.direct, + additional: affected.additional, + packages, + unmatched: changed.unmatched, + }) +} + +pub fn build_clippy_args(mode: LintMode, selection: &ClippySelection) -> Option> { + let mut args = vec!["clippy".to_owned()]; + if mode.is_check_only() { + args.push("--locked".to_owned()); + } + + match selection { + ClippySelection::Workspace { .. } => { + args.push("--workspace".to_owned()); + } + ClippySelection::Packages { packages, .. } => { + for package in packages { + args.push("--package".to_owned()); + args.push(package.clone()); + } + } + ClippySelection::Skip { .. } => return None, + } + + args.extend([ + "--all-targets".to_owned(), + "--quiet".to_owned(), + "--".to_owned(), + "-D".to_owned(), + "warnings".to_owned(), + ]); + Some(args) +} + +pub fn print_selection(selection: &ClippySelection) { + match selection { + ClippySelection::Workspace { reason } => { + println!("Running full workspace clippy: {reason}"); + } + ClippySelection::Packages { + direct, + additional, + unmatched, + .. + } => { + println!( + "Changed crates for clippy: {}", + sorted_list(direct).join(", ") + ); + if !additional.is_empty() { + println!( + "Transitively affected crates for clippy: {}", + sorted_list(additional).join(", ") + ); + } + if !unmatched.is_empty() { + println!( + "Non-crate changes did not widen clippy scope: {}", + unmatched.join(", ") + ); + } + } + ClippySelection::Skip { .. } => {} + } +} + +pub fn selection_success_detail(selection: &ClippySelection) -> String { + match selection { + ClippySelection::Workspace { .. } => "All workspace checks passed".to_owned(), + ClippySelection::Packages { packages, .. } => { + format!("All checks passed for {} affected crate(s)", packages.len()) + } + ClippySelection::Skip { detail } => detail.clone(), + } +} + +pub fn selection_failure_detail(selection: &ClippySelection) -> String { + match selection { + ClippySelection::Workspace { .. } => "cargo clippy reported workspace issues".to_owned(), + ClippySelection::Packages { packages, .. } => { + format!( + "cargo clippy reported issues for {} affected crate(s)", + packages.len() + ) + } + ClippySelection::Skip { detail } => detail.clone(), + } +} + +fn is_global_clippy_input(path: &Path) -> bool { + matches!( + path.to_str(), + Some("clippy.toml") + | Some("rust-toolchain") + | Some("rust-toolchain.toml") + | Some(".cargo/config") + | Some(".cargo/config.toml") + ) +} + +fn has_rust_relevant_unmatched(paths: &[String]) -> bool { + paths.iter().any(|path| { + let path = Path::new(path); + path.extension().is_some_and(|extension| extension == "rs") + }) +} diff --git a/pkg/xtask/src/lint/steps/command.rs b/pkg/xtask/src/lint/steps/command.rs index a3f3497..e42d759 100644 --- a/pkg/xtask/src/lint/steps/command.rs +++ b/pkg/xtask/src/lint/steps/command.rs @@ -5,11 +5,43 @@ use contextful::ResultContextExt; use crate::error::Result; +const CARGO_PACKAGE_ENV_VARS: &[&str] = &[ + "CARGO_BIN_NAME", + "CARGO_CRATE_NAME", + "CARGO_MANIFEST_DIR", + "CARGO_MANIFEST_LINKS", + "CARGO_MANIFEST_PATH", + "CARGO_PRIMARY_PACKAGE", + "OUT_DIR", +]; + pub fn run_command(repo_root: &Path, program: &'static str, args: &[&str]) -> Result { + run_command_with_env(repo_root, program, args, &[]) +} + +pub fn run_command_with_env( + repo_root: &Path, + program: &'static str, + args: &[&str], + envs: &[(&str, &str)], +) -> Result { let mut command = Command::new(program); command.current_dir(repo_root); command.args(args); + // Nested tools should not observe xtask's own Cargo package metadata. + for (key, _) in std::env::vars() { + if key.starts_with("CARGO_PKG_") { + command.env_remove(key); + } + } + for key in CARGO_PACKAGE_ENV_VARS { + command.env_remove(key); + } + for (key, value) in envs { + command.env(key, value); + } + if program == "taplo" { // Taplo logs at info level by default; force a quieter level for lint output. command.env("TAPLO_LOG", "warn"); diff --git a/pkg/xtask/src/lint/steps/hakari.rs b/pkg/xtask/src/lint/steps/hakari.rs deleted file mode 100644 index 2cb4529..0000000 --- a/pkg/xtask/src/lint/steps/hakari.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::collections::BTreeSet; -use std::io::ErrorKind; -use std::path::Path; -use std::time::Instant; - -use crate::error::{Result, XTaskError}; -use crate::git::{capture_file_contents, collect_changed_files, summarize_file_updates}; - -use crate::lint::LintMode; -use crate::lint::steps::{StepResult, run_command}; - -fn ensure_hakari_installed(repo_root: &Path, start: Instant) -> Result> { - let version_status = match run_command(repo_root, "cargo", &["hakari", "--version"]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(Some(StepResult::skipped( - "Cargo Hakari", - "cargo not found; skipping hakari step".to_string(), - start.elapsed(), - ))); - } - Err(error) => return Err(error), - }; - - if version_status.success() { - return Ok(None); - } - - if version_status.code() == Some(101) { - return Ok(Some(StepResult::skipped( - "Cargo Hakari", - "cargo hakari not installed; install via `cargo install cargo-hakari --locked`." - .to_string(), - start.elapsed(), - ))); - } - - Ok(Some(StepResult::failed( - "Cargo Hakari", - "cargo hakari --version failed; see output above.".to_string(), - start.elapsed(), - ))) -} - -pub fn run_hakari(repo_root: &Path, mode: LintMode) -> Result { - let start = Instant::now(); - - if let Some(step) = ensure_hakari_installed(repo_root, start)? { - return Ok(step); - } - - if matches!(mode, LintMode::CheckOnly) { - return run_hakari_check_only(repo_root, start); - } - - run_hakari_manage_deps(repo_root, start) -} - -fn run_hakari_check_only(repo_root: &Path, start: Instant) -> Result { - let generate_status = match run_command(repo_root, "cargo", &["hakari", "generate", "--diff"]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "Cargo Hakari", - "cargo not found; skipping hakari step".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if !generate_status.success() { - return Ok(StepResult::failed( - "Cargo Hakari", - "workspace-hack crate is out of date; run `cargo hakari generate`.".to_string(), - start.elapsed(), - )); - } - - let manage_status = - match run_command(repo_root, "cargo", &["hakari", "manage-deps", "--dry-run"]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "Cargo Hakari", - "cargo not found; skipping hakari step".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if !manage_status.success() { - return Ok(StepResult::failed( - "Cargo Hakari", - "workspace-hack dependencies need updates; run `cargo hakari manage-deps --yes`." - .to_string(), - start.elapsed(), - )); - } - - Ok(StepResult::success( - "Cargo Hakari", - "Workspace hack crate is up to date".to_string(), - start.elapsed(), - )) -} - -fn run_hakari_manage_deps(repo_root: &Path, start: Instant) -> Result { - let before_set = collect_changed_files(repo_root)? - .into_iter() - .filter(|path| is_relevant_path(path)) - .collect::>(); - let before_contents = capture_file_contents(repo_root, &before_set)?; - - let generate_status = match run_command(repo_root, "cargo", &["hakari", "generate"]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "Cargo Hakari", - "cargo not found; skipping hakari step".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if !generate_status.success() { - return Ok(StepResult::failed( - "Cargo Hakari", - "cargo hakari generate failed; see output above.".to_string(), - start.elapsed(), - )); - } - - let manage_status = match run_command(repo_root, "cargo", &["hakari", "manage-deps", "--yes"]) { - Ok(status) => status, - Err(XTaskError::Io(source)) if source.kind() == ErrorKind::NotFound => { - return Ok(StepResult::skipped( - "Cargo Hakari", - "cargo not found; skipping hakari step".to_string(), - start.elapsed(), - )); - } - Err(error) => return Err(error), - }; - - if !manage_status.success() { - return Ok(StepResult::failed( - "Cargo Hakari", - "cargo hakari manage-deps failed; see output above.".to_string(), - start.elapsed(), - )); - } - - let after_set = collect_changed_files(repo_root)? - .into_iter() - .filter(|path| is_relevant_path(path)) - .collect::>(); - - let updated = summarize_file_updates(repo_root, &before_set, &before_contents, &after_set)?; - - if updated.is_empty() { - Ok(StepResult::success( - "Cargo Hakari", - "Workspace hack crate already up to date".to_string(), - start.elapsed(), - )) - } else { - let detail = format!("Updated {} file(s) via cargo hakari", updated.len()); - Ok(StepResult::fixed( - "Cargo Hakari", - detail, - updated, - start.elapsed(), - )) - } -} - -fn is_relevant_path(path: &str) -> bool { - path.ends_with(".toml") || path == "Cargo.lock" || path.contains("workspace-hack") -} diff --git a/pkg/xtask/src/lint/steps/mod.rs b/pkg/xtask/src/lint/steps/mod.rs index 1a8b180..6f002fc 100644 --- a/pkg/xtask/src/lint/steps/mod.rs +++ b/pkg/xtask/src/lint/steps/mod.rs @@ -1,19 +1,17 @@ mod checks; mod claude; +mod clippy; mod command; mod formatting; -mod hakari; mod result; mod spec_lint; mod workspace_deps; -pub use checks::{ - run_ast_grep, run_clippy, run_file_length, run_i18n_consistency, run_taplo_check, -}; +pub use checks::{run_ast_grep, run_file_length, run_i18n_consistency, run_taplo_check}; pub use claude::run_claude_doc; -pub use command::run_command; +pub use clippy::run_clippy; +pub use command::{run_command, run_command_with_env}; pub use formatting::{run_rustfmt, run_taplo_fmt}; -pub use hakari::run_hakari; pub use result::{StepResult, print_step}; pub use spec_lint::run_spec_lint; pub use workspace_deps::run_workspace_deps; diff --git a/pkg/xtask/src/lint/steps/workspace_deps.rs b/pkg/xtask/src/lint/steps/workspace_deps.rs index 359dec7..7a7d3a9 100644 --- a/pkg/xtask/src/lint/steps/workspace_deps.rs +++ b/pkg/xtask/src/lint/steps/workspace_deps.rs @@ -7,8 +7,8 @@ use std::time::Instant; use contextful::ResultContextExt; use toml::Value; +use crate::cargo_metadata::load_workspace_metadata; use crate::error::Result; - use crate::lint::steps::StepResult; const DEPENDENCY_TABLE_KEYS: &[&str] = &["dependencies", "dev-dependencies", "build-dependencies"]; @@ -31,7 +31,7 @@ pub fn run_workspace_deps(repo_root: &Path) -> Result { if violations.is_empty() { return Ok(StepResult::success( "Workspace dependencies", - "All crate dependencies inherit from the workspace".to_string(), + "All workspace crate dependencies inherit from the workspace".to_string(), start.elapsed(), )); } @@ -69,28 +69,11 @@ pub fn run_workspace_deps(repo_root: &Path) -> Result { } fn collect_package_manifests(repo_root: &Path) -> Result> { - let mut manifests = Vec::new(); - let pkg_dir = repo_root.join("pkg"); - let entries = fs::read_dir(&pkg_dir).with_context(|| format!("list {}", pkg_dir.display()))?; - - for entry in entries { - let entry = entry.with_context(|| format!("iterate {}", pkg_dir.display()))?; - let metadata = entry - .metadata() - .with_context(|| format!("load metadata for {}", entry.path().display()))?; - if !metadata.is_dir() { - continue; - } - - if entry.file_name() == "workspace-hack" { - continue; - } - - let manifest_path = entry.path().join("Cargo.toml"); - if manifest_path.exists() { - manifests.push(manifest_path); - } - } + let metadata = load_workspace_metadata(repo_root)?; + let mut manifests = metadata + .workspace_packages() + .map(|package| package.manifest_path_abs().to_path_buf()) + .collect::>(); manifests.sort(); Ok(manifests) @@ -99,16 +82,47 @@ fn collect_package_manifests(repo_root: &Path) -> Result> { fn check_manifest(repo_root: &Path, manifest_path: &Path, manifest: &Value) -> Vec { let mut violations = Vec::new(); + let Some(table) = manifest.as_table() else { + return violations; + }; + + check_dependency_tables(repo_root, manifest_path, table, None, &mut violations); + + if let Some(targets) = table.get("target").and_then(Value::as_table) { + for (target, target_value) in targets { + let Some(target_table) = target_value.as_table() else { + continue; + }; + + check_dependency_tables( + repo_root, + manifest_path, + target_table, + Some(&format!("target.{target}")), + &mut violations, + ); + } + } + + violations +} + +fn check_dependency_tables( + repo_root: &Path, + manifest_path: &Path, + table: &toml::value::Table, + section_prefix: Option<&str>, + violations: &mut Vec, +) { for section in DEPENDENCY_TABLE_KEYS { - let Some(table) = manifest.get(*section).and_then(Value::as_table) else { + let Some(dependencies) = table.get(*section).and_then(Value::as_table) else { continue; }; + let section_display = section_prefix + .map(|prefix| format!("{prefix}.{section}")) + .unwrap_or_else(|| (*section).to_owned()); - for (dependency, value) in table { - if dependency == "workspace-hack" { - continue; - } - + for (dependency, value) in dependencies { if dependency_uses_workspace(value) { continue; } @@ -117,13 +131,11 @@ fn check_manifest(repo_root: &Path, manifest_path: &Path, manifest: &Value) -> V repo_root, manifest_path, dependency, - section, + §ion_display, value, )); } } - - violations } fn dependency_uses_workspace(value: &Value) -> bool { diff --git a/pkg/xtask/src/main.rs b/pkg/xtask/src/main.rs index 6625857..721e421 100644 --- a/pkg/xtask/src/main.rs +++ b/pkg/xtask/src/main.rs @@ -1,3 +1,4 @@ +mod cargo_metadata; mod error; mod git; mod lint; @@ -5,6 +6,7 @@ mod noir_fixtures; mod revi; mod setup; mod test; +mod workspace_changes; use clap::{Parser, Subcommand}; diff --git a/pkg/xtask/src/test/changes.rs b/pkg/xtask/src/test/changes.rs deleted file mode 100644 index d439a63..0000000 --- a/pkg/xtask/src/test/changes.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::collections::BTreeSet; -use std::path::Path; - -use crate::test::metadata::Metadata; - -pub struct ChangedCrates { - pub direct: BTreeSet, - pub unmatched: Vec, - pub touches_all: bool, -} - -pub fn determine_changed_crates( - metadata: &Metadata, - repo_root: &Path, - changed_files: &BTreeSet, -) -> ChangedCrates { - let mut direct = BTreeSet::new(); - let mut unmatched = Vec::new(); - let mut touches_all = false; - - for path_str in changed_files { - let path = Path::new(path_str); - if touches_workspace_manifest(path) { - touches_all = true; - break; - } - - let absolute_path = repo_root.join(path); - let mut matched = false; - - for package in metadata.workspace_packages() { - if absolute_path.starts_with(package.manifest_dir_abs()) { - direct.insert(package.name.clone()); - matched = true; - } - } - - if !matched { - unmatched.push(path_str.clone()); - } - } - - if touches_all { - direct = metadata - .workspace_packages() - .map(|package| package.name.clone()) - .collect(); - unmatched.clear(); - } - - ChangedCrates { - direct, - unmatched, - touches_all, - } -} - -pub fn sorted_list(set: &BTreeSet) -> Vec { - set.iter().cloned().collect() -} - -fn touches_workspace_manifest(path: &Path) -> bool { - if path.ends_with("Cargo.toml") && path.parent().is_none() { - return true; - } - - if path.ends_with("Cargo.lock") { - // A small change like adding a feature or dependency to a single crate - // can update the Cargo.lock for the whole workspace, - // but there is no point in running all tests in that case. - // So this is purposely commented out. - // return true; - } - - false -} diff --git a/pkg/xtask/src/test/graph.rs b/pkg/xtask/src/test/graph.rs deleted file mode 100644 index 95556ce..0000000 --- a/pkg/xtask/src/test/graph.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::collections::{BTreeSet, HashMap, HashSet, VecDeque}; - -use crate::test::metadata::Metadata; - -#[derive(Debug)] -pub struct DependencyGraph { - reverse: HashMap>, -} - -impl DependencyGraph { - pub fn build(metadata: &Metadata) -> Self { - let mut reverse = HashMap::>::new(); - - for member_id in metadata.workspace_member_ids() { - if let Some(package) = metadata.package_for_id(member_id) { - reverse.entry(package.name.clone()).or_default(); - - for dependency_id in metadata.dependencies_for(member_id) { - if !metadata.is_workspace_member(dependency_id) { - continue; - } - - if let Some(dep_package) = metadata.package_for_id(dependency_id) { - reverse - .entry(dep_package.name.clone()) - .or_default() - .insert(package.name.clone()); - } - } - } - } - - DependencyGraph { reverse } - } - - pub fn dependents_of(&self, crate_name: &str) -> Option<&BTreeSet> { - self.reverse.get(crate_name) - } -} - -pub fn calculate_affected_crates( - graph: &DependencyGraph, - changed_crates: &BTreeSet, -) -> BTreeSet { - let mut visited = changed_crates.iter().cloned().collect::>(); - let mut queue = changed_crates.iter().cloned().collect::>(); - - while let Some(crate_name) = queue.pop_front() { - if let Some(dependents) = graph.dependents_of(&crate_name) { - for dependent in dependents { - if visited.insert(dependent.clone()) { - queue.push_back(dependent.clone()); - } - } - } - } - - visited.into_iter().collect() -} diff --git a/pkg/xtask/src/test/mod.rs b/pkg/xtask/src/test/mod.rs index 0ef6eec..3c07f6b 100644 --- a/pkg/xtask/src/test/mod.rs +++ b/pkg/xtask/src/test/mod.rs @@ -1,9 +1,5 @@ -mod changes; -mod graph; -mod metadata; mod workspace; -use std::collections::BTreeSet; use std::process::Command; use clap::Args; @@ -12,10 +8,12 @@ use contextful::ResultContextExt; use crate::error::{Result, XTaskError, workspace_root}; use crate::git::collect_changed_files; -use crate::test::changes::{ChangedCrates, determine_changed_crates, sorted_list}; -use crate::test::graph::DependencyGraph; -use crate::test::metadata::{Metadata, load_metadata}; +use crate::cargo_metadata::{Metadata, load_workspace_metadata}; use crate::test::workspace::{CompiledWorkspace, compile_package_tests}; +use crate::workspace_changes::{ + ChangedCrates, DependencyGraph, RootManifestBehavior, calculate_affected_crates, + determine_changed_crates, sorted_list, +}; fn prepare_execution_order( graph: &DependencyGraph, @@ -29,29 +27,19 @@ fn prepare_execution_order( return None; } - let direct_list = sorted_list(&changed.direct); + let affected = calculate_affected_crates(graph, &changed.direct); + let direct_list = sorted_list(&affected.direct); println!("Changed crates: {}", direct_list.join(", ")); - let affected = graph::calculate_affected_crates(graph, &changed.direct) - .into_iter() - .collect::>(); - let additional = affected - .iter() - .filter(|crate_name| !changed.direct.contains(*crate_name)) - .cloned() - .collect::>(); - - if !additional.is_empty() { - let additional_list = sorted_list(&additional); + if !affected.additional.is_empty() { + let additional_list = sorted_list(&affected.additional); println!( "Transitively affected crates: {}", additional_list.join(", ") ); } - let mut execution_order = direct_list.clone(); - execution_order.extend(sorted_list(&additional)); - Some(execution_order) + Some(affected.ordered_package_names()) } fn run_execution_order( @@ -135,8 +123,13 @@ pub fn run_test(_args: TestArgs) -> Result<()> { return Ok(()); } - let metadata = load_metadata(&repo_root)?; - let changed = determine_changed_crates(&metadata, &repo_root, &changed_files); + let metadata = load_workspace_metadata(&repo_root)?; + let changed = determine_changed_crates( + &metadata, + &repo_root, + &changed_files, + RootManifestBehavior::TouchesAll, + ); if changed.touches_all { println!("Detected root manifest change; all workspace crate tests will run"); diff --git a/pkg/xtask/src/test/workspace.rs b/pkg/xtask/src/test/workspace.rs index 6e943a2..87128a3 100644 --- a/pkg/xtask/src/test/workspace.rs +++ b/pkg/xtask/src/test/workspace.rs @@ -7,7 +7,7 @@ use serde::Deserialize; use crate::error::{Result, XTaskError}; -use crate::test::metadata::Metadata; +use crate::cargo_metadata::Metadata; pub struct CompiledWorkspace { test_binaries: HashMap>, diff --git a/pkg/xtask/src/workspace_changes.rs b/pkg/xtask/src/workspace_changes.rs new file mode 100644 index 0000000..cba62dc --- /dev/null +++ b/pkg/xtask/src/workspace_changes.rs @@ -0,0 +1,147 @@ +use std::collections::{BTreeSet, HashMap, HashSet, VecDeque}; +use std::path::Path; + +use crate::cargo_metadata::Metadata; + +pub struct ChangedCrates { + pub direct: BTreeSet, + pub unmatched: Vec, + pub touches_all: bool, +} + +#[derive(Clone, Copy)] +pub enum RootManifestBehavior { + TouchesAll, + TreatAsUnmatched, +} + +pub struct AffectedCrates { + pub direct: BTreeSet, + pub additional: BTreeSet, +} + +impl AffectedCrates { + pub fn ordered_package_names(&self) -> Vec { + let mut package_names = sorted_list(&self.direct); + package_names.extend(sorted_list(&self.additional)); + package_names + } +} + +#[derive(Debug)] +pub struct DependencyGraph { + reverse: HashMap>, +} + +impl DependencyGraph { + pub fn build(metadata: &Metadata) -> Self { + let mut reverse = HashMap::>::new(); + + for package in metadata.workspace_packages() { + reverse.entry(package.name.clone()).or_default(); + + for dependency_id in package.workspace_dependency_ids() { + if let Some(dep_package) = metadata.package_for_id(dependency_id) { + reverse + .entry(dep_package.name.clone()) + .or_default() + .insert(package.name.clone()); + } + } + } + + DependencyGraph { reverse } + } + + pub fn dependents_of(&self, crate_name: &str) -> Option<&BTreeSet> { + self.reverse.get(crate_name) + } +} + +pub fn determine_changed_crates( + metadata: &Metadata, + repo_root: &Path, + changed_files: &BTreeSet, + root_manifest_behavior: RootManifestBehavior, +) -> ChangedCrates { + let mut direct = BTreeSet::new(); + let mut unmatched = Vec::new(); + let mut touches_all = false; + + for path_str in changed_files { + let path = Path::new(path_str); + if is_root_manifest(path) { + match root_manifest_behavior { + RootManifestBehavior::TouchesAll => { + touches_all = true; + break; + } + RootManifestBehavior::TreatAsUnmatched => {} + } + } + + let absolute_path = repo_root.join(path); + let mut matched = false; + + for package in metadata.workspace_packages() { + if absolute_path.starts_with(package.manifest_dir_abs()) { + direct.insert(package.name.clone()); + matched = true; + } + } + + if !matched { + unmatched.push(path_str.clone()); + } + } + + if touches_all { + direct = metadata + .workspace_packages() + .map(|package| package.name.clone()) + .collect(); + unmatched.clear(); + } + + ChangedCrates { + direct, + unmatched, + touches_all, + } +} + +pub fn calculate_affected_crates( + graph: &DependencyGraph, + changed_crates: &BTreeSet, +) -> AffectedCrates { + let mut visited = changed_crates.iter().cloned().collect::>(); + let mut queue = changed_crates.iter().cloned().collect::>(); + + while let Some(crate_name) = queue.pop_front() { + if let Some(dependents) = graph.dependents_of(&crate_name) { + for dependent in dependents { + if visited.insert(dependent.clone()) { + queue.push_back(dependent.clone()); + } + } + } + } + + let additional = visited + .into_iter() + .filter(|crate_name| !changed_crates.contains(crate_name)) + .collect::>(); + + AffectedCrates { + direct: changed_crates.clone(), + additional, + } +} + +pub fn sorted_list(set: &BTreeSet) -> Vec { + set.iter().cloned().collect() +} + +fn is_root_manifest(path: &Path) -> bool { + path.ends_with("Cargo.toml") && path.parent().is_none() +} diff --git a/pkg/zk-circuits/Cargo.toml b/pkg/zk-circuits/Cargo.toml index d0ad2ed..b6bab49 100644 --- a/pkg/zk-circuits/Cargo.toml +++ b/pkg/zk-circuits/Cargo.toml @@ -28,7 +28,6 @@ flate2 = { workspace = true } async-trait = { workspace = true } tokio = { workspace = true } paste = { workspace = true } -workspace-hack.workspace = true [dev-dependencies] smirk = { workspace = true } diff --git a/pkg/zk-primitives/Cargo.toml b/pkg/zk-primitives/Cargo.toml index be0797f..05ba46c 100644 --- a/pkg/zk-primitives/Cargo.toml +++ b/pkg/zk-primitives/Cargo.toml @@ -17,7 +17,6 @@ rand = { workspace = true } serde = { workspace = true, features = ["derive"] } sha3 = { workspace = true } web3 = { workspace = true } -workspace-hack.workspace = true [dependencies.ts-rs] workspace = true diff --git a/scripts/check-file-length.sh b/scripts/check-file-length.sh deleted file mode 100755 index c7bf057..0000000 --- a/scripts/check-file-length.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -ROOT_DIR="$(git rev-parse --show-toplevel)" -TARGET_DIR="$ROOT_DIR/pkg" -DEFAULT_LIMIT=200 -OVERRIDE_PATTERN='^[[:space:]]*//[[:space:]]*lint-long-file-override[[:space:]]+allow-max-lines[[:space:]]*=[[:space:]]*([0-9]+)' - -if [[ ! -d "$TARGET_DIR" ]]; then - echo "pkg directory not found at $TARGET_DIR" >&2 - exit 1 -fi - -violations=() - -# Track whether we discovered any Rust files without relying on mapfile (which -# is unavailable on macOS's default bash 3.2). -found_files=0 - -while IFS= read -r file; do - found_files=1 - - limit=$DEFAULT_LIMIT - - if head -n 1 "$file" | grep -Eq '^//[[:space:]]*@generated'; then - continue - fi - - override_line="$(head -n 20 "$file" | grep -E "$OVERRIDE_PATTERN" || true)" - if [[ -n "$override_line" ]]; then - if [[ $override_line =~ $OVERRIDE_PATTERN ]]; then - limit="${BASH_REMATCH[1]}" - fi - fi - - line_count=$(wc -l < "$file") - # Trim whitespace that wc emits - line_count="${line_count//[[:space:]]/}" - - if [[ "$line_count" =~ ^[0-9]+$ ]] && [[ "$limit" =~ ^[0-9]+$ ]]; then - if (( line_count > limit )); then - relative_path="${file#$ROOT_DIR/}" - violations+=("$relative_path has $line_count lines (limit $limit)") - fi - else - echo "Unable to determine line limit or count for $file" >&2 - exit 1 - fi - -done < <(find "$TARGET_DIR" -type f -name '*.rs' -print | sort) - -if [[ $found_files -eq 0 ]]; then - echo "No Rust files found under pkg/." - exit 0 -fi - -if [[ ${#violations[@]} -ne 0 ]]; then - echo "❌ File length check failed. The following files exceed their configured limits:" - echo "" - for violation in "${violations[@]}"; do - echo "- $violation" - done - echo "" - echo "Primary hint: Refactor large files to reduce their length." - echo "Secondary hint: If the additional length is justified, add an override comment at the top of the file." - echo " Example override comment: '// lint-long-file-override allow-max-lines=300' to bump the limit to 300 lines" - echo " Bump the limits in increments of 100." - echo "" - exit 1 -fi - -echo "✅ All Rust files in pkg/ comply with the file length limits." diff --git a/taplo.toml b/taplo.toml index 58b734c..740728c 100644 --- a/taplo.toml +++ b/taplo.toml @@ -11,9 +11,6 @@ include = [ "*.toml", ] -# Exclude generated workspace hack manifest from formatting -exclude = ["pkg/workspace-hack/Cargo.toml"] - # Global formatting rules [formatting] # Don't align entries (key = value) to the same column