diff --git a/Cargo.lock b/Cargo.lock index 4120fcd..33d4c1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,6 +441,12 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -1374,6 +1380,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1413,6 +1429,12 @@ dependencies = [ "wide", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "feature-probe" version = "0.1.1" @@ -1672,7 +1694,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -1740,6 +1781,15 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + [[package]] name = "hex-conservative" version = "0.2.1" @@ -1796,6 +1846,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1803,7 +1864,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", "pin-project-lite", ] @@ -1835,9 +1919,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1849,6 +1933,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.10", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1856,11 +1960,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" +dependencies = [ + "http 1.3.1", + "hyper 1.6.0", + "hyper-util", + "rustls 0.23.27", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.2", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.6.0", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration 0.6.1", + "tokio", + "tower-service", + "tracing", + "windows-registry", ] [[package]] @@ -2038,6 +2200,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -2194,6 +2366,12 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "litemap" version = "0.8.0" @@ -2300,6 +2478,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nix" version = "0.29.0" @@ -2727,6 +2922,8 @@ dependencies = [ "anyhow", "borsh 0.9.3", "clap", + "hex", + "reqwest 0.12.19", "secp256k1", "serde", "sha3", @@ -3014,11 +3211,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -3032,10 +3229,10 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -3046,6 +3243,48 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "h2 0.4.10", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls 0.27.6", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "reqwest-middleware" version = "0.2.5" @@ -3054,8 +3293,8 @@ checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" dependencies = [ "anyhow", "async-trait", - "http", - "reqwest", + "http 0.2.12", + "reqwest 0.11.27", "serde", "task-local-extensions", "thiserror 1.0.69", @@ -3105,6 +3344,19 @@ dependencies = [ "nom", ] +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rustls" version = "0.21.12" @@ -3140,7 +3392,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.2.0", ] [[package]] @@ -3177,7 +3429,7 @@ dependencies = [ "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki 0.103.3", - "security-framework", + "security-framework 3.2.0", "security-framework-sys", "webpki-root-certs 0.26.11", "windows-sys 0.59.0", @@ -3309,6 +3561,19 @@ dependencies = [ "cc", ] +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.2.0" @@ -4370,7 +4635,7 @@ dependencies = [ "gethostname", "lazy_static", "log", - "reqwest", + "reqwest 0.11.27", "solana-clock", "solana-cluster-type", "solana-sha256-hasher", @@ -4760,7 +5025,7 @@ dependencies = [ "crossbeam-channel", "futures-util", "log", - "reqwest", + "reqwest 0.11.27", "semver", "serde", "serde_derive", @@ -4902,7 +5167,7 @@ dependencies = [ "bs58", "indicatif", "log", - "reqwest", + "reqwest 0.11.27", "reqwest-middleware", "semver", "serde", @@ -4938,7 +5203,7 @@ dependencies = [ "base64 0.22.1", "bs58", "jsonrpc-core", - "reqwest", + "reqwest 0.11.27", "reqwest-middleware", "semver", "serde", @@ -6072,6 +6337,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -6103,7 +6377,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "system-configuration-sys 0.6.0", ] [[package]] @@ -6116,6 +6401,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "task-local-extensions" version = "0.1.4" @@ -6125,6 +6420,19 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -6259,6 +6567,16 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -6269,6 +6587,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls 0.23.27", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.17" @@ -6290,7 +6618,7 @@ dependencies = [ "log", "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tungstenite", "webpki-roots 0.25.4", ] @@ -6334,6 +6662,45 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.1", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -6387,7 +6754,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand 0.8.5", @@ -6726,7 +7093,7 @@ dependencies = [ "windows-interface", "windows-link", "windows-result", - "windows-strings", + "windows-strings 0.4.2", ] [[package]] @@ -6757,6 +7124,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result", + "windows-strings 0.3.1", + "windows-targets 0.53.0", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -6766,6 +7144,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -6850,13 +7237,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -6875,6 +7278,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +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" @@ -6893,6 +7302,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +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" @@ -6911,12 +7326,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +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" @@ -6935,6 +7362,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +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" @@ -6953,6 +7386,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +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" @@ -6971,6 +7410,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +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" @@ -6989,6 +7434,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.7.10" diff --git a/Cargo.toml b/Cargo.toml index bb5f12e..e12efcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" anyhow = "1.0.98" borsh = "0.9.3" clap = { version = "4.5.39", features = ["derive", "env"] } +hex = { version = "0.4.3", features = ["serde"] } +reqwest = { version = "0.12.19", features = ["json"] } secp256k1 = { version = "0.31.0", features = ["recovery"] } serde = "1.0.219" sha3 = "0.10.8" diff --git a/README.md b/README.md index 12440f9..915500a 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ You can run the project using `cargo run` by passing the required flags: ```bash cargo run -- \ --pythnet-url wss://api2.pythnet.pyth.network \ + --server-url https://watcher.pyth.network \ --secret-key /path/to/secret.key \ - --wormhole-pid H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU \ + --wormhole-pid H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU ``` --- @@ -39,6 +40,7 @@ Instead of CLI flags, you can also set environment variables: ```bash export PYTHNET_URL=wss://api2.pythnet.pyth.network +export SERVER_URL=https://watcher.pyth.network export SECRET_KEY=/path/to/secret.key export WORMHOLE_PID=H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU @@ -49,4 +51,4 @@ cargo run ### 🧪 Testing Locally -To test in a non-production environment (e.g. with devnet or a local Pythnet fork), just provide a different `--pythnet-url` and optionally use custom `--wormhole-pid`. +To test in a non-production environment (e.g. with devnet or a local Pythnet fork), just provide a different `--pythnet-url`, and `--server-url`, and optionally use custom `--wormhole-pid`. diff --git a/src/api_client.rs b/src/api_client.rs new file mode 100644 index 0000000..e8210cc --- /dev/null +++ b/src/api_client.rs @@ -0,0 +1,103 @@ +use { + reqwest::{Client, Url}, + secp256k1::{Message, Secp256k1, SecretKey}, + serde::Serialize, + std::{sync::Arc, time::Duration}, + wormhole_sdk::vaa::Body, +}; + +pub struct ApiClientConfig { + pub timeout: Option, +} + +struct ApiClientInner { + client: Client, + base_url: Url, +} + +#[derive(Clone)] +pub struct ApiClient { + inner: Arc, +} + +const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); + +#[derive(Serialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Observation

{ + pub version: u8, + #[serde(with = "hex::serde")] + pub signature: [u8; 65], + pub body: Body

, +} + +impl Observation

{ + pub fn try_new(body: Body

, secret_key: SecretKey) -> Result { + let digest = body.digest()?; + let signature = Secp256k1::new() + .sign_ecdsa_recoverable(Message::from_digest(digest.secp256k_hash), &secret_key); + let (recovery_id, signature_bytes) = signature.serialize_compact(); + let recovery_id: i32 = recovery_id.into(); + let mut signature = [0u8; 65]; + signature[..64].copy_from_slice(&signature_bytes); + signature[64] = recovery_id as u8; + + Ok(Self { + version: 1, + signature, + body, + }) + } +} + +impl ApiClient { + pub fn try_new( + base_url: String, + config: Option, + ) -> Result { + let base_url = + Url::parse(&base_url).map_err(|e| anyhow::anyhow!("Invalid base URL: {}", e))?; + + let timeout = config.and_then(|c| c.timeout).unwrap_or(DEFAULT_TIMEOUT); + let client = Client::builder() + .timeout(timeout) + .build() + .map_err(|e| anyhow::anyhow!("Failed to create api client: {}", e))?; + + let inner = ApiClientInner { client, base_url }; + Ok(Self { + inner: Arc::new(inner), + }) + } + + pub async fn post_observation( + &self, + observation: Observation

, + ) -> Result<(), anyhow::Error> { + let url = self + .inner + .base_url + .join("observation") + .map_err(|e| anyhow::anyhow!("Failed to construct URL: {}", e))?; + let response = self + .inner + .client + .post(url) + .json(&observation) + .send() + .await + .map_err(|e| anyhow::anyhow!("Failed to post observation: {}", e))?; + + if response.status().is_success() { + Ok(()) + } else { + Err(anyhow::anyhow!( + "Failed to post observation with status: {} - {}", + response.status(), + response + .text() + .await + .unwrap_or_else(|_| String::from("No response text")) + )) + } + } +} diff --git a/src/config.rs b/src/config.rs index 8879c64..beacc98 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,4 +15,6 @@ pub struct RunOptions { default_value = "H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU" )] pub wormhole_pid: String, + #[arg(long = "server-url", env = "SERVER_URL")] + pub server_url: String, } diff --git a/src/main.rs b/src/main.rs index e522c06..d47dbb3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ use { + api_client::{ApiClient, Observation}, borsh::BorshDeserialize, clap::Parser, posted_message::PostedMessageUnreliableData, secp256k1::SecretKey, - signed_body::SignedBody, solana_account_decoder::UiAccountEncoding, solana_client::{ nonblocking::pubsub_client::PubsubClient, @@ -18,15 +18,16 @@ use { wormhole_sdk::{vaa::Body, Address, Chain}, }; +mod api_client; mod config; mod posted_message; -mod signed_body; -struct ListenerConfig { +struct RunListenerInput { ws_url: String, secret_key: SecretKey, wormhole_pid: Pubkey, accumulator_address: Pubkey, + api_client: ApiClient, } fn find_message_pda(wormhole_pid: &Pubkey, slot: u64) -> Pubkey { @@ -38,11 +39,11 @@ fn find_message_pda(wormhole_pid: &Pubkey, slot: u64) -> Pubkey { .0 } -async fn run_listener(config: ListenerConfig) -> Result<(), PubsubClientError> { - let client = PubsubClient::new(config.ws_url.as_str()).await?; +async fn run_listener(input: RunListenerInput) -> Result<(), PubsubClientError> { + let client = PubsubClient::new(input.ws_url.as_str()).await?; let (mut stream, unsubscribe) = client .program_subscribe( - &config.wormhole_pid, + &input.wormhole_pid, Some(RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new( 0, @@ -61,7 +62,7 @@ async fn run_listener(config: ListenerConfig) -> Result<(), PubsubClientError> { .await?; while let Some(update) = stream.next().await { - if find_message_pda(&config.wormhole_pid, update.context.slot).to_string() + if find_message_pda(&input.wormhole_pid, update.context.slot).to_string() != update.value.pubkey { continue; // Skip updates that are not for the expected PDA @@ -88,7 +89,7 @@ async fn run_listener(config: ListenerConfig) -> Result<(), PubsubClientError> { if Chain::Pythnet != unreliable_data.emitter_chain.into() { continue; } - if config.accumulator_address != Pubkey::from(unreliable_data.emitter_address) { + if input.accumulator_address != Pubkey::from(unreliable_data.emitter_address) { continue; } @@ -102,9 +103,20 @@ async fn run_listener(config: ListenerConfig) -> Result<(), PubsubClientError> { payload: unreliable_data.payload.clone(), }; - match SignedBody::try_new(body, config.secret_key) { - Ok(signed_body) => println!("Signed Body: {:?}", signed_body), - Err(e) => tracing::error!(error = ?e, "Failed to sign body"), + match Observation::try_new(body, input.secret_key) { + Ok(observation) => { + tokio::spawn({ + let api_client = input.api_client.clone(); + async move { + if let Err(e) = api_client.post_observation(observation).await { + tracing::error!(error = ?e, "Failed to post observation"); + } else { + tracing::info!("Observation posted successfully"); + } + } + }); + } + Err(e) => tracing::error!(error = ?e, "Failed to create observation"), }; } @@ -141,13 +153,16 @@ async fn main() { .expect("Invalid accumulator address"); let wormhole_pid = Pubkey::from_str(&run_options.wormhole_pid).expect("Invalid Wormhole program ID"); + let api_client = + ApiClient::try_new(run_options.server_url, None).expect("Failed to create API client"); loop { - if let Err(e) = run_listener(ListenerConfig { + if let Err(e) = run_listener(RunListenerInput { ws_url: run_options.pythnet_url.clone(), secret_key, wormhole_pid, accumulator_address, + api_client: api_client.clone(), }) .await { diff --git a/src/signed_body.rs b/src/signed_body.rs deleted file mode 100644 index d51534c..0000000 --- a/src/signed_body.rs +++ /dev/null @@ -1,31 +0,0 @@ -use { - secp256k1::{Message, Secp256k1, SecretKey}, - serde::Serialize, - wormhole_sdk::vaa::Body, -}; - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct SignedBody

{ - pub version: u8, - pub signature: [u8; 65], - pub body: Body

, -} - -impl SignedBody

{ - pub fn try_new(body: Body

, secret_key: SecretKey) -> Result { - let digest = body.digest()?; - let signature = Secp256k1::new() - .sign_ecdsa_recoverable(Message::from_digest(digest.secp256k_hash), &secret_key); - let (recovery_id, signature_bytes) = signature.serialize_compact(); - let recovery_id: i32 = recovery_id.into(); - let mut signature = [0u8; 65]; - signature[..64].copy_from_slice(&signature_bytes); - signature[64] = recovery_id as u8; - - Ok(Self { - version: 1, - signature, - body, - }) - } -}