diff --git a/Cargo.lock b/Cargo.lock index 9895fbfb..195cc8fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + [[package]] name = "aes" version = "0.8.4" @@ -28,6 +38,18 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -108,7 +130,7 @@ dependencies = [ "alloy-tx-macros", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.0.1", "either", "k256", "once_cell", @@ -236,11 +258,11 @@ dependencies = [ "alloy-serde", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.0.1", "either", "serde", "serde_with 3.14.0", - "sha2", + "sha2 0.10.9", "thiserror 2.0.17", ] @@ -304,7 +326,7 @@ dependencies = [ "alloy-sol-types", "async-trait", "auto_impl", - "derive_more", + "derive_more 2.0.1", "futures-utils-wasm", "serde", "serde_json", @@ -334,7 +356,7 @@ dependencies = [ "bytes", "cfg-if", "const-hex", - "derive_more", + "derive_more 2.0.1", "foldhash", "hashbrown 0.15.5", "indexmap 2.11.0", @@ -421,7 +443,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4" dependencies = [ "alloy-rlp-derive", - "arrayvec", + "arrayvec 0.7.6", "bytes", ] @@ -630,7 +652,7 @@ dependencies = [ "alloy-primitives", "auto_impl", "base64 0.22.1", - "derive_more", + "derive_more 2.0.1", "futures", "futures-utils-wasm", "parking_lot", @@ -685,8 +707,8 @@ checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" dependencies = [ "alloy-primitives", "alloy-rlp", - "arrayvec", - "derive_more", + "arrayvec 0.7.6", + "derive_more 2.0.1", "nybbles", "serde", "smallvec", @@ -967,6 +989,21 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -1070,6 +1107,17 @@ dependencies = [ "slab", ] +[[package]] +name = "async-fs" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" +dependencies = [ + "async-lock 3.4.1", + "blocking", + "futures-lite 2.6.1", +] + [[package]] name = "async-global-executor" version = "3.1.0" @@ -1153,6 +1201,35 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io 2.5.0", + "blocking", + "futures-lite 2.6.1", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel 2.5.0", + "async-io 2.5.0", + "async-lock 3.4.1", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.4.1", + "futures-lite 2.6.1", + "rustix 1.0.8", +] + [[package]] name = "async-reactor-trait" version = "1.1.0" @@ -1176,6 +1253,24 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "async-signal" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +dependencies = [ + "async-io 2.5.0", + "async-lock 3.4.1", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.0.8", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -1235,6 +1330,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-take" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" + [[package]] name = "atomic-waker" version = "1.1.2" @@ -1404,14 +1505,14 @@ dependencies = [ "bytes", "fastrand 2.3.0", "hex", - "hmac", + "hmac 0.12.1", "http 0.2.12", "http 1.3.1", "http-body 0.4.6", "lru 0.12.5", "percent-encoding", "regex-lite", - "sha2", + "sha2 0.10.9", "tracing", "url", ] @@ -1520,13 +1621,13 @@ dependencies = [ "crypto-bigint 0.5.5", "form_urlencoded", "hex", - "hmac", + "hmac 0.12.1", "http 0.2.12", "http 1.3.1", "p256", "percent-encoding", "ring 0.17.14", - "sha2", + "sha2 0.10.9", "subtle", "time", "tracing", @@ -1560,7 +1661,7 @@ dependencies = [ "md-5", "pin-project-lite", "sha1", - "sha2", + "sha2 0.10.9", "tracing", ] @@ -2104,6 +2205,36 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +dependencies = [ + "arrayref", + "arrayvec 0.7.6", + "constant_time_eq 0.3.1", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -2168,6 +2299,15 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.12.0" @@ -2344,6 +2484,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -2375,6 +2521,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "chrono" version = "0.4.41" @@ -2387,7 +2544,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -2632,6 +2789,27 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "cookie-factory" version = "0.3.3" @@ -2974,6 +3152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -3224,13 +3403,44 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + [[package]] name = "derive_more" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ - "derive_more-impl", + "derive_more-impl 2.0.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.106", ] [[package]] @@ -3239,6 +3449,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ + "convert_case", "proc-macro2", "quote", "syn 2.0.106", @@ -3269,7 +3480,7 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -3350,6 +3561,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dunce" version = "1.0.5" @@ -3419,7 +3636,21 @@ dependencies = [ "ed25519", "rand_core 0.6.4", "serde", - "sha2", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0017d969298eec91e3db7a2985a8cab4df6341d86e6f3a6f5878b13fb7846bc9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "sha2 0.10.9", "subtle", "zeroize", ] @@ -3633,7 +3864,7 @@ dependencies = [ "libc", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "toml 0.9.5", "tracing", "tracing-subscriber", @@ -3712,7 +3943,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" dependencies = [ - "arrayvec", + "arrayvec 0.7.6", "auto_impl", "bytes", ] @@ -3723,7 +3954,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" dependencies = [ - "arrayvec", + "arrayvec 0.7.6", "auto_impl", "bytes", ] @@ -3881,6 +4112,34 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "frame-decode" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470df86cf28818dd3cd2fc4667b80dbefe2236c722c3dc1d09e7c6c82d6dfcd" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-decode", + "scale-encode", + "scale-info", + "scale-type-resolver", + "sp-crypto-hashing", + "thiserror 2.0.17", +] + +[[package]] +name = "frame-metadata" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c26fcb0454397c522c05fdad5380c4e622f8a875638af33bff5a320d1fc965" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] + [[package]] name = "fs-set-times" version = "0.20.3" @@ -4014,6 +4273,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -4134,6 +4399,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom_or_panic" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "gimli" version = "0.31.1" @@ -4356,6 +4630,10 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" @@ -4432,7 +4710,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" dependencies = [ - "arrayvec", + "arrayvec 0.7.6", ] [[package]] @@ -4447,7 +4725,17 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", ] [[package]] @@ -4459,6 +4747,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + [[package]] name = "home" version = "0.5.11" @@ -4858,6 +5157,24 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "impl-codec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d40b9d5e17727407e55028eafc22b2dc68781786e6d7eb8a21103f5058e3a14" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a143eada6a1ec4aefa5049037a26a6d597bfd64f8c026d07b77133e02b7dd0b" +dependencies = [ + "serde", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.3" @@ -5071,6 +5388,28 @@ dependencies = [ "cc", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.34" @@ -5092,10 +5431,90 @@ dependencies = [ ] [[package]] -name = "jsonwebtoken" -version = "9.3.1" +name = "jsonrpsee" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "37b26c20e2178756451cfeb0661fb74c47dd5988cb7e3939de7e9241fd604d42" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "jsonrpsee-ws-client", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bacb85abf4117092455e1573625e21b8f8ef4dec8aff13361140b2dc266cdff2" +dependencies = [ + "base64 0.22.1", + "futures-util", + "http 1.3.1", + "jsonrpsee-core", + "pin-project", + "rustls 0.23.31", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto", + "thiserror 1.0.69", + "tokio", + "tokio-rustls 0.26.2", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456196007ca3a14db478346f58c7238028d55ee15c1df15115596e411ff27925" +dependencies = [ + "async-trait", + "futures-timer", + "futures-util", + "jsonrpsee-types", + "pin-project", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a8e70baf945b6b5752fc8eb38c918a48f1234daf11355e07106d963f860089" +dependencies = [ + "http 1.3.1", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b3323d890aa384f12148e8d2a1fd18eb66e9e7e825f9de4fa53bcc19b93eef" +dependencies = [ + "http 1.3.1", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[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", @@ -5127,7 +5546,7 @@ dependencies = [ "elliptic-curve 0.13.8", "once_cell", "serdect", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -5146,7 +5565,7 @@ dependencies = [ "snap", "thiserror 1.0.69", "tracing", - "twox-hash", + "twox-hash 1.6.3", ] [[package]] @@ -5168,6 +5587,16 @@ dependencies = [ "sha3-asm", ] +[[package]] +name = "keccak-hash" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e1b8590eb6148af2ea2d75f38e7d29f5ca970d5a4df456b3ef19b8b415d0264" +dependencies = [ + "primitive-types 0.13.1", + "tiny-keccak", +] + [[package]] name = "kes-summed-ed25519" version = "0.2.1" @@ -5264,6 +5693,54 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "libsecp256k1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" +dependencies = [ + "arrayref", + "base64 0.22.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + [[package]] name = "libsqlite3-sys" version = "0.30.1" @@ -5456,6 +5933,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "miette" version = "7.6.0" @@ -5634,7 +6123,7 @@ dependencies = [ "serde_bytes", "serde_json", "serde_with 3.14.0", - "sha2", + "sha2 0.10.9", "slog", "strum 0.27.2", "thiserror 2.0.17", @@ -5663,6 +6152,12 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "multi-stash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685a9ac4b61f4e728e1d2c6a7844609c16527aeb5e6c865915c08e619c16410f" + [[package]] name = "multimap" version = "0.10.1" @@ -5701,6 +6196,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nom" version = "7.1.3" @@ -6023,6 +6524,7 @@ dependencies = [ "sqlx", "strum 0.26.3", "strum_macros 0.25.3", + "subxt", "tempfile", "thiserror 1.0.69", "tokio", @@ -6064,13 +6566,13 @@ dependencies = [ "der 0.7.10", "des", "hex", - "hmac", + "hmac 0.12.1", "pkcs12", "pkcs5", "rand 0.9.2", "rc2", "sha1", - "sha2", + "sha2 0.10.9", "thiserror 2.0.17", "x509-parser", ] @@ -6083,7 +6585,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6394,7 +6896,7 @@ version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" dependencies = [ - "arrayvec", + "arrayvec 0.7.6", "bitvec", "byte-slice-cast", "const_format", @@ -6501,7 +7003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", ] [[package]] @@ -6570,7 +7072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" dependencies = [ "pest", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6685,7 +7187,7 @@ dependencies = [ "der 0.7.10", "pbkdf2", "scrypt", - "sha2", + "sha2 0.10.9", "spki 0.7.3", ] @@ -6745,6 +7247,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "port-selector" version = "0.1.6" @@ -6813,8 +7326,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", - "impl-codec", - "uint", + "impl-codec 0.6.0", + "uint 0.9.5", +] + +[[package]] +name = "primitive-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" +dependencies = [ + "fixed-hash", + "impl-codec 0.7.1", + "impl-serde", + "scale-info", + "uint 0.10.0", ] [[package]] @@ -7450,7 +7976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint 0.4.9", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -7460,7 +7986,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -7573,7 +8099,7 @@ dependencies = [ "num-integer", "num-traits", "parity-scale-codec", - "primitive-types", + "primitive-types 0.12.2", "proptest", "rand 0.8.5", "rand 0.9.2", @@ -7818,6 +8344,33 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.31", + "rustls-native-certs 0.8.1", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.4", + "security-framework 3.3.0", + "security-framework-sys", + "webpki-root-certs 0.26.11", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -7858,6 +8411,12 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "ruzstd" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c" + [[package]] name = "ryu" version = "1.0.20" @@ -7882,6 +8441,141 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scale-bits" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27243ab0d2d6235072b017839c5f0cd1a3b1ce45c0f7a715363b0c7d36c76c94" +dependencies = [ + "parity-scale-codec", + "scale-info", + "scale-type-resolver", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d78196772d25b90a98046794ce0fe2588b39ebdfbdc1e45b4c6c85dd43bebad" +dependencies = [ + "parity-scale-codec", + "primitive-types 0.13.1", + "scale-bits", + "scale-decode-derive", + "scale-type-resolver", + "smallvec", + "thiserror 2.0.17", +] + +[[package]] +name = "scale-decode-derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4b54a1211260718b92832b661025d1f1a4b6930fbadd6908e00edd265fa5f7" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "scale-encode" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64901733157f9d25ef86843bd783eda439fac7efb0ad5a615d12d2cf3a29464b" +dependencies = [ + "parity-scale-codec", + "primitive-types 0.13.1", + "scale-bits", + "scale-encode-derive", + "scale-type-resolver", + "smallvec", + "thiserror 2.0.17", +] + +[[package]] +name = "scale-encode-derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78a3993a13b4eafa89350604672c8757b7ea84c7c5947d4b3691e3169c96379b" +dependencies = [ + "darling 0.20.11", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "scale-info" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" +dependencies = [ + "bitvec", + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec", + "scale-info-derive", + "serde", +] + +[[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", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" +dependencies = [ + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-typegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c61b6b706a3eaad63b506ab50a1d2319f817ae01cf753adcc3f055f9f0fcd6" +dependencies = [ + "proc-macro2", + "quote", + "scale-info", + "syn 2.0.106", + "thiserror 2.0.17", +] + +[[package]] +name = "scale-value" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884aab179aba344c67ddcd1d7dd8e3f8fee202f2e570d97ec34ec8688442a5b3" +dependencies = [ + "base58", + "blake2 0.10.6", + "either", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-type-resolver", + "serde", + "thiserror 2.0.17", + "yap", +] + [[package]] name = "schannel" version = "0.1.27" @@ -7915,6 +8609,25 @@ dependencies = [ "serde_json", ] +[[package]] +name = "schnorrkel" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9fcb6c2e176e86ec703e22560d99d65a5ee9056ae45a08e13e84ebf796296f" +dependencies = [ + "aead", + "arrayref", + "arrayvec 0.7.6", + "curve25519-dalek", + "getrandom_or_panic", + "merlin", + "rand_core 0.6.4", + "serde_bytes", + "sha2 0.10.9", + "subtle", + "zeroize", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -7929,7 +8642,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ "pbkdf2", "salsa20", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -8293,19 +9006,32 @@ checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" -version = "0.10.9" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest 0.9.0", + "opaque-debug", ] [[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.7", @@ -8428,6 +9154,12 @@ dependencies = [ "time", ] +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.11" @@ -8449,6 +9181,113 @@ dependencies = [ "serde", ] +[[package]] +name = "smol" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" +dependencies = [ + "async-channel 2.5.0", + "async-executor", + "async-fs", + "async-io 2.5.0", + "async-lock 3.4.1", + "async-net", + "async-process", + "blocking", + "futures-lite 2.6.1", +] + +[[package]] +name = "smoldot" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16e5723359f0048bf64bfdfba64e5732a56847d42c4fd3fe56f18280c813413" +dependencies = [ + "arrayvec 0.7.6", + "async-lock 3.4.1", + "atomic-take", + "base64 0.22.1", + "bip39", + "blake2-rfc", + "bs58", + "chacha20", + "crossbeam-queue", + "derive_more 2.0.1", + "ed25519-zebra", + "either", + "event-listener 5.4.1", + "fnv", + "futures-lite 2.6.1", + "futures-util", + "hashbrown 0.15.5", + "hex", + "hmac 0.12.1", + "itertools 0.14.0", + "libm", + "libsecp256k1", + "merlin", + "nom 8.0.0", + "num-bigint", + "num-rational", + "num-traits", + "pbkdf2", + "pin-project", + "poly1305", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd", + "schnorrkel", + "serde", + "serde_json", + "sha2 0.10.9", + "sha3", + "siphasher", + "slab", + "smallvec", + "soketto", + "twox-hash 2.1.2", + "wasmi", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "smoldot-light" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bba9e591716567d704a8252feeb2f1261a286e1e2cbdd4e49e9197c34a14e2" +dependencies = [ + "async-channel 2.5.0", + "async-lock 3.4.1", + "base64 0.22.1", + "blake2-rfc", + "bs58", + "derive_more 2.0.1", + "either", + "event-listener 5.4.1", + "fnv", + "futures-channel", + "futures-lite 2.6.1", + "futures-util", + "hashbrown 0.15.5", + "hex", + "itertools 0.14.0", + "log", + "lru 0.12.5", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "serde_json", + "siphasher", + "slab", + "smol", + "smoldot", + "zeroize", +] + [[package]] name = "snap" version = "1.1.1" @@ -8485,6 +9324,35 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "soketto" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha1", +] + +[[package]] +name = "sp-crypto-hashing" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9927a7f81334ed5b8a98a4a978c81324d12bd9713ec76b5c68fd410174c5eb" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.9", + "sha3", + "twox-hash 1.6.3", +] + [[package]] name = "spin" version = "0.5.2" @@ -8565,7 +9433,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror 2.0.17", "tokio", @@ -8602,7 +9470,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", @@ -8634,7 +9502,7 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "itoa", "log", "md-5", @@ -8645,7 +9513,7 @@ dependencies = [ "rsa", "serde", "sha1", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -8672,7 +9540,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "home", "itoa", "log", @@ -8682,7 +9550,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -8796,6 +9664,174 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "subxt" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddbf938ac1d86a361a84709a71cdbae5d87f370770b563651d1ec052eed9d0b4" +dependencies = [ + "async-trait", + "derive-where", + "either", + "frame-metadata", + "futures", + "hex", + "jsonrpsee", + "parity-scale-codec", + "primitive-types 0.13.1", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing", + "subxt-core", + "subxt-lightclient", + "subxt-macro", + "subxt-metadata", + "subxt-rpcs", + "thiserror 2.0.17", + "tokio", + "tokio-util", + "tracing", + "url", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "subxt-codegen" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c250ad8cd102d40ae47977b03295a2ff791375f30ddc7474d399fb56efb793b" +dependencies = [ + "heck 0.5.0", + "parity-scale-codec", + "proc-macro2", + "quote", + "scale-info", + "scale-typegen", + "subxt-metadata", + "syn 2.0.106", + "thiserror 2.0.17", +] + +[[package]] +name = "subxt-core" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5705c5b420294524e41349bf23c6b11aa474ce731de7317f4153390e1927f702" +dependencies = [ + "base58", + "blake2 0.10.6", + "derive-where", + "frame-decode", + "frame-metadata", + "hashbrown 0.14.5", + "hex", + "impl-serde", + "keccak-hash", + "parity-scale-codec", + "primitive-types 0.13.1", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-crypto-hashing", + "subxt-metadata", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "subxt-lightclient" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e02732a6c9ae46bc282c1a741b3d3e494021b3e87e7e92cfb3620116d92911" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "subxt-macro" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501bf358698f5ab02a6199a1fcd3f1b482e2f5b6eb5d185411e6a74a175ec8e8" +dependencies = [ + "darling 0.20.11", + "parity-scale-codec", + "proc-macro-error2", + "quote", + "scale-typegen", + "subxt-codegen", + "subxt-metadata", + "subxt-utils-fetchmetadata", + "syn 2.0.106", +] + +[[package]] +name = "subxt-metadata" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fb7c0bfafad78dda7084c6a2444444744af3bbf7b2502399198b9b4c20eddf" +dependencies = [ + "frame-decode", + "frame-metadata", + "hashbrown 0.14.5", + "parity-scale-codec", + "scale-info", + "sp-crypto-hashing", + "thiserror 2.0.17", +] + +[[package]] +name = "subxt-rpcs" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab68a9c20ecedb0cb7d62d64f884e6add91bb70485783bf40aa8eac5c389c6e0" +dependencies = [ + "derive-where", + "frame-metadata", + "futures", + "hex", + "impl-serde", + "jsonrpsee", + "parity-scale-codec", + "primitive-types 0.13.1", + "serde", + "serde_json", + "subxt-core", + "subxt-lightclient", + "thiserror 2.0.17", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "subxt-utils-fetchmetadata" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e450f6812a653c5a3e63a079aa3b60a3f4c362722753c3222286eaa1800f9002" +dependencies = [ + "hex", + "parity-scale-codec", + "thiserror 2.0.17", +] + [[package]] name = "supports-color" version = "3.0.2" @@ -9284,6 +10320,7 @@ checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -9601,10 +10638,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", + "digest 0.10.7", "rand 0.8.5", "static_assertions", ] +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + [[package]] name = "typeid" version = "1.0.3" @@ -9659,6 +10703,18 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unarray" version = "0.1.4" @@ -9691,9 +10747,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -9737,6 +10793,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -10081,6 +11147,56 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmi" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19af97fcb96045dd1d6b4d23e2b4abdbbe81723dbc5c9f016eb52145b320063" +dependencies = [ + "arrayvec 0.7.6", + "multi-stash", + "smallvec", + "spin 0.9.8", + "wasmi_collections", + "wasmi_core", + "wasmi_ir", + "wasmparser 0.221.3", +] + +[[package]] +name = "wasmi_collections" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e80d6b275b1c922021939d561574bf376613493ae2b61c6963b15db0e8813562" + +[[package]] +name = "wasmi_core" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8c51482cc32d31c2c7ff211cd2bedd73c5bd057ba16a2ed0110e7a96097c33" +dependencies = [ + "downcast-rs", + "libm", +] + +[[package]] +name = "wasmi_ir" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e431a14c186db59212a88516788bd68ed51f87aa1e08d1df742522867b5289a" +dependencies = [ + "wasmi_core", +] + +[[package]] +name = "wasmparser" +version = "0.221.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185" +dependencies = [ + "bitflags 2.9.3", +] + [[package]] name = "wasmparser" version = "0.224.1" @@ -10197,7 +11313,7 @@ dependencies = [ "rustix 0.38.44", "serde", "serde_derive", - "sha2", + "sha2 0.10.9", "toml 0.8.23", "windows-sys 0.59.0", "zstd", @@ -10446,6 +11562,24 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "webpki-root-certs" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.3", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" @@ -10586,7 +11720,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -10619,13 +11753,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -10636,7 +11776,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -10645,7 +11785,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -10684,6 +11833,30 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -10721,7 +11894,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -10732,6 +11905,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -10750,6 +11929,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -10768,6 +11953,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -10798,6 +11989,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -10816,6 +12013,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -10834,6 +12037,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -10852,6 +12061,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -10972,6 +12187,18 @@ dependencies = [ "tap", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + [[package]] name = "x509-cert" version = "0.2.5" @@ -11031,6 +12258,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yap" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe269e7b803a5e8e20cbd97860e136529cd83bf2c9c6d37b142467e7e1f051f" + [[package]] name = "yoke" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index f4a61e1f..d60a1fdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ mithril = ["mithril-client"] hydra = ["tungstenite", "tokio-tungstenite", "futures-util", "bytes"] eth = ["futures-util", "alloy"] btc = ["bitcoind-async-client", "corepc-types"] +substrate = ["futures-util", "subxt"] # elasticsearch = auto feature flag # kafka = auto feature flag @@ -87,6 +88,7 @@ zmq = { version = "0.10.0", optional = true } bitcoind-async-client = { version = "0.6.0", optional = true } corepc-types = { version = "0.10.1", optional = true } alloy = { version = "1.0.38", features = ["provider-ws"], optional = true } +subxt = { version = "0.44.0", optional = true } [dev-dependencies] goldenfile = "1.7.3" diff --git a/README.md b/README.md index a1c4b52e..bcbc1093 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,8 @@ The data pipeline is implemented by the [Gasket](https://github.com/construkts/g You can run: - `oura watch cardano ` to print Cardano transaction data into the terminal from the tip of a local or remote node - `oura watch bitcoin ` to watch Bitcoin blockchain events -- `oura watch ethereum ` to watch Ethereum blockchain events via WebSocket. +- `oura watch ethereum ` to watch Ethereum blockchain events via WebSocket +- `oura watch substrate ` to watch Substrate blockchain events from any Substrate-based network These commands are useful as debugging tools for developers or if you're just curious to see what's going on in the network (for example, to see airdrops as they happen or oracles posting new information). diff --git a/docs/v3/index.mdx b/docs/v3/index.mdx index 671d5a2e..762855b0 100644 --- a/docs/v3/index.mdx +++ b/docs/v3/index.mdx @@ -27,7 +27,8 @@ The data pipeline makes heavy use (maybe a bit too much) of multi-threading and You can run: - `oura watch cardano ` to print Cardano transaction data into the terminal from the tip of a local or remote node - `oura watch bitcoin ` to watch Bitcoin blockchain events -- `oura watch ethereum ` to watch Ethereum blockchain events via WebSocket. +- `oura watch ethereum ` to watch Ethereum blockchain events via WebSocket +- `oura watch substrate ` to watch Substrate blockchain events from any Substrate-based network These commands are useful as debugging tools for developers or if you're just curious to see what's going on in the network (for example, to see airdrops as they happen or oracles posting new information). diff --git a/docs/v3/sources/substrate.mdx b/docs/v3/sources/substrate.mdx new file mode 100644 index 00000000..f1f89e9b --- /dev/null +++ b/docs/v3/sources/substrate.mdx @@ -0,0 +1,163 @@ +--- +title: Substrate RPC +--- + +The Substrate RPC source connects to a Substrate-based blockchain node via WebSocket RPC to subscribe to new blocks and retrieve complete block data. It works with any Substrate-based network including Polkadot, Kusama, and parachains. + +## Configuration + +The following snippet shows an example of how to set up a Substrate WebSocket source: + +```toml +[source] +type = "substrate-rpc" +url = "ws://localhost:9944" +``` + +### Section `source`: + +- `type`: this field must be set to the literal value `substrate-rpc`. +- `url`: the WebSocket URL of the Substrate RPC endpoint (required). Must use `ws://` or `wss://` protocol. + +## Supported Networks + +The Substrate source works with any Substrate-based blockchain, including: + +- **Polkadot** - The main relay chain +- **Kusama** - Polkadot's canary network +- **Westend** - Polkadot's testnet +- **Parachains** - Any parachain connected to Polkadot or Kusama +- **Solo chains** - Independent Substrate-based blockchains +- **Local development nodes** - For testing and development + +## Examples + +### Local Substrate Node + +```toml +[source] +type = "substrate-rpc" +url = "ws://localhost:9944" +``` + +### Polkadot Mainnet via OnFinality + +```toml +[source] +type = "substrate-rpc" +url = "wss://polkadot.api.onfinality.io/public-ws" +``` + +### Kusama Network + +```toml +[source] +type = "substrate-rpc" +url = "wss://kusama-rpc.polkadot.io" +``` + +### Westend Testnet + +```toml +[source] +type = "substrate-rpc" +url = "wss://westend-rpc.polkadot.io" +``` + +### Astar Parachain + +```toml +[source] +type = "substrate-rpc" +url = "wss://rpc.astar.network" +``` + +## How It Works + +The Substrate source operates using Subxt library for Substrate interaction: + +1. **Connection**: Connects to the Substrate node via WebSocket using the Subxt client. + +2. **Subscription**: Subscribes to the best block stream to receive notifications when new blocks are finalized. + +3. **Block Processing**: For each new block: + - Retrieves the complete block header information + - Parses all extrinsics (transactions) in the block + - Extracts signature information for signed extrinsics + - Calculates block and extrinsic hashes + +4. **Event Generation**: Converts the block data into Oura's internal `ChainEvent::Apply` format for processing by filters and sinks. + +## Output Events + +The Substrate source produces `ChainEvent::Apply` events containing parsed Substrate block data. Each event includes: + +### Block Header +- Block number and hash +- Parent block hash +- State root and extrinsics root +- Block timestamp and other metadata + +### Extrinsics +For each extrinsic in the block: +- Extrinsic index and hash +- Raw bytes (hex-encoded) +- Signature information (for signed extrinsics): + - Signer address + - Signature data + - Signed extensions metadata + +### Additional Information +- Total extrinsics count +- Block processing metrics +- Chain tip information + +## Data Structure + +The parsed block follows this structure: + +```rust +ParsedBlock { + header: BlockHeader { + number: u64, + hash: String, + parent_hash: String, + state_root: String, + extrinsics_root: String, + }, + extrinsics: Vec, + extrinsics_count: usize, +} + +Extrinsic { + index: u32, + hash: String, + bytes: Option, + signature: Option, +} + +SignatureInfo { + address: String, + signature: String, + extra: Option, +} +``` + +## Substrate Runtime Compatibility + +The source is designed to work with any Substrate runtime without requiring specific runtime metadata knowledge. It focuses on the core block structure that is consistent across all Substrate chains: + +- Block headers follow the standard Substrate format +- Extrinsics use the SCALE codec for encoding +- Signature extraction works with standard Substrate transaction formats + +This makes the source compatible with both current and future Substrate networks without requiring updates for new runtime versions. + +## Performance Considerations + +- The source subscribes to the best blocks only, ensuring reliable block ordering +- Block processing is done asynchronously to maintain good throughput +- Extrinsic parsing includes detailed signature extraction which may add some processing overhead +- WebSocket connections are automatically managed and reconnected if needed + +The events follow the same pattern as other Oura sources, allowing them to be processed by standard filters and sinks in the pipeline. \ No newline at end of file diff --git a/docs/v3/usage/watch.mdx b/docs/v3/usage/watch.mdx index 15989d69..dc5a4905 100644 --- a/docs/v3/usage/watch.mdx +++ b/docs/v3/usage/watch.mdx @@ -2,7 +2,7 @@ title: Watch --- -The `watch` mode provides a quick way to tail the latest events from blockchain networks. It supports Cardano, Bitcoin, and Ethereum blockchains, each with their own subcommands and connection methods. +The `watch` mode provides a quick way to tail the latest events from blockchain networks. It supports Cardano, Bitcoin, Ethereum, and Substrate blockchains, each with their own subcommands and connection methods. The output is colorized by type of event and dynamically truncated to fit the width of the terminal. The speed of the output lines is throttled to facilitate visual inspection of each event, otherwise, all events for a block would be output simultaneously. @@ -61,6 +61,21 @@ oura watch ethereum [OPTIONS] - `--throttle`: milliseconds to wait between output lines (for easier reading). - `--wrap`: indicates that long output text should break and continue in the following line. +### Substrate + +To watch Substrate blockchain events: + +``` +oura watch substrate [OPTIONS] +``` + +- ``: the Substrate WebSocket RPC URL to connect to. + +#### Substrate Options + +- `--throttle`: milliseconds to wait between output lines (for easier reading). +- `--wrap`: indicates that long output text should break and continue in the following line. + ## Examples ### Cardano Examples @@ -148,3 +163,35 @@ oura watch ethereum ws://localhost:8546 --throttle 1000 --wrap ```sh oura watch ethereum wss://ethereum-sepolia-rpc.publicnode.com ``` + +### Substrate Examples + +#### Watch Live Data From A Local Polkadot Node + +```sh +oura watch substrate ws://localhost:9944 +``` + +#### Watch Polkadot Mainnet via OnFinality + +```sh +oura watch substrate wss://polkadot.api.onfinality.io/public-ws +``` + +#### Watch Substrate With Output Throttling + +```sh +oura watch substrate ws://localhost:9944 --throttle 1000 --wrap +``` + +#### Watch Kusama Network + +```sh +oura watch substrate wss://kusama-rpc.polkadot.io +``` + +#### Watch Westend Testnet + +```sh +oura watch substrate wss://westend-rpc.polkadot.io +``` diff --git a/examples/substrate/daemon.toml b/examples/substrate/daemon.toml new file mode 100644 index 00000000..9ed9826b --- /dev/null +++ b/examples/substrate/daemon.toml @@ -0,0 +1,15 @@ +[source] +type = "substrate-rpc" +url = "wss://polkadot-rpc.publicnode.com" + +[intersect] +type = "Tip" + +[sink] +# type = "Stdout" +type = "FileRotate" +output_path = "/tmp/oura-substrate/mainnet" +output_format = "JSONL" +max_bytes_per_file = 1_000_000 +max_total_files = 10 +compress_files = false diff --git a/src/bin/oura/watch.rs b/src/bin/oura/watch.rs index 642ec74a..26c9c15c 100644 --- a/src/bin/oura/watch.rs +++ b/src/bin/oura/watch.rs @@ -6,6 +6,9 @@ use oura::watch::btc; #[cfg(feature = "eth")] use oura::watch::eth; +#[cfg(feature = "substrate")] +use oura::watch::substrate; + use clap::{Parser, Subcommand}; use oura::framework::Error; @@ -18,6 +21,9 @@ pub fn run(args: &Args) -> Result<(), Error> { #[cfg(feature = "eth")] WatchCommand::Ethereum(eth_args) => eth::run(eth_args), + + #[cfg(feature = "substrate")] + WatchCommand::Substrate(substrate_args) => substrate::run(substrate_args), } } @@ -40,4 +46,8 @@ pub enum WatchCommand { /// Watch Ethereum blockchain #[cfg(feature = "eth")] Ethereum(eth::Args), + + /// Watch Substrate blockchain + #[cfg(feature = "substrate")] + Substrate(substrate::Args), } diff --git a/src/framework/mod.rs b/src/framework/mod.rs index 0dc5b5ca..0b4db041 100644 --- a/src/framework/mod.rs +++ b/src/framework/mod.rs @@ -23,6 +23,8 @@ pub mod bitcoin; #[cfg(feature = "eth")] pub mod ethereum; + +#[cfg(feature = "substrate")] pub mod substrate; pub mod errors; @@ -93,6 +95,8 @@ pub enum Record { #[cfg(feature = "btc")] Bitcoin(bitcoin::Record), + + #[cfg(feature = "substrate")] Substrate(substrate::Record), } impl From for JsonValue { @@ -104,6 +108,7 @@ impl From for JsonValue { Record::Ethereum(record) => record.into(), #[cfg(feature = "btc")] Record::Bitcoin(record) => record.into(), + #[cfg(feature = "substrate")] Record::Substrate(record) => record.into(), } } diff --git a/src/framework/substrate/mod.rs b/src/framework/substrate/mod.rs index e9a52c43..1009dc26 100644 --- a/src/framework/substrate/mod.rs +++ b/src/framework/substrate/mod.rs @@ -1,17 +1,75 @@ +use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; +/// Serializable representation of a Substrate block header +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BlockHeader { + pub number: u64, + pub hash: String, + pub parent_hash: String, + pub state_root: String, + pub extrinsics_root: String, +} + +/// Signature information for signed extrinsics +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignatureInfo { + pub address: String, + pub signature: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub extra: Option, +} + +/// Call information +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CallInfo { + pub pallet_name: String, + pub function_name: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub args: Option, +} + +/// Events emitted by the extrinsic +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ExtrinsicEvent { + pub pallet_name: String, + pub event_name: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub fields: Option, +} + +/// Serializable representation of a Substrate extrinsic +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Extrinsic { + pub index: u32, + pub hash: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub bytes: Option, + + // Signature information + #[serde(skip_serializing_if = "Option::is_none")] + pub signature: Option, +} + +/// Serializable representation of a complete Substrate block +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ParsedBlock { + pub header: BlockHeader, + pub extrinsics: Vec, + pub extrinsics_count: usize, +} + #[derive(Debug, Clone)] pub enum Record { - /// Scaffold placeholder for now - ParsedBlock(()), + ParsedBlock(Box), RawBlock(Vec), } impl From for JsonValue { fn from(value: Record) -> Self { match value { - Record::ParsedBlock(x) => json!(x), - Record::RawBlock(x) => json!({ "hex": hex::encode(x) }), + Record::ParsedBlock(block) => json!(block), + Record::RawBlock(bytes) => json!({ "hex": hex::encode(bytes) }), } } } diff --git a/src/sinks/terminal/format.rs b/src/sinks/terminal/format.rs index ddfaa874..2f06f12f 100644 --- a/src/sinks/terminal/format.rs +++ b/src/sinks/terminal/format.rs @@ -158,7 +158,33 @@ impl LogLine { log } }, - Record::Substrate(_record) => todo!(), + #[cfg(feature = "substrate")] + Record::Substrate(record) => match record { + substrate::Record::ParsedBlock(block) => { + let mut log = LogLine::new("BLOCK", Color::Magenta); + log.max_width = max_width; + + let height = block.header.number; + let hash = block.header.hash.clone(); + let tx_count = block.extrinsics_count; + + log.content = format!( + "{{ height: {}, hash: {}, tx_count: {} }}", + height, + hash, + tx_count, + ); + log.block_num = Some(height as u64); + + log + } + _ => { + let mut log = LogLine::new("RECORD", Color::Magenta); + log.max_width = max_width; + log.content = "Other Bitcoin record type".to_string(); + log + } + }, Record::GenericJson(_json) => { todo!("GenericJson not implemented yet") } diff --git a/src/sources/mod.rs b/src/sources/mod.rs index 3d477b97..e1a100b6 100644 --- a/src/sources/mod.rs +++ b/src/sources/mod.rs @@ -15,6 +15,9 @@ pub mod eth; #[cfg(feature = "btc")] pub mod btc; +#[cfg(feature = "substrate")] +pub mod substrate; + #[cfg(feature = "hydra")] pub mod hydra; @@ -39,6 +42,9 @@ pub enum Bootstrapper { #[cfg(feature = "btc")] BitcoinRpc(btc::Stage), + #[cfg(feature = "substrate")] + SubstrateRpc(substrate::Stage), + #[cfg(feature = "hydra")] Hydra(hydra::Stage), @@ -66,6 +72,9 @@ impl Bootstrapper { #[cfg(feature = "btc")] Bootstrapper::BitcoinRpc(p) => &mut p.output, + #[cfg(feature = "substrate")] + Bootstrapper::SubstrateRpc(p) => &mut p.output, + #[cfg(feature = "hydra")] Bootstrapper::Hydra(p) => &mut p.output, @@ -93,6 +102,9 @@ impl Bootstrapper { #[cfg(feature = "btc")] Bootstrapper::BitcoinRpc(x) => gasket::runtime::spawn_stage(x, policy), + #[cfg(feature = "substrate")] + Bootstrapper::SubstrateRpc(x) => gasket::runtime::spawn_stage(x, policy), + #[cfg(feature = "hydra")] Bootstrapper::Hydra(x) => gasket::runtime::spawn_stage(x, policy), @@ -124,6 +136,10 @@ pub enum Config { #[serde(rename = "bitcoin-rpc")] BitcoinRpc(btc::Config), + #[cfg(feature = "substrate")] + #[serde(rename = "substrate-rpc")] + SubstrateRpc(substrate::Config), + #[cfg(feature = "hydra")] Hydra(hydra::Config), @@ -151,6 +167,9 @@ impl Config { #[cfg(feature = "btc")] Config::BitcoinRpc(c) => Ok(Bootstrapper::BitcoinRpc(c.bootstrapper(ctx)?)), + #[cfg(feature = "substrate")] + Config::SubstrateRpc(c) => Ok(Bootstrapper::SubstrateRpc(c.bootstrapper(ctx)?)), + #[cfg(feature = "hydra")] Config::Hydra(c) => Ok(Bootstrapper::Hydra(c.bootstrapper(ctx)?)), diff --git a/src/sources/substrate.rs b/src/sources/substrate.rs new file mode 100644 index 00000000..56d261b0 --- /dev/null +++ b/src/sources/substrate.rs @@ -0,0 +1,166 @@ +use std::time::Duration; +use tokio::time::sleep; +use gasket::framework::*; +use serde::Deserialize; +use tracing::{debug, info}; + +use subxt::{backend::StreamOf, blocks::Block, OnlineClient, SubstrateConfig}; + +use crate::framework::*; + +type SubxtBlock = Block>; + +pub struct Worker { + #[allow(dead_code)] + api: OnlineClient, + subscription: StreamOf>, +} + +#[async_trait::async_trait(?Send)] +impl gasket::framework::Worker for Worker { + async fn bootstrap(stage: &Stage) -> Result { + debug!("connecting"); + + let api = OnlineClient::::from_url(&stage.config.url).await.map_err(|e| { + debug!("Failed to connect to Substrate node: {}", e); + WorkerError::Panic + })?; + + let subscription = api.blocks().subscribe_best().await.map_err(|e| { + debug!("Failed to subscribe to new blocks: {}", e); + WorkerError::Panic + })?; + + Ok(Self { api, subscription }) + } + + async fn schedule(&mut self, _: &mut Stage) -> Result, WorkerError> { + info!("awaiting next block (blocking)"); + + if let Some(Ok(block)) = self.subscription.next().await { + debug!("new block received: {:?}", block.hash()); + return Ok(WorkSchedule::Unit(block)); + } + + sleep(Duration::from_secs(5)).await; + + Ok(WorkSchedule::Idle) + } + + async fn execute(&mut self, block: &SubxtBlock, stage: &mut Stage) -> Result<(), WorkerError> { + debug!("processing substrate block"); + + let block_number = block.number().into(); + let block_hash = block.hash(); + + info!("new block #{}: {:?}", block_number, block_hash); + + // Extract header information + let header = block.header(); + let parent_hash = header.parent_hash; + let state_root = header.state_root; + let extrinsics_root = header.extrinsics_root; + + // Parse extrinsics with detailed information + let extrinsics_result = block.extrinsics().await.or_retry()?; + let mut parsed_extrinsics = Vec::new(); + + for (index, extrinsic) in extrinsics_result.iter().enumerate() { + let ext_hash = format!("{:?}", extrinsic.hash()); + let ext_bytes = extrinsic.bytes(); + + // Extract signature info (if signed) + let signature_info = match (extrinsic.address_bytes(), extrinsic.signature_bytes()) { + (Some(addr), Some(sig)) => { + let address = hex::encode(addr); + let signature = hex::encode(sig); + + Some(substrate::SignatureInfo { + address, + signature, + extra: None, // Could be enhanced to parse signed extensions + }) + } + _ => None, + }; + + parsed_extrinsics.push(substrate::Extrinsic { + index: index as u32, + hash: ext_hash, + bytes: Some(hex::encode(ext_bytes)), + signature: signature_info, + }); + } + + let extrinsics_count = parsed_extrinsics.len(); + + // Create the parsed block structure + let parsed_block = substrate::ParsedBlock { + header: substrate::BlockHeader { + number: block_number, + hash: format!("{:?}", block_hash), + parent_hash: format!("{:?}", parent_hash), + state_root: format!("{:?}", state_root), + extrinsics_root: format!("{:?}", extrinsics_root), + }, + extrinsics: parsed_extrinsics, + extrinsics_count, + }; + + info!("block #{} parsed with {} extrinsics", block_number, extrinsics_count); + + // Create the point for this block + let point = pallas::network::miniprotocols::Point::Specific( + block_number, + block_hash.0.to_vec(), + ); + + // Create and send the chain event + let event = ChainEvent::Apply( + point, + Record::Substrate(substrate::Record::ParsedBlock(Box::new(parsed_block))), + ); + + stage.output.send(event.into()).await.or_panic()?; + stage.ops_count.inc(1); + stage.chain_tip.set(block_number as i64); + + Ok(()) + } +} + +#[derive(Stage)] +#[stage(name = "source", unit = "SubxtBlock", worker = "Worker")] +pub struct Stage { + config: Config, + + pub output: SourceOutputPort, + + #[metric] + ops_count: gasket::metrics::Counter, + + #[metric] + chain_tip: gasket::metrics::Gauge, + + #[metric] + current_slot: gasket::metrics::Gauge, +} + +#[derive(Deserialize)] +pub struct Config { + pub url: String, +} + +impl Config { + pub fn bootstrapper(self, _ctx: &Context) -> Result { + let stage = Stage { + config: self, + output: Default::default(), + ops_count: Default::default(), + chain_tip: Default::default(), + current_slot: Default::default(), + }; + + Ok(stage) + } +} diff --git a/src/watch/mod.rs b/src/watch/mod.rs index 622f811c..471fa13b 100644 --- a/src/watch/mod.rs +++ b/src/watch/mod.rs @@ -4,4 +4,7 @@ pub mod cardano; pub mod btc; #[cfg(feature = "eth")] -pub mod eth; \ No newline at end of file +pub mod eth; + +#[cfg(feature = "substrate")] +pub mod substrate; \ No newline at end of file diff --git a/src/watch/substrate.rs b/src/watch/substrate.rs new file mode 100644 index 00000000..6efb5226 --- /dev/null +++ b/src/watch/substrate.rs @@ -0,0 +1,67 @@ +use clap::Parser; +use tracing::{info, Level}; +use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; + +use crate::{ + daemon::{run_daemon, ConfigRoot}, + framework::{Error, IntersectConfig}, + sinks, sources, +}; + +pub fn run(args: &Args) -> Result<(), Error> { + let env_filter = EnvFilter::builder() + .with_default_directive(Level::INFO.into()) + .with_env_var("RUST_LOG") + .from_env_lossy(); + + tracing_subscriber::registry() + .with(fmt::layer()) + .with(env_filter) + .init(); + + let source = sources::Config::SubstrateRpc(sources::substrate::Config { + url: args.url.clone(), + }); + + let sink = sinks::Config::Terminal(sinks::terminal::Config { + throttle_min_span_millis: args.throttle, + wrap: Some(args.wrap), + adahandle_policy: Default::default(), + }); + + let config = ConfigRoot { + source, + filters: None, + sink, + intersect: IntersectConfig::Tip, + finalize: None, + chain: None, + retries: None, + cursor: None, + metrics: None, + }; + + let daemon = run_daemon(config)?; + + daemon.block(); + + info!("oura is stopping"); + + daemon.teardown(); + + Ok(()) +} + +#[derive(Parser, Clone)] +pub struct Args { + /// Substrate WS RPC url + url: String, + + /// milliseconds to wait between output lines (for easier reading) + #[arg(long)] + throttle: Option, + + /// wrap output lines + #[arg(short, long, default_value_t = false)] + wrap: bool, +} \ No newline at end of file