diff --git a/Cargo.lock b/Cargo.lock index e72c592..cfc8a59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,6 +54,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-feature-set" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe79fc4c114c51ea8461d829bb49853a21a76c7c8ef20e9041b071558f628ce" +dependencies = [ + "ahash", + "solana-epoch-schedule", + "solana-hash 3.1.0", + "solana-pubkey 3.0.0", + "solana-sha256-hasher", + "solana-svm-feature-set 3.1.14", +] + [[package]] name = "agave-feature-set" version = "4.1.2" @@ -66,7 +80,7 @@ dependencies = [ "solana-keypair", "solana-pubkey 4.2.1", "solana-sha256-hasher", - "solana-svm-feature-set", + "solana-svm-feature-set 4.1.2", ] [[package]] @@ -75,7 +89,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea33710f30b13f62e6d73dbbb114117029d29539cb9439c30ef39a0736f935cc" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "solana-pubkey 4.2.1", "solana-sdk-ids", ] @@ -188,6 +202,58 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "anza-quinn" +version = "0.11.9-rustsec20260037" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91bfa08f6e7e4187354ff4f793b81cc08218a6a95cc48f5de7616d44452bf6e0" +dependencies = [ + "anza-quinn-proto", + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.19", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "anza-quinn-proto" +version = "0.11.13-rustsec20260037" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00a4d8cf8d72ee56e0ee20d3b4eef4785ce1b05299c4982c6de7f251c458efe" +dependencies = [ + "bytes", + "fastbloom", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.5", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "slab", + "thiserror 2.0.19", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + [[package]] name = "ark-bn254" version = "0.4.0" @@ -447,6 +513,45 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "async-compression" version = "0.4.43" @@ -459,6 +564,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.91" @@ -488,6 +604,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.22.1" @@ -529,6 +651,9 @@ name = "bitflags" version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +dependencies = [ + "serde_core", +] [[package]] name = "bitvec" @@ -719,6 +844,18 @@ name = "bytes" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +dependencies = [ + "serde", +] + +[[package]] +name = "caps" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ddba47aba30b6a889298ad0109c3b8dcb0e8fc993b459daa7067d46f865e0" +dependencies = [ + "libc", +] [[package]] name = "cc" @@ -732,6 +869,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" @@ -841,6 +984,16 @@ dependencies = [ "unreachable", ] +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compression-codecs" version = "0.4.38" @@ -883,6 +1036,22 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cow-settlement-client" version = "0.2.0" @@ -920,17 +1089,20 @@ dependencies = [ "anyhow", "clap", "cow-settlement-client", + "orca_whirlpools", + "solana-client", "solana-commitment-config", "solana-hash 4.5.0", "solana-instruction", "solana-program-pack", "solana-pubkey 4.2.1", - "solana-rpc-client", + "solana-rpc-client 4.1.2", "solana-sdk", "solana-system-interface 3.2.0", "spl-associated-token-account-interface", "spl-token", "spl-token-interface 3.0.0", + "tokio", ] [[package]] @@ -960,6 +1132,40 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + [[package]] name = "crunchy" version = "0.2.4" @@ -1079,6 +1285,25 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + [[package]] name = "der" version = "0.7.10" @@ -1089,6 +1314,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint 0.4.8", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + [[package]] name = "derivation-path" version = "0.2.0" @@ -1169,6 +1414,29 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "eager" version = "0.1.0" @@ -1325,6 +1593,44 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "ethnum" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f" + +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastbloom" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +dependencies = [ + "getrandom 0.3.4", + "libm", + "rand 0.9.5", + "siphasher 1.0.3", +] + [[package]] name = "fastrand" version = "2.5.0" @@ -1486,6 +1792,12 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" +[[package]] +name = "futures-timer" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" + [[package]] name = "futures-util" version = "0.3.33" @@ -1514,6 +1826,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -1534,9 +1856,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1559,6 +1883,26 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.7", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -1590,6 +1934,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.5" @@ -1623,6 +1973,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" +[[package]] +name = "histogram" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" + [[package]] name = "hmac" version = "0.12.1" @@ -1632,6 +1988,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.5.0" @@ -1649,7 +2016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", - "http", + "http 1.5.0", ] [[package]] @@ -1660,7 +2027,7 @@ checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" dependencies = [ "bytes", "futures-core", - "http", + "http 1.5.0", "http-body", "pin-project-lite", ] @@ -1690,7 +2057,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "http", + "http 1.5.0", "http-body", "httparse", "itoa", @@ -1706,14 +2073,14 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http", + "http 1.5.0", "hyper", "hyper-util", "rustls", "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.9", ] [[package]] @@ -1722,11 +2089,11 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", - "http", + "http 1.5.0", "http-body", "hyper", "ipnet", @@ -1935,14 +2302,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] -name = "jobserver" -version = "0.1.35" +name = "jni" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ - "getrandom 0.4.3", - "libc", -] + "cesu8", + "cfg-if", + "combine 4.6.8", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] [[package]] name = "js-sys" @@ -2005,6 +2416,12 @@ version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + [[package]] name = "libsecp256k1" version = "0.7.2" @@ -2012,7 +2429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" dependencies = [ "arrayref", - "base64", + "base64 0.22.1", "digest 0.9.0", "libsecp256k1-core", "libsecp256k1-gen-ecmult", @@ -2093,7 +2510,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f959134a3232f13a9c38786c49aa0778cb96b5b8559b8429aaef5cc5415f4d18" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "agave-reserved-account-keys", "ansi_term", "indexmap", @@ -2109,7 +2526,7 @@ dependencies = [ "solana-compute-budget-instruction", "solana-epoch-rewards", "solana-epoch-schedule", - "solana-feature-gate-interface", + "solana-feature-gate-interface 4.0.0", "solana-fee", "solana-fee-calculator", "solana-fee-structure", @@ -2121,7 +2538,7 @@ dependencies = [ "solana-last-restart-slot", "solana-loader-v3-interface 8.0.1", "solana-loader-v4-interface", - "solana-message", + "solana-message 4.4.1", "solana-native-token", "solana-nonce", "solana-nonce-account", @@ -2146,8 +2563,8 @@ dependencies = [ "solana-system-program", "solana-sysvar 4.1.0", "solana-sysvar-id", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 4.1.6", + "solana-transaction-context 4.1.2", "solana-transaction-error", "thiserror 2.0.19", "wincode 0.5.5", @@ -2169,7 +2586,7 @@ dependencies = [ "solana-rent 4.3.0", "solana-signer", "solana-system-interface 3.2.0", - "solana-transaction", + "solana-transaction 4.1.6", "solana-transaction-error", "spl-associated-token-account-interface", "spl-token-interface 3.0.0", @@ -2223,6 +2640,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2244,6 +2667,41 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "num" version = "0.2.1" @@ -2289,6 +2747,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-derive" version = "0.4.2" @@ -2372,6 +2836,15 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -2390,6 +2863,91 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "orca_whirlpools" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6471e77f1decfe9309b492f11482a218f5c19170d9e2323346cab4d65888e9c1" +dependencies = [ + "bincode", + "bs58", + "orca_whirlpools_client", + "orca_whirlpools_core", + "serde", + "serde_json", + "solana-account 3.4.0", + "solana-account-decoder 3.1.14", + "solana-client", + "solana-commitment-config", + "solana-epoch-info", + "solana-instruction", + "solana-keypair", + "solana-message 3.1.0", + "solana-program-error", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", + "solana-sha256-hasher", + "solana-signature", + "solana-system-interface 2.0.0", + "solana-sysvar-id", + "solana-transaction 3.1.0", + "spl-associated-token-account-interface", + "spl-memo-interface", + "spl-token-2022-interface", + "spl-token-interface 2.0.0", +] + +[[package]] +name = "orca_whirlpools_client" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08496c5b41482cfdd9ccbde3d25f3d063c5a2eab0dec913059307ede01c068f8" +dependencies = [ + "borsh", + "num-derive", + "num-traits", + "orca_whirlpools_core", + "solana-account 3.4.0", + "solana-account-decoder 3.1.14", + "solana-account-info", + "solana-client", + "solana-cpi", + "solana-instruction", + "solana-program 3.0.0", + "solana-program-error", + "solana-pubkey 3.0.0", + "thiserror 2.0.19", +] + +[[package]] +name = "orca_whirlpools_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fa5a2318d63ef4c7241234b3aa53690bf76b7bd797c90b90ec38f494d847cc6" +dependencies = [ + "ethnum", + "libm", + "orca_whirlpools_macros", +] + +[[package]] +name = "orca_whirlpools_macros" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b093a9e60ca608c1dff40fcd841a2d5680b96f877080b6279044c159ebd50b78" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "pairing" version = "0.23.0" @@ -2399,6 +2957,12 @@ dependencies = [ "group", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -2443,6 +3007,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2542,6 +3115,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -2608,6 +3187,21 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -2800,6 +3394,35 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -2844,12 +3467,12 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http", + "http 1.5.0", "http-body", "http-body-util", "hyper", @@ -2875,7 +3498,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 1.0.9", ] [[package]] @@ -2886,7 +3509,7 @@ checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e" dependencies = [ "anyhow", "async-trait", - "http", + "http 1.5.0", "reqwest", "serde", "thiserror 1.0.69", @@ -2938,6 +3561,15 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "1.1.4" @@ -2965,6 +3597,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.15.1" @@ -2975,6 +3619,33 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[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.103.13" @@ -3010,6 +3681,24 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3030,6 +3719,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.28" @@ -3156,6 +3868,17 @@ dependencies = [ "solana-system-interface 3.2.0", ] +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + [[package]] name = "sha2" version = "0.9.9" @@ -3234,6 +3957,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + [[package]] name = "slab" version = "0.4.12" @@ -3262,11 +3991,16 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efc0ed36decb689413b9da5d57f2be49eea5bebb3cf7897015167b0c4336e731" dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", "solana-account-info", "solana-clock", "solana-instruction-error", "solana-pubkey 4.2.1", "solana-sdk-ids", + "solana-sysvar 3.1.1", ] [[package]] @@ -3289,37 +4023,37 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "4.1.2" +version = "3.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1daf7a9ad1ba8952f79d02ff2ff2f75d789bfb9c33aa53da4a377de86c5da02e" +checksum = "751157b033a30c178a272ec2bbab8a5bae14b21490451627990cbe84391b8264" dependencies = [ "Inflector", - "base64", + "base64 0.22.1", "bincode", "bs58", "bv", "serde", "serde_json", - "solana-account 4.3.2", - "solana-account-decoder-client-types", + "solana-account 3.4.0", + "solana-account-decoder-client-types 3.1.14", "solana-address-lookup-table-interface", "solana-clock", "solana-config-interface", "solana-epoch-schedule", "solana-fee-calculator", "solana-instruction", - "solana-loader-v3-interface 7.0.0", + "solana-loader-v3-interface 6.1.1", "solana-nonce", "solana-program-option", "solana-program-pack", - "solana-pubkey 4.2.1", - "solana-rent 4.3.0", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", "solana-sdk-ids", "solana-slot-hashes", "solana-slot-history", - "solana-stake-interface", - "solana-sysvar 4.1.0", - "solana-vote-interface", + "solana-stake-interface 2.0.2", + "solana-sysvar 3.1.1", + "solana-vote-interface 4.0.4", "spl-generic-token", "spl-token-2022-interface", "spl-token-group-interface", @@ -3329,13 +4063,70 @@ dependencies = [ "zstd", ] +[[package]] +name = "solana-account-decoder" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1daf7a9ad1ba8952f79d02ff2ff2f75d789bfb9c33aa53da4a377de86c5da02e" +dependencies = [ + "Inflector", + "base64 0.22.1", + "bincode", + "bs58", + "bv", + "serde", + "serde_json", + "solana-account 4.3.2", + "solana-account-decoder-client-types 4.1.2", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-config-interface", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-instruction", + "solana-loader-v3-interface 7.0.0", + "solana-nonce", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 4.2.1", + "solana-rent 4.3.0", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface 3.1.0", + "solana-sysvar 4.1.0", + "solana-vote-interface 6.0.3", + "spl-generic-token", + "spl-token-2022-interface", + "spl-token-group-interface", + "spl-token-interface 2.0.0", + "spl-token-metadata-interface", + "thiserror 2.0.19", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c200fb0019770f6ccf869a9b71653d37b76a633114d79176eedea6931c09cc7c" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_json", + "solana-account 3.4.0", + "solana-pubkey 3.0.0", + "zstd", +] + [[package]] name = "solana-account-decoder-client-types" version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02c4eb99bb799650f2c6cb7291d93cf6db05e956320f3c772e58ca49f8b6192e" dependencies = [ - "base64", + "base64 0.22.1", "bs58", "serde", "serde_json", @@ -3467,7 +4258,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f7e9dbeff4dab3484175666a367171b60fe514b707d6de1ab3b741f0168e735" dependencies = [ - "base64", + "base64 0.22.1", "blst", "blstrs", "cfg_eval", @@ -3536,15 +4327,15 @@ dependencies = [ "solana-packet 4.2.0", "solana-program-runtime", "solana-pubkey 4.2.1", - "solana-sbpf", + "solana-sbpf 0.21.0", "solana-sdk-ids", - "solana-svm-feature-set", + "solana-svm-feature-set 4.1.2", "solana-svm-log-collector", "solana-svm-measure", - "solana-svm-type-overrides", + "solana-svm-type-overrides 4.1.2", "solana-syscalls", "solana-system-interface 3.2.0", - "solana-transaction-context", + "solana-transaction-context 4.1.2", ] [[package]] @@ -3553,7 +4344,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0e54d03edadcb2f38bdb8b6524380a858f5ad51654db1f71eccc3fb5dc4d492" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "solana-bpf-loader-program", "solana-compute-budget-program", "solana-hash 4.5.0", @@ -3572,12 +4363,81 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a63b9b3ae7b09c32f7f15d83e875dbf8715d0853c2354e3306316158f19d9c90" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "ahash", "solana-pubkey 4.2.1", "solana-sdk-ids", ] +[[package]] +name = "solana-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1021bbda77368c57f3d8b850c5d9b19077906d21d1c516b1ccfbb8fe7737553f" +dependencies = [ + "anza-quinn", + "async-trait", + "bincode", + "dashmap", + "futures", + "futures-util", + "indexmap", + "indicatif", + "log", + "rayon", + "solana-account 3.4.0", + "solana-client-traits", + "solana-commitment-config", + "solana-connection-cache", + "solana-epoch-info", + "solana-hash 3.1.0", + "solana-instruction", + "solana-keypair", + "solana-measure", + "solana-message 3.1.0", + "solana-net-utils", + "solana-pubkey 3.0.0", + "solana-pubsub-client", + "solana-quic-client", + "solana-quic-definitions", + "solana-rpc-client 3.1.14", + "solana-rpc-client-api 3.1.14", + "solana-rpc-client-nonce-utils", + "solana-signature", + "solana-signer", + "solana-streamer", + "solana-time-utils", + "solana-tpu-client", + "solana-transaction 3.1.0", + "solana-transaction-error", + "solana-transaction-status-client-types 3.1.14", + "solana-udp-client", + "thiserror 2.0.19", + "tokio", + "tokio-util", +] + +[[package]] +name = "solana-client-traits" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08618ed587e128105510c54ae3e456b9a06d674d8640db75afe66dad65cb4e02" +dependencies = [ + "solana-account 3.4.0", + "solana-commitment-config", + "solana-epoch-info", + "solana-hash 3.1.0", + "solana-instruction", + "solana-keypair", + "solana-message 3.1.0", + "solana-pubkey 3.0.0", + "solana-signature", + "solana-signer", + "solana-system-interface 2.0.0", + "solana-transaction 3.1.0", + "solana-transaction-error", +] + [[package]] name = "solana-clock" version = "3.1.1" @@ -3593,6 +4453,15 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-cluster-type" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a494cf8eda7d98d9f0144b288bb409c88308d2e86f15cc1045aa77b83304718" +dependencies = [ + "solana-hash 4.5.0", +] + [[package]] name = "solana-commitment-config" version = "3.1.1" @@ -3619,7 +4488,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3ad15d715b0c4e21f6b591f126b7fa8070aadf0d75fcd89bc4c98afc9e5f8f6" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "solana-borsh", "solana-builtins-default-costs", "solana-compute-budget", @@ -3669,6 +4538,29 @@ dependencies = [ "solana-system-interface 2.0.0", ] +[[package]] +name = "solana-connection-cache" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a1f37271395e9e5371ef18d93197d5d53a18acd5651b66a5aa2ac68bd6dd54" +dependencies = [ + "async-trait", + "bincode", + "crossbeam-channel", + "futures-util", + "indexmap", + "log", + "rand 0.8.7", + "rayon", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-time-utils", + "solana-transaction-error", + "thiserror 2.0.19", + "tokio", +] + [[package]] name = "solana-cpi" version = "3.1.0" @@ -3772,7 +4664,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ee8beac9bff4db9225e57d532d169b0be5e447f1e6601a2f50f27a01bf5518f" dependencies = [ - "siphasher", + "siphasher 0.3.11", "solana-address 2.6.1", "solana-hash 4.5.0", ] @@ -3803,6 +4695,27 @@ dependencies = [ "solana-pubkey 4.2.1", ] +[[package]] +name = "solana-example-mocks" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978855d164845c1b0235d4b4d101cadc55373fffaf0b5b6cfa2194d25b2ed658" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash 3.1.0", + "solana-instruction", + "solana-keccak-hasher", + "solana-message 3.1.0", + "solana-nonce", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-system-interface 2.0.0", + "thiserror 2.0.19", +] + [[package]] name = "solana-example-mocks" version = "4.0.0" @@ -3820,6 +4733,19 @@ dependencies = [ "thiserror 2.0.19", ] +[[package]] +name = "solana-feature-gate-interface" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ca9b5cbb6f500f7fd73db5bd95640f71a83f04d6121a0e59a43b202dca2731" +dependencies = [ + "serde", + "serde_derive", + "solana-program-error", + "solana-pubkey 4.2.1", + "solana-sdk-ids", +] + [[package]] name = "solana-feature-gate-interface" version = "4.0.0" @@ -3845,7 +4771,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5fbffe004ec900267fc0bcf0c3b532c01905e6c4e3f318562718d1cdf6db939" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "solana-fee-structure", "solana-svm-transaction", ] @@ -4050,6 +4976,20 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-loader-v3-interface" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0538d4dbc9022e01616f1c58f2db98ece739c5d5ed4a2ef8737a953e76a2d4" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey 4.2.1", + "solana-sdk-ids", +] + [[package]] name = "solana-loader-v3-interface" version = "7.0.0" @@ -4088,6 +5028,31 @@ dependencies = [ "solana-sdk-ids", ] +[[package]] +name = "solana-measure" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0eef68497ca818f50da3de449c64dc406d28170e395fd2ec40b64b6798afec" + +[[package]] +name = "solana-message" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0448b1fd891c5f46491e5dc7d9986385ba3c852c340db2911dd29faa01d2b08d" +dependencies = [ + "bincode", + "lazy_static", + "serde", + "serde_derive", + "solana-address 2.6.1", + "solana-hash 4.5.0", + "solana-instruction", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-transaction-error", +] + [[package]] name = "solana-message" version = "4.4.1" @@ -4107,6 +5072,22 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-metrics" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba33d34f2297e307bc124c3108da4b5b536a63022d705c0367a8512caebc9c4f" +dependencies = [ + "crossbeam-channel", + "gethostname", + "log", + "reqwest", + "solana-cluster-type", + "solana-sha256-hasher", + "solana-time-utils", + "thiserror 2.0.19", +] + [[package]] name = "solana-msg" version = "3.1.0" @@ -4122,6 +5103,29 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae8dd4c280dca9d046139eb5b7a5ac9ad10403fbd64964c7d7571214950d758f" +[[package]] +name = "solana-net-utils" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a83f0f11be6d2c0104871136ae22250a5dafd013fe137678312b73a7e35044" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "cfg-if", + "dashmap", + "itertools 0.12.1", + "log", + "nix", + "rand 0.8.7", + "serde", + "socket2", + "solana-serde", + "solana-svm-type-overrides 3.1.14", + "tokio", + "url", +] + [[package]] name = "solana-nonce" version = "3.2.1" @@ -4181,7 +5185,12 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6edf2f25743c95229ac0fdc32f8f5893ef738dbf332c669e9861d33ddb0f469d" dependencies = [ + "bincode", "bitflags", + "cfg_eval", + "serde", + "serde_derive", + "serde_with", ] [[package]] @@ -4194,6 +5203,39 @@ dependencies = [ "solana-pubkey 4.2.1", ] +[[package]] +name = "solana-perf" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794506987f9168331a84836eb66e762ecd5fd18920f0c5bcdf349eefff553e59" +dependencies = [ + "ahash", + "bincode", + "bv", + "bytes", + "caps", + "curve25519-dalek", + "dlopen2", + "fnv", + "libc", + "log", + "nix", + "rand 0.8.7", + "rayon", + "serde", + "solana-hash 3.1.0", + "solana-message 3.1.0", + "solana-metrics", + "solana-packet 3.0.0", + "solana-pubkey 3.0.0", + "solana-rayon-threadlimit", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-time-utils", + "solana-transaction-context 3.1.14", +] + [[package]] name = "solana-poseidon" version = "4.0.0" @@ -4230,9 +5272,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "4.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778f08fb0eaf52c9a3bef2978247f7fab0ccfddc44cfddb936d5ad9f98ede886" +checksum = "91b12305dd81045d705f427acd0435a2e46444b65367d7179d7bdcfc3bc5f5eb" dependencies = [ "memoffset", "solana-account-info", @@ -4241,13 +5283,13 @@ dependencies = [ "solana-borsh", "solana-clock", "solana-cpi", - "solana-define-syscall 5.2.0", + "solana-define-syscall 3.0.0", "solana-epoch-rewards", "solana-epoch-schedule", "solana-epoch-stake", - "solana-example-mocks", + "solana-example-mocks 3.0.0", "solana-fee-calculator", - "solana-hash 4.5.0", + "solana-hash 3.1.0", "solana-instruction", "solana-instruction-error", "solana-instructions-sysvar 3.0.1", @@ -4260,8 +5302,8 @@ dependencies = [ "solana-program-memory", "solana-program-option", "solana-program-pack", - "solana-pubkey 4.2.1", - "solana-rent 4.3.0", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", "solana-sdk-ids", "solana-secp256k1-recover", "solana-serde-varint", @@ -4271,13 +5313,60 @@ dependencies = [ "solana-slot-hashes", "solana-slot-history", "solana-stable-layout", - "solana-sysvar 4.1.0", + "solana-sysvar 3.1.1", "solana-sysvar-id", ] [[package]] -name = "solana-program-entrypoint" -version = "3.1.1" +name = "solana-program" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778f08fb0eaf52c9a3bef2978247f7fab0ccfddc44cfddb936d5ad9f98ede886" +dependencies = [ + "memoffset", + "solana-account-info", + "solana-big-mod-exp", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-define-syscall 5.2.0", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-epoch-stake", + "solana-example-mocks 4.0.0", + "solana-fee-calculator", + "solana-hash 4.5.0", + "solana-instruction", + "solana-instruction-error", + "solana-instructions-sysvar 3.0.1", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 4.2.1", + "solana-rent 4.3.0", + "solana-sdk-ids", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-sysvar 4.1.0", + "solana-sysvar-id", +] + +[[package]] +name = "solana-program-entrypoint" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c9b0a1ff494e05f503a08b3d51150b73aa639544631e510279d6375f290997" dependencies = [ @@ -4328,7 +5417,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0364032ca71f9be2ffab27791cd6535dbe9d2990da0e2346e99013a9bcb57f4" dependencies = [ - "base64", + "base64 0.22.1", "bincode", "cfg-if", "itertools 0.14.0", @@ -4349,22 +5438,22 @@ dependencies = [ "solana-program-entrypoint", "solana-pubkey 4.2.1", "solana-rent 4.3.0", - "solana-sbpf", + "solana-sbpf 0.21.0", "solana-sdk-ids", "solana-slot-hashes", "solana-stable-layout", - "solana-stake-interface", + "solana-stake-interface 3.1.0", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 4.1.2", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", "solana-svm-transaction", - "solana-svm-type-overrides", + "solana-svm-type-overrides 4.1.2", "solana-system-interface 3.2.0", "solana-sysvar 4.1.0", "solana-sysvar-id", - "solana-transaction-context", + "solana-transaction-context 4.1.2", "thiserror 2.0.19", ] @@ -4387,6 +5476,81 @@ dependencies = [ "solana-address 2.6.1", ] +[[package]] +name = "solana-pubsub-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3eb58936a5c35140f7eb0fc0a30685a32523001b24c4e3e18e70ca05c8c680b" +dependencies = [ + "crossbeam-channel", + "futures-util", + "http 0.2.12", + "log", + "semver", + "serde", + "serde_json", + "solana-account-decoder-client-types 3.1.14", + "solana-clock", + "solana-pubkey 3.0.0", + "solana-rpc-client-types 3.1.14", + "solana-signature", + "thiserror 2.0.19", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab47dde0f9b63bfee69fb7f4c7525b87b6685de2e538e8d0ab614625df3d093" +dependencies = [ + "anza-quinn", + "anza-quinn-proto", + "async-lock", + "async-trait", + "futures", + "itertools 0.12.1", + "log", + "rustls", + "solana-connection-cache", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-pubkey 3.0.0", + "solana-quic-definitions", + "solana-rpc-client-api 3.1.14", + "solana-signer", + "solana-streamer", + "solana-tls-utils", + "solana-transaction-error", + "thiserror 2.0.19", + "tokio", +] + +[[package]] +name = "solana-quic-definitions" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15319accf7d3afd845817aeffa6edd8cc185f135cefbc6b985df29cfd8c09609" +dependencies = [ + "solana-keypair", +] + +[[package]] +name = "solana-rayon-threadlimit" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06a84c1c10b97998364e06e1254e2e2364c338ce0cf1bdcfc996ab39e85c618" +dependencies = [ + "log", + "num_cpus", +] + [[package]] name = "solana-rent" version = "3.1.0" @@ -4415,6 +5579,16 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-reward-info" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82be7946105c2ee6be9f9ee7bd18a068b558389221d29efa92b906476102bfcc" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "solana-reward-info" version = "6.2.0" @@ -4426,6 +5600,46 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-rpc-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11dd2723748fb6a7a2b5b83e4186cb99f35f1384d8b310cd57122ea8627839a" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bincode", + "bs58", + "futures", + "indicatif", + "log", + "reqwest", + "reqwest-middleware", + "semver", + "serde", + "serde_json", + "solana-account 3.4.0", + "solana-account-decoder 3.1.14", + "solana-account-decoder-client-types 3.1.14", + "solana-clock", + "solana-commitment-config", + "solana-epoch-info", + "solana-epoch-schedule", + "solana-feature-gate-interface 3.1.0", + "solana-hash 3.1.0", + "solana-instruction", + "solana-message 3.1.0", + "solana-pubkey 3.0.0", + "solana-rpc-client-api 3.1.14", + "solana-signature", + "solana-transaction 3.1.0", + "solana-transaction-error", + "solana-transaction-status-client-types 3.1.14", + "solana-version 3.1.14", + "solana-vote-interface 4.0.4", + "tokio", +] + [[package]] name = "solana-rpc-client" version = "4.1.2" @@ -4433,7 +5647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "849a4576002de8ba30ebb60aa4067b82643b23907be874786473736c616c24ec" dependencies = [ "async-trait", - "base64", + "base64 0.22.1", "bincode", "bs58", "futures", @@ -4445,27 +5659,48 @@ dependencies = [ "serde", "serde_json", "solana-account 4.3.2", - "solana-account-decoder", - "solana-account-decoder-client-types", + "solana-account-decoder 4.1.2", + "solana-account-decoder-client-types 4.1.2", "solana-clock", "solana-commitment-config", "solana-epoch-info", "solana-epoch-schedule", - "solana-feature-gate-interface", + "solana-feature-gate-interface 4.0.0", "solana-hash 4.5.0", "solana-instruction", - "solana-message", + "solana-message 4.4.1", "solana-pubkey 4.2.1", - "solana-rpc-client-api", + "solana-rpc-client-api 4.1.2", "solana-signature", - "solana-transaction", + "solana-transaction 4.1.6", "solana-transaction-error", - "solana-transaction-status-client-types", - "solana-version", - "solana-vote-interface", + "solana-transaction-status-client-types 4.1.2", + "solana-version 4.1.2", + "solana-vote-interface 6.0.3", "tokio", ] +[[package]] +name = "solana-rpc-client-api" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81a57ed54176e3aa4bca8e894f9326638a3f6870f79b078d8b3fadda8a4c9b" +dependencies = [ + "anyhow", + "jsonrpc-core", + "reqwest", + "reqwest-middleware", + "serde", + "serde_json", + "solana-account-decoder-client-types 3.1.14", + "solana-clock", + "solana-rpc-client-types 3.1.14", + "solana-signer", + "solana-transaction-error", + "solana-transaction-status-client-types 3.1.14", + "thiserror 2.0.19", +] + [[package]] name = "solana-rpc-client-api" version = "4.1.2" @@ -4479,10 +5714,54 @@ dependencies = [ "serde", "serde_json", "solana-clock", - "solana-rpc-client-types", + "solana-rpc-client-types 4.1.2", "solana-signer", "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 4.1.2", + "thiserror 2.0.19", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4804524b94b49e721c6febc0b4c8f745cd76fc05dfbd972a1e6257e23502b59" +dependencies = [ + "solana-account 3.4.0", + "solana-commitment-config", + "solana-hash 3.1.0", + "solana-message 3.1.0", + "solana-nonce", + "solana-pubkey 3.0.0", + "solana-rpc-client 3.1.14", + "solana-sdk-ids", + "thiserror 2.0.19", +] + +[[package]] +name = "solana-rpc-client-types" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a6f06038b9f88ecaecb0d283a325040429c700c1d04526c015c2c8182686c9b" +dependencies = [ + "base64 0.22.1", + "bs58", + "semver", + "serde", + "serde_json", + "solana-account 3.4.0", + "solana-account-decoder-client-types 3.1.14", + "solana-address 1.1.0", + "solana-clock", + "solana-commitment-config", + "solana-fee-calculator", + "solana-inflation", + "solana-reward-info 3.0.0", + "solana-transaction 3.1.0", + "solana-transaction-error", + "solana-transaction-status-client-types 3.1.14", + "solana-version 3.1.14", + "spl-generic-token", "thiserror 2.0.19", ] @@ -4492,22 +5771,22 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae18406ee879a0d91da081313f591d1b3e1c370e010c63ee1b1a3741db88693e" dependencies = [ - "base64", + "base64 0.22.1", "bs58", "semver", "serde", "serde_json", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 4.1.2", "solana-address 2.6.1", "solana-clock", "solana-commitment-config", "solana-fee-calculator", "solana-inflation", - "solana-reward-info", - "solana-transaction", + "solana-reward-info 6.2.0", + "solana-transaction 4.1.6", "solana-transaction-error", - "solana-transaction-status-client-types", - "solana-version", + "solana-transaction-status-client-types 4.1.2", + "solana-version 4.1.2", "thiserror 2.0.19", ] @@ -4517,6 +5796,20 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf09694a0fc14e5ffb18f9b7b7c0f15ecb6eac5b5610bf76a1853459d19daf9" +[[package]] +name = "solana-sbpf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15b079e08471a9dbfe1e48b2c7439c85aa2a055cbd54eddd8bd257b0a7dbb29" +dependencies = [ + "byteorder", + "combine 3.8.1", + "hash32", + "log", + "rustc-demangle", + "thiserror 2.0.19", +] + [[package]] name = "solana-sbpf" version = "0.21.0" @@ -4524,7 +5817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f84c593fa3d4131045b606dec5acf9d8eac73791bc786ca9911057aec8f43ec" dependencies = [ "byteorder", - "combine", + "combine 3.8.1", "hash32", "libc", "log", @@ -4549,10 +5842,10 @@ dependencies = [ "solana-fee-structure", "solana-inflation", "solana-keypair", - "solana-message", + "solana-message 4.4.1", "solana-offchain-message", "solana-presigner", - "solana-program", + "solana-program 4.0.0", "solana-program-memory", "solana-pubkey 4.2.1", "solana-sanitize", @@ -4567,7 +5860,7 @@ dependencies = [ "solana-signature", "solana-signer", "solana-time-utils", - "solana-transaction", + "solana-transaction 4.1.6", "solana-transaction-error", "thiserror 2.0.19", ] @@ -4778,6 +6071,25 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-stake-interface" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9bc26191b533f9a6e5a14cca05174119819ced680a80febff2f5051a713f0db" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-system-interface 2.0.0", + "solana-sysvar 3.1.1", + "solana-sysvar-id", +] + [[package]] name = "solana-stake-interface" version = "3.1.0" @@ -4797,6 +6109,54 @@ dependencies = [ "solana-sysvar-id", ] +[[package]] +name = "solana-streamer" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1506f6dc927e86fd673bee67fafa27c942527874bac7d4aea63869dcbf22615" +dependencies = [ + "anza-quinn", + "anza-quinn-proto", + "arc-swap", + "bytes", + "crossbeam-channel", + "dashmap", + "futures", + "futures-util", + "governor", + "histogram", + "indexmap", + "itertools 0.12.1", + "libc", + "log", + "nix", + "num_cpus", + "pem", + "percentage", + "rand 0.8.7", + "rustls", + "smallvec", + "socket2", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-packet 3.0.0", + "solana-perf", + "solana-pubkey 3.0.0", + "solana-quic-definitions", + "solana-signature", + "solana-signer", + "solana-time-utils", + "solana-tls-utils", + "solana-transaction-error", + "solana-transaction-metrics-tracker", + "thiserror 2.0.19", + "tokio", + "tokio-util", + "x509-parser", +] + [[package]] name = "solana-svm-callback" version = "4.1.2" @@ -4809,6 +6169,12 @@ dependencies = [ "solana-pubkey 4.2.1", ] +[[package]] +name = "solana-svm-feature-set" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc2e2fdebd77159b7a14ee45c9dbb3f1d202e8e7ccc14e4cda78c006a7a78a9" + [[package]] name = "solana-svm-feature-set" version = "4.1.2" @@ -4848,11 +6214,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "998e6d7d1197d29a77d3701ae273cfc3e95e79978546faa4d28af637ef5211e7" dependencies = [ "solana-hash 4.5.0", - "solana-message", + "solana-message 4.4.1", "solana-pubkey 4.2.1", "solana-sdk-ids", "solana-signature", - "solana-transaction", + "solana-transaction 4.1.6", +] + +[[package]] +name = "solana-svm-type-overrides" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b78cd0bfb102d4197ce8c590f800a119ba0d358369ca57b0f66e94d1317fd0e" +dependencies = [ + "rand 0.8.7", ] [[package]] @@ -4890,19 +6265,19 @@ dependencies = [ "solana-program-entrypoint", "solana-program-runtime", "solana-pubkey 4.2.1", - "solana-sbpf", + "solana-sbpf 0.21.0", "solana-sdk-ids", "solana-secp256k1-recover", "solana-sha256-hasher", "solana-sha512-hasher", "solana-stable-layout", - "solana-stake-interface", - "solana-svm-feature-set", + "solana-stake-interface 3.1.0", + "solana-svm-feature-set 4.1.2", "solana-svm-log-collector", - "solana-svm-type-overrides", + "solana-svm-type-overrides 4.1.2", "solana-sysvar 4.1.0", "solana-sysvar-id", - "solana-transaction-context", + "solana-transaction-context 4.1.2", "thiserror 2.0.19", ] @@ -4958,7 +6333,7 @@ dependencies = [ "solana-svm-log-collector", "solana-system-interface 3.2.0", "solana-sysvar 4.1.0", - "solana-transaction-context", + "solana-transaction-context 4.1.2", ] [[package]] @@ -4967,8 +6342,10 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6690d3dd88f15c21edff68eb391ef8800df7a1f5cec84ee3e8d1abf05affdf74" dependencies = [ - "base64", + "base64 0.22.1", "bincode", + "bytemuck", + "bytemuck_derive", "lazy_static", "serde", "serde_derive", @@ -4999,7 +6376,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ada7045bbfdd802af08fbc9c7e2b56ddabb20599d22e4c3840fcef5e7afb8324" dependencies = [ - "base64", + "base64 0.22.1", "bincode", "bytemuck", "bytemuck_derive", @@ -5040,12 +6417,81 @@ dependencies = [ "solana-sdk-ids", ] -[[package]] -name = "solana-time-utils" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced92c60aa76ec4780a9d93f3bd64dfa916e1b998eacc6f1c110f3f444f02c9" - +[[package]] +name = "solana-time-utils" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced92c60aa76ec4780a9d93f3bd64dfa916e1b998eacc6f1c110f3f444f02c9" + +[[package]] +name = "solana-tls-utils" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e195a1cd2dbb54fb234abb1fd5c92021152669f0d8853075a52b67bc9e7095" +dependencies = [ + "rustls", + "solana-keypair", + "solana-pubkey 3.0.0", + "solana-signer", + "x509-parser", +] + +[[package]] +name = "solana-tpu-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b3e8d4db00daee1efb357c2e810ce07fd5f0d9167c722434b77c4f9aa668b1" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap", + "indicatif", + "log", + "rayon", + "solana-client-traits", + "solana-clock", + "solana-commitment-config", + "solana-connection-cache", + "solana-epoch-schedule", + "solana-measure", + "solana-message 3.1.0", + "solana-net-utils", + "solana-pubkey 3.0.0", + "solana-pubsub-client", + "solana-quic-definitions", + "solana-rpc-client 3.1.14", + "solana-rpc-client-api 3.1.14", + "solana-signature", + "solana-signer", + "solana-transaction 3.1.0", + "solana-transaction-error", + "thiserror 2.0.19", + "tokio", +] + +[[package]] +name = "solana-transaction" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96697cff5075a028265324255efed226099f6d761ca67342b230d09f72cc48d2" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-address 2.6.1", + "solana-hash 4.5.0", + "solana-instruction", + "solana-instruction-error", + "solana-message 3.1.0", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-transaction-error", +] + [[package]] name = "solana-transaction" version = "4.1.6" @@ -5058,7 +6504,7 @@ dependencies = [ "solana-hash 4.5.0", "solana-instruction", "solana-instruction-error", - "solana-message", + "solana-message 4.4.1", "solana-sanitize", "solana-sdk-ids", "solana-short-vec", @@ -5068,6 +6514,23 @@ dependencies = [ "wincode 0.5.5", ] +[[package]] +name = "solana-transaction-context" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a3c3a69688293a195b02c60a5384d855b8de19981f404c71ccb9e7f139b98f" +dependencies = [ + "bincode", + "serde", + "solana-account 3.4.0", + "solana-instruction", + "solana-instructions-sysvar 3.0.1", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", + "solana-sbpf 0.13.1", + "solana-sdk-ids", +] + [[package]] name = "solana-transaction-context" version = "4.1.2" @@ -5081,7 +6544,7 @@ dependencies = [ "solana-instructions-sysvar 3.0.1", "solana-pubkey 4.2.1", "solana-rent 4.3.0", - "solana-sbpf", + "solana-sbpf 0.21.0", "solana-sdk-ids", ] @@ -5097,37 +6560,107 @@ dependencies = [ "solana-sanitize", ] +[[package]] +name = "solana-transaction-metrics-tracker" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfdbabf25f0b1335c4042924011f1be7d93b668d3315b12bbb33781ad388adc" +dependencies = [ + "base64 0.22.1", + "bincode", + "log", + "rand 0.8.7", + "solana-packet 3.0.0", + "solana-perf", + "solana-short-vec", + "solana-signature", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f7c3d15f25111cd1e320ad8ee3515ccae9983ab750cec83517c8553419b70a" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_json", + "solana-account-decoder-client-types 3.1.14", + "solana-commitment-config", + "solana-instruction", + "solana-message 3.1.0", + "solana-pubkey 3.0.0", + "solana-reward-info 3.0.0", + "solana-signature", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.14", + "solana-transaction-error", + "thiserror 2.0.19", +] + [[package]] name = "solana-transaction-status-client-types" version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be5aafaae40f808411265e0de673c1dc2b8a68bf4ad4d38ba7e141d5232a5f23" dependencies = [ - "base64", + "base64 0.22.1", "bincode", "bs58", "serde", "serde_json", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 4.1.2", "solana-commitment-config", "solana-instruction", - "solana-message", - "solana-reward-info", + "solana-message 4.4.1", + "solana-reward-info 6.2.0", "solana-signature", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 4.1.6", + "solana-transaction-context 4.1.2", "solana-transaction-error", "thiserror 2.0.19", "wincode 0.5.5", ] +[[package]] +name = "solana-udp-client" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e01a3aa2c2f0c1cd9e493e59ef9c7f0281cdf56845900927d3e3a021222bbab" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-keypair", + "solana-net-utils", + "solana-streamer", + "solana-transaction-error", + "thiserror 2.0.19", + "tokio", +] + +[[package]] +name = "solana-version" +version = "3.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8b34a38f1aab0be22e3d9810c84229a5668a50839fc38e9a409912dabbc227" +dependencies = [ + "agave-feature-set 3.1.14", + "rand 0.8.7", + "semver", + "serde", + "solana-sanitize", + "solana-serde-varint", +] + [[package]] name = "solana-version" version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a33921090d55beb8dcded76d80982dd4eb02c8bc8115bad8a9aeb901531c10df" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "rand 0.9.5", "semver", "serde", @@ -5135,6 +6668,32 @@ dependencies = [ "solana-serde-varint", ] +[[package]] +name = "solana-vote-interface" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6e123e16bfdd7a81d71b4c4699e0b29580b619f4cd2ef5b6aae1eb85e8979f" +dependencies = [ + "bincode", + "cfg_eval", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "serde_with", + "solana-clock", + "solana-hash 3.1.0", + "solana-instruction", + "solana-instruction-error", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface 2.0.0", +] + [[package]] name = "solana-vote-interface" version = "6.0.3" @@ -5167,7 +6726,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16d772aa219b97b0cd9ec512c9330179714e3bb6231df4a8b81981b6c88f85f1" dependencies = [ - "agave-feature-set", + "agave-feature-set 4.1.2", "bincode", "log", "solana-account 4.3.2", @@ -5184,8 +6743,8 @@ dependencies = [ "solana-sdk-ids", "solana-slot-hashes", "solana-system-interface 3.2.0", - "solana-transaction-context", - "solana-vote-interface", + "solana-transaction-context 4.1.2", + "solana-vote-interface 6.0.3", ] [[package]] @@ -5220,7 +6779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9602bcb1f7af15caef92b91132ec2347e1c51a72ecdbefdaefa3eac4b8711475" dependencies = [ "aes-gcm-siv", - "base64", + "base64 0.22.1", "bincode", "bytemuck", "bytemuck_derive", @@ -5257,7 +6816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09670ff59f60e6ddc2209c2e4353992a9b9f01d4e244f3e9d67bd5146e33d388" dependencies = [ "aes-gcm-siv", - "base64", + "base64 0.22.1", "bincode", "bytemuck", "bytemuck_derive", @@ -5293,6 +6852,15 @@ dependencies = [ "solana-program-runtime", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -5359,6 +6927,16 @@ dependencies = [ "solana-pubkey 3.0.0", ] +[[package]] +name = "spl-memo-interface" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3745d384b0afee980d43d62b66c27bdcbbd03507732b8d3626d3413cb72084f2" +dependencies = [ + "solana-instruction", + "solana-pubkey 4.2.1", +] + [[package]] name = "spl-pod" version = "0.7.3" @@ -5621,6 +7199,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -5707,6 +7297,36 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.3" @@ -5770,6 +7390,33 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.26.11", +] + [[package]] name = "tokio-util" version = "0.7.19" @@ -5779,6 +7426,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", "pin-project-lite", "tokio", ] @@ -5839,7 +7487,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", + "http 1.5.0", "http-body", "http-body-util", "pin-project-lite", @@ -5869,6 +7517,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-core", ] @@ -5888,6 +7537,26 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http 1.5.0", + "httparse", + "log", + "rand 0.9.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 2.0.19", + "utf-8", + "webpki-roots 0.26.11", +] + [[package]] name = "typenum" version = "1.20.1" @@ -5912,6 +7581,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "unit-prefix" version = "0.5.2" @@ -5965,6 +7640,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -5998,6 +7679,16 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -6097,6 +7788,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.9", +] + [[package]] name = "webpki-roots" version = "1.0.9" @@ -6122,6 +7831,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -6185,13 +7903,22 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[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]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -6203,34 +7930,67 @@ dependencies = [ "windows-link", ] +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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_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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[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.52.6" @@ -6243,24 +8003,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[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.52.6" @@ -6297,6 +8081,24 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs", + "base64 0.13.1", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + [[package]] name = "yoke" version = "0.8.3" @@ -6317,7 +8119,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.119", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -6358,7 +8160,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.119", - "synstructure", + "synstructure 0.13.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6e24208..c53e955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ anyhow = "1" arrayref = "0.3" bincode = "1" clap = { version = "4", features = ["derive", "env"] } +solana-client = "3" solana-commitment-config = "3" solana-program-pack = "3" solana-rpc-client = "4" @@ -30,6 +31,7 @@ hex-literal = "1" litesvm = "0.15" litesvm-token = "0.15" num_enum = "0.7" +orca_whirlpools = "8" pinocchio = "0.11" pinocchio-system = "0.6" pinocchio-token = "0.6" @@ -57,6 +59,7 @@ solana-system-interface = "3" spl-associated-token-account-interface = "2" spl-token = "9" spl-token-interface = "3" +tokio = { version = "1", features = ["rt-multi-thread"] } [workspace.metadata.cli] # Used to help solana-verify identify the correct build image. diff --git a/test-cli/Cargo.toml b/test-cli/Cargo.toml index 0938df2..8d7d6aa 100644 --- a/test-cli/Cargo.toml +++ b/test-cli/Cargo.toml @@ -24,7 +24,9 @@ path = "src/main.rs" [dependencies] anyhow.workspace = true clap.workspace = true +orca_whirlpools.workspace = true cow-settlement-client.workspace = true +solana-client.workspace = true solana-commitment-config.workspace = true solana-hash.workspace = true solana-instruction.workspace = true @@ -36,6 +38,7 @@ solana-system-interface = { workspace = true, features = ["bincode"] } spl-associated-token-account-interface.workspace = true spl-token.workspace = true spl-token-interface.workspace = true +tokio.workspace = true [lints] workspace = true diff --git a/test-cli/src/cmd/settle.rs b/test-cli/src/cmd/settle.rs index 18e9cf7..b1a881f 100644 --- a/test-cli/src/cmd/settle.rs +++ b/test-cli/src/cmd/settle.rs @@ -17,8 +17,10 @@ use solana_sdk::{ signature::{Signature, Signer}, transaction::Transaction, }; +use spl_associated_token_account_interface::address::get_associated_token_address_with_program_id; use std::collections::{HashMap, HashSet}; +use crate::liquidity::orca::{self, OrcaClient}; use crate::token::{resolve_from_token_account, ResolvedToken}; use super::Context; @@ -90,9 +92,30 @@ pub fn run(ctx: Context, args: SettleArgs) -> anyhow::Result<()> { let intents = resolve_intents(&ctx, &args)?; let mut all_ixs: Vec = vec![]; - prepare_setup_ixs(&ctx, &intents, &mut all_ixs)?; + let (sell_amount_pulled, buy_amount_pushed) = prepare_setup_ixs(&ctx, &intents, &mut all_ixs)?; + + // figure out the net amount we have to buy (deficits) and the net amount we have to buy it with (surplus) + let surplus = union_with_positive_remainder(&sell_amount_pulled, &buy_amount_pushed); + let deficits = union_with_positive_remainder(&buy_amount_pushed, &sell_amount_pulled); + + let mut swap_ixs: Vec = vec![]; + let mut teardown_ixs: Vec = vec![]; + let mut swap_sinks: HashMap = HashMap::new(); + + // If we don't have enough of any token just from the order inputs, we are going to need to swap for it on a DEX + if !deficits.is_empty() { + let orca = OrcaClient::new(&ctx.rpc.url(), ctx.rpc.commitment())?; + let plan = orca::plan_swaps(&orca, &ctx, &surplus, &deficits)?; + all_ixs.extend(plan.setup_ixs); + swap_ixs = plan.swap_ixs; + teardown_ixs = plan.teardown_ixs; + swap_sinks = plan.sinks; + } - let pulls = compute_pulls(&ctx, &intents); + // At this point, we know what DEX swaps we need to do. Figure out the routing + // of funds to make that happen. + let mut sinks = compute_sinks(&ctx, &sell_amount_pulled, &swap_sinks)?; + let pulls = compute_pulls(&intents, &mut sinks)?; let initialized_intents: Vec<_> = intents .iter() @@ -103,10 +126,12 @@ pub fn run(ctx: Context, args: SettleArgs) -> anyhow::Result<()> { }) .collect(); - let (begin_ix_index, finalize_ix_index) = u16::try_from(all_ixs.len()) + let begin_ix_index = + u16::try_from(all_ixs.len()).context("too many instructions: begin index overflow")?; + let finalize_ix_index = u16::try_from(swap_ixs.len()) .ok() - .and_then(|begin| Some((begin, begin.checked_add(1)?))) - .context("too many instructions: begin/finalize index overflow")?; + .and_then(|n| begin_ix_index.checked_add(1)?.checked_add(n)) + .context("too many instructions: finalize index overflow")?; let begin_ix = BeginSettle { program_id: ctx.program_id, @@ -131,7 +156,9 @@ pub fn run(ctx: Context, args: SettleArgs) -> anyhow::Result<()> { }; all_ixs.push(begin_ix.into()); + all_ixs.extend(swap_ixs); all_ixs.push(finalize_ix.into()); + all_ixs.extend(teardown_ixs); let blockhash = ctx.rpc.get_latest_blockhash().context("fetch blockhash")?; let tx = Transaction::new_signed_with_payer( @@ -260,13 +287,13 @@ fn tally_and_register_buffer( Ok(()) } -/// Create any missing buffer PDAs before the settle tx, and check that the -/// settlement is self-funding (see [`ensure_cow_balance`]). +/// Create any missing buffer PDAs before the settle tx, and tally up the +/// total sell/buy amount per mint across all orders. fn prepare_setup_ixs( ctx: &Context, intents: &[ResolvedIntent], all_ixs: &mut Vec, -) -> anyhow::Result<()> { +) -> anyhow::Result<(HashMap, HashMap)> { let mut sell_amount_pulled: HashMap = HashMap::new(); let mut buy_amount_pushed: HashMap = HashMap::new(); let mut mint_buffers_to_create: HashSet = HashSet::new(); @@ -290,8 +317,6 @@ fn prepare_setup_ixs( )?; } - ensure_cow_balance(&sell_amount_pulled, &buy_amount_pushed)?; - if !mint_buffers_to_create.is_empty() { all_ixs.push( CreateBuffers { @@ -303,44 +328,122 @@ fn prepare_setup_ixs( ); } - Ok(()) + Ok((sell_amount_pulled, buy_amount_pushed)) +} + +/// Computes a new set that subtracts key-matching elements of b_set from a_set +/// Useful for getting net per-token settlement amounts. +fn union_with_positive_remainder( + a_set: &HashMap, + b_set: &HashMap, +) -> HashMap { + a_set + .iter() + .filter_map(|(&mint, &pulled)| { + let pushed = b_set.get(&mint).copied().unwrap_or(0); + (pulled > pushed).then(|| { + let extra = pulled + .checked_sub(pushed) + .expect("gated by prior condition"); + (mint, extra) + }) + }) + .collect() } -/// Check that the orders can settle against each other: for every mint, the -/// amount the users sell into its buffer must cover the amount the settlement -/// pushes back out of it. Otherwise there is nothing to CoW the orders with and -/// the settlement would have to be funded from elsewhere. -/// -/// This deliberately ignores whatever the buffers already hold, so a settlement -/// that would only work by spending pre-existing buffer balances is rejected -/// here rather than silently draining them. -fn ensure_cow_balance( +/// Compute each sold mint's pull destinations. +fn compute_sinks( + ctx: &Context, sell_amount_pulled: &HashMap, - buy_amount_pushed: &HashMap, -) -> anyhow::Result<()> { - for (mint, &pushed) in buy_amount_pushed { - let pulled = sell_amount_pulled.get(mint).copied().unwrap_or_default(); - anyhow::ensure!( - pulled >= pushed, - "orders can't be CoW'd: mint {mint} needs {pushed} pushed out of its buffer \ - but only {pulled} is sold into it", - ); + swap_sinks: &HashMap, +) -> anyhow::Result>> { + sell_amount_pulled + .iter() + .map(|(&mint, &sold)| { + let to_payer = swap_sinks.get(&mint).copied().unwrap_or(0).min(sold); + let to_buffer = sold.checked_sub(to_payer).with_context(|| { + format!("swaps reserved more of mint {mint} than the orders sell") + })?; + + let mut mint_sinks = Vec::with_capacity(2); + if to_buffer > 0 { + let (buffer_pda, _) = find_buffer_pda(&ctx.program_id, &mint); + mint_sinks.push(Pull { + destination: buffer_pda, + amount: to_buffer, + }); + } + if to_payer > 0 { + let payer_ata = get_associated_token_address_with_program_id( + &ctx.payer.pubkey(), + &mint, + &spl_token_interface::id(), + ); + mint_sinks.push(Pull { + destination: payer_ata, + amount: to_payer, + }); + } + + Ok((mint, mint_sinks)) + }) + .collect() +} + +/// Carve `amount` out of `mint_sinks` (a single mint's entry from +/// [`compute_sinks`]'s map), depleting it from the back as we go. Splits +/// across multiple `Pull`s when a single sink entry doesn't cover the whole +/// amount (e.g. an order that draws from both the buffer and the payer's +/// swap-funding wallet). +fn carve_pulls(amount: u64, mint_sinks: &mut Vec) -> anyhow::Result> { + let mut pulls = Vec::with_capacity(1); + let mut remaining = amount; + + while remaining > 0 { + let Some(sink) = mint_sinks.last().cloned() else { + break; + }; + + // Both subtractions run in the direction this branch just established, so an + // underflow would mean the comparison and the arithmetic disagree. + if sink.amount <= remaining { + mint_sinks.pop(); + remaining = remaining + .checked_sub(sink.amount) + .context("sink is larger than the amount it was chosen to fit inside")?; + pulls.push(sink); + } else { + mint_sinks + .last_mut() + .expect("checked non-empty above") + .amount = sink + .amount + .checked_sub(remaining) + .context("sink is smaller than the amount carved out of it")?; + pulls.push(Pull { + destination: sink.destination, + amount: remaining, + }); + remaining = 0; + } } - Ok(()) + Ok(pulls) } -/// Compute the pull destinations for a settlement: every order's full sell -/// amount goes into the buffer PDA of its sell mint. -fn compute_pulls(ctx: &Context, intents: &[ResolvedIntent]) -> Vec<[Pull; 1]> { +/// Fulfill the swap input destinations required input tokens (typically computed by [`compute_sinks`]) +/// by constructing [`Pull`]'s necessary to fill them. +fn compute_pulls( + intents: &[ResolvedIntent], + sinks: &mut HashMap>, +) -> anyhow::Result>> { intents .iter() .map(|intent| { - let (buffer_pda, _) = find_buffer_pda(&ctx.program_id, &intent.sell.mint); - [Pull { - destination: buffer_pda, - amount: intent.data.sell_amount, - }] + sinks + .get_mut(&intent.sell.mint) + .map(|mint_sinks| carve_pulls(intent.data.sell_amount, mint_sinks)) + .unwrap_or_else(|| Ok(Vec::new())) }) .collect() } @@ -449,31 +552,110 @@ mod tests { } #[test] - fn cow_balance_accepts_covered_and_exact_mints() { - let a = Pubkey::new_unique(); - let b = Pubkey::new_unique(); - // `a` is oversold (the surplus stays in its buffer), `b` matches exactly. - let sold = HashMap::from([(a, 100), (b, 50)]); - let bought = HashMap::from([(a, 90), (b, 50)]); - assert!(ensure_cow_balance(&sold, &bought).is_ok()); + fn remainder_drops_mints_that_net_out_exactly() { + let mint = Pubkey::new_unique(); + let sold = HashMap::from([(mint, 50)]); + let bought = HashMap::from([(mint, 50)]); + assert!(union_with_positive_remainder(&sold, &bought).is_empty()); + assert!(union_with_positive_remainder(&bought, &sold).is_empty()); + } + + #[test] + fn remainder_keeps_only_what_the_other_side_does_not_cover() { + let oversold = Pubkey::new_unique(); + let overbought = Pubkey::new_unique(); + let sold = HashMap::from([(oversold, 100)]); + let bought = HashMap::from([(oversold, 90), (overbought, 11)]); + + // Called the way `run` does: surplus first, then deficits. + assert_eq!( + union_with_positive_remainder(&sold, &bought), + HashMap::from([(oversold, 10)]), + ); + assert_eq!( + union_with_positive_remainder(&bought, &sold), + HashMap::from([(overbought, 11)]), + ); + } + + #[test] + fn remainder_ignores_keys_missing_from_the_left_side() { + let only_bought = Pubkey::new_unique(); + let sold = HashMap::new(); + let bought = HashMap::from([(only_bought, 7)]); + + // A mint the left side never mentions contributes nothing, however large the + // right side's entry is. + assert!(union_with_positive_remainder(&sold, &bought).is_empty()); + assert_eq!( + union_with_positive_remainder(&bought, &sold), + HashMap::from([(only_bought, 7)]), + ); } #[test] - fn cow_balance_rejects_undersold_mint() { + fn sinks_split_a_mint_between_its_buffer_and_the_payer_wallet() { + let ctx = Context { + payer: solana_sdk::signature::Keypair::new(), + program_id: Pubkey::new_unique(), + rpc: RpcClient::new("http://localhost:8899".to_string()), + }; let mint = Pubkey::new_unique(); - let sold = HashMap::from([(mint, 10)]); - let bought = HashMap::from([(mint, 11)]); - let err = ensure_cow_balance(&sold, &bought) - .expect_err("pushing more than is sold can't be CoW'd") - .to_string(); - assert!(err.contains("can't be CoW'd"), "unexpected error: {err}"); + let sold = HashMap::from([(mint, 100)]); + let payer_pulls = HashMap::from([(mint, 30)]); + + let sinks = compute_sinks(&ctx, &sold, &payer_pulls).expect("shouldn't overflow"); + let mint_sinks = &sinks[&mint]; + let total: u64 = mint_sinks.iter().map(|p| p.amount).sum(); + assert_eq!(total, 100); + assert!(mint_sinks.iter().any(|p| p.amount == 30)); + assert!(mint_sinks.iter().any(|p| p.amount == 70)); } #[test] - fn cow_balance_rejects_mint_that_is_only_bought() { - // A mint nobody sells has nothing in its buffer to push from. - let bought = HashMap::from([(Pubkey::new_unique(), 1)]); - assert!(ensure_cow_balance(&HashMap::new(), &bought).is_err()); + fn carve_pulls_splits_across_sinks_when_one_alone_is_short() { + let buffer = Pubkey::new_unique(); + let payer_ata = Pubkey::new_unique(); + let mut mint_sinks = vec![ + Pull { + destination: buffer, + amount: 70, + }, + Pull { + destination: payer_ata, + amount: 30, + }, + ]; + + let pulls = carve_pulls(100, &mut mint_sinks).expect("overflow shouldn't happen"); + let total: u64 = pulls.iter().map(|p| p.amount).sum(); + assert_eq!(total, 100); + assert!(mint_sinks.is_empty()); + } + + #[test] + fn carve_pulls_takes_only_what_it_needs_from_the_last_sink() { + let buffer = Pubkey::new_unique(); + let mut mint_sinks = vec![Pull { + destination: buffer, + amount: 70, + }]; + + let pulls = carve_pulls(40, &mut mint_sinks).expect("overflow shouldn't happen"); + assert_eq!( + pulls, + vec![Pull { + destination: buffer, + amount: 40 + }] + ); + assert_eq!( + mint_sinks, + vec![Pull { + destination: buffer, + amount: 30 + }] + ); } #[test] diff --git a/test-cli/src/liquidity/mod.rs b/test-cli/src/liquidity/mod.rs new file mode 100644 index 0000000..fe3276b --- /dev/null +++ b/test-cli/src/liquidity/mod.rs @@ -0,0 +1,20 @@ +use std::collections::HashMap; + +use solana_instruction::Instruction; +use solana_pubkey::Pubkey; + +pub mod orca; + +/// Defines the instructions needed to cover every deficit, and the amount of sink funds needed to do so +pub struct SwapPlan { + /// Txns to execute before pulling user funds + pub setup_ixs: Vec, + /// The swap transactions which fund the deficits to the buffer + pub swap_ixs: Vec, + /// Any transactions that should be run following the pushing of user funds + pub teardown_ixs: Vec, + + /// How much of each input token needs to be pulled to the keyed token account + /// to fund the swaps + pub sinks: HashMap, +} diff --git a/test-cli/src/liquidity/orca.rs b/test-cli/src/liquidity/orca.rs new file mode 100644 index 0000000..6ead31d --- /dev/null +++ b/test-cli/src/liquidity/orca.rs @@ -0,0 +1,353 @@ +//! Orca Whirlpool swap planning +//! +//! The Whirlpools SDK is async-only, so [`OrcaClient`] bridges into it with a +//! small Tokio runtime scoped to this module so the rest of the CLI can stay +//! synchronous. + +use anyhow::Context as _; +use cow_settlement_client::cow_settlement_interface::{pda::buffer::find_buffer_pda, Pubkey}; +use orca_whirlpools::{ + fetch_splash_pool, fetch_whirlpools_by_token_pair, set_native_mint_wrapping_strategy, + swap_instructions, NativeMintWrappingStrategy, PoolInfo, SwapConfig, SwapQuote, SwapType, + WhirlpoolDeployment, +}; +use solana_client::nonblocking::rpc_client::RpcClient as AsyncRpcClient; +use solana_commitment_config::CommitmentConfig; +use solana_instruction::Instruction; +use solana_sdk::signature::Signer; +use spl_associated_token_account_interface::{ + address::get_associated_token_address_with_program_id, + instruction::create_associated_token_account_idempotent, program::ID as ATA_PROGRAM_ID, +}; +use std::collections::{HashMap, HashSet}; + +use super::SwapPlan; +use crate::cmd::Context; +use crate::network::{DEVNET_GENESIS_HASH, MAINNET_GENESIS_HASH}; + +/// Bridges this otherwise-synchronous CLI into the (async-only) Orca Whirlpools SDK. +pub struct OrcaClient { + rpc: AsyncRpcClient, + runtime: tokio::runtime::Runtime, + deployment: WhirlpoolDeployment, +} + +impl OrcaClient { + pub fn new(rpc_url: &str, commitment: CommitmentConfig) -> anyhow::Result { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .context("failed to start the Tokio runtime needed to drive the Orca SDK")?; + + // Compatibility hack: The SDK's default wraps SOL through an ephemeral keypair account. + // But we are sophisticated and want do our own wrapping. To prevent this from happening, + // set `NativeMintWrappingStrategy::None`. + set_native_mint_wrapping_strategy(NativeMintWrappingStrategy::None).map_err(|e| { + anyhow::anyhow!("failed to configure Orca's SOL-wrapping strategy: {e}") + })?; + + let rpc = AsyncRpcClient::new_with_commitment(rpc_url.to_string(), commitment); + let deployment = runtime.block_on(resolve_deployment(&rpc))?; + + Ok(Self { + rpc, + runtime, + deployment, + }) + } +} + +/// Resolve the Orca deployment configuration corresponding to the configured RPC URL +async fn resolve_deployment(rpc: &AsyncRpcClient) -> anyhow::Result { + let genesis_hash = rpc + .get_genesis_hash() + .await + .context("failed to fetch genesis hash (is the RPC URL correct?)")? + .to_string(); + + match genesis_hash.as_str() { + DEVNET_GENESIS_HASH => Ok(WhirlpoolDeployment::devnet()), + MAINNET_GENESIS_HASH => Ok(WhirlpoolDeployment::mainnet()), + other => anyhow::bail!( + "no Orca Whirlpools deployment is known for the network with genesis hash {other}.", + ), + } +} + +/// Find Orca swaps that cover every mint in `deficits` (mints the settlement +/// is short of) by drawing down `surplus` (mints the settlement has extra of), +/// greedily pairing them off. Errors if a deficit can't be fully covered by +/// the available surplus and Orca liquidity. +pub fn plan_swaps( + orca: &OrcaClient, + ctx: &Context, + surplus: &HashMap, + deficits: &HashMap, +) -> anyhow::Result { + let mut surplus_remaining = surplus.clone(); + let mut setup_ixs = Vec::new(); + let mut swap_ixs = Vec::new(); + let mut sinks: HashMap = HashMap::new(); + let mut payer_atas_created: HashSet = HashSet::new(); + + for (deficit_mint, deficit_amount) in deficits { + let mut deficit_remaining = *deficit_amount; + let (deficit_buffer, _) = find_buffer_pda(&ctx.program_id, deficit_mint); + + for (&surplus_mint, avail) in surplus_remaining.iter_mut() { + if deficit_remaining == 0 { + break; + } + if *avail == 0 { + continue; + } + + // See if there is a swap route from surplus to deficit + let Some(fill) = orca.runtime.block_on(plan_pair( + orca, + ctx.payer.pubkey(), + surplus_mint, + *deficit_mint, + deficit_buffer, + deficit_remaining, + *avail, + ))? + else { + // No route for this pair; try the next surplus mint. + continue; + }; + + if payer_atas_created.insert(surplus_mint) { + setup_ixs.push(create_associated_token_account_idempotent( + &ctx.payer.pubkey(), + &ctx.payer.pubkey(), + &surplus_mint, + &spl_token_interface::id(), + )); + } + + swap_ixs.extend(fill.instructions); + + // update the amount of funds needed to complete the settlement + let sink = sinks.entry(surplus_mint).or_insert(0); + *sink = sink + .checked_add(fill.input_used) + .with_context(|| format!("swap input tally overflow for mint {surplus_mint}"))?; + + // `plan_pair` never spends more than the `*avail` it was handed, so an + // underflow here would mean it ignored the budget. + *avail = avail.checked_sub(fill.input_used).with_context(|| { + format!("swap consumed more of mint {surplus_mint} than was available") + })?; + + // Unlike the input side, the output can legitimately overshoot, so saturating is fine here + deficit_remaining = deficit_remaining.saturating_sub(fill.output_covered); + } + + anyhow::ensure!( + deficit_remaining == 0, + "no Orca liquidity/surplus available to cover the remaining {deficit_remaining} of mint \ + {deficit_mint}'s deficit", + ); + } + + Ok(SwapPlan { + setup_ixs, + swap_ixs, + teardown_ixs: vec![], + sinks, + }) +} + +/// The result of covering (some or all of) one deficit mint from one surplus mint. +struct PairFill { + /// Instructions to execute to actually complete the swap + instructions: Vec, + /// How much of `surplus_mint` this swap consumes. + input_used: u64, + /// How much of `deficit_mint` this swap's output covers. + output_covered: u64, +} + +/// Create a route for single surplus/deficit pair. +/// Try to buy the full remaining deficit with an exact-output swap. +/// If the surplus mint can't cover that swap's worst-case input, fall back +/// to spending all of `surplus_avail` via an exact-input swap instead +/// (a partial fill, leaving the rest of the deficit for another surplus mint). +/// The proceeds are paid into `deficit_buffer` rather than the signer's wallet. +/// Returns `None` if there's no suitable Orca pool for this pair. +async fn plan_pair( + orca: &OrcaClient, + signer: Pubkey, + surplus_mint: Pubkey, + deficit_mint: Pubkey, + deficit_buffer: Pubkey, + deficit_remaining: u64, + surplus_avail: u64, +) -> anyhow::Result> { + let Some(pool) = find_pool(orca, surplus_mint, deficit_mint).await? else { + return Ok(None); + }; + + // HACK: orca's rust library only lets us put output tokens into our wallet's ATA. + // however, we actually want to put it into the buffers for the settlement program. + // So we need to search for where the output_ata appears in the transaciton, and replace + // with the actual wallet for the buffer. + let output_ata = get_associated_token_address_with_program_id( + &signer, + &deficit_mint, + &spl_token_interface::id(), + ); + + let swap_instruction_rewrites = |instructions| { + rewrite_swap_output_to_buffer( + instructions, + orca.deployment.id(), + output_ata, + deficit_buffer, + ) + }; + + let config = SwapConfig { + slippage_tolerance_bps: None, + signer: Some(signer), + whirlpool_deployment: Some(orca.deployment), + }; + + // First we try an exact_out transaction. If input funds are insufficient, this will fail + // and we can exact_in the funds we actually have instead. + let exact_out = swap_instructions( + &orca.rpc, + pool, + deficit_remaining, + deficit_mint, + SwapType::ExactOut, + config.clone(), + ) + .await + .map_err(|e| anyhow::anyhow!("failed to quote {surplus_mint} -> {deficit_mint} swap: {e}"))?; + + let SwapQuote::ExactOut(quote) = exact_out.quote else { + anyhow::bail!("Orca returned the wrong quote type for an exact-output swap"); + }; + anyhow::ensure!( + exact_out.additional_signers.is_empty(), + "swap unexpectedly requires extra signers beyond the payer", + ); + + // Exit early if we got the necessary funds + if quote.token_max_in <= surplus_avail { + return Ok(Some(PairFill { + instructions: swap_instruction_rewrites(exact_out.instructions)?, + input_used: quote.token_max_in, + output_covered: deficit_remaining, + })); + } + + // The full deficit would need more than the surplus mint has on offer; spend all of + // it via an exact-input swap instead, and leave the rest of the deficit uncovered. + let exact_in = swap_instructions( + &orca.rpc, + pool, + surplus_avail, + surplus_mint, + SwapType::ExactIn, + config, + ) + .await + .map_err(|e| anyhow::anyhow!("failed to quote {surplus_mint} -> {deficit_mint} swap: {e}"))?; + + let SwapQuote::ExactIn(quote) = exact_in.quote else { + anyhow::bail!("Orca returned the wrong quote type for an exact-input swap"); + }; + anyhow::ensure!( + exact_in.additional_signers.is_empty(), + "swap unexpectedly requires extra signers beyond the payer", + ); + + Ok(Some(PairFill { + instructions: swap_instruction_rewrites(exact_in.instructions)?, + input_used: surplus_avail, + // `token_min_out` is what the swap instruction is guaranteed to deliver even at + // the edge of its slippage tolerance; using the estimate instead could leave the + // buffer short of what FinalizeSettle expects it to push out. + output_covered: quote.token_min_out, + })) +} + +/// Pay the swap's proceeds into `buffer` instead of the signer's own `output_ata`. +/// It also removes any instructions that create the `output_ata`. +/// +/// This function is needed since orca's own library doesn't provide a way to specify swap accounts +/// outside the ATA (and using the lower level libs would be way too much more work) +fn rewrite_swap_output_to_buffer( + instructions: Vec, + whirlpool_program: Pubkey, + output_ata: Pubkey, + buffer: Pubkey, +) -> anyhow::Result> { + let mut redirected = false; + + let routed = instructions + .into_iter() + .filter_map(|mut ix| { + if ix.program_id == whirlpool_program { + for account in &mut ix.accounts { + if account.pubkey == output_ata { + account.pubkey = buffer; + redirected = true; + } + } + return Some(ix); + } + + // Orca also tries to add account creation transaction for the ATA, + // but we don't need it. + (!creates_token_account(&ix, output_ata)).then_some(ix) + }) + .collect(); + + anyhow::ensure!( + redirected, + "no swap instruction references the payer's output ATA {output_ata}; Orca's account \ + layout may have changed", + ); + + Ok(routed) +} + +/// Whether `ix` is an Associated Token Account program instruction creating `account`, +/// which every one of its variants passes as its second account. +fn creates_token_account(ix: &Instruction, account: Pubkey) -> bool { + ix.program_id == ATA_PROGRAM_ID && ix.accounts.get(1).is_some_and(|a| a.pubkey == account) +} + +/// Find the Orca Whirlpool with the most liquidity for `mint_a`/`mint_b` on the +/// cluster's deployment, across every fee tier plus the splash pool. Returns `None` +/// if none are initialized. +async fn find_pool( + orca: &OrcaClient, + mint_a: Pubkey, + mint_b: Pubkey, +) -> anyhow::Result> { + let deployment = orca.deployment; + + let mut pools = fetch_whirlpools_by_token_pair(&orca.rpc, mint_a, mint_b, Some(deployment)) + .await + .map_err(|e| anyhow::anyhow!("failed to look up Orca pools for {mint_a}/{mint_b}: {e}"))?; + + // The splash pool uses a fee tier outside the ones enumerated above; a failure here + // (e.g. it was never created for this pair) just means one fewer candidate to check. + if let Ok(splash) = fetch_splash_pool(&orca.rpc, mint_a, mint_b, Some(deployment)).await { + pools.push(splash); + } + + Ok(pools + .into_iter() + .filter_map(|pool| match pool { + PoolInfo::Initialized(pool) => Some(pool), + PoolInfo::Uninitialized(_) => None, + }) + .max_by_key(|pool| pool.data.liquidity) + .map(|pool| pool.address)) +} diff --git a/test-cli/src/main.rs b/test-cli/src/main.rs index 352c309..ce78192 100644 --- a/test-cli/src/main.rs +++ b/test-cli/src/main.rs @@ -4,6 +4,8 @@ use cow_settlement_client::cow_settlement_interface::Pubkey; mod cmd; mod helpers; mod instructions; +mod liquidity; +mod network; mod token; fn home_dir() -> String { diff --git a/test-cli/src/network.rs b/test-cli/src/network.rs new file mode 100644 index 0000000..0f1dd11 --- /dev/null +++ b/test-cli/src/network.rs @@ -0,0 +1,7 @@ +//! Identifies which Solana cluster an RPC endpoint serves, by genesis hash. + +/// Genesis hash of Solana Devnet. +pub const DEVNET_GENESIS_HASH: &str = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG"; + +/// Genesis hash of Solana Mainnet Beta. +pub const MAINNET_GENESIS_HASH: &str = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"; diff --git a/test-cli/src/token.rs b/test-cli/src/token.rs index 8950510..9495474 100644 --- a/test-cli/src/token.rs +++ b/test-cli/src/token.rs @@ -17,6 +17,8 @@ use spl_associated_token_account_interface::instruction::create_associated_token use spl_token_interface::native_mint; use spl_token_interface::state::{Account as TokenAccount, Mint}; +use crate::network::DEVNET_GENESIS_HASH; + /// Inline registry of recognised token symbols. /// Avoids an RPC round-trip for well-known mints whose decimals are fixed. /// Replace with a proper on-chain registry or quote-API lookup when available. @@ -24,8 +26,6 @@ struct KnownToken { mint: Pubkey, } -const DEVNET_GENESIS_HASH: &str = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG"; - // Temporary registry mapping solana networks (isolated by "genesis" hash) and token symbols to mint addresess. Intended to be replaced in the // future with something more robust. static REGISTRY: &[(&str, &str, KnownToken)] = &[(