From dea88b82f6933efea3e8964efff6a21f69e68138 Mon Sep 17 00:00:00 2001 From: Vraj Desai Date: Wed, 25 Feb 2026 13:55:13 +0530 Subject: [PATCH 1/3] add MetEngine smart money analytics with URL/slug resolution --- Cargo.lock | 3633 +++++++++++++++++++++++++++++++++++-- Cargo.toml | 9 +- README.md | 144 ++ src/commands/metengine.rs | 936 ++++++++++ src/commands/mod.rs | 1 + src/config.rs | 22 + src/main.rs | 10 + src/metengine.rs | 119 ++ src/output/metengine.rs | 1130 ++++++++++++ src/output/mod.rs | 1 + 10 files changed, 5833 insertions(+), 172 deletions(-) create mode 100644 src/commands/metengine.rs create mode 100644 src/metengine.rs create mode 100644 src/output/metengine.rs diff --git a/Cargo.lock b/Cargo.lock index 26a3032..ccd097d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,72 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-feature-set" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd05b6a1f0867ccce373385f007b9683a116228bad9c3a0965316209617788a8" +dependencies = [ + "ahash 0.8.12", + "solana-epoch-schedule", + "solana-hash 3.1.0", + "solana-pubkey 3.0.0", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + [[package]] name = "ahash" version = "0.7.8" @@ -13,6 +79,19 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -22,6 +101,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -30,9 +124,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4973038846323e4e69a433916522195dce2947770076c03078fc21c80ea0f1c4" +checksum = "07dc44b606f29348ce7c127e7f872a6d2df3cfeff85b7d6bba62faca75112fdd" dependencies = [ "alloy-consensus", "alloy-contract", @@ -62,9 +156,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c0dc44157867da82c469c13186015b86abef209bf0e41625e4b68bac61d728" +checksum = "4e4ff99651d46cef43767b5e8262ea228cd05287409ccb0c947cc25e70a952f9" dependencies = [ "alloy-eips", "alloy-primitives", @@ -89,9 +183,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4cdb42df3871cd6b346d6a938ec2ba69a9a0f49d1f82714bc5c48349268434" +checksum = "1a0701b0eda8051a2398591113e7862f807ccdd3315d0b441f06c2a0865a379b" dependencies = [ "alloy-consensus", "alloy-eips", @@ -103,9 +197,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca63b7125a981415898ffe2a2a696c83696c9c6bdb1671c8a912946bbd8e49e7" +checksum = "f3c83c7a3c4e1151e8cac383d0a67ddf358f37e5ea51c95a1283d897c9de0a5a" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -204,9 +298,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f7ef09f21bd1e9cb8a686f168cb4a206646804567f0889eadb8dcc4c9288c8" +checksum = "def1626eea28d48c6cc0a6f16f34d4af0001906e4f889df6c660b39c86fd044d" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -240,13 +334,13 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff42cd777eea61f370c0b10f2648a1c81e0b783066cd7269228aa993afd487f7" +checksum = "e57586581f2008933241d16c3e3f633168b3a5d2738c5c42ea5246ec5e0ef17a" dependencies = [ "alloy-primitives", "alloy-sol-types", - "http", + "http 1.4.0", "serde", "serde_json", "thiserror 2.0.18", @@ -255,9 +349,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbca04f9b410fdc51aaaf88433cbac761213905a65fe832058bcf6690585762" +checksum = "3b36c2a0ed74e48851f78415ca5b465211bd678891ba11e88fee09eac534bab1" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -281,9 +375,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d6d15e069a8b11f56bef2eccbad2a873c6dd4d4c81d04dda29710f5ea52f04" +checksum = "636c8051da58802e757b76c3b65af610b95799f72423dc955737dec73de234fd" dependencies = [ "alloy-consensus", "alloy-eips", @@ -321,9 +415,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d181c8cc7cf4805d7e589bf4074d56d55064fa1a979f005a45a62b047616d870" +checksum = "b3dd56e2eafe8b1803e325867ac2c8a4c73c9fb5f341ffd8347f9344458c5922" dependencies = [ "alloy-chains", "alloy-consensus", @@ -341,7 +435,7 @@ dependencies = [ "async-stream", "async-trait", "auto_impl", - "dashmap", + "dashmap 6.1.0", "either", "futures", "futures-utils-wasm", @@ -382,9 +476,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2792758a93ae32a32e9047c843d536e1448044f78422d71bf7d7c05149e103f" +checksum = "91577235d341a1bdbee30a463655d08504408a4d51e9f72edbfc5a622829f402" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -405,9 +499,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd720b63f82b457610f2eaaf1f32edf44efffe03ae25d537632e7d23e7929e1a" +checksum = "73234a141ecce14e2989748c04fcac23deee67a445e2c4c167cfb42d4dacd1b6" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -416,9 +510,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2dc411f13092f237d2bf6918caf80977fc2f51485f9b90cb2a2f956912c8c9" +checksum = "010e101dbebe0c678248907a2545b574a87d078d82c2f6f5d0e8e7c9a6149a10" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -437,9 +531,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ce1e0dbf7720eee747700e300c99aac01b1a95bb93f493a01e78ee28bb1a37" +checksum = "9e6d631f8b975229361d8af7b2c749af31c73b3cf1352f90e144ddb06227105e" dependencies = [ "alloy-primitives", "serde", @@ -448,9 +542,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2425c6f314522c78e8198979c8cbf6769362be4da381d4152ea8eefce383535d" +checksum = "97f40010b5e8f79b70bf163b38cd15f529b18ca88c4427c0e43441ee54e4ed82" dependencies = [ "alloy-primitives", "async-trait", @@ -463,9 +557,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ecb71ee53d8d9c3fa7bac17542c8116ebc7a9726c91b1bf333ec3d04f5a789" +checksum = "9c4ec1cc27473819399a3f0da83bc1cef0ceaac8c1c93997696e46dc74377a58" dependencies = [ "alloy-consensus", "alloy-network", @@ -552,13 +646,13 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa186e560d523d196580c48bf00f1bf62e63041f28ecf276acc22f8b27bb9f53" +checksum = "a03bb3f02b9a7ab23dacd1822fa7f69aa5c8eefcdcf57fad085e0b8d76fb4334" dependencies = [ "alloy-json-rpc", "auto_impl", - "base64", + "base64 0.22.1", "derive_more", "futures", "futures-utils-wasm", @@ -575,9 +669,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa501ad58dd20acddbfebc65b52e60f05ebf97c52fa40d1b35e91f5e2da0ad0e" +checksum = "5ce599598ef8ebe067f3627509358d9faaa1ef94f77f834a7783cd44209ef55c" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -608,9 +702,9 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.7.3" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa0c53e8c1e1ef4d01066b01c737fb62fc9397ab52c6e7bb5669f97d281b9bc" +checksum = "397406cf04b11ca2a48e6f81804c70af3f40a36abf648e11dc7416043eb0834d" dependencies = [ "darling 0.21.3", "proc-macro2", @@ -683,6 +777,15 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +[[package]] +name = "arc-swap" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" +dependencies = [ + "rustversion", +] + [[package]] name = "ark-ff" version = "0.3.0" @@ -694,7 +797,7 @@ dependencies = [ "ark-serialize 0.3.0", "ark-std 0.3.0", "derivative", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.3.3", @@ -714,7 +817,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.4.1", @@ -735,7 +838,7 @@ dependencies = [ "digest 0.10.7", "educe", "itertools 0.13.0", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "zeroize", @@ -777,7 +880,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "quote", "syn 1.0.109", @@ -789,7 +892,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -802,7 +905,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -827,7 +930,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std 0.4.0", "digest 0.10.7", - "num-bigint", + "num-bigint 0.4.6", ] [[package]] @@ -839,7 +942,7 @@ dependencies = [ "ark-std 0.5.0", "arrayvec", "digest 0.10.7", - "num-bigint", + "num-bigint 0.4.6", ] [[package]] @@ -872,6 +975,12 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -881,6 +990,51 @@ dependencies = [ "serde", ] +[[package]] +name = "ascii" +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 = "assert_cmd" version = "2.1.2" @@ -896,6 +1050,29 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "async-compression" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d67d43201f4d20c78bcda740c142ca52482d81da80681533d33bf3f0596c8e2" +dependencies = [ + "compression-codecs", + "compression-core", + "pin-project-lite", + "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-stream" version = "0.3.6" @@ -980,6 +1157,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" @@ -992,6 +1175,15 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -1028,6 +1220,9 @@ name = "bitflags" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +dependencies = [ + "serde_core", +] [[package]] name = "bitvec" @@ -1110,6 +1305,36 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.12.1" @@ -1127,6 +1352,16 @@ version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + [[package]] name = "byte-slice-cast" version = "1.2.3" @@ -1161,6 +1396,26 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -1191,6 +1446,15 @@ 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" version = "1.2.56" @@ -1221,11 +1485,33 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cfg_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.0", +] + [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", @@ -1235,6 +1521,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.60" @@ -1299,6 +1595,19 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + [[package]] name = "combine" version = "4.6.7" @@ -1309,6 +1618,46 @@ dependencies = [ "memchr", ] +[[package]] +name = "compression-codecs" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" +dependencies = [ + "brotli", + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.61.2", +] + [[package]] name = "const-hex" version = "1.17.0" @@ -1316,7 +1665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "proptest", "serde_core", ] @@ -1391,6 +1740,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.4.0" @@ -1407,39 +1765,115 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] -name = "crossbeam-utils" -version = "0.8.21" +name = "crc32fast" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] [[package]] -name = "crunchy" -version = "0.2.4" +name = "crossbeam-channel" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] [[package]] -name = "crypto-bigint" -version = "0.5.5" +name = "crossbeam-deque" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "generic-array", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version 0.4.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "darling" version = "0.21.3" @@ -1510,6 +1944,19 @@ dependencies = [ "syn 2.0.117", ] +[[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 = "dashmap" version = "6.1.0" @@ -1524,6 +1971,12 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + [[package]] name = "der" version = "0.7.10" @@ -1534,6 +1987,20 @@ 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.6", + "num-traits", + "rusticata-macros", +] + [[package]] name = "deranged" version = "0.5.8" @@ -1544,6 +2011,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + [[package]] name = "derivative" version = "2.2.0" @@ -1637,6 +2110,29 @@ dependencies = [ "syn 2.0.117", ] +[[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.117", +] + [[package]] name = "dunce" version = "1.0.5" @@ -1664,6 +2160,31 @@ dependencies = [ "spki", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "educe" version = "0.6.0" @@ -1705,6 +2226,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -1762,6 +2289,39 @@ version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "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.2", + "siphasher", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1798,9 +2358,15 @@ checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + [[package]] name = "ff" version = "0.13.1" @@ -1811,12 +2377,42 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "five8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_const" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c31d7d36c43fe39d89e55711858b4da8be7eb6dabac23c7289b1a19489406" + [[package]] name = "fixed-hash" version = "0.8.0" @@ -1829,6 +2425,16 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "float-cmp" version = "0.10.0" @@ -1948,6 +2554,12 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.32" @@ -1973,15 +2585,25 @@ checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", "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" @@ -2018,6 +2640,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", + "rand_core 0.10.0", "wasip2", "wasip3", ] @@ -2028,6 +2651,26 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap 5.5.3", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -2050,7 +2693,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.4.0", "indexmap 2.13.0", "slab", "tokio", @@ -2058,13 +2701,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.8", ] [[package]] @@ -2075,10 +2727,12 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.1.5", ] @@ -2128,6 +2782,12 @@ dependencies = [ "arrayvec", ] +[[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" @@ -2146,6 +2806,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[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.4.0" @@ -2163,7 +2834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.4.0", ] [[package]] @@ -2174,7 +2845,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http", + "http 1.4.0", "http-body", "pin-project-lite", ] @@ -2196,7 +2867,7 @@ dependencies = [ "futures-channel", "futures-core", "h2", - "http", + "http 1.4.0", "http-body", "httparse", "itoa", @@ -2213,7 +2884,7 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http", + "http 1.4.0", "hyper", "hyper-util", "rustls", @@ -2221,7 +2892,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -2230,11 +2901,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.4.0", "http-body", "hyper", "ipnet", @@ -2430,6 +3101,28 @@ dependencies = [ "serde_core", ] +[[package]] +name = "indicatif" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +dependencies = [ + "console", + "portable-atomic", + "unicode-width", + "unit-prefix", + "web-time", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -2461,6 +3154,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -2493,7 +3195,7 @@ checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", "cfg-if", - "combine", + "combine 4.6.7", "jni-sys", "log", "thiserror 1.0.69", @@ -2519,14 +3221,29 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.88" +version = "0.3.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e709f3e3d22866f9c25b3aff01af289b18422cc8b4262fb19103ee80fe513d" +checksum = "f4eacb0641a310445a4c513f2a5e23e19952e269c6a38887254d5f837a305506" dependencies = [ "once_cell", "wasm-bindgen", ] +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "k256" version = "0.13.4" @@ -2547,7 +3264,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -2561,7 +3278,13 @@ dependencies = [ ] [[package]] -name = "leb128fmt" +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" @@ -2647,12 +3370,59 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.1.1" @@ -2685,12 +3455,72 @@ dependencies = [ "libc", ] +[[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 = "normalize-line-endings" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -2701,12 +3531,33 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -2716,6 +3567,29 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2752,6 +3626,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.117", @@ -2771,6 +3646,15 @@ dependencies = [ "smallvec", ] +[[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.3" @@ -2783,6 +3667,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl-probe" version = "0.2.1" @@ -2834,6 +3724,12 @@ dependencies = [ "syn 2.0.117", ] +[[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" @@ -2863,12 +3759,45 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + [[package]] name = "pest" version = "2.8.6" @@ -2964,6 +3893,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "polymarket-cli" version = "0.1.4" @@ -2976,13 +3911,20 @@ dependencies = [ "dirs", "polymarket-client-sdk", "predicates", + "reqwest 0.13.2", + "reqwest-middleware 0.5.1", "rust_decimal", "rust_decimal_macros", "rustyline", "serde", "serde_json", + "solana-client", + "solana-keypair", "tabled", "tokio", + "x402-chain-solana", + "x402-reqwest", + "x402-types", ] [[package]] @@ -2994,10 +3936,10 @@ dependencies = [ "alloy", "async-stream", "async-trait", - "base64", + "base64 0.22.1", "bon", "chrono", - "dashmap", + "dashmap 6.1.0", "futures", "hmac", "phf", @@ -3017,6 +3959,24 @@ dependencies = [ "uuid", ] +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + [[package]] name = "potential_utf" version = "0.1.4" @@ -3171,6 +4131,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[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" @@ -3205,6 +4189,7 @@ checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "aws-lc-rs", "bytes", + "fastbloom", "getrandom 0.3.4", "lru-slab", "rand 0.9.2", @@ -3212,6 +4197,7 @@ dependencies = [ "rustc-hash", "rustls", "rustls-pki-types", + "rustls-platform-verifier", "slab", "thiserror 2.0.18", "tinyvec", @@ -3287,6 +4273,17 @@ dependencies = [ "serde", ] +[[package]] +name = "rand" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +dependencies = [ + "chacha20", + "getrandom 0.4.1", + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -3326,6 +4323,12 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_core" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" + [[package]] name = "rand_xorshift" version = "0.4.0" @@ -3344,6 +4347,35 @@ dependencies = [ "rustversion", ] +[[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.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +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" @@ -3409,9 +4441,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rend" @@ -3428,10 +4460,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", - "http", + "futures-util", + "http 1.4.0", "http-body", "http-body-util", "hyper", @@ -3457,7 +4491,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -3466,12 +4500,13 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "encoding_rs", "futures-core", + "futures-util", "h2", - "http", + "http 1.4.0", "http-body", "http-body-util", "hyper", @@ -3480,6 +4515,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "percent-encoding", "pin-project-lite", "quinn", @@ -3501,6 +4537,36 @@ dependencies = [ "web-sys", ] +[[package]] +name = "reqwest-middleware" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e" +dependencies = [ + "anyhow", + "async-trait", + "http 1.4.0", + "reqwest 0.12.28", + "serde", + "thiserror 1.0.69", + "tower-service", +] + +[[package]] +name = "reqwest-middleware" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "199dda04a536b532d0cc04d7979e39b1c763ea749bf91507017069c00b96056f" +dependencies = [ + "anyhow", + "async-trait", + "http 1.4.0", + "reqwest 0.13.2", + "serde", + "thiserror 2.0.18", + "tower-service", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -3577,7 +4643,7 @@ dependencies = [ "bytes", "fastrlp 0.3.1", "fastrlp 0.4.0", - "num-bigint", + "num-bigint 0.4.6", "num-integer", "num-traits", "parity-scale-codec", @@ -3624,6 +4690,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + [[package]] name = "rustc-hash" version = "2.1.1" @@ -3654,6 +4726,15 @@ dependencies = [ "semver 1.0.27", ] +[[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" @@ -3775,7 +4856,7 @@ dependencies = [ "libc", "log", "memchr", - "nix", + "nix 0.29.0", "radix_trie", "unicode-segmentation", "unicode-width", @@ -3947,16 +5028,35 @@ dependencies = [ ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "serde-big-array" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" dependencies = [ - "serde_derive", + "serde", ] [[package]] -name = "serde_derive" +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" @@ -4021,7 +5121,7 @@ version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", @@ -4057,97 +5157,2017 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.10.9" +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "solana-account" +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.1.0", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-decoder" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6a5b65d6fb868dbb2266c6f8c12d352355e7cefcb79dd7e352c48eb5f93f0b" +dependencies = [ + "Inflector", + "base64 0.22.1", + "bincode", + "bs58", + "bv", + "serde", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-config-interface", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-instruction", + "solana-loader-v3-interface", + "solana-nonce", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar", + "solana-vote-interface", + "spl-generic-token", + "spl-token-2022-interface", + "spl-token-group-interface", + "spl-token-interface", + "spl-token-metadata-interface", + "thiserror 2.0.18", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a014e9accf57f76bdc51ac1b4e52319728b15accac62ed7a924fe67c2f0509e5" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_json", + "solana-account", + "solana-pubkey 3.0.0", + "zstd", +] + +[[package]] +name = "solana-account-info" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3397241392f5756925029acaa8515dc70fcbe3d8059d4885d7d6533baf64fd" +dependencies = [ + "solana-address 2.2.0", + "solana-program-error", + "solana-program-memory", +] + +[[package]] +name = "solana-address" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ecac8e1b7f74c2baa9e774c42817e3e75b20787134b76cc4d45e8a604488f5" +dependencies = [ + "solana-address 2.2.0", +] + +[[package]] +name = "solana-address" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c5d02824391b072dc5cd0aaa85fb0af9784a21d23286a767994d1e8a322131" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "five8", + "five8_const", + "serde", + "serde_derive", + "sha2-const-stable", + "solana-atomic-u64", + "solana-define-syscall 5.0.0", + "solana-program-error", + "solana-sanitize", + "solana-sha256-hasher", + "wincode", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e8df0b083c10ce32490410f3795016b1b5d9b4d094658c0a5e496753645b7cd" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-instruction-error", + "solana-pubkey 4.1.0", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085db4906d89324cef2a30840d59eaecf3d4231c560ec7c9f6614a93c652f501" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-borsh" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4a37fc44f0633779a619840b5117c2a895996cec57eb3dc10597fac7867875" +dependencies = [ + "borsh", +] + +[[package]] +name = "solana-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28412018d248fc57d9746ba2ef23971a001127ab79f3e86ffeb96210fe557b09" +dependencies = [ + "async-trait", + "bincode", + "dashmap 5.5.3", + "futures", + "futures-util", + "indexmap 2.13.0", + "indicatif", + "log", + "quinn", + "rayon", + "solana-account", + "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", + "solana-net-utils", + "solana-pubkey 3.0.0", + "solana-pubsub-client", + "solana-quic-client", + "solana-quic-definitions", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", + "solana-signature", + "solana-signer", + "solana-streamer", + "solana-time-utils", + "solana-tpu-client", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-udp-client", + "thiserror 2.0.18", + "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", + "solana-commitment-config", + "solana-epoch-info", + "solana-hash 3.1.0", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey 3.0.0", + "solana-signature", + "solana-signer", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", +] + +[[package]] +name = "solana-clock" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cf11109c3b6115cc510f1e31f06fdd52f504271bc24ef5f1249fbbcae5f9f3" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[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.2.0", +] + +[[package]] +name = "solana-commitment-config" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1517aa49dcfa9cb793ef90e7aac81346d62ca4a546bb1a754030a033e3972e1c" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-compute-budget-interface" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8292c436b269ad23cecc8b24f7da3ab07ca111661e25e00ce0e1d22771951ab9" +dependencies = [ + "solana-instruction", + "solana-sdk-ids", +] + +[[package]] +name = "solana-config-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e401ae56aed512821cc7a0adaa412ff97fecd2dff4602be7b1330d2daec0c4" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-instruction", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-connection-cache" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec965cfd5b866a97a72490d17b8fd7db7c0f472f202e25e7f8e3573eac9cfc2" +dependencies = [ + "async-trait", + "bincode", + "crossbeam-channel", + "futures-util", + "indexmap 2.13.0", + "log", + "rand 0.8.5", + "rayon", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-time-utils", + "solana-transaction-error", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "solana-cpi" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dea26709d867aada85d0d3617db0944215c8bb28d3745b912de7db13a23280c" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-instruction", + "solana-program-error", + "solana-pubkey 4.1.0", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720e1d774f0404957bf112365b2720ca9af9b0d1bdf0a653b22cfb52dbaa9c9e" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "solana-define-syscall 3.0.0", + "subtle", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-define-syscall" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9697086a4e102d28a156b8d6b521730335d6951bd39a5e766512bbe09007cee" + +[[package]] +name = "solana-define-syscall" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e5b1c0bc1d4a4d10c88a4100499d954c09d3fecfae4912c1a074dff68b1738" + +[[package]] +name = "solana-define-syscall" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03aacdd7a61e2109887a7a7f046caebafce97ddf1150f33722eeac04f9039c73" + +[[package]] +name = "solana-derivation-path" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff71743072690fdbdfcdc37700ae1cb77485aaad49019473a81aee099b1e0b8c" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-info" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e093c84f6ece620a6b10cd036574b0cd51944231ab32d81f80f76d54aba833e6" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-epoch-rewards" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e7b0ba210593ba8ddd39d6d234d81795d1671cebf3026baa10d5dc23ac42f0" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 4.2.0", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5481e72cc4d52c169db73e4c0cd16de8bc943078aac587ec4817a75cc6388f" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[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.1.0", + "solana-sdk-ids", +] + +[[package]] +name = "solana-fee-calculator" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2a5675b2cf8d407c672dc1776492b1f382337720ddf566645ae43237a3d8c3" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "337c246447142f660f778cf6cb582beba8e28deb05b3b24bfb9ffd7c562e5f41" +dependencies = [ + "solana-hash 4.2.0", +] + +[[package]] +name = "solana-hash" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8064ea1d591ec791be95245058ca40f4f5345d390c200069d0f79bbf55bfae55" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "five8", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wincode", +] + +[[package]] +name = "solana-inflation" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e92f37a14e7c660628752833250dd3dcd8e95309876aee751d7f8769a27947c6" + +[[package]] +name = "solana-instruction" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6d22d0a6fdf345be294bb9afdcd40c296cdc095e64e7ceaa3bb3c2f608c1c" +dependencies = [ + "bincode", + "borsh", + "serde", + "serde_derive", + "solana-define-syscall 5.0.0", + "solana-instruction-error", + "solana-pubkey 4.1.0", +] + +[[package]] +name = "solana-instruction-error" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3d048edaaeef5a3dc8c01853e585539a74417e4c2d43a9e2c161270045b838" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-program-error", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ddf67876c541aa1e21ee1acae35c95c6fbc61119814bfef70579317a5e26955" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-instruction-error", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keypair" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d3c6690dc56679545e3a31f72f590b3f5deaf48d9ea03efd2922c6a5984ed4" +dependencies = [ + "ed25519-dalek", + "five8", + "rand 0.9.2", + "solana-address 2.2.0", + "solana-seed-phrase", + "solana-signature", + "solana-signer", +] + +[[package]] +name = "solana-last-restart-slot" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcda154ec827f5fc1e4da0af3417951b7e9b8157540f81f936c4a8b1156134d0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee44c9b1328c5c712c68966fb8de07b47f3e7bac006e74ddd1bb053d3e46e5d" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey 3.0.0", + "solana-sdk-ids", +] + +[[package]] +name = "solana-measure" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eb8079c13f0925bb65614d189365a771663d6207e43ced65b11909305531483" + +[[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.2.0", + "solana-hash 4.2.0", + "solana-instruction", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-transaction-error", +] + +[[package]] +name = "solana-metrics" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98359394fc09ac87337ec139cfaa2c7fe469feb584f417fe401a2527a7536013" +dependencies = [ + "crossbeam-channel", + "gethostname", + "log", + "reqwest 0.12.28", + "solana-cluster-type", + "solana-sha256-hasher", + "solana-time-utils", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-msg" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726b7cbbc6be6f1c6f29146ac824343b9415133eee8cce156452ad1db93f8008" +dependencies = [ + "solana-define-syscall 5.0.0", +] + +[[package]] +name = "solana-net-utils" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202905ad5fba5270032f361208146faf1f750acff8ea0ec34c6c34b52da2b27f" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "cfg-if", + "dashmap 5.5.3", + "itertools 0.12.1", + "log", + "nix 0.30.1", + "rand 0.8.5", + "serde", + "socket2", + "solana-serde", + "solana-svm-type-overrides", + "tokio", + "url", +] + +[[package]] +name = "solana-nonce" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc469152a63284ef959b80c59cda015262a021da55d3b8fe42171d89c4b64f8" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash 4.2.0", + "solana-pubkey 4.1.0", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-packet" +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]] +name = "solana-perf" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1de1a806f091fd0d1585d607412c21872e0476e9597820c6cfb6e08973ac71" +dependencies = [ + "ahash 0.8.12", + "bincode", + "bv", + "bytes", + "caps", + "curve25519-dalek", + "dlopen2", + "fnv", + "libc", + "log", + "nix 0.30.1", + "rand 0.8.5", + "rayon", + "serde", + "solana-hash 3.1.0", + "solana-message", + "solana-metrics", + "solana-packet", + "solana-pubkey 3.0.0", + "solana-rayon-threadlimit", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-time-utils", + "solana-transaction-context", +] + +[[package]] +name = "solana-program-entrypoint" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c9b0a1ff494e05f503a08b3d51150b73aa639544631e510279d6375f290997" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-program-error", + "solana-pubkey 4.1.0", +] + +[[package]] +name = "solana-program-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" +dependencies = [ + "borsh", +] + +[[package]] +name = "solana-program-memory" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4068648649653c2c50546e9a7fb761791b5ab0cda054c771bb5808d3a4b9eb52" +dependencies = [ + "solana-define-syscall 4.0.1", +] + +[[package]] +name = "solana-program-option" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7b4ddb464f274deb4a497712664c3b612e3f5f82471d4e47710fc4ab1c3095" + +[[package]] +name = "solana-program-pack" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7701cb15b90667ae1c89ef4ac35a59c61e66ce58ddee13d729472af7f41d59" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8909d399deb0851aa524420beeb5646b115fd253ef446e35fe4504c904da3941" +dependencies = [ + "solana-address 1.1.0", +] + +[[package]] +name = "solana-pubkey" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b06bd918d60111ee1f97de817113e2040ca0cedb740099ee8d646233f6b906c" +dependencies = [ + "solana-address 2.2.0", +] + +[[package]] +name = "solana-pubsub-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3daa2eb063d4ad87f84818058e5b5694e99a3228dc7b9b00622931f324171968" +dependencies = [ + "crossbeam-channel", + "futures-util", + "http 0.2.12", + "log", + "semver 1.0.27", + "serde", + "serde_json", + "solana-account-decoder-client-types", + "solana-clock", + "solana-pubkey 3.0.0", + "solana-rpc-client-types", + "solana-signature", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1192f277ab11b25dc71c6f3409af0b311845237c29791485658cd67368e490f4" +dependencies = [ + "async-lock", + "async-trait", + "futures", + "itertools 0.12.1", + "log", + "quinn", + "quinn-proto", + "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", + "solana-signer", + "solana-streamer", + "solana-tls-utils", + "solana-transaction-error", + "thiserror 2.0.18", + "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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1efd11b13a6fe84bdceed4316ded099fb4539da723c7822897c99ff75b71e17" +dependencies = [ + "log", + "num_cpus", +] + +[[package]] +name = "solana-rent" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e860d5499a705369778647e97d760f7670adfb6fc8419dd3d568deccd46d5487" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[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-rpc-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de17e2526aee596e7eb0326e675fe5dfe0c4476d96149b31d910a5b3e0860c" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bincode", + "bs58", + "futures", + "indicatif", + "log", + "reqwest 0.12.28", + "reqwest-middleware 0.4.2", + "semver 1.0.27", + "serde", + "serde_json", + "solana-account", + "solana-account-decoder", + "solana-account-decoder-client-types", + "solana-clock", + "solana-commitment-config", + "solana-epoch-info", + "solana-epoch-schedule", + "solana-feature-gate-interface", + "solana-hash 3.1.0", + "solana-instruction", + "solana-message", + "solana-pubkey 3.0.0", + "solana-rpc-client-api", + "solana-signature", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-version", + "solana-vote-interface", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a582104f231f27a9574fdffeb20e60cd0deefda64766a5a126bff85afdfe21" +dependencies = [ + "anyhow", + "jsonrpc-core", + "reqwest 0.12.28", + "reqwest-middleware 0.4.2", + "serde", + "serde_json", + "solana-account-decoder-client-types", + "solana-clock", + "solana-rpc-client-types", + "solana-signer", + "solana-transaction-error", + "solana-transaction-status-client-types", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6670ad3b1157cfac408b3c666009faa9e4b26ee79ef6b2d04e264e9affe687c0" +dependencies = [ + "solana-account", + "solana-commitment-config", + "solana-hash 3.1.0", + "solana-message", + "solana-nonce", + "solana-pubkey 3.0.0", + "solana-rpc-client", + "solana-sdk-ids", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-types" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceefb93da18068352dfb487122c2baf7597676dfe6378afb0a8c20bbf7320415" +dependencies = [ + "base64 0.22.1", + "bs58", + "semver 1.0.27", + "serde", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-address 1.1.0", + "solana-clock", + "solana-commitment-config", + "solana-fee-calculator", + "solana-inflation", + "solana-reward-info", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-version", + "spl-generic-token", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-sanitize" +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.18", +] + +[[package]] +name = "solana-sdk-ids" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def234c1956ff616d46c9dd953f251fa7096ddbaa6d52b165218de97882b7280" +dependencies = [ + "solana-address 2.2.0", +] + +[[package]] +name = "solana-sdk-macro" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8765316242300c48242d84a41614cb3388229ec353ba464f6fe62a733e41806f" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "156bb61a96c605fa124e052d630dba2f6fb57e08c7d15b757e1e958b3ed7b3fe" +dependencies = [ + "hashbrown 0.15.2", +] + +[[package]] +name = "solana-seed-derivable" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff7bdb72758e3bec33ed0e2658a920f1f35dfb9ed576b951d20d63cb61ecd95c" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc905b200a95f2ea9146e43f2a7181e3aeb55de6bc12afb36462d00a3c7310de" +dependencies = [ + "hmac", + "pbkdf2", + "sha2", +] + +[[package]] +name = "solana-serde" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709a93cab694c70f40b279d497639788fc2ccbcf9b4aa32273d4b361322c02dd" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serde-varint" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950e5b83e839dc0f92c66afc124bb8f40e89bc90f0579e8ec5499296d27f54e3" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7cc401931d178472358e6b78dc72d031dc08f752d7410f0e8bd259dd6f02fa" +dependencies = [ + "solana-instruction-error", + "solana-pubkey 4.1.0", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" +dependencies = [ + "sha2", + "solana-define-syscall 4.0.1", + "solana-hash 4.2.0", +] + +[[package]] +name = "solana-short-vec" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3bd991c2cc415291c86bb0b6b4d53e93d13bb40344e4c5a2884e0e4f5fa93f" +dependencies = [ + "serde_core", +] + +[[package]] +name = "solana-signature" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "132a93134f1262aa832f1849b83bec6c9945669b866da18661a427943b9e801e" +dependencies = [ + "ed25519-dalek", + "five8", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize", + "wincode", +] + +[[package]] +name = "solana-signer" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bfea97951fee8bae0d6038f39a5efcb6230ecdfe33425ac75196d1a1e3e3235" +dependencies = [ + "solana-pubkey 3.0.0", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2585f70191623887329dfb5078da3a00e15e3980ea67f42c2e10b07028419f43" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 4.2.0", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f914f6b108f5bba14a280b458d023e3621c9973f27f015a4d755b50e88d89e97" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9f6a291ba063a37780af29e7db14bdd3dc447584d8ba5b3fc4b88e2bbc982fa" +dependencies = [ + "solana-instruction", + "solana-pubkey 4.1.0", +] + +[[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", + "solana-sysvar", + "solana-sysvar-id", +] + +[[package]] +name = "solana-streamer" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edc0b36b510b293063f242837834d86b3f1cc2c67ca93488914b3b9783c6d5d" +dependencies = [ + "arc-swap", + "bytes", + "crossbeam-channel", + "dashmap 5.5.3", + "futures", + "futures-util", + "governor", + "histogram", + "indexmap 2.13.0", + "itertools 0.12.1", + "libc", + "log", + "nix 0.30.1", + "num_cpus", + "pem", + "percentage", + "quinn", + "quinn-proto", + "rand 0.8.5", + "rustls", + "smallvec", + "socket2", + "solana-keypair", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-packet", + "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.18", + "tokio", + "tokio-util", + "x509-parser", +] + +[[package]] +name = "solana-svm-feature-set" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b991162ad8f2fa5e35f15c7d2c90bf8ad3fdfc269cc1eaac199749d60420e4" + +[[package]] +name = "solana-svm-type-overrides" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c9f8e9939fd6ae4d9b1072de19500380f3dc7b990439b304b504219016cc3d" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "solana-system-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e1790547bfc3061f1ee68ea9d8dc6c973c02a163697b24263a8e9f2e6d4afa2" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-sysvar" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690d3dd88f15c21edff68eb391ef8800df7a1f5cec84ee3e8d1abf05affdf74" +dependencies = [ + "base64 0.22.1", + "bincode", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall 4.0.1", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash 4.2.0", + "solana-instruction", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey 4.1.0", + "solana-rent", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17358d1e9a13e5b9c2264d301102126cf11a47fd394cdf3dec174fe7bc96e1de" +dependencies = [ + "solana-address 2.2.0", + "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-tls-utils" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60abec26f129fee5a91a65543b7780c747becb4659a7b78d4cf89a74750eef9e" +dependencies = [ + "rustls", + "solana-keypair", + "solana-pubkey 3.0.0", + "solana-signer", + "x509-parser", +] + +[[package]] +name = "solana-tpu-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed23b178ef386e89bff1ccb7639207b371692c712898c751aa471d9e29bdd304" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap 2.13.0", + "indicatif", + "log", + "rayon", + "solana-client-traits", + "solana-clock", + "solana-commitment-config", + "solana-connection-cache", + "solana-epoch-schedule", + "solana-measure", + "solana-message", + "solana-net-utils", + "solana-pubkey 3.0.0", + "solana-pubsub-client", + "solana-quic-definitions", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-signature", + "solana-signer", + "solana-transaction", + "solana-transaction-error", + "thiserror 2.0.18", + "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.2.0", + "solana-hash 4.2.0", + "solana-instruction", + "solana-instruction-error", + "solana-message", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-transaction-error", +] + +[[package]] +name = "solana-transaction-context" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5378750bacbb3e3c19203588a240e725712e2e92336aa345ece0efb67258215" +dependencies = [ + "bincode", + "serde", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sbpf", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8396904805b0b385b9de115a652fe80fd01e5b98ce0513f4fcd8184ada9bb792" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction-error", + "solana-sanitize", +] + +[[package]] +name = "solana-transaction-metrics-tracker" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "137423bee0812d668a9fe0bf0ecdb50d308ba9e22903736179d92c72ebbb336c" +dependencies = [ + "base64 0.22.1", + "bincode", + "log", + "rand 0.8.5", + "solana-packet", + "solana-perf", + "solana-short-vec", + "solana-signature", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53ca1155ae0800d267526785cadf73f5a2a79d739ecd82d3abdbd90ed704273d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_json", + "solana-account-decoder-client-types", + "solana-commitment-config", + "solana-instruction", + "solana-message", + "solana-pubkey 3.0.0", + "solana-reward-info", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-udp-client" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79f47f883810051c278e241fbcb51deb340c1e42ba8a942b15a24a6a41955b90" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-keypair", + "solana-net-utils", + "solana-streamer", + "solana-transaction-error", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "solana-version" +version = "3.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed13b707fbd80fc6afdba0afa480b02c17bf1122210f93360a6f8cf4e4d8c9b" +dependencies = [ + "agave-feature-set", + "rand 0.8.5", + "semver 1.0.27", + "serde", + "solana-sanitize", + "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", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-zk-sdk" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9602bcb1f7af15caef92b91132ec2347e1c51a72ecdbefdaefa3eac4b8711475" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "getrandom 0.2.17", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "spl-discriminator" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48cc11459e265d5b501534144266620289720b4c44522a47bc6b63cd295d2f3" +dependencies = [ + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.117", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +dependencies = [ + "proc-macro2", + "quote", + "sha2", + "syn 2.0.117", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-elgamal-registry-interface" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065f54100d118d24036283e03120b2f60cb5b7d597d3db649e13690e22d41398" +dependencies = [ + "bytemuck", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-token-confidential-transfer-proof-extraction", +] + +[[package]] +name = "spl-generic-token" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233df81b75ab99b42f002b5cdd6e65a7505ffa930624f7096a7580a56765e9cf" +dependencies = [ + "bytemuck", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "spl-memo-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4e2aedd58f858337fa609af5ad7100d4a243fdaf6a40d6eb4c28c5f19505d3" +dependencies = [ + "solana-instruction", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "spl-pod" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f3df240f67bea453d4bc5749761e45436d14b9457ed667e0300555d5c271f3" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "num_enum", + "solana-program-error", + "solana-program-option", + "solana-pubkey 3.0.0", + "solana-zk-sdk", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-program-error" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c4f6cf26cb6768110bf024bc7224326c720d711f7ad25d16f40f6cee40edb2d" +dependencies = [ + "num-derive", + "num-traits", + "num_enum", + "solana-msg", + "solana-program-error", + "spl-program-error-derive", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec8965aa4dc6c74701cbb48b9cad5af35b9a394514934949edbb357b78f840d" +dependencies = [ + "proc-macro2", + "quote", + "sha2", + "syn 2.0.117", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6927f613c9d7ce20835d3cefb602137cab2518e383a047c0eaa58054a60644c8" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878b0183d51fcd8a53e1604f4c13321894cf53227e6773c529b0d03d499a8dfd" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sdk-ids", + "solana-sysvar", + "spl-token-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-2022" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "552427d9117528d037daa0e70416d51322c8a33241317210f230304d852be61e" dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-clock", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sdk-ids", + "solana-security-txt", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-elgamal-registry-interface", + "spl-memo-interface", + "spl-pod", + "spl-token-2022-interface", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "thiserror 2.0.18", ] [[package]] -name = "sha3" -version = "0.10.8" +name = "spl-token-2022-interface" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "2fcd81188211f4b3c8a5eba7fd534c7142f9dd026123b3472492782cc72f4dc6" dependencies = [ - "digest 0.10.7", - "keccak", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "sha3-asm" -version = "0.1.5" +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" +checksum = "afbeb07f737d868f145512a4bcf9f59da275b7a3483df0add3f71eb812b689fb" dependencies = [ - "cc", - "cfg-if", + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "879a9ebad0d77383d3ea71e7de50503554961ff0f4ef6cbca39ad126e6f6da3a" +dependencies = [ + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.18", +] [[package]] -name = "signature" -version = "2.2.0" +name = "spl-token-confidential-transfer-proof-generation" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "a0cd59fce3dc00f563c6fa364d67c3f200d278eae681f4dc250240afcfe044b1" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "curve25519-dalek", + "solana-zk-sdk", + "thiserror 2.0.18", ] [[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "siphasher" -version = "1.0.2" +name = "spl-token-group-interface" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "452d0f758af20caaa10d9a6f7608232e000d4c74462f248540b3d2ddfa419776" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", +] [[package]] -name = "slab" -version = "0.4.12" +name = "spl-token-interface" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "8c564ac05a7c8d8b12e988a37d82695b5ba4db376d07ea98bc4882c81f96c7f3" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-instruction", + "solana-program-error", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "thiserror 2.0.18", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "spl-token-metadata-interface" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "9c467c7c3bd056f8fe60119e7ec34ddd6f23052c2fa8f1f51999098063b72676" dependencies = [ - "serde", + "borsh", + "num-derive", + "num-traits", + "solana-borsh", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "socket2" -version = "0.6.2" +name = "spl-transfer-hook-interface" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "c34b46b8f39bc64a9ab177a0ea8e9a58826db76f8d9d154a2400ee60baef7b1e" dependencies = [ - "libc", - "windows-sys 0.60.2", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-system-interface", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "spki" -version = "0.7.3" +name = "spl-type-length-value" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "ca20a1a19f4507a98ca4b28ff5ed54cac9b9d34ed27863e2bde50a3238f9a6ac" dependencies = [ - "base64ct", - "der", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", ] [[package]] @@ -4238,6 +7258,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" @@ -4301,9 +7333,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.25.0" +version = "3.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" dependencies = [ "fastrand", "getrandom 0.4.1", @@ -4432,7 +7464,9 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.61.2", @@ -4471,6 +7505,22 @@ dependencies = [ "tokio-util", ] +[[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.18" @@ -4480,6 +7530,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", "pin-project-lite", "tokio", ] @@ -4535,13 +7586,18 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ + "async-compression", "bitflags", "bytes", + "futures-core", "futures-util", - "http", + "http 1.4.0", "http-body", + "http-body-util", "iri-string", "pin-project-lite", + "tokio", + "tokio-util", "tower", "tower-layer", "tower-service", @@ -4565,6 +7621,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4596,6 +7653,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.4.0", + "httparse", + "log", + "rand 0.9.2", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 2.0.18", + "utf-8", + "webpki-roots 0.26.11", +] + [[package]] name = "typenum" version = "1.19.0" @@ -4626,6 +7703,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-ident" version = "1.0.24" @@ -4650,12 +7733,47 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + [[package]] name = "url" version = "2.5.8" @@ -4669,6 +7787,12 @@ dependencies = [ "serde_derive", ] +[[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" @@ -4705,6 +7829,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "wait-timeout" version = "0.2.1" @@ -4759,9 +7889,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.111" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1adf1535672f5b7824f817792b1afd731d7e843d2d04ec8f27e8cb51edd8ac" +checksum = "05d7d0fce354c88b7982aec4400b3e7fcf723c32737cef571bd165f7613557ee" dependencies = [ "cfg-if", "once_cell", @@ -4772,9 +7902,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.61" +version = "0.4.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe88540d1c934c4ec8e6db0afa536876c5441289d7f9f9123d4f065ac1250a6b" +checksum = "ee85afca410ac4abba5b584b12e77ea225db6ee5471d0aebaae0861166f9378a" dependencies = [ "cfg-if", "futures-util", @@ -4786,9 +7916,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.111" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e638317c08b21663aed4d2b9a2091450548954695ff4efa75bff5fa546b3b1" +checksum = "55839b71ba921e4f75b674cb16f843f4b1f3b26ddfcb3454de1cf65cc021ec0f" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4796,9 +7926,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.111" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c64760850114d03d5f65457e96fc988f11f01d38fbaa51b254e4ab5809102af" +checksum = "caf2e969c2d60ff52e7e98b7392ff1588bffdd1ccd4769eba27222fd3d621571" dependencies = [ "bumpalo", "proc-macro2", @@ -4809,9 +7939,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.111" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60eecd4fe26177cfa3339eb00b4a36445889ba3ad37080c2429879718e20ca41" +checksum = "0861f0dcdf46ea819407495634953cdcc8a8c7215ab799a7a7ce366be71c7b30" dependencies = [ "unicode-ident", ] @@ -4845,7 +7975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags", - "hashbrown 0.15.5", + "hashbrown 0.15.2", "indexmap 2.13.0", "semver 1.0.27", ] @@ -4866,9 +7996,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.88" +version = "0.3.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6bb20ed2d9572df8584f6dc81d68a41a625cadc6f15999d649a70ce7e3597a" +checksum = "10053fbf9a374174094915bbce141e87a6bf32ecd9a002980db4b638405e8962" dependencies = [ "js-sys", "wasm-bindgen", @@ -4893,6 +8023,15 @@ 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.6", +] + [[package]] name = "webpki-roots" version = "1.0.6" @@ -4902,6 +8041,22 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -4911,6 +8066,37 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wincode" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "466e67917609b2d40a838a5b972d1a6237c9749600cb8de8f65559b90d48485b" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror 2.0.18", + "wincode-derive", +] + +[[package]] +name = "wincode-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26a7a568eda854acc9945ed136a9d50b8c6d31911584624958808ae96eee3912" +dependencies = [ + "darling 0.21.3", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -5324,6 +8510,83 @@ dependencies = [ "tap", ] +[[package]] +name = "x402-chain-solana" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c82c55569ee5e30b75c3cf52c0d97882a9d6626307142720b1e65f8ac39d91" +dependencies = [ + "alloy-primitives", + "async-trait", + "bincode", + "rand 0.10.0", + "serde", + "serde_json", + "solana-account", + "solana-client", + "solana-commitment-config", + "solana-compute-budget-interface", + "solana-message", + "solana-pubkey 4.1.0", + "solana-signature", + "solana-signer", + "solana-transaction", + "spl-token", + "spl-token-2022", + "thiserror 2.0.18", + "tokio", + "x402-types", +] + +[[package]] +name = "x402-reqwest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b037e0f81cb9d36a35b87648150d962d8fa11b9e5b699900819f683e147085f9" +dependencies = [ + "async-trait", + "http 1.4.0", + "reqwest 0.13.2", + "reqwest-middleware 0.5.1", + "serde_json", + "x402-types", +] + +[[package]] +name = "x402-types" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1e301e6d1a47442f2d0b6965f5231ce349a0aeaeec215b4f954fddcbc2cd79" +dependencies = [ + "alloy-primitives", + "async-trait", + "base64 0.22.1", + "regex", + "rust_decimal", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.18", +] + +[[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.1" @@ -5344,7 +8607,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -5385,7 +8648,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -5446,3 +8709,31 @@ name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index a01bf05..d77892a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ path = "src/main.rs" [dependencies] polymarket-client-sdk = { version = "0.4", features = ["gamma", "data", "bridge", "clob", "ctf"] } -alloy = { version = "1.6.3", default-features = false, features = ["providers", "sol-types", "contract", "reqwest", "reqwest-rustls-tls", "signer-local", "signers"] } +alloy = { version = ">=1.6.3,<1.7", default-features = false, features = ["providers", "sol-types", "contract", "reqwest", "reqwest-rustls-tls", "signer-local", "signers"] } clap = { version = "4", features = ["derive"] } tokio = { version = "1", features = ["rt-multi-thread", "macros"] } serde_json = "1" @@ -26,6 +26,13 @@ anyhow = "1" chrono = "0.4" dirs = "6" rustyline = "15" +reqwest = { version = "0.13", features = ["json", "rustls"], default-features = false } +reqwest-middleware = { version = "0.5", features = ["json", "multipart"] } +x402-reqwest = "1.3" +x402-chain-solana = { version = "1.3", features = ["client"] } +x402-types = "1.3" +solana-keypair = "3.1" +solana-client = "3.1" [dev-dependencies] assert_cmd = "2" diff --git a/README.md b/README.md index e9a2eee..c0f928c 100644 --- a/README.md +++ b/README.md @@ -406,6 +406,131 @@ polymarket shell Supports command history. All commands work the same as the CLI, just without the `polymarket` prefix. +### MetEngine (Smart Money Analytics) + +Smart money analytics powered by [MetEngine](https://metengine.xyz). Uses the x402 payment protocol on Solana Mainnet -- no API keys, payment IS authentication. Each request is pay-per-use in USDC. + +**Setup:** + +```bash +# Set your Solana private key (Base58 format) +export METENGINE_SOLANA_KEY= + +# Or pass it per-command +polymarket --solana-key metengine trending + +# Optional: use a private Solana RPC (recommended for heavy usage) +export SOLANA_RPC_URL=https://your-rpc-endpoint.com +``` + +The Solana wallet must hold USDC on Mainnet to pay for requests. Resolution order: `--solana-key` flag > `METENGINE_SOLANA_KEY` env > config file. + +**Free endpoints (no wallet needed):** + +```bash +polymarket metengine health # API status +polymarket metengine pricing # Endpoint pricing tiers +``` + +**Market Discovery:** + +```bash +# Trending markets by volume spike, trade count, or smart money inflow +polymarket metengine trending --timeframe 24h --sort-by volume_spike --limit 20 + +# Search markets +polymarket metengine search "bitcoin" --status active --sort-by relevance + +# Market categories with volume/trade stats +polymarket metengine categories --timeframe 24h + +# Platform-wide statistics +polymarket metengine platform-stats --timeframe 7d + +# OHLCV price history (accepts condition ID, slug, or Polymarket URL) +polymarket metengine price-history 0xCONDITION_ID --timeframe 7d --bucket-size 1h +polymarket metengine price-history https://polymarket.com/event/foo/bar-slug --timeframe 7d +polymarket metengine price-history bar-slug --timeframe 7d + +# Similar markets (overlapping traders) +polymarket metengine similar 0xCONDITION_ID --limit 10 + +# Smart money opportunity scanner +polymarket metengine opportunities --min-signal-strength moderate --min-smart-wallets 3 + +# Highest smart money conviction +polymarket metengine high-conviction --min-smart-wallets 5 --min-avg-score 65 + +# Capital flow across categories +polymarket metengine capital-flow --timeframe 7d --smart-money-only + +# Volume heatmap +polymarket metengine volume-heatmap --timeframe 24h --group-by category + +# Recently resolved markets with smart money accuracy +polymarket metengine resolutions --sort-by smart_money_accuracy --limit 25 + +# Dumb money positions (low-score traders) +polymarket metengine dumb-money 0xCONDITION_ID --max-score 30 +``` + +**Intelligence & Trades:** + +```bash +# Deep smart money intelligence (accepts condition ID, slug, or URL) +polymarket metengine intelligence 0xCONDITION_ID --top-n-wallets 10 +polymarket metengine intelligence https://polymarket.com/event/foo/bar-slug + +# Sentiment over time +polymarket metengine sentiment 0xCONDITION_ID --timeframe 7d --bucket-size 4h + +# Participant breakdown by tier +polymarket metengine participants 0xCONDITION_ID + +# Insider detection on a market +polymarket metengine insiders 0xCONDITION_ID --min-score 20 + +# Recent trades (filterable) +polymarket metengine trades 0xCONDITION_ID --timeframe 24h --smart-money-only + +# Whale trades across all markets (--market accepts condition ID, slug, or URL) +polymarket metengine whale-trades --min-usdc 10000 --timeframe 24h +polymarket metengine whale-trades --market https://polymarket.com/event/foo/bar-slug + +# Wallets that called outcomes early +polymarket metengine alpha-callers --days-back 30 --min-days-early 7 --min-bet-usdc 100 + +# Platform-wide insider detection +polymarket metengine wallet-insiders --min-score 50 --limit 50 +``` + +**Wallet Analytics:** + +```bash +# Full wallet profile (score, stats, positions) +polymarket metengine wallet-profile 0xWALLET + +# Recent trading activity +polymarket metengine wallet-activity 0xWALLET --timeframe 24h + +# PnL breakdown by position +polymarket metengine wallet-pnl 0xWALLET --timeframe 90d + +# Compare 2-5 wallets side by side +polymarket metengine wallet-compare "0xWALLET1,0xWALLET2" + +# Find copy-traders of a wallet +polymarket metengine copy-traders 0xWALLET --max-lag-minutes 60 + +# Top performing wallets leaderboard +polymarket metengine top-performers --timeframe 7d --metric pnl --limit 25 + +# Category specialists +polymarket metengine niche-experts "crypto" --min-category-trades 10 --sort-by category_sharpe +``` + +All MetEngine commands support `--output table` (default) and `--output json`. + ### Other ```bash @@ -461,6 +586,24 @@ polymarket clob cancel ORDER_ID polymarket clob cancel-all ``` +### Research with smart money analytics + +```bash +# Find trending markets with smart money activity +polymarket metengine trending --timeframe 24h --sort-by smart_money_inflow + +# Deep-dive into a specific market (use condition ID, slug, or full URL) +polymarket metengine intelligence 0xCONDITION_ID +polymarket metengine sentiment https://polymarket.com/event/foo/bar-slug --timeframe 7d + +# Check who's trading it +polymarket metengine whale-trades --market 0xCONDITION_ID --timeframe 24h + +# Profile a smart wallet +polymarket metengine wallet-profile 0xWALLET +polymarket metengine wallet-pnl 0xWALLET --timeframe 90d +``` + ### Script with JSON output ```bash @@ -483,6 +626,7 @@ src/ main.rs -- CLI entry point, clap parsing, error handling auth.rs -- Wallet resolution, RPC provider, CLOB authentication config.rs -- Config file (~/.config/polymarket/config.json) + metengine.rs -- x402 HTTP client (FreeClient + PaidClient with Solana signing) shell.rs -- Interactive REPL commands/ -- One module per command group output/ -- Table and JSON rendering per command group diff --git a/src/commands/metengine.rs b/src/commands/metengine.rs new file mode 100644 index 0000000..3e0a4c3 --- /dev/null +++ b/src/commands/metengine.rs @@ -0,0 +1,936 @@ +use anyhow::{Result, bail}; +use clap::{Args, Subcommand}; +use polymarket_client_sdk::gamma::{self, types::request::MarketBySlugRequest}; +use serde_json::json; + +use crate::config; +use crate::metengine::{FreeClient, PaidClient}; +use crate::output::OutputFormat; +use crate::output::metengine as out; + +/// Resolve a market identifier to a condition ID. +/// +/// Accepts: +/// - `0x...` hex condition ID (validated: 66 chars, hex digits only) +/// - `https://polymarket.com/event/.../slug` URL (extracts last path segment) +/// - bare slug (resolved via Gamma API) +async fn resolve_condition_id(input: &str) -> Result { + let trimmed = input.trim(); + + // Already a hex condition ID -- validate format + if trimmed.starts_with("0x") || trimmed.starts_with("0X") { + let hex = &trimmed[2..]; + if hex.len() != 64 || !hex.chars().all(|c| c.is_ascii_hexdigit()) { + bail!("Invalid condition ID: must be 0x followed by 64 hex characters"); + } + return Ok(trimmed.to_lowercase()); + } + + // Extract slug from URL or use as bare slug + let slug = if let Ok(url) = reqwest::Url::parse(trimmed) { + let host = url.host_str().unwrap_or_default(); + if host != "polymarket.com" && !host.ends_with(".polymarket.com") { + bail!("Only polymarket.com URLs are supported, got: {host}"); + } + url.path_segments() + .and_then(|segs| segs.filter(|s| !s.is_empty()).next_back()) + .ok_or_else(|| anyhow::anyhow!("Could not extract slug from URL"))? + .to_string() + } else { + trimmed.to_string() + }; + + // Resolve slug via Gamma API + let client = gamma::Client::default(); + let req = MarketBySlugRequest::builder().slug(&slug).build(); + let market = client + .market_by_slug(&req) + .await + .map_err(|e| anyhow::anyhow!("Failed to resolve slug '{slug}': {e}"))?; + + let cid = market + .condition_id + .ok_or_else(|| anyhow::anyhow!("Market '{slug}' has no condition_id"))?; + + Ok(cid.to_string().to_lowercase()) +} + +#[derive(Args)] +pub struct MetengineArgs { + #[command(subcommand)] + pub command: MetengineCommand, +} + +#[derive(Subcommand)] +pub enum MetengineCommand { + // -- Free endpoints -- + /// Check MetEngine API health + Health, + /// Show endpoint pricing tiers + Pricing, + + // -- Market Discovery -- + /// Trending markets by volume spike, trade count, or smart money inflow + Trending { + /// Time window: 1h, 4h, 12h, 24h, 7d + #[arg(long, default_value = "24h")] + timeframe: String, + /// Filter by category + #[arg(long)] + category: Option, + /// Sort: volume_spike, trade_count, smart_money_inflow + #[arg(long, default_value = "volume_spike")] + sort_by: String, + /// Max results (1-100) + #[arg(long, default_value = "20")] + limit: u32, + }, + /// Search markets by keyword or URL + Search { + /// Search query + query: String, + /// Filter by category + #[arg(long)] + category: Option, + /// Status: active, closing_soon, resolved + #[arg(long, default_value = "active")] + status: String, + /// Only markets with smart money signal + #[arg(long)] + has_smart_money_signal: bool, + /// Sort: relevance, volume, end_date + #[arg(long, default_value = "relevance")] + sort_by: String, + /// Max results (1-100) + #[arg(long, default_value = "20")] + limit: u32, + }, + /// List market categories with stats + Categories { + /// Include volume/trade stats + #[arg(long, default_value_t = true, action = clap::ArgAction::Set)] + include_stats: bool, + /// Time window: 24h, 7d + #[arg(long, default_value = "24h")] + timeframe: String, + }, + /// Platform-wide statistics + PlatformStats { + /// Time window: 24h, 7d, 30d + #[arg(long, default_value = "24h")] + timeframe: String, + }, + /// OHLCV price history for a market + PriceHistory { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Time window: 1h, 4h, 12h, 24h, 7d, 30d + #[arg(long, default_value = "7d")] + timeframe: String, + /// Candle size: 5m, 15m, 1h, 4h, 12h, 1d + #[arg(long, default_value = "1h")] + bucket_size: String, + }, + /// Find markets with overlapping traders + Similar { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Max results (1-50) + #[arg(long, default_value = "10")] + limit: u32, + }, + /// Smart money opportunity scanner + Opportunities { + /// Minimum signal: weak, moderate, strong + #[arg(long, default_value = "moderate")] + min_signal_strength: String, + /// Filter by category + #[arg(long)] + category: Option, + /// Only markets closing within N hours + #[arg(long)] + closing_within_hours: Option, + /// Minimum smart wallets + #[arg(long, default_value = "3")] + min_smart_wallets: u32, + /// Max results (1-100) + #[arg(long, default_value = "20")] + limit: u32, + }, + /// Markets with strongest smart money conviction + HighConviction { + /// Filter by category + #[arg(long)] + category: Option, + /// Minimum smart wallets + #[arg(long, default_value = "5")] + min_smart_wallets: u32, + /// Minimum average smart score (0-100) + #[arg(long, default_value = "65")] + min_avg_score: u32, + /// Max results (1-100) + #[arg(long, default_value = "20")] + limit: u32, + }, + /// Capital flow across categories + CapitalFlow { + /// Time window: 24h, 7d, 30d + #[arg(long, default_value = "7d")] + timeframe: String, + /// Smart money only + #[arg(long)] + smart_money_only: bool, + /// Top N categories (1-50) + #[arg(long, default_value = "20")] + top_n_categories: u32, + }, + /// Volume heatmap by category, hour, or day + VolumeHeatmap { + /// Time window: 24h, 7d, 30d + #[arg(long, default_value = "24h")] + timeframe: String, + /// Group by: category, hour_of_day, day_of_week + #[arg(long, default_value = "category")] + group_by: String, + /// Smart money only + #[arg(long)] + smart_money_only: bool, + }, + /// Recently resolved markets with smart money accuracy + Resolutions { + /// Filter by category + #[arg(long)] + category: Option, + /// Keyword filter + #[arg(long)] + query: Option, + /// Sort: resolved_recently, volume, smart_money_accuracy + #[arg(long, default_value = "resolved_recently")] + sort_by: String, + /// Max results (1-100) + #[arg(long, default_value = "25")] + limit: u32, + }, + /// Dumb money positions on a market (low-score traders) + DumbMoney { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Max wallet score (0-100) + #[arg(long, default_value = "30")] + max_score: u32, + /// Minimum trades + #[arg(long, default_value = "5")] + min_trades: u32, + /// Max results (1-200) + #[arg(long, default_value = "50")] + limit: u32, + }, + + // -- Intelligence / Trades -- + /// Deep smart money intelligence for a market + Intelligence { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Top N wallets to analyze (1-50) + #[arg(long, default_value = "10")] + top_n_wallets: u32, + }, + /// Market sentiment over time + Sentiment { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Time window: 24h, 7d, 30d + #[arg(long, default_value = "7d")] + timeframe: String, + /// Bucket size: 1h, 4h, 12h, 1d + #[arg(long, default_value = "4h")] + bucket_size: String, + }, + /// Market participant breakdown by tier + Participants { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + }, + /// Detect insider trading patterns on a market + Insiders { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Max results (1-100) + #[arg(long, default_value = "25")] + limit: u32, + /// Minimum insider score (0-100) + #[arg(long, default_value = "20")] + min_score: u32, + }, + /// Recent trades on a market + Trades { + /// Market condition ID (0x...), slug, or Polymarket URL + market: String, + /// Time window: 1h, 4h, 12h, 24h, 7d, 30d + #[arg(long, default_value = "24h")] + timeframe: String, + /// Filter: BUY or SELL + #[arg(long)] + side: Option, + /// Minimum USDC size + #[arg(long)] + min_usdc: Option, + /// Smart money only + #[arg(long)] + smart_money_only: bool, + /// Max results (1-500) + #[arg(long, default_value = "100")] + limit: u32, + }, + /// Large trades across all markets + WhaleTrades { + /// Minimum USDC size + #[arg(long, default_value = "10000")] + min_usdc: f64, + /// Time window: 1h, 4h, 12h, 24h, 7d, 30d + #[arg(long, default_value = "24h")] + timeframe: String, + /// Filter by market condition ID (0x...), slug, or Polymarket URL + #[arg(long)] + market: Option, + /// Filter by category + #[arg(long)] + category: Option, + /// Filter: BUY or SELL + #[arg(long)] + side: Option, + /// Smart money only + #[arg(long)] + smart_money_only: bool, + /// Max results (1-200) + #[arg(long, default_value = "50")] + limit: u32, + }, + /// Wallets that called market outcomes early + AlphaCallers { + /// Look back N days (1-90) + #[arg(long, default_value = "30")] + days_back: u32, + /// Minimum days before resolution (1-60) + #[arg(long, default_value = "7")] + min_days_early: u32, + /// Minimum bet size in USDC + #[arg(long, default_value = "100")] + min_bet_usdc: f64, + /// Max results (1-100) + #[arg(long, default_value = "25")] + limit: u32, + }, + /// Platform-wide insider detection + WalletInsiders { + /// Max results (1-200) + #[arg(long, default_value = "50")] + limit: u32, + /// Minimum insider score (0-100) + #[arg(long, default_value = "50")] + min_score: u32, + /// Maximum wallet age in days (1-90) + #[arg(long, default_value = "60")] + max_wallet_age_days: u32, + }, + + // -- Wallet Analytics -- + /// Full wallet profile with score, stats, positions + WalletProfile { + /// Wallet address (0x..., will be lowercased) + wallet: String, + /// Include active positions + #[arg(long, default_value_t = true, action = clap::ArgAction::Set)] + include_positions: bool, + /// Include recent trades + #[arg(long, default_value_t = true, action = clap::ArgAction::Set)] + include_trades: bool, + /// Trade history limit (1-500) + #[arg(long, default_value = "50")] + trades_limit: u32, + }, + /// Recent wallet trading activity + WalletActivity { + /// Wallet address (0x..., will be lowercased) + wallet: String, + /// Time window: 1h, 4h, 24h, 7d, 30d + #[arg(long, default_value = "24h")] + timeframe: String, + /// Filter by category + #[arg(long)] + category: Option, + /// Minimum USDC size + #[arg(long)] + min_usdc: Option, + /// Max results (1-500) + #[arg(long, default_value = "100")] + limit: u32, + }, + /// Wallet PnL breakdown by position + WalletPnl { + /// Wallet address (0x..., will be lowercased) + wallet: String, + /// Time window: 7d, 30d, 90d, all + #[arg(long, default_value = "90d")] + timeframe: String, + /// Max positions (1-200) + #[arg(long, default_value = "50")] + limit: u32, + }, + /// Compare 2-5 wallets side by side + WalletCompare { + /// Wallet addresses (2-5, comma-separated) + wallets: String, + /// Include shared positions + #[arg(long)] + include_shared_positions: bool, + }, + /// Find wallets that copy-trade a target wallet + CopyTraders { + /// Target wallet address (0x..., will be lowercased) + wallet: String, + /// Max lag in minutes (1-1440) + #[arg(long, default_value = "60")] + max_lag_minutes: u32, + /// Time window: 24h, 7d, 30d + #[arg(long, default_value = "7d")] + timeframe: String, + /// Minimum overlapping trades + #[arg(long, default_value = "3")] + min_overlap_trades: u32, + /// Max results (1-100) + #[arg(long, default_value = "20")] + limit: u32, + }, + /// Top performing wallets leaderboard + TopPerformers { + /// Time window: today, 24h, 7d, 30d, 90d, 365d + #[arg(long, default_value = "7d")] + timeframe: String, + /// Filter by category + #[arg(long)] + category: Option, + /// Rank by: pnl, roi, sharpe, win_rate, volume + #[arg(long, default_value = "pnl")] + metric: String, + /// Minimum trades + #[arg(long, default_value = "5")] + min_trades: u32, + /// Max results (1-100) + #[arg(long, default_value = "25")] + limit: u32, + }, + /// Category specialists with high sharpe/win rate + NicheExperts { + /// Category (required) + category: String, + /// Minimum trades in category + #[arg(long, default_value = "10")] + min_category_trades: u32, + /// Sort: category_sharpe, category_pnl, category_volume + #[arg(long, default_value = "category_sharpe")] + sort_by: String, + /// Max results (1-100) + #[arg(long, default_value = "25")] + limit: u32, + }, +} + +pub async fn execute( + args: MetengineArgs, + output: OutputFormat, + solana_key: Option<&str>, +) -> Result<()> { + match args.command { + MetengineCommand::Health | MetengineCommand::Pricing => { + execute_free(args.command, &output).await + } + _ => { + let key = solana_key + .map(String::from) + .or_else(|| config::resolve_solana_key(None).0); + let Some(key) = key else { + bail!( + "Solana key required for paid MetEngine endpoints.\n\ + Set METENGINE_SOLANA_KEY env var or use --solana-key flag." + ); + }; + let client = PaidClient::new(&key)?; + execute_paid(&client, args.command, &output).await + } + } +} + +async fn execute_free(command: MetengineCommand, output: &OutputFormat) -> Result<()> { + let client = FreeClient::new(); + match command { + MetengineCommand::Health => { + let data = client.get("/health").await?; + out::print_health(&data, output) + } + MetengineCommand::Pricing => { + let data = client.get("/api/v1/pricing").await?; + out::print_pricing(&data, output) + } + _ => unreachable!(), + } +} + +fn push_opt<'a>(q: &mut Vec<(&'a str, &'a str)>, key: &'a str, val: &'a Option) { + if let Some(v) = val { + q.push((key, v.as_str())); + } +} + +async fn execute_paid( + client: &PaidClient, + command: MetengineCommand, + output: &OutputFormat, +) -> Result<()> { + match command { + // -- Market Discovery (GET) -- + MetengineCommand::Trending { + timeframe, + category, + sort_by, + limit, + } => { + let limit_s = limit.to_string(); + let mut q = vec![ + ("timeframe", timeframe.as_str()), + ("sort_by", sort_by.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "category", &category); + let data = client.get("/api/v1/markets/trending", &q).await?; + out::print_trending(&data, output) + } + MetengineCommand::Search { + query, + category, + status, + has_smart_money_signal, + sort_by, + limit, + } => { + let limit_s = limit.to_string(); + let mut q = vec![ + ("query", query.as_str()), + ("status", status.as_str()), + ("sort_by", sort_by.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "category", &category); + if has_smart_money_signal { + q.push(("has_smart_money_signal", "true")); + } + let data = client.get("/api/v1/markets/search", &q).await?; + out::print_search(&data, output) + } + MetengineCommand::Categories { + include_stats, + timeframe, + } => { + let include_stats_s = include_stats.to_string(); + let q = vec![ + ("include_stats", include_stats_s.as_str()), + ("timeframe", timeframe.as_str()), + ]; + let data = client.get("/api/v1/markets/categories", &q).await?; + out::print_categories(&data, output) + } + MetengineCommand::PlatformStats { timeframe } => { + let q = vec![("timeframe", timeframe.as_str())]; + let data = client.get("/api/v1/platform/stats", &q).await?; + out::print_platform_stats(&data, output) + } + MetengineCommand::PriceHistory { + market, + timeframe, + bucket_size, + } => { + let condition_id = resolve_condition_id(&market).await?; + let q = vec![ + ("condition_id", condition_id.as_str()), + ("timeframe", timeframe.as_str()), + ("bucket_size", bucket_size.as_str()), + ]; + let data = client.get("/api/v1/markets/price-history", &q).await?; + out::print_price_history(&data, output) + } + MetengineCommand::Similar { + market, + limit, + } => { + let condition_id = resolve_condition_id(&market).await?; + let limit_s = limit.to_string(); + let q = vec![("condition_id", condition_id.as_str()), ("limit", &limit_s)]; + let data = client.get("/api/v1/markets/similar", &q).await?; + out::print_similar(&data, output) + } + MetengineCommand::Opportunities { + min_signal_strength, + category, + closing_within_hours, + min_smart_wallets, + limit, + } => { + let limit_s = limit.to_string(); + let msw_s = min_smart_wallets.to_string(); + let mut q = vec![ + ("min_signal_strength", min_signal_strength.as_str()), + ("min_smart_wallets", msw_s.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "category", &category); + let cwh_s; + if let Some(h) = closing_within_hours { + cwh_s = h.to_string(); + q.push(("closing_within_hours", cwh_s.as_str())); + } + let data = client.get("/api/v1/markets/opportunities", &q).await?; + out::print_opportunities(&data, output) + } + MetengineCommand::HighConviction { + category, + min_smart_wallets, + min_avg_score, + limit, + } => { + let limit_s = limit.to_string(); + let msw_s = min_smart_wallets.to_string(); + let mas_s = min_avg_score.to_string(); + let mut q = vec![ + ("min_smart_wallets", msw_s.as_str()), + ("min_avg_score", mas_s.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "category", &category); + let data = client.get("/api/v1/markets/high-conviction", &q).await?; + out::print_high_conviction(&data, output) + } + MetengineCommand::CapitalFlow { + timeframe, + smart_money_only, + top_n_categories, + } => { + let tnc_s = top_n_categories.to_string(); + let mut q = vec![ + ("timeframe", timeframe.as_str()), + ("top_n_categories", &tnc_s), + ]; + if smart_money_only { + q.push(("smart_money_only", "true")); + } + let data = client.get("/api/v1/markets/capital-flow", &q).await?; + out::print_capital_flow(&data, output) + } + MetengineCommand::VolumeHeatmap { + timeframe, + group_by, + smart_money_only, + } => { + let mut q = vec![ + ("timeframe", timeframe.as_str()), + ("group_by", group_by.as_str()), + ]; + if smart_money_only { + q.push(("smart_money_only", "true")); + } + let data = client.get("/api/v1/markets/volume-heatmap", &q).await?; + out::print_volume_heatmap(&data, output) + } + MetengineCommand::Resolutions { + category, + query, + sort_by, + limit, + } => { + let limit_s = limit.to_string(); + let mut q = vec![("sort_by", sort_by.as_str()), ("limit", limit_s.as_str())]; + push_opt(&mut q, "category", &category); + push_opt(&mut q, "query", &query); + let data = client.get("/api/v1/markets/resolutions", &q).await?; + out::print_resolutions(&data, output) + } + MetengineCommand::DumbMoney { + market, + max_score, + min_trades, + limit, + } => { + let condition_id = resolve_condition_id(&market).await?; + let limit_s = limit.to_string(); + let ms_s = max_score.to_string(); + let mt_s = min_trades.to_string(); + let q = vec![ + ("condition_id", condition_id.as_str()), + ("max_score", &ms_s), + ("min_trades", &mt_s), + ("limit", &limit_s), + ]; + let data = client.get("/api/v1/markets/dumb-money", &q).await?; + out::print_dumb_money(&data, output) + } + + // -- Intelligence / Trades (POST for most, GET for trades/whales/alpha/wallet-insiders) -- + MetengineCommand::Intelligence { + market, + top_n_wallets, + } => { + let condition_id = resolve_condition_id(&market).await?; + let body = json!({ + "condition_id": condition_id, + "top_n_wallets": top_n_wallets, + }); + let data = client.post("/api/v1/markets/intelligence", &body).await?; + out::print_intelligence(&data, output) + } + MetengineCommand::Sentiment { + market, + timeframe, + bucket_size, + } => { + let condition_id = resolve_condition_id(&market).await?; + let body = json!({ + "condition_id": condition_id, + "timeframe": timeframe, + "bucket_size": bucket_size, + }); + let data = client.post("/api/v1/markets/sentiment", &body).await?; + out::print_sentiment(&data, output) + } + MetengineCommand::Participants { market } => { + let condition_id = resolve_condition_id(&market).await?; + let body = json!({ "condition_id": condition_id }); + let data = client.post("/api/v1/markets/participants", &body).await?; + out::print_participants(&data, output) + } + MetengineCommand::Insiders { + market, + limit, + min_score, + } => { + let condition_id = resolve_condition_id(&market).await?; + let body = json!({ + "condition_id": condition_id, + "limit": limit, + "min_score": min_score, + }); + let data = client.post("/api/v1/markets/insiders", &body).await?; + out::print_insiders(&data, output) + } + MetengineCommand::Trades { + market, + timeframe, + side, + min_usdc, + smart_money_only, + limit, + } => { + let condition_id = resolve_condition_id(&market).await?; + let limit_s = limit.to_string(); + let mut q = vec![ + ("condition_id", condition_id.as_str()), + ("timeframe", timeframe.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "side", &side); + let mu_s = min_usdc.map(|v| v.to_string()); + push_opt(&mut q, "min_usdc", &mu_s); + if smart_money_only { + q.push(("smart_money_only", "true")); + } + let data = client.get("/api/v1/markets/trades", &q).await?; + out::print_trades(&data, output) + } + MetengineCommand::WhaleTrades { + min_usdc, + timeframe, + market, + category, + side, + smart_money_only, + limit, + } => { + let resolved_cid = match &market { + Some(m) => Some(resolve_condition_id(m).await?), + None => None, + }; + let limit_s = limit.to_string(); + let mu_s = min_usdc.to_string(); + let mut q = vec![ + ("min_usdc", mu_s.as_str()), + ("timeframe", timeframe.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "condition_id", &resolved_cid); + push_opt(&mut q, "category", &category); + push_opt(&mut q, "side", &side); + if smart_money_only { + q.push(("smart_money_only", "true")); + } + let data = client.get("/api/v1/trades/whales", &q).await?; + out::print_whale_trades(&data, output) + } + MetengineCommand::AlphaCallers { + days_back, + min_days_early, + min_bet_usdc, + limit, + } => { + let db_s = days_back.to_string(); + let mde_s = min_days_early.to_string(); + let mbu_s = min_bet_usdc.to_string(); + let limit_s = limit.to_string(); + let q = vec![ + ("days_back", db_s.as_str()), + ("min_days_early", &mde_s), + ("min_bet_usdc", &mbu_s), + ("limit", &limit_s), + ]; + let data = client.get("/api/v1/wallets/alpha-callers", &q).await?; + out::print_alpha_callers(&data, output) + } + MetengineCommand::WalletInsiders { + limit, + min_score, + max_wallet_age_days, + } => { + let limit_s = limit.to_string(); + let ms_s = min_score.to_string(); + let mwad_s = max_wallet_age_days.to_string(); + let q = vec![ + ("limit", limit_s.as_str()), + ("min_score", &ms_s), + ("max_wallet_age_days", &mwad_s), + ]; + let data = client.get("/api/v1/wallets/insiders", &q).await?; + out::print_wallet_insiders(&data, output) + } + + // -- Wallet Analytics (POST) -- + MetengineCommand::WalletProfile { + wallet, + include_positions, + include_trades, + trades_limit, + } => { + let body = json!({ + "wallet": wallet.to_lowercase(), + "include_positions": include_positions, + "include_trades": include_trades, + "trades_limit": trades_limit, + }); + let data = client.post("/api/v1/wallets/profile", &body).await?; + out::print_wallet_profile(&data, output) + } + MetengineCommand::WalletActivity { + wallet, + timeframe, + category, + min_usdc, + limit, + } => { + let mut body = json!({ + "wallet": wallet.to_lowercase(), + "timeframe": timeframe, + "limit": limit, + }); + if let Some(c) = &category { + body["category"] = json!(c); + } + if let Some(mu) = min_usdc { + body["min_usdc"] = json!(mu); + } + let data = client.post("/api/v1/wallets/activity", &body).await?; + out::print_wallet_activity(&data, output) + } + MetengineCommand::WalletPnl { + wallet, + timeframe, + limit, + } => { + let body = json!({ + "wallet": wallet.to_lowercase(), + "timeframe": timeframe, + "limit": limit, + }); + let data = client.post("/api/v1/wallets/pnl-breakdown", &body).await?; + out::print_wallet_pnl(&data, output) + } + MetengineCommand::WalletCompare { + wallets, + include_shared_positions, + } => { + let wallet_list: Vec = wallets + .split(',') + .map(|w| w.trim().to_lowercase()) + .collect(); + if wallet_list.len() < 2 || wallet_list.len() > 5 { + bail!("Provide 2-5 comma-separated wallet addresses"); + } + let body = json!({ + "wallets": wallet_list, + "include_shared_positions": include_shared_positions, + }); + let data = client.post("/api/v1/wallets/compare", &body).await?; + out::print_wallet_compare(&data, output) + } + MetengineCommand::CopyTraders { + wallet, + max_lag_minutes, + timeframe, + min_overlap_trades, + limit, + } => { + let body = json!({ + "wallet": wallet.to_lowercase(), + "max_lag_minutes": max_lag_minutes, + "timeframe": timeframe, + "min_overlap_trades": min_overlap_trades, + "limit": limit, + }); + let data = client.post("/api/v1/wallets/copy-traders", &body).await?; + out::print_copy_traders(&data, output) + } + MetengineCommand::TopPerformers { + timeframe, + category, + metric, + min_trades, + limit, + } => { + let limit_s = limit.to_string(); + let mt_s = min_trades.to_string(); + let mut q = vec![ + ("timeframe", timeframe.as_str()), + ("metric", metric.as_str()), + ("min_trades", mt_s.as_str()), + ("limit", limit_s.as_str()), + ]; + push_opt(&mut q, "category", &category); + let data = client.get("/api/v1/wallets/top-performers", &q).await?; + out::print_top_performers(&data, output) + } + MetengineCommand::NicheExperts { + category, + min_category_trades, + sort_by, + limit, + } => { + let limit_s = limit.to_string(); + let mct_s = min_category_trades.to_string(); + let q = vec![ + ("category", category.as_str()), + ("min_category_trades", &mct_s), + ("sort_by", sort_by.as_str()), + ("limit", &limit_s), + ]; + let data = client.get("/api/v1/wallets/niche-experts", &q).await?; + out::print_niche_experts(&data, output) + } + + MetengineCommand::Health | MetengineCommand::Pricing => unreachable!(), + } +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 671c0ee..800d55a 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -8,6 +8,7 @@ pub mod ctf; pub mod data; pub mod events; pub mod markets; +pub mod metengine; pub mod profiles; pub mod series; pub mod setup; diff --git a/src/config.rs b/src/config.rs index d2f5395..ec0a480 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; const ENV_VAR: &str = "POLYMARKET_PRIVATE_KEY"; const SIG_TYPE_ENV_VAR: &str = "POLYMARKET_SIGNATURE_TYPE"; pub const DEFAULT_SIGNATURE_TYPE: &str = "proxy"; +const SOLANA_KEY_ENV_VAR: &str = "METENGINE_SOLANA_KEY"; pub const NO_WALLET_MSG: &str = "No wallet configured. Run `polymarket wallet create` or `polymarket wallet import `"; @@ -17,6 +18,8 @@ pub struct Config { pub chain_id: u64, #[serde(default = "default_signature_type")] pub signature_type: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub solana_private_key: Option, } fn default_signature_type() -> String { @@ -98,6 +101,7 @@ pub fn save_wallet(key: &str, chain_id: u64, signature_type: &str) -> Result<()> private_key: key.to_string(), chain_id, signature_type: signature_type.to_string(), + solana_private_key: None, }; let json = serde_json::to_string_pretty(&config)?; let path = config_path()?; @@ -125,6 +129,24 @@ pub fn save_wallet(key: &str, chain_id: u64, signature_type: &str) -> Result<()> Ok(()) } +/// Priority: CLI flag > env var > config file. +pub fn resolve_solana_key(cli_flag: Option<&str>) -> (Option, KeySource) { + if let Some(key) = cli_flag { + return (Some(key.to_string()), KeySource::Flag); + } + if let Ok(key) = std::env::var(SOLANA_KEY_ENV_VAR) + && !key.is_empty() + { + return (Some(key), KeySource::EnvVar); + } + if let Some(config) = load_config() + && let Some(key) = config.solana_private_key + { + return (Some(key), KeySource::ConfigFile); + } + (None, KeySource::None) +} + /// Priority: CLI flag > env var > config file. pub fn resolve_key(cli_flag: Option<&str>) -> (Option, KeySource) { if let Some(key) = cli_flag { diff --git a/src/main.rs b/src/main.rs index 61af087..dd06f66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod auth; mod commands; mod config; +mod metengine; mod output; mod shell; @@ -26,6 +27,10 @@ pub(crate) struct Cli { /// Signature type: eoa, proxy, or gnosis-safe #[arg(long, global = true)] signature_type: Option, + + /// Solana private key for MetEngine x402 payments (overrides env var and config file) + #[arg(long, global = true)] + solana_key: Option, } #[derive(Subcommand)] @@ -60,6 +65,8 @@ enum Commands { Bridge(commands::bridge::BridgeArgs), /// Manage wallet and authentication Wallet(commands::wallet::WalletArgs), + /// MetEngine smart money analytics (x402-paid) + Metengine(commands::metengine::MetengineArgs), /// Check API health status Status, /// Update to the latest version @@ -184,6 +191,9 @@ pub(crate) async fn run(cli: Cli) -> anyhow::Result<()> { Commands::Wallet(args) => { commands::wallet::execute(args, &cli.output, cli.private_key.as_deref()) } + Commands::Metengine(args) => { + commands::metengine::execute(args, cli.output, cli.solana_key.as_deref()).await + } Commands::Upgrade => commands::upgrade::execute(), Commands::Status => { let status = polymarket_client_sdk::gamma::Client::default() diff --git a/src/metengine.rs b/src/metengine.rs new file mode 100644 index 0000000..c0e0511 --- /dev/null +++ b/src/metengine.rs @@ -0,0 +1,119 @@ +use anyhow::{Context, Result}; +use reqwest_middleware::ClientWithMiddleware; +use serde_json::Value; +use std::sync::Arc; +use x402_reqwest::{ReqwestWithPayments, ReqwestWithPaymentsBuild, X402Client}; + +const BASE_URL: &str = "https://agent.metengine.xyz"; +const DEFAULT_SOLANA_RPC_URL: &str = "https://api.mainnet-beta.solana.com"; + +fn solana_rpc_url() -> String { + std::env::var("SOLANA_RPC_URL").unwrap_or_else(|_| DEFAULT_SOLANA_RPC_URL.to_string()) +} + +/// Plain reqwest client for free endpoints (health, pricing). +pub struct FreeClient { + inner: reqwest::Client, +} + +impl FreeClient { + pub fn new() -> Self { + Self { + inner: reqwest::Client::new(), + } + } + + pub async fn get(&self, path: &str) -> Result { + let url = format!("{BASE_URL}{path}"); + let resp = self + .inner + .get(&url) + .send() + .await + .map_err(|e| anyhow::anyhow!("MetEngine GET {path} failed: {e:#}"))?; + handle_response(resp, path).await + } +} + +/// x402-paid reqwest client for paid endpoints. Solana signing is handled +/// automatically by the x402-reqwest middleware on HTTP 402 responses. +pub struct PaidClient { + inner: ClientWithMiddleware, +} + +impl PaidClient { + pub fn new(solana_base58_key: &str) -> Result { + let keypair = solana_keypair::Keypair::try_from_base58_string(solana_base58_key) + .map_err(|e| anyhow::anyhow!("Invalid Solana private key: {e}"))?; + let rpc = solana_client::nonblocking::rpc_client::RpcClient::new(solana_rpc_url()); + let scheme = x402_chain_solana::V2SolanaExactClient::new(Arc::new(keypair), Arc::new(rpc)); + let x402 = X402Client::new().register(scheme); + + let client = reqwest::Client::new().with_payments(x402).build(); + + Ok(Self { inner: client }) + } + + pub async fn get, V: AsRef>( + &self, + path: &str, + query: &[(K, V)], + ) -> Result { + let pairs: Vec<(&str, &str)> = query + .iter() + .map(|(k, v)| (k.as_ref(), v.as_ref())) + .collect(); + let url = reqwest::Url::parse_with_params(&format!("{BASE_URL}{path}"), &pairs) + .context("Invalid query parameters")?; + let resp = self + .inner + .get(url.as_str()) + .send() + .await + .map_err(|e| anyhow::anyhow!("MetEngine GET {path} failed: {e:#}"))?; + handle_response(resp, path).await + } + + pub async fn post(&self, path: &str, body: &Value) -> Result { + let url = format!("{BASE_URL}{path}"); + let resp = self + .inner + .post(&url) + .json(body) + .send() + .await + .map_err(|e| anyhow::anyhow!("MetEngine POST {path} failed: {e:#}"))?; + handle_response(resp, path).await + } +} + +/// Shared response handling for reqwest responses. +async fn handle_response(resp: reqwest::Response, path: &str) -> Result { + let status = resp.status(); + if !status.is_success() { + let body = resp.text().await.unwrap_or_default(); + let truncated = truncate_error(&body); + anyhow::bail!("MetEngine API error {status} on {path}: {truncated}"); + } + let json: Value = resp.json().await.context("Failed to parse response")?; + Ok(unwrap_data(json)) +} + +fn truncate_error(body: &str) -> &str { + let end = body + .char_indices() + .nth(500) + .map(|(i, _)| i) + .unwrap_or(body.len()); + &body[..end] +} + +/// If the response has a top-level `"data"` key, return its value. +/// Otherwise return the whole response as-is. +fn unwrap_data(v: Value) -> Value { + if let Value::Object(mut map) = v { + map.remove("data").unwrap_or(Value::Object(map)) + } else { + v + } +} diff --git a/src/output/metengine.rs b/src/output/metengine.rs new file mode 100644 index 0000000..e157836 --- /dev/null +++ b/src/output/metengine.rs @@ -0,0 +1,1130 @@ +use serde_json::Value; +use tabled::settings::Style; +use tabled::{Table, Tabled}; + +use super::{OutputFormat, truncate}; + +fn str_field(v: &Value, key: &str) -> String { + v.get(key) + .and_then(Value::as_str) + .unwrap_or("—") + .to_string() +} + +fn num_field(v: &Value, key: &str) -> String { + v.get(key) + .and_then(Value::as_f64) + .map(|n| format!("{n:.2}")) + .unwrap_or_else(|| "—".into()) +} + +fn int_field(v: &Value, key: &str) -> String { + v.get(key) + .and_then(Value::as_i64) + .map(|n| n.to_string()) + .unwrap_or_else(|| "—".into()) +} + +fn usd_field(v: &Value, key: &str) -> String { + v.get(key) + .and_then(Value::as_f64) + .map(|n| { + if n >= 1_000_000.0 { + format!("${:.1}M", n / 1_000_000.0) + } else if n >= 1_000.0 { + format!("${:.1}K", n / 1_000.0) + } else { + format!("${n:.2}") + } + }) + .unwrap_or_else(|| "—".into()) +} + +fn pct_field(v: &Value, key: &str) -> String { + v.get(key) + .and_then(Value::as_f64) + .map(|n| format!("{n:.1}%")) + .unwrap_or_else(|| "—".into()) +} + +fn print_json_raw(data: &Value) -> anyhow::Result<()> { + super::print_json(data) +} + +fn as_array(data: &Value) -> &[Value] { + data.as_array().map(|v| v.as_slice()).unwrap_or_default() +} + +// --------------------------------------------------------------------------- +// Free endpoints +// --------------------------------------------------------------------------- + +pub fn print_health(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("MetEngine API: {}", str_field(data, "status")); + Ok(()) + } + } +} + +pub fn print_pricing(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let tiers = data + .as_array() + .or_else(|| data.get("tiers").and_then(|v| v.as_array())); + if let Some(tiers) = tiers { + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Tier")] + tier: String, + #[tabled(rename = "Price")] + price: String, + #[tabled(rename = "Endpoints")] + endpoints: String, + } + let rows: Vec = tiers + .iter() + .map(|t| Row { + tier: str_field(t, "name"), + price: str_field(t, "price"), + endpoints: int_field(t, "endpoint_count"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } else { + println!("{}", serde_json::to_string_pretty(data)?); + } + Ok(()) + } + } +} + +// --------------------------------------------------------------------------- +// Market Discovery +// --------------------------------------------------------------------------- + +pub fn print_trending(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No trending markets found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Category")] + category: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "Trades")] + trades: String, + #[tabled(rename = "Spike")] + spike: String, + #[tabled(rename = "Smart $")] + smart_dir: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 45), + category: str_field(m, "category"), + volume: usd_field(m, "period_volume_usdc"), + trades: int_field(m, "period_trade_count"), + spike: num_field(m, "volume_spike_multiplier"), + smart_dir: str_field(m, "smart_money_net_direction"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_search(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No markets found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Category")] + category: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "Smart $")] + smart_outcome: String, + #[tabled(rename = "Price")] + price: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 50), + category: str_field(m, "category"), + volume: usd_field(m, "total_volume_usdc"), + smart_outcome: str_field(m, "smart_money_outcome"), + price: num_field(m, "leader_price"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_categories(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No categories found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Category")] + name: String, + #[tabled(rename = "Markets")] + active: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "Trades")] + trades: String, + #[tabled(rename = "Traders")] + traders: String, + } + let rows: Vec = items + .iter() + .map(|c| Row { + name: str_field(c, "name"), + active: int_field(c, "active_markets"), + volume: usd_field(c, "period_volume"), + trades: int_field(c, "period_trades"), + traders: int_field(c, "unique_traders"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_platform_stats(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let rows = vec![ + ["Timeframe".into(), str_field(data, "timeframe")], + ["Total Volume".into(), usd_field(data, "total_volume_usdc")], + ["Total Trades".into(), int_field(data, "total_trades")], + ["Active Traders".into(), int_field(data, "active_traders")], + ["Active Markets".into(), int_field(data, "active_markets")], + [ + "Resolved Markets".into(), + int_field(data, "resolved_markets"), + ], + [ + "Smart Wallets".into(), + int_field(data, "smart_wallet_count"), + ], + [ + "Avg Trade Size".into(), + usd_field(data, "avg_trade_size_usdc"), + ], + ]; + super::print_detail_table(rows); + Ok(()) + } + } +} + +pub fn print_price_history(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + if let Some(candles_map) = data.get("candles_by_outcome").and_then(|v| v.as_object()) { + for (outcome, candles) in candles_map { + println!("\nOutcome: {outcome}"); + let items = candles.as_array().map(|v| v.as_slice()).unwrap_or_default(); + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Time")] + bucket: String, + #[tabled(rename = "Open")] + open: String, + #[tabled(rename = "High")] + high: String, + #[tabled(rename = "Low")] + low: String, + #[tabled(rename = "Close")] + close: String, + #[tabled(rename = "Volume")] + volume: String, + } + let rows: Vec = items + .iter() + .map(|c| Row { + bucket: str_field(c, "bucket"), + open: num_field(c, "open"), + high: num_field(c, "high"), + low: num_field(c, "low"), + close: num_field(c, "close"), + volume: usd_field(c, "volume"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } + } + Ok(()) + } + } +} + +pub fn print_similar(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No similar markets found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Overlap %")] + overlap: String, + #[tabled(rename = "Shared")] + shared: String, + #[tabled(rename = "Volume")] + volume: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 45), + overlap: pct_field(m, "wallet_overlap_pct"), + shared: int_field(m, "shared_wallet_count"), + volume: usd_field(m, "total_volume_usdc"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_opportunities(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No opportunities found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Favors")] + favors: String, + #[tabled(rename = "Signal")] + signal: String, + #[tabled(rename = "Smart %")] + smart_pct: String, + #[tabled(rename = "Gap")] + gap: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 40), + favors: str_field(m, "smart_money_favors"), + signal: str_field(m, "signal_strength"), + smart_pct: pct_field(m, "smart_money_percentage"), + gap: num_field(m, "price_signal_gap"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_high_conviction(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No high-conviction markets found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Favors")] + favors: String, + #[tabled(rename = "Score")] + conviction: String, + #[tabled(rename = "Smart $")] + smart_usd: String, + #[tabled(rename = "Wallets")] + wallets: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 40), + favors: str_field(m, "favored_outcome"), + conviction: num_field(m, "conviction_score"), + smart_usd: usd_field(m, "total_smart_usdc"), + wallets: int_field(m, "smart_wallet_count"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_capital_flow(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Timeframe: {}", str_field(data, "timeframe")); + println!("Total Net Flow: {}", usd_field(data, "total_net_flow")); + println!( + "Biggest Inflow: {} | Biggest Outflow: {}", + str_field(data, "biggest_inflow"), + str_field(data, "biggest_outflow") + ); + let cats = data + .get("categories") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if !cats.is_empty() { + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Category")] + category: String, + #[tabled(rename = "Buy")] + buy: String, + #[tabled(rename = "Sell")] + sell: String, + #[tabled(rename = "Net Flow")] + net: String, + #[tabled(rename = "Trend")] + trend: String, + } + let rows: Vec = cats + .iter() + .map(|c| Row { + category: str_field(c, "category"), + buy: usd_field(c, "current_buy_volume"), + sell: usd_field(c, "current_sell_volume"), + net: usd_field(c, "current_net_flow"), + trend: str_field(c, "flow_trend"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } + Ok(()) + } + } +} + +pub fn print_volume_heatmap(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Total Volume: {}", usd_field(data, "total_volume")); + println!("Total Trades: {}", int_field(data, "total_trades")); + let items = data + .get("breakdown") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if !items.is_empty() { + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Label")] + label: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "Trades")] + trades: String, + #[tabled(rename = "% Total")] + pct: String, + #[tabled(rename = "Trend")] + trend: String, + } + let rows: Vec = items + .iter() + .map(|b| Row { + label: str_field(b, "label"), + volume: usd_field(b, "volume"), + trades: int_field(b, "trade_count"), + pct: pct_field(b, "pct_of_total"), + trend: str_field(b, "trend"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } + Ok(()) + } + } +} + +pub fn print_resolutions(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No resolved markets found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Winner")] + winner: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "SM Accuracy")] + accuracy: String, + } + let rows: Vec = items + .iter() + .map(|m| Row { + question: truncate(&str_field(m, "question"), 45), + winner: str_field(m, "winning_outcome"), + volume: usd_field(m, "total_volume_usdc"), + accuracy: pct_field(m, "smart_money_accuracy"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_dumb_money(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + if let Some(summary) = data.get("summary") { + println!( + "Wallets: {} | Total USDC: {} | Avg Score: {} | Consensus: {}", + int_field(summary, "total_wallets"), + usd_field(summary, "total_usdc"), + num_field(summary, "avg_score"), + str_field(summary, "consensus_outcome"), + ); + } + let positions = data + .get("positions") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if !positions.is_empty() { + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Score")] + score: String, + #[tabled(rename = "Outcome")] + outcome: String, + #[tabled(rename = "USDC")] + usdc: String, + } + let rows: Vec = positions + .iter() + .map(|p| Row { + wallet: truncate(&str_field(p, "wallet"), 14), + score: num_field(p, "score"), + outcome: str_field(p, "outcome"), + usdc: usd_field(p, "usdc_invested"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } + Ok(()) + } + } +} + +// --------------------------------------------------------------------------- +// Intelligence / Trades +// --------------------------------------------------------------------------- + +pub fn print_intelligence(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + if let Some(sm) = data.get("smart_money") { + println!( + "Smart Money Consensus: {} (strength: {})", + str_field(sm, "consensus_outcome"), + num_field(sm, "consensus_strength"), + ); + } + if let Some(sig) = data.get("signal_analysis") { + println!("Signal: {}", str_field(sig, "signal_summary")); + } + if let Some(act) = data.get("recent_activity") { + println!( + "24h: Volume {} | Trades {} | B/S Ratio {} | Trend: {}", + usd_field(act, "volume_24h"), + int_field(act, "trade_count_24h"), + num_field(act, "buy_sell_ratio"), + str_field(act, "volume_trend"), + ); + } + Ok(()) + } + } +} + +pub fn print_sentiment(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + if let Some(overall) = data.get("overall_sentiment") { + println!( + "Overall Sentiment: {} (score: {})", + str_field(overall, "label"), + num_field(overall, "score"), + ); + } + if let Some(momentum) = data.get("momentum") { + println!( + "Momentum: {} (strength: {})", + str_field(momentum, "direction"), + num_field(momentum, "strength"), + ); + } + Ok(()) + } + } +} + +pub fn print_participants(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + println!( + "Total Wallets: {} | Total USDC: {}", + int_field(data, "total_wallets"), + usd_field(data, "total_usdc"), + ); + if let Some(tiers) = data.get("tier_distribution").and_then(|v| v.as_object()) { + println!("Tier Distribution:"); + for (tier, count) in tiers { + println!(" {tier}: {count}"); + } + } + Ok(()) + } + } +} + +pub fn print_insiders(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + let items = data + .get("insiders") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if items.is_empty() { + println!("No insiders detected."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Score")] + score: String, + #[tabled(rename = "Outcome")] + outcome: String, + #[tabled(rename = "USDC")] + usdc: String, + #[tabled(rename = "Age (d)")] + age: String, + } + let rows: Vec = items + .iter() + .map(|i| Row { + wallet: truncate(&str_field(i, "wallet"), 14), + score: num_field(i, "insider_score"), + outcome: str_field(i, "outcome"), + usdc: usd_field(i, "buy_usdc"), + age: int_field(i, "wallet_age_days"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_trades(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Market: {}", str_field(data, "question")); + println!( + "Trades: {} | Volume: {}", + int_field(data, "trade_count"), + usd_field(data, "total_volume"), + ); + let items = data + .get("trades") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if !items.is_empty() { + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Side")] + side: String, + #[tabled(rename = "Outcome")] + outcome: String, + #[tabled(rename = "USDC")] + usdc: String, + #[tabled(rename = "Price")] + price: String, + #[tabled(rename = "Score")] + score: String, + } + let rows: Vec = items + .iter() + .map(|t| Row { + wallet: truncate(&str_field(t, "wallet"), 14), + side: str_field(t, "side"), + outcome: str_field(t, "outcome"), + usdc: usd_field(t, "usdc_size"), + price: num_field(t, "price"), + score: num_field(t, "wallet_score"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + } + Ok(()) + } + } +} + +pub fn print_whale_trades(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No whale trades found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Question")] + question: String, + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Side")] + side: String, + #[tabled(rename = "Outcome")] + outcome: String, + #[tabled(rename = "USDC")] + usdc: String, + #[tabled(rename = "Score")] + score: String, + } + let rows: Vec = items + .iter() + .map(|t| Row { + question: truncate(&str_field(t, "question"), 35), + wallet: truncate(&str_field(t, "wallet"), 14), + side: str_field(t, "side"), + outcome: str_field(t, "outcome"), + usdc: usd_field(t, "usdc_size"), + score: num_field(t, "wallet_score"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_alpha_callers(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No alpha callers found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Market")] + market: String, + #[tabled(rename = "Days Early")] + days_early: String, + #[tabled(rename = "Bet")] + bet: String, + #[tabled(rename = "Score")] + score: String, + #[tabled(rename = "Win Rate")] + win_rate: String, + } + let rows: Vec = items + .iter() + .map(|a| Row { + wallet: truncate(&str_field(a, "wallet"), 14), + market: truncate(&str_field(a, "market_question"), 35), + days_early: int_field(a, "days_before_resolution"), + bet: usd_field(a, "bet_size_usdc"), + score: num_field(a, "wallet_score"), + win_rate: pct_field(a, "win_rate"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_wallet_insiders(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = data + .get("candidates") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if items.is_empty() { + println!("No insider candidates found."); + return Ok(()); + } + println!("Total candidates: {}", int_field(data, "total_candidates")); + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Score")] + score: String, + #[tabled(rename = "Age (d)")] + age: String, + #[tabled(rename = "Markets")] + markets: String, + #[tabled(rename = "Buy USDC")] + buy_usdc: String, + #[tabled(rename = "Win Rate")] + win_rate: String, + } + let rows: Vec = items + .iter() + .map(|c| Row { + wallet: truncate(&str_field(c, "wallet"), 14), + score: num_field(c, "insider_score"), + age: int_field(c, "wallet_age_days"), + markets: int_field(c, "markets_traded"), + buy_usdc: usd_field(c, "total_buy_usdc"), + win_rate: pct_field(c, "win_rate"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +// --------------------------------------------------------------------------- +// Wallet Analytics +// --------------------------------------------------------------------------- + +pub fn print_wallet_profile(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Wallet: {}", str_field(data, "wallet")); + if let Some(p) = data.get("profile") { + let rows = vec![ + ["Score".into(), num_field(p, "score")], + ["Tier".into(), str_field(p, "tier")], + ["Win Rate".into(), pct_field(p, "win_rate")], + ["Sharpe".into(), num_field(p, "sharpe")], + ["Total PnL".into(), usd_field(p, "total_pnl")], + ["Total Volume".into(), usd_field(p, "total_volume")], + ["Resolved".into(), int_field(p, "resolved_positions")], + ["Category".into(), str_field(p, "primary_category")], + ]; + super::print_detail_table(rows); + } + Ok(()) + } + } +} + +pub fn print_wallet_activity(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!( + "Wallet: {} (score: {})", + str_field(data, "wallet"), + num_field(data, "wallet_score"), + ); + let items = data + .get("trades") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if items.is_empty() { + println!("No activity found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Market")] + market: String, + #[tabled(rename = "Side")] + side: String, + #[tabled(rename = "Outcome")] + outcome: String, + #[tabled(rename = "USDC")] + usdc: String, + #[tabled(rename = "Price")] + price: String, + } + let rows: Vec = items + .iter() + .map(|t| Row { + market: truncate(&str_field(t, "question"), 40), + side: str_field(t, "side"), + outcome: str_field(t, "outcome"), + usdc: usd_field(t, "usdc_size"), + price: num_field(t, "price"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_wallet_pnl(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + println!("Wallet: {}", str_field(data, "wallet")); + let rows = vec![ + ["Realized PnL".into(), usd_field(data, "total_realized_pnl")], + ["Total Positions".into(), int_field(data, "total_positions")], + ["Winning".into(), int_field(data, "winning_positions")], + ["Losing".into(), int_field(data, "losing_positions")], + ]; + super::print_detail_table(rows); + Ok(()) + } + } +} + +pub fn print_wallet_compare(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let wallets = data + .get("wallets") + .and_then(|v| v.as_array()) + .map(|v| v.as_slice()) + .unwrap_or_default(); + if wallets.is_empty() { + println!("No wallet data."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Score")] + score: String, + #[tabled(rename = "Win Rate")] + win_rate: String, + #[tabled(rename = "PnL")] + pnl: String, + #[tabled(rename = "Volume")] + volume: String, + } + let rows: Vec = wallets + .iter() + .map(|w| { + let profile = w.get("profile").unwrap_or(w); + Row { + wallet: truncate(&str_field(w, "wallet"), 14), + score: num_field(profile, "score"), + win_rate: pct_field(profile, "win_rate"), + pnl: usd_field(profile, "total_pnl"), + volume: usd_field(profile, "total_volume"), + } + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_copy_traders(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No copy traders found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Overlap")] + overlap: String, + #[tabled(rename = "Avg Lag (s)")] + lag: String, + #[tabled(rename = "Score")] + score: String, + } + let rows: Vec = items + .iter() + .map(|c| Row { + wallet: truncate(&str_field(c, "wallet"), 14), + overlap: int_field(c, "overlap_trades"), + lag: num_field(c, "avg_lag_seconds"), + score: num_field(c, "wallet_score"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_top_performers(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No top performers found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "#")] + rank: String, + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "PnL")] + pnl: String, + #[tabled(rename = "ROI")] + roi: String, + #[tabled(rename = "Win Rate")] + win_rate: String, + #[tabled(rename = "Score")] + score: String, + } + let rows: Vec = items + .iter() + .map(|w| Row { + rank: int_field(w, "rank"), + wallet: truncate(&str_field(w, "wallet"), 14), + pnl: usd_field(w, "period_pnl_usdc"), + roi: pct_field(w, "period_roi_percent"), + win_rate: pct_field(w, "period_win_rate"), + score: num_field(w, "overall_score"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} + +pub fn print_niche_experts(data: &Value, output: &OutputFormat) -> anyhow::Result<()> { + match output { + OutputFormat::Json => print_json_raw(data), + OutputFormat::Table => { + let items = as_array(data); + if items.is_empty() { + println!("No niche experts found."); + return Ok(()); + } + #[derive(Tabled)] + struct Row { + #[tabled(rename = "Wallet")] + wallet: String, + #[tabled(rename = "Sharpe")] + sharpe: String, + #[tabled(rename = "Win Rate")] + win_rate: String, + #[tabled(rename = "PnL")] + pnl: String, + #[tabled(rename = "Volume")] + volume: String, + #[tabled(rename = "Score")] + score: String, + } + let rows: Vec = items + .iter() + .map(|w| Row { + wallet: truncate(&str_field(w, "wallet"), 14), + sharpe: num_field(w, "category_sharpe"), + win_rate: pct_field(w, "category_win_rate"), + pnl: usd_field(w, "category_pnl"), + volume: usd_field(w, "category_volume"), + score: num_field(w, "overall_score"), + }) + .collect(); + println!("{}", Table::new(rows).with(Style::rounded())); + Ok(()) + } + } +} diff --git a/src/output/mod.rs b/src/output/mod.rs index cc76acd..e74562b 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -6,6 +6,7 @@ pub mod ctf; pub mod data; pub mod events; pub mod markets; +pub mod metengine; pub mod profiles; pub mod series; pub mod sports; From 415515f169ca8b7c1622215b380b22a209925110 Mon Sep 17 00:00:00 2001 From: Vraj Desai Date: Fri, 6 Mar 2026 19:12:07 +0530 Subject: [PATCH 2/3] docs: add smart wallet Kelly Criterion trading article Marketing article showcasing MetEngine's 27 CLI subcommands in the context of a quantitative trading workflow. Covers edge discovery, Kelly position sizing, smart money validation, and wallet analytics. All CLI commands verified against actual clap definitions. Fixed: - whale-trades --timeframe 48h -> 7d (valid enum values) - wallet-profile --include-positions -> --include-positions true (ArgAction::Set) Co-Authored-By: Claude Opus 4.6 --- docs/smart-wallet-kelly-ev.md | 395 ++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100644 docs/smart-wallet-kelly-ev.md diff --git a/docs/smart-wallet-kelly-ev.md b/docs/smart-wallet-kelly-ev.md new file mode 100644 index 0000000..6e3a7d5 --- /dev/null +++ b/docs/smart-wallet-kelly-ev.md @@ -0,0 +1,395 @@ +# 70% of Polymarket Traders Lose Money. One Formula Fixes That. + +Let me tell you about two traders. + +**Trader A** went dormant for seven months. Did nothing. Then in February and March 2026, he made **$1.02 million** on $7.3 million in volume -- a 14% return. + +**Trader B** made **$2.55 million in five days** in late February. Then lost **$3.66 million from that peak** in the next six days. He's currently down $1.1 million and still bleeding. + +Both are trading soccer markets on Polymarket right now. Same sport. Same contract types. Same week. + +Trader A ([WoofMaster](https://polymarket.com/profile/0x916f7165c2c836aba22edb6453cdbb5f3ea253ba)) had a system. Trader B ([pinkblanket](https://polymarket.com/profile/0x0720803c7cb0d0c5a928787b3b7ea148c6831cdb)) was dropping $2-3 million per soccer match with the risk management strategy of "I just made $2.5M so clearly I know what I'm doing." + +> **[Meme: "We are not the same" template -- Trader A: "I use a 200-year-old formula from Bell Labs to size my bets" / Trader B: "I trust my gut and bet the mortgage"]** + +An on-chain analysis by DefiOasis covering **1,733,785 unique Polymarket addresses** found that **70% have negative realized returns.** The top 0.04% -- fewer than 700 wallets -- captured 70% of the platform's $3.7 billion in total realized profits. Only 0.51% of all wallets ever profit more than $1,000. + +There's a formula for this. Every Polymarket bot uses it. Most humans have never heard of it. Let's fix that. + +--- + +## The Kelly Criterion, Explained Like You're 5 + +You find a rigged coin. It lands heads 60% of the time. You get to bet on heads over and over. + +How much of your money do you bet each flip? + +**Most people's answer:** "All of it! It's rigged in my favor!" + +**What actually happens if you bet all of it:** You hit tails once and you're broke. Game over. Do not pass go. + +**The right answer:** Bet a *specific fraction* of your money each time, and your bankroll grows as fast as mathematically possible without ever going to zero. + +That fraction is what the Kelly Criterion calculates. + +For Polymarket, the simplified version is: + +> **f = (p - m) / (1 - m)** + +- **f** = how much of your bankroll to bet +- **p** = what you think the real probability is +- **m** = the current market price + +That's it. That's the whole thing. + +--- + +## "Cool Formula. Does It Actually Work?" + +Glad you asked. Let's look at what wallets on the Polymarket leaderboard are doing *right now* -- using real on-chain data pulled March 6, 2026 from Polymarket's public APIs. + +### WoofMaster -- $1.02M profit, dormant 7 months then $1M in one month + +[WoofMaster](https://polymarket.com/profile/0x916f7165c2c836aba22edb6453cdbb5f3ea253ba) is rank #92 all-time and #19 on this week's leaderboard. $1.02M in profit on $7.28M in volume -- a 14% PnL-to-volume ratio. + +Here's the part that matters: this wallet was registered in February 2025. Then it went **completely dormant for seven months** -- August 2025 through January 2026, zero activity. PnL flatlined at -$47. + +Then February 2026 hits: + +| Month | Cumulative PnL | Monthly Change | +|---|---|---| +| Feb 2025 - Jan 2026 | -$47 | Dormant | +| Feb 2026 | +$419,819 | +$419,866 | +| Mar 2026 (6 days) | +$1,020,631 | +$600,812 | + +Seven months of nothing. Then **$1 million in 34 days.** Max drawdown: $406K. And as of March 6, the PnL has flatlined -- he may have stopped trading or is waiting for the next setup. Patience is the whole strategy. + +Was he building a model that whole time? Backtesting? Waiting for the right market conditions? We don't know. What we know is that when he finally deployed capital, his sizing was controlled enough to survive a $406K drawdown and keep compounding. + +> **[Meme: The "this is fine" dog sitting in flames, but the last panel is him in a Lambo. Caption: "WoofMaster's equity curve"]** + +### jtwyslljy -- $1.67M profit, 10 months of steady compounding + +[jtwyslljy](https://polymarket.com/profile/0x9cb990f1862568a63d8601efeebe0304225c32f2) is rank #51 all-time, #4 on this week's leaderboard ($627K this week). $1.67M in profit on $34.7M volume over 10 months. + +No moonshots. No blowups. Just steady monthly gains: + +| Month | Cumulative PnL | Monthly Change | +|---|---|---| +| May 2025 | -$76,820 | -$76,820 | +| Sep 2025 | +$43,629 | +$63,524 | +| Oct 2025 | +$199,327 | +$155,698 | +| Nov 2025 | +$316,274 | +$116,947 | +| Dec 2025 | +$156,698 | -$159,576 | +| Jan 2026 | +$704,192 | +$547,494 | +| Feb 2026 | +$1,240,980 | +$536,788 | +| Mar 2026 (6 days) | +$1,673,399 | +$432,419 | + +Started underwater. Had a losing month in December (-$160K). Kept going. January: +$547K. February: +$537K. March is on pace to be even better -- +$432K in just six days. + +Max drawdown: just $435K. That's a 34% drawdown from peak at the worst point. Compare that to the losers we'll see below. + +### gmanas -- $5.01M profit, the bot that never sleeps + +[gmanas](https://polymarket.com/profile/0xe90bec87d9ef430f27f9dcfe72c34b76967d5da2) is rank #13 all-time and #20 on this week's leaderboard ($215K this week). $5.01M in profit on **$529M** in total volume. Active since November 2025 -- just four months. + +That volume isn't a typo. Over half a billion dollars in four months. Activity data shows **455 trades in a 21-hour window** -- that's 21+ trades per hour. No human is doing that. + +This is a bot running Kelly sizing at scale: identify edge, calculate position size, execute, adjust as bankroll changes. All automated. All disciplined. No emotions. PnL-to-volume ratio of just 0.95% -- razor-thin margins ground out at enormous scale. + +| Month | Monthly PnL | +|---|---| +| Nov 2025 | +$1,231,707 | +| Dec 2025 | +$1,105,366 | +| Jan 2026 | +$2,654,778 | +| Feb 2026 | -$644,520 | +| Mar 2026 (6 days) | +$661,186 | + +Even the bot had a losing month (February). Max drawdown: $3.18M. The system kept running. Six days into March: +$661K and recovering. + +### pinkblanket -- $2.55M to -$1.1M in 14 days + +[pinkblanket](https://polymarket.com/profile/0x0720803c7cb0d0c5a928787b3b7ea148c6831cdb). This wallet is two weeks old. Here's every single day: + +| Date | Cumulative PnL | Daily Change | +|---|---|---| +| Feb 20 | -$118,386 | -$118,386 | +| Feb 22 | -$510,188 | -$391,679 | +| Feb 23 | +$1,059,664 | +$1,569,851 | +| Feb 25 | +$2,553,820 | +$1,494,157 | +| Feb 26 | +$1,287,624 | -$1,266,196 | +| Feb 27 | -$603,967 | -$1,891,591 | +| Mar 1 | -$363,459 | +$241,994 | +| Mar 2 | -$1,399,644 | -$1,036,185 | +| Mar 3 | -$1,107,294 | +$291,945 | + +Up $2.55M by February 25th. Then lost **$3.66 million from peak in six days.** + +His positions tell you exactly why: + +| Market | Position Size | PnL | +|---|---|---| +| Will Nottingham Forest FC win? | $2,970,842 | -$1,891,746 | +| Will Real Madrid CF win? | $2,661,094 | -$1,267,527 | +| Will RB Leipzig win? | $2,628,250 | -$1,291,204 | +| Will Fulham FC win? | $1,921,077 | -$1,036,185 | +| Will AS Omonia win? | $258,211 | -$124,290 | +| Will Cagliari Calcio win? | $129,434 | -$35,542 | + +Six positions. All soccer "will X win" bets. All losers. **$2-3 million per match.** Combined position PnL: **-$5.65M.** + +He got lucky twice (Feb 23 and 25 -- probably two soccer wins at massive size). That convinced him to keep sizing huge. Then reality hit. Three losses at $2M+ each and the whole thing collapsed. + +> **[Meme: Panik/Kalm/Panik -- "I just made $2.5M in 5 days" (Kalm) / "by betting $3M per soccer game" (PANIK)]** + +### The wallet that won't stop losing -- $10.7M and counting + +An unnamed wallet ([0x4924...](https://polymarket.com/profile/0x492442EaB586F242B53bDa933fD5dE859c8A3782)) has been bleeding since December 2025. **Still active as of today.** Current PnL: **-$10,715,901.** Max drawdown from peak: **$13.2 million.** + +| Month | Cumulative PnL | Monthly Change | +|---|---|---| +| Dec 2025 | -$483,911 | -$483,911 | +| Jan 2026 | -$11,036,162 | -$10,552,251 | +| Feb 2026 | -$10,743,893 | +$292,269 | +| Mar 2026 (6 days) | -$10,715,901 | +$27,992 | + +$343M in total volume. He briefly hit $1.33M in profit in early January before losing $13.2M from that peak. Lost $10.55M in January alone. Had a tiny recovery in February (+$292K). + +March tells you everything about this wallet's volatility: on March 5 he was down to -$11.69M. On March 6 he swung **+$1.16M in a single day** to claw back to -$10.72M. Wild daily swings on sports bets with no risk management. He's not adjusting. He's not reducing size. He's not stopping. + +If pinkblanket or 0x4924 had used even Quarter-Kelly, they'd have lost thousands instead of millions. Same brains. Same picks. Different outcome. That's what position sizing does. + +--- + +## "OK But Where Do I Find the Edge in the First Place?" + +This is the part where most articles wave their hands and say "do your research." + +I'll be more specific. The edge on Polymarket comes from one place: **knowing what the smartest wallets are doing before the market catches up.** + +Every trade on Polymarket is on-chain. Every wallet has a track record you can verify -- win rate, PnL, Sharpe ratio, the works. When wallets with *proven* accuracy cluster heavily on one side of a market and the price disagrees, that gap is your edge. + +The problem? There are 1.7 million addresses. You're not going to analyze them manually over your morning coffee. + +This is where MetEngine comes in. It scores every active wallet on Polymarket and lets you query the smart money from the command line. Here's how the workflow actually looks: + +### Scan: "Show Me Where Smart Money Disagrees With the Market" + +```bash +polymarket metengine opportunities --min-signal-strength moderate --min-smart-wallets 5 --limit 10 +``` + +This scans every active market and spits out the ones where scored wallets diverge from the current price. You get the market, which side smart money favors, and the **price-signal gap** -- which goes directly into your Kelly formula as the edge. + +Want only the strongest plays? + +```bash +polymarket metengine high-conviction --min-smart-wallets 8 --min-avg-score 75 --limit 10 +``` + +8+ wallets with scores above 75, all aligned. These are the markets where the best traders on the platform agree on something the crowd hasn't figured out yet. + +Want to see where money is *actively moving* right now? + +```bash +polymarket metengine trending --sort-by smart_money_inflow --timeframe 24h --limit 15 +``` + +Stale positions don't mean much. Fresh inflows mean conviction is *live*. + +--- + +### Analyze: Turn CLI Output Into a Kelly Number + +Found something interesting? Go deep: + +```bash +polymarket metengine intelligence will-fed-cut-rates-march-2026 --top-n-wallets 15 +``` + +This gives you the smart money consensus strength -- the single most important number for your Kelly calculation. + +Let's say it comes back: **82% of scored wallets favor YES.** Market price is **$0.55.** + +Watch what happens: + +> p = 0.82, m = 0.55 +> f = (0.82 - 0.55) / (1 - 0.55) +> f = 0.27 / 0.45 +> **f = 0.60** + +Full Kelly says bet 60% of your bankroll. + +**Please don't do that.** Full Kelly assumes your probability estimate is perfect. jtwyslljy started $77K underwater before his strategy paid off. Nobody's estimate is perfect. + +**Quarter-Kelly: 0.60 / 4 = 15% of your bankroll.** That's the move. + +With a $10K bankroll? $1,500 on this trade. Feels small. That's how you know it's right. + +Who's actually in this market? + +```bash +polymarket metengine participants will-fed-cut-rates-march-2026 +``` + +If 70% of capital comes from top-tier wallets, the signal is real. If smart money is only 20% of the pool and retail is driving the price, be more skeptical. + +--- + +### Validate: Is the Dumb Money on the Wrong Side? + +This is my favorite part. Never trade on a single signal. Always check the other side. + +```bash +polymarket metengine dumb-money will-fed-cut-rates-march-2026 --max-score 30 --min-trades 5 +``` + +This shows you what the *worst* traders on the platform are doing. Low scores. Bad track records. The wallets that consistently lose money. + +**When dumb money is overwhelmingly opposite to smart money, you have something beautiful.** The weak hands are wrong. And when the market corrects, they'll provide your exit liquidity. They're not just wrong -- they're funding your trade. + +> **[Meme: Spider-Man pointing meme -- "Smart money consensus: 82% YES" pointing at "Dumb money consensus: 70% NO" / You in the middle: "I love confirmation"]** + +Now make sure the smart money is actually *doing something*, not just sitting: + +```bash +polymarket metengine whale-trades --market will-fed-cut-rates-march-2026 --smart-money-only --min-usdc 5000 --timeframe 7d +``` + +An 80% consensus from last week is interesting. An 80% consensus where whales are *still adding* in the last 48 hours? That's actionable. + +One more look -- are any "alpha callers" in this market? + +```bash +polymarket metengine alpha-callers --days-back 30 --min-days-early 7 --min-bet-usdc 500 +``` + +Alpha callers are wallets that bet **at least 7 days before resolution** and turned out to be right. The early birds. If they're in your target market, that's another check in the "yes" column. + +--- + +### Profile: Don't Trust a Wallet You Haven't Stalked + +Not all smart money is equal. A wallet with a Sharpe of 2.5 across 200 markets is not the same as a wallet that got lucky once on a Super Bowl bet. + +```bash +polymarket metengine top-performers --metric sharpe --timeframe 30d --min-trades 10 --limit 15 +``` + +This ranks wallets by risk-adjusted return. Consistency over flashiness. + +Trading a crypto market? Check the specialists: + +```bash +polymarket metengine niche-experts "crypto" --min-category-trades 10 --sort-by category_sharpe --limit 15 +``` + +A crypto expert with a 2.0 category Sharpe carries a much stronger signal on a crypto market than a generalist who mostly trades politics. + +See a wallet that's heavily positioned in your target market? Dig in: + +```bash +polymarket metengine wallet-profile 0x --include-positions true --include-trades true --trades-limit 25 +``` + +Composite score, tier, win rate, Sharpe, PnL, category breakdown -- everything you need to decide if you trust this wallet's signal in your Kelly math. + +--- + +### Monitor: The Trade Isn't Over When You Enter + +```bash +polymarket metengine sentiment will-fed-cut-rates-march-2026 --timeframe 7d --bucket-size 4h +``` + +Steady climb in smart money sentiment over 7 days? Solid. Single-day spike that's reversing? Maybe get out. + +```bash +polymarket metengine capital-flow --smart-money-only --timeframe 7d --top-n-categories 10 +``` + +If smart money is rotating *out* of your market's category at the macro level, pay attention. Your individual trade signal might still be valid, but the backdrop is shifting. + +--- + +### Calibrate: The Part That Separates Pros From Tourists + +```bash +polymarket metengine resolutions --sort-by smart_money_accuracy --limit 25 +``` + +This is where you find out if the signal is actually any good. + +If smart money consensus above 80% resolves correctly 78% of the time, the signal is well-calibrated. Trust it. + +If it only resolves correctly 60% of the time, you need to discount your **p** before plugging into Kelly. Multiply by 0.75. Adjust. + +**If you don't check, you'll overbet. If you overbet, you'll blow up.** It's not a question of if, it's when. + +--- + +## The Cheat Sheet (Screenshot This) + +| Your Edge | Full Kelly | Half-Kelly | Quarter-Kelly | Hard Cap | +|---|---|---|---|---| +| 5 pts | ~11% | ~6% | ~3% | 5% | +| 10 pts | ~22% | ~11% | ~6% | 10% | +| 15 pts | ~33% | ~17% | ~8% | 15% | +| 20+ pts | ~44% | ~22% | ~11% | 20% | + +**Use Quarter-Kelly.** Full Kelly is for textbooks. Half-Kelly is for people who think they're smarter than they are. Quarter-Kelly is for people who want to still be trading next month. + +**Never exceed 20% on a single market.** WoofMaster survived a $406K drawdown because his sizing kept him in the game. pinkblanket went from +$2.55M to -$1.1M in six days because his didn't. + +--- + +## The Full Flow (Save This Too) + +| Step | What You Do | MetEngine Command | +|---|---|---| +| **Scan** | Find smart money / price gaps | `metengine opportunities` | +| **Filter** | Narrow to strongest conviction | `metengine high-conviction` | +| **Analyze** | Get consensus strength -> your **p** | `metengine intelligence ` | +| **Validate** | Confirm dumb money is wrong | `metengine dumb-money ` | +| **Confirm** | Check whales are actively buying | `metengine whale-trades --smart-money-only` | +| **Profile** | Verify wallet track records | `metengine wallet-profile ` | +| **Size** | Kelly -> Quarter-Kelly -> Cap 20% | *Your calculator* | +| **Monitor** | Track sentiment trajectory | `metengine sentiment ` | +| **Calibrate** | Check accuracy post-resolution | `metengine resolutions` | + +--- + +## Why Most People Won't Do This + +The formula is public. The data is on-chain. The CLI is right there. + +And yet 70% of addresses lose money. Why? + +**It feels small.** Quarter-Kelly on a 10-point edge says bet 6%. Your brain screams "that's nothing, I'm *sure* about this one." jtwyslljy made $1.67M over 10 months and had a losing month in December. He wasn't sure about anything. He just sized correctly and kept compounding. + +**It requires surviving drawdowns.** WoofMaster sat dormant for seven months before deploying. Most people? pinkblanket made $2.55M in five days and immediately started betting $3M per soccer match. Six days later he was down $1.1M. + +> **[Meme: Grim Reaper knocking on doors -- Door 1: "Your stop loss" (survives) / Door 2: "Your conviction that it'll come back" (does not survive)]** + +**It requires being boring.** The highest-volume trader on Polymarket -- a bot called `risk-manager` -- has $558M in volume and a PnL-to-volume ratio of 0.04%. That's a 0.04% edge ground out over half a billion dollars. Nobody's posting that on X. It's just compounding. Quietly. While everyone else argues about whether some market is mispriced. + +The edge isn't secret. It's just that most people would rather be exciting than rich. + +**The math doesn't care about your feelings. That's the whole point.** + +--- + +## Data Sources + +All trader data in this article was pulled from Polymarket's public APIs on March 6, 2026: +- **Leaderboard**: `data-api.polymarket.com/v1/leaderboard` +- **PnL curves**: `user-pnl-api.polymarket.com/user-pnl` +- **Positions**: `data-api.polymarket.com/v1/positions` +- **Activity**: `data-api.polymarket.com/v1/activity` +- **Profitability statistics**: [DefiOasis on-chain analysis](https://financefeeds.com/data-reveals-70-percent-of-polymarket-trading-addresses-incur-losses/) (Dec 2025, 1.73M addresses) + +Wallet addresses are linked directly to Polymarket profiles. Verify everything yourself -- that's the point of on-chain data. + +--- + +*[MetEngine](https://metengine.ai) scores every active Polymarket wallet and surfaces where the best traders disagree with the market -- from the CLI. Pay-per-request via x402 on Solana. No API keys. Payment IS authentication. Run `polymarket metengine pricing` to see current rates.* From 176240545289d034b662c32c8a11efb7ee6350e2 Mon Sep 17 00:00:00 2001 From: Vraj Desai Date: Fri, 6 Mar 2026 19:13:38 +0530 Subject: [PATCH 3/3] feat: add 48h timeframe to whale-trades CLI help and article Co-Authored-By: Claude Opus 4.6 --- docs/smart-wallet-kelly-ev.md | 2 +- src/commands/metengine.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/smart-wallet-kelly-ev.md b/docs/smart-wallet-kelly-ev.md index 6e3a7d5..1005bdb 100644 --- a/docs/smart-wallet-kelly-ev.md +++ b/docs/smart-wallet-kelly-ev.md @@ -253,7 +253,7 @@ This shows you what the *worst* traders on the platform are doing. Low scores. B Now make sure the smart money is actually *doing something*, not just sitting: ```bash -polymarket metengine whale-trades --market will-fed-cut-rates-march-2026 --smart-money-only --min-usdc 5000 --timeframe 7d +polymarket metengine whale-trades --market will-fed-cut-rates-march-2026 --smart-money-only --min-usdc 5000 --timeframe 48h ``` An 80% consensus from last week is interesting. An 80% consensus where whales are *still adding* in the last 48 hours? That's actionable. diff --git a/src/commands/metengine.rs b/src/commands/metengine.rs index 3e0a4c3..1443ef2 100644 --- a/src/commands/metengine.rs +++ b/src/commands/metengine.rs @@ -287,7 +287,7 @@ pub enum MetengineCommand { /// Minimum USDC size #[arg(long, default_value = "10000")] min_usdc: f64, - /// Time window: 1h, 4h, 12h, 24h, 7d, 30d + /// Time window: 1h, 4h, 12h, 24h, 48h, 7d, 30d #[arg(long, default_value = "24h")] timeframe: String, /// Filter by market condition ID (0x...), slug, or Polymarket URL