diff --git a/.bumpversion.toml b/.bumpversion.toml new file mode 100644 index 0000000..be0b713 --- /dev/null +++ b/.bumpversion.toml @@ -0,0 +1,18 @@ +[bumpversion] +current_version = 0.0.5 + +[bumpversion:file:Cargo.toml] +search = 'version = "{current_version}"' +replace = 'version = "{new_version}"' + +[bumpversion:file:Cargo.lock] +search = 'version = "{current_version}"' +replace = 'version = "{new_version}"' + +[bumpversion:file:README.md] +search = 'openbook = "{current_version}"' +replace = 'openbook = "{new_version}"' + +[bumpversion:file:src/lib.rs] +search = '//! openbook = "{current_version}"' +replace = '//! openbook = "{new_version}"' diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..a3de363 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,39 @@ +# Rust CircleCI 2.1 configuration file +version: 2.1 +aliases: + - &rust_container + docker: + - image: cimg/rust:1.75.0 + + - &install_solana + run: + name: Install Solana CLI + command: | + sudo apt-get -qq update + sh -c "$(curl -sSfL https://release.solana.com/v1.18.3/install)" + export PATH="~/.local/share/solana/install/active_release/bin:$PATH" + + - &set_env_vars + run: + name: Setup Environment Variables + command: | + mkdir -p "$(dirname "${KEY_PATH}")" && touch "${KEY_PATH}" + echo ${KEY} >> ${KEY_PATH} + +jobs: + testing: + <<: *rust_container + steps: + - checkout + - *install_solana + - *set_env_vars + - run: + name: Run Tests + command: | + cargo test + +workflows: + version: 2 + test: + jobs: + - testing diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e8d486a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "cargo" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.gitignore b/.gitignore index ea8c4bf..0b745e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.env \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index ee5dfc2..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/openbook-v1-sdk.iml b/.idea/openbook-v1-sdk.iml deleted file mode 100644 index cf84ae4..0000000 --- a/.idea/openbook-v1-sdk.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 6afa28b..19bcde9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,5570 @@ version = 3 [[package]] -name = "openbook-v1-sdk" +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" +dependencies = [ + "cfg-if", + "getrandom 0.2.12", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +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 = "alloc-traits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" + +[[package]] +name = "anchor-attribute-access-control" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" +dependencies = [ + "anchor-syn", + "bs58 0.5.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-serde", + "anchor-derive-space", + "arrayref", + "base64 0.13.1", + "bincode", + "borsh 0.10.3", + "bytemuck", + "getrandom 0.2.12", + "solana-program", + "thiserror", +] + +[[package]] +name = "anchor-spl" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" +dependencies = [ + "anchor-lang", + "solana-program", + "spl-associated-token-account", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", +] + +[[package]] +name = "anchor-syn" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "heck 0.3.3", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.4", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[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", + "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", +] + +[[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_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive 0.10.3", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +dependencies = [ + "borsh-derive 1.3.1", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +dependencies = [ + "once_cell", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.52", + "syn_derive", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bump2version" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b47a6cfa344b5d6812f2222b961e92353eea8eb991e9199ab5a6332be18af14" +dependencies = [ + "clap 4.5.1", + "regex", +] + +[[package]] +name = "bumpalo" +version = "3.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" + +[[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 = "bytemuck" +version = "1.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "caps" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" +dependencies = [ + "libc", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.4", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap 0.16.1", +] + +[[package]] +name = "clap" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.7.0", + "strsim 0.11.0", +] + +[[package]] +name = "clap_derive" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[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 = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.52", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.52", +] + +[[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.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid", +] + +[[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.4", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[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.52", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "eager" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek", + "hmac 0.12.1", + "sha2 0.10.8", +] + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "enumflags2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset 0.9.0", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[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.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "goblin" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.5", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.10", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "histogram" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "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 = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint 0.4.4", + "thiserror", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +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 = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + +[[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 = "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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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.52", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[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.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openbook" +version = "0.0.5" +dependencies = [ + "anchor-spl", + "anyhow", + "borsh 1.3.1", + "bump2version", + "clap 4.5.1", + "log", + "memoffset 0.9.0", + "openbook_dex", + "pyth-sdk-solana", + "rand 0.8.5", + "serde_json", + "serum_dex", + "solana-account-decoder", + "solana-client", + "solana-program", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "spl-associated-token-account", + "tokio", +] + +[[package]] +name = "openbook_dex" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2795442782f5eff209621e49e0ac00f9d1f209fc0f879e345d30b67479ba2b" +dependencies = [ + "arrayref", + "bincode", + "bytemuck", + "byteorder", + "enumflags2", + "field-offset", + "itertools 0.9.0", + "num-traits", + "num_enum 0.5.11", + "safe-transmute", + "serde", + "solana-program", + "spl-token 3.5.0", + "static_assertions", + "thiserror", + "without-alloc", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyth-sdk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7aeef4d5f0a9c98ff5af2ddd84a8b89919c512188305b497a9eb9afa97a949" +dependencies = [ + "borsh 0.10.3", + "borsh-derive 0.10.3", + "getrandom 0.2.12", + "hex", + "schemars", + "serde", +] + +[[package]] +name = "pyth-sdk-solana" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e75b45587aea6c3c877bdfe4c2b768f5d1131490fd4c3d270bf798afeb82b2c" +dependencies = [ + "borsh 0.10.3", + "borsh-derive 0.10.3", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "pyth-sdk", + "serde", + "solana-program", + "thiserror", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls", + "rustls-native-certs", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +dependencies = [ + "bytes", + "libc", + "socket2", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +dependencies = [ + "async-compression", + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rpassword" +version = "7.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.48.0", +] + +[[package]] +name = "rtoolbox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "safe-transmute" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a01dab6acf992653be49205bdd549f32f17cb2803e8eacf1560bf97259aae8" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "serum_dex" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62b5450e2d875e269af76b80080126e2d8eeb10ac256f900dc7cbad1a8dc85e" +dependencies = [ + "arrayref", + "bincode", + "bytemuck", + "byteorder", + "enumflags2", + "field-offset", + "itertools 0.9.0", + "num-traits", + "num_enum 0.5.11", + "safe-transmute", + "serde", + "solana-program", + "spl-token 3.5.0", + "static_assertions", + "thiserror", + "without-alloc", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[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 = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "solana-account-decoder" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e769cfd7410944d41208631c6c69f8d7a8fa92cc5af85593ce7c6984375c6335" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "bs58 0.4.0", + "bv", + "lazy_static", + "serde", + "serde_derive", + "serde_json", + "solana-config-program", + "solana-sdk", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror", + "zstd", +] + +[[package]] +name = "solana-clap-utils" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5cdcbc655b99c18cf86a17a6080de9fc7370ea3824d26ef0d174e903eccfe9a" +dependencies = [ + "chrono", + "clap 2.34.0", + "rpassword", + "solana-remote-wallet", + "solana-sdk", + "thiserror", + "tiny-bip39", + "uriparse", + "url", +] + +[[package]] +name = "solana-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80529b6cf2be6337ab4711bb0f7f2b5618301b6f14698d670215a51e5944cb17" +dependencies = [ + "async-trait", + "bincode", + "dashmap", + "futures", + "futures-util", + "indexmap 2.2.5", + "indicatif", + "log", + "quinn", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-quic-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", + "solana-sdk", + "solana-streamer", + "solana-thin-client", + "solana-tpu-client", + "solana-udp-client", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-config-program" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d61ec5e55f26061a56fd4bf6484c5fa1a9a8a3d3b2188b4983369df2a564a70" +dependencies = [ + "bincode", + "chrono", + "serde", + "serde_derive", + "solana-program-runtime", + "solana-sdk", +] + +[[package]] +name = "solana-connection-cache" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370c11d0787f203231c4a28972f55826fe38175c8961e240001a3a3de24d17e3" +dependencies = [ + "async-trait", + "bincode", + "crossbeam-channel", + "futures-util", + "indexmap 2.2.5", + "log", + "rand 0.8.5", + "rayon", + "rcgen", + "solana-measure", + "solana-metrics", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-frozen-abi" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e608aeeb42922e803589258af0028e2c9e70fbfb04e1f1ff6c5f07019c2af95" +dependencies = [ + "block-buffer 0.10.4", + "bs58 0.4.0", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc7a55ad8a177287f3abb1be371b2a252d4c474d71c2e3983a7dff7db15d3f2" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.52", +] + +[[package]] +name = "solana-logger" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f507f00c12d7309475fde8bfc58502ed87bd4024769760223cc9c03dd5aa53" +dependencies = [ + "env_logger", + "lazy_static", + "log", +] + +[[package]] +name = "solana-measure" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9671ea55a8613da1fa3bfcbf211cc19881b08097db2a6b6c188579c4bb82c660" +dependencies = [ + "log", + "solana-sdk", +] + +[[package]] +name = "solana-metrics" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f136e251c6eb16898947d6128cd3fbc5aa4b25362f1537cb00e0987123dd495" +dependencies = [ + "crossbeam-channel", + "gethostname", + "lazy_static", + "log", + "reqwest", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-net-utils" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c3bf1d905b81cdf4e0a9c81448ddd777367c9e3227025ed8f1a1aa9b417fc0" +dependencies = [ + "bincode", + "clap 3.2.25", + "crossbeam-channel", + "log", + "nix", + "rand 0.8.5", + "serde", + "serde_derive", + "socket2", + "solana-logger", + "solana-sdk", + "solana-version", + "tokio", + "url", +] + +[[package]] +name = "solana-perf" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330eba34f8d5e711453f7ba28382898e27353cac43b0e9b47113a1d3b3acfd73" +dependencies = [ + "ahash 0.8.10", + "bincode", + "bv", + "caps", + "curve25519-dalek", + "dlopen2", + "fnv", + "lazy_static", + "libc", + "log", + "nix", + "rand 0.8.5", + "rayon", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-vote-program", +] + +[[package]] +name = "solana-program" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fad730d66a6f33ef5bb180def74a3d84e7487b829a8f67ff58570332481f6c" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags 2.4.2", + "blake3", + "borsh 0.10.3", + "borsh 0.9.3", + "borsh 1.3.1", + "bs58 0.4.0", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.12", + "itertools 0.10.5", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset 0.9.0", + "num-bigint 0.4.4", + "num-derive 0.4.2", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-program-runtime" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea72e967256cbeb1279b7e83bdee17fa9ff641676dde07e34a98842d1d9562d" +dependencies = [ + "base64 0.21.7", + "bincode", + "eager", + "enum-iterator", + "itertools 0.10.5", + "libc", + "log", + "num-derive 0.4.2", + "num-traits", + "percentage", + "rand 0.8.5", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-sdk", + "solana_rbpf", + "thiserror", +] + +[[package]] +name = "solana-pubsub-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c001d326505e0ad178db0b3b81e81b9d0a3247d5582fa3818c563352d8b401" +dependencies = [ + "crossbeam-channel", + "futures-util", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60019bc9e7817ddef328ad7ffb0c3a5ea63e2afcbee4897bff1e7a1fd1e1a55a" +dependencies = [ + "async-mutex", + "async-trait", + "futures", + "itertools 0.10.5", + "lazy_static", + "log", + "quinn", + "quinn-proto", + "rcgen", + "rustls", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-rpc-client-api", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-rayon-threadlimit" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652cd60beb6e0006c4b5c7b449b0593e09e8340966414eff9b30543aeae4c761" +dependencies = [ + "lazy_static", + "num_cpus", +] + +[[package]] +name = "solana-remote-wallet" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed53b5cf416c93a9f233ee95c6c2242941de8a606230262a16ca650b2bc519d5" +dependencies = [ + "console", + "dialoguer", + "log", + "num-derive 0.4.2", + "num-traits", + "parking_lot", + "qstring", + "semver", + "solana-sdk", + "thiserror", + "uriparse", +] + +[[package]] +name = "solana-rpc-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a03ef7807e31203d07aa9f3baf76d8f98d9ded2e88aab9044f42a5c068e19b1e" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bincode", + "bs58 0.4.0", + "indicatif", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5d71639e7600d23558f29414772f20334af5ce0d1977aaac09b5d23e2b06a1" +dependencies = [ + "base64 0.21.7", + "bs58 0.4.0", + "jsonrpc-core", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7e20e6b3874a8da9db9b50db917b868797b5841776b269184deb2f521296a" +dependencies = [ + "clap 2.34.0", + "solana-clap-utils", + "solana-rpc-client", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-sdk" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d3612d0b4c2120c2a4cef6bac8af469908575319249e1a5c0de5a487fb7610f" +dependencies = [ + "assert_matches", + "base64 0.21.7", + "bincode", + "bitflags 2.4.2", + "borsh 1.3.1", + "bs58 0.4.0", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek", + "ed25519-dalek-bip32", + "generic-array", + "hmac 0.12.1", + "itertools 0.10.5", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memmap2", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "pbkdf2 0.11.0", + "qstring", + "qualifier_attr", + "rand 0.7.3", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "serde_with", + "sha2 0.10.8", + "sha3 0.10.8", + "siphasher", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df952c230e35ba179882cef765655b171b8f99f512f04fc4a84800fa43cfe592" +dependencies = [ + "bs58 0.4.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.52", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-streamer" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a852027d8b095aaf6931cab230562118bdf71e0b38a17d073f9a808aebcba9" +dependencies = [ + "async-channel", + "bytes", + "crossbeam-channel", + "futures-util", + "histogram", + "indexmap 2.2.5", + "itertools 0.10.5", + "libc", + "log", + "nix", + "pem", + "percentage", + "pkcs8", + "quinn", + "quinn-proto", + "rand 0.8.5", + "rcgen", + "rustls", + "solana-metrics", + "solana-perf", + "solana-sdk", + "thiserror", + "tokio", + "x509-parser", +] + +[[package]] +name = "solana-thin-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104cda4f0cc977db2474728413253a35bd283492546d57bfcc6eddb2f9432a4a" +dependencies = [ + "bincode", + "log", + "rayon", + "solana-connection-cache", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", +] + +[[package]] +name = "solana-tpu-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0c2cd930f1ef2ced8f73d67543d04ab69f6f0b4b0733e8ef4c973022c0a9dc" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap 2.2.5", + "indicatif", + "log", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-transaction-status" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7fed91baf079b21ea8b9a70ab61910f2a539e6d08740f0f6f6c1f90784472b" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "borsh 0.10.3", + "bs58 0.4.0", + "lazy_static", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "spl-associated-token-account", + "spl-memo", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "solana-udp-client" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f0fa2c7d277206afcad3e13472379cf7e7c804d02de0fb0bd61730a72df1fef" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-net-utils", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-version" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30194d1b6a9311f9d92e68fd4355e075169fbc19794e3cef19b45829fa83c0bd" +dependencies = [ + "log", + "rustc_version", + "semver", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", +] + +[[package]] +name = "solana-vote-program" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2880e99200ac244ffd63ff7b978f989d9b42a16d2639dce0bf7db1f029c07050" +dependencies = [ + "bincode", + "log", + "num-derive 0.4.2", + "num-traits", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "1.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd13a3e898ab98d3a3cb781935f2d0298ba85d11d589b82be5537d6498bf42d" +dependencies = [ + "aes-gcm-siv", + "base64 0.21.7", + "bincode", + "bytemuck", + "byteorder", + "curve25519-dalek", + "getrandom 0.1.16", + "itertools 0.10.5", + "lazy_static", + "merlin", + "num-derive 0.4.2", + "num-traits", + "rand 0.7.3", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "solana_rbpf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d457cc2ba742c120492a64b7fa60e22c575e891f6b55039f4d736568fb112a3" +dependencies = [ + "byteorder", + "combine", + "goblin", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "scroll", + "thiserror", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "spl-associated-token-account" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" +dependencies = [ + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa600f2fe56f32e923261719bae640d873edadbc5237681a39b8e37bfd4d263" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.52", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.52", + "thiserror", +] + +[[package]] +name = "spl-memo" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5db7e4efb1107b0b8e52a13f035437cdcb36ef99c58f6d467f089d9b2915a" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0657b6490196971d9e729520ba934911ff41fbb2cb9004463dbe23cf8b4b4f" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.52", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f335787add7fa711819f9e7c573f8145a5358a709446fe2d24bf2a88117c90" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-token" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.5.11", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "solana-program", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token 4.0.0", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.3.0", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "solana-program", + "solana-security-txt", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token 4.0.0", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.4.1", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-group-interface" version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.4.0", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.5.2", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9ebd75d29c5f48de5f6a9c114e08531030b75b8ac2c557600ac7da0b73b1e8" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[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 = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "time" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.25.4", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.5", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.5", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", + "webpki-roots 0.24.0", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "unsize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa7a7a734c1a5664a662ddcea0b6c9472a21da8888c957c7f1eaa09dba7a939" +dependencies = [ + "autocfg", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + +[[package]] +name = "web-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" +dependencies = [ + "rustls-webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[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 = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "without-alloc" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375db0478b203b950ef10d1cce23cdbe5f30c2454fd9e7673ff56656df23adbb" +dependencies = [ + "alloc-traits", + "unsize", +] + +[[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", + "time", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 8731f9e..bb455f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,40 @@ [package] -name = "openbook-v1-sdk" -version = "0.1.0" +name = "openbook" +version = "0.0.5" edition = "2021" +description = "📖 A CLI and library for interacting with the OpenBook market on the Solana blockchain." +license = "MIT" +keywords = ["blockchain", "cli", "solana", "dex"] +categories = ["command-line-utilities", "web-programming", "science"] +repository = "https://github.com/wiseaidev/openbook" +documentation = "https://docs.rs/openbook" +authors = ["Mahmoud Harmouch "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +openbook_dex = { version = "0.5.6" , features = ["test", "client"]} +solana-rpc-client = "=1.18.4" +anyhow = "1.0.80" +solana-program = "=1.18.4" +solana-sdk = "=1.18.4" +rand = "0.8.5" +solana-rpc-client-api = "=1.18.4" +anchor-spl = "0.29.0" +solana-client = "=1.18.4" +serum_dex = "0.5.4" +pyth-sdk-solana = "0.10.0" +memoffset = "0.9.0" +borsh = "1.3.1" +serde_json = "1.0.114" +clap = { version = "4.5.1", features = ["derive"] , optional = true } +log = "0.4.21" +tokio = { version = "1.36.0", features = ["full"] } +spl-associated-token-account = "=2.3.0" +solana-account-decoder = "=1.18.4" + +[features] +cli = ["clap"] + +[dev-dependencies] +bump2version = "0.1.3" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9062ee7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Mahmoud Harmouch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 2dc701c..f3bd422 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,187 @@ -# Openbook v1 SDK +# 📖 OpenBook -## Job Description -Translate OpenBook SDK from JS to Rust. -Source repository: https://github.com/openbook-dex/openbook-ts +[![CircleCI](https://dl.circleci.com/status-badge/img/gh/wiseaidev/openbook/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/wiseaidev/openbook/tree/master) +[![Crates.io](https://img.shields.io/crates/v/openbook.svg)](https://crates.io/crates/openbook) +[![docs](https://docs.rs/openbook/badge.svg)](https://docs.rs/openbook/) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -Only the /packages/openbook directory needs to be translated. The rest of the packages can be imported as standard rust cargo dependencies. The swap package can be ignored (our use case only requires limit orders). Also, we do not require any of the functionality related to creating new markets, or using the crank. +> A CLI and library for interacting with the OpenBook market on the Solana blockchain. +## Table of Contents -## Acceptance Criteria -The Acceptance Criteria for this bounty is to implement the code snippet found in the README.md of the openbook package. I.e. execute the following functionalities: +- [Installation](#-installation) +- [Functionalities](#-functionalities) +- [Usage](#-usage-as-cli) +- [Usage as Dependency](#-usage-as-dep) +- [Options](#-options) +- [Contributing](#-contributing) +- [License](#-license) -- Load asks and bids for a target market. -- Place new limit orders -- View existing limit orders -- Cancel existing limit orders -- Retrieve fill history -- Settle funds +## 🚀 Installation -### Suggested Approach +To install `openbook` cli, use the following Cargo command: -This job has two primary components: -1) Serde for relevant state structures (e.g. critbit slab) -2) Building instructions (key metas and data inputs are in instruction.js) +```bash +cargo install --locked openbook --all-features +``` -Note that for component (1), you can just copy the structures directly from the contract source code, eg: https://github.com/openbook-dex/program/blob/master/dex/src/critbit.rs. +## ✨ Functionalities -For component (2), you can get the data structs directly from the source, and the key metas from the instructions.js… this is just one approach. You can use whatever approach is more efficient for you. +- Place a limit bid in the OpenBook market. +- Cancel an existing order in the OpenBook market. +- Settle balances in the OpenBook market. +- Consume events instructions in the OpenBook market. +- Consume events permissioned instructions in the OpenBook market. +- Load orders for a specific owner in the OpenBook market. +- Find open orders accounts for a specific owner in the OpenBook market. -### Requirements -- `rustc -V == 1.74.1` +## Usage -## A note to Bounty Hunters +Before using the `openbook` crate or CLI, make sure to set the following environment variables: -This repo has two functions: -1) It will be used in our production code. -2) It will be used to determine which devs have enough skill to work with GigaDAO. +```bash +export RPC_URL=https://api.mainnet-beta.solana.com +export KEY_PATH= +``` -If you want to prove that you are a skilled Rust programmer, and thus receive paid bounty assignments, this is your -opportunity. ***You do not have to implement the whole SDK.*** If you submit a PR for partially complete SDK, but it proves -your skill level, then I can assign you paid bounties. The minimum requirement all PR's is: -1) Must have working unit tests. -2) Must be clean and readable. +> [!NOTE] +> Certain RPC methods, like `getProgramAccounts`, are no longer available on `api.mainnet-beta.solana.com`. We recommend utilizing [helius.dev](https://www.helius.dev) as an alternative. +## ⌨ Usage as CLI + +### Fetch Market Info: + +```sh +openbook info +``` + +### Place a limit bid order: + +```sh +openbook place -t 10.0 -s bid -b 0.5 -e -p 15.0 +``` + +### Place a limit ask order: + +```sh +openbook place -t 10.0 -s ask -b 0.5 -e -p 15.0 +``` + +### Cancel all limit orders: + +```sh +openbook cancel -e +``` + +### Settle balances: + +```sh +openbook settle -e +``` + +### Fetch all orders for current owner (bids + asks): + +```sh +openbook load +``` + +### Make match orders transaction: + +```sh +openbook match --limit 3 +``` + +### Make consume events instruction: + +```sh +openbook consume --limit 2 +``` + +### Make consume events permissioned instruction: + +```sh +openbook consume-permissioned --limit 2 +``` + +## 💻 Usage as Dependency + +```toml +[dependencies] +openbook = "0.0.5" +``` + +```rust +use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; +use openbook::market::Market; +use openbook::utils::read_keypair; +use openbook::matching::Side; +use openbook::commitment_config::CommitmentConfig; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + + let commitment_config = CommitmentConfig::confirmed(); + let rpc_client = RpcClient::new_with_commitment(rpc_url, commitment_config); + + let keypair = read_keypair(&key_path); + + let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + + println!("Initialized Market: {:?}", market); + + let r = market + .place_limit_order( + 10.0, + Side::Bid, // or Side::Ask + 0.5, + true, + 15.0, + ) + .await?; + println!("Place Limit Order Result: {:?}", r); + + let c = market.cancel_orders(true).await?; + println!("Cancel Orders Result: {:?}", c); + + let s = market.settle_balance(true).await?; + println!("Settle Balance Result: {:?}", s); + + let m = market.make_match_orders_transaction(1).await?; + println!("Match Order Result: {:?}", m); + + let open_orders_accounts = vec![Pubkey::new_from_array([0; 32])]; + let limit = 10; + + let e = market.make_consume_events_instruction(open_orders_accounts.clone(), limit).await?; + println!("Consume Events Result: {:?}", e); + + let p = market.make_consume_events_permissioned_instruction(open_orders_accounts.clone(), limit).await?; + println!("Consume Events Permissioned Result: {:?}", p); + + Ok(()) + } +``` + +## 🎨 Options + +| Option | Default Value | Description | +|----------------------------------------|---------------|----------------------------------------------------------| +| `place -t -s -b -e -p ` | - | Place a limit order with the specified parameters. | +| `cancel -e` | - | Cancel all existing order for the current owner. | +| `settle -e` | - | Settle balances in the OpenBook market. | +| `match --limit ` | - | Match orders transaction with the specified limit. | +| `consume --limit ` | - | Consume events instruction with the specified limit. | +| `consume-permissioned --limit ` | - | Consume events permissioned instruction with the specified limit. | +| `find --future_option ` | - | Find open orders accounts for a specific owner. | +| `load` | - | Load orders for the current owner, bids + asks. | +| `info` | - | Fetch OpenBook market info. | + +## 🤝 Contributing + +Contributions and feedback are welcome! If you'd like to contribute, report an issue, or suggest an enhancement, please engage with the project on [GitHub](https://github.com/wiseaidev/openbook). Your contributions help improve this CLI and library for the community. + +## 📄 License + +This project is licensed under the [MIT License](LICENSE). diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..0627083 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,192 @@ +//! This module contains the cli functionalities related to the openbook market. + +#[cfg(feature = "cli")] +use clap::builder::styling::{AnsiColor, Effects, Styles}; +#[cfg(feature = "cli")] +use clap::{Args, Parser, Subcommand}; + +#[cfg(feature = "cli")] +fn styles() -> Styles { + Styles::styled() + .header(AnsiColor::Red.on_default() | Effects::BOLD) + .usage(AnsiColor::Red.on_default() | Effects::BOLD) + .literal(AnsiColor::Blue.on_default() | Effects::BOLD) + .error(AnsiColor::Red.on_default() | Effects::BOLD) + .placeholder(AnsiColor::Green.on_default()) +} + +#[cfg(feature = "cli")] +#[derive(Parser, Debug, Clone)] +#[command( + author = "Mahmoud Harmouch", + version, + name = "openbook", + propagate_version = true, + styles = styles(), + help_template = r#"{before-help}{name} {version} +{about-with-newline} + +{usage-heading} {usage} + +{all-args}{after-help} + +AUTHORS: + {author} +"#, + about=r#" +📖 OPENBOOK CLI +============== + +A command-line tool for interacting with the OpenBook market on the Solana blockchain. + +FUNCTIONALITIES: + - Place Limit Bid: Place a limit bid in the OpenBook market. + - Cancel Order: Cancel an existing order in the OpenBook market. + - Settle Balance: Settle balances in the OpenBook market. + - Match Orders Transaction: Match orders transactions in the OpenBook market. + - Consume Events Instruction: Consume events instructions in the OpenBook market. + - Consume Events Permissioned Instruction: Consume events permissioned instructions in the OpenBook market. + - Load Orders For Owner: Load orders for a specific owner in the OpenBook market. + - Find Open Orders Accounts For Owner: Find open orders accounts for a specific owner in the OpenBook market. + +USAGE: + openbook [OPTIONS] + +EXAMPLES: + Place a bid limit order: + openbook place -t 10.0 -s bid -b 0.5 -e -p 15.0 + + Place a ask limit order: + openbook place -t 10.0 -s ask -b 0.5 -e -p 15.0 + + Cancel all limit orders: + openbook cancel -e + + Settle balances: + openbook settle -e + +For more information, visit: github.com/wiseaidev/openbook +"# +)] +pub struct Cli { + /// Turn debugging information on. + #[arg(short, long, action = clap::ArgAction::Count)] + pub debug: u8, + + /// The subcommand to execute. + #[command(subcommand)] + pub command: Option, +} + +/// Represents OpenBook-related subcommands. +#[cfg(feature = "cli")] +#[derive(Subcommand, Debug, Clone)] +pub enum Commands { + /// Place a limit order. + Place(Place), + /// Cancel an order. + Cancel(Cancel), + /// Settle balance. + Settle(Settle), + /// Match orders transaction. + Match(Match), + /// Consume events instruction. + Consume(Consume), + /// Consume events permissioned instruction. + ConsumePermissioned(ConsumePermissioned), + /// Load orders for owner. + Load(Load), + /// Find open orders accounts for owner. + Find(Find), + /// Fetch Market Info. + Info(Info), +} + +/// Represents options for placing a limit order in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Place { + /// Target amount in quote currency. + #[arg(short, long)] + pub target_amount_quote: f64, + + /// Side of the order (Bid or Ask). + #[arg(short, long)] + pub side: String, + + /// Best offset in USDC. + #[arg(short, long)] + pub best_offset_usdc: f64, + + /// Flag indicating whether to execute the order immediately. + #[arg(short, long)] + pub execute: bool, + + /// Target price for the order. + #[arg(short, long)] + pub price_target: f64, +} + +/// Represents options for cancelling an order in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Cancel { + /// Flag indicating whether to execute the order immediately. + #[arg(short, long)] + pub execute: bool, +} + +/// Represents options for settling balances in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Settle { + /// Flag indicating whether to execute the order immediately. + #[arg(short, long)] + pub execute: bool, +} + +/// Represents options for match orders transactions in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Match { + /// The maximum number of orders to match. + #[arg(short, long)] + pub limit: u16, +} + +/// Represents options for consume events instructions in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Consume { + /// Limit for consume events instruction. + #[arg(short, long)] + pub limit: u16, +} + +/// Represents options for consume events permissioned instructions in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct ConsumePermissioned { + /// Limit for consume events permissioned instruction. + #[arg(short, long)] + pub limit: u16, +} + +/// Represents options for loading orders for the current owner in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Load {} + +/// Represents options for finding open orders accounts for a specific owner in the OpenBook market. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Find { + /// Comming Soon: future options related to finding open orders accounts. + #[arg(short, long)] + pub future_option: String, +} + +/// Represents options for fetching the OpenBook market info. +#[cfg(feature = "cli")] +#[derive(Args, Debug, Clone)] +pub struct Info {} diff --git a/src/fees.rs b/src/fees.rs new file mode 100644 index 0000000..7ca694c --- /dev/null +++ b/src/fees.rs @@ -0,0 +1,101 @@ +//! This module contains functions related to the openbook market fees. + +use crate::tokens_and_markets::get_layout_version; +use solana_sdk::pubkey::Pubkey; + +/// Checks if a program supports SRM fee discounts based on its layout version. +/// +/// # Arguments +/// +/// * `program_id` - The program ID to check for SRM fee discounts. +/// +/// # Returns +/// +/// `true` if the program supports SRM fee discounts, `false` otherwise. +/// +/// # Examples +/// +/// ```rust +/// use openbook::pubkey::Pubkey; +/// use openbook::fees::supports_srm_fee_discounts; +/// +/// let program_id = Pubkey::new_unique(); +/// let is_supported = supports_srm_fee_discounts(&program_id); +/// +/// assert_eq!(is_supported, true); +/// ``` +pub fn supports_srm_fee_discounts(program_id: &Pubkey) -> bool { + get_layout_version(program_id) > 1 +} + +/// Gets the fee rates for a given fee tier. +/// +/// # Arguments +/// +/// * `fee_tier` - The fee tier for which to retrieve fee rates. +/// +/// # Returns +/// +/// A tuple containing the taker and maker fee rates. +/// +/// # Examples +/// +/// ```rust +/// use openbook::fees::get_fee_rates; +/// +/// let fee_tier = 3; +/// let (taker_rate, maker_rate) = get_fee_rates(fee_tier); +/// +/// assert_eq!((taker_rate, maker_rate), (0.0016, -0.0003)); +/// ``` +pub fn get_fee_rates(fee_tier: u32) -> (f64, f64) { + match fee_tier { + 1 => (0.002, -0.0003), // SRM2 + 2 => (0.0018, -0.0003), // SRM3 + 3 => (0.0016, -0.0003), // SRM4 + 4 => (0.0014, -0.0003), // SRM5 + 5 => (0.0012, -0.0003), // SRM6 + 6 => (0.001, -0.0005), // MSRM + _ => (0.0022, -0.0003), // Base + } +} + +/// Gets the fee tier based on MSRM and SRM balances. +/// +/// # Arguments +/// +/// * `msrm_balance` - The MSRM (Mega SRM) balance. +/// * `srm_balance` - The SRM (Serum) balance. +/// +/// # Returns +/// +/// The fee tier corresponding to the balances. +/// +/// # Examples +/// +/// ```rust +/// use openbook::fees::get_fee_tier; +/// +/// let msrm_balance = 1.5; +/// let srm_balance = 0.0; +/// let fee_tier = get_fee_tier(msrm_balance, srm_balance); +/// +/// assert_eq!(fee_tier, 6); +/// ``` +pub fn get_fee_tier(msrm_balance: f64, srm_balance: f64) -> u32 { + if msrm_balance >= 1.0 { + 6 + } else if srm_balance >= 1_000_000.0 { + 5 + } else if srm_balance >= 100_000.0 { + 4 + } else if srm_balance >= 10_000.0 { + 3 + } else if srm_balance >= 1_000.0 { + 2 + } else if srm_balance >= 100.0 { + 1 + } else { + 0 + } +} diff --git a/src/lib.rs b/src/lib.rs index 7d12d9a..ba6620c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,121 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} +//! # 📖 OpenBook +//! +//! A Rust library and CLI for interacting with the OpenBook market on the Solana blockchain. +//! +//! ## Quick Start +//! +//! Before using the `openbook` crate or CLI, make sure to set the following environment variables: +//! +//! ```bash +//! export RPC_URL=https://api.mainnet-beta.solana.com +//! export KEY_PATH= +//! ``` +//! +//! Get started with the `openbook` crate by following these simple steps: +//! +//! 1. Install the `openbook` crate by adding the following line to your `Cargo.toml` file: +//! +//! ```toml +//! [dependencies] +//! openbook = "0.0.5" +//! ``` +//! +//! 2. Use the `Market` struct to perform various operations in the OpenBook market: +//! +//! ```rust +//! use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; +//! use openbook::market::Market; +//! use openbook::utils::read_keypair; +//! use openbook::matching::Side; +//! use openbook::commitment_config::CommitmentConfig; +//! +//! #[tokio::main] +//! async fn main() -> Result<(), Box> { +//! let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); +//! let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); +//! +//! let commitment_config = CommitmentConfig::confirmed(); +//! let rpc_client = RpcClient::new_with_commitment(rpc_url, commitment_config); +//! +//! let keypair = read_keypair(&key_path); +//! +//! let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; +//! +//! println!("Initialized Market: {:?}", market); +//! +//! let r = market +//! .place_limit_order( +//! 10.0, +//! Side::Bid, // or Side::Ask +//! 0.5, +//! true, +//! 15.0, +//! ) +//! .await?; +//! println!("Place Limit Order Result: {:?}", r); +//! +//! let c = market.cancel_orders(true).await?; +//! println!("Cancel Orders Result: {:?}", c); +//! +//! let s = market.settle_balance(true).await?; +//! println!("Settle Balance Result: {:?}", s); +//! +//! let m = market.make_match_orders_transaction(1).await?; +//! println!("Match Order Result: {:?}", m); +//! +//! let open_orders_accounts = vec![Pubkey::new_from_array([0; 32])]; +//! let limit = 10; +//! +//! let e = market.make_consume_events_instruction(open_orders_accounts.clone(), limit).await?; +//! println!("Consume Events Results: {:?}", e); +//! +//! let p = market.make_consume_events_permissioned_instruction(open_orders_accounts.clone(), limit).await?; +//! println!("Consume Events Permissioned Results: {:?}", p); +//! +//! Ok(()) +//! } +//! ``` +//! +//! ## Options +//! +//! | Option | Default Value | Description | +//! |----------------------------------------|---------------|----------------------------------------------------------| +//! | `place -t -s -b -e -p ` | - | Place a limit order with the specified parameters. | +//! | `cancel -e` | - | Cancel all existing order for the current owner. | +//! | `settle -e` | - | Settle balances in the OpenBook market. | +//! | `match --limit ` | - | Match orders transaction with the specified limit. | +//! | `consume --limit ` | - | Consume events instruction with the specified limit. | +//! | `consume-permissioned --limit ` | - | Consume events permissioned instruction with the specified limit. | +//! | `find --future_option ` | - | Find open orders accounts for a specific owner. | +//! | `load` | - | Load orders for the current owner, bids + asks. | +//! | `info` | - | Fetch OpenBook market info. | +//! +//! ## GitHub Repository +//! +//! You can access the source code for the `openbook` crate on [GitHub](https://github.com/wiseaidev/openbook). +//! +//! ## Contributing +//! +//! Contributions and feedback are welcome! If you'd like to contribute, report an issue, or suggest an enhancement, +//! please engage with the project on [GitHub](https://github.com/wiseaidev/openbook). +//! Your contributions help improve this crate and CLI for the community. -#[cfg(test)] -mod tests { - use super::*; +#[cfg(feature = "cli")] +pub mod cli; +pub mod fees; +pub mod market; +pub mod orders; +pub mod tokens_and_markets; +pub mod utils; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +// Re-export common func +pub use openbook_dex::matching; +pub use openbook_dex::state; +pub use solana_client::rpc_filter; +pub use solana_program::pubkey; +pub use solana_rpc_client::nonblocking::rpc_client; +pub use solana_sdk::account; +pub use solana_sdk::bs58; +pub use solana_sdk::commitment_config; +pub use solana_sdk::signature; +pub use solana_sdk::signer::keypair; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ceebe28 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,97 @@ +/// The entry point for the OpenBook CLI application. +/// +/// # Returns +/// +/// Returns `Ok(())` on success or an error if an error occurs.| +#[tokio::main] +async fn main() -> Result<(), Box> { + #[cfg(feature = "cli")] + { + use clap::Parser; + use openbook::cli::{Cli, Commands}; + use openbook::commitment_config::CommitmentConfig; + use openbook::market::Market; + use openbook::matching::Side; + use openbook::rpc_client::RpcClient; + use openbook::utils::read_keypair; + + let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set"); + let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set"); + + let args = Cli::parse(); + + let commitment_config = CommitmentConfig::confirmed(); + let rpc_client = RpcClient::new_with_commitment(rpc_url, commitment_config); + + let keypair = read_keypair(&key_path); + + let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + + match args.command { + Some(Commands::Info(_)) => { + println!("[*] Market Info: {:?}", market); + } + Some(Commands::Place(arg)) => { + let side = match arg.side.as_str() { + "bid" => Side::Bid, + "ask" => Side::Ask, + _ => Side::Bid, + }; + + let result = market + .place_limit_order( + arg.target_amount_quote, + side, + arg.best_offset_usdc, + arg.execute, + arg.price_target, + ) + .await?; + println!( + "[*] Transaction successful, signature: {:?}", + result.unwrap() + ); + } + Some(Commands::Cancel(arg)) => { + let c = market.cancel_orders(arg.execute).await?; + println!("[*] Transaction successful, signature: {:?}", c); + } + Some(Commands::Settle(arg)) => { + let result = market.settle_balance(arg.execute).await?; + println!( + "[*] Transaction successful, signature: {:?}", + result.unwrap() + ); + } + Some(Commands::Match(arg)) => { + let m = market.make_match_orders_transaction(arg.limit).await?; + println!("[*] Transaction successful, signature: {:?}", m); + } + Some(Commands::Consume(arg)) => { + let e = market + .make_consume_events_instruction(Vec::new(), arg.limit) + .await?; + println!("[*] Transaction successful, signature: {:?}", e); + } + Some(Commands::ConsumePermissioned(arg)) => { + let p = market + .make_consume_events_permissioned_instruction(Vec::new(), arg.limit) + .await?; + println!("[*] Transaction successful, signature: {:?}", p); + } + Some(Commands::Load(_arg)) => { + let l = market.load_orders_for_owner().await?; + println!("[*] Found Program Accounts: {:?}", l); + } + Some(Commands::Find(_arg)) => { + // Todo: Handle Find Open Accounts command + println!("[*] Find Open Accounts Results: Placeholder"); + } + None => println!( + "\x1b[1;91m{}\x1b[0m", + "Unknown command. Use '--help' for usage instructions." + ), + }; + } + Ok(()) +} diff --git a/src/market.rs b/src/market.rs new file mode 100644 index 0000000..114d464 --- /dev/null +++ b/src/market.rs @@ -0,0 +1,1503 @@ +//! This module contains structs and functions related to the openbook market. +use crate::{ + orders::{MarketInfo, OpenOrders, OpenOrdersCacheEntry}, + rpc_client::RpcClient, + tokens_and_markets::{get_market_name, get_program_id}, + utils::{get_unix_secs, u64_slice_to_bytes}, +}; +use log::debug; +use openbook_dex::{ + critbit::Slab, + instruction::SelfTradeBehavior, + matching::{OrderType, Side}, + state::MarketState, +}; +use rand::random; +use solana_client::{client_error::ClientError, rpc_request::TokenAccountsFilter}; +use solana_program::{account_info::AccountInfo, pubkey::Pubkey}; +use solana_rpc_client_api::config::RpcSendTransactionConfig; +use solana_sdk::sysvar::slot_history::ProgramError; +use solana_sdk::{ + account::Account, + message::Message, + nonce::state::Data as NonceData, + signature::Signature, + signature::{Keypair, Signer}, + transaction::Transaction, +}; +use spl_associated_token_account::{ + get_associated_token_address, instruction::create_associated_token_account, +}; +use std::{ + cell::RefMut, + collections::HashMap, + error::Error, + fmt, + num::NonZeroU64, + str::FromStr, + time::{SystemTime, UNIX_EPOCH}, +}; + +/// Struct representing a market with associated state and information. +#[derive(Debug)] +pub struct Market { + /// The RPC client for interacting with the Solana blockchain. + pub rpc_client: DebuggableRpcClient, + + /// The public key of the program associated with the market. + pub program_id: Pubkey, + + /// The public key of the market. + pub market_address: Pubkey, + + /// The keypair used for signing transactions related to the market. + pub keypair: Keypair, + + /// The number of decimal places for the base currency (coin) in the market. + pub coin_decimals: u8, + + /// The number of decimal places for the quote currency (pc) in the market. + pub pc_decimals: u8, + + /// The lot size for the base currency (coin) in the market. + pub coin_lot_size: u64, + + /// The account flags associated with the market. + pub account_flags: u64, + + /// The lot size for the quote currency (pc) in the market. + pub pc_lot_size: u64, + + /// The public key of the account holding USDC tokens. + pub quote_ata: Pubkey, + + /// The public key of the base market token. + pub base_ata: Pubkey, + + /// The public key of the vault holding base currency (coin) tokens. + pub coin_vault: Pubkey, + + /// The public key of the vault holding quote currency (pc) tokens. + pub pc_vault: Pubkey, + + /// The public key of the vault signer key associated with the market. + pub vault_signer_key: Pubkey, + + /// The public key of the orders account associated with the market. + pub orders_key: Pubkey, + + /// The public key of the event queue associated with the market. + pub event_queue: Pubkey, + + /// The public key of the request queue associated with the market. + pub request_queue: Pubkey, + + /// A HashMap containing open orders cache entries associated with their public keys. + pub open_orders_accounts_cache: HashMap, + + /// Information about the market. + pub market_info: MarketInfo, +} + +/// Wrapper type for RpcClient to enable Debug trait implementation. +pub struct DebuggableRpcClient(RpcClient); + +/// Implement the Debug trait for the wrapper type `DebuggableRpcClient`. +impl fmt::Debug for DebuggableRpcClient { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Include relevant information about RpcClient + f.debug_struct("RpcClient").finish() + } +} + +impl Market { + /// This function is responsible for creating a new instance of the `Market` struct, representing an OpenBook market + /// on the Solana blockchain. It requires essential parameters such as the RPC client, program version, market name, + /// and a keypair for transaction signing. The example demonstrates how to set up the necessary environment variables, + /// initialize the RPC client, and read the keypair from a file path. After initializing the market, information about + /// the newly created instance is printed for verification and further usage. Ensure that the required environment variables, + /// such as `RPC_URL`, `KEY_PATH` are appropriately configured before executing this method. + /// + /// # Arguments + /// + /// * `rpc_client` - The RPC client for interacting with the Solana blockchain. + /// * `program_version` - The program dex version representing the market. + /// * `market_name` - The market name. + /// * `keypair` - The keypair used for signing transactions. + /// + /// # Returns + /// + /// Returns an instance of the `Market` struct with default values and configurations. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// println!("Initialized Market: {:?}", market); + /// + /// Ok(()) + /// } + /// ``` + pub async fn new( + rpc_client: RpcClient, + program_version: u8, + market_name: &'static str, + keypair: Keypair, + ) -> Self { + let quote_ata = get_market_name("usdc").1.parse().unwrap(); + let base_ata = get_market_name("sol").1.parse().unwrap(); + let orders_key = Default::default(); + let coin_vault = Default::default(); + let pc_vault = Default::default(); + let vault_signer_key = Default::default(); + let event_queue = Default::default(); + let request_queue = Default::default(); + let market_info = Default::default(); + + let decoded = Default::default(); + let program_id = get_program_id(program_version).parse().unwrap(); + let market_address = get_market_name(market_name).0.parse().unwrap(); + let open_orders = OpenOrders::new(market_address, decoded, keypair.pubkey()); + let mut open_orders_accounts_cache = HashMap::new(); + + let open_orders_cache_entry = OpenOrdersCacheEntry { + accounts: vec![open_orders], + ts: 123456789, + }; + open_orders_accounts_cache.insert(keypair.pubkey(), open_orders_cache_entry); + + let mut market = Self { + rpc_client: DebuggableRpcClient(rpc_client), + program_id, + market_address, + keypair, + coin_decimals: 9, + pc_decimals: 6, + coin_lot_size: 1_000_000, + pc_lot_size: 1, + quote_ata, + base_ata, + coin_vault, + pc_vault, + vault_signer_key, + orders_key, + event_queue, + request_queue, + account_flags: 0, + open_orders_accounts_cache, + market_info, + }; + + let oos_key_str = std::env::var("OOS_KEY").unwrap_or("".to_string()); + + let orders_key = Pubkey::from_str(oos_key_str.as_str()); + + if orders_key.is_err() { + debug!("[*] Orders Key not found, creating Orders Key..."); + + let key = OpenOrders::make_create_account_transaction( + &market.rpc_client.0, + program_id, + &market.keypair, + market_address, + ) + .await + .unwrap(); + debug!("[*] Orders Key created successfully!"); + market.orders_key = key; + } else { + market.orders_key = orders_key.unwrap(); + } + + market.load().await.unwrap(); + // let _ata_address = market + // .find_or_create_associated_token_account(&market.keypair, &market_address) + // .await + // .unwrap(); + + market + } + + /// Finds or creates an associated token account for a given wallet and mint. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `wallet` - A reference to the wallet's `Keypair`. + /// * `mint` - A reference to the mint's `Pubkey`. + /// + /// # Returns + /// + /// A `Result` containing the `Pubkey` of the associated token account or a boxed `Error` if an error occurs. + pub async fn find_or_create_associated_token_account( + &self, + wallet: &Keypair, + mint: &Pubkey, + ) -> Result> { + let ata_address = get_associated_token_address(&wallet.pubkey(), mint); + + let tokens = self + .rpc_client + .0 + .get_token_accounts_by_owner( + &wallet.pubkey(), + TokenAccountsFilter::ProgramId(anchor_spl::token::ID), + ) + .await?; + + for token in tokens { + debug!("[*] Found Token: {:?}", token); + if token.pubkey == ata_address.to_string() { + debug!("[*] Found ATA: {:?}", ata_address); + return Ok(ata_address); + } + } + + debug!("[*] ATA not found, creating ATA"); + + let create_ata_ix = create_associated_token_account( + &wallet.pubkey(), + &ata_address, + mint, + &anchor_spl::token::ID, + ); + let message = Message::new(&[create_ata_ix], Some(&wallet.pubkey())); + let mut transaction = Transaction::new_unsigned(message); + let recent_blockhash = self.rpc_client.0.get_latest_blockhash().await?; + transaction.sign(&[wallet], recent_blockhash); + + let result = self + .rpc_client + .0 + .send_and_confirm_transaction(&transaction) + .await; + + match result { + Ok(sig) => debug!("[*] Transaction successful, signature: {:?}", sig), + Err(err) => debug!("[*] Transaction failed: {:?}", err), + }; + + Ok(ata_address) + } + + /// Loads market information, including account details and state, using the provided RPC client. + /// + /// This function fetches and processes the necessary account information from Solana + /// blockchain to initialize the `Market` struct. It retrieves the market state, bids + /// information, and other relevant details. + /// + /// # Arguments + /// + /// * `&mut self` - A mutable reference to the `Market` struct. + /// + /// # Returns + /// + /// `Result` indicating success or an error if loading the market information fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with fetching accounts + /// or processing the market information. + pub async fn load(&mut self) -> anyhow::Result { + let mut account = self.rpc_client.0.get_account(&self.market_address).await?; + let owner = account.owner; + let program_id_binding = self.program_id; + let market_account_binding = self.market_address; + let account_info; + { + account_info = self.create_account_info_from_account( + &mut account, + &market_account_binding, + &program_id_binding, + false, + false, + ); + } + if self.program_id != owner { + return Err(ProgramError::InvalidArgument.into()); + } + + let market_state = self.load_market_state_bids_info(&account_info).await?; + + Ok(*market_state) + } + + /// Loads the market state and bids information from the provided account information. + /// + /// # Arguments + /// + /// * `&mut self` - A mutable reference to the `Market` struct. + /// * `account_info` - A reference to the account information used to load the market state. + /// + /// # Returns + /// + /// A `Result` containing a mutable reference to the loaded `MarketState` if successful, + /// or an error if loading the market state fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with loading the market state. + pub async fn load_market_state_bids_info<'a>( + &'a mut self, + account_info: &'a AccountInfo<'_>, + ) -> anyhow::Result> { + let account_data = account_info.deserialize_data::()?; + debug!("[*] Account Data: {:?}", account_data); + let mut market_state = MarketState::load(account_info, &self.program_id, false)?; + + { + let coin_vault_array: [u8; 32] = u64_slice_to_bytes(market_state.coin_vault); + let pc_vault_array: [u8; 32] = u64_slice_to_bytes(market_state.pc_vault); + let request_queue_array: [u8; 32] = u64_slice_to_bytes(market_state.req_q); + let event_queue_array: [u8; 32] = u64_slice_to_bytes(market_state.event_q); + + let coin_vault_temp = Pubkey::new_from_array(coin_vault_array); + let pc_vault_temp = Pubkey::new_from_array(pc_vault_array); + let request_queue_temp = Pubkey::new_from_array(request_queue_array); + let event_queue_temp = Pubkey::new_from_array(event_queue_array); + + self.coin_vault = coin_vault_temp; + self.pc_vault = pc_vault_temp; + self.request_queue = request_queue_temp; + self.account_flags = market_state.account_flags; + self.coin_lot_size = market_state.coin_lot_size; + self.pc_lot_size = market_state.pc_lot_size; + self.coin_lot_size = market_state.coin_lot_size; + self.event_queue = event_queue_temp; + } + let _result = self.load_bids_asks_info(&mut market_state).await?; + + Ok(market_state) + } + + /// Loads information about bids, asks, and the maximum bid price from the market state. + /// + /// This function fetches and processes bids information from the provided `MarketState`, + /// including extracting the bids and asks addresses, loading the bids account, and determining + /// the maximum bid price. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `market_state` - A mutable reference to the `MarketState` representing the current state of the market. + /// + /// # Returns + /// + /// A `Result` containing a tuple of `(bids_address, asks_address, max_bid)` if successful, + /// or an error if loading the bids information fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with fetching accounts + /// or processing the bids information. + pub async fn load_bids_asks_info( + &mut self, + market_state: &RefMut<'_, MarketState>, + ) -> anyhow::Result<(Pubkey, Pubkey, MarketInfo)> { + let (bids_address, asks_address) = self.get_bids_asks_addresses(market_state); + + let mut bids_account = self.rpc_client.0.get_account(&bids_address).await?; + let bids_info = self.create_account_info_from_account( + &mut bids_account, + &bids_address, + &self.program_id, + false, + false, + ); + let mut bids = market_state.load_bids_mut(&bids_info)?; + let (open_bids, open_bids_prices, max_bid) = self.process_bids(&mut bids)?; + + let mut asks_account = self.rpc_client.0.get_account(&asks_address).await?; + let asks_info = self.create_account_info_from_account( + &mut asks_account, + &asks_address, + &self.program_id, + false, + false, + ); + let mut asks = market_state.load_asks_mut(&asks_info)?; + let (open_asks, open_asks_prices, min_ask) = self.process_asks(&mut asks)?; + + self.market_info = MarketInfo { + min_ask, + max_bid, + open_asks, + open_bids, + bids_address, + asks_address, + open_asks_prices, + open_bids_prices, + base_total: 0., + quote_total: 0., + }; + + Ok((bids_address, asks_address, self.market_info.clone())) + } + + /// Processes bids information to find the maximum bid price. + /// + /// This function iteratively removes bids from the provided `Slab` until + /// it finds the maximum bid price. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `bids` - A mutable reference to the `Slab` containing bids information. + /// + /// # Returns + /// + /// A `Result` containing the maximum bid price if successful, or an error if processing bids fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with processing the bids information. + pub fn process_bids( + &self, + bids: &mut RefMut, + ) -> anyhow::Result<(Vec, Vec, u64)> { + let mut max_bid = 0; + let mut open_bids = Vec::new(); + let mut open_bids_prices = Vec::new(); + loop { + let node = bids.remove_max(); + match node { + Some(node) => { + let owner = node.owner(); + let bytes = u64_slice_to_bytes(owner); + let owner_address = Pubkey::from(bytes); + + let order_id = node.order_id(); + let price_raw = node.price().get(); + let ui_price = price_raw as f64 / 1e4; + + debug!("[*] Bid: {price_raw}"); + + if max_bid == 0 { + max_bid = price_raw; + } + + if owner_address == self.orders_key { + open_bids.push(order_id); + open_bids_prices.push(ui_price); + } + + break; + } + None => { + break; + } + } + } + Ok((open_bids, open_bids_prices, max_bid)) + } + + /// Processes asks information to fetch asks info. + /// + /// This function iteratively removes asks from the provided `Slab` until + /// it finds the all asks. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `asks` - A mutable reference to the `Slab` containing asks information. + /// + /// # Returns + /// + /// A `Result` containing the maximum bid price if successful, or an error if processing asks fails. + pub fn process_asks( + &self, + asks: &mut RefMut, + ) -> anyhow::Result<(Vec, Vec, u64)> { + let mut min_ask = 0; + let mut open_asks = Vec::new(); + let mut open_asks_prices = Vec::new(); + loop { + let node = asks.remove_min(); + match node { + Some(node) => { + let owner = node.owner(); + let bytes = u64_slice_to_bytes(owner); + let owner_address = Pubkey::from(bytes); + + let order_id = node.order_id(); + let price_raw = node.price().get(); + let ui_price = price_raw as f64 / 1e4; + + debug!("[*] Ask: {price_raw}"); + + if min_ask == 0 { + min_ask = price_raw; + } + + if owner_address == self.orders_key { + open_asks.push(order_id); + open_asks_prices.push(ui_price); + } + } + None => { + break; + } + } + } + Ok((open_asks, open_asks_prices, min_ask)) + } + + /// Retrieves the bids and asks addresses from the given market state. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `market_state` - A reference to the `MarketState` representing the current state of the market. + /// + /// # Returns + /// + /// A tuple containing the bids and asks addresses. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// use openbook::state::MarketState; + /// use openbook::tokens_and_markets::{get_market_name, get_program_id}; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let program_id = get_program_id(3).parse().unwrap(); + /// let market_address = get_market_name("usdc").0.parse().unwrap(); + /// + /// let rpc_client1 = RpcClient::new(rpc_url.clone()); + /// let rpc_client2 = RpcClient::new(rpc_url.clone()); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client1, 3, "usdc", keypair).await; + /// + /// let mut account = rpc_client2.get_account(&market_address).await?; + /// + /// let account_info = market.create_account_info_from_account( + /// &mut account, + /// &market_address, + /// &program_id, + /// false, + /// false, + /// ); + /// + /// let mut market_state = MarketState::load(&account_info, &program_id, false)?; + /// let (bids_address, asks_address) = market.get_bids_asks_addresses(&market_state); + /// + /// assert_eq!(&bids_address.to_string(), "5jWUncPNBMZJ3sTHKmMLszypVkoRK6bfEQMQUHweeQnh"); + /// assert_eq!(&asks_address.to_string(), "EaXdHx7x3mdGA38j5RSmKYSXMzAFzzUXCLNBEDXDn1d5"); + /// + /// Ok(()) + /// } + /// ``` + pub fn get_bids_asks_addresses(&self, market_state: &MarketState) -> (Pubkey, Pubkey) { + let bids = market_state.bids; + let asks = market_state.asks; + let bids_bytes = u64_slice_to_bytes(bids); + let asks_bytes = u64_slice_to_bytes(asks); + + let bids_address = Pubkey::new_from_array(bids_bytes); + let asks_address = Pubkey::new_from_array(asks_bytes); + + (bids_address, asks_address) + } + + /// Creates an `AccountInfo` instance from an `Account`. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `account` - A mutable reference to the account from which to create `AccountInfo`. + /// * `key` - A reference to the public key associated with the account. + /// * `my_program_id` - A reference to the program's public key. + /// * `is_signer` - A boolean indicating whether the account is a signer. + /// * `is_writable` - A boolean indicating whether the account is writable. + /// + /// # Returns + /// + /// An `AccountInfo` instance created from the provided parameters. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::tokens_and_markets::{get_market_name, get_program_id}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// use openbook::state::MarketState; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let program_id = get_program_id(3).parse().unwrap(); + /// let market_address = get_market_name("usdc").0.parse().unwrap(); + /// + /// let rpc_client1 = RpcClient::new(rpc_url.clone()); + /// let rpc_client2 = RpcClient::new(rpc_url.clone()); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client1, 3, "usdc", keypair).await; + /// + /// let mut account = rpc_client2.get_account(&market_address).await?; + /// + /// let account_info = market.create_account_info_from_account( + /// &mut account, + /// &market_address, + /// &program_id, + /// false, + /// false, + /// ); + /// + /// println!("{:?}", account_info); + /// + /// Ok(()) + /// } + /// ``` + pub fn create_account_info_from_account<'a>( + &self, + account: &'a mut Account, + key: &'a Pubkey, + my_program_id: &'a Pubkey, + is_signer: bool, + is_writable: bool, + ) -> AccountInfo<'a> { + AccountInfo::new( + key, + is_signer, + is_writable, + &mut account.lamports, + &mut account.data, + my_program_id, + account.executable, + account.rent_epoch, + ) + } + + /// Places a limit order on the market. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `target_amount_quote` - The target amount in quote currency for the order. + /// * `side` - The side of the order (buy or sell). + /// * `best_offset_usdc` - The best offset in USDC for the order. + /// * `execute` - A boolean indicating whether to execute the order immediately. + /// * `target_price` - The target price for the order. + /// + /// # Returns + /// + /// A `Result` containing the transaction signature if successful, + /// or an error if placing the limit order fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with creating or sending the transaction. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// use openbook::matching::Side; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let target_amount_quote = 10.0; + /// let side = Side::Bid; // or Side::Ask + /// let best_offset_usdc = 0.5; + /// let execute = true; + /// let target_price = 15.0; + /// + /// let result = market.place_limit_order( + /// target_amount_quote, + /// side, + /// best_offset_usdc, + /// execute, + /// target_price + /// ).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn place_limit_order( + &self, + target_amount_quote: f64, + side: Side, + best_offset_usdc: f64, + execute: bool, + target_price: f64, + ) -> anyhow::Result, ClientError> { + // coin: base + // pc: quote + let base_d_factor = 10u32.pow(self.coin_decimals as u32) as f64; + let quote_d_factor = 10u32.pow(self.pc_decimals as u32) as f64; + let base_lot_factor = self.coin_lot_size as f64; + let quote_lot_factor = 10u32.pow(self.pc_lot_size as u32) as f64; + + let price_factor = quote_d_factor * base_lot_factor / base_d_factor / quote_lot_factor; + + let (input_ata, price) = match side { + Side::Bid => { + let mut price = self.market_info.max_bid as f64 / price_factor - best_offset_usdc; + if !execute { + price = target_price; + } + + (&self.quote_ata, price) + } + Side::Ask => { + let mut price = self.market_info.min_ask as f64 / price_factor + best_offset_usdc; + if !execute { + price = target_price; + } + + (&self.base_ata, price) + } + }; + + let limit_price_lots = (price * price_factor) as u64; + let target_amount_base = target_amount_quote / price; + + let target_base_lots = (target_amount_base * base_d_factor / base_lot_factor) as u64; + let target_quote_lots_w_fee = + (target_base_lots as f64 * quote_lot_factor * limit_price_lots as f64) as u64; + + debug!("[*] Using limit price lots: {:?}", limit_price_lots); + debug!("[*] Using target base lots: {:?}", target_base_lots); + + if target_base_lots == 0 { + debug!( + "[*] Got zero base lots, and quote: {:?}", + target_amount_quote + ); + return Ok(None); + } + + let limit_price = NonZeroU64::new(limit_price_lots).unwrap(); + let max_coin_qty = NonZeroU64::new(target_base_lots).unwrap(); // max wsol lots + let max_native_pc_qty_including_fees = NonZeroU64::new(target_quote_lots_w_fee).unwrap(); // max usdc lots + fees + + let place_order_ix = openbook_dex::instruction::new_order( + &self.market_address, + &self.orders_key, + &self.request_queue, + &self.event_queue, + &self.market_info.bids_address, + &self.market_info.asks_address, + &input_ata, + &self.keypair.pubkey(), + &self.coin_vault, + &self.pc_vault, + &anchor_spl::token::ID, + &solana_program::sysvar::rent::ID, + None, + &self.program_id, + Side::Bid, + limit_price, + max_coin_qty, + OrderType::PostOnly, + random::(), + SelfTradeBehavior::AbortTransaction, + u16::MAX, + max_native_pc_qty_including_fees, + (get_unix_secs() + 30) as i64, + ) + .unwrap(); + + let instructions = vec![place_order_ix]; + + let recent_hash = self.rpc_client.0.get_latest_blockhash().await?; + let txn = Transaction::new_signed_with_payer( + &instructions, + Some(&self.keypair.pubkey()), + &[&self.keypair], + recent_hash, + ); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + Ok(Some( + self.rpc_client + .0 + .send_transaction_with_config(&txn, config) + .await?, + )) + } + + /// Cancels all limit orders in the market. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `execute` - A boolean indicating whether to execute the order immediately. + /// + /// # Returns + /// + /// A `Result` containing the transaction signature if successful, + /// or an error if canceling all orders fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with creating or sending the transaction. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.cancel_orders(true).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn cancel_orders( + &self, + execute: bool, + ) -> anyhow::Result, ClientError> { + let mut ixs = Vec::new(); + + for oid in &self.market_info.open_bids { + let ix = openbook_dex::instruction::cancel_order( + &self.program_id, + &self.market_address, + &self.market_info.bids_address, + &self.market_info.asks_address, + &self.orders_key, + &self.keypair.pubkey(), + &self.event_queue, + Side::Bid, + *oid, + ) + .unwrap(); + ixs.push(ix); + } + + for oid in &self.market_info.open_asks { + let ix = openbook_dex::instruction::cancel_order( + &self.program_id, + &self.market_address, + &self.market_info.bids_address, + &self.market_info.asks_address, + &self.orders_key, + &self.keypair.pubkey(), + &self.event_queue, + Side::Ask, + *oid, + ) + .unwrap(); + ixs.push(ix); + } + + if ixs.len() == 0 || !execute { + return Ok(None); + } + + let recent_hash = self.rpc_client.0.get_latest_blockhash().await?; + let txn = Transaction::new_signed_with_payer( + &ixs, + Some(&self.keypair.pubkey()), + &[&self.keypair], + recent_hash, + ); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + Ok(Some( + self.rpc_client + .0 + .send_transaction_with_config(&txn, config) + .await?, + )) + } + + /// Settles the balance for a user in the market. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `execute` - A boolean indicating whether to execute the order immediately. + /// + /// # Returns + /// + /// A `Result` containing the transaction signature if successful, + /// or an error if settling the balance fails. + /// + /// # Errors + /// + /// This function may return an error if there is an issue with creating or sending the transaction. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.settle_balance(true).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn settle_balance( + &self, + execute: bool, + ) -> anyhow::Result, ClientError> { + let ix = openbook_dex::instruction::settle_funds( + &self.program_id, + &self.market_address, + &anchor_spl::token::ID, + &self.orders_key, + &self.keypair.pubkey(), + &self.coin_vault, + &self.base_ata, + &self.pc_vault, + &self.quote_ata, + None, + &self.vault_signer_key, + ) + .unwrap(); + + let instructions = vec![ix]; + + if !execute { + return Ok(None); + } + + let recent_hash = self.rpc_client.0.get_latest_blockhash().await?; + let txn = Transaction::new_signed_with_payer( + &instructions, + Some(&self.keypair.pubkey()), + &[&self.keypair], + recent_hash, + ); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + Ok(Some( + self.rpc_client + .0 + .send_transaction_with_config(&txn, config) + .await?, + )) + } + + /// Creates a new transaction to match orders in the market. + /// + /// # Arguments + /// + /// * `limit` - The maximum number of orders to match. + /// + /// # Returns + /// + /// A transaction for matching orders. + /// + /// # Errors + /// + /// Returns an error if there is an issue with transaction creation or sending. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.make_match_orders_transaction(100).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn make_match_orders_transaction( + &self, + limit: u16, + ) -> anyhow::Result { + let tx = Transaction::new_with_payer(&[], Some(&self.keypair.pubkey())); + + let _match_orders_ix = openbook_dex::instruction::match_orders( + &self.program_id, + &self.market_address, + &self.request_queue, + &self.market_info.bids_address, + &self.market_info.asks_address, + &self.event_queue, + &self.coin_vault, + &self.pc_vault, + limit, + ) + .unwrap(); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + self.rpc_client + .0 + .send_transaction_with_config(&tx, config) + .await + } + + /// Loads the bids from the market. + /// + /// # Returns + /// + /// The bids stored in the market. + /// + /// # Errors + /// + /// Returns an error if there is an issue with loading the bids. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.load_bids()?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub fn load_bids(&mut self) -> Result, ProgramError> { + Ok(self.market_info.open_bids.clone()) + } + + /// Loads the asks from the market. + /// + /// # Returns + /// + /// The asks stored in the market. + /// + /// # Errors + /// + /// Returns an error if there is an issue with loading the asks. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.load_asks()?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub fn load_asks(&mut self) -> Result, ProgramError> { + Ok(self.market_info.open_asks.clone()) + } + + /// Consumes events from the market for specified open orders accounts. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `open_orders_accounts` - A vector of `Pubkey` representing the open orders accounts. + /// * `limit` - The maximum number of events to consume. + /// + /// # Returns + /// + /// A `Result` containing the `Signature` of the transaction or a `ClientError` if an error occurs. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let open_orders_accounts = vec![Pubkey::new_from_array([0; 32])]; + /// let limit = 10; + /// let result = market.make_consume_events_instruction(open_orders_accounts, limit).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn make_consume_events_instruction( + &self, + open_orders_accounts: Vec, + limit: u16, + ) -> Result { + let consume_events_ix = openbook_dex::instruction::consume_events( + &self.program_id, + open_orders_accounts.iter().collect(), + &self.market_address, + &self.event_queue, + &self.coin_vault, + &self.pc_vault, + limit, + ) + .unwrap(); + + let tx = + Transaction::new_with_payer(&[consume_events_ix.clone()], Some(&self.keypair.pubkey())); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + self.rpc_client + .0 + .send_transaction_with_config(&tx, config) + .await + } + + /// Consumes permissioned events from the market for specified open orders accounts. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `open_orders_accounts` - A vector of `Pubkey` representing the open orders accounts. + /// * `limit` - The maximum number of events to consume. + /// + /// # Returns + /// + /// A `Result` containing the `Signature` of the transaction or a `ClientError` if an error occurs. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let open_orders_accounts = vec![Pubkey::new_from_array([0; 32])]; + /// let limit = 10; + /// let result = market.make_consume_events_permissioned_instruction(open_orders_accounts, limit).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn make_consume_events_permissioned_instruction( + &self, + open_orders_accounts: Vec, + limit: u16, + ) -> Result { + let consume_events_permissioned_ix = + openbook_dex::instruction::consume_events_permissioned( + &self.program_id, + open_orders_accounts.iter().collect(), + &self.market_address, + &self.event_queue, + &self.event_queue, // TODO: Update to consume_events_authority + limit, + ) + .unwrap(); + + let tx = Transaction::new_with_payer( + &[consume_events_permissioned_ix.clone()], + Some(&self.keypair.pubkey()), + ); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + self.rpc_client + .0 + .send_transaction_with_config(&tx, config) + .await + } + + /// Loads open orders accounts for the owner, filtering them based on bids and asks. + /// + /// # Arguments + /// + /// * `&mut self` - A mutable reference to the `Market` struct. + /// + /// # Returns + /// + /// A `Result` containing a vector of `Account` representing open orders accounts or a boxed `Error` if an error occurs. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let result = market.load_orders_for_owner().await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn load_orders_for_owner(&mut self) -> Result, Box> { + let mut bids = self.load_bids()?; + let asks = self.load_asks()?; + bids.extend(asks); + // let open_orders_accounts = self + // .find_open_orders_accounts_for_owner( + // &self.orders_key.clone(), + // 5000, + // ) + // .await?; + + Ok(bids) + } + + /// Filters open orders accounts based on bids and asks. + /// + /// # Arguments + /// + /// * `&self` - A reference to the `Market` struct. + /// * `bids` - A `MarketInfo` struct representing bids information. + /// * `asks` - A `MarketInfo` struct representing asks information. + /// * `open_orders_accounts` - A vector of `OpenOrders` representing open orders accounts. + /// + /// # Returns + /// + /// A filtered vector of `OpenOrders` based on bids and asks addresses. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// + /// let bids = market.market_info.clone(); + /// let asks = market.market_info.clone(); + /// + /// let open_orders_accounts = vec![]; + /// let result = market.filter_for_open_orders(bids, asks, open_orders_accounts); + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub fn filter_for_open_orders( + &self, + bids: MarketInfo, + asks: MarketInfo, + open_orders_accounts: Vec, + ) -> Vec { + let bids_address = bids.bids_address; + let asks_address = asks.asks_address; + + open_orders_accounts + .into_iter() + .filter(|open_orders| { + open_orders.address == bids_address || open_orders.address == asks_address + }) + .collect() + } + + /// Finds open orders accounts for a specified owner and caches them based on the specified duration. + /// + /// # Arguments + /// + /// * `&mut self` - A mutable reference to the `Market` struct. + /// * `owner_address` - A reference to the owner's `Pubkey`. + /// * `cache_duration_ms` - The duration in milliseconds for which to cache open orders accounts. + /// + /// # Returns + /// + /// A `Result` containing a vector of `Account` representing open orders accounts or a boxed `Error` if an error occurs. + /// + /// # Examples + /// + /// ```rust + /// use openbook::{pubkey::Pubkey, signature::Keypair, rpc_client::RpcClient}; + /// use openbook::market::Market; + /// use openbook::utils::read_keypair; + /// + /// #[tokio::main] + /// async fn main() -> Result<(), Box> { + /// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + /// let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + /// + /// let rpc_client = RpcClient::new(rpc_url); + /// + /// let keypair = read_keypair(&key_path); + /// + /// let mut market = Market::new(rpc_client, 3, "usdc", keypair).await; + /// let owner_address = &Pubkey::new_from_array([0; 32]); + /// + /// let result = market.find_open_orders_accounts_for_owner(&owner_address, 5000).await?; + /// + /// println!("{:?}", result); + /// + /// Ok(()) + /// } + /// ``` + pub async fn find_open_orders_accounts_for_owner( + &mut self, + owner_address: &Pubkey, + cache_duration_ms: u64, + ) -> Result, Box> { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis(); + if let Some(cache_entry) = self.open_orders_accounts_cache.get(owner_address) { + if now - cache_entry.ts < cache_duration_ms.into() { + // return Ok(cache_entry.accounts.clone()); + } + } + + let open_orders_accounts_for_owner = OpenOrders::find_for_market_and_owner( + &self.rpc_client.0, + self.keypair.pubkey(), + *owner_address, + false, + ) + .await?; + // self.open_orders_accounts_cache.insert( + // *owner_address, + // OpenOrdersCacheEntry { + // accounts: open_orders_accounts_for_owner.clone(), + // ts: now, + // }, + // ); + + Ok(open_orders_accounts_for_owner) + } +} diff --git a/src/orders.rs b/src/orders.rs new file mode 100644 index 0000000..bc3a4b2 --- /dev/null +++ b/src/orders.rs @@ -0,0 +1,586 @@ +//! This module contains structs and functions related to open orders on the Solana blockchain. + +#![allow(dead_code, deprecated)] +use crate::{ + rpc_client::RpcClient, tokens_and_markets::get_layout_version, + utils::get_filtered_program_accounts, +}; +use borsh::{BorshDeserialize, BorshSerialize}; +use log::debug; +use memoffset::offset_of; +use solana_client::{ + rpc_config::RpcSendTransactionConfig, + rpc_filter::MemcmpEncodedBytes, + rpc_filter::{Memcmp, MemcmpEncodedBytes::Base58, MemcmpEncoding, RpcFilterType}, +}; +use solana_sdk::{ + account::Account, bs58, compute_budget::ComputeBudgetInstruction, + nonce::state::Data as NonceData, pubkey::Pubkey, signature::Signer, signer::keypair::Keypair, + transaction::Transaction, +}; +use std::{borrow::Borrow, convert::TryInto, error::Error}; + +/// Struct representing an open orders account. +#[derive(Debug, BorshDeserialize, BorshSerialize, Clone)] +pub struct OpenOrders { + /// The public key of the open orders account. + pub address: Pubkey, + + /// The public key of the market associated with the open orders. + pub market: Pubkey, + + /// The public key of the owner of the open orders. + pub owner: Pubkey, + + /// The amount of base token that is free and available in the open orders account. + pub base_token_free: u64, + + /// The total amount of base token in the open orders account. + pub base_token_total: u64, + + /// The amount of quote token that is free and available in the open orders account. + pub quote_token_free: u64, + + /// The total amount of quote token in the open orders account. + pub quote_token_total: u64, + + /// Bit field representing free slots in the open orders account. + pub free_slot_bits: u64, + + /// Bit field representing whether each slot contains a bid order. + pub is_bid_bits: u64, + + /// List of order IDs in the open orders account. + pub orders: Vec, + + /// List of client IDs associated with the orders in the open orders account. + pub client_ids: Vec, +} + +impl OpenOrders { + /// Creates a new `OpenOrders` instance from the given data. + /// + /// # Arguments + /// + /// * `address` - The public key of the open orders account. + /// * `decoded` - The decoded layout data of the open orders account. + /// * `_program_id` - The program ID associated with the open orders. + /// + /// # Returns + /// + /// An instance of `OpenOrders`. + pub fn new(address: Pubkey, decoded: OpenOrdersLayoutV1, _program_id: Pubkey) -> Self { + let OpenOrdersLayoutV1 { + market, + owner, + base_token_free, + base_token_total, + quote_token_free, + quote_token_total, + free_slot_bits, + is_bid_bits, + orders, + client_ids, + account_flags: _, + padding: _, + } = decoded; + + Self { + address, + market: market.into(), + owner: owner.into(), + base_token_free, + base_token_total, + quote_token_free, + quote_token_total, + free_slot_bits: free_slot_bits.try_into().unwrap(), + is_bid_bits: is_bid_bits.try_into().unwrap(), + orders: orders.into(), + client_ids: client_ids.into(), + } + } + + /// Returns the layout size of the `OpenOrders` struct based on the program ID. + pub fn get_layout(program_id: Pubkey) -> usize { + match get_layout_version(&program_id) { + 1 => std::mem::size_of::(), + _ => std::mem::size_of::(), + } + } + + /// Returns the derived open orders account pubkey and seed for the given owner and market. + /// + /// # Arguments + /// + /// * `owner_address` - The public key of the owner. + /// * `market_address` - The public key of the market. + /// * `program_id` - The program ID associated with the open orders. + /// + /// # Returns + /// + /// A tuple containing the derived pubkey and seed. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during pubkey creation. + pub fn get_derived_oo_account_pubkey( + owner_address: Pubkey, + market_address: Pubkey, + program_id: Pubkey, + ) -> Result> { + let seed = market_address + .to_string() + .chars() + .take(32) + .collect::(); + let public_key = Pubkey::create_with_seed(&owner_address, &seed, &program_id)?; + Ok(public_key) + } + + /// Finds open orders accounts associated with the given owner. + /// + /// # Arguments + /// + /// * `connection` - The RPC client for interacting with the Solana blockchain. + /// * `owner_address` - The public key of the owner. + /// * `program_id` - The program ID associated with the open orders. + /// + /// # Returns + /// + /// A `Result` containing a vector of `OpenOrders` or an error. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during the RPC call or deserialization. + pub async fn find_for_owner( + connection: &RpcClient, + owner_address: Pubkey, + program_id: Pubkey, + ) -> Result, Box> { + let offset = offset_of!(OpenOrdersLayoutV1, owner); + let filters = vec![ + RpcFilterType::Memcmp(Memcmp { + offset, + bytes: Base58(owner_address.to_string()), + encoding: Some(MemcmpEncoding::Binary), + }), + RpcFilterType::DataSize(OpenOrders::get_layout(program_id) as u64), + ]; + + let accounts = get_filtered_program_accounts(connection, filters).await?; + + let open_orders_result: Result, _> = accounts + .into_iter() + .map(|account| OpenOrders::from_account_info(account.clone(), program_id)) + .collect(); + + open_orders_result + } + + /// Finds open orders accounts for a given market and owner. + /// + /// This function queries the blockchain for open orders accounts associated with a specific + /// market and owner. Optionally, it can force the creation of a seed account if none is found. + /// + /// # Arguments + /// + /// * `connection` - The RPC client for interacting with the Solana blockchain. + /// * `market_address` - The public key representing the market associated with the open orders. + /// * `owner_address` - The public key representing the owner of the open orders. + /// * `program_id` - The program ID associated with the open orders. + /// * `force_seed_account` - A boolean indicating whether to force the creation of a seed account + /// if no open orders account is found. + /// + /// # Returns + /// + /// A `Result` containing a vector of `OpenOrders` instances or an error. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during the RPC call, deserialization, or + /// ownership check. + pub async fn find_for_market_and_owner( + connection: &RpcClient, + market_address: Pubkey, + owner_address: Pubkey, + force_seed_account: bool, + ) -> Result, Box> { + let _account_info = connection.get_account(&owner_address).await?; + + if force_seed_account { + return Ok(vec![]); + } + + let _market_offset = offset_of!(OpenOrdersLayoutV1, market); + let _owner_offset = offset_of!(OpenOrdersLayoutV1, owner); + + let filters = vec![ + RpcFilterType::Memcmp(Memcmp { + offset: 32, + bytes: MemcmpEncodedBytes::Base58(bs58::encode(owner_address).into_string()), + encoding: Some(MemcmpEncoding::Binary), + }), + RpcFilterType::Memcmp(Memcmp { + offset: 32, + bytes: MemcmpEncodedBytes::Base58(bs58::encode(market_address).into_string()), + encoding: Some(MemcmpEncoding::Binary), + }), + RpcFilterType::DataSize(165), + ]; + let accounts = get_filtered_program_accounts(connection, filters).await?; + + let _open_orders_result: Result, _> = accounts + .clone() + .into_iter() + .map(|account| account.deserialize_data::()) + .collect(); + + Ok(accounts) + } + + /// Loads an open orders account from the blockchain. + /// + /// # Arguments + /// + /// * `connection` - The RPC client for interacting with the Solana blockchain. + /// * `address` - The public key of the open orders account. + /// * `program_id` - The program ID associated with the open orders. + /// + /// # Returns + /// + /// A `Result` containing an `OpenOrders` instance or an error. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during the RPC call or deserialization. + pub async fn load( + connection: &RpcClient, + address: Pubkey, + program_id: Pubkey, + ) -> Result> { + let account = connection.get_account(&address).await?; + OpenOrders::from_account_info(account, program_id) + } + + /// Creates an `OpenOrders` instance from the given account information. + /// + /// # Arguments + /// + /// * `account_info` - The account information received from the blockchain. + /// * `program_id` - The program ID associated with the open orders. + /// + /// # Returns + /// + /// A `Result` containing an `OpenOrders` instance or an error. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during deserialization or ownership check. + pub fn from_account_info( + mut account_info: Account, + program_id: Pubkey, + ) -> Result> { + // Fix: Not all bytes read + let data_size: usize = 165; + account_info.data.resize(data_size, 0); + let decoded = OpenOrdersLayoutV1::try_from_slice(account_info.data.borrow())?; + let _account_flags = decoded.account_flags; + if !account_info.owner.eq(&program_id) { + return Err("Address not owned by program".into()); + } + + // if !account_flags.initialized || !account_flags.open_orders { + // return Err("Invalid open orders account".into()); + // } + + let OpenOrdersLayoutV1 { + account_flags: _, + market, + owner, + base_token_free, + base_token_total, + quote_token_free, + quote_token_total, + free_slot_bits, + is_bid_bits, + orders, + client_ids, + padding: _, + } = decoded; + + Ok(Self { + address: account_info.owner, + market: market.into(), + owner: owner.into(), + base_token_free, + base_token_total, + quote_token_free, + quote_token_total, + free_slot_bits: free_slot_bits.try_into().unwrap(), + is_bid_bits: is_bid_bits.try_into().unwrap(), + orders: orders.into(), + client_ids: client_ids.into(), + }) + } + + /// Generates a transaction instruction for creating a new open orders account. + /// + /// # Arguments + /// + /// * `connection` - The RPC client for interacting with the Solana blockchain. + /// * `owner_address` - The public key of the owner. + /// * `new_account_address` - The public key for the new open orders account. + /// * `program_id` - The program ID associated with the open orders. + /// * `seed` - The seed for deriving the new account address. + /// + /// # Returns + /// + /// A `Result` containing an `Instruction` or an error. + /// + /// # Errors + /// + /// Returns a `Box` if there is an error during the RPC call or transaction creation. + pub async fn make_create_account_transaction( + connection: &RpcClient, + program_id: Pubkey, + keypair: &Keypair, + market_account: Pubkey, + ) -> Result> { + let new_account_address = Keypair::new(); + let minimum_balance = connection + .get_minimum_balance_for_rent_exemption(OpenOrders::get_layout(program_id)) + .await?; + let space: u64 = OpenOrders::get_layout(program_id).try_into().unwrap(); + + // let seed = market_account + // .to_string() + // .chars() + // .take(32) + // .collect::(); + + // let instruction = create_account_with_seed( + // &keypair.pubkey(), + // &new_account_address.pubkey(), + // &new_account_address.pubkey(), + // &seed, + // minimum_balance, + // space + 12, + // &program_id, + // ); + let instruction = solana_sdk::system_instruction::create_account( + &keypair.pubkey(), + &new_account_address.pubkey(), + minimum_balance, + space + 12, + &program_id, + ); + let init_ix = openbook_dex::instruction::init_open_orders( + &program_id, + &new_account_address.pubkey(), + &keypair.pubkey(), + &market_account, + None, + )?; + debug!( + "Got New Account Address: {:?}", + new_account_address.pubkey() + ); + + let mut instructions = Vec::new(); + let r = connection + .get_recent_prioritization_fees(&[]) + .await + .unwrap(); + let mut max_fee = 1; + for f in r { + if f.prioritization_fee > max_fee { + max_fee = f.prioritization_fee; + } + } + + let budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_000_000); + let fee_ix = ComputeBudgetInstruction::set_compute_unit_price(max_fee); + instructions.push(budget_ix); + instructions.push(fee_ix); + + instructions.push(instruction); + instructions.push(init_ix); + + debug!("Using Pubkey: {}", &keypair.pubkey().to_string()); + + let recent_hash = connection.get_latest_blockhash().await?; + let txn = Transaction::new_signed_with_payer( + &instructions, + Some(&keypair.pubkey()), + &[&new_account_address, &keypair], + recent_hash, + ); + + let mut config = RpcSendTransactionConfig::default(); + config.skip_preflight = true; + + let result = connection.send_transaction_with_config(&txn, config).await; + + match result { + Ok(sig) => debug!("Transaction successful, signature: {:?}", sig), + Err(err) => debug!("Transaction failed: {:?}", err), + }; + + Ok(new_account_address.pubkey()) + } + + pub fn get_public_key(&self) -> Pubkey { + self.address + } +} + +/// Enumeration representing account flags. +#[derive(Debug)] +struct AccountFlags { + /// Flag indicating whether the account is initialized. + initialized: bool, + + /// Flag indicating whether the account is open orders. + open_orders: bool, +} + +/// Layout of the open orders account for version 1. +#[derive(Debug, BorshDeserialize, BorshSerialize)] +pub struct OpenOrdersLayoutV1 { + /// Account flags indicating initialization and open orders status. + pub account_flags: u64, + + /// Public key of the market associated with the open orders. + pub market: [u8; 32], + + /// Public key of the owner of the open orders. + pub owner: [u8; 32], + + /// Amount of base token that is free and available in the open orders account. + pub base_token_free: u64, + + /// Total amount of base token in the open orders account. + pub base_token_total: u64, + + /// Amount of quote token that is free and available in the open orders account. + pub quote_token_free: u64, + + /// Total amount of quote token in the open orders account. + pub quote_token_total: u64, + + /// Bit field representing free slots in the open orders account. + pub free_slot_bits: u128, + + /// Bit field representing whether each slot contains a bid order. + pub is_bid_bits: u128, + + /// List of order IDs in the open orders account. + pub orders: [u64; 128], + + /// List of client IDs associated with the orders in the open orders account. + pub client_ids: [u64; 128], + + /// Padding for alignment. + pub padding: [u8; 7], +} + +impl Default for OpenOrdersLayoutV1 { + fn default() -> Self { + Self { + account_flags: 0, + market: [0; 32], + owner: [0; 32], + base_token_free: 0, + base_token_total: 0, + quote_token_free: 0, + quote_token_total: 0, + free_slot_bits: 0, + is_bid_bits: 0, + orders: [0; 128], + client_ids: [0; 128], + padding: [0; 7], + } + } +} + +/// Layout of the open orders account for version 2. +#[derive(Debug, BorshDeserialize, BorshSerialize)] +pub struct OpenOrdersLayoutV2 { + /// Account flags indicating initialization and open orders status. + pub account_flags: u64, + + /// Public key of the market associated with the open orders. + pub market: [u8; 32], + + /// Public key of the owner of the open orders. + pub owner: [u8; 32], + + /// Amount of base token that is free and available in the open orders account. + pub base_token_free: u64, + + /// Total amount of base token in the open orders account. + pub base_token_total: u64, + + /// Amount of quote token that is free and available in the open orders account. + pub quote_token_free: u64, + + /// Total amount of quote token in the open orders account. + pub quote_token_total: u64, + + /// Bit field representing free slots in the open orders account. + pub free_slot_bits: u128, + + /// Bit field representing whether each slot contains a bid order. + pub is_bid_bits: u128, + + /// List of order IDs in the open orders account. + pub orders: [u64; 128], + + /// List of client IDs associated with the orders in the open orders account. + pub client_ids: [u64; 128], + + /// Additional field for version 2. + pub referrer_rebates_accrued: u64, + + /// Padding for alignment. + pub padding: [u8; 7], +} +impl Default for OpenOrdersLayoutV2 { + fn default() -> Self { + Self { + account_flags: 0, + market: [0; 32], + owner: [0; 32], + base_token_free: 0, + base_token_total: 0, + quote_token_free: 0, + quote_token_total: 0, + free_slot_bits: 0, + is_bid_bits: 0, + orders: [0; 128], + client_ids: [0; 128], + referrer_rebates_accrued: 0, + padding: [0; 7], + } + } +} + +#[derive(Debug)] +pub struct OpenOrdersCacheEntry { + pub accounts: Vec, + pub ts: u128, +} + +#[derive(Debug, Clone, Default)] +pub struct MarketInfo { + pub min_ask: u64, + pub max_bid: u64, + pub open_asks: Vec, + pub open_bids: Vec, + pub bids_address: Pubkey, + pub asks_address: Pubkey, + pub open_asks_prices: Vec, + pub open_bids_prices: Vec, + pub base_total: f64, + pub quote_total: f64, +} diff --git a/src/tokens_and_markets.rs b/src/tokens_and_markets.rs new file mode 100644 index 0000000..060e16f --- /dev/null +++ b/src/tokens_and_markets.rs @@ -0,0 +1,145 @@ +//! This module contains utility functions related openbook token and market info. + +use solana_sdk::pubkey::Pubkey; + +/// Represents the layout versions associated with Solana programs. +/// +/// This static array contains tuples where the first element represents the program ID in string format, +/// and the second element represents the associated layout version. +pub static PROGRAM_LAYOUT_VERSIONS: [(&str, u8); 4] = [ + ("4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn", 1), // DEX Version 1 + ("BJ3jrUzddfuSrZHXSCxMUUQsjKEyLmuuyZebkcaFp2fg", 1), // DEX Version 1 + ("EUqojwWA2rd19FZrzeBncJsm38Jm1hEhE3zsmX3bRc2o", 2), // DEX Version 2 + ("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX", 3), // DEX Version 3 +]; + +/// Represents openbook market ids, and base mints associated with the tokens. +/// +/// This static array contains tuples where the first element represents the market ID, +/// the second element represents the associated base mint, and the third element represents +/// the associated token. +pub static MARKET_IDS_TO_NAMES: [(&str, &str, &str); 6] = [ + ( + "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6", + "So11111111111111111111111111111111111111112", + "sol", + ), + ( + "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6", + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "usdc", + ), + ( + "HTHMfoxePjcXFhrV74pfCUNoWGe374ecFwiDjPGTkzHr", + "SLNDpmoWTVADgEdndyvWzroNL7zSi1dF9PC3xHGtPwp", + "slnd", + ), + ( + "DZjbn4XC8qoHKikZqzmhemykVzmossoayV9ffbsUqxVj", + "4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", + "ray", + ), + ( + "BbJgE7HZMaDp5NTYvRh5jZSkQPVDTU8ubPFtpogUkEj4", + "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs", + "eth", + ), + ( + "CC9VYJprbxacpiS94tPJ1GyBhfvrLQbUiUSVMWvFohNW", + "MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey", + "mnde", + ), + // TODO: add all markets +]; + +/// Gets the layout version for the given program ID. +/// +/// # Arguments +/// +/// * `program_id` - The program ID for which the layout version is requested. +/// +/// # Returns +/// +/// The layout version associated with the program ID. Returns 3 if not found. +/// +/// # Examples +/// +/// ```rust +/// use openbook::pubkey::Pubkey; +/// use openbook::tokens_and_markets::get_layout_version; +/// +/// let program_id = Pubkey::new_unique(); +/// let version = get_layout_version(&program_id); +/// +/// assert_eq!(version, 3); +/// ``` +pub fn get_layout_version(program_id: &Pubkey) -> u8 { + PROGRAM_LAYOUT_VERSIONS + .iter() + .find(|(id, _)| *id == program_id.to_string()) + .map(|(_, version)| *version) + .unwrap_or(3) +} + +/// Gets the program ID for the given layout version. +/// +/// # Arguments +/// +/// * `version` - The layout version for which the program ID is requested. +/// +/// # Returns +/// +/// The program ID associated with the layout version. Returns program ID for version +/// 3 if not found. +/// +/// # Examples +/// +/// ```rust +/// use openbook::pubkey::Pubkey; +/// use openbook::tokens_and_markets::get_program_id; +/// +/// let program_id = get_program_id(3); +/// +/// assert_eq!(&program_id, "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"); +/// ``` +pub fn get_program_id(version: u8) -> String { + PROGRAM_LAYOUT_VERSIONS + .iter() + .find(|(_, v)| *v == version) + .map(|(id, _)| id.to_string()) + .unwrap_or("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX".to_string()) +} + +/// Gets the market id for the given market name. +/// +/// # Arguments +/// +/// * `market_name` - The market name for which the market id is requested. +/// +/// # Returns +/// +/// The market id ID associated with the market name. Returns market ID for "openbook" market +/// if not found. +/// +/// # Examples +/// +/// ```rust +/// use openbook::pubkey::Pubkey; +/// use openbook::tokens_and_markets::get_market_name; +/// +/// let market_id = get_market_name("usdc").0; +/// +/// assert_eq!(&market_id, "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6"); +/// ``` +pub fn get_market_name(market_name: &str) -> (String, String) { + MARKET_IDS_TO_NAMES + .iter() + .find(|(_, _, val)| *val == market_name) + .map(|(id, base, _)| (id.to_string(), base.to_string())) + .unwrap_or_else(|| { + ( + "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6".to_string(), + "So11111111111111111111111111111111111111112".to_string(), + ) + }) +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..afd3798 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,167 @@ +//! This module contains utility functions related openbook. + +use crate::{account::Account, bs58, keypair::Keypair, rpc_client::RpcClient}; +use log::debug; +use solana_account_decoder::UiAccountEncoding; +use solana_client::{ + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, + rpc_filter::RpcFilterType, +}; +use solana_sdk::sysvar::slot_history::ProgramError; +use std::{fs, time::SystemTime, time::UNIX_EPOCH}; + +/// Converts a slice of `u64` values into a fixed-size byte array. +/// +/// # Arguments +/// +/// * `&self` - A reference to the `Market` struct. +/// * `slice` - A reference to a slice of `u64` values to be converted. +/// +/// # Returns +/// +/// A fixed-size array of bytes containing the serialized `u64` values. +/// +/// # Examples +/// +/// ```rust +/// use openbook::utils::u64_slice_to_bytes; +/// +/// let slice = [1, 2, 3, 4]; +/// let bytes_array = u64_slice_to_bytes(slice); +/// ``` +pub fn u64_slice_to_bytes(array: [u64; 4]) -> [u8; 32] { + let mut result = [0u8; 32]; + for (i, &item) in array.iter().enumerate() { + result[i * 8..(i + 1) * 8].copy_from_slice(&item.to_le_bytes()); + } + result +} + +/// Reads a keypair from a file. +/// +/// # Arguments +/// +/// * `path` - The file path containing the keypair information. +/// +/// # Returns +/// +/// A `Keypair` instance created from the keypair information in the file. +/// +/// # Examples +/// +/// ```rust +/// use openbook::utils::read_keypair; +/// +/// let path = String::from("/path/to/keypair_file.json"); +/// // let keypair = read_keypair(&path); +/// ``` +pub fn read_keypair(path: &String) -> Keypair { + let secret_string: String = fs::read_to_string(path).expect("Can't find key file"); + let secret_bytes: Vec = match serde_json::from_str(&secret_string) { + Ok(bytes) => bytes, + Err(_) => match bs58::decode(&secret_string.trim()).into_vec() { + Ok(bytes) => bytes, + Err(_) => panic!("failed to load secret key from file"), + }, + }; + Keypair::from_bytes(&secret_bytes).expect("failed to generate keypair from secret bytes") +} + +/// Gets the current UNIX timestamp in seconds. +/// +/// # Returns +/// +/// The current UNIX timestamp in seconds. +/// +/// # Examples +/// +/// ```rust +/// use openbook::utils::get_unix_secs; +/// +/// let timestamp = get_unix_secs(); +/// ``` +pub fn get_unix_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() +} + +/// Helper function for getting filtered program accounts based on specified filters. +/// +/// # Arguments +/// +/// * `connection` - The RPC client for interacting with the Solana blockchain. +/// * `program_id` - The program ID associated with the accounts. +/// * `filters` - List of filters to apply for querying accounts. +/// +/// # Returns +/// +/// A `Result` containing a vector of `Account` instances or a `ProgramError`. +/// +/// # Examples +/// +/// ```rust +/// use openbook::utils::get_filtered_program_accounts; +/// use openbook::rpc_filter::RpcFilterType; +/// use openbook::rpc_filter::MemcmpEncoding; +/// use openbook::bs58; +/// use openbook::rpc_filter::Memcmp; +/// use openbook::rpc_filter::MemcmpEncodedBytes; +/// use openbook::{pubkey::Pubkey, account::Account, rpc_client::RpcClient}; +/// use openbook::tokens_and_markets::get_market_name; +/// use std::str::FromStr; +/// +/// #[tokio::main] +/// async fn main() -> Result<(), Box> { +/// let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set"); +/// let connection = RpcClient::new(rpc_url); +/// let market_address: Pubkey = get_market_name("usdc").0.parse().unwrap(); +/// +/// let filters = vec![ +/// RpcFilterType::Memcmp(Memcmp { +/// offset: 32, +/// bytes: MemcmpEncodedBytes::Base58(bs58::encode(market_address).into_string()), +/// encoding: Some(MemcmpEncoding::Binary), +/// }), +/// RpcFilterType::DataSize(165), +/// ]; +/// +/// match get_filtered_program_accounts(&connection, filters).await { +/// Ok(accounts) => println!("Filtered accounts: {:?}", accounts), +/// Err(err) => eprintln!("Error getting filtered accounts: {:?}", err), +/// } +/// Ok(()) +/// } +/// ``` +pub async fn get_filtered_program_accounts( + connection: &RpcClient, + filters: Vec, +) -> Result, ProgramError> { + let config = RpcProgramAccountsConfig { + filters: Some(filters), + account_config: RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + commitment: Some(connection.commitment()), + ..RpcAccountInfoConfig::default() + }, + with_context: Some(false), + }; + // Error 410: Resource No Longer Available + // The occurrence of this error is attributed to the high cost of the + // `get_program_accounts_with_config` call on the mainnet-beta network. As a result, + // consider utilizing the Helius network as an alternative to mitigate this issue. + let accounts = connection + .get_program_accounts_with_config(&anchor_spl::token::ID, config) + .await + .unwrap(); + + let mut result = Vec::new(); + + for (i, account) in accounts.iter().enumerate() { + debug!("\n[*] ATA {:?}: {:?}\n", i, account); + result.push(account.1.clone()); + } + + Ok(result) +} diff --git a/tests/fees.rs b/tests/fees.rs new file mode 100644 index 0000000..8ae40e1 --- /dev/null +++ b/tests/fees.rs @@ -0,0 +1,27 @@ +use openbook::fees::{get_fee_rates, get_fee_tier, supports_srm_fee_discounts}; +use openbook::pubkey::Pubkey; + +#[test] +fn test_supports_srm_fee_discounts() { + let program_id = Pubkey::new_unique(); + assert!(supports_srm_fee_discounts(&program_id)); +} + +#[test] +fn test_get_fee_rates() { + assert_eq!(get_fee_rates(1), (0.002, -0.0003)); + assert_eq!(get_fee_rates(3), (0.0016, -0.0003)); + assert_eq!(get_fee_rates(6), (0.001, -0.0005)); + assert_eq!(get_fee_rates(7), (0.0022, -0.0003)); +} + +#[test] +fn test_get_fee_tier() { + assert_eq!(get_fee_tier(1.5, 0.0), 6); + assert_eq!(get_fee_tier(0.0, 1_000_001.0), 5); + assert_eq!(get_fee_tier(0.0, 100_001.0), 4); + assert_eq!(get_fee_tier(0.0, 10_001.0), 3); + assert_eq!(get_fee_tier(0.0, 1_001.0), 2); + assert_eq!(get_fee_tier(0.0, 101.0), 1); + assert_eq!(get_fee_tier(0.0, 0.0), 0); +} diff --git a/tests/market.rs b/tests/market.rs new file mode 100644 index 0000000..06ed3ae --- /dev/null +++ b/tests/market.rs @@ -0,0 +1,60 @@ +use openbook::market::Market; +use openbook::rpc_client::RpcClient; +use openbook::utils::read_keypair; + +#[tokio::test] +async fn test_market_state_info() { + let rpc_url = std::env::var("RPC_URL").expect("RPC_URL is not set in .env file"); + let key_path = std::env::var("KEY_PATH").expect("KEY_PATH is not set in .env file"); + + let rpc_client = RpcClient::new(rpc_url); + + let keypair = read_keypair(&key_path); + + let market = Market::new(rpc_client, 3, "usdc", keypair).await; + + assert_eq!( + &market.program_id.to_string(), + "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX" + ); + assert_eq!( + &market.market_address.to_string(), + "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6" + ); + assert_eq!( + &market.event_queue.to_string(), + "8CvwxZ9Db6XbLD46NZwwmVDZZRDy7eydFcAGkXKh9axa" + ); + assert_eq!( + &market.request_queue.to_string(), + "CPjXDcggXckEq9e4QeXUieVJBpUNpLEmpihLpg5vWjGF" + ); + assert_eq!( + &market.market_info.bids_address.to_string(), + "5jWUncPNBMZJ3sTHKmMLszypVkoRK6bfEQMQUHweeQnh" + ); + assert_eq!( + &market.market_info.asks_address.to_string(), + "EaXdHx7x3mdGA38j5RSmKYSXMzAFzzUXCLNBEDXDn1d5" + ); + assert_eq!( + &market.quote_ata.to_string(), + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + ); + assert_eq!( + &market.base_ata.to_string(), + "So11111111111111111111111111111111111111112" + ); + + // Additional Details + + assert_eq!(market.coin_decimals, 9); + + // Base Decimals + assert_eq!(market.pc_decimals, 6); + + // Base Lot Size + assert_eq!(market.coin_lot_size, 1000000); + + assert_eq!(market.pc_lot_size, 1); +} diff --git a/tests/tokens_and_markets.rs b/tests/tokens_and_markets.rs new file mode 100644 index 0000000..0136c2f --- /dev/null +++ b/tests/tokens_and_markets.rs @@ -0,0 +1,42 @@ +use openbook::{ + pubkey::Pubkey, + tokens_and_markets::{get_layout_version, get_program_id}, +}; +use std::str::FromStr; + +#[test] +fn test_get_layout_version_known_id() { + let known_program_id = + Pubkey::from_str("4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn").unwrap(); + assert_eq!(get_layout_version(&known_program_id), 1); +} + +#[test] +fn test_get_layout_version_non_existing_id() { + let program_id = Pubkey::new_unique(); + assert_eq!(get_layout_version(&program_id), 3); +} + +#[test] +fn test_get_program_id_existing_version() { + assert_eq!( + &get_program_id(1), + "4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn" + ); + assert_eq!( + &get_program_id(2), + "EUqojwWA2rd19FZrzeBncJsm38Jm1hEhE3zsmX3bRc2o" + ); + assert_eq!( + &get_program_id(3), + "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX" + ); +} + +#[test] +fn test_get_program_id_non_existing_version() { + assert_eq!( + &get_program_id(4), + "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX" + ); +}